From ad480757252169b1a2e362225658e909c18d246e Mon Sep 17 00:00:00 2001
From: hawkspar <quentin.chevalier@polytechnique.edu>
Date: Sat, 20 Oct 2018 11:12:54 +0200
Subject: [PATCH] Reorganisation LDAP

---
 configfile_doc.json                       |    2 +-
 ldap_config.json                          |   86 +-
 package-lock.json                         | 3023 ++++++++++++---------
 package.json                              |   23 +-
 src/app.ts                                |    5 +-
 src/graphql/typeDefs/objects.graphql      |    7 +-
 src/graphql/typeDefs/objects_ldap.graphql |  243 ++
 src/ldap/admins.ts                        |  410 ---
 src/ldap/basics.ts                        |   34 +-
 src/ldap/group.ts                         |  391 +++
 src/ldap/user.ts                          |  331 +++
 src/ldap/users.ts                         |  416 ---
 src/ldap/utilities.ts                     |  240 +-
 13 files changed, 2907 insertions(+), 2304 deletions(-)
 create mode 100644 src/graphql/typeDefs/objects_ldap.graphql
 delete mode 100644 src/ldap/admins.ts
 create mode 100644 src/ldap/group.ts
 create mode 100644 src/ldap/user.ts
 delete mode 100644 src/ldap/users.ts

diff --git a/configfile_doc.json b/configfile_doc.json
index ca587bd..2949f28 100644
--- a/configfile_doc.json
+++ b/configfile_doc.json
@@ -27,6 +27,6 @@
       "extensions": ["ts", "tsx"],
       "babelrc": false,
       "presets": [["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/typescript"],
-      "plugins": ["@babel/proposal-class-properties", "@babel/proposal-object-rest-spread"]
+      "plugins": ["@babel/plugin-proposal-class-properties", "@babel/proposal-object-rest-spread"]
     }
 }
\ No newline at end of file
diff --git a/ldap_config.json b/ldap_config.json
index d18f831..60790a9 100644
--- a/ldap_config.json
+++ b/ldap_config.json
@@ -9,55 +9,49 @@
 	
 	"comment_3": "Placeholders et indications de contenu de certains champs du LDAP généré par frankiz pour les utilisateurs",
 	"user": {
-		"single": {
-			"photo": "jpegPhoto",
-			"givenName": "givenName",
-			"lastName": "sn",
-			"fullName": "cn",
-			"cleanFullName": "gecos",
-			"nickname": "displayName",
-			"birthdate": "brBirthdate",
-			"nationality": "country",
-			"promotion": "brPromo",
-			"phone": "telephoneNumber",
-			"adress": "brRoom",
-			"id": "uidNumber",
-			"sport": "brMemberOf",
-			"password": "userPassword",
-			"idNum": "gidNumber",
-			"directory": "homeDirectory",
-			"login": "loginShell",
-			"readPerm": "brNewsReadAccess",
-			"writePerm": "brNewsPostAccess"
-		},
-		"multiple": {
-			"mail": "mail",
-			"ip": "brIP",
-			"forlifes": "brAlias",
-			"groups": "brMemberOf",
-			"school": "brMemberOf",
-			"course": "brMemberOf",
-			"class": "objectClass"
-		}
+		"uid": "uid",
+		"photo": "jpegPhoto",
+		"givenName": "givenName",
+		"lastName": "sn",
+		"fullName": "cn",
+		"cleanFullName": "gecos",
+		"nickname": "displayName",
+		"birthdate": "brBirthdate",
+		"nationality": "country",
+		"promotion": "brPromo",
+		"phone": "telephoneNumber",
+		"adress": "brRoom",
+		"id": "uidNumber",
+		"sport": "brMemberOf",
+		"password": "userPassword",
+		"idNum": "gidNumber",
+		"directory": "homeDirectory",
+		"login": "loginShell",
+		"readPerm": "brNewsReadAccess",
+		"writePerm": "brNewsPostAccess",
+		"mails": "mail",
+		"ips": "brIP",
+		"forlifes": "brAlias",
+		"groups": "brMemberOf",
+		"schools": "brMemberOf",
+		"courses": "brMemberOf",
+		"classes": "objectClass"
 	},
 	"comment_4": "Placeholders et indications de contenu de certains champs du LDAP généré par frankiz pour les groupes",
 	"group": {
-		"single": {
-			"name": "cn",
-			"nickname": "brAlias",
-			"type": "brNS",
-			"idNumber": "uidNumber",
-			"idNumber2": "gidNumber",
-			"login": "loginShell",
-			"password": "userPassword",
-			"directory": "homeDirectory",
-			"cleanFullName": "gecos"
-		},
-		"multiple": {
-			"member": "restrictedMemberUid",
-			"admin": "memberUid",
-			"class": "objectClass"
-		}
+		"gid": "uid",
+		"name": "brAlias",
+		"type": "brNS",
+		"members": "restrictedMemberUid",
+		"admins": "memberUid",
+		"adress":"cn",
+		"idNumber": "uidNumber",
+		"idNumber2": "gidNumber",
+		"login": "loginShell",
+		"password": "userPassword",
+		"directory": "homeDirectory",
+		"cleanFullName": "gecos",
+		"classes": "objectClass"
 	},
 	"sessionSecret":"ozyNMHdT,WFTu|t"
 }
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index b79e367..02a7868 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,21 +20,157 @@
       "integrity": "sha512-QAZIFrfVRkjvMkUHIQKZXZ3La0V5t12w5PWrhihYEabHwzIZV/txQd/kSYHgYPXC4s5OURxsXZop9f0BzI2QIQ=="
     },
     "@babel/cli": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.1.2.tgz",
-      "integrity": "sha512-K3WDlpBPGpoW11SLKFEBhMsITomPovsrZ/wnM3y+WStbytukDXC0OBic3yQp+j058QUw0+R/jfx2obwp1fOzcA==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/cli/-/cli-7.0.0-beta.40.tgz",
+      "integrity": "sha512-7f2pWUlklOYn5USkVPlDw1yX71WsgP8EG7CTn17j4ydtGnYtD+nptTMM4J3EaRgILOgfesVkSOV+lIOnUVOAlg==",
       "dev": true,
       "requires": {
-        "chokidar": "^2.0.3",
+        "chokidar": "^1.6.1",
         "commander": "^2.8.1",
         "convert-source-map": "^1.1.0",
-        "fs-readdir-recursive": "^1.1.0",
+        "fs-readdir-recursive": "^1.0.0",
         "glob": "^7.0.0",
-        "lodash": "^4.17.10",
-        "mkdirp": "^0.5.1",
+        "lodash": "^4.2.0",
         "output-file-sync": "^2.0.0",
-        "slash": "^2.0.0",
+        "slash": "^1.0.0",
         "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+          "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "micromatch": "^2.1.5",
+            "normalize-path": "^2.0.0"
+          }
+        },
+        "arr-diff": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+          "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "arr-flatten": "^1.0.1"
+          }
+        },
+        "array-unique": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+          "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+          "dev": true,
+          "optional": true
+        },
+        "braces": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+          "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "expand-range": "^1.8.1",
+            "preserve": "^0.2.0",
+            "repeat-element": "^1.1.2"
+          }
+        },
+        "chokidar": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+          "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "anymatch": "^1.3.0",
+            "async-each": "^1.0.0",
+            "fsevents": "^1.0.0",
+            "glob-parent": "^2.0.0",
+            "inherits": "^2.0.1",
+            "is-binary-path": "^1.0.0",
+            "is-glob": "^2.0.0",
+            "path-is-absolute": "^1.0.0",
+            "readdirp": "^2.0.0"
+          }
+        },
+        "expand-brackets": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+          "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-posix-bracket": "^0.1.0"
+          }
+        },
+        "extglob": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+          "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        },
+        "glob-parent": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+          "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-glob": "^2.0.0"
+          }
+        },
+        "is-extglob": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+          "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+          "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        },
+        "micromatch": {
+          "version": "2.3.11",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+          "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "arr-diff": "^2.0.0",
+            "array-unique": "^0.2.1",
+            "braces": "^1.8.2",
+            "expand-brackets": "^0.1.4",
+            "extglob": "^0.3.1",
+            "filename-regex": "^2.0.0",
+            "is-extglob": "^1.0.0",
+            "is-glob": "^2.0.1",
+            "kind-of": "^3.0.2",
+            "normalize-path": "^2.0.1",
+            "object.omit": "^2.0.0",
+            "parse-glob": "^3.0.4",
+            "regex-cache": "^0.4.2"
+          }
+        }
       }
     },
     "@babel/code-frame": {
@@ -47,133 +183,214 @@
       }
     },
     "@babel/core": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.1.2.tgz",
-      "integrity": "sha512-IFeSSnjXdhDaoysIlev//UzHZbdEmm7D0EIH2qtse9xK7mXEZQpYjs2P00XlP1qYsYvid79p+Zgg6tz1mp6iVw==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.0.0",
-        "@babel/generator": "^7.1.2",
-        "@babel/helpers": "^7.1.2",
-        "@babel/parser": "^7.1.2",
-        "@babel/template": "^7.1.2",
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.1.2",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/core/-/core-7.0.0-beta.40.tgz",
+      "integrity": "sha512-jJMjn/EMg89xDGv7uq4BoFg+fHEchSeqNc9YUMnGuAi/FWKBkSsDbhh2y5euw4qaGOFD2jw1le0rvCu5gPUc6Q==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "7.0.0-beta.40",
+        "@babel/generator": "7.0.0-beta.40",
+        "@babel/helpers": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40",
+        "babylon": "7.0.0-beta.40",
         "convert-source-map": "^1.1.0",
-        "debug": "^3.1.0",
+        "debug": "^3.0.1",
         "json5": "^0.5.0",
-        "lodash": "^4.17.10",
+        "lodash": "^4.2.0",
+        "micromatch": "^2.3.11",
         "resolve": "^1.3.2",
-        "semver": "^5.4.1",
         "source-map": "^0.5.0"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/generator": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.1.3.tgz",
-          "integrity": "sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.1.3",
+            "@babel/types": "7.0.0-beta.40",
             "jsesc": "^2.5.1",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "source-map": "^0.5.0",
             "trim-right": "^1.0.1"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/traverse": {
-          "version": "7.1.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.4.tgz",
-          "integrity": "sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/generator": "^7.1.3",
-            "@babel/helper-function-name": "^7.1.0",
-            "@babel/helper-split-export-declaration": "^7.0.0",
-            "@babel/parser": "^7.1.3",
-            "@babel/types": "^7.1.3",
-            "debug": "^3.1.0",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
             "globals": "^11.1.0",
-            "lodash": "^4.17.10"
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "arr-diff": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+          "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "^1.0.1"
+          }
+        },
+        "array-unique": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+          "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+          "dev": true
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        },
+        "braces": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+          "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+          "dev": true,
+          "requires": {
+            "expand-range": "^1.8.1",
+            "preserve": "^0.2.0",
+            "repeat-element": "^1.1.2"
+          }
+        },
+        "expand-brackets": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+          "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+          "dev": true,
+          "requires": {
+            "is-posix-bracket": "^0.1.0"
+          }
+        },
+        "extglob": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+          "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        },
+        "is-extglob": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+          "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
           "dev": true
+        },
+        "is-glob": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+          "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        },
+        "micromatch": {
+          "version": "2.3.11",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+          "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+          "dev": true,
+          "requires": {
+            "arr-diff": "^2.0.0",
+            "array-unique": "^0.2.1",
+            "braces": "^1.8.2",
+            "expand-brackets": "^0.1.4",
+            "extglob": "^0.3.1",
+            "filename-regex": "^2.0.0",
+            "is-extglob": "^1.0.0",
+            "is-glob": "^2.0.1",
+            "kind-of": "^3.0.2",
+            "normalize-path": "^2.0.1",
+            "object.omit": "^2.0.0",
+            "parse-glob": "^3.0.4",
+            "regex-cache": "^0.4.2"
+          }
         }
       }
     },
@@ -191,366 +408,351 @@
       }
     },
     "@babel/helper-annotate-as-pure": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz",
-      "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.40.tgz",
+      "integrity": "sha512-bJd92d70QTlcqCO9WiE8C94r7NwVzJx1V6Yz7rYi4IQ53P0jbh9jjKL2zl8YoU2S8M/KX1jpu+yIgXbx+LOruQ==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         }
       }
     },
     "@babel/helper-builder-binary-assignment-operator-visitor": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz",
-      "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.40.tgz",
+      "integrity": "sha512-rMfjqkQrfHsA3ppMc2MsICoMqXH1b0BD77fTr4Kf+aUzEt5GSx5ZP5aNYlCqaPzhafg3znEEg/LVeq2EyGY8JQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-explode-assignable-expression": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/helper-explode-assignable-expression": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         }
       }
     },
     "@babel/helper-call-delegate": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz",
-      "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.40.tgz",
+      "integrity": "sha512-kfLlTpTayyCwj3/Rq4zDaK85GVPzRIR433QLhuNb0qjJfMQgLit2UEfBHUPPMRvKlb0FelrlXGTxXfsHLmfgzw==",
       "dev": true,
       "requires": {
-        "@babel/helper-hoist-variables": "^7.0.0",
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/helper-hoist-variables": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/generator": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.1.3.tgz",
-          "integrity": "sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.1.3",
+            "@babel/types": "7.0.0-beta.40",
             "jsesc": "^2.5.1",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "source-map": "^0.5.0",
             "trim-right": "^1.0.1"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/traverse": {
-          "version": "7.1.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.4.tgz",
-          "integrity": "sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/generator": "^7.1.3",
-            "@babel/helper-function-name": "^7.1.0",
-            "@babel/helper-split-export-declaration": "^7.0.0",
-            "@babel/parser": "^7.1.3",
-            "@babel/types": "^7.1.3",
-            "debug": "^3.1.0",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
             "globals": "^11.1.0",
-            "lodash": "^4.17.10"
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
     "@babel/helper-define-map": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz",
-      "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.40.tgz",
+      "integrity": "sha512-hDg3sFSAxYQ/CSXzIBzGeNRD4yp89MkC3wkwvGBH80LXobL6csEdQpzCPhwpL0K8RNB07awRnck1OtPqjeCpgA==",
       "dev": true,
       "requires": {
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/types": "^7.0.0",
-        "lodash": "^4.17.10"
+        "@babel/helper-function-name": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40",
+        "lodash": "^4.2.0"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
     "@babel/helper-explode-assignable-expression": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz",
-      "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.40.tgz",
+      "integrity": "sha512-EUbu+uVNtHVp9emICjYO5wYodqWnSTx/s4Hfk++7IdnPTQi7UA9F/tPXf1GS8BLazlWc9tDwQ2aHFQLheHEXHw==",
       "dev": true,
       "requires": {
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/generator": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.1.3.tgz",
-          "integrity": "sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.1.3",
+            "@babel/types": "7.0.0-beta.40",
             "jsesc": "^2.5.1",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "source-map": "^0.5.0",
             "trim-right": "^1.0.1"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/traverse": {
-          "version": "7.1.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.4.tgz",
-          "integrity": "sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/generator": "^7.1.3",
-            "@babel/helper-function-name": "^7.1.0",
-            "@babel/helper-split-export-declaration": "^7.0.0",
-            "@babel/parser": "^7.1.3",
-            "@babel/types": "^7.1.3",
-            "debug": "^3.1.0",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
             "globals": "^11.1.0",
-            "lodash": "^4.17.10"
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
@@ -576,480 +778,430 @@
       }
     },
     "@babel/helper-hoist-variables": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz",
-      "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.0.0"
-      },
-      "dependencies": {
-        "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
-          "dev": true,
-          "requires": {
-            "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
-            "to-fast-properties": "^2.0.0"
-          }
-        }
-      }
-    },
-    "@babel/helper-member-expression-to-functions": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz",
-      "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.40.tgz",
+      "integrity": "sha512-ghnJxUUEmqK8mssF7Y7R5jNzF5xDu4hmWQ1aZghZtLNJSymmj3HrXCLl5m1dBYpq9gGk7TlZK8stIvIJsCGmTQ==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         }
       }
     },
     "@babel/helper-module-imports": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz",
-      "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.40.tgz",
+      "integrity": "sha512-QFOskAKWbqJSBbGIl/Y1igJI4mW0A+wD5NFqsgDJj85KSvj/dHM4wNGIeqCi85nN9aMa4DgTBBrzUK4zSMsN2Q==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "7.0.0-beta.40",
+        "lodash": "^4.2.0"
       },
       "dependencies": {
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         }
       }
     },
     "@babel/helper-module-transforms": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz",
-      "integrity": "sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.40.tgz",
+      "integrity": "sha512-1H7cBk7kUWJpTepPH77TIRGwKILRGpu1yXmz1OjOruR6y2z0qfbp7ZzzZ3/xg6NlLDENLArEyO2+J0mO+VyQsg==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-imports": "^7.0.0",
-        "@babel/helper-simple-access": "^7.1.0",
-        "@babel/helper-split-export-declaration": "^7.0.0",
-        "@babel/template": "^7.1.0",
-        "@babel/types": "^7.0.0",
-        "lodash": "^4.17.10"
+        "@babel/helper-module-imports": "7.0.0-beta.40",
+        "@babel/helper-simple-access": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40",
+        "lodash": "^4.2.0"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
-          "dev": true,
-          "requires": {
-            "@babel/highlight": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
     "@babel/helper-optimise-call-expression": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz",
-      "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.40.tgz",
+      "integrity": "sha512-2f4ZKEkvdnKiTUA/Nhju+oEoRcyHcpf6lFuQI5cxbo1Toxqa8E9HBO5tiOWwlIwuak7RZPYSnxnrJQy/0d4YUw==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         }
       }
     },
-    "@babel/helper-plugin-utils": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz",
-      "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==",
-      "dev": true
-    },
     "@babel/helper-regex": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz",
-      "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-75zi8hZSdWLT7upmEyAemfN0hJ7522svItPGbIj4Pi2T/C5vbgNFXLy8o/iOCX4FzB+yVKhz0zWC3SzN9hyigA==",
       "dev": true,
       "requires": {
-        "lodash": "^4.17.10"
+        "lodash": "^4.2.0"
       }
     },
     "@babel/helper-remap-async-to-generator": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz",
-      "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.40.tgz",
+      "integrity": "sha512-RISz7EebAqaf4ofdG9LdVNfeqhK+JlFYJxvqCGMcS+Pyz84dA41MxgtjrRQdT85be1lZLI2OArvD7zDrj1psag==",
       "dev": true,
       "requires": {
-        "@babel/helper-annotate-as-pure": "^7.0.0",
-        "@babel/helper-wrap-function": "^7.1.0",
-        "@babel/template": "^7.1.0",
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/helper-annotate-as-pure": "7.0.0-beta.40",
+        "@babel/helper-wrap-function": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/generator": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.1.3.tgz",
-          "integrity": "sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.1.3",
+            "@babel/types": "7.0.0-beta.40",
             "jsesc": "^2.5.1",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "source-map": "^0.5.0",
             "trim-right": "^1.0.1"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/traverse": {
-          "version": "7.1.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.4.tgz",
-          "integrity": "sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/generator": "^7.1.3",
-            "@babel/helper-function-name": "^7.1.0",
-            "@babel/helper-split-export-declaration": "^7.0.0",
-            "@babel/parser": "^7.1.3",
-            "@babel/types": "^7.1.3",
-            "debug": "^3.1.0",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
             "globals": "^11.1.0",
-            "lodash": "^4.17.10"
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
     "@babel/helper-replace-supers": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz",
-      "integrity": "sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.40.tgz",
+      "integrity": "sha512-Nu/5wpUV3rG35RzOq/upZlm61cP0lSAtmNkJLFfO5k2zOGCiHRczD1Y/xKqYOMl5f2iZmYw9fANi1jE4odMIIQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-member-expression-to-functions": "^7.0.0",
-        "@babel/helper-optimise-call-expression": "^7.0.0",
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/helper-optimise-call-expression": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/generator": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.1.3.tgz",
-          "integrity": "sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.1.3",
+            "@babel/types": "7.0.0-beta.40",
             "jsesc": "^2.5.1",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "source-map": "^0.5.0",
             "trim-right": "^1.0.1"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/traverse": {
-          "version": "7.1.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.4.tgz",
-          "integrity": "sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/generator": "^7.1.3",
-            "@babel/helper-function-name": "^7.1.0",
-            "@babel/helper-split-export-declaration": "^7.0.0",
-            "@babel/parser": "^7.1.3",
-            "@babel/types": "^7.1.3",
-            "debug": "^3.1.0",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
             "globals": "^11.1.0",
-            "lodash": "^4.17.10"
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
     "@babel/helper-simple-access": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz",
-      "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.40.tgz",
+      "integrity": "sha512-hEKOIXUZFOiyqUPiGydGc+Jr0s8mVCFrD1OtAw2BDkXf1BaR+PxVEVcBAWcJVLOjqrr7oVZL9SENjR4B/Y+yEw==",
       "dev": true,
       "requires": {
-        "@babel/template": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40",
+        "lodash": "^4.2.0"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
@@ -1064,242 +1216,226 @@
       }
     },
     "@babel/helper-wrap-function": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz",
-      "integrity": "sha512-R6HU3dete+rwsdAfrOzTlE9Mcpk4RjU3aX3gi9grtmugQY0u79X7eogUvfXA5sI81Mfq1cn6AgxihfN33STjJA==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.40.tgz",
+      "integrity": "sha512-VBXE/uGQuZC9IaYufa3eCoT5ZqcCPv21Uhs/vo4ZqNRDX5QemYEkgDj5SmV2p73bhC66jDwUHaQHKQIiW7ExxA==",
       "dev": true,
       "requires": {
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/template": "^7.1.0",
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/helper-function-name": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/generator": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.1.3.tgz",
-          "integrity": "sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.1.3",
+            "@babel/types": "7.0.0-beta.40",
             "jsesc": "^2.5.1",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "source-map": "^0.5.0",
             "trim-right": "^1.0.1"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/traverse": {
-          "version": "7.1.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.4.tgz",
-          "integrity": "sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/generator": "^7.1.3",
-            "@babel/helper-function-name": "^7.1.0",
-            "@babel/helper-split-export-declaration": "^7.0.0",
-            "@babel/parser": "^7.1.3",
-            "@babel/types": "^7.1.3",
-            "debug": "^3.1.0",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
             "globals": "^11.1.0",
-            "lodash": "^4.17.10"
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
     "@babel/helpers": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.1.2.tgz",
-      "integrity": "sha512-Myc3pUE8eswD73aWcartxB16K6CGmHDv9KxOmD2CeOs/FaEAQodr3VYGmlvOmog60vNQ2w8QbatuahepZwrHiA==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helpers/-/helpers-7.0.0-beta.40.tgz",
+      "integrity": "sha512-NK/mM/I16inThgXmKPxoqrg+N6OCLt+e9Zsmy8TJ93/zMx4Eddd679I231YwDP2J1Z12UgkfWCLbbvauU5TLlQ==",
       "dev": true,
       "requires": {
-        "@babel/template": "^7.1.2",
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.1.2"
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/generator": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.1.3.tgz",
-          "integrity": "sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.1.3",
+            "@babel/types": "7.0.0-beta.40",
             "jsesc": "^2.5.1",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "source-map": "^0.5.0",
             "trim-right": "^1.0.1"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/traverse": {
-          "version": "7.1.4",
-          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.4.tgz",
-          "integrity": "sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q==",
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/generator": "^7.1.3",
-            "@babel/helper-function-name": "^7.1.0",
-            "@babel/helper-split-export-declaration": "^7.0.0",
-            "@babel/parser": "^7.1.3",
-            "@babel/types": "^7.1.3",
-            "debug": "^3.1.0",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
             "globals": "^11.1.0",
-            "lodash": "^4.17.10"
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
@@ -1315,709 +1451,600 @@
         "js-tokens": "^3.0.0"
       }
     },
-    "@babel/parser": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.1.3.tgz",
-      "integrity": "sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w==",
-      "dev": true
-    },
     "@babel/plugin-proposal-async-generator-functions": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz",
-      "integrity": "sha512-Fq803F3Jcxo20MXUSDdmZZXrPe6BWyGcWBPPNB/M7WaUYESKDeKMOGIxEzQOjGSmW/NWb6UaPZrtTB2ekhB/ew==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.40.tgz",
+      "integrity": "sha512-DU9JstbqQRAPhbW3Pk0yrEJA8GIiIDdylrnIuPI9x01jAwijxJfRwi6FbUAZUbS+3mzAAM5ALXUJkF1i1R5qbQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-remap-async-to-generator": "^7.1.0",
-        "@babel/plugin-syntax-async-generators": "^7.0.0"
+        "@babel/helper-remap-async-to-generator": "7.0.0-beta.40",
+        "@babel/plugin-syntax-async-generators": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-proposal-class-properties": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.1.0.tgz",
-      "integrity": "sha512-/PCJWN+CKt5v1xcGn4vnuu13QDoV+P7NcICP44BoonAJoPSGwVkgrXihFIQGiEjjPlUDBIw1cM7wYFLARS2/hw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.40.tgz",
+      "integrity": "sha512-Sg9dQw/4TpYKdTO5wx+AxxICXEraBbdhDUFl9tJfJYgz4grJm+UR2xMXbBO6fGRyBlFLMqQQQcY7Olk5iN6qNA==",
       "dev": true,
       "requires": {
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/helper-member-expression-to-functions": "^7.0.0",
-        "@babel/helper-optimise-call-expression": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-replace-supers": "^7.1.0",
-        "@babel/plugin-syntax-class-properties": "^7.0.0"
+        "@babel/helper-function-name": "7.0.0-beta.40",
+        "@babel/plugin-syntax-class-properties": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
-    "@babel/plugin-proposal-json-strings": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz",
-      "integrity": "sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-syntax-json-strings": "^7.0.0"
-      }
-    },
     "@babel/plugin-proposal-object-rest-spread": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz",
-      "integrity": "sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.40.tgz",
+      "integrity": "sha512-nsQEWEvBgDcxYPBhmeIHqIXVVkPLQJBTD/bAdCMFhVe0vQdOR/px5E+rMsbP+9CywqV3AJ7PngYadnPgiuu4sg==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-syntax-object-rest-spread": "^7.0.0"
+        "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-proposal-optional-catch-binding": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz",
-      "integrity": "sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0-beta.40.tgz",
+      "integrity": "sha512-GKKY7LDS3Z2iAVsM0KP745LAML8jKUdFqD+rGLa6F4Q9pEqDh3pjbL8eqiWLv/g/phpuCdvjaj+4wmUHi/E5eg==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.0.0"
+        "@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-proposal-unicode-property-regex": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz",
-      "integrity": "sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-BJlgIZcqodpkgNLOsKtkprA3zeXhg0O9Hru+IIaDVhcrZnkIIMVsdIG6gY5cKCAnpKFVN4kloQRTB61qYdKueA==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-regex": "^7.0.0",
-        "regexpu-core": "^4.2.0"
+        "@babel/helper-regex": "7.0.0-beta.40",
+        "regexpu-core": "^4.1.3"
       }
     },
     "@babel/plugin-syntax-async-generators": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz",
-      "integrity": "sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.40.tgz",
+      "integrity": "sha512-UczObsgk1A4DaSMqTj59iETtmtuiXdBMs/1WBpy6LvLtf8AdjO/bZ2IbvrwKR5gEp8xJxBgzNq2sfK8RUsQBsQ==",
+      "dev": true
     },
     "@babel/plugin-syntax-class-properties": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0.tgz",
-      "integrity": "sha512-cR12g0Qzn4sgkjrbrzWy2GE7m9vMl/sFkqZ3gIpAQdrvPDnLM8180i+ANDFIXfjHo9aqp0ccJlQ0QNZcFUbf9w==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
-    },
-    "@babel/plugin-syntax-json-strings": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz",
-      "integrity": "sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.40.tgz",
+      "integrity": "sha512-JQUvaacmUpzXDU6BVE1l7hMES6AOJLAyGuEapTop3hD1BDvKwLOIrzwZxawBmp3GOA02S3m4VdUyIfWS5DATjw==",
+      "dev": true
     },
     "@babel/plugin-syntax-object-rest-spread": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz",
-      "integrity": "sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.40.tgz",
+      "integrity": "sha512-LY96LEXC+qxuiOcoqrkrsyEUaD95gS7AQE7nZJ/lZBGG14h4cJhc+T0FYdJpVKqhqNuEqVHsJV9xfCYHI4Ksug==",
+      "dev": true
     },
-    "@babel/plugin-syntax-optional-catch-binding": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz",
-      "integrity": "sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+    "@babel/plugin-syntax-optional-catch-binding": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-beta.40.tgz",
+      "integrity": "sha512-YP2Zqhi6r5mnp6LALz19pvF7szhEzBFybw4KqGFj6OwGmfF1nrvCG3h6cOTRhIKSwkfM7IlqGZm+GBhbYRYxGA==",
+      "dev": true
     },
     "@babel/plugin-syntax-typescript": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0.tgz",
-      "integrity": "sha512-5fxmdqiAQVQTIS+KSvYeZuTt91wKtBTYi6JlIkvbQ6hmO+9fZE81ezxmMiFMIsxE7CdRSgzn7nQ1BChcvK9OpA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0-beta.40.tgz",
+      "integrity": "sha512-o4xi4GbvyV5sG6vLMahVMQbx2qQYpuaC4KCZrwTko/Pd/1ZTO3cSezTgWeTQpCksjt3ngkuqbvvREWwles1GEg==",
+      "dev": true
     },
     "@babel/plugin-transform-arrow-functions": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz",
-      "integrity": "sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.40.tgz",
+      "integrity": "sha512-B6wh62BErLWS3XInOUHhLcqBSK1QGdBph8E2K82EEFgJdQvphy30QXb0vwLUr8YU1efYyZXTsRA0JZ12jcm30Q==",
+      "dev": true
     },
     "@babel/plugin-transform-async-to-generator": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz",
-      "integrity": "sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-beta.40.tgz",
+      "integrity": "sha512-4yTmjiZQw0S6dpnJqj0os0hom2czOAFKPhAuPplDay2zyqzDjbNt3zHFadIRTU4ekTonMb6ghTbMO1vlKcLMiQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-imports": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-remap-async-to-generator": "^7.1.0"
+        "@babel/helper-module-imports": "7.0.0-beta.40",
+        "@babel/helper-remap-async-to-generator": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-block-scoped-functions": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz",
-      "integrity": "sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0-beta.40.tgz",
+      "integrity": "sha512-GC64FqQfGJ5Wt3i0zSMcwRxmnZwgrx8fVLCeONNNm3BlK7Ui5Usuc7WubygM3bDq47UiHfeKo8ih54pr/POsFw==",
+      "dev": true
     },
     "@babel/plugin-transform-block-scoping": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0.tgz",
-      "integrity": "sha512-GWEMCrmHQcYWISilUrk9GDqH4enf3UmhOEbNbNrlNAX1ssH3MsS1xLOS6rdjRVPgA7XXVPn87tRkdTEoA/dxEg==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.40.tgz",
+      "integrity": "sha512-8QpOK9lXdzrq1QIrP3Hfx/BmGPaCKjBORd2QSjdghPNNRlQFZmO2l3kb0I6yC7w75U1M5q26KvUbAcPrE68E4w==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "lodash": "^4.17.10"
+        "lodash": "^4.2.0"
       }
     },
     "@babel/plugin-transform-classes": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz",
-      "integrity": "sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.0.0",
-        "@babel/helper-define-map": "^7.1.0",
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/helper-optimise-call-expression": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-replace-supers": "^7.1.0",
-        "@babel/helper-split-export-declaration": "^7.0.0",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.40.tgz",
+      "integrity": "sha512-yjViyoOYJtt2vLDai8jluxl9quOtq/Xq4GTjT9uzy+mOfUTE77dcJySMGkWHE52Mu3n0TSI09ENBFYykpvXXDw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "7.0.0-beta.40",
+        "@babel/helper-define-map": "7.0.0-beta.40",
+        "@babel/helper-function-name": "7.0.0-beta.40",
+        "@babel/helper-optimise-call-expression": "7.0.0-beta.40",
+        "@babel/helper-replace-supers": "7.0.0-beta.40",
         "globals": "^11.1.0"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.0.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
-          "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
     "@babel/plugin-transform-computed-properties": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz",
-      "integrity": "sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.40.tgz",
+      "integrity": "sha512-1VBpE+6YN4bj72MtbQoIwXZxoI5VfPLutQ5uhOx/tIrjf1KbLKsFR0epPPGx4nZ13u++lUR8CjUFUHGJ6RJirA==",
+      "dev": true
     },
     "@babel/plugin-transform-destructuring": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz",
-      "integrity": "sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.40.tgz",
+      "integrity": "sha512-/FJq+WUAw4R5kg+2XWkmk0rDJqVs76rNNSIPpxeE0SiJvp8tvou7y8u0D1IhoO29ZgC+53jbdL+MkVN7mrH/iQ==",
+      "dev": true
     },
     "@babel/plugin-transform-dotall-regex": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz",
-      "integrity": "sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-5npi7X6QGNWWfXxVBMQl+fEAn0LceNNFT139yaGRkyWZtUXmueFLgXKsa9dY2DhuEis29KuZrwGcmGSQWnEmtg==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-regex": "^7.0.0",
+        "@babel/helper-regex": "7.0.0-beta.40",
         "regexpu-core": "^4.1.3"
       }
     },
     "@babel/plugin-transform-duplicate-keys": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz",
-      "integrity": "sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0-beta.40.tgz",
+      "integrity": "sha512-rxEyRbU/iEGR99oBMoer5QeGWLMhT3Kq4a8B03DFLCBpGLv3XirpSGC/Ys1YhUKAmEio4jIcVVI8dRBbcVeyDw==",
+      "dev": true
     },
     "@babel/plugin-transform-exponentiation-operator": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz",
-      "integrity": "sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.40.tgz",
+      "integrity": "sha512-nh9qIA4P1wQczihazVOvTpkl2EBfoSMfkM6/21p8NBY4GxZJcEwT1O1nke/+RLludUekHqXHGH+9ekfEfLwKRQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-builder-binary-assignment-operator-visitor": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-for-of": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz",
-      "integrity": "sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.40.tgz",
+      "integrity": "sha512-ArDbLAGMzI++G5Ut8HIbLvnAxZNOC5tFzMXiud51JJTHRaeFB7AwX+duY9x/Hu/KypISXjels3BYVYCV/EH+ow==",
+      "dev": true
     },
     "@babel/plugin-transform-function-name": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz",
-      "integrity": "sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.40.tgz",
+      "integrity": "sha512-wvpswFciLQ2eAnHAs6/NSWymPg88LhHH87BljjXDxNnyGBzckip/iEa051Dz6lDumVUUjXLukw3D2fv5NBitVA==",
       "dev": true,
       "requires": {
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-function-name": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/code-frame": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-          "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
           "dev": true,
           "requires": {
-            "@babel/highlight": "^7.0.0"
+            "@babel/highlight": "7.0.0-beta.40"
           }
         },
         "@babel/helper-function-name": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-          "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
           "dev": true,
           "requires": {
-            "@babel/helper-get-function-arity": "^7.0.0",
-            "@babel/template": "^7.1.0",
-            "@babel/types": "^7.0.0"
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/highlight": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-          "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
           "dev": true,
           "requires": {
             "chalk": "^2.0.0",
             "esutils": "^2.0.2",
-            "js-tokens": "^4.0.0"
+            "js-tokens": "^3.0.0"
           }
         },
         "@babel/template": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz",
-          "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
           "dev": true,
           "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "@babel/parser": "^7.1.2",
-            "@babel/types": "^7.1.2"
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         },
-        "js-tokens": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
           "dev": true
         }
       }
     },
     "@babel/plugin-transform-literals": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz",
-      "integrity": "sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.40.tgz",
+      "integrity": "sha512-p7VlTod2r7srx0uKVrKqMJR1f6iyvDAnlLdTEDGrLHpP9pXXvIc/bP8xZTxVPn+IziSFh6FvOzHXXLMtnRKnow==",
+      "dev": true
     },
     "@babel/plugin-transform-modules-amd": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz",
-      "integrity": "sha512-wt8P+xQ85rrnGNr2x1iV3DW32W8zrB6ctuBkYBbf5/ZzJY99Ob4MFgsZDFgczNU76iy9PWsy4EuxOliDjdKw6A==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0-beta.40.tgz",
+      "integrity": "sha512-o/XTve9C+M9203MVxGRBOXNx4f9DZGiPLbwPPeDobdtw3NKHUCymFNbh9xxMJy0MPMEe8JldxbVwGy2f8DY/3w==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-transforms": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-module-transforms": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-modules-commonjs": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz",
-      "integrity": "sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.40.tgz",
+      "integrity": "sha512-1kRhaQP3K9kRiJhhLpP7J5NsMV+SiKWSsli6TUR6uxbuHHNAleRtlsZ76JgCRMaufBgPMLxq5pp7yibUhwTn8w==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-transforms": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-simple-access": "^7.1.0"
+        "@babel/helper-module-transforms": "7.0.0-beta.40",
+        "@babel/helper-simple-access": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-modules-systemjs": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.1.3.tgz",
-      "integrity": "sha512-PvTxgjxQAq4pvVUZF3mD5gEtVDuId8NtWkJsZLEJZMZAW3TvgQl1pmydLLN1bM8huHFVVU43lf0uvjQj9FRkKw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0-beta.40.tgz",
+      "integrity": "sha512-q5IpFXNlzrK2ObpHkH5jzTCqRVzoNzmH8RoE8ZHQvLLiaIT346u8ynNv/BH1ltA49SPUPWyYpA+Z7OqCM4d3NA==",
       "dev": true,
       "requires": {
-        "@babel/helper-hoist-variables": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-hoist-variables": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-modules-umd": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz",
-      "integrity": "sha512-enrRtn5TfRhMmbRwm7F8qOj0qEYByqUvTttPEGimcBH4CJHphjyK1Vg7sdU7JjeEmgSpM890IT/efS2nMHwYig==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0-beta.40.tgz",
+      "integrity": "sha512-LHKqJFwo7x/CeEwjLyUE99SlG/kbTl8LS1DQ26fWctVnW5JuPt3hwYrggnmo1L/g/dal7EP2IL56+UezDMpJUQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-transforms": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-module-transforms": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-new-target": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz",
-      "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0-beta.40.tgz",
+      "integrity": "sha512-t4ivwZVGrVf1bhLgHcgaLhFH4loZhV5WmEKKNPEe7QnGikJBibrLmggOM1w5s6BMsHj03+j0rxUmcKLmGlC/fg==",
+      "dev": true
     },
     "@babel/plugin-transform-object-super": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz",
-      "integrity": "sha512-/O02Je1CRTSk2SSJaq0xjwQ8hG4zhZGNjE8psTsSNPXyLRCODv7/PBozqT5AmQMzp7MI3ndvMhGdqp9c96tTEw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0-beta.40.tgz",
+      "integrity": "sha512-a9kXy4amuvAz7eFuntXiyjg0eKXej1FH++xQg37ugh24zozD0cmfr3pvRbYOGlmbmOeZWJnlq+O6X8BSfLSycw==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-replace-supers": "^7.1.0"
+        "@babel/helper-replace-supers": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-parameters": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz",
-      "integrity": "sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.40.tgz",
+      "integrity": "sha512-JShFDeKEzwwTB+pHcUuLdX9zPi98sRekvtdCEOt8UoF5pzW02k1XdsVOckp/PzcEdoGAgZiiI1PFkJZ+xanfPg==",
       "dev": true,
       "requires": {
-        "@babel/helper-call-delegate": "^7.1.0",
-        "@babel/helper-get-function-arity": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-call-delegate": "7.0.0-beta.40",
+        "@babel/helper-get-function-arity": "7.0.0-beta.40"
       },
       "dependencies": {
         "@babel/helper-get-function-arity": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-          "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
           "dev": true,
           "requires": {
-            "@babel/types": "^7.0.0"
+            "@babel/types": "7.0.0-beta.40"
           }
         },
         "@babel/types": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.1.3.tgz",
-          "integrity": "sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA==",
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
           "dev": true,
           "requires": {
             "esutils": "^2.0.2",
-            "lodash": "^4.17.10",
+            "lodash": "^4.2.0",
             "to-fast-properties": "^2.0.0"
           }
         }
       }
     },
     "@babel/plugin-transform-regenerator": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz",
-      "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.40.tgz",
+      "integrity": "sha512-hFj52wAXbEpXwwfKsMol5Y967D3L8tz46Jin9n/gYPgcNWugvsw6d7g+HknBJ8FzaUESrDruFRkGPXgD+FyjvQ==",
       "dev": true,
       "requires": {
-        "regenerator-transform": "^0.13.3"
+        "regenerator-transform": "^0.12.3"
       }
     },
     "@babel/plugin-transform-shorthand-properties": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz",
-      "integrity": "sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.40.tgz",
+      "integrity": "sha512-1leHn9ST0PKFHwH7klJqGA76YPoqs3cR5zeJK6YGZETeX89YiAVtR+5JTSGhfI/1RR0Vcg9Tl1LnPpf7LmYlng==",
+      "dev": true
     },
     "@babel/plugin-transform-spread": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz",
-      "integrity": "sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.40.tgz",
+      "integrity": "sha512-RPrIpV+h8OqoqyMic7CNeM8TdSDk7ec+T6jM97vMb9XQQrRInAUWlwWvG6d36v72xobFtHoPA28VN/0aVsbQDg==",
+      "dev": true
     },
     "@babel/plugin-transform-sticky-regex": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz",
-      "integrity": "sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-dJPUaV2D5SwSXypaDFRJd+LIhabeaWhZ3McmNo0COn+lBINJ9iL7mYuPxnqwhM/KoBNv+vYIoFFZzT/I27K6AQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-regex": "^7.0.0"
+        "@babel/helper-regex": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-template-literals": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz",
-      "integrity": "sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.40.tgz",
+      "integrity": "sha512-ScGHntym1y5FweT751OJxGW4rydxdLA9BwkHfJ5o6RcCoq+LRubDeGu2HeuX4SMEvAw0MnZeSk8vw5TwIOzEIQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-annotate-as-pure": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-annotate-as-pure": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-typeof-symbol": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz",
-      "integrity": "sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
-      }
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0-beta.40.tgz",
+      "integrity": "sha512-y+mXC0tIlTZj04ZD9326grEIvFjI/IeLSIVVKMIf8nSodLDCgipuM6zXhxqXVvjcTrvvUKuxPrvPeSuht0eeMg==",
+      "dev": true
     },
     "@babel/plugin-transform-typescript": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.1.0.tgz",
-      "integrity": "sha512-TOTtVeT+fekAesiCHnPz+PSkYSdOSLyLn42DI45nxg6iCdlQY6LIj/tYqpMB0y+YicoTUiYiXqF8rG6SKfhw6Q==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.0.0-beta.40.tgz",
+      "integrity": "sha512-7MLJ5DU6j8B76yYrfhQvV4LKXOX5AQz4Z+SlZy7tUEiARilztqE1vBymju5FGBNCsWaE27lkHSaSXhtIBCjn6g==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-syntax-typescript": "^7.0.0"
+        "@babel/plugin-syntax-typescript": "7.0.0-beta.40"
       }
     },
     "@babel/plugin-transform-unicode-regex": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz",
-      "integrity": "sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-+eProDq93qiYnXOy+LDSMoKF2lEQVQ+r6DF3ZZXJV5QJ3f2+vwpSqGIQy61sSkVMEaoNtYL/Jy+G8HrWFw9p3w==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-regex": "^7.0.0",
+        "@babel/helper-regex": "7.0.0-beta.40",
         "regexpu-core": "^4.1.3"
       }
     },
     "@babel/preset-env": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.1.0.tgz",
-      "integrity": "sha512-ZLVSynfAoDHB/34A17/JCZbyrzbQj59QC1Anyueb4Bwjh373nVPq5/HMph0z+tCmcDjXDe+DlKQq9ywQuvWrQg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-proposal-async-generator-functions": "^7.1.0",
-        "@babel/plugin-proposal-json-strings": "^7.0.0",
-        "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
-        "@babel/plugin-proposal-optional-catch-binding": "^7.0.0",
-        "@babel/plugin-proposal-unicode-property-regex": "^7.0.0",
-        "@babel/plugin-syntax-async-generators": "^7.0.0",
-        "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.0.0",
-        "@babel/plugin-transform-arrow-functions": "^7.0.0",
-        "@babel/plugin-transform-async-to-generator": "^7.1.0",
-        "@babel/plugin-transform-block-scoped-functions": "^7.0.0",
-        "@babel/plugin-transform-block-scoping": "^7.0.0",
-        "@babel/plugin-transform-classes": "^7.1.0",
-        "@babel/plugin-transform-computed-properties": "^7.0.0",
-        "@babel/plugin-transform-destructuring": "^7.0.0",
-        "@babel/plugin-transform-dotall-regex": "^7.0.0",
-        "@babel/plugin-transform-duplicate-keys": "^7.0.0",
-        "@babel/plugin-transform-exponentiation-operator": "^7.1.0",
-        "@babel/plugin-transform-for-of": "^7.0.0",
-        "@babel/plugin-transform-function-name": "^7.1.0",
-        "@babel/plugin-transform-literals": "^7.0.0",
-        "@babel/plugin-transform-modules-amd": "^7.1.0",
-        "@babel/plugin-transform-modules-commonjs": "^7.1.0",
-        "@babel/plugin-transform-modules-systemjs": "^7.0.0",
-        "@babel/plugin-transform-modules-umd": "^7.1.0",
-        "@babel/plugin-transform-new-target": "^7.0.0",
-        "@babel/plugin-transform-object-super": "^7.1.0",
-        "@babel/plugin-transform-parameters": "^7.1.0",
-        "@babel/plugin-transform-regenerator": "^7.0.0",
-        "@babel/plugin-transform-shorthand-properties": "^7.0.0",
-        "@babel/plugin-transform-spread": "^7.0.0",
-        "@babel/plugin-transform-sticky-regex": "^7.0.0",
-        "@babel/plugin-transform-template-literals": "^7.0.0",
-        "@babel/plugin-transform-typeof-symbol": "^7.0.0",
-        "@babel/plugin-transform-unicode-regex": "^7.0.0",
-        "browserslist": "^4.1.0",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/preset-env/-/preset-env-7.0.0-beta.40.tgz",
+      "integrity": "sha512-IBnkVmaM/K2pHB8RR0tC5oHrPdS4y0RZXrGc+lmfDuj4tgyCAmDBuQ1EWVaLOpWw8fXPwXfX70Vdp65L2df+RQ==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-proposal-async-generator-functions": "7.0.0-beta.40",
+        "@babel/plugin-proposal-object-rest-spread": "7.0.0-beta.40",
+        "@babel/plugin-proposal-optional-catch-binding": "7.0.0-beta.40",
+        "@babel/plugin-proposal-unicode-property-regex": "7.0.0-beta.40",
+        "@babel/plugin-syntax-async-generators": "7.0.0-beta.40",
+        "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.40",
+        "@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.40",
+        "@babel/plugin-transform-arrow-functions": "7.0.0-beta.40",
+        "@babel/plugin-transform-async-to-generator": "7.0.0-beta.40",
+        "@babel/plugin-transform-block-scoped-functions": "7.0.0-beta.40",
+        "@babel/plugin-transform-block-scoping": "7.0.0-beta.40",
+        "@babel/plugin-transform-classes": "7.0.0-beta.40",
+        "@babel/plugin-transform-computed-properties": "7.0.0-beta.40",
+        "@babel/plugin-transform-destructuring": "7.0.0-beta.40",
+        "@babel/plugin-transform-dotall-regex": "7.0.0-beta.40",
+        "@babel/plugin-transform-duplicate-keys": "7.0.0-beta.40",
+        "@babel/plugin-transform-exponentiation-operator": "7.0.0-beta.40",
+        "@babel/plugin-transform-for-of": "7.0.0-beta.40",
+        "@babel/plugin-transform-function-name": "7.0.0-beta.40",
+        "@babel/plugin-transform-literals": "7.0.0-beta.40",
+        "@babel/plugin-transform-modules-amd": "7.0.0-beta.40",
+        "@babel/plugin-transform-modules-commonjs": "7.0.0-beta.40",
+        "@babel/plugin-transform-modules-systemjs": "7.0.0-beta.40",
+        "@babel/plugin-transform-modules-umd": "7.0.0-beta.40",
+        "@babel/plugin-transform-new-target": "7.0.0-beta.40",
+        "@babel/plugin-transform-object-super": "7.0.0-beta.40",
+        "@babel/plugin-transform-parameters": "7.0.0-beta.40",
+        "@babel/plugin-transform-regenerator": "7.0.0-beta.40",
+        "@babel/plugin-transform-shorthand-properties": "7.0.0-beta.40",
+        "@babel/plugin-transform-spread": "7.0.0-beta.40",
+        "@babel/plugin-transform-sticky-regex": "7.0.0-beta.40",
+        "@babel/plugin-transform-template-literals": "7.0.0-beta.40",
+        "@babel/plugin-transform-typeof-symbol": "7.0.0-beta.40",
+        "@babel/plugin-transform-unicode-regex": "7.0.0-beta.40",
+        "browserslist": "^3.0.0",
         "invariant": "^2.2.2",
-        "js-levenshtein": "^1.1.3",
         "semver": "^5.3.0"
       }
     },
     "@babel/preset-typescript": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.1.0.tgz",
-      "integrity": "sha512-LYveByuF9AOM8WrsNne5+N79k1YxjNB6gmpCQsnuSBAcV8QUeB+ZUxQzL7Rz7HksPbahymKkq2qBR+o36ggFZA==",
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.0.0-beta.40.tgz",
+      "integrity": "sha512-G74AcsTo4QPTn6RhZGxG2TapvbeA7SZ7+1dNtn2FZRD5LisJiC33AlBal6MMl3hqBL61xJVcAkNadbtC6PoC1Q==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-transform-typescript": "^7.1.0"
+        "@babel/plugin-transform-typescript": "7.0.0-beta.40"
       }
     },
     "@babel/runtime": {
@@ -2365,9 +2392,9 @@
       "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA=="
     },
     "@types/node": {
-      "version": "10.11.7",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.11.7.tgz",
-      "integrity": "sha512-yOxFfkN9xUFLyvWaeYj90mlqTJ41CsQzWKS3gXdOMOyPVacUsymejKxJ4/pMW7exouubuEeZLJawGgcNGYlTeg=="
+      "version": "10.12.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.0.tgz",
+      "integrity": "sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ=="
     },
     "@types/passport": {
       "version": "0.4.6",
@@ -2725,8 +2752,7 @@
     "ansi-regex": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-      "dev": true
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
     },
     "ansi-styles": {
       "version": "3.2.1",
@@ -3235,8 +3261,7 @@
     "async-each": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
-      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
-      "dev": true
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0="
     },
     "async-limiter": {
       "version": "1.0.0",
@@ -3261,11 +3286,175 @@
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
       "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio="
     },
+    "babel-cli": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz",
+      "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=",
+      "requires": {
+        "babel-core": "^6.26.0",
+        "babel-polyfill": "^6.26.0",
+        "babel-register": "^6.26.0",
+        "babel-runtime": "^6.26.0",
+        "chokidar": "^1.6.1",
+        "commander": "^2.11.0",
+        "convert-source-map": "^1.5.0",
+        "fs-readdir-recursive": "^1.0.0",
+        "glob": "^7.1.2",
+        "lodash": "^4.17.4",
+        "output-file-sync": "^1.1.2",
+        "path-is-absolute": "^1.0.1",
+        "slash": "^1.0.0",
+        "source-map": "^0.5.6",
+        "v8flags": "^2.1.1"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+          "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+          "optional": true,
+          "requires": {
+            "micromatch": "^2.1.5",
+            "normalize-path": "^2.0.0"
+          }
+        },
+        "arr-diff": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+          "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+          "optional": true,
+          "requires": {
+            "arr-flatten": "^1.0.1"
+          }
+        },
+        "array-unique": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+          "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+          "optional": true
+        },
+        "braces": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+          "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+          "optional": true,
+          "requires": {
+            "expand-range": "^1.8.1",
+            "preserve": "^0.2.0",
+            "repeat-element": "^1.1.2"
+          }
+        },
+        "chokidar": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+          "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+          "optional": true,
+          "requires": {
+            "anymatch": "^1.3.0",
+            "async-each": "^1.0.0",
+            "fsevents": "^1.0.0",
+            "glob-parent": "^2.0.0",
+            "inherits": "^2.0.1",
+            "is-binary-path": "^1.0.0",
+            "is-glob": "^2.0.0",
+            "path-is-absolute": "^1.0.0",
+            "readdirp": "^2.0.0"
+          }
+        },
+        "expand-brackets": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+          "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+          "optional": true,
+          "requires": {
+            "is-posix-bracket": "^0.1.0"
+          }
+        },
+        "extglob": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+          "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+          "optional": true,
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        },
+        "glob-parent": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+          "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+          "optional": true,
+          "requires": {
+            "is-glob": "^2.0.0"
+          }
+        },
+        "is-extglob": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+          "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
+        },
+        "is-glob": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+          "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "optional": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        },
+        "micromatch": {
+          "version": "2.3.11",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+          "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+          "optional": true,
+          "requires": {
+            "arr-diff": "^2.0.0",
+            "array-unique": "^0.2.1",
+            "braces": "^1.8.2",
+            "expand-brackets": "^0.1.4",
+            "extglob": "^0.3.1",
+            "filename-regex": "^2.0.0",
+            "is-extglob": "^1.0.0",
+            "is-glob": "^2.0.1",
+            "kind-of": "^3.0.2",
+            "normalize-path": "^2.0.1",
+            "object.omit": "^2.0.0",
+            "parse-glob": "^3.0.4",
+            "regex-cache": "^0.4.2"
+          }
+        },
+        "output-file-sync": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz",
+          "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=",
+          "requires": {
+            "graceful-fs": "^4.1.4",
+            "mkdirp": "^0.5.1",
+            "object-assign": "^4.1.0"
+          }
+        },
+        "v8flags": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz",
+          "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=",
+          "requires": {
+            "user-home": "^1.1.1"
+          }
+        }
+      }
+    },
     "babel-code-frame": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
       "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
-      "dev": true,
       "requires": {
         "chalk": "^1.1.3",
         "esutils": "^2.0.2",
@@ -3275,14 +3464,12 @@
         "ansi-styles": {
           "version": "2.2.1",
           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
         },
         "chalk": {
           "version": "1.1.3",
           "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
           "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
           "requires": {
             "ansi-styles": "^2.2.1",
             "escape-string-regexp": "^1.0.2",
@@ -3295,7 +3482,6 @@
           "version": "3.0.1",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-          "dev": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -3303,8 +3489,48 @@
         "supports-color": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-          "dev": true
+          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+        }
+      }
+    },
+    "babel-core": {
+      "version": "6.26.3",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+      "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
+      "requires": {
+        "babel-code-frame": "^6.26.0",
+        "babel-generator": "^6.26.0",
+        "babel-helpers": "^6.24.1",
+        "babel-messages": "^6.23.0",
+        "babel-register": "^6.26.0",
+        "babel-runtime": "^6.26.0",
+        "babel-template": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "convert-source-map": "^1.5.1",
+        "debug": "^2.6.9",
+        "json5": "^0.5.1",
+        "lodash": "^4.17.4",
+        "minimatch": "^3.0.4",
+        "path-is-absolute": "^1.0.1",
+        "private": "^0.1.8",
+        "slash": "^1.0.0",
+        "source-map": "^0.5.7"
+      },
+      "dependencies": {
+        "babylon": {
+          "version": "6.18.0",
+          "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+          "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
         }
       }
     },
@@ -3322,6 +3548,76 @@
         "eslint-visitor-keys": "^1.0.0"
       }
     },
+    "babel-generator": {
+      "version": "6.26.1",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+      "requires": {
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "detect-indent": "^4.0.0",
+        "jsesc": "^1.3.0",
+        "lodash": "^4.17.4",
+        "source-map": "^0.5.7",
+        "trim-right": "^1.0.1"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+          "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
+        }
+      }
+    },
+    "babel-helpers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+      "requires": {
+        "babel-runtime": "^6.22.0",
+        "babel-template": "^6.24.1"
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "requires": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "babel-polyfill": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+      "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "core-js": "^2.5.0",
+        "regenerator-runtime": "^0.10.5"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.10.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+          "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg="
+        }
+      }
+    },
+    "babel-register": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+      "requires": {
+        "babel-core": "^6.26.0",
+        "babel-runtime": "^6.26.0",
+        "core-js": "^2.5.0",
+        "home-or-tmp": "^2.0.0",
+        "lodash": "^4.17.4",
+        "mkdirp": "^0.5.1",
+        "source-map-support": "^0.4.15"
+      }
+    },
     "babel-runtime": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -3331,6 +3627,61 @@
         "regenerator-runtime": "^0.11.0"
       }
     },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "lodash": "^4.17.4"
+      },
+      "dependencies": {
+        "babylon": {
+          "version": "6.18.0",
+          "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+          "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
+        }
+      }
+    },
+    "babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "requires": {
+        "babel-code-frame": "^6.26.0",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "debug": "^2.6.8",
+        "globals": "^9.18.0",
+        "invariant": "^2.2.2",
+        "lodash": "^4.17.4"
+      },
+      "dependencies": {
+        "babylon": {
+          "version": "6.18.0",
+          "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+          "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "globals": {
+          "version": "9.18.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+          "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
+        }
+      }
+    },
     "babel-types": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
@@ -3457,8 +3808,7 @@
     "binary-extensions": {
       "version": "1.11.0",
       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
-      "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
-      "dev": true
+      "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU="
     },
     "bluebird": {
       "version": "3.5.1",
@@ -3680,14 +4030,13 @@
       }
     },
     "browserslist": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.2.0.tgz",
-      "integrity": "sha512-Berls1CHL7qfQz8Lct6QxYA5d2Tvt4doDWHcjvAISybpd+EKZVppNtXgXhaN6SdrPKo7YLTSZuYBs5cYrSWN8w==",
+      "version": "3.2.8",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+      "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
       "dev": true,
       "requires": {
-        "caniuse-lite": "^1.0.30000889",
-        "electron-to-chromium": "^1.3.73",
-        "node-releases": "^1.0.0-alpha.12"
+        "caniuse-lite": "^1.0.30000844",
+        "electron-to-chromium": "^1.3.47"
       }
     },
     "buffer": {
@@ -3862,9 +4211,9 @@
       "dev": true
     },
     "caniuse-lite": {
-      "version": "1.0.30000890",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000890.tgz",
-      "integrity": "sha512-4NI3s4Y6ROm+SgZN5sLUG4k7nVWQnedis3c/RWkynV5G6cHSY7+a8fwFyn2yoBDE3E6VswhTNNwR3PvzGqlTkg==",
+      "version": "1.0.30000893",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000893.tgz",
+      "integrity": "sha512-kOddHcTEef+NgN/fs0zmX2brHTNATVOWMEIhlZHCuwQRtXobjSw9pAECc44Op4bTBcavRjkLaPrGomknH7+Jvg==",
       "dev": true
     },
     "capture-stack-trace": {
@@ -3969,9 +4318,9 @@
       }
     },
     "chownr": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
-      "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE="
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
+      "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g=="
     },
     "chrome-trace-event": {
       "version": "1.0.0",
@@ -4336,7 +4685,6 @@
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
       "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
-      "dev": true,
       "requires": {
         "safe-buffer": "~5.1.1"
       }
@@ -4379,9 +4727,9 @@
       "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
     },
     "copy-webpack-plugin": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.3.tgz",
-      "integrity": "sha512-VKCiNXQcc8zyznaepXfKpCH2cZD+/j3T3B+gsFY97P7qMlEsj34wr/sI9OCG7QPUUh7gAHVx3q8Q1rdQIDM4bA==",
+      "version": "4.5.4",
+      "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.4.tgz",
+      "integrity": "sha512-0lstlEyj74OAtYMrDxlNZsU7cwFijAI3Ofz2fD6Mpo9r4xCv4yegfa3uHIKvZY1NSuOtE9nvG6TAhJ+uz9gDaQ==",
       "requires": {
         "cacache": "^10.0.4",
         "find-cache-dir": "^1.0.0",
@@ -4698,6 +5046,14 @@
       "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
       "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc="
     },
+    "detect-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "requires": {
+        "repeating": "^2.0.0"
+      }
+    },
     "dicer": {
       "version": "0.2.5",
       "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
@@ -4840,9 +5196,9 @@
       "dev": true
     },
     "duplexify": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz",
-      "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==",
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz",
+      "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==",
       "requires": {
         "end-of-stream": "^1.0.0",
         "inherits": "^2.0.1",
@@ -4864,9 +5220,9 @@
       "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
     },
     "electron-to-chromium": {
-      "version": "1.3.79",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.79.tgz",
-      "integrity": "sha512-LQdY3j4PxuUl6xfxiFruTSlCniTrTrzAd8/HfsLEMi0PUpaQ0Iy+Pr4N4VllDYjs0Hyu2lkTbvzqlG+PX9NsNw==",
+      "version": "1.3.80",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.80.tgz",
+      "integrity": "sha512-WClidEWEUNx7OfwXehB0qaxCuetjbKjev2SmXWgybWPLKAThBiMTF/2Pd8GSUDtoGOavxVzdkKwfFAPRSWlkLw==",
       "dev": true
     },
     "elliptic": {
@@ -5368,6 +5724,52 @@
         }
       }
     },
+    "expand-range": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+      "requires": {
+        "fill-range": "^2.1.0"
+      },
+      "dependencies": {
+        "fill-range": {
+          "version": "2.2.4",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
+          "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
+          "requires": {
+            "is-number": "^2.1.0",
+            "isobject": "^2.0.0",
+            "randomatic": "^3.0.0",
+            "repeat-element": "^1.1.2",
+            "repeat-string": "^1.5.2"
+          }
+        },
+        "is-number": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+          "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+          "requires": {
+            "kind-of": "^3.0.2"
+          }
+        },
+        "isobject": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+          "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+          "requires": {
+            "isarray": "1.0.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
     "expand-tilde": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
@@ -5660,6 +6062,11 @@
         }
       }
     },
+    "filename-regex": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY="
+    },
     "fill-range": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
@@ -5854,8 +6261,7 @@
     "fs-readdir-recursive": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
-      "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
-      "dev": true
+      "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA=="
     },
     "fs-then-native": {
       "version": "2.0.0",
@@ -5883,7 +6289,6 @@
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
       "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
-      "dev": true,
       "optional": true,
       "requires": {
         "nan": "^2.9.2",
@@ -5893,24 +6298,20 @@
         "abbrev": {
           "version": "1.1.1",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "ansi-regex": {
           "version": "2.1.1",
-          "bundled": true,
-          "dev": true
+          "bundled": true
         },
         "aproba": {
           "version": "1.2.0",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "are-we-there-yet": {
           "version": "1.1.4",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "delegates": "^1.0.0",
@@ -5919,15 +6320,11 @@
         },
         "balanced-match": {
           "version": "1.0.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
+          "bundled": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
-          "dev": true,
-          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -5936,37 +6333,28 @@
         "chownr": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "code-point-at": {
           "version": "1.1.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
+          "bundled": true
         },
         "concat-map": {
           "version": "0.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
+          "bundled": true
         },
         "console-control-strings": {
           "version": "1.1.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
+          "bundled": true
         },
         "core-util-is": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "debug": {
           "version": "2.6.9",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "ms": "2.0.0"
@@ -5975,25 +6363,21 @@
         "deep-extend": {
           "version": "0.5.1",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "delegates": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "detect-libc": {
           "version": "1.0.3",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "fs-minipass": {
           "version": "1.2.5",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "minipass": "^2.2.1"
@@ -6002,13 +6386,11 @@
         "fs.realpath": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "gauge": {
           "version": "2.7.4",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "aproba": "^1.0.3",
@@ -6024,7 +6406,6 @@
         "glob": {
           "version": "7.1.2",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "fs.realpath": "^1.0.0",
@@ -6038,13 +6419,11 @@
         "has-unicode": {
           "version": "2.0.1",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "iconv-lite": {
           "version": "0.4.21",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "safer-buffer": "^2.1.0"
@@ -6053,7 +6432,6 @@
         "ignore-walk": {
           "version": "3.0.1",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "minimatch": "^3.0.4"
@@ -6062,7 +6440,6 @@
         "inflight": {
           "version": "1.0.6",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "once": "^1.3.0",
@@ -6071,21 +6448,16 @@
         },
         "inherits": {
           "version": "2.0.3",
-          "bundled": true,
-          "dev": true,
-          "optional": true
+          "bundled": true
         },
         "ini": {
           "version": "1.3.5",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "is-fullwidth-code-point": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true,
-          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -6093,29 +6465,22 @@
         "isarray": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "minimatch": {
           "version": "3.0.4",
           "bundled": true,
-          "dev": true,
-          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
         },
         "minimist": {
           "version": "0.0.8",
-          "bundled": true,
-          "dev": true,
-          "optional": true
+          "bundled": true
         },
         "minipass": {
           "version": "2.2.4",
           "bundled": true,
-          "dev": true,
-          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.1",
             "yallist": "^3.0.0"
@@ -6124,7 +6489,6 @@
         "minizlib": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "minipass": "^2.2.1"
@@ -6133,8 +6497,6 @@
         "mkdirp": {
           "version": "0.5.1",
           "bundled": true,
-          "dev": true,
-          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -6142,13 +6504,11 @@
         "ms": {
           "version": "2.0.0",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "needle": {
           "version": "2.2.0",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "debug": "^2.1.2",
@@ -6159,7 +6519,6 @@
         "node-pre-gyp": {
           "version": "0.10.0",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "detect-libc": "^1.0.2",
@@ -6177,7 +6536,6 @@
         "nopt": {
           "version": "4.0.1",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "abbrev": "1",
@@ -6187,13 +6545,11 @@
         "npm-bundled": {
           "version": "1.0.3",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "npm-packlist": {
           "version": "1.1.10",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "ignore-walk": "^3.0.1",
@@ -6203,7 +6559,6 @@
         "npmlog": {
           "version": "4.1.2",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "are-we-there-yet": "~1.1.2",
@@ -6214,21 +6569,16 @@
         },
         "number-is-nan": {
           "version": "1.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
+          "bundled": true
         },
         "object-assign": {
           "version": "4.1.1",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "once": {
           "version": "1.4.0",
           "bundled": true,
-          "dev": true,
-          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -6236,19 +6586,16 @@
         "os-homedir": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "os-tmpdir": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "osenv": {
           "version": "0.1.5",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "os-homedir": "^1.0.0",
@@ -6258,19 +6605,16 @@
         "path-is-absolute": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "process-nextick-args": {
           "version": "2.0.0",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "rc": {
           "version": "1.2.7",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "deep-extend": "^0.5.1",
@@ -6282,7 +6626,6 @@
             "minimist": {
               "version": "1.2.0",
               "bundled": true,
-              "dev": true,
               "optional": true
             }
           }
@@ -6290,7 +6633,6 @@
         "readable-stream": {
           "version": "2.3.6",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -6305,7 +6647,6 @@
         "rimraf": {
           "version": "2.6.2",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "glob": "^7.0.5"
@@ -6313,44 +6654,36 @@
         },
         "safe-buffer": {
           "version": "5.1.1",
-          "bundled": true,
-          "dev": true
+          "bundled": true
         },
         "safer-buffer": {
           "version": "2.1.2",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "sax": {
           "version": "1.2.4",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "semver": {
           "version": "5.5.0",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "set-blocking": {
           "version": "2.0.0",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "signal-exit": {
           "version": "3.0.2",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "string-width": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true,
-          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -6360,7 +6693,6 @@
         "string_decoder": {
           "version": "1.1.1",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "safe-buffer": "~5.1.0"
@@ -6369,7 +6701,6 @@
         "strip-ansi": {
           "version": "3.0.1",
           "bundled": true,
-          "dev": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -6377,13 +6708,11 @@
         "strip-json-comments": {
           "version": "2.0.1",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "tar": {
           "version": "4.4.1",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "chownr": "^1.0.1",
@@ -6398,13 +6727,11 @@
         "util-deprecate": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true,
           "optional": true
         },
         "wide-align": {
           "version": "1.1.2",
           "bundled": true,
-          "dev": true,
           "optional": true,
           "requires": {
             "string-width": "^1.0.2"
@@ -6412,13 +6739,11 @@
         },
         "wrappy": {
           "version": "1.0.2",
-          "bundled": true,
-          "dev": true
+          "bundled": true
         },
         "yallist": {
           "version": "3.0.2",
-          "bundled": true,
-          "dev": true
+          "bundled": true
         }
       }
     },
@@ -6468,6 +6793,38 @@
         "path-is-absolute": "^1.0.0"
       }
     },
+    "glob-base": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+      "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+      "requires": {
+        "glob-parent": "^2.0.0",
+        "is-glob": "^2.0.0"
+      },
+      "dependencies": {
+        "glob-parent": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+          "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+          "requires": {
+            "is-glob": "^2.0.0"
+          }
+        },
+        "is-extglob": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+          "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
+        },
+        "is-glob": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+          "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        }
+      }
+    },
     "glob-parent": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
@@ -6714,7 +7071,6 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
       "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
-      "dev": true,
       "requires": {
         "ansi-regex": "^2.0.0"
       }
@@ -6803,6 +7159,15 @@
       "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
       "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
     },
+    "home-or-tmp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+      "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+      "requires": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.1"
+      }
+    },
     "homedir-polyfill": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
@@ -7070,7 +7435,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
       "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
-      "dev": true,
       "requires": {
         "binary-extensions": "^1.0.0"
       }
@@ -7143,6 +7507,19 @@
         }
       }
     },
+    "is-dotfile": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+      "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE="
+    },
+    "is-equal-shallow": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+      "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+      "requires": {
+        "is-primitive": "^2.0.0"
+      }
+    },
     "is-expression": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
@@ -7169,6 +7546,14 @@
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
       "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
     },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "requires": {
+        "number-is-nan": "^1.0.0"
+      }
+    },
     "is-fullwidth-code-point": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
@@ -7295,6 +7680,16 @@
         "isobject": "^3.0.1"
       }
     },
+    "is-posix-bracket": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+      "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q="
+    },
+    "is-primitive": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+      "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU="
+    },
     "is-promise": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
@@ -7409,12 +7804,6 @@
       "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz",
       "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA=="
     },
-    "js-levenshtein": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.4.tgz",
-      "integrity": "sha512-PxfGzSs0ztShKrUYPIn5r0MtyAhYcCwmndozzpz8YObbPnD1jFxzlBGbRnX2mIu6Z13xN6+PTu05TQFnZFlzow==",
-      "dev": true
-    },
     "js-stringify": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
@@ -7490,12 +7879,11 @@
       }
     },
     "jsdoc-babel": {
-      "version": "0.4.0",
-      "resolved": "http://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.4.0.tgz",
-      "integrity": "sha512-KF3WTPvoPYc8ZyXzC1m+vvwi+2VCKkqZX/NkqcE1tFephp8RnZAxG52QB/wvz/zoDS6XU28aM8NItMPMad50PA==",
+      "version": "0.4.0-alpha.0",
+      "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.4.0-alpha.0.tgz",
+      "integrity": "sha1-wUJ7XLTU+D1Fymf52uMrkSz7B0k=",
       "dev": true,
       "requires": {
-        "jsdoc-regex": "^1.0.1",
         "lodash": "^4.13.1"
       }
     },
@@ -7513,12 +7901,6 @@
         "test-value": "^3.0.0"
       }
     },
-    "jsdoc-regex": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/jsdoc-regex/-/jsdoc-regex-1.0.1.tgz",
-      "integrity": "sha1-hCRCjVtWOtjFx/vsB5uaiwnI3Po=",
-      "dev": true
-    },
     "jsdoc-to-markdown": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-4.0.1.tgz",
@@ -8204,6 +8586,11 @@
       "integrity": "sha512-+AKbNsjZl6jFfLPwHhWmGTqE009wTKn3RTmn9K8oUKHrX/abPJjtcRtXpYB/FFrwPJRUA86LX/de3T0knkPCmQ==",
       "dev": true
     },
+    "math-random": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
+      "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w="
+    },
     "md5.js": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -8520,9 +8907,9 @@
       "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
     },
     "neo-async": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz",
-      "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==",
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz",
+      "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==",
       "dev": true
     },
     "nice-try": {
@@ -8577,15 +8964,6 @@
         "vm-browserify": "0.0.4"
       }
     },
-    "node-releases": {
-      "version": "1.0.0-alpha.12",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.0.0-alpha.12.tgz",
-      "integrity": "sha512-VPB4rTPqpVyWKBHbSa4YPFme3+8WHsOSpvbp0Mfj0bWsC8TEjt4HQrLl1hsBDELlp1nB4lflSgSuGTYiuyaP7Q==",
-      "dev": true,
-      "requires": {
-        "semver": "^5.3.0"
-      }
-    },
     "nodemon": {
       "version": "1.18.4",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.4.tgz",
@@ -8629,7 +9007,6 @@
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
       "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
-      "dev": true,
       "requires": {
         "remove-trailing-separator": "^1.0.1"
       }
@@ -8651,8 +9028,7 @@
     "number-is-nan": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-      "dev": true
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
     },
     "object-assign": {
       "version": "4.1.1",
@@ -8752,6 +9128,25 @@
         "make-iterator": "^1.0.0"
       }
     },
+    "object.omit": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+      "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+      "requires": {
+        "for-own": "^0.1.4",
+        "is-extendable": "^0.1.1"
+      },
+      "dependencies": {
+        "for-own": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+          "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+          "requires": {
+            "for-in": "^1.0.1"
+          }
+        }
+      }
+    },
     "object.pick": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@@ -8847,8 +9242,7 @@
     "os-tmpdir": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-      "dev": true
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
     },
     "output-file-sync": {
       "version": "2.0.1",
@@ -8977,6 +9371,32 @@
         "path-root": "^0.1.1"
       }
     },
+    "parse-glob": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+      "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+      "requires": {
+        "glob-base": "^0.3.0",
+        "is-dotfile": "^1.0.0",
+        "is-extglob": "^1.0.0",
+        "is-glob": "^2.0.0"
+      },
+      "dependencies": {
+        "is-extglob": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+          "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
+        },
+        "is-glob": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+          "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        }
+      }
+    },
     "parse-json": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
@@ -9302,11 +9722,15 @@
       "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
       "dev": true
     },
+    "preserve": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+      "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks="
+    },
     "private": {
       "version": "0.1.8",
       "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
-      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
-      "dev": true
+      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
     },
     "process": {
       "version": "0.11.10",
@@ -9587,6 +10011,23 @@
       "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
       "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
     },
+    "randomatic": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz",
+      "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==",
+      "requires": {
+        "is-number": "^4.0.0",
+        "kind-of": "^6.0.0",
+        "math-random": "^1.0.1"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
+        }
+      }
+    },
     "randombytes": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
@@ -9760,7 +10201,6 @@
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
       "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
-      "dev": true,
       "requires": {
         "graceful-fs": "^4.1.2",
         "minimatch": "^3.0.2",
@@ -9891,14 +10331,22 @@
       "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
     },
     "regenerator-transform": {
-      "version": "0.13.3",
-      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz",
-      "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==",
+      "version": "0.12.4",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.12.4.tgz",
+      "integrity": "sha512-p2I0fY+TbSLD2/VFTFb/ypEHxs3e3AjU0DzttdPqk2bSmDhfSh5E54b86Yc6XhUa5KykK1tgbvZ4Nr82oCJWkQ==",
       "dev": true,
       "requires": {
         "private": "^0.1.6"
       }
     },
+    "regex-cache": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+      "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+      "requires": {
+        "is-equal-shallow": "^0.1.3"
+      }
+    },
     "regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -9973,8 +10421,7 @@
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
-      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
-      "dev": true
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
     },
     "repeat-element": {
       "version": "1.1.2",
@@ -9986,6 +10433,14 @@
       "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
       "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
     },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "requires": {
+        "is-finite": "^1.0.0"
+      }
+    },
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -10298,8 +10753,7 @@
     "set-immediate-shim": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
-      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
-      "dev": true
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
     },
     "set-value": {
       "version": "2.0.0",
@@ -10364,10 +10818,9 @@
       "dev": true
     },
     "slash": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
-      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
-      "dev": true
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU="
     },
     "slice-ansi": {
       "version": "1.0.0",
@@ -10515,9 +10968,9 @@
       }
     },
     "source-list-map": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
-      "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
       "dev": true
     },
     "source-map": {
@@ -10537,6 +10990,14 @@
         "urix": "^0.1.0"
       }
     },
+    "source-map-support": {
+      "version": "0.4.18",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+      "requires": {
+        "source-map": "^0.5.6"
+      }
+    },
     "source-map-url": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
@@ -10669,9 +11130,9 @@
       }
     },
     "stream-each": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
-      "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
+      "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
       "requires": {
         "end-of-stream": "^1.1.0",
         "stream-shift": "^1.0.0"
@@ -11069,13 +11530,12 @@
     "trim-right": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
-      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
-      "dev": true
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
     },
     "ts-loader": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.2.1.tgz",
-      "integrity": "sha512-KC0cOvsFVyxBlg5h9jvaMlIL2tNsyQLvT2/OvIlO0AMUBJ4iXTtOfaDEqvmqv2lM/icekQfDsP2PsYBCDHpuOQ==",
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.2.2.tgz",
+      "integrity": "sha512-vM/TrEKXBqRYq5yLatsXyKFnYSpv53klmGtrILGlNqcMsxPVi8+e4yr1Agbu9oMZepx/4szDVn5QpFo83IQdQg==",
       "dev": true,
       "requires": {
         "chalk": "^2.3.0",
@@ -11310,17 +11770,17 @@
       }
     },
     "unique-filename": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz",
-      "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
       "requires": {
         "unique-slug": "^2.0.0"
       }
     },
     "unique-slug": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz",
-      "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz",
+      "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==",
       "requires": {
         "imurmurhash": "^0.1.4"
       }
@@ -11491,6 +11951,11 @@
         "kind-of": "^6.0.2"
       }
     },
+    "user-home": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
+      "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA="
+    },
     "util": {
       "version": "0.10.4",
       "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
@@ -11625,9 +12090,9 @@
       }
     },
     "webpack": {
-      "version": "4.20.2",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.20.2.tgz",
-      "integrity": "sha512-75WFUMblcWYcocjSLlXCb71QuGyH7egdBZu50FtBGl2Nso8CK3Ej+J7bTZz2FPFq5l6fzCisD9modB7t30ikuA==",
+      "version": "4.21.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.21.0.tgz",
+      "integrity": "sha512-CGBeop4AYR0dcmk9Afl33qQULwTHQCXQPAIBTHMJoy9DpY8FPUDna/NUlAGTr5o5y9QC901Ww3wCY4wNo1X9Lw==",
       "dev": true,
       "requires": {
         "@webassemblyjs/ast": "1.7.8",
diff --git a/package.json b/package.json
index ac8c03c..4b8caef 100644
--- a/package.json
+++ b/package.json
@@ -18,12 +18,13 @@
   "license": "ISC",
   "dependencies": {
     "apollo-server-express": "^2.1.0",
+    "babel-cli": "^6.26.0",
     "body-parser": "^1.18.3",
     "colors": "^1.3.2",
     "connect-ensure-login": "^0.1.1",
     "connect-flash": "^0.1.1",
     "cookie-parser": "^1.4.3",
-    "copy-webpack-plugin": "^4.5.3",
+    "copy-webpack-plugin": "^4.5.4",
     "cors": "^2.8.4",
     "dotenv": "^6.1.0",
     "express": "^4.16.4",
@@ -53,17 +54,17 @@
     "url-loader": "^0.6.2"
   },
   "devDependencies": {
-    "@babel/cli": "^7.1.2",
-    "@babel/core": "^7.1.2",
-    "@babel/plugin-proposal-class-properties": "^7.1.0",
-    "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
-    "@babel/preset-env": "^7.1.0",
-    "@babel/preset-typescript": "^7.1.0",
+    "@babel/cli": "^7.0.0-beta.40",
+    "@babel/core": "^7.0.0-beta.40",
+    "@babel/plugin-proposal-class-properties": "^7.0.0-beta.40",
+    "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.40",
+    "@babel/preset-env": "^7.0.0-beta.40",
+    "@babel/preset-typescript": "^7.0.0-beta.40",
     "@types/connect-ensure-login": "^0.1.4",
     "@types/connect-flash": "0.0.34",
     "@types/graphql": "^0.13.4",
     "@types/knex": "^0.14.26",
-    "@types/node": "^10.11.7",
+    "@types/node": "^10.12.0",
     "@types/passport": "^0.4.6",
     "babel-eslint": "^8.2.6",
     "eslint": "^4.19.1",
@@ -74,12 +75,12 @@
     "eslint-plugin-promise": "^3.8.0",
     "eslint-plugin-standard": "^3.1.0",
     "jsdoc": "^3.5.5",
-    "jsdoc-babel": "^0.4.0",
+    "jsdoc-babel": "^0.4.0-alpha.0",
     "jsdoc-to-markdown": "^4.0.1",
     "nodemon": "^1.18.4",
-    "ts-loader": "^5.2.1",
+    "ts-loader": "^5.2.2",
     "typescript": "^3.1.3",
-    "webpack": "^4.20.2",
+    "webpack": "^4.21.0",
     "webpack-cli": "^3.1.2",
     "webpack-graphql-loader": "^1.0.0",
     "webpack-node-externals": "^1.7.2"
diff --git a/src/app.ts b/src/app.ts
index ec374e4..11bc5b8 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -4,7 +4,8 @@
  * La configuration inclut tout le _middleware_ définissant les API et les services
  * nécessaire utilisés, comme `express-session`, GraphiQL, GraphQL Voyager.
  * 
- * @todo changer cette description... ^
+ * @todo changer cette description... ^^
+ * @todo Passer les docstrings en FR
  * @todo qu'arrive-t-il aux requetes avec un cookie expire? elles ne sont traitees ni par passport.session() ni par passport.authenticate('ldapauth')...
  * 
  * @author manifold, kadabra
@@ -24,7 +25,7 @@ import router from './routing/admin.router';
 // packages pour l'authentification
 import passport from 'passport';
 import session from 'express-session';
-import cookieParser from 'cookie-parser'; //hawkspar->manifold VSCode râle ici pr moi
+import cookieParser from 'cookie-parser';
 import cors from 'cors';
 // packages divers
 import favicon from 'serve-favicon';
diff --git a/src/graphql/typeDefs/objects.graphql b/src/graphql/typeDefs/objects.graphql
index 47ba8ea..eca0577 100644
--- a/src/graphql/typeDefs/objects.graphql
+++ b/src/graphql/typeDefs/objects.graphql
@@ -31,11 +31,12 @@ simples, dont les membres sont des utilisateurs, et les métagroupes, dont les m
 des groupes simples (tel que Federez, dont les membres incluent le BR et DaTA). 
 """
 interface Group {
-    uid: ID
+    gid: ID!
     name: String
     # Site Web.
     website: String
     description: String
+    type: String
     
     # Jour et heure de création du groupe.
     createdAt: String!
@@ -49,9 +50,7 @@ interface Group {
     # Les questions addressees à ce groupe
     questions: [Question]
     # Les reponses donnees par ce groupe
-    answers: [Answer]
-
-
+    answers: [Answer] 
 }
 
 # Le groupe de base, dont les membres sont des utilisateurs : binets, Kès...
diff --git a/src/graphql/typeDefs/objects_ldap.graphql b/src/graphql/typeDefs/objects_ldap.graphql
new file mode 100644
index 0000000..577b693
--- /dev/null
+++ b/src/graphql/typeDefs/objects_ldap.graphql
@@ -0,0 +1,243 @@
+# hawkspar->all ; doc ?
+
+# Utilisateurs
+type User {
+    # Prénom de l'utilisateur
+    givenName: String!
+    # Nom de famille
+    lastName: String!
+    # Surnom
+    nickname: String
+    nationality: String
+    uid: ID!
+    birthdate: String!
+    mail: String
+    phone: String
+    # Groupes dont l'utilisateur est membre.
+    groups: [SimpleGroup]
+    # Groupes que l'utilisateur aime.
+    likes: [Group]
+    # A terme rajouter aussi admin
+    # Adresse(s) de l'utilisateur.
+    address: [String]
+    # Promotion
+    promotion: String
+    photo: String
+}
+
+# Groupes associatifs
+
+"""
+L'interface Group représente les deux types de groupes implémentés dans Sigma : les groupes
+simples, dont les membres sont des utilisateurs, et les métagroupes, dont les membres sont
+des groupes simples (tel que Federez, dont les membres incluent le BR et DaTA). 
+"""
+interface Group {
+    uid: ID
+    name: String
+    # Site Web.
+    website: String
+    description: String
+    
+    # Jour et heure de création du groupe.
+    createdAt: String!
+    # Dernière mise à jour du groupe.
+    updatedAt: String!
+
+    # member requests
+
+    # Les posts prives dans ce groupe
+    privatePosts: [PrivatePost]
+    # Les questions addressees à ce groupe
+    questions: [Question]
+    # Les reponses donnees par ce groupe
+    answers: [Answer]
+
+
+}
+
+# Le groupe de base, dont les membres sont des utilisateurs : binets, Kès...
+type SimpleGroup implements Group {
+    uid: ID
+    name: String
+    website: String
+    createdAt: String!
+    updatedAt: String!
+
+    # Admin, membres, sympathisants du groupe
+    admins: [User]
+    members: [User]
+    likers: [User]
+
+    description: String
+    # École d'origine du groupe
+    school: String
+    # Groupe parent
+    parent: Group
+
+    privatePosts: [PrivatePost]
+    questions: [Question]
+    answers: [Answer]
+}
+
+# Un groupe dont les membre sont d'autres groupes
+type MetaGroup implements Group {
+    uid: ID
+    name: String
+    website: String
+    createdAt: String!
+    updatedAt: String!
+    description: String
+
+    # Les groupes constitutifs du méta-groupe.
+    members: [Group]!
+
+    privatePosts: [PrivatePost]
+    questions: [Question]
+    answers: [Answer]
+}
+
+
+# Tout type de message adressé à un ou plusieurs groupes.
+
+# Auteur possible d'un Message
+# union AuthorUnion = Group | [Group] | User
+# union RecipientUnion = Group | [Group]
+
+# Les unions sont assez faibles dans GraphQL, 
+# elles n'acceptent pas les listes ni les interfaces
+
+# L'interface Message représente toute information que veut communiquer un groupe ou un user.
+# Par choix de paradigme, tout Message est adressé à un (ou des) groupe(s).
+# Les types implémentés sont divisés en deux :
+# - les Message émanant d'un groupe : Announcement et Event, ainsi que Answer
+# - les Message émanant d'un user : PrivatePost, ainsi que Question
+
+interface Message {
+    id: ID!
+    # Titre du message
+    title: String!
+    content: String
+    createdAt: String!
+    updatedAt: String!
+}
+
+# Annonce publique effectuée par un ou plusieurs groupes.
+type Announcement implements Message {
+    id: ID!
+    title: String!
+    createdAt: String!
+    updatedAt: String!
+    content: String!
+    importance: Int
+    views: Int
+    forEvent: Event
+
+    authors: [Group]
+    recipients: [Group]
+}
+
+# Événements organisés par un ou plusieurs groupes.
+type Event implements Message {
+    id: ID!
+    # Intitulé de l'événement
+    title: String!
+    # Lieu de l'événement
+    location: String
+    createdAt: String!
+    updatedAt: String!
+    startTime: String!
+    endTime: String!
+    # Organisateurs
+    # Personnes qui participent à l'événement.
+    participatingGroups: [Group]
+    participatingUsers: [User]
+    content: String
+    asAnnouncement: Announcement
+
+    authors: [Group]
+    recipients: [Group]
+}
+
+# Post interne d'un membre sur la page interne de son groupe
+type PrivatePost implements Message {
+    id: ID!
+    createdAt: String!
+    updatedAt: String!
+    title: String!
+    content: String!
+
+    authors: User
+    recipients: Group
+}
+
+# Question posée par un user à un groupe
+type Question implements Message {
+    id: ID!
+    createdAt: String!
+    updatedAt: String!
+    title: String!
+    content: String!
+
+    authors: User
+    recipients: Group
+
+    # Une annonce éventuellement concernée par cette question. 
+    # Null si la question ne concerne pas une annonce particulière
+
+    forAnnouncement: Announcement
+
+    # Référence la réponse donnée par le groupe à cette Question. Si pas encore répondu, null.
+    forAnswer: Answer
+}
+
+# Réponse à une Question 
+type Answer implements Message {
+    id: ID!
+    createdAt: String!
+    updatedAt: String!
+    title: String!
+    content: String!
+
+    authors: Group
+    recipients: Group
+
+    # La question à laquelle cette Answer répond. Non-nullable bien sûr
+    forQuestion: Question!
+}
+
+interface Request {
+    # ID de la demande
+    id: ID!
+    # message accompagnant la demande
+    message: String
+}
+
+# Demande d'un utilisateur désirant rejoindre le groupe.
+type UserJoinGroup implements Request{
+    id: ID!
+    message: String
+    # Émetteur de la demande
+    user: User
+}
+
+
+# Demande d'un groupe voulant rejoindre un événement
+type GroupJoinEvent implements Request{
+    id: ID!
+    message: String
+    # Événement concerné
+    event: Event
+    # Groupe voulant rejoindre l'événement
+    groupWantingToJoin: Group
+}
+
+# Demande au récipiendaire de rejoindre l'organisation d'un événement.
+type YourGroupHostEvent implements Request{
+    id: ID!
+    message: String
+    # Événement concerné
+    event: Event
+    # Groupe ayant publié l'évènement et lancé l'invitation
+    sender: Group
+}
diff --git a/src/ldap/admins.ts b/src/ldap/admins.ts
deleted file mode 100644
index 4b08db1..0000000
--- a/src/ldap/admins.ts
+++ /dev/null
@@ -1,410 +0,0 @@
-/**
- * @file Ce fichier regroupe les différentes classes avec différents admins. Ces classes sont dédiées à être exportées directement pour être utilisées par le solver.
- * Le découpage par fichier est arbitraire mais permet de regrouper certaines classes proches.
- * @author hawkspar
- */
-
-import {ldapConfig} from './config';
-import {LDAP} from './basics';
-import {Tests} from './utilities';
-import {Open, User, userData, groupData} from './users';
-
-export class Admin extends User {
-    /**
-     * @class Cette classe est la classe de l'administrateur d'un groupe qui lui permet de rajouter des membres, en supprimer, idem pour des admins,
-     * ou éditer, voir supprimer le groupe.
-     * @summary Ce constructeur appelle simplement le constructeur de sa classe mère.
-    */
-    constructor() { super(); }
-    
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonctions de relation TBT
-    //------------------------------------------------------------------------------------------------------------------------
-    
-    /**
-     * @summary Fonction qui permet de rajouter un membre déjà créé à un groupe.
-     * @desc Cette fonction fait essentiellement appel à {@link LDAP.modifier} et {@link listerGroupes}. Elle n'autorise pas les doublons et opère dans les deux dns users
-     * et groups.
-     * @arg {string} uid - Identifiant du futur membre
-     * @arg {string} gid - Identifiant du groupe
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async addGroupMember(uid: string, gid: string) : Promise<boolean> {
-        try {
-            // Vérifie que l'utilisateur est pas déjà membre pour groupes
-            let lm = await Open.getMembers(gid);
-            if (!lm.includes(uid)) {
-                let vals = {};
-                vals[ldapConfig.groups.member] = uid;
-                // Erreur si pb lors de la modification
-                if (!await LDAP.change(ldapConfig.key_id+gid+ldapConfig.dn_groups, "add", vals)) {
-                    throw "Erreur lors de la modification dans l'arbre des groupes pour ajouter un membre.";
-                }
-            }
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche de la liste des membres pour ajouter un membre.";
-        }
-        try {
-            // Vérifie que l'utilisateur est pas déjà membre pour users
-            let lg = await Open.getGroups(uid);
-            if (!lg.includes(gid)) {
-                let vals2 = {};
-                vals2[ldapConfig.users.groups] = gid;
-                // Erreur si pb lors de la modification
-                if (!await LDAP.change(ldapConfig.key_id+uid+ldapConfig.dn_users, "add", vals2)) {
-                    throw "Erreur lors de la modification dans l'arbre des utilisateurs pour ajouter un membre.";
-                }
-            }
-            return true;
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche de la liste des membres pour ajouter un membre.";
-        }
-    }
-
-    /**
-     * @summary Fonction qui permet de supprimer un membre existant d'un groupe.
-     * @desc Cette fonction fait essentiellement appel à {@link LDAP.search}, {@link LDAP.change}, {@link Open.getGroups} et {@link Open.getMembers}.
-     * @arg {string} uid - Identifiant de l'ex-membre
-     * @arg {string} gid - Identifiant du groupe
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async delGroupMember(uid: string, gid: string): Promise<boolean> {
-        try {
-            // Vérifie que l'utilisateur est pas déjà viré pour groupes
-            let lm = await Open.getMembers(gid);
-            if (lm.includes(uid)) {
-                // Supprime tous les utilisateurs
-                if (!await LDAP.change(ldapConfig.key_id+gid+ldapConfig.dn_groups, "del", ldapConfig.group.member)) {
-                    throw "Erreur lors de la suppression de tous les membres du groupe.";
-                }
-                // Les rajoute un par un, sauf pour le supprimé
-                lm.forEach(id => {
-                    if (id!=uid) {
-                        this.addGroupMember(id, gid).then(res => {
-                            if (!res) { throw "Erreur lors du ré-ajout des autres membres"; }
-                        });
-                    }
-                });
-            }
-        }
-        catch(err) {
-            throw "Erreur pour obtenir une liste de membres d'un groupe pour supprimer un membre du groupe.";
-        }
-        try {
-            let lg = await Open.getGroups(uid);
-            // Vérifie que l'utilisateur est pas déjà viré pour users
-            if (lg.includes(gid)) {
-                // Supprime tous les groupes
-                if (!await LDAP.change(ldapConfig.key_id+uid+ldapConfig.dn_users, "del", ldapConfig.member.groups)) {
-                    throw "Erreur lors de la suppression de tous les groupes du membre.";
-                }
-                // Les rajoute un par un, sauf pour le supprimé
-                lg.forEach(id => {
-                    if (id!=gid) {
-                        this.addGroupMember(uid, id).then(res => {
-                            if (!res) { throw "Erreur lors du ré-ajout des autres groupes"; }
-                        });
-                    }
-                });
-            }
-            return true;
-        }
-        catch(err) {
-            throw "Erreur pour obtenir une liste de groupes d'un membres pour le supprimer du groupe.";
-        }
-    }
-
-    /**
-     * @summary Fonction qui permet de promouvoir membre au stade d'administrateur d'un groupe.
-     * @desc Cette fonction fait essentiellement appel à {@link Admin.addGroupMember} {@link LDAP.change} et {@link Open.getAdmins}. Elle n'autorise pas
-     * les doublons et opère dans les deux dns users et groups.
-     * @arg {string} uid - Identifiant du futur membre
-     * @arg {string} gid - Identifiant du groupe
-     * @return {boolean} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async addGroupAdmin(uid: string, gid: string): Promise<boolean> {
-        // Ajoute le membre au groupe avant d'en faire un admin
-        if (!await Admin.addGroupMember(uid,gid)) { throw "Erreur lors de l'ajout du futur admin en tant que membre."; }
-        try {
-            let la = await Open.getAdmins(gid);
-            if (!la.includes(uid)) {
-                // Finalement modification, uniquement dans groups
-                let vals = {};
-                vals[ldapConfig.groups.admin] = uid;
-                if (!await LDAP.change(ldapConfig.key_id+gid+ldapConfig.dn_groups, "add", vals)) {
-                    throw "Erreur lors de l'ajout de l'admin dans l'arbre des groupes.";
-                }
-            }
-            return true;
-        }
-        catch(err) {
-            throw "Erreur lors de l'obtention de la liste des administrateurs d'un groupe.";
-        }
-    }
-
-    /**
-     * @summary Fonction qui permet de rétrograder un membre du stade d'administrateur d'un groupe au stade d'utilisateur.
-     * @desc Cette fonction fait essentiellement appel à {@link LDAP.change}.
-     * @arg {string} uid - Identifiant du futur membre
-     * @arg {string} gid - Identifiant du groupe
-     * @return {boolean} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async delGroupAdmin(uid: string, gid: string): Promise<boolean> {
-        // Peut paraître absurde mais permet de s'assurer que le membre est bien présent et que ses champs sont comme il faut
-        if (!(await Admin.delGroupMember(uid, gid)&&Admin.addGroupMember(uid,gid))) { throw "Erreur dans l'éjection/réadmission du futur admin."; }
-        try {
-            // Vérifie que l'utilisateur est bien admin (comme dans delGroupMember)
-            let la = await Open.getAdmins(gid);
-            if (la.includes(uid)) {
-                // Supprime tous les administrateurs
-                if (!await LDAP.change(ldapConfig.key_id+gid+ldapConfig.dn_groups, "del", ldapConfig.group.admin)) { throw "Erreur dans la suppression de tous les admins pour en supprimer un."; }
-                // Les rajoute un par un, sauf pour le supprimé
-                la.forEach(id => {
-                    if (id!=uid) { Admin.addGroupAdmin(id, gid).then(res => {
-                        if (!res) { throw "Erreur dans le réajout d'un des autres admins."; }
-                    }); }
-                });
-            }
-            return true;
-        }
-        catch(err) {
-            throw "Erreur lors de l'obtention de la liste des administrateurs d'un groupe.";
-        }
-    }
-    
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonction d'édition TBT
-    //------------------------------------------------------------------------------------------------------------------------
-
-    /**
-     * @summary Fonction qui édite un groupe existant dans le LDAP. Très similaire à {@link User.addGroup}
-     * @desc Appelle {@link LDAP.add} bien sûr, mais aussi {@link Admin.addGroupMember} et {@link Admin.addGroupAdmin} en godmode pour gérer les groupes du nouvel utilisateur.
-     * @arg {string} gid - Identifiant du groupe à modifier
-     * @arg {groupData} data - Dictionnaire des informations utilisateurs au même format que pour {@link User.addGroup} avec tous les champs optionnels.
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async editGroup(gid: string, data: groupData) : Promise<boolean> {
-        try {
-            // Récupération des anciennes données
-            let profil = await Open.peekGroup(gid);
-            // Reecriture de profil avec les bons champs
-            Object.keys(profil).forEach(keyLDAP => {
-                Object.keys(ldapConfig.group).forEach(keyAlias => {
-                    ldapConfig.group[keyAlias]=keyLDAP;
-                    profil[keyAlias]=profil[keyLDAP];
-                });
-            });
-            // Surcharge des champs à modifier selon data
-            Object.keys(data).forEach(key => {
-                profil[key]=data[key];
-            });
-            // Modification propre
-            if (!await Admin.delGroup(gid)&&await User.addGroup(profil)) { throw "Erreur de la destruction/recréation du groupe pour le modifier."; }
-            return true;
-        }
-        catch(err) {
-            throw "Erreur lors de l'obtention du profil d'un groupe pour le modifier.";
-        }
-    }
-    
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonctions de suppression TBT
-    //------------------------------------------------------------------------------------------------------------------------
-    
-    /**
-     * @summary Fonction qui supprime un groupe du LDAP.
-     * @desc Cette fonction commence par gérer les groupes du membre puis le supprime entièrement.
-     * Appelle {@link LDAP.clear} bien sûr, mais aussi {@link Admin.delGroupMember} et {@link Admin.delGroupAdmin} pour gérer les groupes de l'utilisateur sortant.
-     * @arg {string} gid - gid de la victime
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async delGroup(gid): Promise<boolean> {
-        try {
-            // Gestion des membres et administrateurs d'abord
-            let profil = await Open.peekGroup(gid);
-            // Ordre important
-            profil[ldapConfig.group['admin']].forEach( id => {
-                this.delGroupAdmin( id, gid).then(res => { if (!res) { throw "Erreur lors de la suppression d'un admin d'un groupe en cours de suppression."; } });
-            });
-            profil[ldapConfig.group['member']].forEach(id => {
-                this.delGroupMember(id, gid).then(res => { if (!res) { throw "Erreur lors de la suppression d'un membre."; } });
-            });
-            // Elimination
-            if (!await LDAP.clear(ldapConfig.key_id+"="+gid+","+ldapConfig.dn_groups)) { throw "Erreur lors de la suppression de la feuille dans l'arbre des groupes."; }
-            return true;
-        }
-        catch(err) {
-            throw "Erreur lors de l'obtention du profil d'un groupe pour le supprimer.";
-        }
-    }
-}
-
-export class Supervisor extends Admin {
-    /**
-     * @class Cette classe est la classe du super administrateur qui créé et supprime des membres.
-     * @summary Constructeur vide.
-     * @author hawkspar
-     */
-    constructor(user) { super(); }
-
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonctions de création TBT
-    //------------------------------------------------------------------------------------------------------------------------
-    
-    /**
-     * @summary Fonction qui créé un nouvel utilisateur dans le LDAP.
-     * @desc Appelle {@link LDAP.add} bien sûr, mais aussi {@link User.addGroupMember} et {@link Admin.addGroupAdmin} pour gérer les groupes du nouvel utilisateur.
-     * @arg {userData} data - Dictionnaire des informations utilisateurs. Des erreurs peuvent apparaître si tous les champs ne sont pas remplis.
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async addUser(data: userData): Promise<boolean> {
-        // Calcul d'un dictionnaire d'ajout
-        let vals = {};
-
-        // uid de base généré à partir de nom et prénom, plus potentiellement promo et un offset
-        // MEF mélange de Promise et de fonction standard
-        try {
-            Tests.generateUid(data['givenName'],data['lastName'],data['promotion']).then(id => { vals[ldapConfig.key_id]=id; } );
-        }
-        catch(err) {
-            throw "Erreur lors de la génération d'un hruid pour un nouvel utilisateur.";
-        }
-
-        let uid = vals[ldapConfig.key_id];
-
-        // Ecriture de toutes les valeurs directement inscrites dans le LDAP (in pour input)
-        // Génère une erreur si un champ n'est pas rempli
-        ldapConfig.user.single.forEach(key_att => vals[ldapConfig.user.single[key_att]]=data[key_att]);
-
-        // Appel à la fonction de base
-        if (!await LDAP.add(ldapConfig.key_id+"="+uid+","+ldapConfig.dn_users, vals)) { throw "Erreur de l'ajout de la feuille à l'arbre utilisateur."; }
-        
-        // Modifications multiples pour avoir plusieurs champs de même type ; boucle sur les attributs multiples
-        ldapConfig.user.multiple.forEach(key_att => {
-            // On rajoute chaque valeur en entrée
-            data[key_att].forEach(val => {
-                let vals2 = {};
-                vals2[ldapConfig.user.multiple[key_att]]=val;
-                LDAP.change(ldapConfig.key_id+"="+uid+","+ldapConfig.dn_users, "add", vals2).then(res => {
-                    if (!res) { throw "Erreur lors de l'ajout d'une valeur pour un champ à valeurs multiples à la feuille du nouvel utilisateur."; }
-                });
-            });
-        });
-
-        // Certains champs nécessitent de petits calculs
-        let vals3={};
-
-        // Création d'un nom complet lisible
-        vals3[ldapConfig.user.single['fullName']]=data['givenName']+' '+data['lastName'].toUpperCase();
-
-        // ldapConfiguration du mot de passe utilisateur
-        // Le préfixe {CRYPT} signifie que le mdp est hashé dans OpenLDAP voir : https://www.openldap.org/doc/admin24/security.html 
-        vals3[ldapConfig.user.single['password']] = "{CRYPT}"+data['password'];
-        
-        // Ecriture d'un surnom s'il y a lieu
-        if ((data['nickname']!=undefined) && (data['nickname']!='')) {
-            vals3[ldapConfig.user.single['nickname']]=data['nickname'];
-        }
-        try {
-            // Génération id aléatoire unique
-            vals3[ldapConfig.user.single['id']]= await Tests.generateId(ldapConfig.user.single['id'], ldapConfig.dn_users);
-        }
-        catch(err) {
-            throw "Erreur lors de la génération d'un id numérique pour un nouvel utilisateur.";
-        }
-        
-        // Stockage machine ; dépend du prénom
-        vals3[ldapConfig.user['directory']] = '/hosting/users/' + data['givenName'][0];
-
-        // Code root
-        vals3[ldapConfig.user.single['cleanFullName']]=data['fullName'].replace(':', ';').toLowerCase().normalize('UFD');
-        
-        // Adressage root
-        if (data['groups'].includes("on_platal")) { vals3[ldapConfig.user.single['login']] = "/bin/bash"; }
-        else  { vals3[ldapConfig.user.single['login']] = "/sbin/nologin"; }
-        
-        // Permissions BR
-        vals3[ldapConfig.user.single['readPerm']] = 'br.*,public.*';
-        if (data['readPerm'].length>0) { vals3[ldapConfig.user.single['readPerm']] += ',' + data['readPerm']; }
-        vals3[ldapConfig.user.single['writePerm']] = 'br.*,!br.blague-du-jour,public.*,!br.campagnekes';
-        if (data['writePerm'].length>0) { vals3[ldapConfig.user.single['readPerm']] += ',' + data['writePerm']; }
-
-        // Valeur nécessaire ASKIP mais inutile
-        vals3[ldapConfig.user.single['idNum']] ='5000';
-
-        // Inscription des valeurs calculées
-        if (!await LDAP.change(ldapConfig.key_id+"="+uid+","+ldapConfig.dn_users, "add", vals3)) {
-            throw "Erreur lors de l'ajout des valeurs calculées à la feuille du nouvel utilisateur.";
-        }
-
-        ["posixAccount", "shadowAccount", "inetOrgPerson", "brAccount"].forEach(cst => {
-            let val3={};
-            vals3[ldapConfig.user.multiple['class']]=cst;
-            LDAP.change(ldapConfig.key_id+"="+uid+","+ldapConfig.dn_users, "add", vals3).then(res => {
-                if (!res) { throw "Erreur lors de l'ajout d'une valeur constante à la feuille du nouvel utilisateur."; }
-            });
-        });
-
-        // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble
-        data['groupsIsMember'].forEach(gid => {
-            Admin.addGroupMember(uid, gid).then(res => {
-                if (!res) { throw "Erreur lors de l'ajout du nouvel utilisateur à un groupe."; }
-            });
-        });
-        data['groupsIsAdmin'].forEach(gid => { 
-            Admin.addGroupAdmin(uid, gid).then(res => {
-                if (!res) { throw "Erreur lors de l'ajout du nouvel utilisateur à un groupe en tant qu'admin."; }
-            });
-        });
-
-        return true;
-    }
-
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonctions de suppression TBT
-    //------------------------------------------------------------------------------------------------------------------------
-    
-    /**
-     * @summary Fonction qui supprime un utilisateur du LDAP.
-     * @desc Cette fonction commence par gérer les groupes du membre puis le supprime entièrement.
-     * Appelle {@link LDAP.clear} bien sûr, mais aussi {@link Admin.delGroupMember} et {@link Admin.delGroupAdmin} pour gérer les groupes de l'utilisateur sortant.
-     * @arg {string} uid - uid de la victime
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async delUser(uid: string): Promise<boolean> {
-        try {
-            // Gestion des groupes d'abord
-            let profil = await Open.peekUser(uid);
-            profil[ldapConfig.user.multiple['groups']].forEach(gid => {
-                if (Open.isGroupAdmin(uid,gid)) {
-                    if (!Admin.delGroupAdmin(uid, gid)) { throw "Erreur lors de la suppression des droits d'admin de l'utilisateur."; }
-                }
-                if (!Admin.delGroupMember(uid, gid)) { throw "Erreur lors de la suppression de l'appartenance à un groupe de l'utilisateur."; }
-            });
-        }
-        catch(err) {
-            throw "Erreur lors de l'obtention des informations de l'utilisateur à supprimer.";
-        }
-        // Elimination
-        if (!LDAP.clear(ldapConfig.key_id+"="+uid+","+ldapConfig.dn_users)) { throw "Erreur lors de la suppression de l'utilisateur."; }
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/src/ldap/basics.ts b/src/ldap/basics.ts
index 9e29669..85cf2d6 100644
--- a/src/ldap/basics.ts
+++ b/src/ldap/basics.ts
@@ -76,16 +76,20 @@ export class LDAP {
      * @summary Fonction qui interroge le LDAP selon un protocole spécifié en argument et renvoit les valeurs trouvées.
      * @desc Cette fonction utilise ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode search). Cette fonction fait une demande au LDAP
      * qu'elle filtre selon un schéma prédéfini dans `filter` et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end).
-     * @arg {string} dn - DN de l'emplacement de la requête
-     * @arg {string} filter ["(objectClass=*)"] - Filtre logique de la recherche (format [`RFC2254`](https://tools.ietf.org/search/rfc2254)) déjà passé au ldapEscape
+     * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur)
      * @arg {string[]} attributes - Liste des attributs qui figureront dans le résultat final ; peut aussi être un seul élément
+     * @arg {string} id [null] - Identifiant facultatif pour une recherche triviale en o(1)
+     * @arg {string} filter ["(objectClass=*)"] - Filtre logique de la recherche (format [`RFC2254`](https://tools.ietf.org/search/rfc2254)) déjà passé au ldapEscape
      * @return {(Promise(Array.<Object>)|Promise(Array.Object.<string, Object>))} Résultats de la recherche ; soit une liste de valeurs d'attributs, 
      * soit une liste de dictionnaires si on veut plus d'un attribut (les clés du dictionnaire sont celles du LDAP)
      * @static
      * @async
      */
-    static async search(dn: string, attributes: string[], filter="(objectClass=*)") : Promise<Array<any>> {
+    static async search(domain: 'gr'|'us', attributes: string[], id=null, filter="(objectClass=*)") : Promise<Array<any>> {
         LDAP.adminBind();
+        if (domain == "gr") { var dn = ldapConfig.dn_groups; }
+        else                { var dn = ldapConfig.dn_users; }
+        if (id != null) { dn=ldapConfig.key_id+'='+id+','+dn; }
         let vals=[];
         // Interrogation LDAP selon ldapConfiguration fournie en argument
         client.search(ldapEscape.dn("${txt}", { txt: dn}), {
@@ -123,7 +127,8 @@ export class LDAP {
     /**
      * @summary Fonction qui permet de modifier un élément sur le LDAP. Gestion intelligente de l'appartenance à un binet.
      * @desc Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode modify).
-     * @arg {string} dn - DN de l'endroit à modifier
+     * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur)
+     * @arg {string} id - Identifiant unique de la feuille à modifier
      * @arg {string} op - Operation à réaliser sur le LDAP. Trois opération sont possibles ; "add", qui rajoute des attributs et qui peut créer des doublons,
      * "del" qui en supprime, et "replace" qui remplace du contenu par un autre. 
      * @arg {Object.<string, string>} mod - Dictionnaire contenant les attributs à modifier et les nouvelles valeurs des attributs.
@@ -132,8 +137,11 @@ export class LDAP {
      * @static
      * @async
      */
-    static async change(dn: string, op: string, mod) : Promise<boolean> {
+    static async change(domain: 'gr'|'us', id: string, op: string, mod) : Promise<boolean> {
         LDAP.adminBind();
+        let dn = ldapConfig.key_id+'='+id+','
+        if (domain == "gr") { dn+=ldapConfig.dn_groups }
+        else                { dn+=ldapConfig.dn_users }
         // Modification LDAP selon ldapConfiguration en argument (pourrait prendre une liste de Changes)
         client.modify(ldapEscape.dn("${txt}", {txt: dn}), new ldap.Change({
             operation: ldapEscape.dn("${txt}", {txt: op}),
@@ -150,15 +158,17 @@ export class LDAP {
     /**
      * @summary Fonction qui permet de rajouter un élément sur le LDAP.
      * @desc  Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode add).
-     * @arg {string} dn - Adresse du parent
-     * @arg {Object.<string, string>} vals - Dictionnaire contenant les valeurs à créer
+     * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur)
+     * @arg {Object.<string, string>} vals - Dictionnaire contenant les valeurs à créer (contient un champ en ldapConfig.key_id)
      * @arg {Object} vals[key] - Nouvelle valeur pour le champ key
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon.
      * @static
      * @async
      */
-    static async add(dn: string, vals) : Promise<boolean> {
+    static async add(domain: 'gr'|'us', vals) : Promise<boolean> {
         LDAP.adminBind();
+        if (domain == "gr") { var dn = ldapConfig.dn_groups }
+        else                { var dn = ldapConfig.dn_users }
         // Ajout LDAP selon la ldapConfiguration en argument
         client.add(ldapEscape.dn(ldapConfig.key_id+"="+vals[ldapConfig.key_id]+",${txt}", { txt: dn}), vals, err => {
             throw "Erreur lors d'une opération d'ajout sur le LDAP.";
@@ -172,13 +182,17 @@ export class LDAP {
      * @summary Fonction qui permet de supprimer une feuille du LDAP.
      * @desc Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode del).
      * Elle est différente de modify avec "del" car elle affecte directement une feuille et pas un attribut.
-     * @arg {string} dn - Adresse de la cible
+     * @arg {'gr'|'us'} domain - Emplacement de la requête (groupe ou utilisateur)
+     * @arg {string} id - Identifiant unique de la cible
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      * @static
      * @async
      */
-    static async clear(dn: string) : Promise<boolean> {
+    static async clear(domain: 'gr'|'us', id: string) : Promise<boolean> {
         LDAP.adminBind();
+        let dn = ldapConfig.key_id+'='+id+','
+        if (domain == "gr") { dn+=ldapConfig.dn_groups }
+        else                { dn+=ldapConfig.dn_users }
         // Suppression LDAP
         client.del(ldapEscape.dn("${txt}", {txt: dn}), err => {
             throw "Erreur lors d'une opération de suppression sur le LDAP.";
diff --git a/src/ldap/group.ts b/src/ldap/group.ts
new file mode 100644
index 0000000..ab04387
--- /dev/null
+++ b/src/ldap/group.ts
@@ -0,0 +1,391 @@
+/**
+ * @file Ce fichier contient la classe de l'API du LDAP qui gère les opérations sur les groupes.
+ * @author hawkspar
+ */
+
+import { ldapConfig } from './config';
+import {LDAP} from './basics';
+import {Tests} from './utilities';
+
+/**
+ * @interface groupData
+ * @var {string} gid - Identifiant du groupe
+ * @var {string} name - Nom du groupe
+ * @var {string} type - Statut du groupe ; binet, section sportive... (actuellement juste 'binet' ou 'free')
+ * @var {string[]} members - Liste des membres du groupe
+ * @var {string[]} admins - Liste des admins du groupe ; supposée être une sous-liste de la précédente
+ * @var {string} description - Description du groupe (facultatif)
+ */
+export interface groupData {
+    "gid": string,
+	"name": string,
+	"type": string,
+    "members": string[],
+    "admins": string[],
+    "description"?: string
+}
+
+//------------------------------------------------------------------------------------------------------------------------
+// Classes à exporter TBT
+//------------------------------------------------------------------------------------------------------------------------
+
+export class Group {
+    /**
+     * @class Cette classe est une des deux classes exportables permettant de faire des opérations sur les groupes.
+     * @summary Constructeur vide.
+    */
+    constructor() {}
+     
+    /**
+     * @summary Fonction qui renvoit toutes les infos relatives à un groupe particulier.
+     * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis.
+     * @arg {string} gid - Identifiant du groupe
+     * @return {Promise(groupData)} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet du groupe ;
+     * voir `ldap_ldapConfig.json`(..\..\ldap_ldapConfig.json) pour les clés exactes.
+     * @static
+     * @async
+     */
+    static async peek(gid: string) : Promise<groupData> {
+        try {
+            let fields = [];
+            fields.push(ldapConfig.group.values());
+            let LDAPGroupData = await LDAP.search("gr", fields, gid);
+            let cleanGroupData : groupData;
+            // Rename output
+            for (let uncleanKey in LDAPGroupData) {
+                for (let cleanKey in cleanGroupData) {
+                    if (uncleanKey==ldapConfig.group[cleanKey]) { cleanGroupData[cleanKey] = LDAPGroupData[uncleanKey]; }
+                }
+            }
+            return cleanGroupData;
+        }
+        catch(err) {
+            throw "Erreur lors d'une recherche d'informations sur un groupe.";
+        }
+    }
+
+    /**
+     * @summary Fonction qui retrouve le groupe qui ressemblent à l'input et qui correspond au type fourni. Etape 0 vers un vrai TOL (Trombino On Line).
+     * @desc Cette fonction utilise {@link LDAP.search} mais avec un filtre généré à la volée. 
+     * Accepte des champs exacts ou incomplets mais pas approximatifs
+     * et ne gère pas l'auto-complete. Cette fonction utilise aussi ldapConfig.json. MEF Timeout pour
+     * des recherches trop vagues. Renvoit une liste d'uid.
+     * @arg {string} input - String entré par l'utilisateur qui ressemble au nom du groupe.
+     * @return {Promise(string[])} Liste des gid dont le nom ressemble à l'input.
+     * @static
+     * @async
+    */
+    static async search(input: string) : Promise<string[]> {
+        try {
+            // Construction du filtre custom
+            let filter= "(|("+ldapConfig.key_id+"="+ input+")" +    // On cherche la valeur exacte
+            "(|("+ldapConfig.key_id+"=*"+input+")" +    // La valeur finale avec des trucs avant ; wildcard *
+            "(|("+ldapConfig.key_id+"=*"+input+"*)"+    // La valeur du milieu avec des trucs avant et après
+            "("+  ldapConfig.key_id+"="+ input+"*))))"; // La valeur du début avec des trucs après
+
+            // Appel rechercheLDAP avec filtre de l'espace 
+            return LDAP.search("gr", [ldapConfig.key_id], null, filter);
+        }
+        catch(err) {
+            throw "Erreur lors de la recherche approximative d'un groupe.";
+        }
+    }
+
+    static async addMember(uid: string, gid: string) : Promise<boolean> {
+        try {
+            // Vérifie que l'utilisateur est pas déjà membre pour groupes
+            let lm = await Tests.getMembers(gid);
+            if (!lm.includes(uid)) {
+                let vals = {};
+                vals[ldapConfig.group.members] = uid;
+                // Erreur si pb lors de la modification
+                if (!await LDAP.change("gr", gid, "add", vals)) {
+                    throw "Erreur lors de la modification dans l'arbre des groupes pour ajouter un membre.";
+                }
+            }
+        }
+        catch(err) {
+            throw "Erreur lors de la recherche de la liste des membres pour ajouter un membre.";
+        }
+        try {
+            // Vérifie que l'utilisateur est pas déjà membre pour users
+            let lg = await Tests.getGroups(uid);
+            if (!lg.includes(gid)) {
+                let vals2 = {};
+                vals2[ldapConfig.user.groups] = gid;
+                // Erreur si pb lors de la modification
+                if (!await LDAP.change("us", uid, "add", vals2)) {
+                    throw "Erreur lors de la modification dans l'arbre des utilisateurs pour ajouter un membre.";
+                }
+            }
+            return true;
+        }
+        catch(err) {
+            throw "Erreur lors de la recherche de la liste des membres pour ajouter un membre.";
+        }
+    }
+
+    /**
+     * @summary Fonction qui permet de supprimer un membre existant d'un groupe.
+     * @desc Cette fonction fait essentiellement appel à {@link LDAP.search}, {@link LDAP.change}, {@link Open.getGroups} et {@link Open.getMembers}.
+     * @arg {string} uid - Identifiant de l'ex-membre
+     * @arg {string} gid - Identifiant du groupe
+     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async delMember(uid: string, gid: string): Promise<boolean> {
+        try {
+            // Vérifie que l'utilisateur est pas déjà viré pour groupes
+            let lm = await Tests.getMembers(gid);
+            if (lm.includes(uid)) {
+                // Supprime tous les utilisateurs
+                if (!await LDAP.change("gr", gid, "del", ldapConfig.group.members)) {
+                    throw "Erreur lors de la suppression de tous les membres du groupe.";
+                }
+                // Les rajoute un par un, sauf pour le supprimé
+                lm.forEach(id => {
+                    if (id!=uid) {
+                        this.addMember(id, gid).then(res => {
+                            if (!res) { throw "Erreur lors du ré-ajout des autres membres"; }
+                        });
+                    }
+                });
+            }
+        }
+        catch(err) {
+            throw "Erreur pour obtenir une liste de membres d'un groupe pour supprimer un membre du groupe.";
+        }
+        try {
+            let lg = await Tests.getGroups(uid);
+            // Vérifie que l'utilisateur est pas déjà viré pour users
+            if (lg.includes(gid)) {
+                // Supprime tous les groupes
+                if (!await LDAP.change("us", uid, "del", ldapConfig.user.groups)) {
+                    throw "Erreur lors de la suppression de tous les groupes du membre.";
+                }
+                // Les rajoute un par un, sauf pour le supprimé
+                lg.forEach(id => {
+                    if (id!=gid) {
+                        this.addMember(uid, id).then(res => {
+                            if (!res) { throw "Erreur lors du ré-ajout des autres groupes"; }
+                        });
+                    }
+                });
+            }
+            return true;
+        }
+        catch(err) {
+            throw "Erreur pour obtenir une liste de groupes d'un membres pour le supprimer du groupe.";
+        }
+    }
+
+    /**
+     * @summary Fonction qui permet de promouvoir membre au stade d'administrateur d'un groupe.
+     * @desc Cette fonction fait essentiellement appel à {@link Admin.addGroupMember} {@link LDAP.change} et {@link Open.getAdmins}. Elle n'autorise pas
+     * les doublons et opère dans les deux dns users et groups.
+     * @arg {string} uid - Identifiant du futur membre
+     * @arg {string} gid - Identifiant du groupe
+     * @return {boolean} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async addAdmin(uid: string, gid: string): Promise<boolean> {
+        // Ajoute le membre au groupe avant d'en faire un admin
+        if (!await Group.addMember(uid,gid)) { throw "Erreur lors de l'ajout du futur admin en tant que membre."; }
+        try {
+            let la = await Tests.getAdmins(gid);
+            if (!la.includes(uid)) {
+                // Finalement modification, uniquement dans groups
+                let vals = {};
+                vals[ldapConfig.group.admins] = uid;
+                if (!await LDAP.change("gr", gid, "add", vals)) {
+                    throw "Erreur lors de l'ajout de l'admin dans l'arbre des groupes.";
+                }
+            }
+            return true;
+        }
+        catch(err) {
+            throw "Erreur lors de l'obtention de la liste des administrateurs d'un groupe.";
+        }
+    }
+
+    /**
+     * @summary Fonction qui permet de rétrograder un membre du stade d'administrateur d'un groupe au stade d'utilisateur.
+     * @desc Cette fonction fait essentiellement appel à {@link LDAP.change}.
+     * @arg {string} uid - Identifiant du futur membre
+     * @arg {string} gid - Identifiant du groupe
+     * @return {boolean} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async delAdmin(uid: string, gid: string): Promise<boolean> {
+        // Peut paraître absurde mais permet de s'assurer que le membre est bien présent et que ses champs sont comme il faut
+        if (!(await Group.delMember(uid, gid) && Group.addMember(uid,gid))) { throw "Erreur dans l'éjection/réadmission du futur admin."; }
+        try {
+            // Vérifie que l'utilisateur est bien admin (comme dans delGroupMember)
+            let la = await Tests.getAdmins(gid);
+            if (la.includes(uid)) {
+                // Supprime tous les administrateurs
+                if (!await LDAP.change("gr", gid, "del", ldapConfig.group.admins)) { throw "Erreur dans la suppression de tous les admins pour en supprimer un."; }
+                // Les rajoute un par un, sauf pour le supprimé
+                la.forEach(id => {
+                    if (id!=uid) { Group.addAdmin(id, gid).then(res => {
+                        if (!res) { throw "Erreur dans le réajout d'un des autres admins."; }
+                    }); }
+                });
+            }
+            return true;
+        }
+        catch(err) {
+            throw "Erreur lors de l'obtention de la liste des administrateurs d'un groupe.";
+        }
+    }
+    /**
+     * @summary Fonction qui créé un nouveau groupe dans le LDAP.
+     * @desc Cette fonction fait une utilisation massive d'eval pour anonymiser son code ; c'est mal et cela suppose que beaucoup de soins ont été pris lors de
+     * l'escape de ses paramètres. Appelle {@link LDAP.add} et {@link LDAP.change}, mais aussi {@link Admin.addMemberGroup} et {@link Admin.addAdminGroup}
+     * pour gérer les groupes du nouvel utilisateur. Attention une manip FOIREUSE est cachée dedans.
+     * @arg {groupData} data - Dictionnaire des informations utilisateurs (voir détail des champs dans ldapConfig.json)
+     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async create(data: groupData) : Promise<boolean> {
+        // Calcul d'un dictionnaire d'ajout
+        let vals = {};
+
+        // gid de base généré à partir du nom standardisé, pas à partir de l'entrée 'gid' !
+        try {
+            Tests.generateReadableId(data['name']).then(id => {
+                vals[ldapConfig.key_id]=id;
+                vals[ldapConfig.group['name']]=id;
+            });
+        }
+        catch(err) {
+            throw "Erreur lors de la génération d'un hruid pour créer un nouveau groupe.";
+        }
+
+        let gid : string = vals[ldapConfig.key_id];
+
+        // Ecriture de toutes les valeurs directement inscrites dans le LDAP
+        for (let key_att in data) { vals[ldapConfig.group[key_att]]=data[key_att] };
+
+        // Appel à la fonction de base
+        if (!await LDAP.add("gr", vals)) {
+            throw "Erreur lors de la création d'une nouvelle feuille dans l'arbre des groupes.";
+        }
+        // Certains champs nécessitent de petits calculs
+        let vals2={};
+
+        // Encore un cahmp redondant
+        vals2[ldapConfig.group['adress']] = gid;
+
+        // ?!
+        vals2[ldapConfig.group['password']] = '';
+
+        // Génération id aléatoire et test contre le LDAP
+        try {
+            Tests.generateId(ldapConfig.group["idNumber"], "gr").then(id => { vals2[ldapConfig.group['idNumber']]=id; });
+        }
+        catch(err) {
+            throw "Erreur lors de la génération d'un id numérique pour créer un nouveau groupe.";
+        }
+        // FOIREUX : Hypothèse sur la structure du reste des données mais évite un test.assurerUnicite à deux variables
+        vals2[ldapConfig.group['idNumber2']]=vals2[ldapConfig.group['idNumber']];
+        
+        // Stockage machine ; dépend du prénom
+        vals2[ldapConfig.group['directory']] = '/hosting/groups/'+gid;
+
+        // Code root
+        vals2[ldapConfig.group['cleanFullName']]=data['name'].replace(':', ';').toLowerCase().normalize('UFD');
+        
+        // Adressage root
+        vals2[ldapConfig.group['login']] = "/sbin/nologin";
+        
+        // Permissions BR
+        vals2[ldapConfig.group['readPerm']] = '!*';
+        vals2[ldapConfig.group['writePerm']] = '!*';
+
+        // Inscription des valeurs calculées par effet de bord
+        if (!await LDAP.change("gr", gid, "add", vals2)) {
+            throw "Erreur lors de l'ajout des valeurs intelligentes du nouveau groupe.";
+        }
+
+        ["posixAccount", "posixGroup", "brAccount"].forEach(cst => {
+            let vals3={};
+            vals3[ldapConfig.group['classes']]=cst;
+            LDAP.change("gr", gid, "add", vals3).then(res => {
+                if (!res) { throw "Erreur lors de l'ajout des valeurs constantes du nouveau groupe."; }
+            });
+        });
+
+        // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble
+        data['members'].forEach(uid => {
+            Group.addMember(uid, gid).then(res => {
+                if (!res) { throw "Erreur de l'ajout d'un membre au groupe."; }
+            });
+        });
+        data['admins'].forEach(uid => {
+            Group.addAdmin(uid, gid).then(res => {
+                if (!res) { throw "Erreur de l'ajout d'un admin au groupe."; }
+            });
+        });
+
+        return true;
+    }
+
+    /**
+     * @summary Fonction qui supprime un groupe du LDAP.
+     * @desc Cette fonction commence par gérer les groupes du membre puis le supprime entièrement.
+     * Appelle {@link LDAP.clear} bien sûr, mais aussi {@link Admin.delGroupMember} et {@link Admin.delGroupAdmin} pour gérer les groupes de l'utilisateur sortant.
+     * @arg {string} gid - gid de la victime
+     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async delete(gid): Promise<boolean> {
+        try {
+            // Gestion des membres et administrateurs d'abord
+            let profil = await Group.peek(gid);
+            // Ordre important
+            profil[ldapConfig.group['admin']].forEach( id => {
+                Group.delAdmin( id, gid).then(res => { if (!res) { throw "Erreur lors de la suppression d'un admin d'un groupe en cours de suppression."; } });
+            });
+            profil[ldapConfig.group['member']].forEach(id => {
+                Group.delMember(id, gid).then(res => { if (!res) { throw "Erreur lors de la suppression d'un membre."; } });
+            });
+            // Elimination
+            if (!await LDAP.clear("gr",gid)) { throw "Erreur lors de la suppression de la feuille dans l'arbre des groupes."; }
+            return true;
+        }
+        catch(err) {
+            throw "Erreur lors de l'obtention du profil d'un groupe pour le supprimer.";
+        }
+    }
+
+    /**
+     * @summary Fonction qui édite un groupe existant dans le LDAP. Très similaire à {@link User.addGroup}
+     * @desc Appelle {@link LDAP.add} bien sûr, mais aussi {@link Admin.addGroupMember} et {@link Admin.addGroupAdmin} en godmode pour gérer les groupes du nouvel utilisateur.
+     * @arg {groupData} data - Dictionnaire des informations utilisateurs au même format que pour {@link User.addGroup} avec tous les champs optionnels...
+     * Sauf 'gid', qui permet de savoir quel groupe modifier et qui est donc inchangeable. On peut modifier nickname par contre.
+     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async edit(data: groupData) : Promise<boolean> {
+        try {
+            let gid = data['gid'];
+            // Récupération des anciennes données
+            let profil = await Group.peek(gid);
+            // Surcharge des champs à modifier selon data
+            for (let key in data) { profil[key]=data[key]; }
+            // Modification propre
+            if (!await Group.delete(gid) && await Group.create(profil)) { throw "Erreur de la destruction/recréation du groupe pour le modifier."; }
+            return true;
+        }
+        catch(err) {
+            throw "Erreur lors de l'obtention du profil d'un groupe pour le modifier.";
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/ldap/user.ts b/src/ldap/user.ts
new file mode 100644
index 0000000..3652c9e
--- /dev/null
+++ b/src/ldap/user.ts
@@ -0,0 +1,331 @@
+/**
+ * @file Ce fichier regroupe les différentes classes avec différents utilisateurs. Ces classes sont dédiées à être exportées directement pour être utilisées par le solver.
+ * Le découpage par fichier est arbitraire mais permet de regrouper certaines classes proches.
+ * @author hawkspar
+ */
+
+import { ldapConfig } from './config';
+import {LDAP} from './basics';
+import {Tests} from './utilities';
+import {Group} from './group';
+
+/**
+ * @interface userData
+ * @desc Interface avec toutes les données extractables pour un utilisateur.
+ * @var {string} givenName - Prénom
+ * @var {string} lastName - Nom
+ * @var {string} nickname - Surnom
+ * @var {string} photo - Bytestring de la photo de l'utilisateur
+ * @var {string} birthdate - Date d'anniversaire
+ * @var {string} promotion - Année(s) de promo
+ * @var {string} phone - Numéro(s) de téléphone
+ * @var {string[]} mail - Adresse(s) courriel
+ * @var {string[]} adress - Adresses
+ * @var {string} groups - Un ou plusieurs groupes dont l'utilisateur est membre (inclus section sportive, binet, PA...)
+ * @var {string} password - Mot de passe généré en amont
+ * @var {string[]} ips - Adresse(s) ip
+ * @arg {string} readPerm - Permissions spéciales BR
+ * @var {string} writePerm - Permissions spéciales BR
+ * @var {string[]} forlifes - Alias BR (attention le filtre .fkz n'est plus fonctionnel)
+ * @var {string[]} groupsIsAdmin - Liste des gid dont le pax est admin ; supposé sous-liste de groups
+ */
+export interface userData {
+    "uid": string,
+    "photo"?: string,
+    "givenName"?: string,
+    "lastName"?: string,
+    "fullName"?: string,
+    "cleanFullName": string,
+    "nickname"?: string,
+    "birthdate"?: string,
+    "nationality"?: string,
+    "promotion": string,
+    "phone"?: string,
+    "adress"?: string,
+    "id"?: string,
+    "sport"?: string,
+    "password"?: string,
+    "idNum"?: string,
+    "directory"?: string,
+    "login"?: string,
+    "readPerm"?: string,
+    "writePerm"?: string,
+    "mails"?: string[],
+    "ips"?: string[],
+    "forlifes"?: string[],
+    "groups": string[],
+    "groupsIsAdmin": string[],
+    "schools"?: string[],
+    "courses"?: string[],
+    "classes"?: string[]
+}
+
+//------------------------------------------------------------------------------------------------------------------------
+// Classes à exporter TBT
+//------------------------------------------------------------------------------------------------------------------------
+
+export class User {
+    /**
+     * @class Cette classe est une des deux classes exportables permettant de faire des opérations sur les utilisateurs.
+     * @summary Constructeur vide.
+    */
+    constructor() {}
+     
+    /**
+     * @summary Fonction qui renvoit toutes les infos relatives à un utilisateur particulier.
+     * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis.
+     * @arg {string} uid - Identifiant de l'utilisateur
+     * @return {Promise(userData)} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet de l'utilisateur ;
+     * voir `ldap_ldapConfig.json`(..\..\ldap_ldapConfig.json) pour les clés exactes.
+     * @static
+     * @async
+     */
+    static async peek(uid: string) : Promise<userData> {
+        try {
+            let fields = [];
+            fields.push(ldapConfig.user.values());
+            let LDAPUserData = await LDAP.search("us", fields, uid);
+            let cleanUserData : userData;
+            // Rename output
+            for (let uncleanKey in LDAPUserData) {
+                for (let cleanKey in cleanUserData) {
+                    if (uncleanKey==ldapConfig.group[cleanKey]) { cleanUserData[cleanKey] = LDAPUserData[uncleanKey]; }
+                }
+            }
+            return cleanUserData;
+        }
+        catch(err) {
+            throw "Erreur lors d'une recherche d'informations sur un individu.";
+        }
+    }
+    
+    /**
+     * @summary Fonction qui retrouve les uid des paxs validant les critères de recherche. Autre étape vers vrai TOL (Trombino On Line). Doit être préféré à repliquer TOL
+     * car moins gourmande envers le LDAP (utiliser {@link peekUser} au cas par cas après pour obtenir les vraies infos).
+     * @desc Cette fonction utilise {@link LDAP.search} mais avec un filtre généré à la volée. Accepte des champs exacts ou incomplets pour la plupart des champs
+     * mais pas approximatifs et ne gère pas l'auto-complete. MEF Timeout pour des recherches trop vagues. Va crasher si un champ n'est pas dans ldapConfig.
+     * Utiliser trouverGroupesParTypes pour chaque champ relié à groups.
+     * @arg {userData} data - Dictionnaire contenant les données nécessaires à la recherche. Les valeurs sont celles entrées par l'utilisateur et sont par hypothèse
+     * comme des sous-parties compactes des valeurs renvoyées. Tous les champs ci-dessous peuvent être indifféremment des listes (par exempl pour chercher un membre
+     * de plusieurs groupes) ou des éléments isolés. Si un champ n'est pas pertinent, le mettre à '' ou undefined.
+     * @return {Promise(string[])} gids des profils qui "match" les critères proposés.
+     * @static
+     * @async
+     */
+    static async search(data: userData) : Promise<string[]> {
+        try {
+            let filter="";
+            // Iteration pour chaque champ, alourdissement du filtre selon des trucs prédéfinis dans ldapConfig encore
+            for (var key in data) {
+                if ((data[key]!= undefined) && (data[key] != '')) {                    // Si il y a qque chose à chercher pour ce filtre
+                    if (!Array.isArray(data[key])) { data[key]=[data[key]]; }          // Gestion d'une liste de valeurs à rechercher
+                    // Iteration pour chaque valeur fournie par l'utilisateur
+                    data[key].forEach(val => {
+                        // Traduction en language LDAP
+                        let attribute = ldapConfig.user[key];
+                        // Creation incrémentale du filtre
+                        filter="(&"+filter+ "(|("+attribute+"="+ val+")"+      // On cherche la valeur exacte
+                                            "(|("+attribute+"=*"+val+")"+      // La valeur finale avec des trucs avant ; wildcard * (MEF la wildcart ne marche pas pour tous les attributs)
+                                            "(|("+attribute+"=*"+val+"*)"+     // La valeur du milieu avec des trucs avant et après
+                                            "("+  attribute+"="+ val+"*)))))"; // La valeur du début avec des trucs après
+                    });
+                }
+            }
+            // Appel avec filtre de l'espace 
+            return LDAP.search("us", [ldapConfig.key_id], null, filter);
+        }
+        catch(err) {
+            throw "Erreur lors de la recherche approximative d'un utilisateur.";
+        }
+    }
+    
+    /**
+     * @summary Fonction qui créé un nouvel utilisateur dans le LDAP.
+     * @desc Appelle {@link LDAP.add} bien sûr, mais aussi {@link User.addGroupMember} et {@link Admin.addGroupAdmin} pour gérer les groupes du nouvel utilisateur.
+     * @arg {userData} data - Dictionnaire des informations utilisateurs. Des erreurs peuvent apparaître si tous les champs ne sont pas remplis.
+     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async create(data: userData): Promise<boolean> {
+        // Calcul d'un dictionnaire d'ajout
+        let vals = {};
+
+        // uid de base généré à partir de nom et prénom, plus potentiellement promo et un offset
+        // MEF mélange de Promise et de fonction standard
+        try {
+            Tests.generateUid(data['givenName'],data['lastName'],data['promotion']).then(id => { vals[ldapConfig.key_id]=id; } );
+        }
+        catch(err) {
+            throw "Erreur lors de la génération d'un hruid pour un nouvel utilisateur.";
+        }
+
+        let uid = vals[ldapConfig.key_id];
+
+        // Génère une erreur si un champ n'est pas rempli
+        for (let key_att in data) {
+            // Ecriture de toutes les valeurs uniques
+            if (!Array.isArray(data[key_att])) { vals[ldapConfig.user[key_att]]=data[key_att]; }
+        }
+
+        // Appel à la fonction de base
+        if (!await LDAP.add("us", vals)) { throw "Erreur de l'ajout de la feuille à l'arbre utilisateur."; }
+        
+        for (let key_att in data) {
+            // Modifications multiples pour avoir plusieurs champs de même type ; boucle sur les attributs multiples
+            if (Array.isArray(data[key_att])) {
+                // On rajoute chaque valeur en entrée
+                data[key_att].forEach(val => {
+                    let vals2 = {};
+                    vals2[ldapConfig.user[key_att]]=val;
+                    LDAP.change("us", uid, "add", vals2).then(res => {
+                        if (!res) { throw "Erreur lors de l'ajout d'une valeur pour un champ à valeurs multiples à la feuille du nouvel utilisateur."; }
+                    });
+                });
+            }
+        }
+        
+        // Certains champs nécessitent de petits calculs
+        let vals3={};
+
+        // Création d'un nom complet lisible
+        vals3[ldapConfig.user['fullName']]=data['givenName']+' '+data['lastName'].toUpperCase();
+
+        // ldapConfiguration du mot de passe utilisateur
+        // Le préfixe {CRYPT} signifie que le mdp est hashé dans OpenLDAP voir : https://www.openldap.org/doc/admin24/security.html 
+        vals3[ldapConfig.user['password']] = "{CRYPT}"+data['password'];
+        
+        // Ecriture d'un surnom s'il y a lieu
+        if ((data['nickname']!=undefined) && (data['nickname']!='')) {
+            vals3[ldapConfig.user['nickname']]=data['nickname'];
+        }
+        try {
+            // Génération id aléatoire unique
+            vals3[ldapConfig.user['id']]= await Tests.generateId(ldapConfig.user['id'], "us");
+        }
+        catch(err) {
+            throw "Erreur lors de la génération d'un id numérique pour un nouvel utilisateur.";
+        }
+        
+        // Stockage machine ; dépend du prénom
+        vals3[ldapConfig.user['directory']] = '/hosting/users/' + data['givenName'][0];
+
+        // Code root
+        vals3[ldapConfig.user['cleanFullName']]=data['fullName'].replace(':', ';').toLowerCase().normalize('UFD');
+        
+        // Adressage root
+        if (data['groups'].includes("on_platal")) { vals3[ldapConfig.user['login']] = "/bin/bash"; }
+        else  { vals3[ldapConfig.user['login']] = "/sbin/nologin"; }
+        
+        // Permissions BR
+        vals3[ldapConfig.user['readPerm']] = 'br.*,public.*';
+        if (data['readPerm'].length>0) { vals3[ldapConfig.user['readPerm']] += ',' + data['readPerm']; }
+        vals3[ldapConfig.user['writePerm']] = 'br.*,!br.blague-du-jour,public.*,!br.campagnekes';
+        if (data['writePerm'].length>0) { vals3[ldapConfig.user['readPerm']] += ',' + data['writePerm']; }
+
+        // Valeur nécessaire ASKIP mais inutile
+        vals3[ldapConfig.user['idNum']] ='5000';
+
+        // Inscription des valeurs calculées
+        if (!await LDAP.change("us", uid, "add", vals3)) {
+            throw "Erreur lors de l'ajout des valeurs calculées à la feuille du nouvel utilisateur.";
+        }
+
+        ["posixAccount", "shadowAccount", "inetOrgPerson", "brAccount"].forEach(cst => {
+            let val3={};
+            vals3[ldapConfig.user['class']]=cst;
+            LDAP.change("us", uid, "add", vals3).then(res => {
+                if (!res) { throw "Erreur lors de l'ajout d'une valeur constante à la feuille du nouvel utilisateur."; }
+            });
+        });
+
+        // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble
+        data['groupsIsMember'].forEach(gid => {
+            Group.addMember(uid, gid).then(res => {
+                if (!res) { throw "Erreur lors de l'ajout du nouvel utilisateur à un groupe."; }
+            });
+        });
+        data['groupsIsAdmin'].forEach(gid => { 
+            Group.addAdmin(uid, gid).then(res => {
+                if (!res) { throw "Erreur lors de l'ajout du nouvel utilisateur à un groupe en tant qu'admin."; }
+            });
+        });
+
+        return true;
+    }
+
+    //------------------------------------------------------------------------------------------------------------------------
+    // Fonctions de suppression TBT
+    //------------------------------------------------------------------------------------------------------------------------
+    
+    /**
+     * @summary Fonction qui supprime un utilisateur du LDAP.
+     * @desc Cette fonction commence par gérer les groupes du membre puis le supprime entièrement.
+     * Appelle {@link LDAP.clear} bien sûr, mais aussi {@link Admin.delGroupMember} et {@link Admin.delGroupAdmin} pour gérer les groupes de l'utilisateur sortant.
+     * @arg {string} uid - uid de la victime
+     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async delete(uid: string): Promise<boolean> {
+        try {
+            // Gestion des groupes d'abord
+            let profil = await User.peek(uid);
+            profil[ldapConfig.user['groups']].forEach(gid => {
+                // Opérations effectuées par effet de bord
+                if (Tests.isGroupAdmin(uid,gid)) {
+                    if (!Group.delAdmin(uid, gid)) { throw "Erreur lors de la suppression des droits d'admin de l'utilisateur."; }
+                }
+                if (!Group.delMember(uid, gid)) { throw "Erreur lors de la suppression de l'appartenance à un groupe de l'utilisateur."; }
+            });
+        }
+        catch(err) {
+            throw "Erreur lors de l'obtention des informations de l'utilisateur à supprimer.";
+        }
+        // Elimination
+        if (!LDAP.clear("us", uid)) { throw "Erreur lors de la suppression de l'utilisateur."; }
+        return true;
+    }
+
+    /**
+     * @summary Fonction qui édite un utilisateur existant dans le LDAP. Très similaire à {@link creerUtilisateur}
+     * @desc Appelle simplement {@link creerUtilisateur} et {@link supprimerUtilisateur} en godmode, plus {@link renseignerSurUtilisateur} pour les champs non fournis.
+     * Ce choix a pour conséquence que l'ordre du dictionnaire de correspondance dans ldap_ldapConfig est important.
+     * Une version "nerfée" de cette fonction est envisageable ; elle donne bcp de pouvoir à l'utilisateur.
+     * @arg {userData} data - Dictionnaire des informations utilisateurs au même format que pour {@link creerUtilisateur} avec tous les champs optionnels sauf 'uid',
+     * qui permet de savoir qui modifier. Attention toutes les clés de cette entrée seront modifiées dans le LDAP ; les nouveaux résultats écrasant les précédents,
+     * sauf 'readPerm','writePerm', 'forlifes','ips','groups' et 'groupsIsAdmin' qui sont censurés pour cette fonction).
+     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
+     * @async
+     * @static
+     */
+    static async edit(data : userData) : Promise<boolean> {
+        let uid = data['uid'];
+        // Récupération des anciennes données
+        let profil = await User.peek(uid);
+        try {
+            // Régénération du champ manquant dans profil
+            let lg = await Tests.getGroups(uid);
+            profil['groupsIsAdmin']=[];
+            lg.forEach(gid => {
+                Tests.isGroupAdmin(uid, gid).then(res => {
+                    if (res) { profil['groupsIsAdmin'].push(gid); }
+                });
+            });
+            // Surcharge des champs à modifier selon data
+            Object.keys(data).forEach(function(key: string) {
+                // Some fields the user cannot change (groups and groupsIsAdmin must be changed through addGroupMember and addGroupAdmin in Admin)
+                if (!['readPerm','writePerm','forlifes','ips','groups','groupsIsAdmin'].includes(key)) { profil[key]=data[key]; }
+            });
+            // Modification propre par effet de bord
+            if (!(await User.delete(uid) && await User.create(profil))) {
+                throw "Erreur dans la destruction/création du compte.";
+            } else {
+                return true;
+            }
+        }
+        catch(err) {
+            throw "Erreur lors de la modification des groupes où un utilisateur est admin.";
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/ldap/users.ts b/src/ldap/users.ts
deleted file mode 100644
index 67c4a24..0000000
--- a/src/ldap/users.ts
+++ /dev/null
@@ -1,416 +0,0 @@
-/**
- * @file Ce fichier regroupe les différentes classes avec différents utilisateurs. Ces classes sont dédiées à être exportées directement pour être utilisées par le solver.
- * Le découpage par fichier est arbitraire mais permet de regrouper certaines classes proches.
- * @author hawkspar
- */
-
-import { ldapConfig } from './config';
-import {LDAP} from './basics';
-import {searchUserFields, SmartSearch, Tests} from './utilities';
-import {Admin, Supervisor} from './admins';
-import ldap from 'ldapjs';
-
-/**
- * @const groupDataTemplate
- * @var {string} name - Nom du groupe
- * @var {string} ns - Statut du groupe ; 'binet' ou 'free', càd ouvert à tous
- * @var {string[]} members - Liste des membres du groupe
- * @var {string[]} admins - Liste des admins du groupe ; supposée être une sous-liste de la précédente
- */
-let groupDataTemplate = {}
-for (let key in ldapConfig.group.single)    { groupDataTemplate[key] = ""; }
-for (let key in ldapConfig.group.multiple)  { groupDataTemplate[key] = [""]; }
-
-/**
- * @type groupData
- * @summary Interface sur le modèle de {@link groupDataTemplate}
- */
-export type groupData = typeof groupDataTemplate;
-
-/**
- * @interface userData
- * @desc Interface avec toutes les données extractables pour un utilisateur.
- * @var {string} givenName - Prénom
- * @var {string} lastName - Nom
- * @var {string} nickname - Surnom
- * @var {string} photo - Bytestring de la photo de l'utilisateur
- * @var {string} birthdate - Date d'anniversaire
- * @var {string} promotion - Année(s) de promo
- * @var {string} phone - Numéro(s) de téléphone
- * @var {string} mail - Adresse(s) courriel
- * @var {string} ip - Adresse(s) ip
- * @var {string} adress - Adresse(s)
- * @var {string} groups - Un ou plusieurs groupes dont l'utilisateur est membre (inclus section sportive, binet, PA...)
- * @var {string} password - Mot de passe généré en amont
- * @arg {string} readPerm - Permissions spéciales BR
- * @var {string} writePerm - Permissions spéciales BR
- * @var {string[]} forlifes - Alias BR (attention le filtre .fkz n'est plus fonctionnel)
- * @var {string[]} groupsIsAdmin - Liste des gid dont le pax est admin ; supposé sous-liste de groups
- */
-let userDataTemplate = {}
-for (let key in ldapConfig.user.single)    { userDataTemplate[key] = ""; }
-for (let key in ldapConfig.user.multiple)  { userDataTemplate[key] = [""]; }
-
-/**
- * @type groupData
- * @summary Interface sur le modèle de {@link userDataTemplate}
- */
-export type userData = typeof userDataTemplate;
-
-//------------------------------------------------------------------------------------------------------------------------
-// Classes à exporter TBT
-//------------------------------------------------------------------------------------------------------------------------
-
-export class Open {
-    /**
-     * @class Cette classe est la classe exportable de base permettant à un utilisateur non connecté de faire des petites recherches simples.
-     * @summary Constructeur vide.
-    */
-    constructor() {}
-
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonctions de lecture
-    //------------------------------------------------------------------------------------------------------------------------
-    /**
-     * @summary Fonction qui retrouve les groupes dont un individu est membre.
-     * @desc Cette fonction utilise {@link LDAP.search} va directement à la feuille de l'utilisateur.
-     * @arg {string} uid - Identifiant de l'individu à interroger (le plus souvent prenom.nom, parfois l'année, supposé valide)
-     * @return {Promise(string[])} Liste des uid de groupes (noms flat des groupes) où l'id fourni est membre
-     * @static
-     * @async
-     */
-    static async getGroups(uid: string) {
-        try {
-            return LDAP.search(ldapConfig.key_id+uid+ldapConfig.dn_users, ldapConfig.user.groups)[0];
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche des groupes d'un individu.";
-        }
-    }
-    
-    /**
-     * @summary Fonction qui retrouve la liste des membres d'un groupe.
-     * @desc Cette fonction utilise {@link LDAP.search} avec un dictionnaire prédéfini dans ldapConfig.json.
-     * @arg {string} gid - Identifiant du groupe à interroger (le plus souvent nom du groupe en minuscule)
-     * @return {Promise(String[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
-     * @static
-     * @async
-     */
-    static async getMembers(gid: string) {
-        try {
-            return LDAP.search(ldapConfig.key_id+gid+ldapConfig.dn_users, ldapConfig.group.member)[0];
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche des membres d'un groupe.";
-        }
-    }
-    
-    /**
-     * @summary Fonction qui retrouve la liste des admins d'un groupe.
-     * @desc Cette fonction utilise {@link LDAP.search} avec un dictionnaire prédéfini dans ldapConfig.json.
-     * @arg {string} gid - Identifiant du groupe à interroger (le plus souvent nom du groupe en minuscule)
-     * @return {Promise(string[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
-     * @static
-     * @async
-     */
-    static async getAdmins(gid: string) {
-        try {
-            return LDAP.search(ldapConfig.key_id+gid+ldapConfig.dn_users, ldapConfig.group.admin)[0];
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche des admins d'un groupe.";
-        }
-    }
-
-    /**
-     * @summary Cette fonction teste si un utilisateur est membre d'un groupe.
-     * @desc Utilise les méthodes statiques {@link open.getGroups} et {@link open.getMembers}
-     * @param {string} uid - Identifiant de l'utilisateur à tester 
-     * @param {string} gid  - Identification du groupe à tester
-     * @returns {Promise(boolean)} True si l'utilisateur est membre
-     * @static
-     * @async
-     */
-    static async isGroupMember(uid: string, gid: string) {
-        try {
-            let lg = await this.getGroups(uid);
-            let lm = await this.getMembers(gid);
-            if (lg.includes(gid) && lm.includes(uid)) {
-                return true;
-            }
-        }
-        catch(err) {
-            throw "Erreur lors du test d'appartenance à un groupe.";
-        }
-    }
-
-    /**
-     * @summary Cette fonction teste si un utilisateur est admin d'un groupe.
-     * @desc Utilise la méthode statique {@link Open.getAdmins}
-     * @param {string} uid - Identifiant de l'utilisateur à tester 
-     * @param {string} gid  - Identification du groupe à tester
-     * @returns {Promise(boolean)} True si l'utilisateur est administrateur
-     * @static
-     * @async
-     */
-    static async isGroupAdmin(uid: string, gid: string) {
-        try {
-            let la = await this.getAdmins(gid);
-            if (la.includes(uid)) {
-                return true;
-            }
-        }
-        catch(err) {
-            throw "Erreur lors du test d'appartenance au bureau d'administration un groupe.";
-        }
-    }
-     
-    /**
-     * @summary Fonction qui renvoit toutes les infos relatives à un utilisateur particulier.
-     * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis.
-     * @arg {string} uid - Identifiant de l'utilisateur
-     * @return {Promise(userData)} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet de l'utilisateur ;
-     * voir `ldap_ldapConfig.json`(..\..\ldap_ldapConfig.json) pour les clés exactes.
-     * @static
-     * @async
-     */
-    static async peekUser(uid: string) : Promise<userData> {
-        try {
-            let fields = [];
-            fields.push(ldapConfig.user.single.values());
-            fields.push(ldapConfig.user.multiple.values());
-            let LDAPUserData = await LDAP.search(ldapConfig.key_id+'='+uid+','+ldapConfig.dn_users, fields);
-            let cleanUserData = userDataTemplate;
-            // Rename output
-            for (let uncleanKey in LDAPUserData) {
-                for (let cleanKey in cleanUserData) {
-                    if (uncleanKey==ldapConfig.group.cleanKey) { cleanUserData[cleanKey] = LDAPUserData[uncleanKey]; }
-                }
-            }
-            return cleanUserData;
-        }
-        catch(err) {
-            throw "Erreur lors d'une recherche d'informations sur un individu.";
-        }
-    }
-     
-    /**
-     * @summary Fonction qui renvoit toutes les infos relatives à un groupe particulier.
-     * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis.
-     * @arg {string} gid - Identifiant du groupe
-     * @return {Promise(groupData)} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet du groupe ;
-     * voir `ldap_ldapConfig.json`(..\..\ldap_ldapConfig.json) pour les clés exactes.
-     * @static
-     * @async
-     */
-    static async peekGroup(gid: string) : Promise<groupData> {
-        try {
-            let fields = [];
-            fields.push(ldapConfig.user.single.values());
-            fields.push(ldapConfig.user.multiple.values());
-            let LDAPGroupData = await LDAP.search(ldapConfig.key_id+'='+gid+','+ldapConfig.dn_groups, fields);
-            let cleanGroupData=groupDataTemplate;
-            // Rename output
-            for (let uncleanKey in LDAPGroupData) {
-                for (let cleanKey in cleanGroupData) {
-                    if (uncleanKey==ldapConfig.group.cleanKey) { cleanGroupData[cleanKey] = LDAPGroupData[uncleanKey]; }
-                }
-            }
-            return cleanGroupData;
-        }
-        catch(err) {
-            throw "Erreur lors d'une recherche d'informations sur un groupe.";
-        }
-    }
-
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonctions de recherche
-    //------------------------------------------------------------------------------------------------------------------------
-
-    /**
-     * @summary Fonction qui retrouve le groupe qui ressemblent à l'input et qui correspond au type fourni. Etape 0 vers un vrai TOL (Trombino On Line).
-     * @desc Cette fonction utilise {@link SmartSearch.groups}.
-     * @arg {string} input - String entré par l'utilisateur qui ressemble au nom du groupe.
-     * @return {Promise(string[])} Liste des gid dont le nom ressemble à l'input.
-     * @static
-     * @async
-    */
-    static async findGroups(input: string) : Promise<string[]> {
-        try {
-            // Trucs intelligents faits dans ./utilities
-            return SmartSearch.groups(input, ldapConfig.key_id);
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche approximative d'un groupe.";
-        }
-    }
-
-    /**
-     * @summary Fonction qui retrouve les uid des paxs validant les critères de recherche. Autre étape vers vrai TOL (Trombino On Line). Doit être préféré à repliquer TOL
-     * car moins gourmande envers le LDAP (utiliser {@link peekUser} au cas par cas après pour obtenir les vraies infos).
-     * @desc Cette fonction utilise {@link SmartSearch.users}.
-     * @arg {searchUserFields} data - Dictionnaire contenant les données nécessaires à {@link SmartSearch.groups}
-     * @return {Promise(string[])} gids des profils qui "match" les critères proposés.
-     * @static
-     * @async
-     */
-    static async findUsers(data: searchUserFields) : Promise<string[]> {
-        try {
-            return SmartSearch.users(data, ldapConfig.key_id);
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche approximative d'un utilisateur.";
-        }
-    }
-}
-
-export class User extends Open {
-    /**
-     * @class Cette classe est la classe de l'utilisateur connecté qui peut déjà créer un groupe et changer son profil.
-     * Techniquement, c'est la première classe qui a vraiment besoin de méthodes dynamiques dans l'arborescence, puisque c'est à partir du niveau User
-     * qu'on peut commencer à vouloir tracer les actions de l'utilisateur. 
-     * @summary Constructeur vide.
-    */
-    constructor() { super(); }
-
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonction de création TBT
-    //------------------------------------------------------------------------------------------------------------------------
-
-    /**
-     * @summary Fonction qui créé un nouveau groupe dans le LDAP.
-     * @desc Cette fonction fait une utilisation massive d'eval pour anonymiser son code ; c'est mal et cela suppose que beaucoup de soins ont été pris lors de
-     * l'escape de ses paramètres. Appelle {@link LDAP.add} et {@link LDAP.change}, mais aussi {@link Admin.addMemberGroup} et {@link Admin.addAdminGroup}
-     * pour gérer les groupes du nouvel utilisateur. Attention une manip FOIREUSE est cachée dedans.
-     * @arg {groupData} data - Dictionnaire des informations utilisateurs (voir détail des champs dans ldapConfig.json)
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async addGroup(data: groupData) : Promise<boolean> {
-        // Calcul d'un dictionnaire d'ajout
-        let vals = {};
-
-        // uid de base généré à partir du nom standardisé
-        try {
-            Tests.generateReadableId(data['name']).then(id => {
-                vals[ldapConfig.key_id]=id;
-                vals[ldapConfig.group.single['name']]=id;
-            });
-        }
-        catch(err) {
-            throw "Erreur lors de la génération d'un hruid pour créer un nouveau groupe.";
-        }
-
-        let gid = vals[ldapConfig.key_id];
-
-        // Ecriture de toutes les valeurs directement inscrites dans le LDAP (in pour input)
-        ldapConfig.group.single.forEach(key_att => vals[ldapConfig.group.single[key_att]]=data[key_att]);
-
-        // Appel à la fonction de base
-        if (!await LDAP.add(ldapConfig.key_id+"="+gid+","+ldapConfig.dn_groups, vals)) {
-            throw "Erreur lors de la création d'une nouvelle feuille dans l'arbre des groupes.";
-        }
-        // Certains champs nécessitent de petits calculs
-        let vals2={};
-
-        // ?!
-        vals2[ldapConfig.group.single['password']] = '';
-
-        // Génération id aléatoire et test contre le LDAP
-        try {
-            Tests.generateId(ldapConfig.group.single["idNumber"], ldapConfig.dn_groups).then(id => { vals2[ldapConfig.group.single['idNumber']]=id; });
-        }
-        catch(err) {
-            throw "Erreur lors de la génération d'un id numérique pour créer un nouveau groupe.";
-        }
-        // FOIREUX : Hypothèse sur la structure du reste des données mais évite un test.assurerUnicite à deux variables
-        vals2[ldapConfig.group.single['idNumber2']]=vals2[ldapConfig.group.single['idNumber']];
-        
-        // Stockage machine ; dépend du prénom
-        vals2[ldapConfig.group.single['directory']] = '/hosting/groups/'+gid;
-
-        // Code root
-        vals2[ldapConfig.group.single['cleanFullName']]=data['name'].replace(':', ';').toLowerCase().normalize('UFD');
-        
-        // Adressage root
-        vals2[ldapConfig.group.single['login']] = "/sbin/nologin";
-        
-        // Permissions BR
-        vals2[ldapConfig.group.single['readPerm']] = '!*';
-        vals2[ldapConfig.group.single['writePerm']] = '!*';
-
-        // Inscription des valeurs calculées par effet de bord
-        if (!await LDAP.change(ldapConfig.key_id+"="+gid+","+ldapConfig.dn_groups, "add", vals2)) {
-            throw "Erreur lors de l'ajout des valeurs intelligentes du nouveau groupe.";
-        }
-
-        ["posixAccount", "posixGroup", "brAccount"].forEach(cst => {
-            let vals3={};
-            vals3[ldapConfig.group.multiple['class']]=cst;
-            LDAP.change(ldapConfig.key_id+"="+gid+","+ldapConfig.dn_groups, "add", vals3).then(res => {
-                if (!res) { throw "Erreur lors de l'ajout des valeurs constantes du nouveau groupe."; }
-            });
-        });
-
-        // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble
-        data['members'].forEach(uid => {
-            Admin.addGroupMember(uid, gid).then(res => {
-                if (!res) { throw "Erreur de l'ajout d'un membre au groupe."; }
-            });
-        });
-        data['admins'].forEach(uid => {
-            Admin.addGroupAdmin(uid, gid).then(res => {
-                if (!res) { throw "Erreur de l'ajout d'un admin au groupe."; }
-            });
-        });
-
-        return true;
-    }
-
-    //------------------------------------------------------------------------------------------------------------------------
-    // Fonctions d'édition TBT
-    //------------------------------------------------------------------------------------------------------------------------
-    
-    /**
-     * @summary Fonction qui édite un utilisateur existant dans le LDAP. Très similaire à {@link creerUtilisateur}
-     * @desc Appelle simplement {@link creerUtilisateur} et {@link supprimerUtilisateur} en godmode, plus {@link renseignerSurUtilisateur} pour les champs non fournis.
-     * Ce choix a pour conséquence que l'ordre du dictionnaire de correspondance dans ldap_ldapConfig est important.
-     * Une version "nerfée" de cette fonction est envisageable ; elle donne bcp de pouvoir à l'utilisateur.
-     * @arg {string} uid - Utilisateur à modifier (le plus souvent le même, mais root possible)
-     * @arg {userData} data - Dictionnaire des informations utilisateurs au même format que pour {@link creerUtilisateur} avec tous les champs optionnels ;
-     * Attention toutes les clés de cette entrée seront modifiées dans le LDAP ; les nouveaux résultats écrasant les précédents, sauf 'readPerm','writePerm','forlifes','ips','groups' et 'groupsIsAdmin'
-     * qui sont censurés pour cette fonction)
-     * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
-     * @static
-     */
-    static async editUser(uid : string, data : userData) : Promise<boolean> {
-        // Récupération des anciennes données
-        let profil = await Open.peekUser(uid);
-        try {
-            // Régénération du champ manquant dans profil
-            let lg = await Open.getGroups(uid);
-            profil['groupsIsAdmin']=[];
-            lg.forEach(gid => {
-                Open.isGroupAdmin(uid, gid).then(res => {
-                    if (res) { profil['groupsIsAdmin'].push(gid); }
-                });
-            });
-            // Surcharge des champs à modifier selon data
-            Object.keys(data).forEach(function(key: string) {
-                // Some fields the user cannot change (groups and groupsIsAdmin must be changed through addGroupMember and addGroupAdmin in Admin)
-                if (!['readPerm','writePerm','forlifes','ips','groups','groupsIsAdmin'].includes(key)) { profil[key]=data[key]; }
-            });
-            // Modification propre par effet de bord
-            if (!(await Supervisor.delUser(uid) && await Supervisor.addUser(profil))) {
-                throw "Erreur dans la destruction/création du compte.";
-            } else {
-                return true;
-            }
-        }
-        catch(err) {
-            throw "Erreur lors de la modification des groupes où un utilisateur est admin.";
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/ldap/utilities.ts b/src/ldap/utilities.ts
index 19b5606..f336794 100644
--- a/src/ldap/utilities.ts
+++ b/src/ldap/utilities.ts
@@ -6,122 +6,7 @@
 
 import {ldapConfig} from './config';
 import {LDAP} from './basics';
-
-/**
- * @interface searchUserFields
- * @desc Interface permettant la recherche d'un utilisateur avec des champs incomplets. Plusieurs valeurs sont possibles pour le même champ.
- * Aucun de ces champs n'est obligatoire, mais certains de ces champs doivent être exacts pour obtenir un bon résultat.
- * @var {string|string[]} givenName - Prénom(s)
- * @var {string|string[]} lastName - Nom(s)
- * @var {string|string[]} nickname - Surnom(s)
- * @var {string|string[]} nationality - Nationalité(s) (à implémenter)
- * @var {string|string[]} promotion - Année(s) de promo
- * @var {string|string[]} phone - Numéro(s) de téléphone
- * @var {string|string[]} mail - Adresse(s) courriel
- * @var {string|string[]} ip - Adresse(s) ip
- * @var {string|string[]} adress - Adresse(s)
- * @var {string} school - Ecole d'appartenance (instable, doit être exact)
- * @var {string|string[]} groups - Un ou plusieurs groupes dont l'utilisateur est membre (doit être exact).
- * @var {string} course - PA ou autre. Doit être exact.
- */
-export interface searchUserFields {
-    givenName: string,
-    lastName: string,
-    nickname: string,
-    nationality: string,
-    promotion: string,
-    phone: string,
-    mail: string,
-    ip: string,
-    adress: string,
-    school: string,
-    groups: string[],
-    studies: string,
-    sport: string
-}
-
-//------------------------------------------------------------------------------------------------------------------------
-// Fonctions de recherche
-//------------------------------------------------------------------------------------------------------------------------
-
-export class SmartSearch {
-    /**
-     * @class Cette classe contient des fonctions de recherche génériques trop puissantes pour être exportées tel quel.
-     * @summary Constructeur vide.
-     * @author hawkspar
-    */
-    constructor() {}
-
-    /**
-     * @summary Fonction qui interroge le LDAP et retrouve les groupes (voir LDAP) qui ressemblent
-     *  à l'entrée. Etape 0 vers un vrai TOL (Trombino On Line).
-     * @desc Cette fonction utilise {@link LDAP.search} mais avec un filtre généré à la volée. 
-     * Accepte des champs exacts ou incomplets mais pas approximatifs
-     * et ne gère pas l'auto-complete. Cette fonction utilise aussi ldapConfig.json. MEF Timeout pour
-     * des recherches trop vagues. Renvoit une liste d'uid.
-     * Elle utilise LDAPEscape pour éviter les injections.
-     * @arg {string} input - String entré par l'utilisateur qui ressemble au nom du groupe.
-     * @arg {string[]} return_attributes - Liste d'attributs à renvoyer dans le résultat final
-     * @return {Promise(string[])} Liste des uid de groupes dont le nom ressemble à l'input
-     * @static
-     * @async
-     */
-    static async groups(input: string, return_attributes: string[]) : Promise<string[]> {
-        // Construction du filtre custom
-        let filter= "(|("+ldapConfig.key_id+"="+ input+")" +    // On cherche la valeur exacte
-                    "(|("+ldapConfig.key_id+"=*"+input+")" +    // La valeur finale avec des trucs avant ; wildcard *
-                    "(|("+ldapConfig.key_id+"=*"+input+"*)"+    // La valeur du milieu avec des trucs avant et après
-                    "("+  ldapConfig.key_id+"="+ input+"*))))"; // La valeur du début avec des trucs après
-
-        // Appel rechercheLDAP avec filtre de l'espace 
-        try {
-            return LDAP.search(ldapConfig.dn_groups, return_attributes, filter);
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche intelligente d'un groupe.";
-        }
-    }
-
-    /**
-     * @summary Fonction qui renvoit les attributs demandés des paxs validant les critères de recherche. Première étape vers vrai TOL (Trombino On Line).
-     * @desc Cette fonction utilise {@link LDAP.search} mais avec un filtre généré à la volée. Accepte des champs exacts ou incomplets pour la plupart des champs
-     * mais pas approximatifs et ne gère pas l'auto-complete. MEF Timeout pour des recherches trop vagues. Elle utilise LDAPEscape pour éviter les injections.
-     * Utiliser trouverGroupesParTypes pour chaque champ relié à groups.
-     * @arg {searchUserFields} data - Dictionnaire contenant les données nécessaires à la recherche. Les valeurs sont celles entrées par l'utilisateur et sont par hypothèse
-     * comme des sous-parties compactes des valeurs renvoyées. Tous les champs ci-dessous peuvent être indifféremment des listes (par exempl pour chercher un membre
-     * de plusieurs groupes) ou des éléments isolés. Si un champ n'est pas pertinent, le mettre à '' ou undefined.
-     * @arg {string[]} return_attributes - Liste d'attributs à renvoyer dans le résultat final.
-     * @return {Promise(Object[])} Liste de dictionnaires de profils en cohérence avec l'input avec pour clés les attributs des profils.
-     * @static
-     * @async
-     */
-    static async users(data: searchUserFields, return_attributes: string[]) : Promise<string[]> {
-        let filter="";
-        // Iteration pour chaque champ, alourdissement du filtre selon des trucs prédéfinis dans ldapConfig encore
-        for (var key in data) {
-            if ((data[key]!= undefined) && (data[key] != '')) {                    // Si il y a qque chose à chercher pour ce filtre
-                if (!Array.isArray(data[key])) { data[key]=[data[key]]; }          // Gestion d'une liste de valeurs à rechercher
-                // Iteration pour chaque valeur fournie par l'utilisateur
-                data[key].forEach(val => {
-                    // Traduction en language LDAP
-                    let attribute = ldapConfig.user[key];
-                    // Creation incrémentale du filtre
-                    filter="(&"+filter+ "(|("+attribute+"="+ val+")"+      // On cherche la valeur exacte
-                                        "(|("+attribute+"=*"+val+")"+      // La valeur finale avec des trucs avant ; wildcard * (MEF la wildcart ne marche pas pour tous les attributs)
-                                        "(|("+attribute+"=*"+val+"*)"+     // La valeur du milieu avec des trucs avant et après
-                                        "("+  attribute+"="+ val+"*)))))"; // La valeur du début avec des trucs après
-                });
-            }
-        }
-        // Appel avec filtre de l'espace 
-        try {
-            return LDAP.search(ldapConfig.dn_users, return_attributes, filter);
-        }
-        catch(err) {
-            throw "Erreur lors de la recherche intelligente d'un utilisateur.";
-        }
-    }
-}
+import {Group} from './group';
 
 //------------------------------------------------------------------------------------------------------------------------
 // Fonctions intermédiaires TBT
@@ -148,7 +33,7 @@ export class Tests {
      * dans le dn fourni.
      * @param {string} value - Valeur de l'attribut (le plus souvent un identifiant) à tester à cette itération
      * @param {string} attribute - Attribut à tester
-     * @param {string} dn - *Domain Name* dans lequel l'attribut doit être unique
+     * @param {"gr"|"us"} domain - Domaine dans lequel l'attribut doit être unique
      * @param {changeValueCallback} changeValue - Fonction qui prend uniquement en argument l'id courant et 
      * le nombre d'itérations et qui renvoit la prochaine valeur de l'attribut 
      * @param {int} n [0] - Nombre d'itérations (à initialiser à 0)
@@ -156,15 +41,15 @@ export class Tests {
      * @static
      * @async
      */
-    static async ensureUnique(value: string, attribute: string, dn: string, changeValue: (string, number) => string, n=0) : Promise<string> {
+    static async ensureUnique(value: string, attribute: string, domain: 'gr'|'us', changeValue: (string, number) => string, n=0) : Promise<string> {
         // Recherche d'autres occurences de l'id
         try {
-            return LDAP.search(dn, ldapConfig.key_id, "("+attribute+"="+value+")").then(function (matches: string[]) {
+            return LDAP.search(domain, [ldapConfig.key_id], null, "("+attribute+"="+value+")").then(function (matches: string[]) {
                 if (!matches) { throw ""; }
                 // On renvoit la valeur si elle est bien unique
                 else if (matches.length==0) { return value; }
                 // Sinon, on tente de nouveau notre chance avec la valeur suivante
-                else { return Tests.ensureUnique(changeValue(value, n+1), attribute, dn, changeValue, n+1); }
+                else { return Tests.ensureUnique(changeValue(value, n+1), attribute, domain, changeValue, n+1); }
             });
         }
         catch(err) {
@@ -185,7 +70,7 @@ export class Tests {
     static async generateUid(givenName: string, lastName: string, promotion: string) : Promise<string> {
         try {
             // normalize et lowerCase standardisent le format
-            return this.ensureUnique((givenName+'.'+lastName).toLowerCase().normalize('UFD'), ldapConfig.key_id, ldapConfig.dn_users, (id: string, n: number) => {
+            return this.ensureUnique((givenName+'.'+lastName).toLowerCase().normalize('UFD'), ldapConfig.key_id, "us", (id: string, n: number) => {
                 if (n==1) { id+='.'+promotion; }                // Si prénom.nom existe déjà, on rajoute la promo
                 else if (n==2) { id+='.'+(n-1).toString(); }    // Puis si prénom.nom.promo existe déjà on passe à nom.prenom.promo .1
                 else if (n>2) { id+=n; }                        // Ensuite on continue .123, .1234, etc...
@@ -208,7 +93,7 @@ export class Tests {
     static async generateReadableId(name: string) : Promise<string> {
         try {
             // normalize et lowerCase standardisent le format
-            return this.ensureUnique(name.toLowerCase().normalize('UFD'), ldapConfig.key_id, ldapConfig.dn_groups, (id: string, n: number) => {
+            return this.ensureUnique(name.toLowerCase().normalize('UFD'), ldapConfig.key_id, "gr", (id: string, n: number) => {
                 if (n==1) { id+='.'+n.toString(); }   // Si nom existe déjà, on essaie nom.1
                 else if (n>1) { id+=n.toString(); }   // Ensuite on continue .12, .123, etc...
                 return id;
@@ -222,17 +107,122 @@ export class Tests {
     /**
      * @summary Cette fonction teste une valeur dummy (0) pour un identifiant numérique puis le fait évoluer aléatoirement (entre 1 et 100 000) jusqu'à ce qu'il soit unique.
      * @param {string} attribut - Intitulé exact de l'id concerné
-     * @param {string} dn - *Domain Name* dans lequel l'attribut doit être unique
+     * @param {"gr"|"us"} domain - Domaine dans lequel l'attribut doit être unique
      * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
      * @static
      * @async
      */
-    static async generateId(attribut: string, dn: string) : Promise<string> {
+    static async generateId(attribut: string, domain: "gr"|"us") : Promise<string> {
         try {
-            return this.ensureUnique("0", attribut, dn, (id,n) => { return Math.floor((Math.random() * 100000) + 1).toString(); });
+            return this.ensureUnique("0", attribut, domain, (id,n) => { return Math.floor((Math.random() * 100000) + 1).toString(); });
         }
         catch(err) {
             throw "Erreur lors de l'assurance de l'unicité d'un unique identifier numérique.";
         }
     }
+
+    /**
+     * @summary Fonction qui retrouve les groupes dont un individu est membre.
+     * @desc Cette fonction utilise {@link LDAP.search} va directement à la feuille de l'utilisateur.
+     * @arg {string} uid - Identifiant de l'individu à interroger (le plus souvent prenom.nom, parfois l'année, supposé valide)
+     * @return {Promise(string[])} Liste des uid de groupes (noms flat des groupes) où l'id fourni est membre
+     * @static
+     * @async
+     */
+    static async getGroups(uid: string) {
+        try {
+            return LDAP.search("us", [ldapConfig.user.groups], uid)[0];
+        }
+        catch(err) {
+            throw "Erreur lors de la recherche des groupes d'un individu.";
+        }
+    }
+    
+    /**
+     * @summary Fonction qui retrouve la liste des membres d'un groupe.
+     * @desc Cette fonction utilise {@link LDAP.search} avec un dictionnaire prédéfini dans ldapConfig.json.
+     * @arg {string} gid - Identifiant du groupe à interroger (le plus souvent nom du groupe en minuscule)
+     * @return {Promise(String[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
+     * @static
+     * @async
+     */
+    static async getMembers(gid: string) {
+        try {
+            return LDAP.search("gr", [ldapConfig.group.members], gid)[0];
+        }
+        catch(err) {
+            throw "Erreur lors de la recherche des membres d'un groupe.";
+        }
+    }
+    
+    /**
+     * @summary Fonction qui retrouve la liste des admins d'un groupe.
+     * @desc Cette fonction utilise {@link LDAP.search} avec un dictionnaire prédéfini dans ldapConfig.json.
+     * @arg {string} gid - Identifiant du groupe à interroger (le plus souvent nom du groupe en minuscule)
+     * @return {Promise(string[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
+     * @static
+     * @async
+     */
+    static async getAdmins(gid: string) {
+        try {
+            return LDAP.search("gr", [ldapConfig.group.admins], gid)[0];
+        }
+        catch(err) {
+            throw "Erreur lors de la recherche des admins d'un groupe.";
+        }
+    }
+
+    /**
+     * @summary Cette fonction teste si un utilisateur est membre d'un groupe.
+     * @desc Utilise les méthodes statiques {@link open.getGroups} et {@link open.getMembers}
+     * @param {string} uid - Identifiant de l'utilisateur à tester 
+     * @param {string} gid  - Identification du groupe à tester
+     * @returns {Promise(boolean)} True si l'utilisateur est membre
+     * @static
+     * @async
+     */
+    static async isGroupMember(uid: string, gid: string) {
+        try {
+            let lg = await Tests.getGroups(uid);
+            let lm = await Tests.getMembers(gid);
+            if (lg.includes(gid) && lm.includes(uid)) {
+                return true;
+            }
+            // Réalignement forcé
+            else if (lg.includes(gid) || lm.includes(uid)) {
+                Group.addMember(uid, gid);
+                return true;
+            }
+            else { return false; }
+        }
+        catch(err) {
+            throw "Erreur lors du test d'appartenance à un groupe.";
+        }
+    }
+
+    /**
+     * @summary Cette fonction teste si un utilisateur est admin d'un groupe.
+     * @desc Utilise la méthode statique {@link Open.getAdmins}
+     * @param {string} uid - Identifiant de l'utilisateur à tester 
+     * @param {string} gid  - Identification du groupe à tester
+     * @returns {Promise(boolean)} True si l'utilisateur est administrateur
+     * @static
+     * @async
+     */
+    static async isGroupAdmin(uid: string, gid: string) {
+        try {
+            let lm = await Tests.getMembers(gid);
+            let la = await Tests.getAdmins(gid);
+            if (la.includes(uid) && lm.includes(uid)) { return true; }
+            // Réalignement forcé
+            else if (la.includes(uid)) {
+                Group.addAdmin(uid, gid);
+                return true;
+            }
+            else { return false; }
+        }
+        catch(err) {
+            throw "Erreur lors du test d'appartenance au bureau d'administration un groupe.";
+        }
+    }
 }
\ No newline at end of file
-- 
GitLab