diff --git a/.env b/.env index bd2a7bb5..0f480a58 100644 --- a/.env +++ b/.env @@ -21,6 +21,7 @@ SHUFFLE_DEFAULT_APIKEY= # Local location of your app directory. Can't use ~/ # Files will get better at some point. Right now: local saving. +SHUFFLE_APP_HOTLOAD_FOLDER=./shuffle-apps SHUFFLE_APP_HOTLOAD_LOCATION=./shuffle-apps SHUFFLE_FILE_LOCATION=./shuffle-files @@ -29,18 +30,33 @@ BACKEND_HOSTNAME=shuffle-backend BACKEND_PORT=5001 FRONTEND_PORT=3001 FRONTEND_PORT_HTTPS=3443 +# CHANGE THIS IF YOU WANT GOOD LOCAL EXECUTIONS: OUTER_HOSTNAME=shuffle-backend DB_LOCATION=./shuffle-database # Proxy configurations. SHUFFLE_PASS_WORKER_PROXY must be FALSE to not pass the proxy information to sub-apps. -# PS: It will skip proxy for -SHUFFLE_HTTP_PROXY= -SHUFFLE_HTTPS_PROXY= +# PS: It will skip proxy for +HTTP_PROXY= +HTTPS_PROXY= SHUFFLE_PASS_WORKER_PROXY=TRUE +SHUFFLE_PASS_APP_PROXY=FALSE SHUFFLE_BASE_IMAGE_REGISTRY=ghcr.io SHUFFLE_BASE_IMAGE_NAME=frikky -SHUFFLE_BASE_IMAGE_TAG_SUFFIX="-0.8.60" +SHUFFLE_BASE_IMAGE_TAG_SUFFIX="-0.8.80" # Used for auto-cleanup of containers. REALLY important at scale. SHUFFLE_CONTAINER_AUTO_CLEANUP=false +SHUFFLE_ELASTIC=true + +# DATABASE CONFIGURATIONS +DATASTORE_EMULATOR_HOST=shuffle-database:8000 +#SHUFFLE_OPENSEARCH_URL=https://shuffle-opensearch:9200 +SHUFFLE_OPENSEARCH_URL=http://shuffle-opensearch:9200 +SHUFFLE_OPENSEARCH_USERNAME= +SHUFFLE_OPENSEARCH_PASSWORD= +SHUFFLE_OPENSEARCH_CERTIFICATE_FILE= +SHUFFLE_OPENSEARCH_APIKEY= +SHUFFLE_OPENSEARCH_CLOUDID= +SHUFFLE_OPENSEARCH_PROXY= +SHUFFLE_OPENSEARCH_SKIPSSL_VERIFY=true diff --git a/.github/install-guide.md b/.github/install-guide.md index 34a1f6f2..14440867 100644 --- a/.github/install-guide.md +++ b/.github/install-guide.md @@ -1,23 +1,40 @@ # Installation guide Installation of Shuffle is currently only available in docker. Looking for how to update Shuffle? Check the [updating guide](https://shuffler.io/docs/configuration#updating_shuffle) -## Docker -The Docker setup is done with docker-compose and is a single command to get set up. +This document outlines a an introduction environment which is not scalable. [Read here](https://shuffler.io/docs/configuration#production_readiness) for information on production readiness. + +# Docker - *nix +The Docker setup is done with docker-compose **PS: if you're setting up Shuffle on Windows, go to the next step (Windows Docker setup)** -1. Make sure you have Docker and [docker-compose](https://docs.docker.com/compose/install/) installed. -2. Adapt the .env file to your convenience. -3. Run docker-compose. +1. Make sure you have [Docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/) installed. +2. Download Shuffle ``` git clone https://github.com/frikky/Shuffle cd Shuffle +``` + +3. Fix prerequisites for the Opensearch database (Elasticsearch): +``` +sudo chown 1000:1000 -R shuffle-database # Required for Opensearch +sudo sysctl -w vm.max_map_count=262144 # https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html + +# To make the changes permanent, do: +# 1. Open the file /etc/sysctl.conf +# 2. Go to the bottom of the file +# 3. Add this line: +vm.max_map_count=262144 +``` + +4. Run docker-compose. +``` docker-compose up -d ``` When you're done, skip to the "After installation" step below. -## Windows Docker setup +## Windows with WSL This step is for setting up with Docker on windows from scratch. 1. Make sure you have [Docker](https://docs.docker.com/docker-for-windows/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed. WSL2 may be required. @@ -27,7 +44,18 @@ This step is for setting up with Docker on windows from scratch. ``` OUTER_HOSTNAME=YOUR.IP.HERE ``` -5. Run docker-compose + +5. Configure max memory (WSL) by opening a new CMD/Powershell window. Required for Elasticsearch +``` +wsl -d docker-desktop +sysctl -w vm.max_map_count=262144 +echo "vm.max_map_count = 262144" > /etc/sysctl.d/99-docker-desktop.conf +echo -e "\nvm.max_map_count = 262144\n" >> /etc/sysctl.d/00-alpine.conf + +# https://stackoverflow.com/questions/42111566/elasticsearch-in-windows-docker-image-vm-max-map-count +``` + +6. Run docker-compose ``` docker-compose up -d ``` @@ -35,53 +63,20 @@ docker-compose up -d ### Configurations (proxies, default users etc.) https://shuffler.io/docs/configuration -### After installation -1. After installation, go to http://localhost:3001/adminsetup (or your servername) - -2. Now set up your admin account (username & password). Shuffle doesn't have a default username and password. -3. Check out https://shuffler.io/docs/configuration as it has a lot of useful information to get started +### After installation +1. After installation, go to http://localhost:3001/adminsetup (or your servername - https is on port 3443) +2. Now set up your admin account (username & password). Shuffle doesn't have a default username and password. +3. Sign in with the same Username & Password! Go to /apps and see if you have any apps yet. If not - you may need to [configure proxies](https://shuffler.io/docs/configuration#production_readiness) +4. Check out https://shuffler.io/docs/configuration as it has a lot of useful information to get started ![Admin account setup](https://github.com/frikky/Shuffle/blob/master/frontend/src/assets/img/shuffle_adminaccount.png) ### Useful info * Check out [getting started](https://shuffler.io/docs/getting_started) +* The default state of Shuffle is NOT scalable. See [production setup](https://shuffler.io/docs/configuration#production_readiness) for more info * The server is available on http://localhost:3001 (or your servername) * Further configurations can be done in docker-compose.yml and .env. -* Default database location is /etc/shuffle - -### Execution problems -If you have problems with your first execution (hello world), you might need to set the correct Docker API version. Here's how: - -1. Find your API version by running "docker version" -``` -$ docker version - -Client: - Version: 17.09.1-ce - API version: 1.32 # <-- this one - Go version: go1.8.3 - Git commit: 19e2cf6 - Built: Thu Dec 7 22:24:16 2017 - OS/Arch: linux/amd64 - -Server: - Version: 17.09.1-ce - API version: 1.32 (minimum version 1.12) - Go version: go1.8.3 - Git commit: 19e2cf6 - Built: Thu Dec 7 22:22:56 2017 - OS/Arch: linux/amd64 - Experimental: false -``` - -2. Open docker-compose.yml and change the line with "DOCKER_API_VERSION" to your version. -3. Restart docker-compose -``` -docker-compose down -docker-compose up -``` - -Related issue: #47 +* Default database location is in the same folder: ./shuffle-database # Local development installation Local development is pretty straight forward with **ReactJS** and **Golang**. This part is intended to help you run the code for development purposes. @@ -100,7 +95,7 @@ npm start ## Backend - Golang http://localhost:5001 - REST API - requires [>=go1.13](https://golang.org/dl/) ```bash -export DATASTORE_EMULATOR_HOST=0.0.0.0:8000 +export SHUFFLE_OPENSEARCH_URL="http://localhost:9200" cd backend/go-app go run *.go ``` @@ -121,7 +116,6 @@ cd functions/onprem/orborus go run orborus.go ``` - Environments (modify for Windows): ``` export ORG_ID=Shuffle diff --git a/.gitignore b/.gitignore index ca9d2090..4d3f2d80 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,11 @@ functions/generated_apps backend/onprem/app_sdk/apps *test.py -shuffle-database *.exe *debug* + +shuffle-database/batch_metrics_enabled.conf +shuffle-database/logging_enabled.conf +shuffle-database/nodes +shuffle-database/performance_analyzer_enabled.conf +shuffle-database/rca_enabled.conf diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index c3bc15c4..a4da37fb 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -22,6 +22,7 @@ class AppBase: # apikey is for the user / org # authorization is for the specific workflow + self.url = os.getenv("CALLBACK_URL", "https://shuffler.io") self.base_url = os.getenv("BASE_URL", "https://shuffler.io") self.action = os.getenv("ACTION", "") @@ -54,7 +55,7 @@ class AppBase: # for action["parameters"] # print("AUTH: ", key, value) # params[item["key"]] = item["value"] - #except KeyError: + #except KeyError: # print("No authentication specified!") # pass @@ -513,10 +514,31 @@ class AppBase: # return print("[INFO] Multiplier length: %d" % len(param_multiplier)) + #tmp = "" for subparams in param_multiplier: print(f"SUBPARAMS IN MULTI: {subparams}") try: - tmp = await func(**subparams) + #tmp = await func(**subparams) + + while True: + try: + tmp = await func(**subparams) + break + except TypeError as e: + errorstring = "%s" % e + if "got an unexpected keyword argument" in errorstring: + fieldsplit = errorstring.split("'") + if len(fieldsplit) > 1: + field = fieldsplit[1] + + try: + del subparams[field] + print("Removed field invalid field %s" % field) + except KeyError: + break + else: + raise e + except: e = "" try: @@ -661,6 +683,59 @@ class AppBase: else: return returns + def set_cache(self, key, value): + org_id = self.full_execution["workflow"]["execution_org"]["id"] + url = "%s/api/v1/orgs/%s/set_cache" % (self.url, org_id) + data = { + "workflow_id": self.full_execution["workflow"]["id"], + "execution_id": self.current_execution_id, + "authorization": self.authorization, + "org_id": org_id, + "key": key, + "value": str(value), + } + + response = requests.post(url, json=data) + try: + allvalues = response.json() + allvalues["key"] = key + allvalues["value"] = str(value) + return allvalues + except: + print("Value couldn't be parsed") + #return response.json() + return {"success": False} + + def get_cache(self, key): + org_id = self.full_execution["workflow"]["execution_org"]["id"] + url = "%s/api/v1/orgs/%s/get_cache" % (self.url, org_id) + data = { + "workflow_id": self.full_execution["workflow"]["id"], + "execution_id": self.current_execution_id, + "authorization": self.authorization, + "org_id": org_id, + "key": key, + } + + value = requests.post(url, json=data) + try: + allvalues = value.json() + print("VAL1: ", allvalues) + allvalues["key"] = key + print("VAL2: ", allvalues) + + try: + parsedvalue = json.loads(allvalues["value"]) + allvalues["value"] = parsedvalue + except: + print("Parsing of value as JSON failed. Continue anyway!") + + return allvalues + except: + print("Value couldn't be parsed, or json dump of value failed") + #return value.json() + return {"success": False} + # Sets files in the backend def set_files(self, infiles): full_execution = self.full_execution @@ -859,7 +934,6 @@ class AppBase: return parse_nested_param(string + ')', level) elif len(re.findall("\(", string)) < len(re.findall("\)", string)): return parse_nested_param('(' + string, level) - else: return 'Failed to parse params' @@ -950,23 +1024,25 @@ class AppBase: print(f"JSON ERROR in join(): {e}") if "len" in thistype or "length" in thistype or "lenght" in thistype: - tmp = "" + print(f"Trying to length-parse: {data}") try: - tmp = json.loads(tmpdata) - except: + tmp_len = json.loads(data, parse_float=str, parse_int=str, parse_constant=str) + except (NameError, KeyError, TypeError, json.decoder.JSONDecodeError) as e: try: - tmpdata = data.replace("\'", "\"") - tmp = json.loads(tmpdata) - except: - print("[ERROR] Parsing bug for length in app sdk") - pass + print(f"[WARNING] INITIAL Parsing bug for length in app sdk: {e}") + # data = data.replace("\'", "\"") + data = data.replace("True", "true") + data = data.replace("False", "false") + data = data.replace("None", "null") + data = data.replace("\"", "\\\"") + data = data.replace("'", "\"") - if isinstance(tmp, list): - return str(len(tmp)) - elif isinstance(tmp, object): - return str(len(tmp)) + tmp_len = json.loads(data, parse_float=str, parse_int=str, parse_constant=str) + except (NameError, KeyError, TypeError, json.decoder.JSONDecodeError) as e: + tmp_len = str(data) + + return str(len(tmp_len)) - return str(len(data)) if "parse" in thistype: splitvalues = [] default_error = """Error. Expected syntax: parse(["hello","test1"],0:1)""" @@ -1003,49 +1079,65 @@ class AppBase: def parse_wrapper(data): try: if "(" not in data or ")" not in data: - return (data, False) + return data, False except TypeError: - return (data, False) - - #print("Running %s" % data) - - # Look for the INNER wrapper first, then move out - wrappers = ["int", "number", "lower", "upper", "trim", "strip", "split", "parse", "len", "length", "lenght", "join"] - found = False - for wrapper in wrappers: - if wrapper not in data.lower(): - continue - - found = True - break - - if not found: - return (data, False) - + return data, False + + wrappers = ["int", "number", "lower", "upper", "trim", "strip", "split", "parse", "len", "length", "lenght", + "join"] + + if not any(wrapper in data for wrapper in wrappers): + return data, False + # Do stuff here. - innervalue = parse_nested_param(data, maxDepth(data)-0) - outervalue = parse_nested_param(data, maxDepth(data)-1) - print("INNER: ", innervalue) - print("OUTER: ", outervalue) - - if outervalue != innervalue: - #print("Outer: ", outervalue, " inner: ", innervalue) - for key in range(len(innervalue)): - # Replace OUTERVALUE[key] with INNERVALUE[key] in data. - print("Replace %s with %s in %s" % (outervalue[key], innervalue[key], data)) - data = data.replace(outervalue[key], innervalue[key]) - else: - for thistype in wrappers: - if thistype.lower() not in data.lower(): + inner_value = parse_nested_param(data, maxDepth(data) - 0) + outer_value = parse_nested_param(data, maxDepth(data) - 1) + + print("INNER: ", inner_value) + print("OUTER: ", outer_value) + + wrapper_group = "|".join(wrappers) + parse_string = data + max_depth = maxDepth(parse_string) + + if outer_value != inner_value: + for casting_items in reversed(range(max_depth + 1)): + c_parentheses = parse_nested_param(parse_string, casting_items)[0] + match_string = re.escape(c_parentheses) + custom_casting = re.findall(fr"({wrapper_group})\({match_string}", parse_string) + + # no matching ; go next group + if len(custom_casting) == 0: continue - - parsed_value = parse_type(innervalue[0], thistype.lower()) - print("Parsed value from %s: %s" % (thistype, parsed_value)) - return (parsed_value, True) - - #print("DATA: %s\n" % data) - return (parse_wrapper(data)[0], True) - + + inner_result = parse_type(c_parentheses, custom_casting[0]) + + # if result is a string then parse else return + if isinstance(inner_result, str): + parse_string = parse_string.replace(f"{custom_casting[0]}({c_parentheses})", inner_result) + elif isinstance(inner_result, list): + parse_string = parse_string.replace(f"{custom_casting[0]}({c_parentheses})", + json.dumps(inner_result)) + else: + parse_string = inner_result + break + else: + c_parentheses = parse_nested_param(parse_string, 0)[0] + match_string = re.escape(c_parentheses) + custom_casting = re.findall(fr"({wrapper_group})\({match_string}", parse_string) + + # check if a wrapper was found + if len(custom_casting) != 0: + inner_result = parse_type(c_parentheses, custom_casting[0]) + if isinstance(inner_result, str): + parse_string = parse_string.replace(f"{custom_casting[0]}({c_parentheses})", inner_result) + elif isinstance(inner_result, list): + parse_string = parse_string.replace(f"{custom_casting[0]}({c_parentheses})", + json.dumps(inner_result)) + else: + parse_string = inner_result + + return parse_string, True # Looks for parantheses to grab special cases within a string, e.g: # int(1) lower(HELLO) or length(what's the length) @@ -1121,15 +1213,19 @@ class AppBase: # Parses JSON loops and such down to the item you're looking for def recurse_json(basejson, parsersplit): - match = "#(\d+):?-?([0-9a-z]+)?#?" + match = "#([0-9a-z]+):?-?([0-9a-z]+)?#?" #print("Split: %s\n%s" % (parsersplit, basejson)) try: outercnt = 0 # Loops over split values for value in parsersplit: + #if " " in value: + # value = value.replace(" ", "_", -1) + #print("VALUE: %s\n" % value) actualitem = re.findall(match, value, re.MULTILINE) + #print("ACTUAL RECURSE: (%s) %s" % (value, actualitem)) if value == "#": newvalue = [] for innervalue in basejson: @@ -1158,7 +1254,12 @@ class AppBase: # Means it's a single item -> continue if seconditem == "": - #print("[INFO] In first - handling %s" % firstitem) + print("[INFO] In first - handling %s. Len: %d" % (firstitem, len(basejson))) + if firstitem.lower() == "max" or firstitem.lower() == "last": + firstitem = len(basejson)-1 + if firstitem.lower() == "min" or firstitem.lower() == "first": + firstitem = 0 + tmpitem = basejson[int(firstitem)] try: newvalue, is_loop = recurse_json(tmpitem, parsersplit[outercnt+1:]) @@ -1166,16 +1267,23 @@ class AppBase: newvalue, is_loop = (tmpitem, parsersplit[outercnt+1:]) else: print("[INFO] In ELSE - handling %s and %s" % (firstitem, seconditem)) - if seconditem == "max": - seconditem = len(basejson) - if seconditem == "min": + if firstitem.lower() == "max" or firstitem.lower() == "last": + firstitem = len(basejson)-1 + if firstitem.lower() == "min" or firstitem.lower() == "first": + firstitem = 0 + if seconditem.lower() == "max" or seconditem.lower() == "last": + seconditem = len(basejson)-1 + if seconditem.lower() == "min" or seconditem.lower() == "first": seconditem = 0 newvalue = [] - for i in range(int(firstitem), int(seconditem)): + if int(seconditem) > len(basejson): + seconditem = len(basejson) + + for i in range(int(firstitem), int(seconditem)+1): # 1. Check the next item (message) # 2. Call this function again - print("Base: %s" % basejson[i]) + #print("Base: %s" % basejson[i]) try: ret, is_loop = recurse_json(basejson[i], parsersplit[outercnt+1:]) @@ -1184,10 +1292,11 @@ class AppBase: #ret = innervalue ret, is_loop = recurse_json(innervalue, parsersplit[outercnt:]) - print(ret) + #print("IN LIST: %s" % ret) #exit() newvalue.append(ret) + #print("Returning %s" % newvalue) return newvalue, is_loop else: @@ -1195,16 +1304,43 @@ class AppBase: if len(value) == 0: return basejson, False - if isinstance(basejson[value], str): - print(f"LOADING STRING '%s' AS JSON" % basejson[value]) - try: - basejson = json.loads(basejson[value]) - except json.decoder.JSONDecodeError as e: - print("RETURNING BECAUSE '%s' IS A NORMAL STRING" % basejson[value]) - return basejson[value], False - else: - basejson = basejson[value] - + try: + if isinstance(basejson, list): + print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value) + return basejson, False + elif isinstance(basejson[value], str): + print(f"[INFO] LOADING STRING '%s' AS JSON" % basejson[value]) + try: + basejson = json.loads(basejson[value]) + print("BASEJSON: %s" % basejson) + except json.decoder.JSONDecodeError as e: + print("RETURNING BECAUSE '%s' IS A NORMAL STRING" % basejson[value]) + return basejson[value], False + else: + basejson = basejson[value] + except KeyError as e: + print("[WARNING] Running secondary value check with replacement of underscore in %s: %s" % (value, e)) + if "_" in value: + value = value.replace("_", " ", -1) + elif " " in value: + value = value.replace(" ", "_", -1) + + if isinstance(basejson, list): + print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value) + return basejson, False + elif isinstance(basejson[value], str): + print(f"[INFO] LOADING STRING '%s' AS JSON" % basejson[value]) + try: + basejson = json.loads(basejson[value]) + print("BASEJSON: %s" % basejson) + except json.decoder.JSONDecodeError as e: + print("RETURNING BECAUSE '%s' IS A NORMAL STRING" % basejson[value]) + return basejson[value], False + else: + basejson = basejson[value] + + + #print("Parsed BASEJSON: %s" % basejson) outercnt += 1 except KeyError as e: @@ -1240,12 +1376,28 @@ class AppBase: appendresult += char actionname_lower = "exec" + elif actionname_lower.startswith("shuffle_cache "): + actionname_lower = "shuffle_cache" actionname_lower = actionname_lower.replace(" ", "_", -1) try: if actionname_lower == "exec" or actionname_lower == "webhook" or actionname_lower == "schedule" or actionname_lower == "userinput" or actionname_lower == "email_trigger" or actionname_lower == "trigger": baseresult = execution_data["execution_argument"] + elif actionname_lower == "shuffle_cache": + print("SHOULD GET CACHE KEY: %s" % parsersplit) + if len(parsersplit) > 1: + actual_key = parsersplit[1] + print("KEY: %s" % actual_key) + cachedata = self.get_cache(actual_key) + print("CACHE: %s" % cachedata) + parsersplit.pop(1) + try: + baseresult = json.dumps(cachedata) + except json.decoder.JSONDecodeError as e: + print("Failed json dumping: %s" % e) + + #returndata = str(baseresult)+str(appendresult) else: #print("Within execution data check. Execution data: %s", execution_data["results"]) if execution_data["results"] != None: @@ -1302,7 +1454,9 @@ class AppBase: print("[INFO] After second return") if len(parsersplit) == 1: - return str(baseresult)+str(appendresult), False + returndata = str(baseresult)+str(appendresult) + print("RETURNING!")#: %s" % returndata) + return returndata, False baseresult = baseresult.replace(" True,", " true,") baseresult = baseresult.replace(" False", " false,") @@ -1320,9 +1474,17 @@ class AppBase: return str(baseresult)+str(appendresult), False print("[INFO] After fourth parser return as JSON") - data, is_loop = recurse_json(basejson, parsersplit[1:]) parseditem = data + + if isinstance(parseditem, dict) or isinstance(parseditem, list): + try: + parseditem = json.dumps(parseditem) + except json.decoder.JSONDecodeError as e: + print("Parseditem issue: %s" % e) + pass + + print("DATA: (%s) %s" % (type(data), data)) if is_loop: print("DATA IS A LOOP - SHOULD WRAP") if parsersplit[-1] == "#": @@ -1333,8 +1495,18 @@ class AppBase: print("SET DATA WRAPPER TO %s!" % parsersplit[-1]) parseditem = "${%s%s}$" % (parsersplit[-1], json.dumps(data)) + print("Before last return with %s" % appendresult) - return str(parseditem)+str(appendresult), is_loop + returndata = str(parseditem)+str(appendresult) + + # New in 0.8.97: Don't return items without lists + print("RETURNDATA: %s" % returndata) + #return returndata, is_loop + try: + return json.dumps(json.loads(returndata)), is_loop + except json.decoder.JSONDecodeError as e: + print("Error in decoder: %s" % e) + return returndata, is_loop # Parses parameters sent to it and returns whether it did it successfully with the values found def parse_params(action, fullexecution, parameter): @@ -1362,12 +1534,24 @@ class AppBase: continue # Handles for loops etc. - value, is_loop = get_json_value(fullexecution, to_be_replaced) + # FIXME: Should it dump to string here? Doesn't that defeat the purpose? + # Trying without string dumping. + value, is_loop = get_json_value(fullexecution, to_be_replaced) + #print("\n\nType of value: %s. Value: %s" % (type(value), value)) + print("\n\nType of value: %s" % type(value)) if isinstance(value, str): parameter["value"] = parameter["value"].replace(to_be_replaced, value) - elif isinstance(value, dict): + elif isinstance(value, dict) or isinstance(value, list): + # Changed from JSON dump to str() 28.05.2021 + # This makes it so the parameters gets lists and dicts straight up parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) + + #try: + # parameter["value"] = parameter["value"].replace(to_be_replaced, str(value)) + #except: + # parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) + # print("Failed parsing value as string?") else: print("Unknown type %s" % type(value)) try: @@ -1375,6 +1559,7 @@ class AppBase: except json.decoder.JSONDecodeError as e: parameter["value"] = parameter["value"].replace(to_be_replaced, value) + #print("VALUE: %s" % parameter["value"]) if parameter["variant"] == "WORKFLOW_VARIABLE": print("Handling workflow variable") @@ -1575,16 +1760,15 @@ class AppBase: "matches regex", ] - # FIXME - what should I do here? if not condition["condition"]["value"] in available_checks: self.logger.warning("Skipping %s %s %s because %s is invalid." % (sourcevalue, condition["condition"]["value"], destinationvalue, condition["condition"]["value"])) continue #print(destinationvalue) # NEGATE - validation = run_validation(sourcevalue, condition["condition"]["value"], destinationvalue) # Configuration = negated because of WorkflowAppActionParam.. + validation = run_validation(sourcevalue, condition["condition"]["value"], destinationvalue) try: if condition["condition"]["configuration"]: validation = not validation @@ -1602,9 +1786,18 @@ class AppBase: return True, "" + # THE START IS ACTUALLY RIGHT HERE :O # Checks whether conditions are met, otherwise set branchcheck, tmpresult = check_branch_conditions(action, fullexecution) + if isinstance(tmpresult, object) or isinstance(tmpresult, list): + print("Fixing branch return as object -> string") + try: + #tmpresult = tmpresult.replace("'", "\"") + tmpresult = json.dumps(tmpresult) + except json.decoder.JSONDecodeError as e: + print(f"[WARNING] Failed condition parsing {tmpresult} to string") + if not branchcheck: self.logger.info("Failed one or more branch conditions.") action_result["result"] = tmpresult @@ -1691,23 +1884,21 @@ class AppBase: if values != None: added = 0 for val in values: - #print(f"VAL: {val}") - #parameter["value"].replace(val["key"], val["value"], -1) - #print(f'PARAM1: {action["parameters"][counter]["value"]}') - action["parameters"][counter]["value"] = action["parameters"][counter]["value"].replace(val["key"], val["value"], 1) - #action["parameters"][counter]["value"].replace(r"${url}", r"$Find_URLs.valid.#.data", 1) - #print(f'PARAM2: {action["parameters"][counter]["value"]}') - #newparams.append({ - # "name": val["key"], - # "value": val["value"], - # "variant": "STATIC_VALUE", - # "id": "body_replacement", - # "schema": { - # "type": "string", - # }, - #}) + replace_value = val["value"] + replace_key = val["key"] + if (val["value"].startswith("{") and val["value"].endswith("}")) or (val["value"].startswith("[") and val["value"].endswith("]")): + print(f"""Trying to parse as JSON: {val["value"]}""") + try: + value_replace = json.loads(val["value"]) + # If it gets here, remove the "" infront and behind the key as well since this is preventing the JSON from being loaded + replace_key = f"\"{replace_key}\"" + except json.decoder.JSONDecodeError as e: + print("Failed JSON replacement for OpenAPI %s", val["key"]) + elif val["value"].lower() == "true" or val["value"].lower() == "false": + replace_key = f"\"{replace_key}\"" + + action["parameters"][counter]["value"] = action["parameters"][counter]["value"].replace(replace_key, replace_value, 1) - #print(f'[INFO] Added param {val["key"]} for body with value {val["value"]} (using OpenAPI)') print(f'[INFO] Added param {val["key"]} for body (using OpenAPI)') added += 1 @@ -1718,6 +1909,34 @@ class AppBase: print("KeyError body OpenAPI: %s" % e) pass + try: + newvalue = json.loads(action["parameters"][counter]["value"]) + deletekeys = [] + for key, value in newvalue.items(): + if isinstance(value, str) and len(value) == 0: + deletekeys.append(key) + continue + + for deletekey in deletekeys: + del newvalue[deletekey] + + action["parameters"][counter]["value"] = json.dumps(newvalue) + + except json.decoder.JSONDecodeError as e: + print("Failed JSON replacement for OpenAPI keys (2) {e}") + + #if "\n" in action["parameters"][counter]["value"]: + # print("MODIFYING BODY!!") + # newbody = "" + # for line in action["parameters"][counter]["value"].split("\n"): + # if ": \"\"" in line: + # print("Skipping line %s" % line) + # continue + + # newbody += line + + # print("New body: %s" % newbody) + break #print(action["parameters"]) @@ -1802,7 +2021,6 @@ class AppBase: print("PRE new_replacement") - # FIXME: Only do this IF they want to loop new_replacement = [] for i in range(len(json_replacement)): if isinstance(json_replacement[i], dict) or isinstance(json_replacement[i], list): @@ -1858,6 +2076,13 @@ class AppBase: params[parameter["name"]] = resultarray multi_parameters[parameter["name"]] = resultarray + #if len(resultarray) == 0: + # print("[WARNING] Returning empty array because the array length to be looped is 0 (1)") + # action_result["status"] = "SUCCESS" + # action_result["result"] = "[]" + # self.send_result(action_result, headers, stream_path) + # return + multi_execution_lists.append(new_replacement) #print("MULTI finished: %s" % json_replacement) else: @@ -1942,6 +2167,13 @@ class AppBase: # With this parameter ready, add it to... a greater list of parameters. Rofl print("LENGTH OF ARR: %d" % len(resultarray)) + if len(resultarray) == 0: + print("[WARNING] Returning empty array because the array length to be looped is 0 (0)") + action_result["status"] = "SUCCESS" + action_result["result"] = "[]" + self.send_result(action_result, headers, stream_path) + return + #print("RESULTARRAY: %s" % resultarray) if resultarray not in multi_execution_lists: multi_execution_lists.append(resultarray) @@ -2086,8 +2318,33 @@ class AppBase: return print("[INFO] Running normal execution\n") - newres = await func(**params) - print("\n[INFO] Returned from execution!")#, newres) + + #newres = await func(**params) + #print("PARAMS: %s" % params) + #newres = "" + while True: + try: + newres = await func(**params) + break + except TypeError as e: + newres = "" + errorstring = "%s" % e + if "got an unexpected keyword argument" in errorstring: + fieldsplit = errorstring.split("'") + if len(fieldsplit) > 1: + field = fieldsplit[1] + + try: + del params[field] + print("Removed field invalid field %s" % field) + except KeyError: + break + else: + raise e + #break + + print("\n[INFO] Returned from execution with types %s" % type(newres)) + #print("\n[INFO] Returned from execution with %s of types %s" % (newres, type(newres)))#, newres) if isinstance(newres, tuple): print("[INFO] Handling return as tuple") # Handles files. @@ -2328,7 +2585,6 @@ class AppBase: # self.action = cls app = cls(redis=None, logger=logger, console_logger=logger) - if isinstance(action, str): print("Normal execution. Action is a string.") elif isinstance(action, object): diff --git a/backend/app_sdk/build.sh b/backend/app_sdk/build.sh index eaee980c..1e52f74d 100644 --- a/backend/app_sdk/build.sh +++ b/backend/app_sdk/build.sh @@ -1,9 +1,12 @@ #!/bin/bash + + +### DEFAULT NAME=shuffle-app_sdk -VERSION=0.8.64 +VERSION=0.8.104 docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force -docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION +docker build . -f Dockerfile -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION #docker push frikky/$NAME:$VERSION #docker push docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION @@ -12,3 +15,21 @@ docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg. docker push frikky/shuffle:app_sdk docker push ghcr.io/frikky/$NAME:$VERSION +docker push ghcr.io/frikky/$NAME:nightly + +#### BLACKARCH ### +NAME=shuffle-app_sdk_kali +docker build . -f Dockerfile_kali -t frikky/shuffle:app_sdk_kali -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION + +docker push frikky/shuffle:app_sdk_kali +docker push ghcr.io/frikky/$NAME:$VERSION +docker push ghcr.io/frikky/$NAME:nightly + +### BLACKARCH ### +NAME=shuffle-app_sdk_blackarch +docker build . -f Dockerfile_blackarch -t frikky/shuffle:app_sdk_blackarch -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION + +docker push frikky/shuffle:app_sdk_blackarch +docker push ghcr.io/frikky/$NAME:$VERSION +docker push ghcr.io/frikky/$NAME:nightly + diff --git a/backend/app_sdk/requirements.txt b/backend/app_sdk/requirements.txt index acde3f06..60b59271 100644 --- a/backend/app_sdk/requirements.txt +++ b/backend/app_sdk/requirements.txt @@ -1,2 +1,2 @@ -urllib3=1.25.9 -requests=2.25.1 +urllib3==1.25.9 +requests==2.25.1 diff --git a/backend/app_sdk_blackarch/Dockerfile b/backend/app_sdk_blackarch/Dockerfile deleted file mode 100644 index 02480aad..00000000 --- a/backend/app_sdk_blackarch/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM peterclemenko/blackarch as base - -FROM base as builder - -RUN /bin/pacman -Syu --noconfirm - -RUN /bin/pacman -Sy --noconfirm base-devel libffi musl openssl python python-pip -y - -RUN mkdir /install -WORKDIR /install - -COPY requirements.txt /requirements.txt -RUN pip install --prefix="/install" -r /requirements.txt - -FROM base - -COPY --from=builder /install /usr/local -COPY __init__.py /app/walkoff_app_sdk/__init__.py -COPY app_base.py /app/walkoff_app_sdk/app_base.py diff --git a/backend/app_sdk_blackarch/LICENSE b/backend/app_sdk_blackarch/LICENSE deleted file mode 100644 index ce11f6f3..00000000 --- a/backend/app_sdk_blackarch/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Frikkylikeme - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/backend/app_sdk_blackarch/README.md b/backend/app_sdk_blackarch/README.md deleted file mode 100644 index 754392ff..00000000 --- a/backend/app_sdk_blackarch/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# app_sdk.py -This is the SDK used for apps to behave like they should. -To change it in the backend, upload it to Buckets/shuffler.appspot.com/generated_apps/baseline. - -# static_baseline.py -It's used for python code generation and should be under MIT. Has to be located here because it's used by the backend. - -## If you want to update apps.. PS: downloads from docker hub do overrides.. :) -1. Write your code & check if runtime works -2. Build app_base image -3. docker rm $(docker ps -aq) # Remove all stopped containers -4. Delete the specific app's Docker image (docker rmi frikky/shuffle:...) -5. Rebuild the Docker image (click load in GUI?) - -# LICENSE -Everything in here is MIT, not AGPLv3 as indicated by the license. diff --git a/backend/app_sdk_blackarch/__init__.py b/backend/app_sdk_blackarch/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/app_sdk_blackarch/app_base.py b/backend/app_sdk_blackarch/app_base.py deleted file mode 100644 index e896f67c..00000000 --- a/backend/app_sdk_blackarch/app_base.py +++ /dev/null @@ -1,1169 +0,0 @@ -import os -import sys -import re -import time -import json -import logging -import requests -import urllib.parse - -class AppBase: - """ The base class for Python-based apps in Shuffle, handles logging and callbacks configurations""" - __version__ = None - app_name = None - - def __init__(self, redis=None, logger=None, console_logger=None):#, docker_client=None): - self.logger = logger if logger is not None else logging.getLogger("AppBaseLogger") - self.redis=redis - self.console_logger = logger if logger is not None else logging.getLogger("AppBaseLogger") - - # apikey is for the user / org - # authorization is for the specific workflow - self.url = os.getenv("CALLBACK_URL", "https://shuffler.io") - self.action = os.getenv("ACTION", "") - self.authorization = os.getenv("AUTHORIZATION", "") - self.current_execution_id = os.getenv("EXECUTIONID", "") - self.full_execution = os.getenv("FULL_EXECUTION", "") - - if isinstance(self.action, str): - self.action = json.loads(self.action) - - def send_result(self, action_result, headers, stream_path): - if action_result["status"] == "EXECUTING": - action_result["status"] = "FAILURE" - - # I wonder if this actually works - self.logger.info("Before last stream result") - try: - ret = requests.post("%s%s" % (self.url, stream_path), headers=headers, json=action_result) - self.logger.info("Result: %d" % ret.status_code) - if ret.status_code != 200: - self.logger.info(ret.text) - except requests.exceptions.ConnectionError as e: - self.logger.exception(e) - return - except TypeError as e: - self.logger.exception(e) - action_result["status"] = "FAILURE" - action_result["result"] = "POST error: %s" % e - self.logger.info("Before typeerror stream result") - ret = requests.post("%s%s" % (self.url, stream_path), headers=headers, json=action_result) - self.logger.info("Result: %d" % ret.status_code) - if ret.status_code != 200: - self.logger.info(ret.text) - - async def execute_action(self, action): - # FIXME - add request for the function STARTING here. Use "results stream" or something - # PAUSED, AWAITING_DATA, PENDING, COMPLETED, ABORTED, EXECUTING, SUCCESS, FAILURE - - # !!! Let this line stay - its used for some horrible codegeneration / stitching !!! # - #STARTCOPY - stream_path = "/api/v1/streams" - action_result = { - "action": action, - "authorization": self.authorization, - "execution_id": self.current_execution_id, - "result": "", - "started_at": int(time.time()), - "status": "EXECUTING" - } - self.logger.info("ACTION RESULT (start): %s", action_result) - - if len(self.action) == 0: - print("ACTION env not defined") - action_result["result"] = "Error in setup ENV: ACTION not defined" - self.send_result(action_result, headers, stream_path) - return - if len(self.authorization) == 0: - print("AUTHORIZATION env not defined") - action_result["result"] = "Error in setup ENV: AUTHORIZATION not defined" - self.send_result(action_result, headers, stream_path) - return - if len(self.current_execution_id) == 0: - print("EXECUTIONID env not defined") - action_result["result"] = "Error in setup ENV: EXECUTIONID not defined" - self.send_result(action_result, headers, stream_path) - return - - headers = { - "Content-Type": "application/json", - "Authorization": "Bearer %s" % self.authorization - } - - # Add async logger - # self.console_logger.handlers[0].stream.set_execution_id() - #self.logger.info("Before initial stream result") - try: - ret = requests.post("%s%s" % (self.url, stream_path), headers=headers, json=action_result) - self.logger.info("Workflow: %d" % ret.status_code) - if ret.status_code != 200: - self.logger.info(ret.text) - except requests.exceptions.ConnectionError as e: - print("Connectionerror: %s" % e) - - action_result["result"] = "Bad setup during startup: %s" % e - self.send_result(action_result, headers, stream_path) - return - - # Verify whether there are any parameters with ACTION_RESULT required - # If found, we get the full results list from backend - fullexecution = {} - if len(self.full_execution) == 0: - print("NO EXECUTION - LOADING!") - try: - tmpdata = { - "authorization": self.authorization, - "execution_id": self.current_execution_id - } - - self.logger.info("Before FULLEXEC stream result") - ret = requests.post( - "%s/api/v1/streams/results" % (self.url), - headers=headers, - json=tmpdata - ) - - if ret.status_code == 200: - fullexecution = ret.json() - else: - self.logger.info("Error: Data: ", ret.json()) - self.logger.info("Error with status code for results. Crashing because ACTION_RESULTS or WORKFLOW_VARIABLE can't be handled. Status: %d" % ret.status_code) - action_result["result"] = "Bad result from backend: %d" % ret.status_code - self.send_result(action_result, headers, stream_path) - return - except requests.exceptions.ConnectionError as e: - self.logger.info("Connectionerror: %s" % e) - action_result["result"] = "Connection error during startup: %s" % e - self.send_result(action_result, headers, stream_path) - return - else: - try: - fullexecution = json.loads(self.full_execution) - except json.decoder.JSONDecodeError as e: - print("Json decode execution error: %s" % e) - action_result["result"] = "Json error during startup: %s" % e - self.send_result(action_result, headers, stream_path) - return - - print("") - - - self.logger.info("AFTER FULLEXEC stream result") - - # Gets the value at the parenthesis level you want - def parse_nested_param(string, level): - """ - Generate strings contained in nested (), indexing i = level - """ - if len(re.findall("\(", string)) == len(re.findall("\)", string)): - LeftRightIndex = [x for x in zip( - [Left.start()+1 for Left in re.finditer('\(', string)], - reversed([Right.start() for Right in re.finditer('\)', string)]))] - - elif len(re.findall("\(", string)) > len(re.findall("\)", string)): - return parse_nested_param(string + ')', level) - elif len(re.findall("\(", string)) < len(re.findall("\)", string)): - return parse_nested_param('(' + string, level) - - else: - return 'Failed to parse params' - - try: - return [string[LeftRightIndex[level][0]:LeftRightIndex[level][1]]] - except IndexError: - return [string[LeftRightIndex[level+1][0]:LeftRightIndex[level+1][1]]] - - # Finds the deepest level parenthesis in a string - def maxDepth(S): - current_max = 0 - max = 0 - n = len(S) - - # Traverse the input string - for i in range(n): - if S[i] == '(': - current_max += 1 - - if current_max > max: - max = current_max - elif S[i] == ')': - if current_max > 0: - current_max -= 1 - else: - return -1 - - # finally check for unbalanced string - if current_max != 0: - return -1 - - return max-1 - - # Specific type parsing - def parse_type(data, thistype): - if data == None: - return "Empty" - - if "int" in thistype or "number" in thistype: - try: - return int(data) - except ValueError: - print("ValueError while casting %s" % data) - return data - if "lower" in thistype: - return data.lower() - if "upper" in thistype: - return data.upper() - if "trim" in thistype: - return data.strip() - if "strip" in thistype: - return data.strip() - if "split" in thistype: - return data.split() - if "len" in thistype or "length" in thistype: - tmp = "" - try: - tmp = json.loads(data) - except: - pass - - if isinstance(tmp, list): - return str(len(tmp)) - - return str(len(data)) - if "parse" in thistype: - splitvalues = [] - default_error = """Error. Expected syntax: parse(["hello","test1"],0:1)""" - if "," in data: - splitvalues = data.split(",") - - for item in range(len(splitvalues)): - splitvalues[item] = splitvalues[item].strip() - else: - return default_error - - lastsplit = [] - if ":" in splitvalues[-1]: - lastsplit = splitvalues[-1].split(":") - else: - try: - lastsplit = [int(splitvalues[-1])] - except ValueError: - return default_error - - try: - parsedlist = ",".join(splitvalues[0:-1]) - if len(lastsplit) > 1: - tmp = json.loads(parsedlist)[int(lastsplit[0]):int(lastsplit[1])] - else: - tmp = json.loads(parsedlist)[lastsplit[0]] - - print(tmp) - return tmp - except IndexError as e: - return default_error - - # Parses the INNER value and recurses until everything is done - def parse_wrapper(data): - try: - if "(" not in data or ")" not in data: - return data - except TypeError: - return data - - #print("Running %s" % data) - - # Look for the INNER wrapper first, then move out - wrappers = ["int", "number", "lower", "upper", "trim", "strip", "split", "parse", "len", "length"] - found = False - for wrapper in wrappers: - if wrapper not in data.lower(): - continue - - found = True - break - - if not found: - return data - - # Do stuff here. - innervalue = parse_nested_param(data, maxDepth(data)-0) - outervalue = parse_nested_param(data, maxDepth(data)-1) - print("INNER: ", innervalue) - print("OUTER: ", outervalue) - - if outervalue != innervalue: - #print("Outer: ", outervalue, " inner: ", innervalue) - for key in range(len(innervalue)): - # Replace OUTERVALUE[key] with INNERVALUE[key] in data. - print("Replace %s with %s in %s" % (outervalue[key], innervalue[key], data)) - data = data.replace(outervalue[key], innervalue[key]) - else: - for thistype in wrappers: - if thistype.lower() not in data.lower(): - continue - - parsed_value = parse_type(innervalue[0], thistype.lower()) - return parsed_value - - print("DATA: %s\n" % data) - return parse_wrapper(data) - - def parse_wrapper_start(data): - newdata = [] - newstring = "" - record = True - paranCnt = 0 - for char in data: - if char == "(": - paranCnt += 1 - - if not record: - record = True - - if record: - newstring += char - - if paranCnt == 0 and char == " ": - newdata.append(newstring) - newstring = "" - record = True - - if char == ")": - paranCnt -= 1 - - if paranCnt == 0: - record = False - - if len(newstring) > 0: - newdata.append(newstring) - - #print(newdata) - parsedlist = [] - non_string = False - for item in newdata: - ret = parse_wrapper(item) - if not isinstance(ret, str): - non_string = True - - parsedlist.append(ret) - - if len(parsedlist) > 0 and not non_string: - return " ".join(parsedlist) - elif len(parsedlist) == 1 and non_string: - return parsedlist[0] - else: - #print("Casting back to string because multi: ", parsedlist) - newlist = [] - for item in parsedlist: - try: - newlist.append(str(item)) - except ValueError: - newlist.append("parsing_error") - return " ".join(newlist) - - # Parses JSON loops and such down to the item you're looking for - def recurse_json(basejson, parsersplit): - match = "#(\d+):?-?([0-9a-z]+)?#?" - print("Split: %s\n%s" % (parsersplit, basejson)) - try: - outercnt = 0 - - # Loops over split values - for value in parsersplit: - print("VALUE: %s\n" % value) - actualitem = re.findall(match, value, re.MULTILINE) - if value == "#": - newvalue = [] - for innervalue in basejson: - # 1. Check the next item (message) - # 2. Call this function again - - try: - ret, is_loop = recurse_json(innervalue, parsersplit[outercnt+1:]) - except IndexError: - # Only in here if it's the last loop without anything in it? - ret, is_loop = recurse_json(innervalue, parsersplit[outercnt:]) - - newvalue.append(ret) - - # Magical way of returning which makes app sdk identify - # it as multi execution - return newvalue, True - elif len(actualitem) > 0: - # FIXME: This is absolutely not perfect. - print("In recursion v2: ", actualitem) - - is_loop = True - newvalue = [] - firstitem = actualitem[0][0] - seconditem = actualitem[0][1] - - # Means it's a single item -> continue - if seconditem == "": - print("In first - handling %s", seconditem) - tmpitem = basejson[int(firstitem)] - try: - newvalue, is_loop = recurse_json(tmpitem, parsersplit[outercnt+1:]) - except IndexError: - newvalue, is_loop = (tmpitem, parsersplit[outercnt+1:]) - else: - if seconditem == "max": - seconditem = len(basejson) - if seconditem == "min": - seconditem = 0 - - newvalue = [] - for i in range(int(firstitem), int(seconditem)): - # 1. Check the next item (message) - # 2. Call this function again - print("Base: %s" % basejson[i]) - - try: - ret, is_loop = recurse_json(basejson[i], parsersplit[outercnt+1:]) - except IndexError: - print("INDEXERROR: ", parsersplit[outercnt]) - #ret = innervalue - ret, is_loop = recurse_json(innervalue, parsersplit[outercnt:]) - - print(ret) - #exit() - newvalue.append(ret) - - return newvalue, is_loop - - # FIXME: Add specific loop for other indexes - else: - #print("BEFORE NORMAL VALUE: ", basejson, value) - if len(value) == 0: - return basejson, False - - if isinstance(basejson[value], str): - print(f"LOADING STRING '%s' AS JSON" % basejson[value]) - try: - basejson = json.loads(basejson[value]) - except json.decoder.JSONDecodeError as e: - print("RETURNING BECAUSE '%s' IS A NORMAL STRING" % basejson[value]) - return basejson[value], False - else: - basejson = basejson[value] - - outercnt += 1 - - except KeyError as e: - print("Lower keyerror: %s" % e) - #return basejson - #return "KeyError: Couldn't find key: %s" % e - - return basejson, False - - # Takes a workflow execution as argument - # Returns a string if the result is single, or a list if it's a list - def get_json_value(execution_data, input_data): - parsersplit = input_data.split(".") - actionname = parsersplit[0][1:].replace(" ", "_", -1) - #Actionname: Start_node - - print(f"Actionname: {actionname}") - - # 1. Find the action - baseresult = "" - actionname_lower = actionname.lower() - try: - if actionname_lower == "exec" or actionname_lower == "webhook" or actionname_lower == "schedule" or actionname_lower == "userinput" or actionname_lower == "email_trigger" or actionname_lower == "trigger": - baseresult = execution_data["execution_argument"] - else: - for result in execution_data["results"]: - resultlabel = result["action"]["label"].replace(" ", "_", -1).lower() - if resultlabel.lower() == actionname_lower: - baseresult = result["result"] - break - - print("BEFORE VARIABLES!") - if len(baseresult) == 0: - try: - #print("WF Variables: %s" % execution_data["workflow"]["workflow_variables"]) - for variable in execution_data["workflow"]["workflow_variables"]: - variablename = variable["name"].replace(" ", "_", -1).lower() - - if variablename.lower() == actionname_lower: - baseresult = variable["value"] - break - except KeyError as e: - print("KeyError wf variables: %s" % e) - pass - except TypeError as e: - print("TypeError wf variables: %s" % e) - pass - - print("BEFORE EXECUTION VAR") - if len(baseresult) == 0: - try: - #print("Execution Variables: %s" % execution_data["execution_variables"]) - for variable in execution_data["execution_variables"]: - variablename = variable["name"].replace(" ", "_", -1).lower() - if variablename.lower() == actionname_lower: - baseresult = variable["value"] - break - except KeyError as e: - print("KeyError exec variables: %s" % e) - pass - except TypeError as e: - print("TypeError exec variables: %s" % e) - pass - - except KeyError as error: - print(f"KeyError in JSON: {error}") - - print(f"After first trycatch") - - # 2. Find the JSON data - if len(baseresult) == 0: - return "", False - - if len(parsersplit) == 1: - return baseresult, False - - baseresult = baseresult.replace("\'", "\"") - basejson = {} - try: - basejson = json.loads(baseresult) - except json.decoder.JSONDecodeError as e: - return baseresult, False - - data, is_loop = recurse_json(basejson, parsersplit[1:]) - parseditem = data - if is_loop: - print("DATA IS A LOOP - SHOULD WRAP") - if parsersplit[-1] == "#": - print("SET DATA WRAPPER TO NORMAL!") - parseditem = "${SHUFFLE_NO_SPLITTER%s}$" % json.dumps(data) - else: - # Return value: ${id[12345, 45678]}$ - print("SET DATA WRAPPER TO %s!" % parsersplit[-1]) - parseditem = "${%s%s}$" % (parsersplit[-1], json.dumps(data)) - - return parseditem, is_loop - - # Parses parameters sent to it and returns whether it did it successfully with the values found - def parse_params(action, fullexecution, parameter): - # Skip if it starts with $? - jsonparsevalue = "$." - is_loop = False - - # Matches with space in the first part, but not in subsequent parts. - # JSON / yaml etc shouldn't have spaces in their fields anyway. - match = ".*?([$]{1}([a-zA-Z0-9 _-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,})" - - # Regex to find all the things - if parameter["variant"] == "STATIC_VALUE": - data = parameter["value"] - actualitem = re.findall(match, data, re.MULTILINE) - #self.logger.debug(f"\n\nHandle static data with JSON: {data}\n\n") - #self.logger.info("STATIC PARSED: %s" % actualitem) - if len(actualitem) > 0: - print("ACTUAL: ", actualitem) - for replace in actualitem: - try: - to_be_replaced = replace[0] - except IndexError: - continue - - # Handles for loops etc. - value, is_loop = get_json_value(fullexecution, to_be_replaced) - - if isinstance(value, str): - parameter["value"] = parameter["value"].replace(to_be_replaced, value) - elif isinstance(value, dict): - parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) - else: - print("Unknown type %s" % type(value)) - try: - parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) - except json.decoder.JSONDecodeError as e: - parameter["value"] = parameter["value"].replace(to_be_replaced, value) - - - if parameter["variant"] == "WORKFLOW_VARIABLE": - print("Handling workflow variable") - found = False - try: - for item in fullexecution["workflow"]["workflow_variables"]: - if parameter["action_field"] == item["name"]: - found = True - parameter["value"] = item["value"] - break - except KeyError as e: - print("KeyError WF variable 1: %s" % e) - pass - except TypeError as e: - print("TypeError WF variables 1: %s" % e) - pass - - if not found: - try: - for item in fullexecution["execution_variables"]: - if parameter["action_field"] == item["name"]: - parameter["value"] = item["value"] - break - except KeyError as e: - print("KeyError WF variable 2: %s" % e) - pass - except TypeError as e: - print("TypeError WF variables 2: %s" % e) - pass - - elif parameter["variant"] == "ACTION_RESULT": - # FIXME - calculate value based on action_field and $if prominent - # FIND THE RIGHT LABEL - # GET THE LABEL'S RESULT - - tmpvalue = "" - self.logger.info("ACTION FIELD: %s" % parameter["action_field"]) - - fullname = "$" - if parameter["action_field"] == "Execution Argument": - tmpvalue = fullexecution["execution_argument"] - fullname += "exec" - else: - fullname += parameter["action_field"] - - self.logger.info("PRE Fullname: %s" % fullname) - - if parameter["value"].startswith(jsonparsevalue): - fullname += parameter["value"][1:] - #else: - # fullname = "$%s" % parameter["action_field"] - - self.logger.info("Fullname: %s" % fullname) - actualitem = re.findall(match, fullname, re.MULTILINE) - self.logger.info("ACTION PARSED: %s" % actualitem) - if len(actualitem) > 0: - for replace in actualitem: - try: - to_be_replaced = replace[0] - except IndexError: - print("Nothing to replace?: " % e) - continue - - # This will never be a loop aka multi argument - parameter["value"] = to_be_replaced - - value, is_loop = get_json_value(fullexecution, to_be_replaced) - print("Loop: %s" % is_loop) - if isinstance(value, str): - parameter["value"] = parameter["value"].replace(to_be_replaced, value) - elif isinstance(value, dict): - parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) - else: - print("Unknown type %s" % type(value)) - try: - parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) - except json.decoder.JSONDecodeError as e: - parameter["value"] = parameter["value"].replace(to_be_replaced, value) - - return "", parameter["value"], is_loop - - def run_validation(sourcevalue, check, destinationvalue): - self.logger.info("Checking %s %s %s" % (sourcevalue, check, destinationvalue)) - - if check == "=" or check.lower() == "equals": - if sourcevalue.lower() == destinationvalue.lower(): - return True - elif check == "!=" or check.lower() == "does not equal": - if sourcevalue.lower() != destinationvalue.lower(): - return True - elif check.lower() == "startswith": - if sourcevalue.lower().startswith(destinationvalue.lower()): - return True - elif check.lower() == "endswith": - if sourcevalue.lower().endswith(destinationvalue.lower()): - return True - elif check.lower() == "contains": - if destinationvalue.lower() in sourcevalue.lower(): - return True - elif check.lower() == "larger than": - try: - if sourcevalue.isdigit() and destinationvalue.isdigit(): - if int(sourcevalue) > int(destinationvalue): - return True - except AttributeError as e: - self.logger.error("Condition larger than failed with values %s and %s: %s" % (sourcevalue, destinationvalue, e)) - return False - elif check.lower() == "smaller than": - try: - if sourcevalue.isdigit() and destinationvalue.isdigit(): - if int(sourcevalue) < int(destinationvalue): - return True - except AttributeError as e: - self.logger.error("Condition smaller than failed with values %s and %s: %s" % (sourcevalue, destinationvalue, e)) - return False - else: - self.logger.info("Condition: can't handle %s yet. Setting to true" % check) - - return False - - def check_branch_conditions(action, fullexecution): - # relevantbranches = workflow.branches where destination = action - try: - if fullexecution["workflow"]["branches"] == None or len(fullexecution["workflow"]["branches"]) == 0: - return True, "" - except KeyError: - return True, "" - - relevantbranches = [] - for branch in fullexecution["workflow"]["branches"]: - if branch["destination_id"] != action["id"]: - continue - - # Remove anything without a condition - try: - if (branch["conditions"]) == 0 or branch["conditions"] == None: - continue - except KeyError: - continue - - self.logger.info("Relevant conditions: %s" % branch["conditions"]) - successful_conditions = [] - failed_conditions = [] - for condition in branch["conditions"]: - self.logger.info("Getting condition value of %s" % condition) - - # Parse all values first here - sourcevalue = condition["source"]["value"] - check, sourcevalue, is_loop = parse_params(action, fullexecution, condition["source"]) - if check: - return False, "Failed condition: %s %s %s because %s" % (sourcevalue, condition["condition"]["value"], destinationvalue, check) - - - #sourcevalue = sourcevalue.encode("utf-8") - sourcevalue = parse_wrapper_start(sourcevalue) - destinationvalue = condition["destination"]["value"] - - check, destinationvalue, is_loop = parse_params(action, fullexecution, condition["destination"]) - if check: - return False, "Failed condition: %s %s %s because %s" % (sourcevalue, condition["condition"]["value"], destinationvalue, check) - - #destinationvalue = destinationvalue.encode("utf-8") - destinationvalue = parse_wrapper_start(destinationvalue) - available_checks = [ - "=", - "equals", - "!=", - "does not equal", - ">", - "larger than", - "<", - "less than", - ">=", - "<=", - "startswith", - "endswith", - "contains", - "re", - "matches regex", - ] - - # FIXME - what should I do here? - if not condition["condition"]["value"] in available_checks: - self.logger.info("Skipping %s %s %s because %s is invalid." % (sourcevalue, condition["condition"]["value"], destinationvalue, condition["condition"]["value"])) - continue - - #print(destinationvalue) - # NEGATE - validation = run_validation(sourcevalue, condition["condition"]["value"], destinationvalue) - - # Configuration = negated because of WorkflowAppActionParam.. - try: - if condition["condition"]["configuration"]: - validation = not validation - except KeyError: - pass - - if not validation: - self.logger.info("Failed condition check for %s %s %s." % (sourcevalue, condition["condition"]["value"], destinationvalue)) - return False, "Failed condition: %s %s %s" % (sourcevalue, condition["condition"]["value"], destinationvalue) - - - # Make a general parser here, at least to get param["name"] = param["value"] in maparameter[string]string - #for condition in branch.conditons: - - return True, "" - - # Checks whether conditions are met, otherwise set - branchcheck, tmpresult = check_branch_conditions(action, fullexecution) - if not branchcheck: - self.logger.info("Failed one or more branch conditions.") - action_result["result"] = tmpresult - action_result["status"] = "FAILURE" - try: - ret = requests.post("%s%s" % (self.url, stream_path), headers=headers, json=action_result) - self.logger.info("Result: %d" % ret.status_code) - if ret.status_code != 200: - self.logger.info(ret.text) - except requests.exceptions.ConnectionError as e: - self.logger.exception(e) - - print("\n\nRETURNING BECAUSE A BRANCH FAILED\n\n") - return - - # Replace name cus there might be issues - # Not doing lower() as there might be user-made functions - actionname = action["name"] - if " " in actionname: - actionname.replace(" ", "_", -1) - #if action.generated: - # actionname = actionname.lower() - - # Runs the actual functions - try: - func = getattr(self, actionname, None) - if func == None: - self.logger.debug("Failed executing %s because func is None." % actionname) - action_result["status"] = "FAILURE" - action_result["result"] = "Function %s doesn't exist." % actionname - elif callable(func): - try: - if len(action["parameters"]) < 1: - result = await func() - else: - # Potentially parse JSON here - # FIXME - add potential authentication as first parameter(s) here - # params[parameter["name"]] = parameter["value"] - #print(fullexecution["authentication"] - # What variables are necessary here tho hmm - - params = {} - try: - for item in action["authentication"]: - print("AUTH: ", key, value) - params[item["key"]] = item["value"] - except KeyError: - print("No authentication specified!") - pass - #action["authentication"] - - # calltimes is used to handle forloops in the app itself. - # 2 kinds of loop - one in gui with one app each, and one like this, - # which is super fast, but has a bad overview (potentially good tho) - calltimes = 1 - result = "" - - all_executions = [] - - # Multi_parameter has the data for each. variable - minlength = 0 - multi_parameters = json.loads(json.dumps(params)) - multiexecution = False - multi_execution_lists = [] - for parameter in action["parameters"]: - check, value, is_loop = parse_params(action, fullexecution, parameter) - - if check: - raise "Value check error: %s" % Exception(check) - - # Custom format for ${name[0,1,2,...]}$ - #submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})" - submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})" - actualitem = re.findall(submatch, value, re.MULTILINE) - try: - if action["skip_multicheck"]: - print("Skipping multicheck") - actualitem = [] - except KeyError: - pass - - print("Return value: %s" % value) - actionname = action["name"] - #print("Multicheck ", actualitem) - print("Actual item: %s" % actualitem) - if len(actualitem) > 0: - multiexecution = True - - # Loop WITHOUT JSON variables go here. - # Loop WITH variables go in else. - if len(actualitem[0]) > 2 and actualitem[0][1] == "SHUFFLE_NO_SPLITTER": - print("Pre replacement: %s" % actualitem[0][2]) - tmpitem = value - - replacement = actualitem[0][2] - if replacement.startswith("\"") and replacement.endswith("\""): - replacement = replacement[1:len(replacement)-1] - - replacement = replacement.replace("\'", "\"", -1) - print("POST replacement: %s" % replacement) - - json_replacement = replacement - try: - json_replacement = json.loads(replacement) - except json.decoder.JSONDecodeError as e: - print("JSON error singular: %s" % e) - - if len(json_replacement) > minlength: - minlength = len(json_replacement) - - tmpitem = tmpitem.replace(actualitem[0][0], replacement, 1) - params[parameter["name"]] = tmpitem - multi_execution_lists.append(json_replacement) - multi_parameters[parameter["name"]] = json_replacement - - #print("LENGTH OF ARR: %d" % len(resultarray)) - #print("RESULTARRAY: %s" % resultarray) - print("MULTI finished: %s" % replacement) - else: - - # This is here to handle for loops within variables.. kindof - # 1. Find the length of the longest array - # 2. Build an array with the base values based on parameter["value"] - # 3. Get the n'th value of the generated list from values - # 4. Execute all n answers - replacements = {} - for replace in actualitem: - try: - to_be_replaced = replace[0] - actualitem = replace[2] - except IndexError: - continue - - try: - itemlist = json.loads(actualitem) - if len(itemlist) > minlength: - minlength = len(itemlist) - except json.decoder.JSONDecodeError as e: - print("JSON Error: %s in %s" % (e, actualitem)) - - replacements[to_be_replaced] = actualitem - - # This is a result array for JUST this value.. - # What if there are more? - resultarray = [] - for i in range(0, minlength): - tmpitem = json.loads(json.dumps(parameter["value"])) - for key, value in replacements.items(): - replacement = json.dumps(json.loads(value)[i]) - if replacement.startswith("\"") and replacement.endswith("\""): - replacement = replacement[1:len(replacement)-1] - #except json.decoder.JSONDecodeError as e: - - #print("REPLACING %s with %s" % (key, replacement)) - #replacement = parse_wrapper_start(replacement) - tmpitem = tmpitem.replace(key, replacement, -1) - - resultarray.append(tmpitem) - - # With this parameter ready, add it to... a greater list of parameters. Rofl - print("LENGTH OF ARR: %d" % len(resultarray)) - print("RESULTARRAY: %s" % resultarray) - if resultarray not in multi_execution_lists: - multi_execution_lists.append(resultarray) - - multi_parameters[parameter["name"]] = resultarray - else: - # Parses things like int(value) - self.logger.info("Parsing wrapper data for %s" % value) - value = parse_wrapper_start(value) - - params[parameter["name"]] = value - multi_parameters[parameter["name"]] = value - - # Fix lists here - print("CHECKING multi execution list!") - if len(multi_execution_lists) > 0: - print("\n Multi execution list has more data: %d" % len(multi_execution_lists)) - filteredlist = [] - for listitem in multi_execution_lists: - if listitem in filteredlist: - continue - - filteredlist.append(listitem) - - #print("New list length: %d" % len(filteredlist)) - if len(filteredlist) > 1: - print("Calculating new multi-loop length with %d lists" % len(filteredlist)) - tmplength = 1 - for innerlist in filteredlist: - print("List length: %d. %d*%d" % (len(innerlist), len(innerlist), tmplength)) - tmplength = len(innerlist)*tmplength - - minlength = tmplength - - print("New multi execution length: %d\n" % tmplength) - - # FIXME - this is horrible, but works for now - #for i in range(calltimes): - if not multiexecution: - print("APP_SDK DONE: Starting NORMAL execution of function") - newres = await func(**params) - #print("NEWRES: ", newres) - if isinstance(newres, str): - result += newres - else: - try: - result += str(newres) - except ValueError: - result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres) - print("Can't handle type %s value from function" % (type(newres))) - print("POST NEWRES RESULT: ", result) - else: - print("APP_SDK DONE: Starting MULTI execution with values %s of length %d" % (multi_parameters, minlength)) - # 1. Use number of executions based on the arrays being similar - # 2. Find the right value from the parsed multi_params - results = [] - json_object = False - for i in range(0, minlength): - # To be able to use the results as a list: - baseparams = json.loads(json.dumps(multi_parameters)) - # {'call': ['GoogleSafebrowsing_2_0', 'VirusTotal_GetReport_3_0']} - # 1. Check if list length is same as minlength - # 2. If NOT same length, duplicate based on length of array - # arraylength = 3 ["1", "2", "3"] - # arraylength = 4 ["1", "2", "3", "4"] - # minlength = 12 - 12/3 = 4 per item = ["1", "1", "1", "1", "2", "2", ...] - - try: - firstlist = True - for key, value in baseparams.items(): - - if isinstance(value, list): - try: - newvalue = value[i] - except IndexError: - pass - - if len(value) != minlength and len(value) > 0: - newarray = [] - print("VALUE: ", value) - additiontime = minlength/len(value) - print("Bad length for value: %d - should be %d. Additiontime: %d" % (len(value), minlength, additiontime)) - if firstlist: - print("Running normal list (FIRST)") - for subvalue in value: - for number in range(int(additiontime)): - newarray.append(subvalue) - else: - #print("Running secondary lists") - ## 1. Set up length of array - ## 2. Put values spread out - # FIXME: This works well, except if lists are same length - newarray = [""] * minlength - - cnt = 0 - for number in range(int(additiontime)): - for subvaluerange in range(len(value)): - # newlocation = number+(additiontime*subvaluerange) - # print("%d+(%d*%d) = %d. VAL: %s" % (number, additiontime, subvaluerange, newlocation, value[subvaluerange])) - # Reverse if same length? - if int(minlength/len(value)) == len(value): - tmp = int(len(value)-subvaluerange-1) - print("NEW: %d" % tmp) - newarray[cnt] = value[tmp] - else: - newarray[cnt] = value[subvaluerange] - cnt += 1 - - #print("Newarray =", newarray) - newvalue = newarray[i] - firstlist = False - - baseparams[key] = newvalue - except IndexError as e: - print("IndexError: %s" % e) - baseparams[key] = "IndexError: %s" % e - except KeyError as e: - print("KeyError: %s" % e) - baseparams[key] = "KeyError: %s" % e - - print("Running with params %s" % baseparams) - ret = await func(**baseparams) - if isinstance(ret, dict) or isinstance(ret, list): - results.append(ret) - json_object = True - else: - ret = ret.replace("\"", "\\\"", -1) - - try: - results.append(json.loads(ret)) - json_object = True - except json.decoder.JSONDecodeError as e: - #print("Json: %s" % e) - results.append(ret) - - #print("Inner ret parsed: %s" % ret) - - # Dump the result as a string of a list - #print("RESULTS: %s" % results) - if isinstance(results, list): - print("JSON OBJECT? ", json_object) - if json_object: - result = json.dumps(results) - else: - result = "[" - for item in results: - try: - json.loads(item) - result += item - except json.decoder.JSONDecodeError as e: - # Common nested issue which puts " around everything - try: - tmpitem = item.replace("\\\"", "\"", -1) - json.loads(tmpitem) - result += tmpitem - - except: - result += "\"%s\"" % item - - result += ", " - - result = result[:-2] - result += "]" - else: - print("Normal result?") - result = results - - print("RESULT: %s" % result) - action_result["status"] = "SUCCESS" - action_result["result"] = str(result) - if action_result["result"] == "": - action_result["result"] = result - - self.logger.debug(f"Executed {action['label']}-{action['id']} with result: {result}") - #self.logger.debug(f"Data: %s" % action_result) - except TypeError as e: - print("TypeError issue: %s" % e) - action_result["status"] = "FAILURE" - action_result["result"] = "TypeError: %s" % str(e) - else: - print("Function %s doesn't exist?" % action["name"]) - self.logger.error(f"App {self.__class__.__name__}.{action['name']} is not callable") - action_result["status"] = "FAILURE" - action_result["result"] = "Function %s is not callable." % actionname - - except Exception as e: - print(f"Failed to execute: {e}") - self.logger.exception(f"Failed to execute {e}-{action['id']}") - action_result["status"] = "FAILURE" - action_result["result"] = f"General exception: {e}" - - action_result["completed_at"] = int(time.time()) - - # Send the result :) - self.send_result(action_result, headers, stream_path) - return - - - #STOPCOPY - # !!! Let the above line stay - its used for some horrible codegeneration / stitching !!! # - - @classmethod - async def run(cls): - """ Connect to Redis and HTTP session, await actions """ - logging.basicConfig(format="{asctime} - {name} - {levelname}:{message}", style='{') - logger = logging.getLogger(f"{cls.__name__}") - logger.setLevel(logging.DEBUG) - print("Started execution!!") - - app = cls(redis=None, logger=logger, console_logger=logger) - - # Authorization for the app/function to control the workflow - # Function will crash if its wrong, which it probably should. - - await app.execute_action(app.action) diff --git a/backend/app_sdk_blackarch/build.sh b/backend/app_sdk_blackarch/build.sh deleted file mode 100644 index 029756ce..00000000 --- a/backend/app_sdk_blackarch/build.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -NAME=app_sdk_blackarch -VERSION=0.7.3 - -docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force -docker build . -t frikky/shuffle:$NAME -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION - -#docker push frikky/$NAME:$VERSION -#docker push docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -#docker push ghcr.io/frikky/$NAME:$VERSION - -docker push frikky/shuffle:$NAME -docker push ghcr.io/frikky/$NAME:$VERSION diff --git a/backend/app_sdk_blackarch/requirements.txt b/backend/app_sdk_blackarch/requirements.txt deleted file mode 100644 index 804abb1b..00000000 --- a/backend/app_sdk_blackarch/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -requests -urllib3 diff --git a/backend/app_sdk_blackarch/static_baseline.py b/backend/app_sdk_blackarch/static_baseline.py deleted file mode 100644 index 152131cd..00000000 --- a/backend/app_sdk_blackarch/static_baseline.py +++ /dev/null @@ -1,76 +0,0 @@ -import os -import sys -import time -import logging -import requests - -# Goal here: -# * Make an app from WALKOFF able to run without app_base.py from WALKOFF -# # How: -# * Make it rely 100% on INPUT throug HTTP invocations instead of redis READS -# # But really, how? -# * Make a WORKER that reads the queue, and reuses a function - -# Here to get it global -apikey = "" -try: - apikey = os.environ["FUNCTION_APIKEY"] -except KeyError: - pass - -# Authorize the execution -def authorization(request): - # This is basically my issue, but it enforces the use of an internal API key for execution - try: - apikey = os.environ["FUNCTION_APIKEY"] - except KeyError: - return f"Internal server error", 500 - - - # Check API key from ENV authentication - authentication = request.headers.get("Authorization") - if authentication == None: return f"Unauthorized", 401 - - apikey_split = authentication.split(" ") - if apikey_split[0] != "Bearer" or len(apikey_split) != 2: - return f"Apikey error", 401 - - if apikey != apikey_split[1]: - return f"Unauthorized", 401 - - return run(request) - -class AppBase: - """ The base class for Python-based Walkoff applications, handles Redis and logging configurations. """ - __version__ = None - app_name = None - - def __init__(self, redis=None, logger=None, console_logger=None):#, docker_client=None): - self.logger = logger if logger is not None else logging.getLogger("AppBaseLogger") - self.redis=redis - self.console_logger=console_logger - self.current_execution_id = None - self.url = "https://shuffler.io" - self.apikey = apikey - - @classmethod - async def run(cls, action): - """ Connect to Redis and HTTP session, await actions """ - logging.basicConfig(format="{asctime} - {name} - {levelname}:{message}", style='{') - logger = logging.getLogger(f"{cls.__name__}") - logger.setLevel(logging.DEBUG) - - app = cls(redis=None, logger=logger, console_logger=logger) - - # Authorization for the app/function to control the workflow - # Function will crash if its wrong, which it probably should. - - await app.execute_action(action) - - async def execute_action(self, action): - # FIXME - add request for the function STARTING here. Use "results stream" or something - # PAUSED, AWAITING_DATA, PENDING, COMPLETED, ABORTED, EXECUTING, SUCCESS, FAILURE - - self.authorization = action["authorization"] - self.execution_id = action["execution_id"] - self.current_execution_id = action["execution_id"] diff --git a/backend/app_sdk_kali/Dockerfile b/backend/app_sdk_kali/Dockerfile deleted file mode 100644 index af7fd24f..00000000 --- a/backend/app_sdk_kali/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM kalilinux/kali-rolling as base - -FROM base as builder - -RUN apt-get update -RUN apt-get dist-upgrade -y -RUN apt install build-essential libffi-dev musl-dev openssl python3 python3-pip -y - -RUN mkdir /install -WORKDIR /install - -COPY requirements.txt /requirements.txt -RUN pip install --prefix="/install" -r /requirements.txt - -FROM base - -COPY --from=builder /install /usr/local -COPY __init__.py /app/walkoff_app_sdk/__init__.py -COPY app_base.py /app/walkoff_app_sdk/app_base.py diff --git a/backend/app_sdk_kali/LICENSE b/backend/app_sdk_kali/LICENSE deleted file mode 100644 index ce11f6f3..00000000 --- a/backend/app_sdk_kali/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Frikkylikeme - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/backend/app_sdk_kali/README.md b/backend/app_sdk_kali/README.md deleted file mode 100644 index 754392ff..00000000 --- a/backend/app_sdk_kali/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# app_sdk.py -This is the SDK used for apps to behave like they should. -To change it in the backend, upload it to Buckets/shuffler.appspot.com/generated_apps/baseline. - -# static_baseline.py -It's used for python code generation and should be under MIT. Has to be located here because it's used by the backend. - -## If you want to update apps.. PS: downloads from docker hub do overrides.. :) -1. Write your code & check if runtime works -2. Build app_base image -3. docker rm $(docker ps -aq) # Remove all stopped containers -4. Delete the specific app's Docker image (docker rmi frikky/shuffle:...) -5. Rebuild the Docker image (click load in GUI?) - -# LICENSE -Everything in here is MIT, not AGPLv3 as indicated by the license. diff --git a/backend/app_sdk_kali/__init__.py b/backend/app_sdk_kali/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/app_sdk_kali/app_base.py b/backend/app_sdk_kali/app_base.py deleted file mode 100644 index e896f67c..00000000 --- a/backend/app_sdk_kali/app_base.py +++ /dev/null @@ -1,1169 +0,0 @@ -import os -import sys -import re -import time -import json -import logging -import requests -import urllib.parse - -class AppBase: - """ The base class for Python-based apps in Shuffle, handles logging and callbacks configurations""" - __version__ = None - app_name = None - - def __init__(self, redis=None, logger=None, console_logger=None):#, docker_client=None): - self.logger = logger if logger is not None else logging.getLogger("AppBaseLogger") - self.redis=redis - self.console_logger = logger if logger is not None else logging.getLogger("AppBaseLogger") - - # apikey is for the user / org - # authorization is for the specific workflow - self.url = os.getenv("CALLBACK_URL", "https://shuffler.io") - self.action = os.getenv("ACTION", "") - self.authorization = os.getenv("AUTHORIZATION", "") - self.current_execution_id = os.getenv("EXECUTIONID", "") - self.full_execution = os.getenv("FULL_EXECUTION", "") - - if isinstance(self.action, str): - self.action = json.loads(self.action) - - def send_result(self, action_result, headers, stream_path): - if action_result["status"] == "EXECUTING": - action_result["status"] = "FAILURE" - - # I wonder if this actually works - self.logger.info("Before last stream result") - try: - ret = requests.post("%s%s" % (self.url, stream_path), headers=headers, json=action_result) - self.logger.info("Result: %d" % ret.status_code) - if ret.status_code != 200: - self.logger.info(ret.text) - except requests.exceptions.ConnectionError as e: - self.logger.exception(e) - return - except TypeError as e: - self.logger.exception(e) - action_result["status"] = "FAILURE" - action_result["result"] = "POST error: %s" % e - self.logger.info("Before typeerror stream result") - ret = requests.post("%s%s" % (self.url, stream_path), headers=headers, json=action_result) - self.logger.info("Result: %d" % ret.status_code) - if ret.status_code != 200: - self.logger.info(ret.text) - - async def execute_action(self, action): - # FIXME - add request for the function STARTING here. Use "results stream" or something - # PAUSED, AWAITING_DATA, PENDING, COMPLETED, ABORTED, EXECUTING, SUCCESS, FAILURE - - # !!! Let this line stay - its used for some horrible codegeneration / stitching !!! # - #STARTCOPY - stream_path = "/api/v1/streams" - action_result = { - "action": action, - "authorization": self.authorization, - "execution_id": self.current_execution_id, - "result": "", - "started_at": int(time.time()), - "status": "EXECUTING" - } - self.logger.info("ACTION RESULT (start): %s", action_result) - - if len(self.action) == 0: - print("ACTION env not defined") - action_result["result"] = "Error in setup ENV: ACTION not defined" - self.send_result(action_result, headers, stream_path) - return - if len(self.authorization) == 0: - print("AUTHORIZATION env not defined") - action_result["result"] = "Error in setup ENV: AUTHORIZATION not defined" - self.send_result(action_result, headers, stream_path) - return - if len(self.current_execution_id) == 0: - print("EXECUTIONID env not defined") - action_result["result"] = "Error in setup ENV: EXECUTIONID not defined" - self.send_result(action_result, headers, stream_path) - return - - headers = { - "Content-Type": "application/json", - "Authorization": "Bearer %s" % self.authorization - } - - # Add async logger - # self.console_logger.handlers[0].stream.set_execution_id() - #self.logger.info("Before initial stream result") - try: - ret = requests.post("%s%s" % (self.url, stream_path), headers=headers, json=action_result) - self.logger.info("Workflow: %d" % ret.status_code) - if ret.status_code != 200: - self.logger.info(ret.text) - except requests.exceptions.ConnectionError as e: - print("Connectionerror: %s" % e) - - action_result["result"] = "Bad setup during startup: %s" % e - self.send_result(action_result, headers, stream_path) - return - - # Verify whether there are any parameters with ACTION_RESULT required - # If found, we get the full results list from backend - fullexecution = {} - if len(self.full_execution) == 0: - print("NO EXECUTION - LOADING!") - try: - tmpdata = { - "authorization": self.authorization, - "execution_id": self.current_execution_id - } - - self.logger.info("Before FULLEXEC stream result") - ret = requests.post( - "%s/api/v1/streams/results" % (self.url), - headers=headers, - json=tmpdata - ) - - if ret.status_code == 200: - fullexecution = ret.json() - else: - self.logger.info("Error: Data: ", ret.json()) - self.logger.info("Error with status code for results. Crashing because ACTION_RESULTS or WORKFLOW_VARIABLE can't be handled. Status: %d" % ret.status_code) - action_result["result"] = "Bad result from backend: %d" % ret.status_code - self.send_result(action_result, headers, stream_path) - return - except requests.exceptions.ConnectionError as e: - self.logger.info("Connectionerror: %s" % e) - action_result["result"] = "Connection error during startup: %s" % e - self.send_result(action_result, headers, stream_path) - return - else: - try: - fullexecution = json.loads(self.full_execution) - except json.decoder.JSONDecodeError as e: - print("Json decode execution error: %s" % e) - action_result["result"] = "Json error during startup: %s" % e - self.send_result(action_result, headers, stream_path) - return - - print("") - - - self.logger.info("AFTER FULLEXEC stream result") - - # Gets the value at the parenthesis level you want - def parse_nested_param(string, level): - """ - Generate strings contained in nested (), indexing i = level - """ - if len(re.findall("\(", string)) == len(re.findall("\)", string)): - LeftRightIndex = [x for x in zip( - [Left.start()+1 for Left in re.finditer('\(', string)], - reversed([Right.start() for Right in re.finditer('\)', string)]))] - - elif len(re.findall("\(", string)) > len(re.findall("\)", string)): - return parse_nested_param(string + ')', level) - elif len(re.findall("\(", string)) < len(re.findall("\)", string)): - return parse_nested_param('(' + string, level) - - else: - return 'Failed to parse params' - - try: - return [string[LeftRightIndex[level][0]:LeftRightIndex[level][1]]] - except IndexError: - return [string[LeftRightIndex[level+1][0]:LeftRightIndex[level+1][1]]] - - # Finds the deepest level parenthesis in a string - def maxDepth(S): - current_max = 0 - max = 0 - n = len(S) - - # Traverse the input string - for i in range(n): - if S[i] == '(': - current_max += 1 - - if current_max > max: - max = current_max - elif S[i] == ')': - if current_max > 0: - current_max -= 1 - else: - return -1 - - # finally check for unbalanced string - if current_max != 0: - return -1 - - return max-1 - - # Specific type parsing - def parse_type(data, thistype): - if data == None: - return "Empty" - - if "int" in thistype or "number" in thistype: - try: - return int(data) - except ValueError: - print("ValueError while casting %s" % data) - return data - if "lower" in thistype: - return data.lower() - if "upper" in thistype: - return data.upper() - if "trim" in thistype: - return data.strip() - if "strip" in thistype: - return data.strip() - if "split" in thistype: - return data.split() - if "len" in thistype or "length" in thistype: - tmp = "" - try: - tmp = json.loads(data) - except: - pass - - if isinstance(tmp, list): - return str(len(tmp)) - - return str(len(data)) - if "parse" in thistype: - splitvalues = [] - default_error = """Error. Expected syntax: parse(["hello","test1"],0:1)""" - if "," in data: - splitvalues = data.split(",") - - for item in range(len(splitvalues)): - splitvalues[item] = splitvalues[item].strip() - else: - return default_error - - lastsplit = [] - if ":" in splitvalues[-1]: - lastsplit = splitvalues[-1].split(":") - else: - try: - lastsplit = [int(splitvalues[-1])] - except ValueError: - return default_error - - try: - parsedlist = ",".join(splitvalues[0:-1]) - if len(lastsplit) > 1: - tmp = json.loads(parsedlist)[int(lastsplit[0]):int(lastsplit[1])] - else: - tmp = json.loads(parsedlist)[lastsplit[0]] - - print(tmp) - return tmp - except IndexError as e: - return default_error - - # Parses the INNER value and recurses until everything is done - def parse_wrapper(data): - try: - if "(" not in data or ")" not in data: - return data - except TypeError: - return data - - #print("Running %s" % data) - - # Look for the INNER wrapper first, then move out - wrappers = ["int", "number", "lower", "upper", "trim", "strip", "split", "parse", "len", "length"] - found = False - for wrapper in wrappers: - if wrapper not in data.lower(): - continue - - found = True - break - - if not found: - return data - - # Do stuff here. - innervalue = parse_nested_param(data, maxDepth(data)-0) - outervalue = parse_nested_param(data, maxDepth(data)-1) - print("INNER: ", innervalue) - print("OUTER: ", outervalue) - - if outervalue != innervalue: - #print("Outer: ", outervalue, " inner: ", innervalue) - for key in range(len(innervalue)): - # Replace OUTERVALUE[key] with INNERVALUE[key] in data. - print("Replace %s with %s in %s" % (outervalue[key], innervalue[key], data)) - data = data.replace(outervalue[key], innervalue[key]) - else: - for thistype in wrappers: - if thistype.lower() not in data.lower(): - continue - - parsed_value = parse_type(innervalue[0], thistype.lower()) - return parsed_value - - print("DATA: %s\n" % data) - return parse_wrapper(data) - - def parse_wrapper_start(data): - newdata = [] - newstring = "" - record = True - paranCnt = 0 - for char in data: - if char == "(": - paranCnt += 1 - - if not record: - record = True - - if record: - newstring += char - - if paranCnt == 0 and char == " ": - newdata.append(newstring) - newstring = "" - record = True - - if char == ")": - paranCnt -= 1 - - if paranCnt == 0: - record = False - - if len(newstring) > 0: - newdata.append(newstring) - - #print(newdata) - parsedlist = [] - non_string = False - for item in newdata: - ret = parse_wrapper(item) - if not isinstance(ret, str): - non_string = True - - parsedlist.append(ret) - - if len(parsedlist) > 0 and not non_string: - return " ".join(parsedlist) - elif len(parsedlist) == 1 and non_string: - return parsedlist[0] - else: - #print("Casting back to string because multi: ", parsedlist) - newlist = [] - for item in parsedlist: - try: - newlist.append(str(item)) - except ValueError: - newlist.append("parsing_error") - return " ".join(newlist) - - # Parses JSON loops and such down to the item you're looking for - def recurse_json(basejson, parsersplit): - match = "#(\d+):?-?([0-9a-z]+)?#?" - print("Split: %s\n%s" % (parsersplit, basejson)) - try: - outercnt = 0 - - # Loops over split values - for value in parsersplit: - print("VALUE: %s\n" % value) - actualitem = re.findall(match, value, re.MULTILINE) - if value == "#": - newvalue = [] - for innervalue in basejson: - # 1. Check the next item (message) - # 2. Call this function again - - try: - ret, is_loop = recurse_json(innervalue, parsersplit[outercnt+1:]) - except IndexError: - # Only in here if it's the last loop without anything in it? - ret, is_loop = recurse_json(innervalue, parsersplit[outercnt:]) - - newvalue.append(ret) - - # Magical way of returning which makes app sdk identify - # it as multi execution - return newvalue, True - elif len(actualitem) > 0: - # FIXME: This is absolutely not perfect. - print("In recursion v2: ", actualitem) - - is_loop = True - newvalue = [] - firstitem = actualitem[0][0] - seconditem = actualitem[0][1] - - # Means it's a single item -> continue - if seconditem == "": - print("In first - handling %s", seconditem) - tmpitem = basejson[int(firstitem)] - try: - newvalue, is_loop = recurse_json(tmpitem, parsersplit[outercnt+1:]) - except IndexError: - newvalue, is_loop = (tmpitem, parsersplit[outercnt+1:]) - else: - if seconditem == "max": - seconditem = len(basejson) - if seconditem == "min": - seconditem = 0 - - newvalue = [] - for i in range(int(firstitem), int(seconditem)): - # 1. Check the next item (message) - # 2. Call this function again - print("Base: %s" % basejson[i]) - - try: - ret, is_loop = recurse_json(basejson[i], parsersplit[outercnt+1:]) - except IndexError: - print("INDEXERROR: ", parsersplit[outercnt]) - #ret = innervalue - ret, is_loop = recurse_json(innervalue, parsersplit[outercnt:]) - - print(ret) - #exit() - newvalue.append(ret) - - return newvalue, is_loop - - # FIXME: Add specific loop for other indexes - else: - #print("BEFORE NORMAL VALUE: ", basejson, value) - if len(value) == 0: - return basejson, False - - if isinstance(basejson[value], str): - print(f"LOADING STRING '%s' AS JSON" % basejson[value]) - try: - basejson = json.loads(basejson[value]) - except json.decoder.JSONDecodeError as e: - print("RETURNING BECAUSE '%s' IS A NORMAL STRING" % basejson[value]) - return basejson[value], False - else: - basejson = basejson[value] - - outercnt += 1 - - except KeyError as e: - print("Lower keyerror: %s" % e) - #return basejson - #return "KeyError: Couldn't find key: %s" % e - - return basejson, False - - # Takes a workflow execution as argument - # Returns a string if the result is single, or a list if it's a list - def get_json_value(execution_data, input_data): - parsersplit = input_data.split(".") - actionname = parsersplit[0][1:].replace(" ", "_", -1) - #Actionname: Start_node - - print(f"Actionname: {actionname}") - - # 1. Find the action - baseresult = "" - actionname_lower = actionname.lower() - try: - if actionname_lower == "exec" or actionname_lower == "webhook" or actionname_lower == "schedule" or actionname_lower == "userinput" or actionname_lower == "email_trigger" or actionname_lower == "trigger": - baseresult = execution_data["execution_argument"] - else: - for result in execution_data["results"]: - resultlabel = result["action"]["label"].replace(" ", "_", -1).lower() - if resultlabel.lower() == actionname_lower: - baseresult = result["result"] - break - - print("BEFORE VARIABLES!") - if len(baseresult) == 0: - try: - #print("WF Variables: %s" % execution_data["workflow"]["workflow_variables"]) - for variable in execution_data["workflow"]["workflow_variables"]: - variablename = variable["name"].replace(" ", "_", -1).lower() - - if variablename.lower() == actionname_lower: - baseresult = variable["value"] - break - except KeyError as e: - print("KeyError wf variables: %s" % e) - pass - except TypeError as e: - print("TypeError wf variables: %s" % e) - pass - - print("BEFORE EXECUTION VAR") - if len(baseresult) == 0: - try: - #print("Execution Variables: %s" % execution_data["execution_variables"]) - for variable in execution_data["execution_variables"]: - variablename = variable["name"].replace(" ", "_", -1).lower() - if variablename.lower() == actionname_lower: - baseresult = variable["value"] - break - except KeyError as e: - print("KeyError exec variables: %s" % e) - pass - except TypeError as e: - print("TypeError exec variables: %s" % e) - pass - - except KeyError as error: - print(f"KeyError in JSON: {error}") - - print(f"After first trycatch") - - # 2. Find the JSON data - if len(baseresult) == 0: - return "", False - - if len(parsersplit) == 1: - return baseresult, False - - baseresult = baseresult.replace("\'", "\"") - basejson = {} - try: - basejson = json.loads(baseresult) - except json.decoder.JSONDecodeError as e: - return baseresult, False - - data, is_loop = recurse_json(basejson, parsersplit[1:]) - parseditem = data - if is_loop: - print("DATA IS A LOOP - SHOULD WRAP") - if parsersplit[-1] == "#": - print("SET DATA WRAPPER TO NORMAL!") - parseditem = "${SHUFFLE_NO_SPLITTER%s}$" % json.dumps(data) - else: - # Return value: ${id[12345, 45678]}$ - print("SET DATA WRAPPER TO %s!" % parsersplit[-1]) - parseditem = "${%s%s}$" % (parsersplit[-1], json.dumps(data)) - - return parseditem, is_loop - - # Parses parameters sent to it and returns whether it did it successfully with the values found - def parse_params(action, fullexecution, parameter): - # Skip if it starts with $? - jsonparsevalue = "$." - is_loop = False - - # Matches with space in the first part, but not in subsequent parts. - # JSON / yaml etc shouldn't have spaces in their fields anyway. - match = ".*?([$]{1}([a-zA-Z0-9 _-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,})" - - # Regex to find all the things - if parameter["variant"] == "STATIC_VALUE": - data = parameter["value"] - actualitem = re.findall(match, data, re.MULTILINE) - #self.logger.debug(f"\n\nHandle static data with JSON: {data}\n\n") - #self.logger.info("STATIC PARSED: %s" % actualitem) - if len(actualitem) > 0: - print("ACTUAL: ", actualitem) - for replace in actualitem: - try: - to_be_replaced = replace[0] - except IndexError: - continue - - # Handles for loops etc. - value, is_loop = get_json_value(fullexecution, to_be_replaced) - - if isinstance(value, str): - parameter["value"] = parameter["value"].replace(to_be_replaced, value) - elif isinstance(value, dict): - parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) - else: - print("Unknown type %s" % type(value)) - try: - parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) - except json.decoder.JSONDecodeError as e: - parameter["value"] = parameter["value"].replace(to_be_replaced, value) - - - if parameter["variant"] == "WORKFLOW_VARIABLE": - print("Handling workflow variable") - found = False - try: - for item in fullexecution["workflow"]["workflow_variables"]: - if parameter["action_field"] == item["name"]: - found = True - parameter["value"] = item["value"] - break - except KeyError as e: - print("KeyError WF variable 1: %s" % e) - pass - except TypeError as e: - print("TypeError WF variables 1: %s" % e) - pass - - if not found: - try: - for item in fullexecution["execution_variables"]: - if parameter["action_field"] == item["name"]: - parameter["value"] = item["value"] - break - except KeyError as e: - print("KeyError WF variable 2: %s" % e) - pass - except TypeError as e: - print("TypeError WF variables 2: %s" % e) - pass - - elif parameter["variant"] == "ACTION_RESULT": - # FIXME - calculate value based on action_field and $if prominent - # FIND THE RIGHT LABEL - # GET THE LABEL'S RESULT - - tmpvalue = "" - self.logger.info("ACTION FIELD: %s" % parameter["action_field"]) - - fullname = "$" - if parameter["action_field"] == "Execution Argument": - tmpvalue = fullexecution["execution_argument"] - fullname += "exec" - else: - fullname += parameter["action_field"] - - self.logger.info("PRE Fullname: %s" % fullname) - - if parameter["value"].startswith(jsonparsevalue): - fullname += parameter["value"][1:] - #else: - # fullname = "$%s" % parameter["action_field"] - - self.logger.info("Fullname: %s" % fullname) - actualitem = re.findall(match, fullname, re.MULTILINE) - self.logger.info("ACTION PARSED: %s" % actualitem) - if len(actualitem) > 0: - for replace in actualitem: - try: - to_be_replaced = replace[0] - except IndexError: - print("Nothing to replace?: " % e) - continue - - # This will never be a loop aka multi argument - parameter["value"] = to_be_replaced - - value, is_loop = get_json_value(fullexecution, to_be_replaced) - print("Loop: %s" % is_loop) - if isinstance(value, str): - parameter["value"] = parameter["value"].replace(to_be_replaced, value) - elif isinstance(value, dict): - parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) - else: - print("Unknown type %s" % type(value)) - try: - parameter["value"] = parameter["value"].replace(to_be_replaced, json.dumps(value)) - except json.decoder.JSONDecodeError as e: - parameter["value"] = parameter["value"].replace(to_be_replaced, value) - - return "", parameter["value"], is_loop - - def run_validation(sourcevalue, check, destinationvalue): - self.logger.info("Checking %s %s %s" % (sourcevalue, check, destinationvalue)) - - if check == "=" or check.lower() == "equals": - if sourcevalue.lower() == destinationvalue.lower(): - return True - elif check == "!=" or check.lower() == "does not equal": - if sourcevalue.lower() != destinationvalue.lower(): - return True - elif check.lower() == "startswith": - if sourcevalue.lower().startswith(destinationvalue.lower()): - return True - elif check.lower() == "endswith": - if sourcevalue.lower().endswith(destinationvalue.lower()): - return True - elif check.lower() == "contains": - if destinationvalue.lower() in sourcevalue.lower(): - return True - elif check.lower() == "larger than": - try: - if sourcevalue.isdigit() and destinationvalue.isdigit(): - if int(sourcevalue) > int(destinationvalue): - return True - except AttributeError as e: - self.logger.error("Condition larger than failed with values %s and %s: %s" % (sourcevalue, destinationvalue, e)) - return False - elif check.lower() == "smaller than": - try: - if sourcevalue.isdigit() and destinationvalue.isdigit(): - if int(sourcevalue) < int(destinationvalue): - return True - except AttributeError as e: - self.logger.error("Condition smaller than failed with values %s and %s: %s" % (sourcevalue, destinationvalue, e)) - return False - else: - self.logger.info("Condition: can't handle %s yet. Setting to true" % check) - - return False - - def check_branch_conditions(action, fullexecution): - # relevantbranches = workflow.branches where destination = action - try: - if fullexecution["workflow"]["branches"] == None or len(fullexecution["workflow"]["branches"]) == 0: - return True, "" - except KeyError: - return True, "" - - relevantbranches = [] - for branch in fullexecution["workflow"]["branches"]: - if branch["destination_id"] != action["id"]: - continue - - # Remove anything without a condition - try: - if (branch["conditions"]) == 0 or branch["conditions"] == None: - continue - except KeyError: - continue - - self.logger.info("Relevant conditions: %s" % branch["conditions"]) - successful_conditions = [] - failed_conditions = [] - for condition in branch["conditions"]: - self.logger.info("Getting condition value of %s" % condition) - - # Parse all values first here - sourcevalue = condition["source"]["value"] - check, sourcevalue, is_loop = parse_params(action, fullexecution, condition["source"]) - if check: - return False, "Failed condition: %s %s %s because %s" % (sourcevalue, condition["condition"]["value"], destinationvalue, check) - - - #sourcevalue = sourcevalue.encode("utf-8") - sourcevalue = parse_wrapper_start(sourcevalue) - destinationvalue = condition["destination"]["value"] - - check, destinationvalue, is_loop = parse_params(action, fullexecution, condition["destination"]) - if check: - return False, "Failed condition: %s %s %s because %s" % (sourcevalue, condition["condition"]["value"], destinationvalue, check) - - #destinationvalue = destinationvalue.encode("utf-8") - destinationvalue = parse_wrapper_start(destinationvalue) - available_checks = [ - "=", - "equals", - "!=", - "does not equal", - ">", - "larger than", - "<", - "less than", - ">=", - "<=", - "startswith", - "endswith", - "contains", - "re", - "matches regex", - ] - - # FIXME - what should I do here? - if not condition["condition"]["value"] in available_checks: - self.logger.info("Skipping %s %s %s because %s is invalid." % (sourcevalue, condition["condition"]["value"], destinationvalue, condition["condition"]["value"])) - continue - - #print(destinationvalue) - # NEGATE - validation = run_validation(sourcevalue, condition["condition"]["value"], destinationvalue) - - # Configuration = negated because of WorkflowAppActionParam.. - try: - if condition["condition"]["configuration"]: - validation = not validation - except KeyError: - pass - - if not validation: - self.logger.info("Failed condition check for %s %s %s." % (sourcevalue, condition["condition"]["value"], destinationvalue)) - return False, "Failed condition: %s %s %s" % (sourcevalue, condition["condition"]["value"], destinationvalue) - - - # Make a general parser here, at least to get param["name"] = param["value"] in maparameter[string]string - #for condition in branch.conditons: - - return True, "" - - # Checks whether conditions are met, otherwise set - branchcheck, tmpresult = check_branch_conditions(action, fullexecution) - if not branchcheck: - self.logger.info("Failed one or more branch conditions.") - action_result["result"] = tmpresult - action_result["status"] = "FAILURE" - try: - ret = requests.post("%s%s" % (self.url, stream_path), headers=headers, json=action_result) - self.logger.info("Result: %d" % ret.status_code) - if ret.status_code != 200: - self.logger.info(ret.text) - except requests.exceptions.ConnectionError as e: - self.logger.exception(e) - - print("\n\nRETURNING BECAUSE A BRANCH FAILED\n\n") - return - - # Replace name cus there might be issues - # Not doing lower() as there might be user-made functions - actionname = action["name"] - if " " in actionname: - actionname.replace(" ", "_", -1) - #if action.generated: - # actionname = actionname.lower() - - # Runs the actual functions - try: - func = getattr(self, actionname, None) - if func == None: - self.logger.debug("Failed executing %s because func is None." % actionname) - action_result["status"] = "FAILURE" - action_result["result"] = "Function %s doesn't exist." % actionname - elif callable(func): - try: - if len(action["parameters"]) < 1: - result = await func() - else: - # Potentially parse JSON here - # FIXME - add potential authentication as first parameter(s) here - # params[parameter["name"]] = parameter["value"] - #print(fullexecution["authentication"] - # What variables are necessary here tho hmm - - params = {} - try: - for item in action["authentication"]: - print("AUTH: ", key, value) - params[item["key"]] = item["value"] - except KeyError: - print("No authentication specified!") - pass - #action["authentication"] - - # calltimes is used to handle forloops in the app itself. - # 2 kinds of loop - one in gui with one app each, and one like this, - # which is super fast, but has a bad overview (potentially good tho) - calltimes = 1 - result = "" - - all_executions = [] - - # Multi_parameter has the data for each. variable - minlength = 0 - multi_parameters = json.loads(json.dumps(params)) - multiexecution = False - multi_execution_lists = [] - for parameter in action["parameters"]: - check, value, is_loop = parse_params(action, fullexecution, parameter) - - if check: - raise "Value check error: %s" % Exception(check) - - # Custom format for ${name[0,1,2,...]}$ - #submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})" - submatch = "([${]{2}([0-9a-zA-Z_-]+)(\[.*\])[}$]{2})" - actualitem = re.findall(submatch, value, re.MULTILINE) - try: - if action["skip_multicheck"]: - print("Skipping multicheck") - actualitem = [] - except KeyError: - pass - - print("Return value: %s" % value) - actionname = action["name"] - #print("Multicheck ", actualitem) - print("Actual item: %s" % actualitem) - if len(actualitem) > 0: - multiexecution = True - - # Loop WITHOUT JSON variables go here. - # Loop WITH variables go in else. - if len(actualitem[0]) > 2 and actualitem[0][1] == "SHUFFLE_NO_SPLITTER": - print("Pre replacement: %s" % actualitem[0][2]) - tmpitem = value - - replacement = actualitem[0][2] - if replacement.startswith("\"") and replacement.endswith("\""): - replacement = replacement[1:len(replacement)-1] - - replacement = replacement.replace("\'", "\"", -1) - print("POST replacement: %s" % replacement) - - json_replacement = replacement - try: - json_replacement = json.loads(replacement) - except json.decoder.JSONDecodeError as e: - print("JSON error singular: %s" % e) - - if len(json_replacement) > minlength: - minlength = len(json_replacement) - - tmpitem = tmpitem.replace(actualitem[0][0], replacement, 1) - params[parameter["name"]] = tmpitem - multi_execution_lists.append(json_replacement) - multi_parameters[parameter["name"]] = json_replacement - - #print("LENGTH OF ARR: %d" % len(resultarray)) - #print("RESULTARRAY: %s" % resultarray) - print("MULTI finished: %s" % replacement) - else: - - # This is here to handle for loops within variables.. kindof - # 1. Find the length of the longest array - # 2. Build an array with the base values based on parameter["value"] - # 3. Get the n'th value of the generated list from values - # 4. Execute all n answers - replacements = {} - for replace in actualitem: - try: - to_be_replaced = replace[0] - actualitem = replace[2] - except IndexError: - continue - - try: - itemlist = json.loads(actualitem) - if len(itemlist) > minlength: - minlength = len(itemlist) - except json.decoder.JSONDecodeError as e: - print("JSON Error: %s in %s" % (e, actualitem)) - - replacements[to_be_replaced] = actualitem - - # This is a result array for JUST this value.. - # What if there are more? - resultarray = [] - for i in range(0, minlength): - tmpitem = json.loads(json.dumps(parameter["value"])) - for key, value in replacements.items(): - replacement = json.dumps(json.loads(value)[i]) - if replacement.startswith("\"") and replacement.endswith("\""): - replacement = replacement[1:len(replacement)-1] - #except json.decoder.JSONDecodeError as e: - - #print("REPLACING %s with %s" % (key, replacement)) - #replacement = parse_wrapper_start(replacement) - tmpitem = tmpitem.replace(key, replacement, -1) - - resultarray.append(tmpitem) - - # With this parameter ready, add it to... a greater list of parameters. Rofl - print("LENGTH OF ARR: %d" % len(resultarray)) - print("RESULTARRAY: %s" % resultarray) - if resultarray not in multi_execution_lists: - multi_execution_lists.append(resultarray) - - multi_parameters[parameter["name"]] = resultarray - else: - # Parses things like int(value) - self.logger.info("Parsing wrapper data for %s" % value) - value = parse_wrapper_start(value) - - params[parameter["name"]] = value - multi_parameters[parameter["name"]] = value - - # Fix lists here - print("CHECKING multi execution list!") - if len(multi_execution_lists) > 0: - print("\n Multi execution list has more data: %d" % len(multi_execution_lists)) - filteredlist = [] - for listitem in multi_execution_lists: - if listitem in filteredlist: - continue - - filteredlist.append(listitem) - - #print("New list length: %d" % len(filteredlist)) - if len(filteredlist) > 1: - print("Calculating new multi-loop length with %d lists" % len(filteredlist)) - tmplength = 1 - for innerlist in filteredlist: - print("List length: %d. %d*%d" % (len(innerlist), len(innerlist), tmplength)) - tmplength = len(innerlist)*tmplength - - minlength = tmplength - - print("New multi execution length: %d\n" % tmplength) - - # FIXME - this is horrible, but works for now - #for i in range(calltimes): - if not multiexecution: - print("APP_SDK DONE: Starting NORMAL execution of function") - newres = await func(**params) - #print("NEWRES: ", newres) - if isinstance(newres, str): - result += newres - else: - try: - result += str(newres) - except ValueError: - result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres) - print("Can't handle type %s value from function" % (type(newres))) - print("POST NEWRES RESULT: ", result) - else: - print("APP_SDK DONE: Starting MULTI execution with values %s of length %d" % (multi_parameters, minlength)) - # 1. Use number of executions based on the arrays being similar - # 2. Find the right value from the parsed multi_params - results = [] - json_object = False - for i in range(0, minlength): - # To be able to use the results as a list: - baseparams = json.loads(json.dumps(multi_parameters)) - # {'call': ['GoogleSafebrowsing_2_0', 'VirusTotal_GetReport_3_0']} - # 1. Check if list length is same as minlength - # 2. If NOT same length, duplicate based on length of array - # arraylength = 3 ["1", "2", "3"] - # arraylength = 4 ["1", "2", "3", "4"] - # minlength = 12 - 12/3 = 4 per item = ["1", "1", "1", "1", "2", "2", ...] - - try: - firstlist = True - for key, value in baseparams.items(): - - if isinstance(value, list): - try: - newvalue = value[i] - except IndexError: - pass - - if len(value) != minlength and len(value) > 0: - newarray = [] - print("VALUE: ", value) - additiontime = minlength/len(value) - print("Bad length for value: %d - should be %d. Additiontime: %d" % (len(value), minlength, additiontime)) - if firstlist: - print("Running normal list (FIRST)") - for subvalue in value: - for number in range(int(additiontime)): - newarray.append(subvalue) - else: - #print("Running secondary lists") - ## 1. Set up length of array - ## 2. Put values spread out - # FIXME: This works well, except if lists are same length - newarray = [""] * minlength - - cnt = 0 - for number in range(int(additiontime)): - for subvaluerange in range(len(value)): - # newlocation = number+(additiontime*subvaluerange) - # print("%d+(%d*%d) = %d. VAL: %s" % (number, additiontime, subvaluerange, newlocation, value[subvaluerange])) - # Reverse if same length? - if int(minlength/len(value)) == len(value): - tmp = int(len(value)-subvaluerange-1) - print("NEW: %d" % tmp) - newarray[cnt] = value[tmp] - else: - newarray[cnt] = value[subvaluerange] - cnt += 1 - - #print("Newarray =", newarray) - newvalue = newarray[i] - firstlist = False - - baseparams[key] = newvalue - except IndexError as e: - print("IndexError: %s" % e) - baseparams[key] = "IndexError: %s" % e - except KeyError as e: - print("KeyError: %s" % e) - baseparams[key] = "KeyError: %s" % e - - print("Running with params %s" % baseparams) - ret = await func(**baseparams) - if isinstance(ret, dict) or isinstance(ret, list): - results.append(ret) - json_object = True - else: - ret = ret.replace("\"", "\\\"", -1) - - try: - results.append(json.loads(ret)) - json_object = True - except json.decoder.JSONDecodeError as e: - #print("Json: %s" % e) - results.append(ret) - - #print("Inner ret parsed: %s" % ret) - - # Dump the result as a string of a list - #print("RESULTS: %s" % results) - if isinstance(results, list): - print("JSON OBJECT? ", json_object) - if json_object: - result = json.dumps(results) - else: - result = "[" - for item in results: - try: - json.loads(item) - result += item - except json.decoder.JSONDecodeError as e: - # Common nested issue which puts " around everything - try: - tmpitem = item.replace("\\\"", "\"", -1) - json.loads(tmpitem) - result += tmpitem - - except: - result += "\"%s\"" % item - - result += ", " - - result = result[:-2] - result += "]" - else: - print("Normal result?") - result = results - - print("RESULT: %s" % result) - action_result["status"] = "SUCCESS" - action_result["result"] = str(result) - if action_result["result"] == "": - action_result["result"] = result - - self.logger.debug(f"Executed {action['label']}-{action['id']} with result: {result}") - #self.logger.debug(f"Data: %s" % action_result) - except TypeError as e: - print("TypeError issue: %s" % e) - action_result["status"] = "FAILURE" - action_result["result"] = "TypeError: %s" % str(e) - else: - print("Function %s doesn't exist?" % action["name"]) - self.logger.error(f"App {self.__class__.__name__}.{action['name']} is not callable") - action_result["status"] = "FAILURE" - action_result["result"] = "Function %s is not callable." % actionname - - except Exception as e: - print(f"Failed to execute: {e}") - self.logger.exception(f"Failed to execute {e}-{action['id']}") - action_result["status"] = "FAILURE" - action_result["result"] = f"General exception: {e}" - - action_result["completed_at"] = int(time.time()) - - # Send the result :) - self.send_result(action_result, headers, stream_path) - return - - - #STOPCOPY - # !!! Let the above line stay - its used for some horrible codegeneration / stitching !!! # - - @classmethod - async def run(cls): - """ Connect to Redis and HTTP session, await actions """ - logging.basicConfig(format="{asctime} - {name} - {levelname}:{message}", style='{') - logger = logging.getLogger(f"{cls.__name__}") - logger.setLevel(logging.DEBUG) - print("Started execution!!") - - app = cls(redis=None, logger=logger, console_logger=logger) - - # Authorization for the app/function to control the workflow - # Function will crash if its wrong, which it probably should. - - await app.execute_action(app.action) diff --git a/backend/app_sdk_kali/build.sh b/backend/app_sdk_kali/build.sh deleted file mode 100644 index 78c76ced..00000000 --- a/backend/app_sdk_kali/build.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -NAME=app_sdk_kali -VERSION=0.7.3 - -docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force -docker build . -t frikky/shuffle:$NAME -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION - -#docker push frikky/$NAME:$VERSION -#docker push docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -#docker push ghcr.io/frikky/$NAME:$VERSION - -docker push frikky/shuffle:$NAME -docker push ghcr.io/frikky/$NAME:$VERSION diff --git a/backend/app_sdk_kali/requirements.txt b/backend/app_sdk_kali/requirements.txt deleted file mode 100644 index 804abb1b..00000000 --- a/backend/app_sdk_kali/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -requests -urllib3 diff --git a/backend/app_sdk_kali/static_baseline.py b/backend/app_sdk_kali/static_baseline.py deleted file mode 100644 index 152131cd..00000000 --- a/backend/app_sdk_kali/static_baseline.py +++ /dev/null @@ -1,76 +0,0 @@ -import os -import sys -import time -import logging -import requests - -# Goal here: -# * Make an app from WALKOFF able to run without app_base.py from WALKOFF -# # How: -# * Make it rely 100% on INPUT throug HTTP invocations instead of redis READS -# # But really, how? -# * Make a WORKER that reads the queue, and reuses a function - -# Here to get it global -apikey = "" -try: - apikey = os.environ["FUNCTION_APIKEY"] -except KeyError: - pass - -# Authorize the execution -def authorization(request): - # This is basically my issue, but it enforces the use of an internal API key for execution - try: - apikey = os.environ["FUNCTION_APIKEY"] - except KeyError: - return f"Internal server error", 500 - - - # Check API key from ENV authentication - authentication = request.headers.get("Authorization") - if authentication == None: return f"Unauthorized", 401 - - apikey_split = authentication.split(" ") - if apikey_split[0] != "Bearer" or len(apikey_split) != 2: - return f"Apikey error", 401 - - if apikey != apikey_split[1]: - return f"Unauthorized", 401 - - return run(request) - -class AppBase: - """ The base class for Python-based Walkoff applications, handles Redis and logging configurations. """ - __version__ = None - app_name = None - - def __init__(self, redis=None, logger=None, console_logger=None):#, docker_client=None): - self.logger = logger if logger is not None else logging.getLogger("AppBaseLogger") - self.redis=redis - self.console_logger=console_logger - self.current_execution_id = None - self.url = "https://shuffler.io" - self.apikey = apikey - - @classmethod - async def run(cls, action): - """ Connect to Redis and HTTP session, await actions """ - logging.basicConfig(format="{asctime} - {name} - {levelname}:{message}", style='{') - logger = logging.getLogger(f"{cls.__name__}") - logger.setLevel(logging.DEBUG) - - app = cls(redis=None, logger=logger, console_logger=logger) - - # Authorization for the app/function to control the workflow - # Function will crash if its wrong, which it probably should. - - await app.execute_action(action) - - async def execute_action(self, action): - # FIXME - add request for the function STARTING here. Use "results stream" or something - # PAUSED, AWAITING_DATA, PENDING, COMPLETED, ABORTED, EXECUTING, SUCCESS, FAILURE - - self.authorization = action["authorization"] - self.execution_id = action["execution_id"] - self.current_execution_id = action["execution_id"] diff --git a/backend/go-app/docker.go b/backend/go-app/docker.go index 214f81c9..a4101b61 100644 --- a/backend/go-app/docker.go +++ b/backend/go-app/docker.go @@ -5,20 +5,24 @@ import ( "github.com/frikky/shuffle-shared" "archive/tar" + //"bufio" "path/filepath" + //"strconv" "bytes" "context" "encoding/json" "errors" "fmt" + //"github.com/docker/docker" "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" + //"github.com/docker/docker/api/types/container" "github.com/docker/docker/client" + newdockerclient "github.com/fsouza/go-dockerclient" "github.com/go-git/go-billy/v5" - network "github.com/docker/docker/api/types/network" - natting "github.com/docker/go-connections/nat" + //network "github.com/docker/docker/api/types/network" + //natting "github.com/docker/go-connections/nat" "io" "io/ioutil" @@ -214,11 +218,28 @@ func buildImageMemory(fs billy.Filesystem, tags []string, dockerfileFolder strin // Dockerfile is inside the TAR itself. Not local context // docker build --build-arg http_proxy=http://my.proxy.url + // Attempt at setting name according to #359: https://github.com/frikky/Shuffle/issues/359 + labels := map[string]string{} + target := "" + if len(tags) > 0 { + if strings.Contains(tags[0], ":") { + version := strings.Split(tags[0], ":") + if len(version) == 2 { + target = fmt.Sprintf("shuffle-build-%s", version[1]) + tags = append(tags, target) + labels["name"] = target + } + } + } + + _ = labels buildOptions := types.ImageBuildOptions{ Remove: true, Tags: tags, BuildArgs: map[string]*string{}, + Labels: labels, } + // NetworkMode: "host", httpProxy := os.Getenv("HTTP_PROXY") @@ -231,13 +252,14 @@ func buildImageMemory(fs billy.Filesystem, tags []string, dockerfileFolder strin } // Build the actual image - log.Printf("[INFO] Building %s. This may take up to a few minutes.", dockerfileFolder) + log.Printf(`[INFO] Building %s with proxy "%s". Tags: "%s". This may take up to a few minutes.`, dockerfileFolder, httpsProxy, strings.Join(tags, ",")) imageBuildResponse, err := client.ImageBuild( ctx, dockerFileTarReader, buildOptions, ) + //log.Printf("RESPONSE: %#v", imageBuildResponse) //log.Printf("Response: %#v", imageBuildResponse.Body) //log.Printf("IMAGERESPONSE: %#v", imageBuildResponse.Body) @@ -391,89 +413,6 @@ func stopWebhook(image string, identifier string) error { return nil } -// FIXME - remember to set DOCKER_API_VERSION -// FIXME - remove github.com/docker/docker/vendor -// FIXME - Library dependencies for NAT is fucked.. -// https://docs.docker.com/develop/sdk/examples/ -func deployWebhook(image string, identifier string, path string, port string, callbackurl string, apikey string) error { - cli, err := client.NewEnvClient() - if err != nil { - fmt.Println("Unable to create docker client") - return err - } - - newport, err := natting.NewPort("tcp", port) - if err != nil { - fmt.Println("Unable to create docker port") - return err - } - - // FIXME - logging? - - hostConfig := &container.HostConfig{ - PortBindings: natting.PortMap{ - newport: []natting.PortBinding{ - { - HostIP: "0.0.0.0", - HostPort: port, - }, - }, - }, - RestartPolicy: container.RestartPolicy{ - Name: "always", - }, - LogConfig: container.LogConfig{ - Type: "json-file", - Config: map[string]string{}, - }, - } - - //networkConfig := &network.NetworkSettings{} - networkConfig := &network.NetworkingConfig{ - EndpointsConfig: map[string]*network.EndpointSettings{}, - } - - test := &network.EndpointSettings{ - Gateway: "helo", - } - - networkConfig.EndpointsConfig["bridge"] = test - - exposedPorts := map[natting.Port]struct{}{ - newport: struct{}{}, - } - - config := &container.Config{ - Image: image, - Env: []string{ - fmt.Sprintf("URIPATH=%s", path), - fmt.Sprintf("HOOKPORT=%s", port), - fmt.Sprintf("CALLBACKURL=%s", callbackurl), - fmt.Sprintf("APIKEY=%s", apikey), - fmt.Sprintf("HOOKID=%s", identifier), - }, - ExposedPorts: exposedPorts, - Hostname: fmt.Sprintf("%s-%s", image, identifier), - } - - cont, err := cli.ContainerCreate( - context.Background(), - config, - hostConfig, - networkConfig, - fmt.Sprintf("%s-%s", image, identifier), - ) - - if err != nil { - log.Println(err) - return err - } - - cli.ContainerStart(context.Background(), cont.ID, types.ContainerStartOptions{}) - log.Printf("Container %s is created", cont.ID) - return nil -} - // Starts a new webhook func handleStopHookDocker(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) @@ -501,7 +440,7 @@ func handleStopHookDocker(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - hook, err := getHook(ctx, fileId) + hook, err := shuffle.GetHook(ctx, fileId) if err != nil { log.Printf("Failed getting hook %s (stop docker): %s", fileId, err) resp.WriteHeader(401) @@ -521,8 +460,8 @@ func handleStopHookDocker(resp http.ResponseWriter, request *http.Request) { hook.Status = "stopped" hook.Running = false - hook.Actions = []HookAction{} - err = setHook(ctx, *hook) + hook.Actions = []shuffle.HookAction{} + err = shuffle.SetHook(ctx, *hook) if err != nil { log.Printf("Failed setting hook: %s", err) resp.WriteHeader(401) @@ -585,7 +524,7 @@ func handleDeleteHookDocker(resp http.ResponseWriter, request *http.Request) { return } - err := DeleteKey(ctx, "hooks", fileId) + err := shuffle.DeleteKey(ctx, "hooks", fileId) if err != nil { resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "message": "Can't delete"}`)) @@ -606,121 +545,6 @@ func handleDeleteHookDocker(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(`{"success": true, "message": "Deleted webhook"}`)) } -// Starts a new webhook -func handleStartHookDocker(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - location := strings.Split(request.URL.String(), "/") - - var fileId string - if location[1] == "api" { - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - fileId = location[4] - } - - if len(fileId) != 32 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "message": "ID not valid"}`)) - return - } - - ctx := context.Background() - hook, err := getHook(ctx, fileId) - if err != nil { - log.Printf("Failed getting hook %s (start docker): %s", fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - if len(hook.Info.Url) == 0 { - log.Printf("Hook url can't be empty.") - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - log.Printf("Status: %s", hook.Status) - log.Printf("Running: %t", hook.Running) - if hook.Running || hook.Status == "Running" { - message := fmt.Sprintf("Error: %s is already running", hook.Id) - log.Println(message) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "message": "%s"}`, message))) - return - } - - // FIXME - verify? - // FIXME - static port? Generate from available range. - image := "webhook" - filepath := "/webhook" - baseUrl := "http://localhost" - callbackUrl := "http://localhost:8001" - - // This is here to force stop and remove the old webhook - err = stopWebhook(image, fileId) - if err != nil { - log.Printf("Container stop issue for %s-%s: %s", image, fileId, err) - } - - // Dynamic ish ports - var startPort int64 = 5001 - var endPort int64 = 5010 - port := findAvailablePorts(startPort, endPort) - if len(port) == 0 { - message := fmt.Sprintf("Not ports available in the range %d-%d", startPort, endPort) - log.Println(message) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "message": "%s"}`, message))) - return - - } - - hook.Status = "running" - hook.Running = true - - // Set this for more than just hooks? - if hook.Type == "webhook" { - hook.Info.Url = fmt.Sprintf("%s:%s%s", baseUrl, port, filepath) - } - err = setHook(ctx, *hook) - if err != nil { - log.Printf("Failed setting hook: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - // Cloud run? Let's make a generic webhook that can be deployed easily - log.Printf("Should run a webhook with the following: \nUrl: %s\nId: %s\n", hook.Info.Url, hook.Id) - - // FIXME - set port based on what the user specified / what was generated - // FIXME - add nonstatic APIKEY - apiKey := "ASD" - - err = deployWebhook(image, fileId, filepath, port, callbackUrl, apiKey) - if err != nil { - log.Printf("Failed starting container %s-%s: %s", image, fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - // FIXME - get some real data? - log.Printf("[INFO] Successfully started %s-%s on port %s with filepath %s", image, fileId, port, filepath) - resp.WriteHeader(200) - resp.Write([]byte(`{"success": true, "message": "Started webhook"}`)) - return -} - // Checks if an image exists func imageCheckBuilder(images []string) error { //log.Printf("[FIXME] ImageNames to check: %#v", images) @@ -767,7 +591,7 @@ func imageCheckBuilder(images []string) error { } func hookTest() { - var hook Hook + var hook shuffle.Hook err := json.Unmarshal([]byte(webhook), &hook) log.Println(webhook) if err != nil { @@ -776,12 +600,12 @@ func hookTest() { } ctx := context.Background() - err = setHook(ctx, hook) + err = shuffle.SetHook(ctx, hook) if err != nil { log.Printf("Failed setting hook: %s", err) } - returnHook, err := getHook(ctx, hook.Id) + returnHook, err := shuffle.GetHook(ctx, hook.Id) if err != nil { log.Printf("Failed getting hook %s (test): %s", hook.Id, err) } @@ -799,13 +623,13 @@ func getDockerImage(resp http.ResponseWriter, request *http.Request) { } // Just here to verify that the user is logged in - _, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in validate swagger: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } + //_, err := shuffle.HandleApiAuthentication(resp, request) + //if err != nil { + // log.Printf("[WARNING] Api authentication failed in DOWNLOAD IMAGE: %s", err) + // resp.WriteHeader(401) + // resp.Write([]byte(`{"success": false}`)) + // return + //} body, err := ioutil.ReadAll(request.Body) if err != nil { @@ -818,16 +642,6 @@ func getDockerImage(resp http.ResponseWriter, request *http.Request) { Name string `datastore:"name" json:"name" yaml:"name"` } - //body = []byte(`swagger: "2.0"`) - //body = []byte(`swagger: '1.0'`) - //newbody := string(body) - //newbody = strings.TrimSpace(newbody) - //body = []byte(newbody) - //log.Println(string(body)) - //tmpbody, err := yaml.YAMLToJSON(body) - //log.Println(err) - //log.Println(string(tmpbody)) - // This has to be done in a weird way because Datastore doesn't // support map[string]interface and similar (openapi3.Swagger) var version requestCheck @@ -839,16 +653,10 @@ func getDockerImage(resp http.ResponseWriter, request *http.Request) { return } - log.Printf("Image to load: %s", version.Name) - //cli, err := client.NewEnvClient() - //if err != nil { - // log.Println("Unable to create docker client") - // return err - //} - + log.Printf("[DEBUG] Image to load: %s", version.Name) dockercli, err := client.NewEnvClient() if err != nil { - log.Printf("Unable to create docker client: %s", err) + log.Printf("[WARNING] Unable to create docker client: %s", err) resp.WriteHeader(422) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed JSON marshalling: %s"}`, err))) return @@ -861,37 +669,131 @@ func getDockerImage(resp http.ResponseWriter, request *http.Request) { img := types.ImageSummary{} tagFound := "" + + img2 := types.ImageSummary{} + tagFound2 := "" + + alternativeNameSplit := strings.Split(version.Name, "/") + alternativeName := version.Name + if len(alternativeNameSplit) == 3 { + alternativeName = strings.Join(alternativeNameSplit[1:3], "/") + } + for _, image := range images { for _, tag := range image.RepoTags { - log.Printf("[INFO] Docker Image: %s", tag) - if strings.ToLower(tag) == strings.ToLower(version.Name) { img = image tagFound = tag break } + + if strings.ToLower(tag) == strings.ToLower(alternativeName) { + img2 = image + tagFound2 = tag + } } } + // REBUILDS THE APP if len(img.ID) == 0 { + if len(img2.ID) == 0 { + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 0) + log.Printf("[INFO] Getting workflowapps for a rebuild. Got %d with err %#v", len(workflowapps), err) + if err == nil { + imageName := "" + imageVersion := "" + newNameSplit := strings.Split(version.Name, ":") + if len(newNameSplit) == 2 { + log.Printf("[DEBUG] Found name %#v", newNameSplit) + + findVersionSplit := strings.Split(newNameSplit[1], "_") + log.Printf("[DEBUG] Found another split %#v", findVersionSplit) + if len(findVersionSplit) == 2 { + imageVersion = findVersionSplit[len(findVersionSplit)-1] + imageName = findVersionSplit[0] + } else if len(findVersionSplit) >= 2 { + imageVersion = findVersionSplit[len(findVersionSplit)-1] + imageName = strings.Join(findVersionSplit[0:len(findVersionSplit)-1], "_") + } else { + log.Printf("[DEBUG] Couldn't parse appname & version for %#v", findVersionSplit) + } + } + + if len(imageName) > 0 && len(imageVersion) > 0 { + foundApp := shuffle.WorkflowApp{} + imageName = strings.ToLower(imageName) + imageVersion = strings.ToLower(imageVersion) + log.Printf("[DEBUG] Looking for appname %s with version %s", imageName, imageVersion) + + for _, app := range workflowapps { + if strings.ToLower(strings.Replace(app.Name, " ", "_", -1)) == imageName && app.AppVersion == imageVersion { + if app.Generated { + log.Printf("[DEBUG] Found matching app %s:%s - %s", imageName, imageVersion, app.ID) + foundApp = app + break + } else { + log.Printf("[WARNING] Trying to rebuild app that isn't generated - not allowed. Looking further.") + } + + //break + } + } + + if len(foundApp.ID) > 0 { + openApiApp, err := shuffle.GetOpenApiDatastore(ctx, foundApp.ID) + if err != nil { + log.Printf("[ERROR] Failed getting OpenAPI app %s to database: %s", foundApp.ID, err) + } else { + log.Printf("[DEBUG] Found OpenAPI app for %s as generated - now building!", version.Name) + user := shuffle.User{} + + //img = version.Name + if len(alternativeName) > 0 { + tagFound = alternativeName + } else { + tagFound = version.Name + } + + buildSwaggerApp(resp, []byte(openApiApp.Body), user) + } + } + } + } else { + log.Printf("[WARNING] Couldn't find an image with registry name %s and %s", version.Name, alternativeName) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "message": "Couldn't find image %s"}`, version.Name))) + return + } + } + + if len(tagFound) == 0 && len(tagFound2) > 0 { + img = img2 + tagFound = tagFound2 + } + } + + //log.Printf("[INFO] Img found (%s): %#v", tagFound, img) + log.Printf("[INFO] Img found to be downloaded by client: %s", tagFound) + + newClient, err := newdockerclient.NewClientFromEnv() + if err != nil { + log.Printf("[WARNING] Failed setting up docker env: %s", newClient) resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "message": "Couldn't find image %s"}`, version.Name))) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "message": "Couldn't make docker client"}`))) return } - _ = tagFound - /* - log.Printf("IMg: %#v", img) - pullOptions := types.ImagePullOptions{} - log.Printf("[INFO] Pulling image %s", image) - reader, err := dockercli.ImagePull(ctx, tag, pullOptions) - if err != nil { - log.Printf("[ERROR] Failed getting image %s: %s", image, err) - } + ////https://github.com/fsouza/go-dockerclient/issues/600 + //defer fileReader.Close() + opts := newdockerclient.ExportImageOptions{ + Name: tagFound, + OutputStream: resp, + } - io.Copy(os.Stdout, r) - */ - - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "message": "Downloading image %s"}`, version.Name))) + if err := newClient.ExportImage(opts); err != nil { + log.Printf("[WARNING] FAILED to save image to file: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "message": "Couldn't export image"}`))) + return + } } diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index 4e64fc86..fcc25a96 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -2,7 +2,8 @@ module shuffle go 1.13 -//replace github.com/frikky/shuffle-shared => ../../../../git/shuffle-shared +replace github.com/frikky/shuffle-shared => ../../../../git/shuffle-shared + //replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi require ( @@ -10,15 +11,19 @@ require ( cloud.google.com/go/datastore v1.4.0 cloud.google.com/go/pubsub v1.3.1 cloud.google.com/go/storage v1.12.0 - github.com/Microsoft/go-winio v0.4.14 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/algolia/algoliasearch-client-go/v3 v3.18.1 // indirect github.com/basgys/goxml2json v1.1.0 - github.com/frikky/kin-openapi v0.38.0 + github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013 // indirect github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82 github.com/docker/distribution v2.7.1+incompatible // indirect - github.com/docker/docker v1.13.1 + github.com/docker/docker v20.10.3-0.20210216175712-646072ed6524+incompatible github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.4.0 // indirect - github.com/frikky/shuffle-shared v0.0.23 + github.com/elastic/go-elasticsearch/v7 v7.13.1 // indirect + github.com/frikky/kin-openapi v0.39.0 + github.com/frikky/shuffle-shared v0.0.69 + github.com/fsouza/go-dockerclient v1.7.2 github.com/ghodss/yaml v1.0.0 github.com/go-git/go-billy/v5 v5.0.0 github.com/go-git/go-git/v5 v5.0.0 @@ -26,9 +31,9 @@ require ( github.com/gorilla/handlers v1.4.2 // indirect github.com/gorilla/mux v1.8.0 github.com/h2non/filetype v1.0.12 - github.com/opencontainers/go-digest v1.0.0-rc1 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible github.com/satori/go.uuid v1.2.0 + go4.org v0.0.0-20201209231011-d4a079459e60 // indirect golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/oauth2 v0.0.0-20210113160501-8b1d76fa0423 google.golang.org/api v0.36.0 diff --git a/backend/go-app/go.sum b/backend/go-app/go.sum deleted file mode 100644 index 21fd33ff..00000000 --- a/backend/go-app/go.sum +++ /dev/null @@ -1,604 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0 h1:EpMNVUorLiZIELdMZbCYX/ByTFCdoYopYAGxaGVz9ms= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.75.0 h1:XgtDnVJRCPEUG21gjFiRPz4zI1Mjg16R+NYQjfmU4XY= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.6.0/go.mod h1:hyFDG0qSGdHNz8Q6nDN8rYIkld0q/+5uBZaelxiDLfE= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/datastore v1.4.0 h1:CFDJm15RpYXeEblQ0TMDUrYtqmBmbAWTy536nA8JIc8= -cloud.google.com/go/datastore v1.4.0/go.mod h1:d18825/a9bICdAIJy2EkHs9joU4RlIZ1t6l8WDdbdY0= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.7.0 h1:DzdLPI8Em+DEk7IzA2a10ivq3mxIEASC9GeNJ6FFt5Q= -cloud.google.com/go/storage v1.7.0/go.mod h1:jGMIBwF+L/tL6WN/W5InNgYYu4HP0DvGB6rQ1mufWfs= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.12.0 h1:4y3gHptW1EHVtcPAVE0eBBlFuGqEejTTG3KdIE0lUX4= -cloud.google.com/go/storage v1.12.0/go.mod h1:fFLk2dp2oAhDz8QFKwqrjdJvxSp/W2g7nillojlL5Ho= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw= -github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw= -github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82 h1:9bAydALqAjBfPHd/eAiJBHnMZUYov8m2PkXVr+YGQeI= -github.com/carlescere/scheduler v0.0.0-20170109141437-ee74d2f83d82/go.mod h1:tyA14J0sA3Hph4dt+AfCjPrYR13+vVodshQSM7km9qw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= -github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/frikky/kin-openapi v0.38.0 h1:V7ttwIJS8Vks4KL+mZVj1ZSqhIcQtgaG8akeqXEQgsE= -github.com/frikky/kin-openapi v0.38.0/go.mod h1:Fr28TtCHL4K0kIqtqui8HWxN1LG5uAh3z/tDfFyiA1s= -github.com/frikky/shuffle-shared v0.0.12 h1:+0EIfThmK47Po+LogPYZR4XjbS4Ds19WNMFu2YUSjhw= -github.com/frikky/shuffle-shared v0.0.12/go.mod h1:SEY432/xs4oBkOUnGwxiYKCZWZLRaheGInhAoW7N8ww= -github.com/frikky/shuffle-shared v0.0.15 h1:508ceeEHfPBMCC8/K4Zve3kwRQqiXNJSw6+BDoq9X4E= -github.com/frikky/shuffle-shared v0.0.15/go.mod h1:SEY432/xs4oBkOUnGwxiYKCZWZLRaheGInhAoW7N8ww= -github.com/frikky/shuffle-shared v0.0.20 h1:y6JlPnQDq//elICWvVfUfJyU9gH3fSpQmPy+agqZ5sA= -github.com/frikky/shuffle-shared v0.0.20/go.mod h1:H7SqOta/EAYnfYuWzwzYSh/oWfF0kgnuaJTQNKQBvoQ= -github.com/frikky/shuffle-shared v0.0.21 h1:xj/XPsXTa2rx41mm4nUc7+2K9RGkq2/mpjSPtIfpjE4= -github.com/frikky/shuffle-shared v0.0.21/go.mod h1:H7SqOta/EAYnfYuWzwzYSh/oWfF0kgnuaJTQNKQBvoQ= -github.com/frikky/shuffle-shared v0.0.22 h1:TFMcJCNmOOSneMMWbg5dNzp2z6m0aZLROuL+bzVToRE= -github.com/frikky/shuffle-shared v0.0.22/go.mod h1:H7SqOta/EAYnfYuWzwzYSh/oWfF0kgnuaJTQNKQBvoQ= -github.com/frikky/shuffle-shared v0.0.23 h1:Pnlc2M6fHnFRLFd5K1iLTVv4/t4P04Ri1GJ5CMxzq0U= -github.com/frikky/shuffle-shared v0.0.23/go.mod h1:H7SqOta/EAYnfYuWzwzYSh/oWfF0kgnuaJTQNKQBvoQ= -github.com/getkin/kin-openapi v0.8.0 h1:a6TQjTqwkyscC4/hShJX7WhCVE+4bi9lzw61XHQW5hE= -github.com/getkin/kin-openapi v0.8.0/go.mod h1:zZQMFkVgRHCdhgb6ihCTIo9dyDZFvX0k/xAKqw1FhPw= -github.com/getkin/kin-openapi v0.52.0 h1:6WqsF5d6PfJ8AscdD+9Rtb2RP2iBWyC7V6GcjssWg7M= -github.com/getkin/kin-openapi v0.52.0/go.mod h1:fRpo2Nw4Czgy0QnrIesRrEXs5+15N1F9mGZLP/aIomE= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy v4.2.0+incompatible h1:Z6QtVXd5tjxUtcODLugkJg4WaZnGg13CD8qB9pr+7q0= -github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= -github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA= -github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.0.0 h1:k5RWPm4iJwYtfWoxIJy4wJX9ON7ihPeZZYC1fLYDnpg= -github.com/go-git/go-git/v5 v5.0.0/go.mod h1:oYD8y9kWsGINPFJoLdaScGCN6dlKg23blmClfZwtUVA= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= -github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= -github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= -github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= -github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/h2non/filetype v1.0.12 h1:yHCsIe0y2cvbDARtJhGBTD2ecvqMSTvlIcph9En/Zao= -github.com/h2non/filetype v1.0.12/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= -github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= -github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88= -golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210113160501-8b1d76fa0423 h1:/hEknzWkMPCjTo7StMHRrBRa8YBbXuBWfck8680k3RE= -golang.org/x/oauth2 v0.0.0-20210113160501-8b1d76fa0423/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e h1:hq86ru83GdWTlfQFZGO4nZJTU4Bs2wfHl8oFHRaXsfc= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200409170454-77362c5149f0/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d h1:lzLdP95xJmMpwQ6LUHwrc5V7js93hTiY7gkznu0BgmY= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.21.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.23.0 h1:YlvGEOq2NA2my8cZ/9V8BcEO9okD48FlJcdqN0xJL3s= -google.golang.org/api v0.23.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo= -google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0 h1:l2Nfbl2GPXdWorv+dT2XfinX2jOOw4zv1VhLstx+6rE= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200409111301-baae70f3302d/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200507105951-43844f6eee31 h1:Bz1qTn2YRWV+9OKJtxHJiQKCiXIdf+kwuKXdt9cBxyU= -google.golang.org/genproto v0.0.0-20200507105951-43844f6eee31/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210113195801-ae06605f4595 h1:x7nk+/4+SvuTDI4wnzQUlhvi+DTpyfncXBo3QWTFs7U= -google.golang.org/genproto v0.0.0-20210113195801-ae06605f4595/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.34.1 h1:ugq+9++ZQPFzM2pKUMCIK8gj9M0pFyuUWO9Q8kwEDQw= -google.golang.org/grpc v1.34.1/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= -gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= -gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= -gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= -gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86 h1:OfFoIUYv/me30yv7XlMy4F9RJw8DEm8WQ6QG1Ph4bH0= -gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 097bc190..825a20bb 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -4,26 +4,23 @@ import ( "github.com/frikky/shuffle-shared" "bufio" - "bytes" "context" "crypto/md5" + //"crypto/x509" "encoding/hex" "encoding/json" "errors" - "path/filepath" - "fmt" "io" "io/ioutil" "log" - "net" "net/http" "net/url" "os" "os/exec" + "path/filepath" //"regexp" - "strconv" "strings" "time" @@ -33,17 +30,19 @@ import ( "cloud.google.com/go/storage" "google.golang.org/appengine/mail" + //"github.com/elastic/go-elasticsearch/v7" + //"github.com/elastic/go-elasticsearch/v8/esapi" + "github.com/frikky/kin-openapi/openapi2" "github.com/frikky/kin-openapi/openapi2conv" "github.com/frikky/kin-openapi/openapi3" + /* "github.com/frikky/kin-openapi/openapi2" "github.com/frikky/kin-openapi/openapi2conv" "github.com/frikky/kin-openapi/openapi3" */ - "github.com/google/go-github/v28/github" - "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5" @@ -104,19 +103,6 @@ type ExecutionInfo struct { DailyOnpremExecutions int64 `json:"daily_onprem_executions" datastore:"daily_onprem_executions"` } -type StatisticsData struct { - Timestamp int64 `json:"timestamp" datastore:"timestamp"` - Id string `json:"id" datastore:"id"` - Amount int64 `json:"amount" datastore:"amount"` -} - -type StatisticsItem struct { - Total int64 `json:"total" datastore:"total"` - Fieldname string `json:"field_name" datastore:"field_name"` - Data []StatisticsData `json:"data" datastore:"data"` - OrgId string `json:"org_id" datastore:"org_id"` -} - // "Execution by status" // Execution history //type GlobalStatistics struct { @@ -420,17 +406,6 @@ func createFileFromBytes(ctx context.Context, bucket *storage.BucketHandle, remo return nil } -func deleteFile(ctx context.Context, bucket *storage.BucketHandle, remotePath string) error { - - // [START delete_file] - o := bucket.Object(remotePath) - if err := o.Delete(ctx); err != nil { - return err - } - // [END delete_file] - return nil -} - func readFile(ctx context.Context, bucket *storage.BucketHandle, object string) ([]byte, error) { // [START download_file] rc, err := bucket.Object(object).NewReader(ctx) @@ -591,53 +566,6 @@ func checkFileExistsLocal(basepath string, filepath string) bool { return true } -func handleGetallSchedules(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - var err error - var limit = 50 - - // FIXME - add org search and public / private - key, ok := request.URL.Query()["limit"] - if ok { - limit, err = strconv.Atoi(key[0]) - if err != nil { - limit = 50 - } - } - - // Max datastore limit - if limit > 1000 { - limit = 1000 - } - - // Get URLs from a database index (mapped by orborus) - ctx := context.Background() - q := datastore.NewQuery("schedules").Limit(limit) - var allschedules Schedules - - _, err = dbclient.GetAll(ctx, q, &allschedules.Schedules) - if err != nil { - log.Println(err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed getting schedules"}`))) - return - } - - newjson, err := json.Marshal(allschedules) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking"}`))) - return - } - - resp.WriteHeader(200) - resp.Write(newjson) -} - func redirect(w http.ResponseWriter, req *http.Request) { // remove/add not default ports from req.Host target := "https://" + req.Host + req.URL.Path @@ -681,188 +609,27 @@ func checkUsername(Username string) error { return nil } -func handleRegisterVerification(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - defaultMessage := "Successfully registered" - - var reference string - location := strings.Split(request.URL.String(), "/") - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - reference = location[4] - - if len(reference) != 36 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Id when registering verification is not valid"}`)) - return - } - - ctx := context.Background() - // With user, do a search for workflows with user or user's org attached - // Only giving 200 to not give any suspicion whether they're onto an actual user or not - q := datastore.NewQuery("Users").Filter("verification_token =", reference) - var users []shuffle.User - _, err := dbclient.GetAll(ctx, q, &users) - if err != nil { - log.Printf("Failed getting users for verification token: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, defaultMessage))) - return - } - - // FIXME - check reset_timeout - if len(users) != 1 { - log.Printf("Error - no user with verification id %s", reference) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) - return - } - - Userdata := users[0] - - // FIXME: Not for cloud! - Userdata.Verified = true - err = shuffle.SetUser(ctx, &Userdata) - if err != nil { - log.Printf("Failed adding verification for user %s: %s", Userdata.Username, err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) - return - } - - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) - log.Printf("%s SUCCESSFULLY FINISHED REGISTRATION", Userdata.Username) -} - -func handleSetEnvironments(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - // FIXME: Overhaul the top part. - // Only admin can change environments, but if there are no users, anyone can make (first) - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Can't handle set env auth"}`)) - return - } - - if user.Role != "admin" { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Can't set environment without being admin"}`)) - return - } - - ctx := context.Background() - var environments []shuffle.Environment - q := datastore.NewQuery("Environments").Filter("org_id =", user.ActiveOrg.Id) - _, err = dbclient.GetAll(ctx, q, &environments) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Can't get environments when setting"}`)) - return - } - - body, err := ioutil.ReadAll(request.Body) - if err != nil { - log.Println("Failed reading body") - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed to read data"}`))) - return - } - - var newEnvironments []shuffle.Environment - err = json.Unmarshal(body, &newEnvironments) - if err != nil { - log.Printf("Failed unmarshaling: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed to unmarshal data"}`))) - return - } - - if len(newEnvironments) < 1 { - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "One environment is required"}`))) - return - } - - // Clear old data? Removed for archiving purpose. No straight deletion - //for _, item := range environments { - // err = DeleteKey(ctx, "Environments", item.Name) - // if err != nil { - // resp.WriteHeader(401) - // resp.Write([]byte(`{"success": false, "reason": "Error cleaning up environment"}`)) - // return - // } - //} - - openEnvironments := 0 - for _, item := range newEnvironments { - if !item.Archived { - openEnvironments += 1 - } - } - - if openEnvironments < 1 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Can't archived all environments"}`)) - return - } - - for _, item := range newEnvironments { - if item.OrgId != user.ActiveOrg.Id { - item.OrgId = user.ActiveOrg.Id - } - - err = setEnvironment(ctx, &item) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Failed setting environment variable"}`)) - return - } - } - - //DeleteKey(ctx, entity string, value string) error { - // FIXME - check which are in use - //log.Printf("FIXME: Set new environments: %#v", newEnvironments) - //log.Printf("DONT DELETE ONES THAT ARE IN USE") - - resp.WriteHeader(200) - resp.Write([]byte(`{"success": true}`)) -} - -func createNewUser(username, password, role, apikey string, org shuffle.Org) error { +func createNewUser(username, password, role, apikey string, org shuffle.OrgMini) error { // Returns false if there is an issue // Use this for register err := shuffle.CheckPasswordStrength(password) if err != nil { - log.Printf("Bad password strength: %s", err) + log.Printf("[WARNING] Bad password strength: %s", err) return err } err = checkUsername(username) if err != nil { - log.Printf("Bad Username strength: %s", err) + log.Printf("[WARNING] Bad Username strength: %s", err) return err } ctx := context.Background() - q := datastore.NewQuery("Users").Filter("Username =", username) - var users []shuffle.User - _, err = dbclient.GetAll(ctx, q, &users) - if err != nil { - log.Printf("Failed getting user for registration: %s", err) + //users, err := FindUser(ctx context.Context, username string) ([]User, error) { + + users, err := shuffle.FindUser(ctx, strings.ToLower(strings.TrimSpace(username))) + if err != nil && len(users) == 0 { + log.Printf("[WARNING] Failed getting user %s: %s", username, err) return err } @@ -893,7 +660,10 @@ func createNewUser(username, password, role, apikey string, org shuffle.Org) err newUser.Roles = []string{"user"} } - newUser.ActiveOrg = org + newUser.ActiveOrg = shuffle.OrgMini{ + Id: org.Id, + Name: org.Name, + } if len(apikey) > 0 { newUser.ApiKey = apikey @@ -925,7 +695,7 @@ func createNewUser(username, password, role, apikey string, org shuffle.Org) err newUser.Id = ID.String() newUser.VerificationToken = verifyToken.String() - err = shuffle.SetUser(ctx, newUser) + err = shuffle.SetUser(ctx, newUser, true) if err != nil { log.Printf("Error adding User %s: %s", username, err) return err @@ -938,14 +708,14 @@ func createNewUser(username, password, role, apikey string, org shuffle.Org) err if err != nil { log.Printf("Failed updating org with user %s", newUser.Username) } else { - log.Printf("Successfully updated org with user %s!", newUser.Username) + log.Printf("[INFO] Successfully updated org with user %s!", newUser.Username) } } - err = increaseStatisticsField(ctx, "successful_register", username, 1, org.Id) - if err != nil { - log.Printf("Failed to increase total apps loaded stats: %s", err) - } + //err = increaseStatisticsField(ctx, "successful_register", username, 1, org.Id) + //if err != nil { + // log.Printf("Failed to increase total apps loaded stats: %s", err) + //} return nil } @@ -956,9 +726,10 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) { return } - // FIXME: Overhaul the top part. // Only admin can CREATE users, but if there are no users, anyone can make (first) - count, countErr := getUserCount() + ctx := context.Background() + users, countErr := shuffle.GetAllUsers(ctx) + count := len(users) user, err := shuffle.HandleApiAuthentication(resp, request) if err != nil { if (countErr == nil && count > 0) || countErr != nil { @@ -990,24 +761,67 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) { role = "admin" } - ctx := context.Background() currentOrg := user.ActiveOrg if user.ActiveOrg.Id == "" { - log.Printf("There's no active org for the user. Checking if there's a single one to assing it to.") + log.Printf("[WARNING] There's no active org for the user %s. Checking if there's a single one to assing it to.", user.Username) - var orgs []shuffle.Org - q := datastore.NewQuery("Organizations") - _, err = dbclient.GetAll(ctx, q, &orgs) - if err == nil && len(orgs) == 1 { - log.Printf("No org exists in auth. Setting to default (first one)") - currentOrg = orgs[0] + orgs, err := shuffle.GetAllOrgs(ctx) + if err == nil && len(orgs) > 0 { + log.Printf("[WARNING] No org exists for user %s. Setting to default (first one)", user.Username) + currentOrg = shuffle.OrgMini{ + Id: orgs[0].Id, + Name: orgs[0].Name, + } + } else { + log.Printf("[WARNING] Couldn't find an org to attach to. Create?") + + orgSetupName := "default" + orgId := uuid.NewV4().String() + newOrg := shuffle.Org{ + Name: orgSetupName, + Id: orgId, + Org: orgSetupName, + Users: []shuffle.User{}, + Roles: []string{"admin", "user"}, + CloudSync: false, + } + + err = shuffle.SetOrg(ctx, newOrg, orgId) + if err != nil { + log.Printf("[WARNING] Failed setting init organization: %s", err) + } else { + log.Printf("[DEBUG] Successfully created the default org!") + + defaultEnv := os.Getenv("ORG_ID") + if len(defaultEnv) == 0 { + defaultEnv = "Shuffle" + log.Printf("[DEBUG] Setting default environment for org to %s", defaultEnv) + } + + item := shuffle.Environment{ + Name: defaultEnv, + Type: "onprem", + OrgId: orgId, + Default: true, + Id: uuid.NewV4().String(), + } + + err = shuffle.SetEnvironment(ctx, &item) + if err != nil { + log.Printf("[WARNING] Failed setting up new environment for new org: %s") + } + + currentOrg = shuffle.OrgMini{ + Id: newOrg.Id, + Name: newOrg.Name, + } + } } - } err = createNewUser(data.Username, data.Password, role, "", currentOrg) if err != nil { - log.Printf("Failed registering user: %s", err) + log.Printf("[WARNING] Failed registering user: %s", err) resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) return @@ -1015,7 +829,7 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) { resp.WriteHeader(200) resp.Write([]byte(`{"success": true}`)) - log.Printf("%s Successfully registered.", data.Username) + log.Printf("[INFO] %s Successfully registered.", data.Username) } func handleCookie(request *http.Request) bool { @@ -1031,133 +845,6 @@ func handleCookie(request *http.Request) bool { return true } -func handleUpdateUser(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - userInfo, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in apigen: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - body, err := ioutil.ReadAll(request.Body) - if err != nil { - log.Println("Failed reading body") - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Missing field: user_id"}`))) - return - } - - type newUserStruct struct { - Role string `json:"role"` - Username string `json:"username"` - UserId string `json:"user_id"` - } - - ctx := context.Background() - var t newUserStruct - err = json.Unmarshal(body, &t) - if err != nil { - log.Printf("Failed unmarshaling userId: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unmarshaling. Missing field: user_id"}`))) - return - } - - // Should this role reflect the users' org access? - // When you change org -> change user role - if userInfo.Role != "admin" { - log.Printf("%s tried to update user %s", userInfo.Username, t.UserId) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "You need to be admin to change other users"}`))) - return - } - - foundUser, err := shuffle.GetUser(ctx, t.UserId) - if err != nil { - log.Printf("Can't find user %s (update user): %s", t.UserId, err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false}`))) - return - } - - orgFound := false - for _, item := range foundUser.Orgs { - if item == userInfo.ActiveOrg.Id { - orgFound = true - break - } - } - - if !orgFound { - log.Printf("User %s is admin, but can't edit users outside their own org.", userInfo.Id) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't change users outside your org."}`))) - return - } - - if t.Role != "admin" && t.Role != "user" { - log.Printf("%s tried and failed to update user %s", userInfo.Username, t.UserId) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can only change to role user and admin"}`))) - return - } else { - // Same user - can't edit yourself - if userInfo.Id == t.UserId { - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't update the role of your own user"}`))) - return - } - - log.Printf("Updated user %s from %s to %s", foundUser.Username, foundUser.Role, t.Role) - foundUser.Role = t.Role - foundUser.Roles = []string{t.Role} - } - - if len(t.Username) > 0 { - q := datastore.NewQuery("Users").Filter("username =", t.Username) - var users []shuffle.User - _, err = dbclient.GetAll(ctx, q, &users) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Failed getting users when updating user"}`)) - return - } - - found := false - for _, item := range users { - if item.Username == t.Username { - found = true - break - } - } - - if found { - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "User with username %s already exists"}`, t.Username))) - return - } - - foundUser.Username = t.Username - } - - err = shuffle.SetUser(ctx, foundUser) - if err != nil { - log.Printf("Error patching user %s: %s", foundUser.Username, err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false}`))) - return - } - - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) -} - func handleInfo(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { @@ -1173,13 +860,6 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - //session, err := getSession(ctx, userInfo.Session) - //if err != nil { - // log.Printf("Session %#v doesn't exist: %s", session, err) - // resp.WriteHeader(401) - // resp.Write([]byte(`{"success": false, "reason": "No session"}`)) - // return - //} // This is a long check to see if an inactive admin can access the site parsedAdmin := "false" @@ -1192,9 +872,7 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { parsedAdmin = "true" ctx := context.Background() - q := datastore.NewQuery("Users") - var users []shuffle.User - _, err = dbclient.GetAll(ctx, q, &users) + users, err := shuffle.GetAllUsers(ctx) if err != nil { resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "Failed to get other users when verifying admin user"}`)) @@ -1260,9 +938,7 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { if (len(userInfo.ActiveOrg.Name) == 0 || len(userInfo.ActiveOrg.Id) == 0) && len(userInfo.Orgs) > 0 { _, err := shuffle.GetOrg(ctx, userInfo.Orgs[0]) if err != nil { - var orgs []shuffle.Org - q := datastore.NewQuery("Organizations") - _, err = dbclient.GetAll(ctx, q, &orgs) + orgs, err := shuffle.GetAllOrgs(ctx) if err == nil { newStringOrgs := []string{} newOrgs := []shuffle.Org{} @@ -1274,10 +950,14 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { } if len(newOrgs) > 0 { - userInfo.ActiveOrg = newOrgs[0] + userInfo.ActiveOrg = shuffle.OrgMini{ + Id: newOrgs[0].Id, + Name: newOrgs[0].Name, + } + userInfo.Orgs = newStringOrgs - err = shuffle.SetUser(ctx, &userInfo) + err = shuffle.SetUser(ctx, &userInfo, true) if err != nil { log.Printf("Error patching User for activeOrg: %s", err) } else { @@ -1291,10 +971,10 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { } else { // 1. Check if the org exists by ID // 2. if it does, overwrite user - userInfo.ActiveOrg = shuffle.Org{ + userInfo.ActiveOrg = shuffle.OrgMini{ Id: userInfo.Orgs[0], } - err = shuffle.SetUser(ctx, &userInfo) + err = shuffle.SetUser(ctx, &userInfo, true) if err != nil { log.Printf("Error patching User for activeOrg: %s", err) } @@ -1304,12 +984,15 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { // FIXME: Remove this dependency by updating users' orgs when org itself is updated org, err := shuffle.GetOrg(ctx, userInfo.ActiveOrg.Id) if err == nil { - userInfo.ActiveOrg = *org - userInfo.ActiveOrg.Users = []shuffle.User{} + userInfo.ActiveOrg = shuffle.OrgMini{ + Id: org.Id, + Name: org.Name, + } + + userInfo.ActiveOrg.Users = []shuffle.UserMini{} } - userInfo.ActiveOrg.Users = []shuffle.User{} - userInfo.ActiveOrg.SyncConfig = shuffle.SyncConfig{} + userInfo.ActiveOrg.Users = []shuffle.UserMini{} currentOrg, err := json.Marshal(userInfo.ActiveOrg) if err != nil { currentOrg = []byte("{}") @@ -1336,92 +1019,62 @@ type passwordReset struct { Reference string `json:"reference"` } -func handlePasswordReset(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return +// This might be... a bit off, but that's fine :) +// This might also be stupid, as we want timelines and such +// Anyway, these are super basic stupid stats. +func increaseStatisticsField(ctx context.Context, fieldname, id string, amount int64, orgId string) error { + + // 1. Get current stats + // 2. Increase field(s) + // 3. Put new stats + statisticsId := "global_statistics" + nameKey := fieldname + key := datastore.NameKey(statisticsId, nameKey, nil) + + statisticsItem := shuffle.StatisticsItem{} + newData := shuffle.StatisticsData{ + Timestamp: int64(time.Now().Unix()), + Amount: amount, + Id: id, } - log.Println("Handling password reset") - defaultMessage := "Successfully handled password reset" + if err := dbclient.Get(ctx, key, &statisticsItem); err != nil { + // Should init + if strings.Contains(fmt.Sprintf("%s", err), "entity") { + statisticsItem = shuffle.StatisticsItem{ + Total: amount, + OrgId: orgId, + Fieldname: fieldname, + Data: []shuffle.StatisticsData{ + newData, + }, + } - body, err := ioutil.ReadAll(request.Body) - if err != nil { - log.Println("Failed reading body") - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false}`))) - return + if _, err := dbclient.Put(ctx, key, &statisticsItem); err != nil { + log.Printf("Error setting base stats: %s", err) + return err + } + + return nil + } + //log.Printf("STATSERR: %s", err) + + return err } - var t passwordReset - err = json.Unmarshal(body, &t) - if err != nil { - log.Println("Failed unmarshaling") - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false}`))) - return - } + statisticsItem.Total += amount + statisticsItem.Data = append(statisticsItem.Data, newData) - if t.Password1 != t.Password2 { - resp.WriteHeader(401) - err := "Passwords don't match" - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) - return - } + // New struct, to not add body, author etc + // FIXME - reintroduce + //if _, err := dbclient.Put(ctx, key, &statisticsItem); err != nil { + // log.Printf("Error stats to %s: %s", fieldname, err) + // return err + //} - if len(t.Password1) < 10 || len(t.Password2) < 10 { - resp.WriteHeader(401) - err := "Passwords don't match - 2" - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) - return - } + //log.Printf("Stats: %#v", statisticsItem) - ctx := context.Background() - - // With user, do a search for workflows with user or user's org attached - // Only giving 200 to not give any suspicion whether they're onto an actual user or not - q := datastore.NewQuery("Users").Filter("reset_reference =", t.Reference) - var users []shuffle.User - _, err = dbclient.GetAll(ctx, q, &users) - if err != nil { - log.Printf("Failed getting users: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, defaultMessage))) - return - } - - // FIXME - check reset_timeout - if len(users) != 1 { - log.Printf("Error - no user with id %s", t.Reference) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) - return - } - - Userdata := users[0] - hashedPassword, err := bcrypt.GenerateFromPassword([]byte(t.Password1), 8) - if err != nil { - log.Printf("Wrong password for %s: %s", Userdata.Username, err) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) - return - } - - Userdata.Password = string(hashedPassword) - Userdata.ResetTimeout = 0 - Userdata.ResetReference = "" - err = shuffle.SetUser(ctx, &Userdata) - if err != nil { - log.Printf("Error adding User %s: %s", Userdata.Username, err) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) - return - } - - // FIXME - maybe send a mail here to say that the password was changed - - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, defaultMessage))) + return nil } // FIXME - forward this to emails or whatever CRM system in use @@ -1471,84 +1124,22 @@ func handleContact(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(fmt.Sprintf(`{"success": true, "message": "Thanks for reaching out. We will contact you soon!"}`))) } -func getEnvironmentCount() (int, error) { - ctx := context.Background() - q := datastore.NewQuery("Environments").Limit(1) - count, err := dbclient.Count(ctx, q) - if err != nil { - return 0, err - } - - return count, nil -} - -func getUserCount() (int, error) { - ctx := context.Background() - q := datastore.NewQuery("Users").Limit(1) - count, err := dbclient.Count(ctx, q) - if err != nil { - return 0, err - } - - return count, nil -} - -func handleGetSchedules(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in set new workflowhandler: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - if user.Role != "admin" { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Admin required"}`)) - return - } - - ctx := context.Background() - schedules, err := getAllSchedules(ctx, user.ActiveOrg.Id) - if err != nil { - log.Printf("Failed getting schedules: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Couldn't get schedules"}`)) - return - } - - newjson, err := json.Marshal(schedules) - if err != nil { - log.Printf("Failed unmarshal: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking environments"}`))) - return - } - - //log.Printf("Existing environments: %s", string(newjson)) - - resp.WriteHeader(200) - resp.Write(newjson) -} - func checkAdminLogin(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { return } - count, err := getUserCount() + ctx := context.Background() + users, err := shuffle.GetAllUsers(ctx) if err != nil { resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) return } + count := len(users) + if count == 0 { log.Printf("[WARNING] No users - redirecting for management user") resp.WriteHeader(200) @@ -1585,11 +1176,9 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) { ctx := context.Background() log.Printf("[INFO] Login Username: %s", data.Username) - q := datastore.NewQuery("Users").Filter("Username =", data.Username) - var users []shuffle.User - _, err = dbclient.GetAll(ctx, q, &users) - if err != nil { - log.Printf("Failed getting user %s", data.Username) + users, err := shuffle.FindUser(ctx, strings.ToLower(strings.TrimSpace(data.Username))) + if err != nil && len(users) == 0 { + log.Printf("[WARNING] Failed getting user %s: %s", data.Username, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "Username and/or password is incorrect"}`)) return @@ -1660,7 +1249,7 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) { } Userdata.Session = sessionToken - err = shuffle.SetUser(ctx, &Userdata) + err = shuffle.SetUser(ctx, &Userdata, true) if err != nil { log.Printf("Failed updating user when setting session: %s", err) resp.WriteHeader(500) @@ -1671,76 +1260,12 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) { loginData = fmt.Sprintf(`{"success": true, "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]}`, sessionToken, expiration.Unix()) } - log.Printf("%s SUCCESSFULLY LOGGED IN with session %s", data.Username, Userdata.Session) + log.Printf("[INFO] %s SUCCESSFULLY LOGGED IN with session %s", data.Username, Userdata.Session) resp.WriteHeader(200) resp.Write([]byte(loginData)) } -// Index = Username -func DeleteKeys(ctx context.Context, entity string, value []string) error { - // Non indexed User data - keys := []*datastore.Key{} - for _, item := range value { - keys = append(keys, datastore.NameKey(entity, item, nil)) - } - - err := dbclient.DeleteMulti(ctx, keys) - if err != nil { - log.Printf("Error deleting %s from %s: %s", value, entity, err) - return err - } - - return nil -} - -// Index = Username -func DeleteKey(ctx context.Context, entity string, value string) error { - // Non indexed User data - key1 := datastore.NameKey(entity, value, nil) - - err := dbclient.Delete(ctx, key1) - if err != nil { - log.Printf("Error deleting %s from %s: %s", value, entity, err) - return err - } - - return nil -} - -func setOpenApiDatastore(ctx context.Context, id string, data ParsedOpenApi) error { - k := datastore.NameKey("openapi3", id, nil) - if _, err := dbclient.Put(ctx, k, &data); err != nil { - return err - } - - return nil -} - -func getOpenApiDatastore(ctx context.Context, id string) (ParsedOpenApi, error) { - key := datastore.NameKey("openapi3", id, nil) - api := &ParsedOpenApi{} - if err := dbclient.Get(ctx, key, api); err != nil { - return ParsedOpenApi{}, err - } - - return *api, nil -} - -func setEnvironment(ctx context.Context, data *shuffle.Environment) error { - // clear session_token and API_token for user - k := datastore.NameKey("Environments", strings.ToLower(data.Name), nil) - - // New struct, to not add body, author etc - - if _, err := dbclient.Put(ctx, k, data); err != nil { - log.Println(err) - return err - } - - return nil -} - func fixOrgUser(ctx context.Context, org *shuffle.Org) *shuffle.Org { //found := false //for _, id := range user.Orgs { @@ -2057,7 +1582,7 @@ func handleSetHook(resp http.ResponseWriter, request *http.Request) { log.Println(jsonPrettyPrint(string(body))) - var hook Hook + var hook shuffle.Hook err = json.Unmarshal(body, &hook) if err != nil { log.Printf("Failed unmarshaling: %s", err) @@ -2093,16 +1618,16 @@ func handleSetHook(resp http.ResponseWriter, request *http.Request) { // Get the ID to see whether it exists // FIXME - use return and set READONLY fields (don't allow change from User) ctx := context.Background() - _, err = getHook(ctx, workflowId) + _, err = shuffle.GetHook(ctx, workflowId) if err != nil { - log.Printf("Failed getting hook %s (set): %s", workflowId, err) + log.Printf("[WARNING] Failed getting hook %s (set): %s", workflowId, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "message": "Invalid ID"}`)) return } // Update the fields - err = setHook(ctx, hook) + err = shuffle.SetHook(ctx, hook) if err != nil { log.Printf("Failed setting hook: %s", err) resp.WriteHeader(401) @@ -2115,7 +1640,7 @@ func handleSetHook(resp http.ResponseWriter, request *http.Request) { } // FIXME - some fields (e.g. status) shouldn't be writeable.. Meh -func verifyHook(hook Hook) (bool, string) { +func verifyHook(hook shuffle.Hook) (bool, string) { // required fields: Id, info.name, type, status, running if hook.Id == "" { return false, "Missing required field id" @@ -2236,7 +1761,7 @@ func setSpecificSchedule(resp http.ResponseWriter, request *http.Request) { } jsonPrettyPrint(string(body)) - var schedule ScheduleOld + var schedule shuffle.ScheduleOld err = json.Unmarshal(body, &schedule) if err != nil { log.Printf("Failed unmarshaling: %s", err) @@ -2247,7 +1772,7 @@ func setSpecificSchedule(resp http.ResponseWriter, request *http.Request) { // FIXME - check access etc ctx := context.Background() - err = setSchedule(ctx, schedule) + err = shuffle.SetSchedule(ctx, schedule) if err != nil { log.Printf("Failed setting schedule: %s", err) resp.WriteHeader(401) @@ -2261,16 +1786,6 @@ func setSpecificSchedule(resp http.ResponseWriter, request *http.Request) { return } -//func GetSchedule(ctx context.Context, schedulename string) (*ScheduleOld, error) { -// key := datastore.NameKey("schedules", strings.ToLower(schedulename), nil) -// curUser := &ScheduleOld{} -// if err := dbclient.Get(ctx, key, curUser); err != nil { -// return &ScheduleOld{}, err -// } -// -// return curUser, nil -//} - func getSpecificWebhook(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { @@ -2364,7 +1879,7 @@ func handleDeleteSchedule(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - err = DeleteKey(ctx, "schedules", workflowId) + err = shuffle.DeleteKey(ctx, "schedules", workflowId) if err != nil { resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "message": "Can't delete"}`)) @@ -2392,9 +1907,9 @@ func handleNewSchedule(resp http.ResponseWriter, request *http.Request) { // FIXME - timestamp! // FIXME - applocation - cloud function? timeNow := int64(time.Now().Unix()) - schedule := ScheduleOld{ + schedule := shuffle.ScheduleOld{ Id: newId, - AppInfo: AppInfo{}, + AppInfo: shuffle.AppInfo{}, BaseAppLocation: "/home/frikky/git/shaffuru/tmp/apps", CreationTime: timeNow, LastModificationtime: timeNow, @@ -2402,7 +1917,7 @@ func handleNewSchedule(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - err := setSchedule(ctx, schedule) + err := shuffle.SetSchedule(ctx, schedule) if err != nil { log.Printf("Failed setting hook: %s", err) resp.WriteHeader(401) @@ -2454,9 +1969,9 @@ func handleWebhookCallback(resp http.ResponseWriter, request *http.Request) { hookId = hookId[8:len(hookId)] //log.Printf("HookID: %s", hookId) - hook, err := getHook(ctx, hookId) + hook, err := shuffle.GetHook(ctx, hookId) if err != nil { - log.Printf("Failed getting hook %s (callback): %s", hookId, err) + log.Printf("[WARNING] Failed getting hook %s (callback): %s", hookId, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -2486,10 +2001,15 @@ func handleWebhookCallback(resp http.ResponseWriter, request *http.Request) { log.Printf("This should trigger in the cloud. Duplicate action allowed onprem.") } - type ExecutionStruct struct { - Start string `json:"start"` - ExecutionSource string `json:"execution_source"` - ExecutionArgument string `json:"execution_argument"` + // Check auth + if len(hook.Auth) > 0 { + err = shuffle.CheckHookAuth(request, hook.Auth) + if err != nil { + log.Printf("[WARNING] Failed auth for hook %s: %s", hook.Id, err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Bad authentication headers"}`)) + return + } } body, err := ioutil.ReadAll(request.Body) @@ -2505,31 +2025,30 @@ func handleWebhookCallback(resp http.ResponseWriter, request *http.Request) { // This is a specific fix for MSteams and may fix other things as well // Scared whether it may stop other things though, but that's a future problem // (famous last words) - parsedBody := string(body) - if strings.Contains(parsedBody, "choice") { - if strings.Count(parsedBody, `\\n`) > 2 { - parsedBody = strings.Replace(parsedBody, `\\n`, "", -1) - } - if strings.Count(parsedBody, `\u0022`) > 2 { - parsedBody = strings.Replace(parsedBody, `\u0022`, `"`, -1) - } - if strings.Count(parsedBody, `\\"`) > 2 { - parsedBody = strings.Replace(parsedBody, `\\"`, `"`, -1) - } - - if strings.Contains(parsedBody, `"extra": "{`) { - parsedBody = strings.Replace(parsedBody, `"extra": "{`, `"extra": {`, 1) - parsedBody = strings.Replace(parsedBody, `}"}`, `}}`, 1) - } - } //log.Printf("\n\nPARSEDBODY: %s", parsedBody) - newBody := ExecutionStruct{ + parsedBody := shuffle.GetExecutionbody(body) + newBody := shuffle.ExecutionStruct{ Start: hook.Start, ExecutionSource: "webhook", ExecutionArgument: parsedBody, } + if len(hook.Workflows) == 1 { + workflow, err := shuffle.GetWorkflow(ctx, hook.Workflows[0]) + if err == nil { + for _, branch := range workflow.Branches { + if branch.SourceID == hook.Id { + log.Printf("[INFO] Found ID %s for hook", hook.Id) + if branch.DestinationID != hook.Start { + newBody.Start = branch.DestinationID + break + } + } + } + } + } + b, err := json.Marshal(newBody) if err != nil { log.Printf("Failed newBody marshaling: %s", err) @@ -2592,7 +2111,11 @@ func executeCloudAction(action shuffle.CloudSyncJob, apikey string) error { return err } - client := &http.Client{} + transport := http.DefaultTransport.(*http.Transport).Clone() + client := &http.Client{ + Transport: transport, + } + syncUrl := fmt.Sprintf("%s/api/v1/cloud/sync/handle_action", syncUrl) req, err := http.NewRequest( "POST", @@ -3000,19 +2523,6 @@ func uploadWorkflowResult(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(`{"success": true}`)) } -// Index = Username -func setSchedule(ctx context.Context, schedule ScheduleOld) error { - key1 := datastore.NameKey("schedules", strings.ToLower(schedule.Id), nil) - - // New struct, to not add body, author etc - if _, err := dbclient.Put(ctx, key1, &schedule); err != nil { - log.Printf("Error adding schedule: %s", err) - return err - } - - return nil -} - //dst: {name: "title", required: "true", type: "string"} // //"title": "symptomDescription", @@ -3033,68 +2543,6 @@ func setSchedule(ctx context.Context, schedule ScheduleOld) error { // "value": "kZJmmn05j8wndOGDGvKg/D9eKub1itwO" // }] -func getAllScheduleApps(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - var err error - var limit = 50 - - // FIXME - add org search and public / private - key, ok := request.URL.Query()["limit"] - if ok { - limit, err = strconv.Atoi(key[0]) - if err != nil { - limit = 50 - } - } - - // Max datastore limit - if limit > 1000 { - limit = 1000 - } - - // Get URLs from a database index (mapped by orborus) - ctx := context.Background() - q := datastore.NewQuery("appschedules").Limit(limit) - var allappschedules ScheduleApps - - ret, err := dbclient.GetAll(ctx, q, &allappschedules.Apps) - _ = ret - if err != nil { - log.Printf("Failed getting all apps: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed getting apps"}`))) - return - } - - newjson, err := json.Marshal(allappschedules) - if err != nil { - log.Printf("Failed unmarshal: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking"}`))) - return - } - - resp.WriteHeader(200) - resp.Write(newjson) -} - -func setScheduleApp(ctx context.Context, app ApiYaml, id string) error { - // id = md5(appname:appversion) - key1 := datastore.NameKey("appschedules", id, nil) - - // New struct, to not add body, author etc - if _, err := dbclient.Put(ctx, key1, &app); err != nil { - log.Printf("Error adding schedule app: %s", err) - return err - } - - return nil -} - func findValidScheduleAppFolders(rootAppFolder string) ([]string, error) { rootFiles, err := ioutil.ReadDir(rootAppFolder) if err != nil { @@ -3243,103 +2691,6 @@ func validateAppYaml(fileLocation string) error { return nil } -func getHook(ctx context.Context, hookId string) (*Hook, error) { - key := datastore.NameKey("hooks", strings.ToLower(hookId), nil) - hook := &Hook{} - if err := dbclient.Get(ctx, key, hook); err != nil { - return &Hook{}, err - } - - return hook, nil -} - -func setHook(ctx context.Context, hook Hook) error { - key1 := datastore.NameKey("hooks", strings.ToLower(hook.Id), nil) - - // New struct, to not add body, author etc - if _, err := dbclient.Put(ctx, key1, &hook); err != nil { - log.Printf("Error adding hook: %s", err) - return err - } - - return nil -} - -func handleGetallHooks(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("[WARNING] Api authentication failed in set new workflowhandler: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - ctx := context.Background() - // With user, do a search for workflows with user or user's org attached - q := datastore.NewQuery("hooks").Filter("owner =", user.Username) - var allhooks []Hook - _, err = dbclient.GetAll(ctx, q, &allhooks) - if err != nil { - log.Printf("Failed getting hooks for user %s: %s", user.Username, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - if len(allhooks) == 0 { - resp.WriteHeader(200) - resp.Write([]byte("[]")) - return - } - - newjson, err := json.Marshal(allhooks) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking"}`))) - return - } - - resp.WriteHeader(200) - resp.Write(newjson) -} - -//func deployWebhookCloudrun(ctx context.Context) { -// service, err := cloudrun.NewService(ctx) -// _ = err -// -// projectsLocationsService := cloudrun.NewProjectsLocationsService(service) -// log.Printf("%#v", projectsLocationsService) -// projectsLocationsGetCall := projectsLocationsService.Get("webhook") -// log.Printf("%#v", projectsLocationsGetCall) -// -// location, err := projectsLocationsGetCall.Do() -// log.Printf("%#v, err: %s", location, err) -// -// //func NewProjectsLocationsService(s *Service) *ProjectsLocationsService { -// //func (r *ProjectsLocationsService) Get(name string) *ProjectsLocationsGetCall { -// //func (c *ProjectsLocationsGetCall) Do(opts ...googleapi.CallOption) (*Location, error) { -//} - -// Finds available ports -func findAvailablePorts(startRange int64, endRange int64) string { - for i := startRange; i < endRange; i++ { - s := strconv.FormatInt(i, 10) - l, err := net.Listen("tcp", ":"+s) - - if err == nil { - l.Close() - return s - } - } - - return "" -} - func handleSendalert(resp http.ResponseWriter, request *http.Request) { user, err := shuffle.HandleApiAuthentication(resp, request) if err != nil { @@ -3480,246 +2831,7 @@ type Result struct { List []string `json:"list"` } -var docs_list = Result{List: []string{}} - -func getDocList(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - ctx := context.Background() - //if item, err := memcache.Get(ctx, "docs_list"); err == memcache.ErrCacheMiss { - // // Not in cache - //} else if err != nil { - // // Error with cache - // log.Printf("Error getting item: %v", err) - //} else { - // resp.WriteHeader(200) - // resp.Write([]byte(item.Value)) - // return - //} - - if len(docs_list.List) > 0 { - b, err := json.Marshal(docs_list) - if err != nil { - log.Printf("Failed marshaling result: %s", err) - //http.Error(resp, err.Error(), 500) - } else { - resp.WriteHeader(200) - resp.Write(b) - return - } - } - - client := github.NewClient(nil) - _, item1, _, err := client.Repositories.GetContents(ctx, "frikky", "shuffle-docs", "docs", nil) - if err != nil { - log.Printf("Github error: %s", err) - resp.WriteHeader(500) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Error listing directory: %s"`, err))) - return - } - - if len(item1) == 0 { - resp.WriteHeader(500) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "No docs available."}`))) - return - } - - names := []string{} - for _, item := range item1 { - if !strings.HasSuffix(*item.Name, "md") { - continue - } - - names = append(names, (*item.Name)[0:len(*item.Name)-3]) - } - - log.Println(names) - - var result Result - result.Success = true - result.Reason = "Success" - result.List = names - docs_list = result - - b, err := json.Marshal(result) - if err != nil { - http.Error(resp, err.Error(), 500) - return - } - - //item := &memcache.Item{ - // Key: "docs_list", - // Value: b, - // Expiration: time.Minute * 60, - //} - - //if err := memcache.Add(ctx, item); err == memcache.ErrNotStored { - // if err := memcache.Set(ctx, item); err != nil { - // log.Printf("Error setting item: %v", err) - // } - //} else if err != nil { - // log.Printf("error adding item: %v", err) - //} else { - // log.Printf("Set cache for %s", item.Key) - //} - - resp.WriteHeader(200) - resp.Write(b) -} - // r.HandleFunc("/api/v1/docs/{key}", getDocs).Methods("GET", "OPTIONS") -var alldocs = map[string][]byte{} - -func getDocs(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - location := strings.Split(request.URL.String(), "/") - if len(location) != 5 { - resp.WriteHeader(404) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"}`))) - return - } - - //ctx := context.Background() - docPath := fmt.Sprintf("https://raw.githubusercontent.com/shaffuru/shuffle-docs/master/docs/%s.md", location[4]) - //location[4] - //var, ok := alldocs["asd"] - key, ok := alldocs[fmt.Sprintf("%s", location[4])] - // Custom cache for github issues lol - if ok { - resp.WriteHeader(200) - resp.Write(key) - return - } - - client := &http.Client{} - req, err := http.NewRequest( - "GET", - docPath, - nil, - ) - - if err != nil { - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"}`))) - resp.WriteHeader(404) - //setBadMemcache(ctx, docPath) - return - } - - newresp, err := client.Do(req) - if err != nil { - resp.WriteHeader(404) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad path. Use e.g. /api/v1/docs/workflows.md"}`))) - //setBadMemcache(ctx, docPath) - return - } - - body, err := ioutil.ReadAll(newresp.Body) - if err != nil { - resp.WriteHeader(500) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't parse data"}`))) - //setBadMemcache(ctx, docPath) - return - } - - type Result struct { - Success bool `json:"success"` - Reason string `json:"reason"` - } - - var result Result - result.Success = true - - //applog.Infof(ctx, string(body)) - //applog.Infof(ctx, "Url: %s", docPath) - //applog.Infof(ctx, "Status: %d", newresp.StatusCode) - //applog.Infof(ctx, "GOT BODY OF LENGTH %d", len(string(body))) - - result.Reason = string(body) - b, err := json.Marshal(result) - if err != nil { - http.Error(resp, err.Error(), 500) - //setBadMemcache(ctx, docPath) - return - } - - alldocs[location[4]] = b - - // Add to cache if it doesn't exist - //item := &memcache.Item{ - // Key: docPath, - // Value: b, - // Expiration: time.Minute * 60, - //} - - //if err := memcache.Add(ctx, item); err == memcache.ErrNotStored { - // if err := memcache.Set(ctx, item); err != nil { - // log.Printf("Error setting item: %v", err) - // } - //} else if err != nil { - // log.Printf("error adding item: %v", err) - //} else { - // log.Printf("Set cache for %s", item.Key) - //} - - resp.WriteHeader(200) - resp.Write(b) -} - -func handleGetSpecificStats(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - _, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in getting specific workflow: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - location := strings.Split(request.URL.String(), "/") - - var statsId string - if location[1] == "api" { - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - statsId = location[4] - } - - ctx := context.Background() - statisticsId := "global_statistics" - nameKey := statsId - key := datastore.NameKey(statisticsId, nameKey, nil) - statisticsItem := StatisticsItem{} - if err := dbclient.Get(ctx, key, &statisticsItem); err != nil { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - b, err := json.Marshal(statisticsItem) - if err != nil { - log.Printf("Failed to marshal data: %s", err) - resp.WriteHeader(401) - return - } - - resp.WriteHeader(200) - resp.Write([]byte(b)) -} func getOpenapi(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) @@ -3761,7 +2873,7 @@ func getOpenapi(resp http.ResponseWriter, request *http.Request) { // log.Println("You're supposed to be able to continue now.") //} - parsedApi, err := getOpenApiDatastore(ctx, id) + parsedApi, err := shuffle.GetOpenApiDatastore(ctx, id) if err != nil { resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) @@ -3851,7 +2963,7 @@ func echoOpenapiData(resp http.ResponseWriter, request *http.Request) { resp.Write(urlbody) } -func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) { +func handleSwaggerValidation(body []byte) (shuffle.ParsedOpenApi, error) { type versionCheck struct { Swagger string `datastore:"swagger" json:"swagger" yaml:"swagger"` SwaggerVersion string `datastore:"swaggerVersion" json:"swaggerVersion" yaml:"swaggerVersion"` @@ -3872,7 +2984,7 @@ func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) { // support map[string]interface and similar (openapi3.Swagger) var version versionCheck - parsed := ParsedOpenApi{} + parsed := shuffle.ParsedOpenApi{} swaggerdata := []byte{} idstring := "" @@ -3882,7 +2994,7 @@ func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) { //log.Printf("Json err: %s", err) err = yaml.Unmarshal(body, &version) if err != nil { - log.Printf("Yaml error (1): %s", err) + log.Printf("[WARNING] Yaml error (1): %s", err) } else { //log.Printf("Successfully parsed YAML!") } @@ -3902,13 +3014,13 @@ func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) { swaggerv3, err := swaggerLoader.LoadSwaggerFromData(body) if err != nil { log.Printf("Failed parsing OpenAPI: %s", err) - return ParsedOpenApi{}, err + return shuffle.ParsedOpenApi{}, err } swaggerdata, err = json.Marshal(swaggerv3) if err != nil { log.Printf("Failed unmarshaling v3 data: %s", err) - return ParsedOpenApi{}, err + return shuffle.ParsedOpenApi{}, err } hasher := md5.New() @@ -3925,8 +3037,8 @@ func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) { //log.Printf("Json error? %s", err) err = yaml.Unmarshal(body, &swagger) if err != nil { - log.Printf("Yaml error (2): %s", err) - return ParsedOpenApi{}, err + log.Printf("[WARNING] Yaml error (2): %s", err) + return shuffle.ParsedOpenApi{}, err } else { //log.Printf("Valid yaml!") } @@ -3936,13 +3048,13 @@ func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) { swaggerv3, err := openapi2conv.ToV3Swagger(&swagger) if err != nil { log.Printf("Failed converting from openapi2 to 3: %s", err) - return ParsedOpenApi{}, err + return shuffle.ParsedOpenApi{}, err } swaggerdata, err = json.Marshal(swaggerv3) if err != nil { log.Printf("Failed unmarshaling v3 data: %s", err) - return ParsedOpenApi{}, err + return shuffle.ParsedOpenApi{}, err } hasher := md5.New() @@ -3959,7 +3071,7 @@ func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) { body = swaggerdata // Parsing it to swagger 3 - parsed = ParsedOpenApi{ + parsed = shuffle.ParsedOpenApi{ ID: idstring, Body: string(body), Success: true, @@ -3968,222 +3080,7 @@ func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) { return parsed, err } -// FIXME: Migrate this to use handleSwaggerValidation() -func validateSwagger(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - // Just here to verify that the user is logged in - _, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in validate swagger: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - body, err := ioutil.ReadAll(request.Body) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Failed reading body"}`)) - return - } - - type versionCheck struct { - Swagger string `datastore:"swagger" json:"swagger" yaml:"swagger"` - SwaggerVersion string `datastore:"swaggerVersion" json:"swaggerVersion" yaml:"swaggerVersion"` - OpenAPI string `datastore:"openapi" json:"openapi" yaml:"openapi"` - } - - //body = []byte(`swagger: "2.0"`) - //body = []byte(`swagger: '1.0'`) - //newbody := string(body) - //newbody = strings.TrimSpace(newbody) - //body = []byte(newbody) - //log.Println(string(body)) - //tmpbody, err := yaml.YAMLToJSON(body) - //log.Println(err) - //log.Println(string(tmpbody)) - - // This has to be done in a weird way because Datastore doesn't - // support map[string]interface and similar (openapi3.Swagger) - var version versionCheck - - log.Printf("API length SET: %d", len(string(body))) - - isJson := false - err = json.Unmarshal(body, &version) - if err != nil { - log.Printf("Json err: %s", err) - err = yaml.Unmarshal(body, &version) - if err != nil { - log.Printf("Yaml error (3): %s", err) - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed reading openapi to json and yaml. Is version defined?: %s"}`, err))) - return - } else { - log.Printf("[INFO] Successfully parsed YAML (3)!") - } - } else { - isJson = true - log.Printf("[INFO] Successfully parsed JSON!") - } - - if len(version.SwaggerVersion) > 0 && len(version.Swagger) == 0 { - version.Swagger = version.SwaggerVersion - } - log.Printf("[INFO] Version: %#v", version) - log.Printf("[INFO] OpenAPI: %s", version.OpenAPI) - - if strings.HasPrefix(version.Swagger, "3.") || strings.HasPrefix(version.OpenAPI, "3.") { - log.Println("[INFO] Handling v3 API") - swaggerLoader := openapi3.NewSwaggerLoader() - swaggerLoader.IsExternalRefsAllowed = true - swagger, err := swaggerLoader.LoadSwaggerFromData(body) - if err != nil { - log.Printf("[WARNING] Failed to convert v3 API: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) - return - } - - hasher := md5.New() - hasher.Write(body) - idstring := hex.EncodeToString(hasher.Sum(nil)) - - log.Printf("Swagger v3 validation success with ID %s and %d paths!", idstring, len(swagger.Paths)) - - if !isJson { - log.Printf("[INFO] NEED TO TRANSFORM FROM YAML TO JSON for %s", idstring) - } - - swaggerdata, err := json.Marshal(swagger) - if err != nil { - log.Printf("Failed unmarshaling v3 data: %s", err) - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed marshalling swaggerv3 data: %s"}`, err))) - return - } - parsed := ParsedOpenApi{ - ID: idstring, - Body: string(swaggerdata), - } - - ctx := context.Background() - err = setOpenApiDatastore(ctx, idstring, parsed) - if err != nil { - log.Printf("Failed uploading openapi to datastore: %s", err) - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed reading openapi2: %s"}`, err))) - return - } - - log.Printf("[INFO] Successfully set OpenAPI with ID %s", idstring) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "id": "%s"}`, idstring))) - return - } else { //strings.HasPrefix(version.Swagger, "2.") || strings.HasPrefix(version.OpenAPI, "2.") { - // Convert - log.Println("Handling v2 API") - var swagger openapi2.Swagger - //log.Println(string(body)) - err = json.Unmarshal(body, &swagger) - if err != nil { - log.Printf("Json error for v2 - trying yaml: %s", err) - err = yaml.Unmarshal([]byte(body), &swagger) - if err != nil { - log.Printf("Yaml error (4): %s", err) - - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed reading openapi2: %s"}`, err))) - return - } else { - log.Printf("Found valid yaml!") - } - - } - - swaggerv3, err := openapi2conv.ToV3Swagger(&swagger) - if err != nil { - log.Printf("Failed converting from openapi2 to 3: %s", err) - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed converting from openapi2 to openapi3: %s"}`, err))) - return - } - - swaggerdata, err := json.Marshal(swaggerv3) - if err != nil { - log.Printf("Failed unmarshaling v3 from v2 data: %s", err) - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed marshalling swaggerv3 data: %s"}`, err))) - return - } - - hasher := md5.New() - hasher.Write(swaggerdata) - idstring := hex.EncodeToString(hasher.Sum(nil)) - if !isJson { - log.Printf("FIXME: NEED TO TRANSFORM FROM YAML TO JSON for %s?", idstring) - } - log.Printf("Swagger v2 -> v3 validation success with ID %s!", idstring) - - parsed := ParsedOpenApi{ - ID: idstring, - Body: string(swaggerdata), - } - - ctx := context.Background() - err = setOpenApiDatastore(ctx, idstring, parsed) - if err != nil { - log.Printf("Failed uploading openapi2 to datastore: %s", err) - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed reading openapi2: %s"}`, err))) - return - } - - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "id": "%s"}`, idstring))) - return - } - /* - else { - log.Printf("Swagger / OpenAPI version %s is not supported or there is an error.", version.Swagger) - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Swagger version %s is not currently supported"}`, version.Swagger))) - return - } - */ - - // save the openapi ID - resp.WriteHeader(422) - resp.Write([]byte(`{"success": false}`)) -} - -// Creates an app from the app builder -func verifySwagger(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - log.Printf("[INFO] SETTING APP TO LIVE!!!") - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in verify swagger: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - body, err := ioutil.ReadAll(request.Body) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Failed reading body"}`)) - return - } - +func buildSwaggerApp(resp http.ResponseWriter, body []byte, user shuffle.User) { type Test struct { Editing bool `datastore:"editing"` Id string `datastore:"id"` @@ -4191,9 +3088,9 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { } var test Test - err = json.Unmarshal(body, &test) + err := json.Unmarshal(body, &test) if err != nil { - log.Printf("Failed unmarshalling test: %s", err) + log.Printf("[WARNING] Failed unmarshalling test: %s", err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -4203,12 +3100,13 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { hasher := md5.New() hasher.Write(body) newmd5 := hex.EncodeToString(hasher.Sum(nil)) - if test.Editing { + + if test.Editing && len(user.Id) > 0 { // Quick verification test ctx := context.Background() app, err := shuffle.GetApp(ctx, test.Id, user) if err != nil { - log.Printf("Error getting app when editing: %s", app.Name) + log.Printf("[WARNING] Error getting app when editing: %s", app.Name) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -4222,7 +3120,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { return } - log.Printf("[INFO] EDITING APP WITH ID %s", app.ID) + log.Printf("[INFO] %s is EDITING APP WITH ID %s and md5 %s", user.Id, app.ID, newmd5) newmd5 = app.ID } @@ -4235,6 +3133,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { swagger, err := swaggerLoader.LoadSwaggerFromData(body) if err != nil { log.Printf("[ERROR] Swagger validation error: %s", err) + //log.Printf("%s", string(body)) resp.WriteHeader(500) resp.Write([]byte(`{"success": false, "reason": "Failed verifying openapi"}`)) return @@ -4360,20 +3259,6 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { log.Printf("[INFO] Successfully stitched ZIPFILE for %s", identifier) - // 4. Upload as cloud function - this apikey is specifically for cloud functions rofl - //environmentVariables := map[string]string{ - // "FUNCTION_APIKEY": apikey, - //} - - //fullLocation := fmt.Sprintf("gs://%s/%s", bucketName, applocation) - //err = deployCloudFunctionPython(ctx, identifier, defaultLocation, fullLocation, environmentVariables) - //if err != nil { - // log.Printf("Error uploading cloud function: %s", err) - // resp.WriteHeader(500) - // resp.Write([]byte(`{"success": false, "reason": "Failed to upload function"}`)) - // return - //} - // 4. Build the image locally. // FIXME: Should be moved to a local docker registry dockerLocation := fmt.Sprintf("%s/Dockerfile", basePath) @@ -4419,16 +3304,18 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { user.PrivateApps[foundNumber] = api } - err = shuffle.SetUser(ctx, &user) - if err != nil { - log.Printf("[ERROR] Failed adding verification for user %s: %s", user.Username, err) - resp.WriteHeader(500) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "Failed updating user"}`))) - return + if len(user.Id) > 0 { + err = shuffle.SetUser(ctx, &user, true) + if err != nil { + log.Printf("[ERROR] Failed adding verification for user %s: %s", user.Username, err) + resp.WriteHeader(500) + resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "Failed updating user"}`))) + return + } } //log.Printf("DO I REACH HERE WHEN SAVING?") - parsed := ParsedOpenApi{ + parsed := shuffle.ParsedOpenApi{ ID: newmd5, Body: string(body), } @@ -4437,15 +3324,19 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { // FIXME: Might cause versioning issues if we re-use the same!! // FIXME: Need a way to track different versions of the same app properly. // Hint: Save API.id somewhere, and use newmd5 to save latest version - err = setOpenApiDatastore(ctx, newmd5, parsed) - if err != nil { - log.Printf("[ERROR] Failed saving to datastore: %s", err) - resp.WriteHeader(500) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%"}`, err))) + + if len(user.Id) > 0 { + err = shuffle.SetOpenApiDatastore(ctx, newmd5, parsed) + if err != nil { + log.Printf("[ERROR] Failed saving app %s to database: %s", newmd5, err) + resp.WriteHeader(500) + resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%"}`, err))) + } + + shuffle.SetOpenApiDatastore(ctx, api.ID, parsed) } // Backup every single one - setOpenApiDatastore(ctx, api.ID, parsed) /* err = increaseStatisticsField(ctx, "total_apps_created", newmd5, 1, user.ActiveOrg.Id) @@ -4463,10 +3354,40 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { shuffle.DeleteCache(ctx, cacheKey) cacheKey = fmt.Sprintf("workflowapps-sorted-500") shuffle.DeleteCache(ctx, cacheKey) + cacheKey = fmt.Sprintf("workflowapps-sorted-1000") + shuffle.DeleteCache(ctx, cacheKey) shuffle.DeleteCache(ctx, fmt.Sprintf("apps_%s", user.Id)) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true, "id": "%s"}`, api.ID))) + if len(user.Id) > 0 { + resp.WriteHeader(200) + resp.Write([]byte(fmt.Sprintf(`{"success": true, "id": "%s"}`, api.ID))) + } +} + +// Creates an app from the app builder +func verifySwagger(resp http.ResponseWriter, request *http.Request) { + cors := handleCors(resp, request) + if cors { + return + } + + //log.Printf("[INFO] TRY TO SET APP TO LIVE!!!") + user, err := shuffle.HandleApiAuthentication(resp, request) + if err != nil { + log.Printf("Api authentication failed in verify swagger: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + body, err := ioutil.ReadAll(request.Body) + if err != nil { + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Failed reading body"}`)) + return + } + + buildSwaggerApp(resp, body, user) } func healthCheckHandler(resp http.ResponseWriter, request *http.Request) { @@ -4559,6 +3480,8 @@ func handleAppHotload(ctx context.Context, location string, forceUpdate bool) er shuffle.DeleteCache(ctx, cacheKey) cacheKey = fmt.Sprintf("workflowapps-sorted-500") shuffle.DeleteCache(ctx, cacheKey) + cacheKey = fmt.Sprintf("workflowapps-sorted-1000") + shuffle.DeleteCache(ctx, cacheKey) //shuffle.DeleteCache(ctx, fmt.Sprintf("apps_%s", user.Id)) return nil @@ -4629,7 +3552,7 @@ func handleCloudJob(job shuffle.CloudSyncJob) error { if job.Action == "execute" { // FIXME: Get the email ctx := context.Background() - maildata := MailData{} + maildata := shuffle.MailData{} err := json.Unmarshal([]byte(job.ThirdItem), &maildata) if err != nil { log.Printf("Maildata unmarshal error: %s", err) @@ -4637,7 +3560,7 @@ func handleCloudJob(job shuffle.CloudSyncJob) error { } hookId := job.Id - hook, err := getTriggerAuth(ctx, hookId) + hook, err := shuffle.GetTriggerAuth(ctx, hookId) if err != nil { log.Printf("[INFO] Failed getting trigger %s (callback cloud): %s", hookId, err) return err @@ -4656,7 +3579,7 @@ func handleCloudJob(job shuffle.CloudSyncJob) error { //log.Printf("INSIDE GET OUTLOOK EMAIL!: %#v, %s", emails, err) //type FullEmail struct { - email := FullEmail{} + email := shuffle.FullEmail{} if len(emails) == 1 { email = emails[0] } @@ -4899,16 +3822,363 @@ func remoteOrgJobHandler(org shuffle.Org, interval int) error { return nil } +func runInitCloudSetup() { + action := shuffle.CloudSyncJob{ + Type: "setup", + Action: "init", + OrgId: "", + PrimaryItemId: "", + } + + err := executeCloudAction(action, "") + if err != nil { + log.Printf("[INFO] Failed initial setup: %s", err) + } else { + log.Printf("[INFO] Ran initial setup!") + } +} + +func runInitEs(ctx context.Context) { + log.Printf("[DEBUG] Starting INIT setup (ES)") + + defaultEnv := os.Getenv("ORG_ID") + if len(defaultEnv) == 0 { + defaultEnv = "Shuffle" + log.Printf("[DEBUG] Setting default environment for org to %s", defaultEnv) + } + + log.Printf("[DEBUG] Getting organizations") + activeOrgs, err := shuffle.GetAllOrgs(ctx) + setUsers := false + //log.Printf("ORGS: %d", len(activeOrgs)) + if err != nil { + if fmt.Sprintf("%s", err) == "EOF" { + time.Sleep(7 * time.Second) + runInitEs(ctx) + return + } + + log.Printf("[DEBUG] Error getting organizations: %s", err) + runInitCloudSetup() + } else { + // Add all users to it + if len(activeOrgs) == 1 { + setUsers = true + } else if len(activeOrgs) == 0 { + log.Printf(`[DEBUG] No orgs. Setting NEW org "default"`) + runInitCloudSetup() + + //orgSetupName := "default" + //orgId := uuid.NewV4().String() + //newOrg := shuffle.Org{ + // Name: orgSetupName, + // Id: orgId, + // Org: orgSetupName, + // Users: []shuffle.User{}, + // Roles: []string{"admin", "user"}, + // CloudSync: false, + //} + + //err = shuffle.SetOrg(ctx, newOrg, orgId) + //if err != nil { + // log.Printf("Failed setting organization: %s", err) + //} else { + // log.Printf("Successfully created the default org!") + // setUsers = true + + // item := shuffle.Environment{ + // Name: defaultEnv, + // Type: "onprem", + // OrgId: orgId, + // Default: true, + // Id: uuid.NewV4().String(), + // } + + // err = shuffle.SetEnvironment(ctx, &item) + // if err != nil { + // log.Printf("[WARNING] Failed setting up new environment for new org") + // } + //} + + } else { + log.Printf("[DEBUG] There are %d org(s).", len(activeOrgs)) + + if len(activeOrgs) == 1 { + if len(activeOrgs[0].Users) == 0 { + log.Printf("ORG doesn't have any users??") + + users, err := shuffle.GetAllUsers(ctx) + if err != nil && len(users) == 0 { + log.Printf("Failed getting users in org fix") + } else { + // Remapping everyone to admin. This should never happen. + + for _, user := range users { + user.ActiveOrg = shuffle.OrgMini{ + Id: activeOrgs[0].Id, + Name: activeOrgs[0].Name, + Role: "admin", + } + + activeOrgs[0].Users = append(activeOrgs[0].Users, user) + } + + err = shuffle.SetOrg(ctx, activeOrgs[0], activeOrgs[0].Id) + if err != nil { + log.Printf("Failed setting org: %s", err) + } else { + log.Printf("Successfully updated org to have users!") + } + } + + } + } + } + } + + schedules, err := shuffle.GetAllSchedules(ctx, "ALL") + if err != nil { + log.Printf("[WARNING] Failed getting schedules during service init: %s", err) + } else { + log.Printf("[INFO] Setting up %d schedule(s)", len(schedules)) + url := &url.URL{} + for _, schedule := range schedules { + if schedule.Environment == "cloud" { + log.Printf("Skipping cloud schedule") + continue + } + + //log.Printf("Schedule: %#v", schedule) + job := func() { + //log.Printf("[INFO] Running schedule %s with interval %d.", schedule.Id, schedule.Seconds) + //log.Printf("ARG: %s", schedule.WrappedArgument) + + request := &http.Request{ + URL: url, + Method: "POST", + Body: ioutil.NopCloser(strings.NewReader(schedule.WrappedArgument)), + } + + _, _, err := handleExecution(schedule.WorkflowId, shuffle.Workflow{}, request) + if err != nil { + log.Printf("[WARNING] Failed to execute %s: %s", schedule.WorkflowId, err) + } + } + + //log.Printf("Schedule time: every %d seconds", schedule.Seconds) + jobret, err := newscheduler.Every(schedule.Seconds).Seconds().NotImmediately().Run(job) + if err != nil { + log.Printf("Failed to schedule workflow: %s", err) + } + + scheduledJobs[schedule.Id] = jobret + } + } + + users, err := shuffle.GetAllUsers(ctx) + if len(users) == 0 { + log.Printf("[INFO] Trying to set up user based on environments SHUFFLE_DEFAULT_USERNAME & SHUFFLE_DEFAULT_PASSWORD") + username := os.Getenv("SHUFFLE_DEFAULT_USERNAME") + password := os.Getenv("SHUFFLE_DEFAULT_PASSWORD") + + if len(username) == 0 || len(password) == 0 || len(activeOrgs) > 0 { + log.Printf("[DEBUG] SHUFFLE_DEFAULT_USERNAME and SHUFFLE_DEFAULT_PASSWORD not defined as environments. Running without default user.") + } else { + apikey := os.Getenv("SHUFFLE_DEFAULT_APIKEY") + + log.Printf("[DEBUG] Creating org for default user %s", username) + orgId := uuid.NewV4().String() + orgSetupName := "default" + newOrg := shuffle.Org{ + Name: orgSetupName, + Id: orgId, + Org: orgSetupName, + Users: []shuffle.User{}, + Roles: []string{"admin", "user"}, + CloudSync: false, + } + + err = shuffle.SetOrg(ctx, newOrg, orgId) + setUsers := false + if err != nil { + log.Printf("[WARNING] Failed setting organization when creating original user: %s", err) + } else { + log.Printf("[DEBUG] Successfully created the default org with id %s!", orgId) + setUsers = true + + item := shuffle.Environment{ + Name: defaultEnv, + Type: "onprem", + OrgId: orgId, + Default: true, + Id: uuid.NewV4().String(), + } + + err = shuffle.SetEnvironment(ctx, &item) + if err != nil { + log.Printf("[WARNING] Failed setting up new environment") + } + } + + if setUsers { + tmpOrg := shuffle.OrgMini{ + Name: orgSetupName, + Id: orgId, + } + + err = createNewUser(username, password, "admin", apikey, tmpOrg) + if err != nil { + log.Printf("[INFO] Failed to create default user %s: %s", username, err) + } else { + log.Printf("[INFO] Successfully created user %s", username) + } + } + } + } + _ = setUsers + + log.Printf("[INFO] Starting cloud schedules for orgs if enabled!") + type requestStruct struct { + ApiKey string `json:"api_key"` + } + + for _, org := range activeOrgs { + if !org.CloudSync { + log.Printf("[WARNING] Skipping org %s because sync isn't set (1).", org.Id) + continue + } + + //interval := int(org.SyncConfig.Interval) + interval := 15 + if interval == 0 { + log.Printf("[WARNING] Skipping org %s because sync isn't set (0).", org.Id) + continue + } + + log.Printf("[DEBUG] Should start schedule for org %s", org.Name) + job := func() { + err := remoteOrgJobHandler(org, interval) + if err != nil { + log.Printf("[ERROR] Failed request with remote org setup (2): %s", err) + } + } + + jobret, err := newscheduler.Every(int(interval)).Seconds().NotImmediately().Run(job) + if err != nil { + log.Printf("[CRITICAL] Failed to schedule org: %s", err) + } else { + log.Printf("[INFO] Started sync on interval %d for org %s (%s)", interval, org.Name, org.Id) + scheduledOrgs[org.Id] = jobret + } + } + + forceUpdateEnv := os.Getenv("SHUFFLE_APP_FORCE_UPDATE") + forceUpdate := false + if len(forceUpdateEnv) > 0 && forceUpdateEnv == "true" { + log.Printf("Forcing to rebuild apps") + forceUpdate = true + } + + // Getting apps to see if we should initialize a test + // FIXME: Isn't this a little backwards? + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) + log.Printf("[INFO] Getting and validating workflowapps. Got %d with err %#v", len(workflowapps), err) + if err != nil && len(workflowapps) == 0 { + log.Printf("[WARNING] Failed getting apps (runInit): %s", err) + } else if err == nil { + log.Printf("[DEBUG] Downloading default apps") + fs := memfs.New() + storer := memory.NewStorage() + + url := os.Getenv("SHUFFLE_APP_DOWNLOAD_LOCATION") + if len(url) == 0 { + url = "https://github.com/frikky/shuffle-apps" + } + + username := os.Getenv("SHUFFLE_DOWNLOAD_AUTH_USERNAME") + password := os.Getenv("SHUFFLE_DOWNLOAD_AUTH_PASSWORD") + + cloneOptions := &git.CloneOptions{ + URL: url, + } + + if len(username) > 0 && len(password) > 0 { + cloneOptions.Auth = &http2.BasicAuth{ + Username: username, + Password: password, + } + } + branch := os.Getenv("SHUFFLE_DOWNLOAD_AUTH_BRANCH") + if len(branch) > 0 && branch != "master" && branch != "main" { + cloneOptions.ReferenceName = plumbing.ReferenceName(branch) + } + + log.Printf("[DEBUG] Getting apps from %s", url) + + r, err := git.Clone(storer, fs, cloneOptions) + + if err != nil { + log.Printf("Failed loading repo into memory (init): %s", err) + } + + dir, err := fs.ReadDir("") + if err != nil { + log.Printf("Failed reading folder: %s", err) + } + _ = r + //iterateAppGithubFolders(fs, dir, "", "testing") + + // FIXME: Get all the apps? + _, _, err = iterateAppGithubFolders(fs, dir, "", "", forceUpdate) + if err != nil { + log.Printf("[WARNING] Error from app load in init: %s", err) + } + //_, _, err = iterateAppGithubFolders(fs, dir, "", "", forceUpdate) + + // Hotloads locally + location := os.Getenv("SHUFFLE_APP_HOTLOAD_FOLDER") + if len(location) != 0 { + handleAppHotload(ctx, location, false) + } + } + + log.Printf("[INFO] Downloading OpenAPI data for search - EXTRA APPS") + apis := "https://github.com/frikky/security-openapis" + + // THis gets memory problems hahah + //apis := "https://github.com/APIs-guru/openapi-directory" + fs := memfs.New() + storer := memory.NewStorage() + cloneOptions := &git.CloneOptions{ + URL: apis, + } + _, err = git.Clone(storer, fs, cloneOptions) + if err != nil { + log.Printf("Failed loading repo %s into memory: %s", apis, err) + } else { + log.Printf("[INFO] Finished git clone. Looking for updates to the repo.") + dir, err := fs.ReadDir("") + if err != nil { + log.Printf("Failed reading folder: %s", err) + } + + iterateOpenApiGithub(fs, dir, "", "") + log.Printf("[INFO] Finished downloading extra API samples") + } + + log.Printf("[INFO] Finished INIT (ES)") +} + // Handles configuration items during Shuffle startup func runInit(ctx context.Context) { // Setting stats for backend starts (failure count as well) - log.Printf("Starting INIT setup") - err := increaseStatisticsField(ctx, "backend_executions", "", 1, "") - if err != nil { - log.Printf("Failed increasing local stats: %s", err) - } - log.Printf("Finalized init statistics update") + //err := increaseStatisticsField(ctx, "backend_executions", "", 1, "") + //if err != nil { + // log.Printf("Failed increasing local stats: %s", err) + //} + //log.Printf("[DEBUG] Finalized init statistics update") + log.Printf("[DEBUG] Starting INIT setup") httpProxy := os.Getenv("HTTP_PROXY") if len(httpProxy) > 0 { log.Printf("Running with HTTP proxy %s (env: HTTP_PROXY)", httpProxy) @@ -4954,9 +4224,10 @@ func runInit(ctx context.Context) { */ setUsers := false + log.Printf("[DEBUG] Getting organizations") orgQuery := datastore.NewQuery("Organizations") var activeOrgs []shuffle.Org - _, err = dbclient.GetAll(ctx, orgQuery, &activeOrgs) + _, err := dbclient.GetAll(ctx, orgQuery, &activeOrgs) if err != nil { log.Printf("Error getting organizations!") } else { @@ -4967,7 +4238,7 @@ func runInit(ctx context.Context) { log.Printf("Organizations exist!") if len(activeOrgs) == 0 { - log.Printf(`No orgs. Setting org "default"`) + log.Printf(`[DEBUG] No orgs. Setting org "default"`) orgSetupName := "default" orgId := uuid.NewV4().String() newOrg := shuffle.Org{ @@ -4987,7 +4258,40 @@ func runInit(ctx context.Context) { setUsers = true } } else { - log.Printf("There are %d org(s).", len(activeOrgs)) + log.Printf("[DEBUG] There are %d org(s).", len(activeOrgs)) + + if len(activeOrgs) == 1 { + if len(activeOrgs[0].Users) == 0 { + log.Printf("[WARNING] ORG doesn't have any users??") + + q := datastore.NewQuery("Users") + var users []shuffle.User + _, err = dbclient.GetAll(ctx, q, &users) + if err != nil && len(users) == 0 { + log.Printf("Failed getting users in org fix") + } else { + // Remapping everyone to admin. This should never happen. + + for _, user := range users { + user.ActiveOrg = shuffle.OrgMini{ + Id: activeOrgs[0].Id, + Name: activeOrgs[0].Name, + Role: "admin", + } + + activeOrgs[0].Users = append(activeOrgs[0].Users, user) + } + + err = shuffle.SetOrg(ctx, activeOrgs[0], activeOrgs[0].Id) + if err != nil { + log.Printf("Failed setting org: %s", err) + } else { + log.Printf("Successfully updated org to have users!") + } + } + + } + } } } @@ -5000,11 +4304,13 @@ func runInit(ctx context.Context) { _, err = dbclient.GetAll(ctx, q, &users) if err == nil { setOrgBool := false + usernames := []string{} for _, user := range users { + usernames = append(usernames, user.Username) newUser := shuffle.User{ Username: user.Username, Id: user.Id, - ActiveOrg: shuffle.Org{ + ActiveOrg: shuffle.OrgMini{ Id: activeOrg.Id, }, Orgs: []string{activeOrg.Id}, @@ -5025,6 +4331,8 @@ func runInit(ctx context.Context) { } } + log.Printf("Users found: %s", strings.Join(usernames, ", ")) + if setOrgBool { err = shuffle.SetOrg(ctx, activeOrg, activeOrg.Id) if err != nil { @@ -5050,12 +4358,14 @@ func runInit(ctx context.Context) { q := datastore.NewQuery("Users").Filter("active =", true) var activeusers []shuffle.User _, err = dbclient.GetAll(ctx, q, &activeusers) - if err != nil { + if err != nil && len(activeusers) == 0 { log.Printf("Error getting users during init: %s", err) } else { + log.Printf("Parsing all users and setting them to active.") q := datastore.NewQuery("Users") var users []shuffle.User _, err := dbclient.GetAll(ctx, q, &users) + //log.Printf("User ret: %s", err) if len(activeusers) == 0 && len(users) > 0 { log.Printf("No active users found - setting ALL to active") @@ -5063,7 +4373,7 @@ func runInit(ctx context.Context) { for _, user := range users { user.Active = true if len(user.Username) == 0 { - DeleteKey(ctx, "Users", strings.ToLower(user.Username)) + shuffle.DeleteKey(ctx, "Users", strings.ToLower(user.Username)) continue } @@ -5074,18 +4384,18 @@ func runInit(ctx context.Context) { if len(user.Orgs) == 0 { defaultName := "default" user.Orgs = []string{defaultName} - user.ActiveOrg = shuffle.Org{ + user.ActiveOrg = shuffle.OrgMini{ Name: defaultName, - Role: "user", + Role: "admin", } } - err = shuffle.SetUser(ctx, &user) + err = shuffle.SetUser(ctx, &user, true) if err != nil { log.Printf("Failed to reset user") } else { log.Printf("Remade user %s with ID", user.Id) - err = DeleteKey(ctx, "Users", strings.ToLower(user.Username)) + err = shuffle.DeleteKey(ctx, "Users", strings.ToLower(user.Username)) if err != nil { log.Printf("Failed to delete old user by username") } @@ -5101,9 +4411,10 @@ func runInit(ctx context.Context) { } else { apikey := os.Getenv("SHUFFLE_DEFAULT_APIKEY") - tmpOrg := shuffle.Org{ + tmpOrg := shuffle.OrgMini{ Name: "default", } + err = createNewUser(username, password, "admin", apikey, tmpOrg) if err != nil { log.Printf("Failed to create default user %s: %s", username, err) @@ -5112,19 +4423,23 @@ func runInit(ctx context.Context) { } } } else { - if len(users) < 5 && len(users) > 0 { + if len(users) < 10 && len(users) > 0 { for _, user := range users { log.Printf("[INFO] Username: %s, role: %s", user.Username, user.Role) } } else { - log.Printf("Found %d users.", len(users)) + log.Printf("[INIT] Found %d users.", len(users)) } if len(activeOrgs) == 1 && len(users) > 0 { for _, user := range users { if user.ActiveOrg.Id == "" && len(user.Username) > 0 { - user.ActiveOrg = activeOrgs[0] - err = shuffle.SetUser(ctx, &user) + user.ActiveOrg = shuffle.OrgMini{ + Id: activeOrgs[0].Id, + Name: activeOrgs[0].Name, + } + + err = shuffle.SetUser(ctx, &user, true) if err != nil { log.Printf("Failed updating user %s with org", user.Username) } else { @@ -5138,46 +4453,77 @@ func runInit(ctx context.Context) { } // Gets environments and inits if it doesn't exist - count, err := getEnvironmentCount() + count, err := shuffle.GetEnvironmentCount() if count == 0 && err == nil && len(activeOrgs) == 1 { - log.Printf("Setting up environment with org %s", activeOrgs[0].Id) + log.Printf("[INFO] Setting up environment with org %s", activeOrgs[0].Id) + + defaultEnv := os.Getenv("ORG_ID") + if len(defaultEnv) == 0 { + defaultEnv = "Shuffle" + log.Printf("[DEBUG] Setting default environment for org to %s", defaultEnv) + } + item := shuffle.Environment{ - Name: "Shuffle", + Name: defaultEnv, Type: "onprem", OrgId: activeOrgs[0].Id, Default: true, + Id: uuid.NewV4().String(), } - err = setEnvironment(ctx, &item) + err = shuffle.SetEnvironment(ctx, &item) if err != nil { - log.Printf("Failed setting up new environment") + log.Printf("[WARNING] Failed setting up new environment") } } else if len(activeOrgs) == 1 { - log.Printf("Setting up all environments with org %s", activeOrgs[0].Id) + log.Printf("[INFO] Setting up all environments with org %s", activeOrgs[0].Id) var environments []shuffle.Environment q := datastore.NewQuery("Environments") _, err = dbclient.GetAll(ctx, q, &environments) if err == nil { + existingEnv := []string{} + _ = existingEnv for _, item := range environments { - if item.OrgId == activeOrgs[0].Id { + //if shuffle.ArrayContains(existingEnv, item.Name) { + // log.Printf("[WARNING] Env %s already exists - deleting it. %#v", item.Name, item) + // err = DeleteKey(ctx, "Environments", item.Name) + // if err != nil { + // log.Printf("[WARNING] Env deletion error: %s", err) + // } + + // continue + //} + + //existingEnv = append(existingEnv, item.Name) + + if item.OrgId == activeOrgs[0].Id && len(item.Id) > 0 { continue } + if len(item.Id) == 0 { + item.Id = uuid.NewV4().String() + } + item.OrgId = activeOrgs[0].Id - err = setEnvironment(ctx, &item) + err = shuffle.SetEnvironment(ctx, &item) if err != nil { - log.Printf("Failed adding environment to org %s", activeOrgs[0].Id) + log.Printf("[WARNING] Failed adding environment to org %s", activeOrgs[0].Id) } } } } // Fixing workflows to have real activeorg IDs + //workflowQ := datastore.NewQuery("workflow") + //ret, err := dbclient.GetAll(ctx, workflowQ, &workflows) + //log.Printf("[INFO] Found %d workflows during startup", workflowCount) + //log.Printf("%#v, %s", ret, err) + + var workflows []shuffle.Workflow if len(activeOrgs) == 1 { q := datastore.NewQuery("workflow").Limit(35) - var workflows []shuffle.Workflow _, err = dbclient.GetAll(ctx, q, &workflows) - if err != nil { + if err != nil && len(workflows) == 0 { log.Printf("Error getting workflows in runinit: %s", err) } else { updated := 0 @@ -5186,7 +4532,11 @@ func runInit(ctx context.Context) { setLocal := false if workflow.ExecutingOrg.Id == "" || len(workflow.OrgId) == 0 { workflow.OrgId = activeOrgs[0].Id - workflow.ExecutingOrg = activeOrgs[0] + workflow.ExecutingOrg = shuffle.OrgMini{ + Id: activeOrgs[0].Id, + Name: activeOrgs[0].Name, + } + setLocal = true } else if workflow.Edited == 0 { workflow.Edited = timeNow @@ -5262,7 +4612,7 @@ func runInit(ctx context.Context) { } } - var schedules []ScheduleOld + var schedules []shuffle.ScheduleOld q = datastore.NewQuery("schedules") _, err = dbclient.GetAll(ctx, q, &schedules) if err == nil { @@ -5279,7 +4629,7 @@ func runInit(ctx context.Context) { } item.Org = activeOrgs[0].Id - err = setSchedule(ctx, item) + err = shuffle.SetSchedule(ctx, item) if err != nil { log.Printf("Failed adding schedule to org %s", activeOrgs[0].Id) } @@ -5304,7 +4654,7 @@ func runInit(ctx context.Context) { continue } - log.Printf("Should start schedule for org %s", org.Name) + log.Printf("[DEBUG] Should start schedule for org %s", org.Name) job := func() { err := remoteOrgJobHandler(org, interval) if err != nil { @@ -5323,7 +4673,7 @@ func runInit(ctx context.Context) { // Gets schedules and starts them log.Printf("Relaunching schedules") - schedules, err := getAllSchedules(ctx, "ALL") + schedules, err := shuffle.GetAllSchedules(ctx, "ALL") if err != nil { log.Printf("Failed getting schedules during service init: %s", err) } else { @@ -5337,6 +4687,9 @@ func runInit(ctx context.Context) { //log.Printf("Schedule: %#v", schedule) job := func() { + //log.Printf("[INFO] Running schedule %s with interval %d.", schedule.Id, schedule.Seconds) + //log.Printf("ARG: %s", schedule.WrappedArgument) + request := &http.Request{ URL: url, Method: "POST", @@ -5345,7 +4698,7 @@ func runInit(ctx context.Context) { _, _, err := handleExecution(schedule.WorkflowId, shuffle.Workflow{}, request) if err != nil { - log.Printf("Failed to execute %s: %s", schedule.WorkflowId, err) + log.Printf("[WARNING] Failed to execute %s: %s", schedule.WorkflowId, err) } } @@ -5368,10 +4721,10 @@ func runInit(ctx context.Context) { } // Getting apps to see if we should initialize a test - log.Printf("Getting remote workflow apps") - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 500) - if err != nil { - log.Printf("Failed getting apps (runInit): %s", err) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) + log.Printf("[INFO] Getting and validating workflowapps. Got %d with err %s", len(workflowapps), err) + if err != nil && len(workflowapps) == 0 { + log.Printf("[WARNING] Failed getting apps (runInit): %s", err) } else if err == nil && len(workflowapps) > 0 { var allworkflowapps []shuffle.WorkflowApp q := datastore.NewQuery("workflowapp") @@ -5381,7 +4734,7 @@ func runInit(ctx context.Context) { if workflowapp.Edited == 0 { err = shuffle.SetWorkflowAppDatastore(ctx, workflowapp, workflowapp.ID) if err == nil { - log.Printf("Updating time for workflowapp %s:%s", workflowapp.Name, workflowapp.AppVersion) + log.Printf("[INFO] Updating time for workflowapp %s:%s", workflowapp.Name, workflowapp.AppVersion) } } } @@ -5415,7 +4768,7 @@ func runInit(ctx context.Context) { cloneOptions.ReferenceName = plumbing.ReferenceName(branch) } - log.Printf("Getting apps from %s", url) + log.Printf("[DEBUG] Getting apps from %s", url) r, err := git.Clone(storer, fs, cloneOptions) @@ -5447,7 +4800,7 @@ func runInit(ctx context.Context) { log.Printf("[INFO] Downloading OpenAPI data for search - EXTRA APPS") apis := "https://github.com/frikky/security-openapis" - // THis gets memory problems hahah + // FIXME: This part gets memory problems. Fix in the future to load these apps too. //apis := "https://github.com/APIs-guru/openapi-directory" fs := memfs.New() storer := memory.NewStorage() @@ -5474,7 +4827,7 @@ func runInit(ctx context.Context) { q := datastore.NewQuery("workflow").Limit(35) var workflows []shuffle.Workflow _, err = dbclient.GetAll(ctx, q, &workflows) - if err != nil { + if err != nil && len(workflows) == 0 { log.Printf("Error getting workflows: %s", err) } else { if len(workflows) == 0 { @@ -5553,7 +4906,7 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) (*shuffle.Org, error) return &org, errors.New(fmt.Sprintf("Couldn't find any sync key to disable org %s", org.Id)) } - log.Printf("Should run cloud sync disable for org %s with URL %s and sync key %s", org.Id, syncUrl, org.SyncConfig.Apikey) + log.Printf("[INFO] Should run cloud sync disable for org %s with URL %s and sync key %s", org.Id, syncUrl, org.SyncConfig.Apikey) client := &http.Client{} req, err := http.NewRequest( @@ -5589,7 +4942,7 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) (*shuffle.Org, error) return &org, errors.New(responseData.Reason) } - log.Printf("Everything is success. Should disable org sync for %s", org.Id) + log.Printf("[INFO] Everything is success. Should disable org sync for %s", org.Id) ctx := context.Background() org.CloudSync = false @@ -5598,15 +4951,14 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) (*shuffle.Org, error) err = shuffle.SetOrg(ctx, org, org.Id) if err != nil { - newerror := fmt.Sprintf("ERROR: Failed updating even though there was success: %s", err) + newerror := fmt.Sprintf("[WARNING] ERROR: Failed updating even though there was success: %s", err) log.Printf(newerror) return &org, errors.New(newerror) } - var environments []shuffle.Environment - q := datastore.NewQuery("Environments").Filter("org_id =", org.Id) - _, err = dbclient.GetAll(ctx, q, &environments) + environments, err := shuffle.GetEnvironments(ctx, org.Id) if err != nil { + log.Printf("[WARNING] Failed getting envs in stop sync: %s", err) return &org, err } @@ -5615,7 +4967,7 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) (*shuffle.Org, error) if environment.Type == "cloud" { environment.Name = "Cloud" environment.Archived = true - err = setEnvironment(ctx, &environment) + err = shuffle.SetEnvironment(ctx, &environment) if err == nil { log.Printf("[INFO] Updated cloud environment %s", environment.Name) } else { @@ -5755,9 +5107,9 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) { // Everything below here is to SET UP CLOUD SYNC. // If you want to disable cloud sync, see previous section. if org.CloudSync { - log.Printf("Org %s is already syncing. Skip", org.Id) + log.Printf("[WARNING] Org %s is already syncing. Skip", org.Id) resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Org is already syncing. Nothing to set up."}`))) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Your org is already syncing. Nothing to set up."}`))) return } @@ -5850,16 +5202,15 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) { scheduledOrgs[org.Id] = jobret } - // FIXME: Add this for every feature + // ONLY checked added if workflows are allow huh if org.SyncFeatures.Workflows.Active { log.Printf("[INFO] Should activate cloud workflows for org %s!", org.Id) // 1. Find environment // 2. If cloud env found, enable it (un-archive) // 3. If it doesn't create it - var environments []shuffle.Environment - q := datastore.NewQuery("Environments").Filter("org_id =", org.Id) - _, err = dbclient.GetAll(ctx, q, &environments) + environments, err := shuffle.GetEnvironments(ctx, org.Id) + log.Printf("GETTING ENVS: %#s", environments) if err == nil { // Don't disable, this will be deleted entirely @@ -5868,7 +5219,7 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) { if environment.Type == "cloud" { environment.Name = "Cloud" environment.Archived = false - err = setEnvironment(ctx, &environment) + err = shuffle.SetEnvironment(ctx, &environment) if err == nil { log.Printf("[INFO] Re-added cloud environment %s", environment.Name) } else { @@ -5889,9 +5240,10 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) { Registered: true, Default: false, OrgId: org.Id, + Id: uuid.NewV4().String(), } - err = setEnvironment(ctx, &newEnv) + err = shuffle.SetEnvironment(ctx, &newEnv) if err != nil { log.Printf("Failed setting up NEW org environment for org %s: %s", org.Id, err) } else { @@ -5920,6 +5272,251 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) { resp.Write(respBody) } +// Runs DB migration from Datastore to Opensearch +// If the function has "ALL" in it, that means it's intended to be used for Orgs +// but that we've added a function to grab everything +func migrateDatabase(resp http.ResponseWriter, request *http.Request) { + cors := shuffle.HandleCors(resp, request) + if cors { + return + } + + user, userErr := shuffle.HandleApiAuthentication(resp, request) + if userErr != nil { + log.Printf("[WARNING] Api authentication failed in make workflow public: %s", userErr) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + if user.Role != "admin" { + log.Printf("[WARNING] Failed to migrate because you're not admin") + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + if strings.ToLower(os.Getenv("SHUFFLE_ELASTIC")) != "false" { + log.Printf("[WARNING] Failed to migrate because main DB is Elastic. Set SHUFFLE_ELASTIC=false in .env") + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + ctx := context.Background() + es := shuffle.GetEsConfig() + _, err := shuffle.RunInit(*dbclient, *es, storage.Client{}, gceProject, "onprem", false, "") + if err != nil { + log.Printf("[WARNING] Failed to start migration because of init issues: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + log.Printf("\n\n------- STARTING MIGRATION TO OPENSEARCH --------") + users, err := shuffle.GetAllUsers(ctx) + if err != nil { + log.Printf("[ERROR] Failed getting users: %#v", err) + } else { + log.Printf("[DEBUG] Found %d user(s) to be migrated", len(users)) + } + + orgs, err := shuffle.GetAllOrgs(ctx) + if err != nil { + log.Printf("[ERROR] Failed getting orgs: %#v", err) + } else { + log.Printf("[DEBUG] Found %d org(s) to be migrated", len(orgs)) + } + + workflows, err := shuffle.GetAllWorkflows(ctx, "ALL") + if err != nil { + log.Printf("[ERROR] Failed getting workflows: %#v", err) + } else { + log.Printf("[DEBUG] Found %d workflows(s) to be migrated", len(workflows)) + } + + apps, err := shuffle.GetAllWorkflowApps(ctx, 0) + if err != nil { + log.Printf("[ERROR] Failed getting apps: %#v", err) + } else { + log.Printf("[DEBUG] Found %d app(s) to be migrated", len(apps)) + } + + openapiApps, err := shuffle.GetAllOpenApi(ctx) + if err != nil { + log.Printf("[ERROR] Failed getting openapi apps: %#v", err) + } else { + log.Printf("[DEBUG] Found %d openapi(s) to be migrated", len(openapiApps)) + } + + workflowappauth, err := shuffle.GetAllWorkflowAppAuth(ctx, "ALL") + if err != nil { + log.Printf("[ERROR] Failed getting app auth: %#v", err) + } else { + log.Printf("[DEBUG] Found %d appauth(s) to be migrated", len(workflowappauth)) + } + + environments, err := shuffle.GetEnvironments(ctx, "ALL") + if err != nil { + log.Printf("[ERROR] Failed getting environments: %#v", err) + } else { + log.Printf("[DEBUG] Found %d environment(s) to be migrated", len(environments)) + } + + hooks, err := shuffle.GetAllHooks(ctx) + if err != nil { + log.Printf("[ERROR] Failed getting hooks: %#v", err) + } else { + log.Printf("[DEBUG] Found %d hook(s) to be migrated", len(hooks)) + } + + schedules, err := shuffle.GetAllSchedules(ctx, "ALL") + if err != nil { + log.Printf("[ERROR] Failed getting schedules: %#v", err) + } else { + log.Printf("[DEBUG] Found %d schedule(s) to be migrated", len(schedules)) + } + + log.Printf("\n\n------- SWAPPING TO OPENSEARCH DB WITH ACQUIRED INFO ---------") + userSuccess := 0 + orgSuccess := 0 + workflowSuccess := 0 + appSuccess := 0 + openapiSuccess := 0 + authSuccess := 0 + envSuccess := 0 + hookSuccess := 0 + scheduleSuccess := 0 + _, err = shuffle.RunInit(*dbclient, *es, storage.Client{}, gceProject, "onprem", false, "elasticsearch") + + for _, item := range orgs { + err = shuffle.SetOrg(ctx, item, item.Id) + if err != nil { + //log.Printf("[WARNING] Failed to update org in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set org %s (%s) in opensearch", item.Name, item.Id) + orgSuccess += 1 + } + } + + log.Printf("----- ORGS FOUND: %d - success: %d - failed: %d", len(orgs), orgSuccess, len(orgs)-orgSuccess) + + for _, item := range workflowappauth { + err = shuffle.SetWorkflowAppAuthDatastore(ctx, item, item.Id) + if err != nil { + //log.Printf("[WARNING] Failed to update app auth in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set app auth %s in opensearch", item.Id) + authSuccess += 1 + } + } + + log.Printf("----- AUTH FOUND: %d - success: %d - failed: %d", len(workflowappauth), authSuccess, len(workflowappauth)-authSuccess) + + for _, item := range environments { + err = shuffle.SetEnvironment(ctx, &item) + if err != nil { + //log.Printf("[WARNING] Failed to update env in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set env %s in opensearch", item.Id) + envSuccess += 1 + } + } + + log.Printf("----- ENVS FOUND: %d - success: %d - failed: %d", len(environments), envSuccess, len(environments)-envSuccess) + + for _, item := range hooks { + err = shuffle.SetHook(ctx, item) + if err != nil { + //log.Printf("[WARNING] Failed to update hooks in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set hook %s in opensearch", item.Id) + hookSuccess += 1 + } + } + + log.Printf("---- HOOKS FOUND: %d - success: %d - failed: %d", len(hooks), hookSuccess, len(hooks)-hookSuccess) + + for _, item := range schedules { + err = shuffle.SetSchedule(ctx, item) + if err != nil { + //log.Printf("[WARNING] Failed to update schedule in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set schedule %s in opensearch", item.Id) + scheduleSuccess += 1 + } + } + + log.Printf(" SCHEDULES FOUND: %d - success: %d - failed: %d", len(schedules), scheduleSuccess, len(schedules)-scheduleSuccess) + + for _, item := range users { + err = shuffle.SetUser(ctx, &item, false) + if err != nil { + //log.Printf("[WARNING] Failed to update user in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set user %s (%s) in opensearch", item.Username, item.Id) + userSuccess += 1 + } + } + + log.Printf("---- USERS FOUND: %d - success: %d - failed: %d", len(users), userSuccess, len(users)-userSuccess) + + for _, item := range workflows { + err = shuffle.SetWorkflow(ctx, item, item.ID) + if err != nil { + //log.Printf("[WARNING] Failed to update workflow in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set workflow %s (%s) in opensearch", item.Name, item.ID) + workflowSuccess += 1 + } + } + + log.Printf(" WORKFLOWS FOUND: %d - success: %d - failed: %d", len(workflows), workflowSuccess, len(workflows)-workflowSuccess) + + for _, item := range openapiApps { + err = shuffle.SetOpenApiDatastore(ctx, item.ID, item) + if err != nil { + //log.Printf("[WARNING] Failed to update openapi app in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set openapi %s in opensearch", item.ID) + openapiSuccess += 1 + } + } + + log.Printf("-- OpenAPI FOUND: %d - success: %d - failed: %d", len(openapiApps), openapiSuccess, len(openapiApps)-openapiSuccess) + + for _, item := range apps { + err = shuffle.SetWorkflowAppDatastore(ctx, item, item.ID) + if err != nil { + //log.Printf("[WARNING] Failed to update app in opensearch: %s", err) + } else { + //log.Printf("[DEBUG] Set app %s (%s) in opensearch", item.Name, item.ID) + appSuccess += 1 + } + } + + log.Printf("----- APPS FOUND: %d - success: %d - failed: %d", len(apps), appSuccess, len(apps)-appSuccess) + + // Handle users + // 1. Get users + // 2. Get organizations + // 4. Get workflows + // 5. Get apps + // 6. Get workflowappauth + // 7. Get workflowexecution + // 9. Get Environments + // 10. Get hooks + // 11. Get openapi3 + // 12. Get schedules + + //log.Printf("[INFO] Successfully published workflow %s (%s) TO CLOUD", workflow.Name, workflow.ID) + log.Printf("\n\n[DEBUG] Successfully updated ran migration from Datastore to Opensearch!") + resp.WriteHeader(200) + resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) + log.Printf("[DEBUG] Panicing to force-restart Shuffle post-migration. Stop Shuffle and change database. Docs: https://shuffler.io/docs/configuration#database_migration") + os.Exit(0) +} + func makeWorkflowPublic(resp http.ResponseWriter, request *http.Request) { cors := shuffle.HandleCors(resp, request) if cors { @@ -5970,9 +5567,9 @@ func makeWorkflowPublic(resp http.ResponseWriter, request *http.Request) { // Check workflow.Sharing == private / public / org too if user.Id != workflow.Owner || len(user.Id) == 0 { if workflow.OrgId == user.ActiveOrg.Id && user.Role == "admin" { - log.Printf("[INFO] User %s is accessing workflow %s as admin", user.Username, workflow.ID) + log.Printf("[AUDIT] User %s is accessing workflow %s as admin (public)", user.Username, workflow.ID) } else { - log.Printf("[WARNING] Wrong user (%s) for workflow %s (get workflow)", user.Username, workflow.ID) + log.Printf("[WARNING] Wrong user (%s) for workflow %s (public)", user.Username, workflow.ID) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -6039,7 +5636,15 @@ func makeWorkflowPublic(resp http.ResponseWriter, request *http.Request) { FifthItem: user.Id, } - err = executeCloudAction(action, user.ActiveOrg.SyncConfig.Apikey) + org, err := shuffle.GetOrg(ctx, user.ActiveOrg.Id) + if err != nil { + log.Printf("[WARNING] Failed setting getting org during cloud job setting: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) + return + } + + err = executeCloudAction(action, org.SyncConfig.Apikey) if err != nil { log.Printf("[WARNING] Failed cloud PUBLISH: %s", err) resp.WriteHeader(401) @@ -6056,29 +5661,44 @@ func initHandlers() { var err error ctx := context.Background() - log.Printf("Starting Shuffle backend - initializing database connection") + log.Printf("[DEBUG] Starting Shuffle backend - initializing database connection") //requestCache = cache.New(5*time.Minute, 10*time.Minute) dbclient, err = datastore.NewClient(ctx, gceProject, option.WithGRPCDialOption(grpc.WithNoProxy())) if err != nil { - panic(fmt.Sprintf("DBclient error during init: %s", err)) + log.Fatalf("[DEBUG] Database client error during init: %s", err) } - //dbclient, err := shuffle.GetDatastoreClient(ctx, gceProject) - //if err != nil { - // panic(fmt.Sprintf("Error setting datastore connector: %s", err)) - //} + es := shuffle.GetEsConfig() + elasticConfig := "elasticsearch" + if strings.ToLower(os.Getenv("SHUFFLE_ELASTIC")) == "false" { + elasticConfig = "" + } - _ = shuffle.RunInit(*dbclient, storage.Client{}, gceProject, "onprem", true) - log.Printf("Finished Shuffle database init") + for { + _, err = shuffle.RunInit(*dbclient, *es, storage.Client{}, gceProject, "onprem", true, elasticConfig) + if err != nil { + log.Printf("[ERROR] Error in initial database connection. Retrying in 5 seconds. %s", err) + time.Sleep(5 * time.Second) + continue + } - go runInit(ctx) + break + } + + log.Printf("[DEBUG] Initialized Shuffle database connection. Setting up environment.") + + if elasticConfig == "elasticsearch" { + go runInitEs(ctx) + } else { + go runInit(ctx) + } r := mux.NewRouter() r.HandleFunc("/api/v1/_ah/health", healthCheckHandler) // Make user related locations // Fix user changes with org - r.HandleFunc("/api/v1/users/login", handleLogin).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/users/login", shuffle.HandleLogin).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/users/register", handleRegister).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/users/checkusers", checkAdminLogin).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/users/getinfo", handleInfo).Methods("GET", "OPTIONS") @@ -6087,7 +5707,7 @@ func initHandlers() { r.HandleFunc("/api/v1/users/logout", shuffle.HandleLogout).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/users/getsettings", shuffle.HandleSettings).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/users/getusers", shuffle.HandleGetUsers).Methods("GET", "OPTIONS") - r.HandleFunc("/api/v1/users/updateuser", handleUpdateUser).Methods("PUT", "OPTIONS") + r.HandleFunc("/api/v1/users/updateuser", shuffle.HandleUpdateUser).Methods("PUT", "OPTIONS") r.HandleFunc("/api/v1/users/{user}", shuffle.DeleteUser).Methods("DELETE", "OPTIONS") r.HandleFunc("/api/v1/users/passwordchange", shuffle.HandlePasswordChange).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/users", shuffle.HandleGetUsers).Methods("GET", "OPTIONS") @@ -6106,8 +5726,8 @@ func initHandlers() { r.HandleFunc("/api/v1/getenvironments", shuffle.HandleGetEnvironments).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/setenvironments", shuffle.HandleSetEnvironments).Methods("PUT", "OPTIONS") - r.HandleFunc("/api/v1/docs", getDocList).Methods("GET", "OPTIONS") - r.HandleFunc("/api/v1/docs/{key}", getDocs).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/docs", shuffle.GetDocList).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/docs/{key}", shuffle.GetDocs).Methods("GET", "OPTIONS") // Queuebuilder and Workflow streams. First is to update a stream, second to get a stream // Changed from workflows/streams to streams, as appengine was messing up @@ -6124,11 +5744,11 @@ func initHandlers() { // From here down isnt checked for org specific r.HandleFunc("/api/v1/apps/{appId}", shuffle.UpdateWorkflowAppConfig).Methods("PATCH", "OPTIONS") r.HandleFunc("/api/v1/apps/{appId}", shuffle.DeleteWorkflowApp).Methods("DELETE", "OPTIONS") + r.HandleFunc("/api/v1/apps/{appId}/config", shuffle.GetWorkflowAppConfig).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/apps/run_hotload", handleAppHotloadRequest).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/apps/get_existing", loadSpecificApps).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/apps/download_remote", loadSpecificApps).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/apps/validate", validateAppInput).Methods("POST", "OPTIONS") - r.HandleFunc("/api/v1/apps/{appId}/config", getWorkflowAppConfig).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/apps", getWorkflowApps).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/apps", setNewWorkflowApp).Methods("PUT", "OPTIONS") r.HandleFunc("/api/v1/apps/search", getSpecificApps).Methods("POST", "OPTIONS") @@ -6136,7 +5756,6 @@ func initHandlers() { r.HandleFunc("/api/v1/apps/authentication", shuffle.GetAppAuthentication).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/apps/authentication", shuffle.AddAppAuthentication).Methods("PUT", "OPTIONS") r.HandleFunc("/api/v1/apps/authentication/{appauthId}/config", shuffle.SetAuthenticationConfig).Methods("POST", "OPTIONS") - r.HandleFunc("/api/v1/apps/authentication/{appauthId}", shuffle.DeleteAppAuthentication).Methods("DELETE", "OPTIONS") // Legacy app things @@ -6149,18 +5768,18 @@ func initHandlers() { /* Everything below here increases the counters*/ r.HandleFunc("/api/v1/workflows", shuffle.GetWorkflows).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/workflows", shuffle.SetNewWorkflow).Methods("POST", "OPTIONS") - r.HandleFunc("/api/v1/workflows/{key}", shuffle.GetSpecificWorkflow).Methods("GET", "OPTIONS") - r.HandleFunc("/api/v1/workflows/{key}", shuffle.SaveWorkflow).Methods("PUT", "OPTIONS") - r.HandleFunc("/api/v1/workflows/schedules", handleGetSchedules).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/workflows/schedules", shuffle.HandleGetSchedules).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/workflows/{key}/executions", shuffle.GetWorkflowExecutions).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/workflows/{key}/executions/{key}/abort", shuffle.AbortExecution).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/workflows/{key}/schedule", scheduleWorkflow).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/workflows/download_remote", loadSpecificWorkflows).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/workflows/{key}/execute", executeWorkflow).Methods("GET", "POST", "OPTIONS") r.HandleFunc("/api/v1/workflows/{key}/schedule/{schedule}", stopSchedule).Methods("DELETE", "OPTIONS") r.HandleFunc("/api/v1/workflows/{key}/outlook", createOutlookSub).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/workflows/{key}/outlook/{triggerId}", handleDeleteOutlookSub).Methods("DELETE", "OPTIONS") - r.HandleFunc("/api/v1/workflows/{key}/executions", getWorkflowExecutions).Methods("GET", "OPTIONS") - r.HandleFunc("/api/v1/workflows/{key}/executions/{key}/abort", shuffle.AbortExecution).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/workflows/{key}", deleteWorkflow).Methods("DELETE", "OPTIONS") + r.HandleFunc("/api/v1/workflows/{key}", shuffle.SaveWorkflow).Methods("PUT", "OPTIONS") + r.HandleFunc("/api/v1/workflows/{key}", shuffle.GetSpecificWorkflow).Methods("GET", "OPTIONS") // Triggers r.HandleFunc("/api/v1/hooks/new", shuffle.HandleNewHook).Methods("POST", "OPTIONS") @@ -6171,24 +5790,35 @@ func initHandlers() { r.HandleFunc("/api/v1/verify_swagger", verifySwagger).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/verify_openapi", verifySwagger).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/get_openapi_uri", echoOpenapiData).Methods("POST", "OPTIONS") - r.HandleFunc("/api/v1/validate_openapi", validateSwagger).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/validate_openapi", shuffle.ValidateSwagger).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/get_openapi/{key}", getOpenapi).Methods("GET", "OPTIONS") - // NEW for 0.8.0 + // Specific triggers + r.HandleFunc("/api/v1/triggers/outlook/register", handleNewOutlookRegister).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/triggers/outlook/getFolders", shuffle.HandleGetOutlookFolders).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/triggers/outlook/{key}", handleGetSpecificTrigger).Methods("GET", "OPTIONS") + //r.HandleFunc("/api/v1/triggers/outlook/{key}/callback", handleOutlookCallback).Methods("POST", "OPTIONS") + //r.HandleFunc("/api/v1/stats/{key}", handleGetSpecificStats).Methods("GET", "OPTIONS") + + // EVERYTHING below here is NEW for 0.8.0 (written 25.05.2021) r.HandleFunc("/api/v1/workflows/{key}/publish", makeWorkflowPublic).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/orgs", shuffle.HandleGetOrgs).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/orgs/", shuffle.HandleGetOrgs).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/orgs/{orgId}", shuffle.HandleGetOrg).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/orgs/{orgId}", shuffle.HandleEditOrg).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/orgs/{orgId}/create_sub_org", shuffle.HandleCreateSubOrg).Methods("POST", "OPTIONS") + // This is a new API that validates if a key has been seen before. // Not sure what the best course of action is for it. r.HandleFunc("/api/v1/orgs/{orgId}/validate_app_values", shuffle.HandleKeyValueCheck).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/orgs/{orgId}/get_cache", shuffle.HandleGetCacheKey).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/orgs/{orgId}/set_cache", shuffle.HandleSetCacheKey).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/apps/{key}/execute", executeSingleAction).Methods("POST", "OPTIONS") - //r.HandleFunc("/api/v1/orgs/{orgId}", handleEditOrg).Methods("POST", "OPTIONS") - - // Docker orborus specific - //r.HandleFunc("/api/v1/get_docker_image", getDockerImage).Methods("POST", "OPTIONS") + // Docker orborus specific - downloads an image + r.HandleFunc("/api/v1/get_docker_image", getDockerImage).Methods("POST", "OPTIONS") + r.HandleFunc("/api/v1/migrate_database", migrateDatabase).Methods("POST", "OPTIONS") // Important for email, IDS etc. Create this by: // PS: For cloud, this has to use cloud storage. @@ -6201,13 +5831,6 @@ func initHandlers() { r.HandleFunc("/api/v1/files/{fileId}", shuffle.HandleDeleteFile).Methods("DELETE", "OPTIONS") r.HandleFunc("/api/v1/files", shuffle.HandleGetFiles).Methods("GET", "OPTIONS") - // Trigger hmm - r.HandleFunc("/api/v1/triggers/outlook/register", handleNewOutlookRegister).Methods("GET", "OPTIONS") - r.HandleFunc("/api/v1/triggers/outlook/getFolders", handleGetOutlookFolders).Methods("GET", "OPTIONS") - r.HandleFunc("/api/v1/triggers/outlook/{key}", handleGetSpecificTrigger).Methods("GET", "OPTIONS") - //r.HandleFunc("/api/v1/triggers/outlook/{key}/callback", handleOutlookCallback).Methods("POST", "OPTIONS") - //r.HandleFunc("/api/v1/stats/{key}", handleGetSpecificStats).Methods("GET", "OPTIONS") - http.Handle("/", r) } @@ -6221,10 +5844,10 @@ func main() { innerPort := os.Getenv("BACKEND_PORT") if innerPort == "" { - log.Printf("Running on %s:5001", hostname) + log.Printf("[DEBUG] Running on %s:5001", hostname) log.Fatal(http.ListenAndServe(":5001", nil)) } else { - log.Printf("Running on %s:%s", hostname, innerPort) + log.Printf("[DEBUG] Running on %s:%s", hostname, innerPort) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", innerPort), nil)) } } diff --git a/backend/go-app/oauth2.go b/backend/go-app/oauth2.go index 164c803d..773661f3 100644 --- a/backend/go-app/oauth2.go +++ b/backend/go-app/oauth2.go @@ -15,160 +15,10 @@ import ( "strings" "time" - "cloud.google.com/go/datastore" "golang.org/x/oauth2" ) -// This is what the structure should be when it's sent into a workflow -type ParsedShuffleMail struct { - Body struct { - URI []string `json:"uri"` - Email []string `json:"email"` - Domain []string `json:"domain"` - ContentHeader struct { - } `json:"content_header"` - Content string `json:"content"` - ContentType string `json:"content_type"` - Hash string `json:"hash"` - RawBody string `json:"raw_body"` - } `json:"body"` - Header struct { - Subject string `json:"subject"` - From string `json:"from"` - To []string `json:"to"` - Date string `json:"date"` - Received []struct { - Src string `json:"src"` - From []string `json:"from"` - By []string `json:"by"` - With string `json:"with"` - Date string `json:"date"` - } `json:"received"` - ReceivedDomain []string `json:"received_domain"` - ReceivedIP []string `json:"received_ip"` - Header struct { - } `json:"header"` - } `json:"header"` - MessageID string `json:"message_id"` - EmailFileid string `json:"email_fileid"` - AttachmentUids []string `json:"attachment_uids"` -} - -type FullEmail struct { - OdataContext string `json:"@odata.context"` - OdataEtag string `json:"@odata.etag"` - ID string `json:"id"` - Createddatetime time.Time `json:"createdDateTime"` - Lastmodifieddatetime time.Time `json:"lastModifiedDateTime"` - Changekey string `json:"changeKey"` - Categories []interface{} `json:"categories"` - Receiveddatetime time.Time `json:"receivedDateTime"` - Sentdatetime time.Time `json:"sentDateTime"` - Hasattachments bool `json:"hasAttachments"` - Internetmessageid string `json:"internetMessageId"` - Subject string `json:"subject"` - Bodypreview string `json:"bodyPreview"` - Importance string `json:"importance"` - Parentfolderid string `json:"parentFolderId"` - Conversationid string `json:"conversationId"` - Conversationindex string `json:"conversationIndex"` - Isdeliveryreceiptrequested interface{} `json:"isDeliveryReceiptRequested"` - Isreadreceiptrequested bool `json:"isReadReceiptRequested"` - Isread bool `json:"isRead"` - Isdraft bool `json:"isDraft"` - Weblink string `json:"webLink"` - Inferenceclassification string `json:"inferenceClassification"` - Body struct { - Contenttype string `json:"contentType"` - Content string `json:"content"` - } `json:"body"` - Sender struct { - Emailaddress struct { - Name string `json:"name"` - Address string `json:"address"` - } `json:"emailAddress"` - } `json:"sender"` - From struct { - Emailaddress struct { - Name string `json:"name"` - Address string `json:"address"` - } `json:"emailAddress"` - } `json:"from"` - Torecipients []struct { - Emailaddress struct { - Name string `json:"name"` - Address string `json:"address"` - } `json:"emailAddress"` - } `json:"toRecipients"` - Ccrecipients []interface{} `json:"ccRecipients"` - Bccrecipients []interface{} `json:"bccRecipients"` - Replyto []interface{} `json:"replyTo"` - Flag struct { - Flagstatus string `json:"flagStatus"` - } `json:"flag"` - Attachments []struct { - OdataType string `json:"@odata.type"` - OdataMediacontenttype string `json:"@odata.mediaContentType"` - ID string `json:"id"` - Lastmodifieddatetime time.Time `json:"lastModifiedDateTime"` - Name string `json:"name"` - Contenttype string `json:"contentType"` - Size int `json:"size"` - Isinline bool `json:"isInline"` - Contentid interface{} `json:"contentId"` - Contentlocation interface{} `json:"contentLocation"` - Contentbytes string `json:"contentBytes"` - } -} - -type MailData struct { - Value []struct { - Subscriptionid string `json:"subscriptionId"` - Subscriptionexpirationdatetime string `json:"subscriptionExpirationDateTime"` - Changetype string `json:"changeType"` - Resource string `json:"resource"` - Resourcedata struct { - OdataType string `json:"@odata.type"` - OdataID string `json:"@odata.id"` - OdataEtag string `json:"@odata.etag"` - ID string `json:"id"` - } `json:"resourceData"` - Clientstate string `json:"clientState"` - Tenantid string `json:"tenantId"` - } `json:"value"` -} - -type OutlookProfile struct { - OdataContext string `json:"@odata.context"` - BusinessPhones []string `json:"businessPhones"` - DisplayName string `json:"displayName"` - GivenName string `json:"givenName"` - JobTitle interface{} `json:"jobTitle"` - Mail string `json:"mail"` - MobilePhone interface{} `json:"mobilePhone"` - OfficeLocation interface{} `json:"officeLocation"` - PreferredLanguage interface{} `json:"preferredLanguage"` - Surname string `json:"surname"` - UserPrincipalName string `json:"userPrincipalName"` - ID string `json:"id"` -} - -type OutlookFolder struct { - ID string `json:"id"` - DisplayName string `json:"displayName"` - ParentFolderID string `json:"parentFolderId"` - ChildFolderCount int `json:"childFolderCount"` - UnreadItemCount int `json:"unreadItemCount"` - TotalItemCount int `json:"totalItemCount"` -} - -type OutlookFolders struct { - OdataContext string `json:"@odata.context"` - OdataNextLink string `json:"@odata.nextLink"` - Value []OutlookFolder `json:"value"` -} - -func getOutlookAttachment(client *http.Client, emailId, attachmentId string) ([]FullEmail, error) { +func getOutlookAttachment(client *http.Client, emailId, attachmentId string) ([]shuffle.FullEmail, error) { //requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/users/ec03b4f2-fccf-4c35-b0eb-be85a0f5dd43/mailFolders") requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/%s/attachments/%s", emailId, attachmentId) @@ -177,20 +27,20 @@ func getOutlookAttachment(client *http.Client, emailId, attachmentId string) ([] ret, err := client.Get(requestUrl) if err != nil { log.Printf("[INFO] OutlookErr: %s", err) - return []FullEmail{}, err + return []shuffle.FullEmail{}, err } body, err := ioutil.ReadAll(ret.Body) if err != nil { log.Printf("[WARNING] Failed body decoding from outlook email") - return []FullEmail{}, err + return []shuffle.FullEmail{}, err } //type FullEmail struct { log.Printf("[INFO] Attachment Body: %s", string(body)) log.Printf("[INFO] Status email: %d", ret.StatusCode) if ret.StatusCode != 200 { - return []FullEmail{}, err + return []shuffle.FullEmail{}, err } //log.Printf("Body: %s", string(body)) @@ -206,13 +56,13 @@ func getOutlookAttachment(client *http.Client, emailId, attachmentId string) ([] emails = append(emails, parsedmail) */ - return []FullEmail{}, nil + return []shuffle.FullEmail{}, nil } -func getOutlookEmail(client *http.Client, maildata MailData) ([]FullEmail, error) { +func getOutlookEmail(client *http.Client, maildata shuffle.MailData) ([]shuffle.FullEmail, error) { //requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/users/ec03b4f2-fccf-4c35-b0eb-be85a0f5dd43/mailFolders") - emails := []FullEmail{} + emails := []shuffle.FullEmail{} for _, email := range maildata.Value { //messageId := email.Resourcedata.ID //requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/me/%s", messageId) @@ -222,29 +72,29 @@ func getOutlookEmail(client *http.Client, maildata MailData) ([]FullEmail, error ret, err := client.Get(requestUrl) if err != nil { log.Printf("[INFO] OutlookErr: %s", err) - return []FullEmail{}, err + return []shuffle.FullEmail{}, err } body, err := ioutil.ReadAll(ret.Body) if err != nil { log.Printf("[WARNING] Failed body decoding from outlook email") - return []FullEmail{}, err + return []shuffle.FullEmail{}, err } - //type FullEmail struct { + //type shuffle.FullEmail struct { //log.Printf("[INFO] EMAIL Body: %s", string(body)) //log.Printf("[INFO] Status email: %d", ret.StatusCode) if ret.StatusCode != 200 { - return []FullEmail{}, err + return []shuffle.FullEmail{}, err } //log.Printf("Body: %s", string(body)) - parsedmail := FullEmail{} + parsedmail := shuffle.FullEmail{} err = json.Unmarshal(body, &parsedmail) if err != nil { log.Printf("[INFO] Email unmarshal error: %s", err) - return []FullEmail{}, err + return []shuffle.FullEmail{}, err } emails = append(emails, parsedmail) @@ -253,77 +103,48 @@ func getOutlookEmail(client *http.Client, maildata MailData) ([]FullEmail, error return emails, nil } -func getOutlookFolders(client *http.Client) (OutlookFolders, error) { - //requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/users/ec03b4f2-fccf-4c35-b0eb-be85a0f5dd43/mailFolders") - requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/me/mailFolders") - - ret, err := client.Get(requestUrl) - if err != nil { - log.Printf("[INFO] FolderErr: %s", err) - return OutlookFolders{}, err - } - - body, err := ioutil.ReadAll(ret.Body) - if err != nil { - log.Printf("[WARNING] Failed body decoding from mailfolders") - return OutlookFolders{}, err - } - - //log.Printf("[INFO] Folder Body: %s", string(body)) - log.Printf("[INFO] Status folders: %d", ret.StatusCode) - if ret.StatusCode != 200 { - return OutlookFolders{}, err - } - - //log.Printf("Body: %s", string(body)) - - mailfolders := OutlookFolders{} - err = json.Unmarshal(body, &mailfolders) - if err != nil { - log.Printf("Unmarshal: %s", err) - return OutlookFolders{}, err - } - - //fmt.Printf("%#v", mailfolders) - // FIXME - recursion for subfolders - // Recursive struct - // folderEndpoint := fmt.Sprintf("%s/%s/childfolders?$top=40", requestUrl, parentId) - //for _, folder := range mailfolders.Value { - // log.Println(folder.DisplayName) - //} - - return mailfolders, nil -} - -func getOutlookProfile(client *http.Client) (OutlookProfile, error) { +func getOutlookProfile(client *http.Client) (shuffle.OutlookProfile, error) { requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/me?$select=mail") ret, err := client.Get(requestUrl) if err != nil { log.Printf("[INFO] Folder error: %s", err) - return OutlookProfile{}, err + return shuffle.OutlookProfile{}, err } log.Printf("[INFO] Status profile: %d", ret.StatusCode) body, err := ioutil.ReadAll(ret.Body) if err != nil { log.Printf("[INFO] Body: %s", err) - return OutlookProfile{}, err + return shuffle.OutlookProfile{}, err } log.Printf("[INFO] BODY: %s", string(body)) - profile := OutlookProfile{} + profile := shuffle.OutlookProfile{} err = json.Unmarshal(body, &profile) if err != nil { log.Printf("Unmarshal: %s", err) - return OutlookProfile{}, err + return shuffle.OutlookProfile{}, err } return profile, nil } func handleNewOutlookRegister(resp http.ResponseWriter, request *http.Request) { + cors := shuffle.HandleCors(resp, request) + if cors { + return + } + + user, err := shuffle.HandleApiAuthentication(resp, request) + if err != nil { + log.Printf("[INFO] Api authentication failed in getting specific trigger: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + code := request.URL.Query().Get("code") if len(code) == 0 { log.Println("No code") @@ -334,7 +155,7 @@ func handleNewOutlookRegister(resp http.ResponseWriter, request *http.Request) { url := fmt.Sprintf("http://%s%s", request.Host, request.URL.EscapedPath()) log.Println(url) ctx := context.Background() - _, accessToken, err := getOutlookClient(ctx, code, OauthToken{}, url) + _, accessToken, err := getOutlookClient(ctx, code, shuffle.OauthToken{}, url) if err != nil { log.Printf("Oauth client failure - outlook register: %s", err) resp.WriteHeader(401) @@ -367,7 +188,7 @@ func handleNewOutlookRegister(resp http.ResponseWriter, request *http.Request) { // FIXME - trigger auth senderUser := "" - trigger := TriggerAuth{} + trigger := shuffle.TriggerAuth{} for _, item := range stateitems { itemsplit := strings.Split(item, "%3D") if len(itemsplit) == 1 { @@ -404,7 +225,7 @@ func handleNewOutlookRegister(resp http.ResponseWriter, request *http.Request) { */ trigger.Code = code - trigger.OauthToken = OauthToken{ + trigger.OauthToken = shuffle.OauthToken{ AccessToken: accessToken.AccessToken, TokenType: accessToken.TokenType, RefreshToken: accessToken.RefreshToken, @@ -425,7 +246,7 @@ func handleNewOutlookRegister(resp http.ResponseWriter, request *http.Request) { } // Should also update the user - Userdata, err := shuffle.GetUser(ctx, senderUser) + Userdata, err := shuffle.GetUser(ctx, user.Id) if err != nil { log.Printf("[INFO] Username %s doesn't exist (oauth2): %s", trigger.Username, err) resp.WriteHeader(401) @@ -458,14 +279,14 @@ func handleNewOutlookRegister(resp http.ResponseWriter, request *http.Request) { }) // Set apikey for the user if they don't have one - err = shuffle.SetUser(ctx, Userdata) + err = shuffle.SetUser(ctx, Userdata, true) if err != nil { log.Printf("Failed setting user data for %s: %s", Userdata.Username, err) resp.WriteHeader(401) return } - err = setTriggerAuth(ctx, trigger) + err = shuffle.SetTriggerAuth(ctx, trigger) if err != nil { log.Printf("Failed to set trigger auth for %s - %s", trigger.Username, err) resp.WriteHeader(401) @@ -476,50 +297,8 @@ func handleNewOutlookRegister(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(`{"success": true}`)) } -type OauthToken struct { - AccessToken string `json:"AccessToken" datastore:"AccessToken,noindex"` - TokenType string `json:"TokenType" datastore:"TokenType,noindex"` - RefreshToken string `json:"RefreshToken" datastore:"RefreshToken,noindex"` - Expiry time.Time `json:"Expiry" datastore:"Expiry,noindex"` -} - -type TriggerAuth struct { - Id string `json:"id" datastore:"id"` - SubscriptionId string `json:"subscriptionId" datastore:"subscriptionId"` - - Username string `json:"username" datastore:"username,noindex"` - WorkflowId string `json:"workflow_id" datastore:"workflow_id,noindex"` - Owner string `json:"owner" datastore:"owner"` - Type string `json:"type" datastore:"type"` - Code string `json:"code,omitempty" datastore:"code,noindex"` - Start string `json:"start" datastore:"start"` - OauthToken OauthToken `json:"oauth_token,omitempty" datastore:"oauth_token"` -} - -func getTriggerAuth(ctx context.Context, id string) (*TriggerAuth, error) { - key := datastore.NameKey("trigger_auth", strings.ToLower(id), nil) - triggerauth := &TriggerAuth{} - if err := dbclient.Get(ctx, key, triggerauth); err != nil { - return &TriggerAuth{}, err - } - - return triggerauth, nil -} - -func setTriggerAuth(ctx context.Context, trigger TriggerAuth) error { - key1 := datastore.NameKey("trigger_auth", strings.ToLower(trigger.Id), nil) - - // New struct, to not add body, author etc - if _, err := dbclient.Put(ctx, key1, &trigger); err != nil { - log.Printf("Error adding trigger auth: %s", err) - return err - } - - return nil -} - // THis all of a sudden became really horrible.. fml -func getOutlookClient(ctx context.Context, code string, accessToken OauthToken, redirectUri string) (*http.Client, *oauth2.Token, error) { +func getOutlookClient(ctx context.Context, code string, accessToken shuffle.OauthToken, redirectUri string) (*http.Client, *oauth2.Token, error) { conf := &oauth2.Config{ ClientID: "fd55c175-aa30-4fa6-b303-09a29fb3f750", @@ -557,81 +336,6 @@ func getOutlookClient(ctx context.Context, code string, accessToken OauthToken, return client, access_token, nil } -func handleGetOutlookFolders(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - // Exchange every time hmm - // FIXME - // Should really just get the code from the trigger that's being used OR the user - triggerId := request.URL.Query().Get("trigger_id") - if len(triggerId) == 0 { - log.Println("No trigger_id supplied") - resp.WriteHeader(401) - return - } - - ctx := context.Background() - trigger, err := getTriggerAuth(ctx, triggerId) - if err != nil { - log.Printf("[INFO] Trigger %s doesn't exist - outlook folders.", triggerId) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Trigger doesn't exist."}`)) - return - } - - //client, accessToken, err := getOutlookClient(ctx, code, OauthToken{}, url) - //if err != nil { - // log.Printf("Oauth client failure - outlook register: %s", err) - // resp.WriteHeader(401) - // return - //} - - // FIXME - should be shuffler in literally every case except testing lol - //log.Printf("TRIGGER: %#v", trigger) - redirectDomain := "localhost:5001" - url := fmt.Sprintf("http://%s/api/v1/triggers/outlook/register", redirectDomain) - outlookClient, _, err := getOutlookClient(ctx, "", trigger.OauthToken, url) - if err != nil { - log.Printf("[WARNING] Oauth client failure - outlook folders: %s", err) - resp.Write([]byte(`{"success": false, "reason": "Failed creating outlook client"}`)) - resp.WriteHeader(401) - return - } - - // This should be possible, and will also give the actual username - /* - profile, err := getOutlookProfile(outlookClient) - if err != nil { - log.Printf("Outlook profile failure: %s", err) - resp.WriteHeader(401) - return - } - log.Printf("PROFILE: %#v", profile) - */ - - folders, err := getOutlookFolders(outlookClient) - if err != nil { - log.Printf("[WARNING] Failed setting outlook folders: %s", err) - resp.Write([]byte(`{"success": false, "reason": "Failed getting outlook folders"}`)) - resp.WriteHeader(401) - return - } - - b, err := json.Marshal(folders.Value) - if err != nil { - log.Println("[INFO] Failed to marshal folderdata") - resp.Write([]byte(`{"success": false, "reason": "Failed decoding JSON"}`)) - resp.WriteHeader(401) - return - } - - resp.WriteHeader(200) - resp.Write(b) -} - func handleGetSpecificTrigger(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { @@ -664,7 +368,7 @@ func handleGetSpecificTrigger(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - trigger, err := getTriggerAuth(ctx, workflowId) + trigger, err := shuffle.GetTriggerAuth(ctx, workflowId) if err != nil { log.Printf("[INFO] Trigger %s doesn't exist - specific trigger.", workflowId) resp.WriteHeader(401) @@ -678,7 +382,7 @@ func handleGetSpecificTrigger(resp http.ResponseWriter, request *http.Request) { return } - trigger.OauthToken = OauthToken{} + trigger.OauthToken = shuffle.OauthToken{} trigger.Code = "" b, err := json.Marshal(trigger) @@ -692,201 +396,6 @@ func handleGetSpecificTrigger(resp http.ResponseWriter, request *http.Request) { resp.Write(b) } -// This sets up the sub with outlook itself -// Parses data from the workflow to see whether access is right to subscribe it -// Creates the cloud function for outlook return -// Wait for it to be available, then schedule a workflow to it -func createOutlookSub(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - location := strings.Split(request.URL.String(), "/") - - var workflowId string - if location[1] == "api" { - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - workflowId = location[4] - } - - ctx := context.Background() - workflow, err := shuffle.GetWorkflow(ctx, workflowId) - if err != nil { - log.Printf("Failed getting the workflow locally (outlook sub): %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in outlook deploy: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - // FIXME - have a check for org etc too.. - if user.Id != workflow.Owner && user.Role != "admin" { - log.Printf("Wrong user (%s) for workflow %s when deploying outlook", user.Username, workflow.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - log.Println("[INFO] Handle outlook subscription for trigger") - - // Should already be authorized at this point, as the workflow is shared - body, err := ioutil.ReadAll(request.Body) - if err != nil { - log.Printf("Failed body read for workflow %s", workflow.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - // Based on the input data from frontend - type CurTrigger struct { - Name string `json:"name"` - Folders []string `json:"folders"` - ID string `json:"id"` - } - - //log.Println(string(body)) - var curTrigger CurTrigger - err = json.Unmarshal(body, &curTrigger) - if err != nil { - log.Printf("Failed body read unmarshal for trigger %s", workflow.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - if len(curTrigger.Folders) == 0 { - log.Printf("Error for %s. Choosing folders is required, currently 0", workflow.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - // Now that it's deployed - wait a few seconds before generating: - // 1. Oauth2 token thingies for outlook.office.com - // 2. Set the url to have the right mailboxes (probably ID?) ("https://outlook.office.com/api/v2.0/me/mailfolders('inbox')/messages") - // 3. Set the callback URL to be the new trigger - // 4. Run subscription test - // 5. Set the subscriptionId to the trigger object - - // First - lets regenerate an oauth token for outlook.office.com from the original items - trigger, err := getTriggerAuth(ctx, curTrigger.ID) - if err != nil { - log.Printf("[INFO] Trigger %s doesn't exist - outlook sub.", curTrigger.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": ""}`)) - return - } - - // url doesn't really matter here - //url := fmt.Sprintf("https://shuffler.io") - redirectDomain := "localhost:5001" - url := fmt.Sprintf("http://%s/api/v1/triggers/outlook/register", redirectDomain) - outlookClient, _, err := getOutlookClient(ctx, "", trigger.OauthToken, url) - if err != nil { - log.Printf("Oauth client failure - triggerauth: %s", err) - resp.Write([]byte(`{"success": false, "reason": ""}`)) - resp.WriteHeader(401) - return - } - - // Location + - - // This is here simply to let the function start - // Usually takes 10 attempts minimum :O - // 10 * 5 = 50 seconds. That's waaay too much :( - - if runningEnvironment != "cloud" { - org, err := shuffle.GetOrg(ctx, user.ActiveOrg.Id) - if err != nil { - log.Printf("Failed finding org %s: %s", org.Id, err) - return - } - log.Printf("[INFO] Starting cloud configuration TO START trigger %s in org %s for workflow %s", trigger.Id, org.Id, trigger.WorkflowId) - - action := shuffle.CloudSyncJob{ - Type: "outlook", - Action: "start", - OrgId: org.Id, - PrimaryItemId: trigger.Id, - SecondaryItem: trigger.Start, - ThirdItem: workflowId, - } - - err = executeCloudAction(action, org.SyncConfig.Apikey) - if err != nil { - log.Printf("[INFO] Failed cloud action START outlook execution: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) - return - } else { - log.Printf("[INFO] Successfully set up cloud action trigger") - } - } else { - log.Printf("Should configure a running environment for CLOUD") - } - - notificationURL := fmt.Sprintf("%s/api/v1/hooks/webhook_%s", syncSubUrl, trigger.Id) - curSubscriptions, err := getOutlookSubscriptions(outlookClient) - if err == nil { - for _, sub := range curSubscriptions.Value { - if sub.NotificationURL == notificationURL { - log.Printf("[INFO] Removing existing subscription %s", sub.Id) - removeOutlookSubscription(outlookClient, sub.Id) - } - } - } else { - log.Printf("[INFO] Failed to get subscriptions - need to overwrite") - } - - maxFails := 5 - failCnt := 0 - log.Println(curTrigger.Folders) - for { - subId, err := makeOutlookSubscription(outlookClient, curTrigger.Folders, notificationURL) - if err != nil { - failCnt += 1 - log.Printf("Failed making oauth subscription, retrying in 5 seconds: %s", err) - time.Sleep(5 * time.Second) - if failCnt == maxFails { - log.Printf("Failed to set up subscription %d times.", maxFails) - resp.WriteHeader(401) - return - } - - continue - } - - // Set the ID somewhere here - trigger.SubscriptionId = subId - err = setTriggerAuth(ctx, *trigger) - if err != nil { - log.Printf("Failed setting triggerauth: %s", err) - } - - break - } - - log.Printf("[INFO] Successfully handled outlook subscription for trigger %s in workflow %s", curTrigger.ID, workflow.ID) - - //log.Printf("%#v", user) - resp.WriteHeader(200) - resp.Write([]byte(`{"success": true}`)) -} - // Lists the users current subscriptions func getOutlookSubscriptions(outlookClient *http.Client) (SubscriptionsWrapper, error) { fullUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/subscriptions") @@ -1024,7 +533,7 @@ func handleOutlookCallback(resp http.ResponseWriter, request *http.Request) { } //func getTriggerAuth(ctx context.Context, id string) (*TriggerAuth, error) { - hook, err := getTriggerAuth(ctx, hookId) + hook, err := shuffle.GetTriggerAuth(ctx, hookId) if err != nil { log.Printf("[INFO] Failed getting trigger %s (callback): %s", hookId, err) resp.WriteHeader(401) @@ -1054,7 +563,7 @@ func handleOutlookCallback(resp http.ResponseWriter, request *http.Request) { // 1. Take the body and parse data -> Get the email itself - maildata := MailData{} + maildata := shuffle.MailData{} err = json.Unmarshal(body, &maildata) if err != nil { log.Printf("Maildata unmarshal error: %s", err) @@ -1076,14 +585,14 @@ func handleOutlookCallback(resp http.ResponseWriter, request *http.Request) { log.Printf("[INFO] EMAILS: %d. If this is more than 1, please contact frikky@shuffler.io", len(emails)) //log.Printf("INSIDE GET OUTLOOK EMAIL!: %#v, %s", emails, err) - //type FullEmail struct { - email := FullEmail{} + //type shuffle.FullEmail struct { + email := shuffle.FullEmail{} if len(emails) == 1 { email = emails[0] } // Parse indicators (domains, emails, ips, domains etc)! - newEmail := ParsedShuffleMail{} + newEmail := shuffle.ParsedShuffleMail{} newEmail.Body.ContentType = email.Body.Contenttype newEmail.Body.Content = email.Body.Content newEmail.Body.RawBody = email.Body.Content @@ -1203,7 +712,7 @@ func handleOutlookSubRemoval(ctx context.Context, user shuffle.User, workflowId, // 2. Stop the subscription // 3. Remove the function // 4. Remove the database entry for auth - trigger, err := getTriggerAuth(ctx, triggerId) + trigger, err := shuffle.GetTriggerAuth(ctx, triggerId) if err != nil { log.Printf("Trigger auth %s doesn't exist - outlook sub removal.", triggerId) return err @@ -1293,7 +802,7 @@ func handleDeleteOutlookSub(resp http.ResponseWriter, request *http.Request) { ctx := context.Background() workflow, err := shuffle.GetWorkflow(ctx, workflowId) if err != nil { - log.Printf("Failed getting the workflow locally (delete outlook): %s", err) + log.Printf("[WARNING] Failed getting the workflow locally (delete outlook): %s", err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -1327,3 +836,198 @@ func handleDeleteOutlookSub(resp http.ResponseWriter, request *http.Request) { resp.WriteHeader(200) resp.Write([]byte(`{"success": true}`)) } + +// This sets up the sub with outlook itself +// Parses data from the workflow to see whether access is right to subscribe it +// Creates the cloud function for outlook return +// Wait for it to be available, then schedule a workflow to it +func createOutlookSub(resp http.ResponseWriter, request *http.Request) { + cors := handleCors(resp, request) + if cors { + return + } + + location := strings.Split(request.URL.String(), "/") + + var workflowId string + if location[1] == "api" { + if len(location) <= 4 { + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + workflowId = location[4] + } + + ctx := context.Background() + workflow, err := shuffle.GetWorkflow(ctx, workflowId) + if err != nil { + log.Printf("[WARNING] Failed getting the workflow locally (outlook sub): %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + user, err := shuffle.HandleApiAuthentication(resp, request) + if err != nil { + log.Printf("Api authentication failed in outlook deploy: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + // FIXME - have a check for org etc too.. + if user.Id != workflow.Owner && user.Role != "admin" { + log.Printf("Wrong user (%s) for workflow %s when deploying outlook", user.Username, workflow.ID) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + log.Println("[INFO] Handle outlook subscription for trigger") + + // Should already be authorized at this point, as the workflow is shared + body, err := ioutil.ReadAll(request.Body) + if err != nil { + log.Printf("Failed body read for workflow %s", workflow.ID) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + // Based on the input data from frontend + type CurTrigger struct { + Name string `json:"name"` + Folders []string `json:"folders"` + ID string `json:"id"` + } + + //log.Println(string(body)) + var curTrigger CurTrigger + err = json.Unmarshal(body, &curTrigger) + if err != nil { + log.Printf("Failed body read unmarshal for trigger %s", workflow.ID) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + if len(curTrigger.Folders) == 0 { + log.Printf("Error for %s. Choosing folders is required, currently 0", workflow.ID) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + // Now that it's deployed - wait a few seconds before generating: + // 1. Oauth2 token thingies for outlook.office.com + // 2. Set the url to have the right mailboxes (probably ID?) ("https://outlook.office.com/api/v2.0/me/mailfolders('inbox')/messages") + // 3. Set the callback URL to be the new trigger + // 4. Run subscription test + // 5. Set the subscriptionId to the trigger object + + // First - lets regenerate an oauth token for outlook.office.com from the original items + trigger, err := shuffle.GetTriggerAuth(ctx, curTrigger.ID) + if err != nil { + log.Printf("[INFO] Trigger %s doesn't exist - outlook sub.", curTrigger.ID) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": ""}`)) + return + } + + // url doesn't really matter here + //url := fmt.Sprintf("https://shuffler.io") + redirectDomain := "localhost:5001" + url := fmt.Sprintf("http://%s/api/v1/triggers/outlook/register", redirectDomain) + outlookClient, _, err := getOutlookClient(ctx, "", trigger.OauthToken, url) + if err != nil { + log.Printf("Oauth client failure - triggerauth: %s", err) + resp.Write([]byte(`{"success": false, "reason": ""}`)) + resp.WriteHeader(401) + return + } + + // Location + + + // This is here simply to let the function start + // Usually takes 10 attempts minimum :O + // 10 * 5 = 50 seconds. That's waaay too much :( + + if runningEnvironment != "cloud" { + org, err := shuffle.GetOrg(ctx, user.ActiveOrg.Id) + if err != nil { + log.Printf("Failed finding org %s: %s", org.Id, err) + return + } + log.Printf("[INFO] Starting cloud configuration TO START trigger %s in org %s for workflow %s", trigger.Id, org.Id, trigger.WorkflowId) + + action := shuffle.CloudSyncJob{ + Type: "outlook", + Action: "start", + OrgId: org.Id, + PrimaryItemId: trigger.Id, + SecondaryItem: trigger.Start, + ThirdItem: workflowId, + } + + err = executeCloudAction(action, org.SyncConfig.Apikey) + if err != nil { + log.Printf("[INFO] Failed cloud action START outlook execution: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) + return + } else { + log.Printf("[INFO] Successfully set up cloud action trigger") + } + } else { + log.Printf("Should configure a running environment for CLOUD") + } + + notificationURL := fmt.Sprintf("%s/api/v1/hooks/webhook_%s", syncSubUrl, trigger.Id) + curSubscriptions, err := getOutlookSubscriptions(outlookClient) + if err == nil { + for _, sub := range curSubscriptions.Value { + if sub.NotificationURL == notificationURL { + log.Printf("[INFO] Removing existing subscription %s", sub.Id) + removeOutlookSubscription(outlookClient, sub.Id) + } + } + } else { + log.Printf("[INFO] Failed to get subscriptions - need to overwrite") + } + + maxFails := 5 + failCnt := 0 + log.Println(curTrigger.Folders) + for { + subId, err := makeOutlookSubscription(outlookClient, curTrigger.Folders, notificationURL) + if err != nil { + failCnt += 1 + log.Printf("Failed making oauth subscription, retrying in 5 seconds: %s", err) + time.Sleep(5 * time.Second) + if failCnt == maxFails { + log.Printf("Failed to set up subscription %d times.", maxFails) + resp.WriteHeader(401) + return + } + + continue + } + + // Set the ID somewhere here + trigger.SubscriptionId = subId + err = shuffle.SetTriggerAuth(ctx, *trigger) + if err != nil { + log.Printf("Failed setting triggerauth: %s", err) + } + + break + } + + log.Printf("[INFO] Successfully handled outlook subscription for trigger %s in workflow %s", curTrigger.ID, workflow.ID) + + //log.Printf("%#v", user) + resp.WriteHeader(200) + resp.Write([]byte(`{"success": true}`)) +} diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 86f27be7..c0f16bbf 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -22,13 +22,9 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/client" - "cloud.google.com/go/datastore" - scheduler "cloud.google.com/go/scheduler/apiv1" gyaml "github.com/ghodss/yaml" "github.com/h2non/filetype" uuid "github.com/satori/go.uuid" - "google.golang.org/api/cloudfunctions/v1" - schedulerpb "google.golang.org/genproto/googleapis/cloud/scheduler/v1" newscheduler "github.com/carlescere/scheduler" "github.com/frikky/kin-openapi/openapi3" @@ -43,15 +39,13 @@ import ( //"google.golang.org/appengine/memcache" //"cloud.google.com/go/firestore" // "google.golang.org/api/option" - - "google.golang.org/api/iterator" ) var localBase = "http://localhost:5001" var baseEnvironment = "onprem" var cloudname = "cloud" -var defaultLocation = "europe-west2" + var scheduledJobs = map[string]*newscheduler.Job{} var scheduledOrgs = map[string]*newscheduler.Job{} @@ -474,128 +468,6 @@ var scheduledOrgs = map[string]*newscheduler.Job{} // SuccessExamples []string `json:"success_examples" datastore:"success_examples,noindex"` // FailureExamples []string `json:"failure_examples" datastore:"failure_examples,noindex"` //} - -// This might be... a bit off, but that's fine :) -// This might also be stupid, as we want timelines and such -// Anyway, these are super basic stupid stats. -func increaseStatisticsField(ctx context.Context, fieldname, id string, amount int64, orgId string) error { - - // 1. Get current stats - // 2. Increase field(s) - // 3. Put new stats - statisticsId := "global_statistics" - nameKey := fieldname - key := datastore.NameKey(statisticsId, nameKey, nil) - - statisticsItem := StatisticsItem{} - newData := StatisticsData{ - Timestamp: int64(time.Now().Unix()), - Amount: amount, - Id: id, - } - - if err := dbclient.Get(ctx, key, &statisticsItem); err != nil { - // Should init - if strings.Contains(fmt.Sprintf("%s", err), "entity") { - statisticsItem = StatisticsItem{ - Total: amount, - OrgId: orgId, - Fieldname: fieldname, - Data: []StatisticsData{ - newData, - }, - } - - if _, err := dbclient.Put(ctx, key, &statisticsItem); err != nil { - log.Printf("Error setting base stats: %s", err) - return err - } - - return nil - } - //log.Printf("STATSERR: %s", err) - - return err - } - - statisticsItem.Total += amount - statisticsItem.Data = append(statisticsItem.Data, newData) - - // New struct, to not add body, author etc - // FIXME - reintroduce - //if _, err := dbclient.Put(ctx, key, &statisticsItem); err != nil { - // log.Printf("Error stats to %s: %s", fieldname, err) - // return err - //} - - //log.Printf("Stats: %#v", statisticsItem) - - return nil -} - -func setWorkflowQueue(ctx context.Context, executionRequest shuffle.ExecutionRequest, env string) error { - orgKey := fmt.Sprintf("workflowqueue-%s", env) - key := datastore.NameKey(orgKey, executionRequest.ExecutionId, nil) - - // New struct, to not add body, author etc - if _, err := dbclient.Put(ctx, key, &executionRequest); err != nil { - log.Printf("Error adding workflow queue: %s", err) - return err - } - - return nil -} - -// -//func setWorkflowQueue(ctx context.Context, executionRequests ExecutionRequestWrapper, id string) error { -// key := datastore.NameKey("workflowqueue", id, nil) -// -// // New struct, to not add body, author etc -// if _, err := dbclient.Put(ctx, key, &executionRequests); err != nil { -// log.Printf("Error adding workflow queue: %s", err) -// return err -// } -// -// return nil -//} - -func getWorkflowQueue(ctx context.Context, id string) (shuffle.ExecutionRequestWrapper, error) { - orgId := fmt.Sprintf("workflowqueue-%s", id) - q := datastore.NewQuery(orgId).Limit(10) - executions := []shuffle.ExecutionRequest{} - _, err := dbclient.GetAll(ctx, q, &executions) - if err != nil { - return shuffle.ExecutionRequestWrapper{}, err - } - - return shuffle.ExecutionRequestWrapper{Data: executions}, nil - - //key := datastore.NameKey("workflowqueue", id, nil) - //executions := ExecutionRequestWrapper{} - //if err := dbclient.Get(ctx, key, &workflows); err != nil { - // return ExecutionRequestWrapper{}, err - //} - - //return workflows, nil -} - -//func setWorkflowqueuetest(id string) { -// data := ExecutionRequestWrapper{ -// Data: []ExecutionRequest{ -// ExecutionRequest{ -// ExecutionId: "2349bf96-51ad-68d2-5ca6-75ef8f7ee814", -// WorkflowId: "8e344a2e-db51-448f-804c-eb959a32c139", -// Authorization: "wut", -// }, -// }, -// } -// -// err := setWorkflowQueue(data, id) -// if err != nil { -// log.Printf("Fail: %s", err) -// } -//} - // Frequency = cronjob OR minutes between execution func createSchedule(ctx context.Context, scheduleId, workflowId, name, startNode, frequency, orgId string, body []byte) error { var err error @@ -642,7 +514,7 @@ func createSchedule(ctx context.Context, scheduleId, workflowId, name, startNode Body: ioutil.NopCloser(strings.NewReader(bodyWrapper)), } - _, _, err := handleExecution(workflowId, shuffle.Workflow{ExecutingOrg: shuffle.Org{Id: orgId}}, request) + _, _, err := handleExecution(workflowId, shuffle.Workflow{ExecutingOrg: shuffle.OrgMini{Id: orgId}}, request) if err != nil { log.Printf("Failed to execute %s: %s", workflowId, err) } @@ -660,7 +532,7 @@ func createSchedule(ctx context.Context, scheduleId, workflowId, name, startNode // Doesn't need running/not running. If stopped, we just delete it. timeNow := int64(time.Now().Unix()) - schedule := ScheduleOld{ + schedule := shuffle.ScheduleOld{ Id: scheduleId, WorkflowId: workflowId, StartNode: startNode, @@ -674,7 +546,7 @@ func createSchedule(ctx context.Context, scheduleId, workflowId, name, startNode Environment: "onprem", } - err = setSchedule(ctx, schedule) + err = shuffle.SetSchedule(ctx, schedule) if err != nil { log.Printf("Failed to set schedule: %s", err) return err @@ -704,7 +576,7 @@ func handleGetWorkflowqueueConfirm(resp http.ResponseWriter, request *http.Reque //setWorkflowqueuetest(id) ctx := context.Background() - executionRequests, err := getWorkflowQueue(ctx, id) + executionRequests, err := shuffle.GetWorkflowQueue(ctx, id) if err != nil { log.Printf("(1) Failed reading body for workflowqueue: %s", err) resp.WriteHeader(401) @@ -752,11 +624,11 @@ func handleGetWorkflowqueueConfirm(resp http.ResponseWriter, request *http.Reque ids = append(ids, execution.ExecutionId) } - err = DeleteKeys(ctx, parsedId, ids) + err = shuffle.DeleteKeys(ctx, parsedId, ids) if err != nil { log.Printf("[ERROR] Failed deleting %d execution keys for org %s", len(ids), id) } else { - //log.Printf("[INFO] Deleted %d keys from org %s", len(ids), parsedId) + log.Printf("[INFO] Deleted %d keys from org %s", len(ids), parsedId) } //var newExecutionRequests ExecutionRequestWrapper @@ -776,7 +648,7 @@ func handleGetWorkflowqueueConfirm(resp http.ResponseWriter, request *http.Reque // Push only the remaining to the DB (remove) //if len(executionRequests.Data) != len(newExecutionRequests.Data) { - // err := setWorkflowQueue(ctx, newExecutionRequests, id) + // err := shuffle.SetWorkflowQueue(ctx, newExecutionRequests, id) // if err != nil { // log.Printf("Fail: %s", err) // } @@ -796,14 +668,14 @@ func handleGetWorkflowqueue(resp http.ResponseWriter, request *http.Request) { id := request.Header.Get("Org-Id") if len(id) == 0 { - log.Printf("No org-id header set") + log.Printf("[INFO] No org-id header set") resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Specify the org-id header."}`))) return } ctx := context.Background() - executionRequests, err := getWorkflowQueue(ctx, id) + executionRequests, err := shuffle.GetWorkflowQueue(ctx, id) if err != nil { // Skipping as this comes up over and over //log.Printf("(2) Failed reading body for workflowqueue: %s", err) @@ -816,6 +688,7 @@ func handleGetWorkflowqueue(resp http.ResponseWriter, request *http.Request) { executionRequests.Data = []shuffle.ExecutionRequest{} } else { log.Printf("[INFO] Executionrequests (%s): %d", id, len(executionRequests.Data)) + //log.Printf("IDS: %#v", executionRequests.Data[0].ExecutionId) } newjson, err := json.Marshal(executionRequests) @@ -843,10 +716,11 @@ func handleGetStreamResults(resp http.ResponseWriter, request *http.Request) { return } + //log.Printf("Data: %s", string(body)) var actionResult shuffle.ActionResult err = json.Unmarshal(body, &actionResult) if err != nil { - log.Printf("Failed ActionResult unmarshaling: %s", err) + log.Printf("[WARNING] Failed ActionResult unmarshaling (stream result): %s", err) resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) return @@ -863,7 +737,7 @@ func handleGetStreamResults(resp http.ResponseWriter, request *http.Request) { // Authorization is done here if workflowExecution.Authorization != actionResult.Authorization { - log.Printf("Bad authorization key when getting stream results %s.", actionResult.ExecutionId) + log.Printf("[WARNING] Bad authorization key when getting stream results %s.", actionResult.ExecutionId) resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Bad authorization key or execution_id might not exist."}`))) return @@ -881,61 +755,9 @@ func handleGetStreamResults(resp http.ResponseWriter, request *http.Request) { } -// Finds the child nodes of a node in execution and returns them -// Used if e.g. a node in a branch is exited, and all children have to be stopped -func findChildNodes(workflowExecution shuffle.WorkflowExecution, nodeId string) []string { - //log.Printf("\nNODE TO FIX: %s\n\n", nodeId) - allChildren := []string{nodeId} - - // 1. Find children of this specific node - // 2. Find the children of those nodes etc. - for _, branch := range workflowExecution.Workflow.Branches { - if branch.SourceID == nodeId { - //log.Printf("Children: %s", branch.DestinationID) - allChildren = append(allChildren, branch.DestinationID) - - childNodes := findChildNodes(workflowExecution, branch.DestinationID) - for _, bottomChild := range childNodes { - found := false - for _, topChild := range allChildren { - if topChild == bottomChild { - found = true - break - } - } - - if !found { - allChildren = append(allChildren, bottomChild) - } - } - } - } - - // Remove potential duplicates - newNodes := []string{} - for _, tmpnode := range allChildren { - found := false - for _, newnode := range newNodes { - if newnode == tmpnode { - found = true - break - } - } - - if !found { - newNodes = append(newNodes, tmpnode) - } - } - - return newNodes -} - // Checks if data is sent from Worker >0.8.51, which sends a full execution // instead of individial results func validateNewWorkerExecution(body []byte) error { - //type WorkflowExecution struct { - //} - ctx := context.Background() var execution shuffle.WorkflowExecution err := json.Unmarshal(body, &execution) @@ -943,6 +765,7 @@ func validateNewWorkerExecution(body []byte) error { log.Printf("[WARNING] Failed execution unmarshaling: %s", err) return err } + //log.Printf("\n\nGOT EXEC WITH RESULT %#v (%d)\n\n", execution.Status, len(execution.Results)) baseExecution, err := shuffle.GetWorkflowExecution(ctx, execution.ExecutionId) if err != nil { @@ -963,10 +786,14 @@ func validateNewWorkerExecution(body []byte) error { return errors.New(fmt.Sprintf("Bad length of trigger: %d (probably normal app)", len(execution.Workflow.Triggers))) } - if baseExecution.Status != "WAITING" && baseExecution.Status != "EXECUTING" { - return errors.New(fmt.Sprintf("Workflow is already finished or failed. Can't update")) + if len(baseExecution.Results) >= len(execution.Results) { + return errors.New(fmt.Sprintf("Can't have less actions in a full execution than what exists: %d (old) vs %d (new)", len(baseExecution.Results), len(execution.Results))) } + //if baseExecution.Status != "WAITING" && baseExecution.Status != "EXECUTING" { + // return errors.New(fmt.Sprintf("Workflow is already finished or failed. Can't update")) + //} + if execution.Status == "EXECUTING" { //log.Printf("[INFO] Inside executing.") extra := 0 @@ -981,7 +808,7 @@ func validateNewWorkerExecution(body []byte) error { execution.Status = "FINISHED" } - log.Printf("[INFO] BASEEXECUTION LENGTH: %d", len(baseExecution.Workflow.Actions)+extra) + //log.Printf("[INFO] BASEEXECUTION LENGTH: %d", len(baseExecution.Workflow.Actions)+extra) } // FIXME: Add extra here @@ -993,7 +820,7 @@ func validateNewWorkerExecution(body []byte) error { //log.Printf("\n\nSHOULD SET BACKEND DATA FOR EXEC \n\n") err = shuffle.SetWorkflowExecution(ctx, execution, true) if err == nil { - log.Printf("[INFO] Set workflowexecution based on new worker (>0.8.53) for execution %s. Actions: %d, Triggers: %d, Results: %d", execution.ExecutionId, len(execution.Workflow.Actions), len(execution.Workflow.Triggers), len(execution.Results)) + log.Printf("[INFO] Set workflowexecution based on new worker (>0.8.53) for execution %s. Actions: %d, Triggers: %d, Results: %d, Status: %s", execution.ExecutionId, len(execution.Workflow.Actions), len(execution.Workflow.Triggers), len(execution.Results), execution.Status) //, execution.Result) //log.Printf("[INFO] Successfully set the execution to wait.") } else { log.Printf("[WARNING] Failed to set the execution to wait.") @@ -1029,12 +856,14 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) { var actionResult shuffle.ActionResult err = json.Unmarshal(body, &actionResult) if err != nil { - log.Printf("Failed ActionResult unmarshaling: %s", err) + log.Printf("[WARNING] Failed ActionResult unmarshaling (queue): %s", err) resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) return } + //log.Printf("Received action: %#v", actionResult) + // 1. Get the WorkflowExecution(ExecutionId) from the database // 2. if ActionResult.Authentication != WorkflowExecution.Authentication -> exit // 3. Add to and update actionResult in workflowExecution @@ -1057,15 +886,13 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) { return } - if workflowExecution.Status == "FINISHED" { - log.Printf("Workflowexecution is already FINISHED. No further action can be taken") - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Workflowexecution is already finished because of %s with status %s"}`, workflowExecution.LastNode, workflowExecution.Status))) - return - } + //if workflowExecution.Status == "FINISHED" { + // log.Printf("[INFO] Workflowexecution is already FINISHED. No further action can be taken.") + // resp.WriteHeader(401) + // resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Workflowexecution is already finished because of %s with status %s"}`, workflowExecution.LastNode, workflowExecution.Status))) + // return + //} - // Not sure what's up here - // FIXME - remove comment if workflowExecution.Status == "ABORTED" || workflowExecution.Status == "FAILURE" { if workflowExecution.Workflow.Configuration.ExitOnError { @@ -1074,12 +901,12 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Workflowexecution is aborted because of %s with result %s and status %s"}`, workflowExecution.LastNode, workflowExecution.Result, workflowExecution.Status))) return } else { - log.Printf("Continuing even though it's aborted.") + log.Printf("[WARNING] Continuing workflow even though it's aborted (ExitOnError config)") } } if actionResult.Status == "WAITING" && actionResult.Action.AppName == "User Input" { - log.Printf("SHOULD WAIT A BIT AND RUN CLOUD STUFF WITH USER INPUT! WAITING!") + log.Printf("[INFO] SHOULD WAIT A BIT AND RUN CLOUD STUFF WITH USER INPUT! WAITING!") var trigger shuffle.Trigger err = json.Unmarshal([]byte(actionResult.Result), &trigger) @@ -1144,443 +971,58 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl return } - //resultLength := len(workflowExecution.Results) - dbSave := false - setExecution := true - - if actionResult.Action.ID == "" { - //log.Printf("[ERROR] Failed handling EMPTY action %#v", actionResult) + //log.Printf("BASE LENGTH: %d", len(workflowExecution.Results)) + workflowExecution, dbSave, err := shuffle.ParsedExecutionResult(ctx, *workflowExecution, actionResult, false) + if err != nil { + log.Printf("[ERROR] Failed execution of parsedexecution: %s", err) resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't handle empty action"}`))) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed getting execution"}`))) return } - //tx, err := dbclient.NewTransaction(ctx) - //if err != nil { - // log.Printf("client.NewTransaction: %v", err) - // resp.WriteHeader(401) - // resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed creating transaction"}`))) - // return - //} - //key := datastore.NameKey("workflowexecution", workflowExecutionId, nil) - //workflowExecution := &WorkflowExecution{} - //if err := tx.Get(key, workflowExecution); err != nil { - // log.Printf("[ERROR] tx.Get bug: %v", err) - // tx.Rollback() - // resp.WriteHeader(401) - // resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed getting the workflow key"}`))) - // return - //} + //log.Printf("NEW LENGTH: %d", len(workflowExecution.Results)) - if actionResult.Status == "ABORTED" || actionResult.Status == "FAILURE" { - dbSave = true + _ = dbSave + //resultLength := len(workflowExecution.Results) + setExecution := true - newResults := []shuffle.ActionResult{} - childNodes := []string{} - if workflowExecution.Workflow.Configuration.ExitOnError { - log.Printf("[WARNING] Actionresult is %s for node %s in %s. Should set workflowExecution and exit all running functions", actionResult.Status, actionResult.Action.ID, workflowExecution.ExecutionId) - workflowExecution.Status = actionResult.Status - workflowExecution.LastNode = actionResult.Action.ID - // Find underlying nodes and add them - } else { - log.Printf("[WARNING] Actionresult is %s for node %s in %s. Continuing anyway because of workflow configuration.", actionResult.Status, actionResult.Action.ID, workflowExecution.ExecutionId) - - // Finds ALL childnodes to set them to SKIPPED - childNodes = findChildNodes(*workflowExecution, actionResult.Action.ID) - - // Remove duplicates - //log.Printf("CHILD NODES: %d", len(childNodes)) - for _, nodeId := range childNodes { - if nodeId == actionResult.Action.ID { - continue - } - - // 1. Find the action itself - // 2. Create an actionresult - curAction := shuffle.Action{ID: ""} - for _, action := range workflowExecution.Workflow.Actions { - if action.ID == nodeId { - curAction = action - break - } - } - - if len(curAction.ID) == 0 { - log.Printf("Couldn't find subnode %s", nodeId) - continue - } - - resultExists := false - for _, result := range workflowExecution.Results { - if result.Action.ID == curAction.ID { - resultExists = true - break - } - } - - if !resultExists { - // Check parents are done here. Only add it IF all parents are skipped - skipNodeAdd := false - for _, branch := range workflowExecution.Workflow.Branches { - if branch.DestinationID == nodeId { - // If the branch's source node is NOT in childNodes, it's not a skipped parent - sourceNodeFound := false - for _, item := range childNodes { - if item == branch.SourceID { - sourceNodeFound = true - break - } - } - - if !sourceNodeFound { - log.Printf("Not setting node %s to SKIPPED", nodeId) - skipNodeAdd = true - break - } - } - } - - if !skipNodeAdd { - newAction := shuffle.Action{ - AppName: curAction.AppName, - AppVersion: curAction.AppVersion, - Label: curAction.Label, - Name: curAction.Name, - ID: curAction.ID, - } - - newResult := shuffle.ActionResult{ - Action: newAction, - ExecutionId: actionResult.ExecutionId, - Authorization: actionResult.Authorization, - Result: "Skipped because of previous node", - StartedAt: 0, - CompletedAt: 0, - Status: "SKIPPED", - } - - newResults = append(newResults, newResult) - //increaseStatisticsField(ctx, "workflow_execution_actions_skipped", workflowExecution.Workflow.ID, 1, workflowExecution.ExecutionOrg) - } - } - } - } - - // Cleans up aborted, and always gives a result - lastResult := "" - // type ActionResult struct { - for _, result := range workflowExecution.Results { - if actionResult.Action.ID == result.Action.ID { - continue - } - - if result.Status == "EXECUTING" { - result.Status = actionResult.Status - result.Result = "Aborted because of error in another node (2)" - } - - if len(result.Result) > 0 { - lastResult = result.Result - } - - newResults = append(newResults, result) - } - - workflowExecution.Result = lastResult - workflowExecution.Results = newResults - - if workflowExecution.Status == "ABORTED" { - //err = increaseStatisticsField(ctx, "workflow_executions_aborted", workflowExecution.Workflow.ID, 1, workflowExecution.ExecutionOrg) - //if err != nil { - // log.Printf("Failed to increase aborted execution stats: %s", err) - //} - } else if workflowExecution.Status == "FAILURE" { - //err = increaseStatisticsField(ctx, "workflow_executions_failure", workflowExecution.Workflow.ID, 1, workflowExecution.ExecutionOrg) - //if err != nil { - // log.Printf("Failed to increase failure execution stats: %s", err) - //} - } - } - - // FIXME rebuild to be like this or something - // workflowExecution/ExecutionId/Nodes/NodeId - // Find the appropriate action - //log.Printf("[INFO] Setting value of %s in workflow %s to %s (1)", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status) - if len(workflowExecution.Results) > 0 { - // FIXME - skip := false - found := false - outerindex := 0 - for index, item := range workflowExecution.Results { - if item.Action.ID == actionResult.Action.ID { - found = true - if item.Status == actionResult.Status { - skip = true - } - - outerindex = index - break - } - } - - if skip { - //log.Printf("Both are %s. Skipping this node", item.Status) - } else if found { - // If result exists and execution variable exists, update execution value - //log.Printf("Exec var backend: %s", workflowExecution.Results[outerindex].Action.ExecutionVariable.Name) - actionVarName := workflowExecution.Results[outerindex].Action.ExecutionVariable.Name - // Finds potential execution arguments - if len(actionVarName) > 0 { - log.Printf("EXECUTION VARIABLE LOCAL: %s", actionVarName) - for index, execvar := range workflowExecution.ExecutionVariables { - if execvar.Name == actionVarName { - // Sets the value for the variable - workflowExecution.ExecutionVariables[index].Value = actionResult.Result - break - } - } - } - - log.Printf("[INFO] Updating %s in workflow %s from %s to %s (3)", actionResult.Action.ID, workflowExecution.ExecutionId, workflowExecution.Results[outerindex].Status, actionResult.Status) - workflowExecution.Results[outerindex] = actionResult - } else { - log.Printf("[INFO] Setting value of %s in workflow %s to %s (1)", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status) - workflowExecution.Results = append(workflowExecution.Results, actionResult) - } - } else { - log.Printf("[INFO] Setting value of %s in workflow %s to %s (2)", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status) - workflowExecution.Results = append(workflowExecution.Results, actionResult) - } - - // FIXME: Have a check for skippednodes and their parents - for resultIndex, result := range workflowExecution.Results { - if result.Status != "SKIPPED" { - continue - } - - // Checks if all parents are skipped or failed. Otherwise removes them from the results - for _, branch := range workflowExecution.Workflow.Branches { - if branch.DestinationID == result.Action.ID { - for _, subresult := range workflowExecution.Results { - if subresult.Action.ID == branch.SourceID { - if subresult.Status != "SKIPPED" && subresult.Status != "FAILURE" { - log.Printf("SUBRESULT PARENT STATUS: %s", subresult.Status) - log.Printf("Should remove resultIndex: %d", resultIndex) - - workflowExecution.Results = append(workflowExecution.Results[:resultIndex], workflowExecution.Results[resultIndex+1:]...) - - break - } - } - } - } - } - } - - extraInputs := 0 - for _, trigger := range workflowExecution.Workflow.Triggers { - if trigger.Name == "User Input" && trigger.AppName == "User Input" { - extraInputs += 1 - } else if trigger.Name == "Shuffle Workflow" && trigger.AppName == "Shuffle Workflow" { - extraInputs += 1 - } - } - - //log.Printf("EXTRA: %d", extraInputs) - //log.Printf("LENGTH: %d - %d", len(workflowExecution.Results), len(workflowExecution.Workflow.Actions)+extraInputs) - - if len(workflowExecution.Results) == len(workflowExecution.Workflow.Actions)+extraInputs { - //log.Printf("\nIN HERE WITH RESULTS %d vs %d\n", len(workflowExecution.Results), len(workflowExecution.Workflow.Actions)+extraInputs) - finished := true - lastResult := "" - - // Doesn't have to be SUCCESS and FINISHED everywhere anymore. - skippedNodes := false - for _, result := range workflowExecution.Results { - if result.Status == "EXECUTING" { - finished = false - break - } - - // FIXME: Check if ALL parents are skipped or if its just one. Otherwise execute it - if result.Status == "SKIPPED" { - skippedNodes = true - - // Checks if all parents are skipped or failed. Otherwise removes them from the results - for _, branch := range workflowExecution.Workflow.Branches { - if branch.DestinationID == result.Action.ID { - for _, subresult := range workflowExecution.Results { - if subresult.Action.ID == branch.SourceID { - if subresult.Status != "SKIPPED" && subresult.Status != "FAILURE" { - //log.Printf("SUBRESULT PARENT STATUS: %s", subresult.Status) - //log.Printf("Should remove resultIndex: %d", resultIndex) - finished = false - break - } - } - } - } - - if !finished { - break - } - } - } - - lastResult = result.Result - } - - // FIXME: Handle skip nodes - change status? - _ = skippedNodes - - if finished { - dbSave = true - log.Printf("[INFO] Execution of %s finished.", workflowExecution.ExecutionId) - //log.Println("Might be finished based on length of results and everything being SUCCESS or FINISHED - VERIFY THIS. Setting status to finished.") - - workflowExecution.Result = lastResult - workflowExecution.Status = "FINISHED" - workflowExecution.CompletedAt = int64(time.Now().Unix()) - if workflowExecution.LastNode == "" { - workflowExecution.LastNode = actionResult.Action.ID - } - - //err = increaseStatisticsField(ctx, "workflow_executions_success", workflowExecution.Workflow.ID, 1, workflowExecution.ExecutionOrg) - //if err != nil { - // log.Printf("Failed to increase success execution stats: %s", err) - //} - - // Handles extra statistics stuff when it's done - // Does autocomplete magic with JSON - handleExecutionStatistics(*workflowExecution) - } - } - - // FIXME - why isn't this how it works otherwise, wtf? - //workflow, err := shuffle.GetWorkflow(workflowExecution.Workflow.ID) - //newActions := []Action{} - //for _, action := range workflowExecution.Workflow.Actions { - // log.Printf("Name: %s, Env: %s", action.Name, action.Environment) - //} - - tmpJson, err := json.Marshal(workflowExecution) - if err == nil { - if len(tmpJson) >= 1048487 { - dbSave = true - log.Printf("[ERROR] Result length is too long! Need to reduce result size") - - // Result string `json:"result" datastore:"result,noindex"` - // Arbitrary reduction size - maxSize := 500000 - newResults := []shuffle.ActionResult{} - for _, item := range workflowExecution.Results { - if len(item.Result) > maxSize { - item.Result = "[ERROR] Result too large to handle (https://github.com/frikky/shuffle/issues/171)" - } - - newResults = append(newResults, item) - } - - workflowExecution.Results = newResults - } - } - - // Validating that action results hasn't changed - // Handled using cachhing, so actually pretty fast - cacheKey := fmt.Sprintf("workflowexecution-%s", workflowExecution.ExecutionId) - cache, err := shuffle.GetCache(ctx, cacheKey) - if err == nil { - cacheData := []byte(cache.([]uint8)) - //log.Printf("CACHEDATA: %#v", cacheData) - err = json.Unmarshal(cacheData, &workflowExecution) - if err == nil { - if attempts > 5 { - //log.Printf("\n\nSkipping execution input - %d vs %d. Attempts: (%d)\n\n", len(parsedValue.Results), resultLength, attempts) - } - - attempts += 1 - if len(workflowExecution.Results) <= len(workflowExecution.Workflow.Actions) { - runWorkflowExecutionTransaction(ctx, attempts, workflowExecutionId, actionResult, resp) - return - } - } - } - - //if value, found := requestCache.Get(cacheKey); found { - // parsedValue := value.(*shuffle.WorkflowExecution) - // if len(parsedValue.Results) > 0 && len(parsedValue.Results) != resultLength { + //newExecution, err := shuffle.GetWorkflowExecution(ctx, workflowExecution.ExecutionId) + //if err == nil { + // //log.Printf("GOT GOOD EXECUTION CACHE FOR %s!", workflowExecution.ExecutionId) + // if len(newExecution.Results) > 0 && len(newExecution.Results) != resultLength { // setExecution = false // if attempts > 5 { // //log.Printf("\n\nSkipping execution input - %d vs %d. Attempts: (%d)\n\n", len(parsedValue.Results), resultLength, attempts) // } // attempts += 1 - // if len(workflowExecution.Results) <= len(workflowExecution.Workflow.Actions) { - // runWorkflowExecutionTransaction(ctx, attempts, workflowExecutionId, actionResult, resp) - // return - // } + // //if len(workflowExecution.Results) <= len(workflowExecution.Workflow.Actions) { + // // log.Printf("RUNNING AGAIN!!") + // // runWorkflowExecutionTransaction(ctx, attempts, workflowExecutionId, actionResult, resp) + // // return // } + //} else { + // log.Printf("[WARNING] Failed getting cache for %s: %s", workflowExecution.ExecutionId, err) //} if setExecution || workflowExecution.Status == "FINISHED" || workflowExecution.Status == "ABORTED" || workflowExecution.Status == "FAILURE" { - err = shuffle.SetWorkflowExecution(ctx, *workflowExecution, dbSave) + err = shuffle.SetWorkflowExecution(ctx, *workflowExecution, true) + //err = shuffle.SetWorkflowExecution(ctx, *workflowExecution, dbSave) if err != nil { resp.WriteHeader(401) resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting workflowexecution actionresult: %s"}`, err))) return } + //handleExecutionResult(ctx, *workflowExecution) } else { log.Printf("Skipping setexec with status %s", workflowExecution.Status) } - //ExecutionId - // Transactions: https://cloud.google.com/datastore/docs/concepts/transactions#datastore-datastore-transactional-update-go - // Prevents timing issues - //if _, err := tx.Put(key, workflowExecution); err != nil { - // log.Printf("[ERROR] tx.Put error: %v", err) - // err = tx.Rollback() - // if err != nil { - // log.Printf("[ERROR] Rollback error (3): %s", err) - // } + if resp != nil { + resp.WriteHeader(200) + resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) + } - // resp.WriteHeader(401) - // resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting workflowexecution actionresult: %s"}`, err))) - // return - //} - - //if _, err = tx.Commit(); err != nil { - // err = tx.Rollback() - // if err != nil { - // log.Printf("[ERROR] Rollback error expected ? (1): %s", err) - // } - - // if attempts >= 7 { - // log.Printf("[ERROR] QUITTING: tx.Commit %d: %v", attempts, err) - - // workflowExecution.Status = "ABORTED" - // shuffle.SetWorkflowExecution(ctx, *workflowExecution, true) - - // resp.WriteHeader(401) - // resp.Write([]byte(`{"success": false}`)) - // return - // } - - // if attempts > 3 { - // log.Printf("[WARNING] tx.Commit %d: %v", attempts, err) - // } - - // attempts += 1 - // runWorkflowExecutionTransaction(ctx, attempts, workflowExecutionId, actionResult, resp) - // return - //} else { - // //if grpc.Code(err) == codes.Aborted { - // // return nil, ErrConcurrentTransaction - // //} - // //t.id = nil // mark the transaction as expired - //} - - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) } func JSONCheck(str string) bool { @@ -1667,98 +1109,6 @@ func handleExecutionStatistics(execution shuffle.WorkflowExecution) { } } -func getWorkflows(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in getworkflows: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - //memcacheName := fmt.Sprintf("%s_workflows", user.Username) - ctx := context.Background() - //if item, err := memcache.Get(ctx, memcacheName); err == memcache.ErrCacheMiss { - // // Not in cache - // //log.Printf("Workflows not in cache.") - //} else if err != nil { - // log.Printf("Error getting item: %v", err) - //} else { - // // FIXME - verify if value is ok? Can unmarshal etc. - // resp.WriteHeader(200) - // resp.Write(item.Value) - // return - //} - - // With user, do a search for workflows with user or user's org attached - q := datastore.NewQuery("workflow").Filter("owner =", user.Id) - if user.Role == "admin" { - q = datastore.NewQuery("workflow").Filter("org_id =", user.ActiveOrg.Id) - log.Printf("[INFO] Getting workflows (ADMIN) for organization %s", user.ActiveOrg.Id) - } - - q = q.Order("-edited") - - var workflows []shuffle.Workflow - _, err = dbclient.GetAll(ctx, q, &workflows) - if err != nil { - if strings.Contains(fmt.Sprintf("%s", err), "ResourceExhausted") { - q = q.Limit(35) - _, err = dbclient.GetAll(ctx, q, &workflows) - if err != nil { - log.Printf("Failed getting workflows for user %s: %s (0)", user.Username, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - } else { - log.Printf("Failed getting workflows for user %s: %s (1)", user.Username, err) - //DeleteKey(ctx, "workflow", "5694357e-8063-4580-8529-301cc72df951") - - //log.Printf("Workflows: %#v", workflows) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - } - - if len(workflows) == 0 { - resp.WriteHeader(200) - resp.Write([]byte("[]")) - return - } - - newjson, err := json.Marshal(workflows) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking workflows"}`))) - return - } - - //item := &memcache.Item{ - // Key: memcacheName, - // Value: newjson, - // Expiration: time.Minute * 10, - //} - //if err := memcache.Add(ctx, item); err == memcache.ErrNotStored { - // if err := memcache.Set(ctx, item); err != nil { - // log.Printf("Error setting item: %v", err) - // } - //} else if err != nil { - // log.Printf("Error adding item: %v", err) - //} else { - // //log.Printf("Set cache for %s", item.Key) - //} - - resp.WriteHeader(200) - resp.Write(newjson) -} - func deleteWorkflow(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { @@ -1767,7 +1117,7 @@ func deleteWorkflow(resp http.ResponseWriter, request *http.Request) { user, err := shuffle.HandleApiAuthentication(resp, request) if err != nil { - log.Printf("Api authentication failed in deleting workflow: %s", err) + log.Printf("[WARNING] Api authentication failed in delete workflow: %s", err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -1795,18 +1145,21 @@ func deleteWorkflow(resp http.ResponseWriter, request *http.Request) { ctx := context.Background() workflow, err := shuffle.GetWorkflow(ctx, fileId) if err != nil { - log.Printf("Failed getting the workflow locally (delete workflow): %s", err) + log.Printf("[WARNING] Failed getting workflow %s locally (delete workflow): %s", fileId, err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return } - // FIXME - have a check for org etc too.. - if user.Id != workflow.Owner { - log.Printf("Wrong user (%s) for workflow %s", user.Username, workflow.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return + if user.Id != workflow.Owner || len(user.Id) == 0 { + if workflow.OrgId == user.ActiveOrg.Id && user.Role == "admin" { + log.Printf("[INFO] User %s is deleting workflow %s as admin. Owner: %s", user.Username, workflow.ID, workflow.Owner) + } else { + log.Printf("Wrong user (%s) for workflow %s", user.Username, workflow.ID) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } } // Clean up triggers and executions @@ -1828,30 +1181,29 @@ func deleteWorkflow(resp http.ResponseWriter, request *http.Request) { } } - err = increaseStatisticsField(ctx, "total_workflow_triggers", workflow.ID, -1, workflow.OrgId) - if err != nil { - log.Printf("Failed to increase total workflows: %s", err) - } + //err = increaseStatisticsField(ctx, "total_workflow_triggers", workflow.ID, -1, workflow.OrgId) + //if err != nil { + // log.Printf("Failed to increase total workflows: %s", err) + //} } // FIXME - maybe delete workflow executions - log.Printf("[INFO] Should have deleted workflow %s", fileId) - err = DeleteKey(ctx, "workflow", fileId) + err = shuffle.DeleteKey(ctx, "workflow", fileId) if err != nil { log.Printf("Failed deleting key %s", fileId) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "Failed deleting key"}`)) return } + log.Printf("[INFO] Should have deleted workflow %s", fileId) - //err = increaseStatisticsField(ctx, "total_workflows", fileId, -1, workflow.OrgId) - //if err != nil { - // log.Printf("Failed to increase total workflows: %s", err) - //} //memcacheName := fmt.Sprintf("%s_%s", user.Username, fileId) //memcache.Delete(ctx, memcacheName) //memcacheName = fmt.Sprintf("%s_workflows", user.Username) //memcache.Delete(ctx, memcacheName) + //cacheKey := fmt.Sprintf("%s_workflows", user.Id) + cacheKey := fmt.Sprintf("%s_workflows", user.Id) + shuffle.DeleteCache(ctx, cacheKey) resp.WriteHeader(200) resp.Write([]byte(`{"success": true}`)) @@ -1896,51 +1248,18 @@ func getWorkflowLocal(fileId string, request *http.Request) ([]byte, error) { //// New execution with firestore -func cleanupExecutions(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("[INFO] Api authentication failed in cleanup executions: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "message": "Not authenticated"}`)) - return - } - - if user.Role != "admin" { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "message": "Insufficient permissions"}`)) - return - } - - ctx := context.Background() - - // Removes three months from today - timestamp := int64(time.Now().AddDate(0, -2, 0).Unix()) - log.Println(timestamp) - q := datastore.NewQuery("workflowexecution").Filter("started_at <", timestamp) - var workflowExecutions []shuffle.WorkflowExecution - _, err = dbclient.GetAll(ctx, q, &workflowExecutions) - if err != nil { - log.Printf("Error getting workflowexec (cleanup): %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed getting all workflowexecutions"}`))) - return - } - - resp.WriteHeader(200) - resp.Write([]byte(`{"success": true}`)) -} - func handleExecution(id string, workflow shuffle.Workflow, request *http.Request) (shuffle.WorkflowExecution, string, error) { + //go func() { + // log.Printf("\n\nPRE TIME: %s\n\n", time.Now().Format("2006-01-02 15:04:05")) + // _ = <-time.After(time.Second * 60) + // log.Printf("\n\nPOST TIME: %s\n\n", time.Now().Format("2006-01-02 15:04:05")) + //}() + ctx := context.Background() if workflow.ID == "" || workflow.ID != id { tmpworkflow, err := shuffle.GetWorkflow(ctx, id) if err != nil { - log.Printf("Failed getting the workflow locally (execution cleanup): %s", err) + log.Printf("[WARNING] Failed getting the workflow locally (execution setup): %s", err) return shuffle.WorkflowExecution{}, "Failed getting workflow", err } @@ -2051,7 +1370,7 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request //log.Println(body) //if string(body)[0] == "\"" && string(body)[string(body) - log.Printf("Body: %s", string(body)) + log.Printf("[INFO] Body: %s", string(body)) } var execution shuffle.ExecutionRequest @@ -2076,25 +1395,26 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request } //log.Printf("Execution data: %#v", execution) - if len(execution.Start) == 36 { + if len(execution.Start) == 36 && len(workflow.Actions) > 0 { log.Printf("[INFO] Should start execution on node %s", execution.Start) workflowExecution.Start = execution.Start found := false for _, action := range workflow.Actions { - if action.ID == workflow.Start { + if action.ID == execution.Start { found = true + break } } if !found { - log.Printf("[ERROR] ACTION %s WAS NOT FOUND!", workflow.Start) + log.Printf("[ERROR] Action %s was NOT found! Exiting execution.", execution.Start) return shuffle.WorkflowExecution{}, fmt.Sprintf("Startnode %s was not found in actions", workflow.Start), errors.New(fmt.Sprintf("Startnode %s was not found in actions", workflow.Start)) } } else if len(execution.Start) > 0 { - - log.Printf("[ERROR] START ACTION %s IS WRONG ID LENGTH %d!", execution.Start, len(execution.Start)) - return shuffle.WorkflowExecution{}, fmt.Sprintf("Startnode %s was not found in actions", execution.Start), errors.New(fmt.Sprintf("Startnode %s was not found in actions", execution.Start)) + //log.Printf("[INFO] !") + //log.Printf("[ERROR] START ACTION %s IS WRONG ID LENGTH %d!", execution.Start, len(execution.Start)) + //return shuffle.WorkflowExecution{}, fmt.Sprintf("Startnode %s was not found in actions", execution.Start), errors.New(fmt.Sprintf("Startnode %s was not found in actions", execution.Start)) } if len(execution.ExecutionId) == 36 { @@ -2212,8 +1532,8 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request //workflowExecution.Stream = "tmp" //workflowExecution.WorkflowQueue = "tmp" //workflowExecution.SubscriptionNameNodestream = "testcompany-nodestream" + //workflowExecution.Locations = []string{"europe-west2"} workflowExecution.ProjectId = gceProject - workflowExecution.Locations = []string{"europe-west2"} workflowExecution.WorkflowId = workflow.ID workflowExecution.StartedAt = int64(time.Now().Unix()) workflowExecution.CompletedAt = 0 @@ -2244,12 +1564,12 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request //log.Println(string(mappedData)) - if len(workflowExecution.Start) == 0 { + if len(workflowExecution.Start) == 0 && len(workflowExecution.Workflow.Start) > 0 { workflowExecution.Start = workflowExecution.Workflow.Start } - log.Printf("[INFO] New startnode: %s", workflowExecution.Start) + //log.Printf("[INFO] New startnode: %s", workflowExecution.Start) - childNodes := findChildNodes(workflowExecution, workflowExecution.Start) + childNodes := shuffle.FindChildNodes(workflowExecution, workflowExecution.Start) topic := "workflows" startFound := false @@ -2367,7 +1687,8 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request } } - for _, trigger := range workflowExecution.Workflow.Triggers { + removeTriggers := []string{} + for triggerIndex, trigger := range workflowExecution.Workflow.Triggers { //log.Printf("[INFO] ID: %s vs %s", trigger.ID, workflowExecution.Start) if trigger.ID == workflowExecution.Start { if trigger.AppName == "User Input" { @@ -2406,17 +1727,113 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request Status: "SKIPPED", }) } else { - //log.Printf("SHOULD KEEP TRIGGER %s", trigger.ID) + // Replaces trigger with the subflow + //if trigger.AppName == "Shuffle Workflow" { + // replaceActions := false + // workflowAction := "" + // for _, param := range trigger.Parameters { + // if param.Name == "argument" && !strings.Contains(param.Value, ".#") { + // replaceActions = true + // } + + // if param.Name == "startnode" { + // workflowAction = param.Value + // } + // } + + // if replaceActions { + // replacementNodes, newBranches, lastnode := shuffle.GetReplacementNodes(ctx, workflowExecution, trigger, trigger.Label) + // log.Printf("REPLACEMENTS: %d, %d", len(replacementNodes), len(newBranches)) + // if len(replacementNodes) > 0 { + // for _, action := range replacementNodes { + // found := false + + // for subActionIndex, subaction := range newActions { + // if subaction.ID == action.ID { + // found = true + // //newActions[subActionIndex].Name = action.Name + // newActions[subActionIndex].Label = action.Label + // break + // } + // } + + // if !found { + // action.SubAction = true + // newActions = append(newActions, action) + // } + + // // Check if it's already set to have a value + // for resultIndex, result := range defaultResults { + // if result.Action.ID == action.ID { + // defaultResults = append(defaultResults[:resultIndex], defaultResults[resultIndex+1:]...) + // break + // } + // } + // } + + // for _, branch := range newBranches { + // workflowExecution.Workflow.Branches = append(workflowExecution.Workflow.Branches, branch) + // } + + // // Append branches: + // // parent -> new inner node (FIRST one) + // for branchIndex, branch := range workflowExecution.Workflow.Branches { + // if branch.DestinationID == trigger.ID { + // log.Printf("REPLACE DESTINATION WITH %s!!", workflowAction) + // workflowExecution.Workflow.Branches[branchIndex].DestinationID = workflowAction + // } + + // if branch.SourceID == trigger.ID { + // log.Printf("REPLACE SOURCE WITH LASTNODE %s!!", lastnode) + // workflowExecution.Workflow.Branches[branchIndex].SourceID = lastnode + // } + // } + + // // Remove the trigger + // removeTriggers = append(removeTriggers, workflowExecution.Workflow.Triggers[triggerIndex].ID) + // } + + // log.Printf("NEW ACTION LENGTH %d, RESULT: %d, Triggers: %d, BRANCHES: %d", len(newActions), len(defaultResults), len(workflowExecution.Workflow.Triggers), len(workflowExecution.Workflow.Branches)) + // } + //} + _ = triggerIndex } } } - //childNodes := findChildNodes(workflowExecution, workflowExecution.Start) + + //newTriggers := []shuffle.Trigger{} + //for _, trigger := range workflowExecution.Workflow.Triggers { + // found := false + // for _, triggerId := range removeTriggers { + // if trigger.ID == triggerId { + // found = true + // break + // } + // } + + // if found { + // log.Printf("[WARNING] Removed trigger %s during execution", trigger.ID) + // continue + // } + + // newTriggers = append(newTriggers, trigger) + //} + //workflowExecution.Workflow.Triggers = newTriggers + _ = removeTriggers if !startFound { - log.Printf("[ERROR] Startnode %s doesn't exist!!", workflowExecution.Start) - return shuffle.WorkflowExecution{}, fmt.Sprintf("Workflow action %s doesn't exist in workflow", workflowExecution.Start), errors.New(fmt.Sprintf(`Workflow start node "%s" doesn't exist. Exiting!`, workflowExecution.Start)) + if len(workflowExecution.Start) == 0 && len(workflowExecution.Workflow.Start) > 0 { + workflowExecution.Start = workflow.Start + } else if len(workflowExecution.Workflow.Actions) > 0 { + workflowExecution.Start = workflowExecution.Workflow.Actions[0].ID + } else { + log.Printf("[ERROR] Startnode %s doesn't exist!!", workflowExecution.Start) + return shuffle.WorkflowExecution{}, fmt.Sprintf("Workflow action %s doesn't exist in workflow", workflowExecution.Start), errors.New(fmt.Sprintf(`Workflow start node "%s" doesn't exist. Exiting!`, workflowExecution.Start)) + } } + //log.Printf("EXECUTION START: %s", workflowExecution.Start) + // Verification for execution environments workflowExecution.Results = defaultResults workflowExecution.Workflow.Actions = newActions @@ -2513,10 +1930,10 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request // //workflowExecution.ExecutionOrg.SyncFeatures = Org{} //} - workflowExecution.Workflow.ExecutingOrg = shuffle.Org{ + workflowExecution.Workflow.ExecutingOrg = shuffle.OrgMini{ Id: workflowExecution.Workflow.ExecutingOrg.Id, } - workflowExecution.Workflow.Org = []shuffle.Org{ + workflowExecution.Workflow.Org = []shuffle.OrgMini{ workflowExecution.Workflow.ExecutingOrg, } @@ -2552,7 +1969,7 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request //} //log.Printf("Execution request: %#v", executionRequest) - err = setWorkflowQueue(ctx, executionRequest, environment) + err = shuffle.SetWorkflowQueue(ctx, executionRequest, environment) if err != nil { log.Printf("[ERROR] Failed adding execution to db: %s", err) } @@ -2698,8 +2115,8 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) { //memcacheName := fmt.Sprintf("%s_%s", user.Username, fileId) ctx := context.Background() workflow, err := shuffle.GetWorkflow(ctx, fileId) - if err != nil { - log.Printf("Failed getting the workflow locally (execute workflow): %s", err) + if err != nil && workflow.ID == "" { + log.Printf("[WARNING] Failed getting the workflow locally (execute workflow): %s", err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -2708,15 +2125,19 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) { // FIXME - have a check for org etc too.. // FIXME - admin check like this? idk if user.Id != workflow.Owner && user.Role != "scheduler" && user.Role != fmt.Sprintf("workflow_%s", fileId) { - log.Printf("Wrong user (%s) for workflow %s (execute)", user.Username, workflow.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return + if workflow.OrgId == user.ActiveOrg.Id && user.Role == "admin" { + log.Printf("[INFO] Letting user %s execute %s because they're admin of the same org", user.Username, workflow.ID) + } else { + log.Printf("[WARNING] Wrong user (%s) for workflow %s (execute)", user.Username, workflow.ID) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } } log.Printf("[INFO] Starting execution of %s!", fileId) - user.ActiveOrg.Users = []shuffle.User{} + user.ActiveOrg.Users = []shuffle.UserMini{} workflow.ExecutingOrg = user.ActiveOrg workflowExecution, executionResp, err := handleExecution(fileId, *workflow, request) @@ -2780,15 +2201,30 @@ func stopSchedule(resp http.ResponseWriter, request *http.Request) { return } - // FIXME - have a check for org etc too.. - // FIXME - admin check like this? idk if user.Id != workflow.Owner && user.Role != "scheduler" { - log.Printf("[WARNING] Wrong user (%s) for workflow %s (stop schedule)", user.Username, workflow.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return + if workflow.OrgId == user.ActiveOrg.Id && user.Role == "admin" { + log.Printf("[DEBUG] User %s is accessing workflow %s as admin", user.Username, workflow.ID) + } else { + log.Printf("[WARNING] Wrong user (%s) for workflow %s (stop schedule)", user.Username, workflow.ID) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } } + //if user.Id != workflow.Owner || len(user.Id) == 0 { + // if workflow.OrgId == user.ActiveOrg.Id && user.Role == "admin" { + // log.Printf("[INFO] User %s is accessing workflow %s as admin", user.Username, workflow.ID) + // } else if workflow.Public { + // log.Printf("[INFO] Letting user %s access workflow %s because it's public", user.Username, workflow.ID) + // } else { + // log.Printf("[WARNING] Wrong user (%s) for workflow %s (get workflow)", user.Username, workflow.ID) + // resp.WriteHeader(401) + // resp.Write([]byte(`{"success": false}`)) + // return + // } + //} + schedule, err := shuffle.GetSchedule(ctx, scheduleId) if err != nil { log.Printf("[WARNING] Failed finding schedule %s", scheduleId) @@ -2826,7 +2262,7 @@ func stopSchedule(resp http.ResponseWriter, request *http.Request) { return } else { log.Printf("[INFO] Successfully ran cloud action STOP schedule") - err = DeleteKey(ctx, "schedules", scheduleId) + err = shuffle.DeleteKey(ctx, "schedules", scheduleId) if err != nil { log.Printf("[WARNING] Failed deleting cloud schedule onprem..") resp.WriteHeader(401) @@ -2949,7 +2385,7 @@ func stopScheduleGCP(resp http.ResponseWriter, request *http.Request) { func deleteSchedule(ctx context.Context, id string) error { log.Printf("Should stop schedule %s!", id) - err := DeleteKey(ctx, "schedules", id) + err := shuffle.DeleteKey(ctx, "schedules", id) if err != nil { log.Printf("Failed to delete schedule: %s", err) return err @@ -2967,26 +2403,6 @@ func deleteSchedule(ctx context.Context, id string) error { return nil } -func deleteScheduleGCP(ctx context.Context, id string) error { - c, err := scheduler.NewCloudSchedulerClient(ctx) - if err != nil { - log.Printf("%s", err) - return err - } - - req := &schedulerpb.DeleteJobRequest{ - Name: fmt.Sprintf("projects/%s/locations/europe-west2/jobs/schedule_%s", gceProject, id), - } - - err = c.DeleteJob(ctx, req) - if err != nil { - log.Printf("%s", err) - return err - } - - return nil -} - func scheduleWorkflow(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { @@ -3023,7 +2439,7 @@ func scheduleWorkflow(resp http.ResponseWriter, request *http.Request) { ctx := context.Background() workflow, err := shuffle.GetWorkflow(ctx, fileId) if err != nil { - log.Printf("Failed getting the workflow locally (schedule workflow): %s", err) + log.Printf("[WARNING] Failed getting the workflow locally (schedule workflow): %s", err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -3144,7 +2560,7 @@ func scheduleWorkflow(resp http.ResponseWriter, request *http.Request) { } timeNow := int64(time.Now().Unix()) - newSchedule := ScheduleOld{ + newSchedule := shuffle.ScheduleOld{ Id: schedule.Id, WorkflowId: workflow.ID, StartNode: startNode, @@ -3158,7 +2574,7 @@ func scheduleWorkflow(resp http.ResponseWriter, request *http.Request) { Environment: "cloud", } - err = setSchedule(ctx, newSchedule) + err = shuffle.SetSchedule(ctx, newSchedule) if err != nil { log.Printf("Failed setting cloud schedule: %s", err) resp.WriteHeader(401) @@ -3229,275 +2645,6 @@ func setExampleresult(ctx context.Context, result shuffle.AppExecutionExample) e return nil } -// FIXME: Not suitable for cloud right now :O -func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - user, userErr := shuffle.HandleApiAuthentication(resp, request) - if userErr != nil { - log.Printf("Api authentication failed in edit workflow: %s", userErr) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - location := strings.Split(request.URL.String(), "/") - log.Printf("%#v", location) - var fileId string - if location[1] == "api" { - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - fileId = location[4] - } - - ctx := context.Background() - log.Printf("ID: %s", fileId) - app, err := shuffle.GetApp(ctx, fileId, user) - if err != nil { - log.Printf("Error getting app (delete) %s: %s", fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - // FIXME - check whether it's in use and maybe restrict again for later? - // FIXME - actually delete other than private apps too.. - private := false - if app.Downloaded && user.Role == "admin" { - log.Printf("[INFO] Deleting downloaded app (authenticated users can do this)") - } else if user.Id != app.Owner { - log.Printf("[WARNING] Wrong user (%s) for app %s (delete)", user.Username, app.Name) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } else { - log.Printf("[WARNING] App to be deleted is private") - private = true - } - - // FIXME: Make workflows track themself INSIDE apps, or with a reference - q := datastore.NewQuery("workflow").Filter("org_id = ", user.ActiveOrg.Id).Limit(30) - var workflows []shuffle.Workflow - _, err = dbclient.GetAll(ctx, q, &workflows) - if err != nil { - log.Printf("[WARNING] Failed getting related workflows for the app: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) - return - } - - // Finds workflows using the app to set errors - // FIXME: this will be WAY too big for cloud :O - for _, workflow := range workflows { - found := false - - newActions := []shuffle.Action{} - for _, action := range workflow.Actions { - if action.AppName == app.Name && action.AppVersion == app.AppVersion { - found = true - action.Errors = append(action.Errors, "App has been deleted") - action.IsValid = false - } - - newActions = append(newActions, action) - } - - if found { - workflow.IsValid = false - workflow.Errors = append(workflow.Errors, fmt.Sprintf("App %s_%s has been deleted", app.Name, app.AppVersion)) - workflow.Actions = newActions - - for _, trigger := range workflow.Triggers { - _ = trigger - //log.Printf("TRIGGER: %#v", trigger) - //err = deleteSchedule(ctx, scheduleId) - //if err != nil { - // if strings.Contains(err.Error(), "Job not found") { - // resp.WriteHeader(200) - // resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) - // } else { - // resp.WriteHeader(401) - // resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed stopping schedule"}`))) - // } - // return - //} - } - - err = shuffle.SetWorkflow(ctx, workflow, workflow.ID) - if err != nil { - log.Printf("Failed setting workflow when deleting app: %s", err) - continue - } else { - log.Printf("Set %s (%s) to have errors", workflow.ID, workflow.Name) - } - - } - - } - - //resp.WriteHeader(200) - //resp.Write([]byte(`{"success": true}`)) - //return - - // Not really deleting it, just removing from user cache - if private { - log.Printf("[INFO] Deleting private app") - var privateApps []shuffle.WorkflowApp - for _, item := range user.PrivateApps { - if item.ID == fileId { - continue - } - - privateApps = append(privateApps, item) - } - - user.PrivateApps = privateApps - err = shuffle.SetUser(ctx, &user) - if err != nil { - log.Printf("[ERROR] Failed removing %s app for user %s: %s", app.Name, user.Username, err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": true"}`))) - return - } - } - - log.Printf("[INFO] Deleting public app") - err = DeleteKey(ctx, "workflowapp", fileId) - if err != nil { - log.Printf("Failed deleting workflowapp") - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed deleting workflow app"}`))) - return - } - - err = increaseStatisticsField(ctx, "total_apps_deleted", fileId, 1, user.ActiveOrg.Id) - if err != nil { - log.Printf("Failed to increase total apps loaded stats: %s", err) - } - cacheKey := fmt.Sprintf("workflowapps-sorted-100") - shuffle.DeleteCache(ctx, cacheKey) - cacheKey = fmt.Sprintf("workflowapps-sorted-500") - shuffle.DeleteCache(ctx, cacheKey) - - //err = memcache.Delete(request.Context(), sessionToken) - resp.WriteHeader(200) - resp.Write([]byte(`{"success": true}`)) -} - -func getWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - ctx := context.Background() - - location := strings.Split(request.URL.String(), "/") - var fileId string - if location[1] == "api" { - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - fileId = location[4] - } - - app, err := shuffle.GetApp(ctx, fileId, shuffle.User{}) - if err != nil { - log.Printf("[WARNING] Error getting app %s (app config): %s", fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "App doesn't exist"}`)) - return - } - - //if IsValid bool `json:"is_valid" yaml:"is_valid" required:true datastore:"is_valid"` - // Sharing bool `json:"sharing" yaml:"sharing" required:false datastore:"sharing"` - //log.Printf("Sharing: %s", app.Sharing) - //log.Printf("Generated: %s", app.Generated) - //log.Printf("Downloaded: %s", app.Downloaded) - - // FIXME - Handle sharing and such PROPERLY - if app.Sharing && app.Generated { - log.Printf("CAN SHARE APP!") - parsedApi, err := getOpenApiDatastore(ctx, fileId) - if err != nil { - log.Printf("[WARNING] OpenApi doesn't exist for: %s - err: %s", fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - if len(parsedApi.ID) > 0 { - parsedApi.Success = true - } else { - parsedApi.Success = false - } - - //log.Printf("PARSEDAPI: %#v", parsedApi) - data, err := json.Marshal(parsedApi) - if err != nil { - log.Printf("[WARNING] Error parsing api json: %s", err) - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed marshalling new parsed swagger: %s"}`, err))) - return - } - - resp.WriteHeader(200) - resp.Write(data) - return - } - - user, userErr := shuffle.HandleApiAuthentication(resp, request) - if userErr != nil { - log.Printf("[WARNING] Api authentication failed in get app: %s", userErr) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - if user.Id != app.Owner { - log.Printf("[WARNING] Wrong user (%s) for app %s", user.Username, app.Name) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - log.Printf("[INFO] Getting app %s (OpenAPI)", fileId) - parsedApi, err := getOpenApiDatastore(ctx, fileId) - if err != nil { - log.Printf("OpenApi doesn't exist for: %s - err: %s", fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - //log.Printf("Parsed API: %#v", parsedApi) - if len(parsedApi.ID) > 0 { - parsedApi.Success = true - } else { - parsedApi.Success = false - } - - data, err := json.Marshal(parsedApi) - if err != nil { - resp.WriteHeader(422) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed marshalling new parsed swagger: %s"}`, err))) - return - } - - resp.WriteHeader(200) - resp.Write(data) -} - func getWorkflowApps(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { @@ -3520,87 +2667,15 @@ func getWorkflowApps(resp http.ResponseWriter, request *http.Request) { //return } - //if item, err := memcache.Get(ctx, memcacheName); err == memcache.ErrCacheMiss { - // // Not in cache - // log.Printf("Apps not in cache.") - //} else if err != nil { - // log.Printf("Error getting item: %v", err) - //} else { - // // FIXME - verify if value is ok? Can unmarshal etc. - // allApps := item.Value - - // if userErr == nil && len(user.PrivateApps) > 0 { - // var parsedApps []WorkflowApp - // err = json.Unmarshal(allApps, &parsedApps) - // if err == nil { - // log.Printf("Shouldve added %d apps", len(user.PrivateApps)) - // user.PrivateApps = append(user.PrivateApps, parsedApps...) - - // tmpApps, err := json.Marshal(user.PrivateApps) - // if err == nil { - // allApps = tmpApps - // } - // } - // } - - // resp.WriteHeader(200) - // resp.Write(allApps) - // return - //} - - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 500) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) if err != nil { log.Printf("Failed getting apps (getworkflowapps): %s", err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return } - //log.Printf("Length: %d", len(workflowapps)) - - // FIXME - this is really garbage, but is here to protect again null values etc. newapps := workflowapps - /* - skipApps := []string{"Shuffle Subflow"} - newapps := []WorkflowApp{} - baseApps := []WorkflowApp{} - for _, workflowapp := range workflowapps { - //if !workflowapp.Activated && workflowapp.Generated { - // continue - //} - - if workflowapp.Owner != user.Id && user.Role != "admin" && !workflowapp.Sharing { - continue - } - - continueOuter := false - for _, skip := range skipApps { - if workflowapp.Name == skip { - continueOuter = true - break - } - } - - if continueOuter { - continue - } - - //workflowapp.Environment = "cloud" - newactions := []WorkflowAppAction{} - for _, action := range workflowapp.Actions { - //action.Environment = workflowapp.Environment - if len(action.Parameters) == 0 { - action.Parameters = []WorkflowAppActionParameter{} - } - - newactions = append(newactions, action) - } - - workflowapp.Actions = newactions - newapps = append(newapps, workflowapp) - baseApps = append(baseApps, workflowapp) - } - */ if len(user.PrivateApps) > 0 { found := false @@ -3620,7 +2695,6 @@ func getWorkflowApps(resp http.ResponseWriter, request *http.Request) { // Double unmarshal because of user apps newbody, err := json.Marshal(newapps) - //newbody, err := json.Marshal(workflowapps) if err != nil { log.Printf("Failed unmarshalling all newapps: %s", err) resp.WriteHeader(401) @@ -3628,33 +2702,6 @@ func getWorkflowApps(resp http.ResponseWriter, request *http.Request) { return } - //basebody, err := json.Marshal(baseApps) - ////newbody, err := json.Marshal(workflowapps) - //if err != nil { - // log.Printf("Failed unmarshalling all baseapps: %s", err) - // resp.WriteHeader(401) - // resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking workflow apps"}`))) - // return - //} - - // Refreshed every hour - //item := &memcache.Item{ - // Key: memcacheName, - // Value: basebody, - // Expiration: time.Minute * 60, - //} - //if err := memcache.Add(ctx, item); err == memcache.ErrNotStored { - // if err := memcache.Set(ctx, item); err != nil { - // log.Printf("Error setting item: %v", err) - // } - //} else if err != nil { - // log.Printf("error adding item: %v", err) - //} else { - // log.Printf("Set cache for %s", item.Key) - //} - - //log.Println(string(body)) - //log.Println(string(newbody)) resp.WriteHeader(200) resp.Write(newbody) } @@ -3741,7 +2788,7 @@ func getSpecificApps(resp http.ResponseWriter, request *http.Request) { // FIXME - continue the search here with github repos etc. // Caching might be smart :D ctx := context.Background() - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 500) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) if err != nil { log.Printf("Error: Failed getting workflowapps: %s", err) resp.WriteHeader(401) @@ -3828,151 +2875,6 @@ func validateAppInput(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) } -// Deploy to google cloud function :) -func deployCloudFunctionPython(ctx context.Context, name, localization, applocation string, environmentVariables map[string]string) error { - service, err := cloudfunctions.NewService(ctx) - if err != nil { - return err - } - - // ProjectsLocationsListCall - projectsLocationsFunctionsService := cloudfunctions.NewProjectsLocationsFunctionsService(service) - location := fmt.Sprintf("projects/%s/locations/%s", gceProject, localization) - functionName := fmt.Sprintf("%s/functions/%s", location, name) - - cloudFunction := &cloudfunctions.CloudFunction{ - AvailableMemoryMb: 128, - EntryPoint: "authorization", - EnvironmentVariables: environmentVariables, - HttpsTrigger: &cloudfunctions.HttpsTrigger{}, - MaxInstances: 0, - Name: functionName, - Runtime: "python37", - SourceArchiveUrl: applocation, - } - - //getCall := projectsLocationsFunctionsService.Get(fmt.Sprintf("%s/functions/function-5", location)) - //resp, err := getCall.Do() - - createCall := projectsLocationsFunctionsService.Create(location, cloudFunction) - _, err = createCall.Do() - if err != nil { - log.Printf("Failed creating new function. SKIPPING patch, as it probably already exists: %s", err) - - // FIXME - have patching code or nah? - createCall := projectsLocationsFunctionsService.Patch(fmt.Sprintf("%s/functions/%s", location, name), cloudFunction) - _, err = createCall.Do() - if err != nil { - log.Println("Failed patching function") - return err - } - - log.Printf("Successfully patched %s to %s", name, localization) - } else { - log.Printf("Successfully deployed %s to %s", name, localization) - } - - // FIXME - use response to define the HTTPS entrypoint. It's default to an easy one tho - - return nil -} - -// Deploy to google cloud function :) -func deployCloudFunctionGo(ctx context.Context, name, localization, applocation string, environmentVariables map[string]string) error { - service, err := cloudfunctions.NewService(ctx) - if err != nil { - return err - } - - // ProjectsLocationsListCall - projectsLocationsFunctionsService := cloudfunctions.NewProjectsLocationsFunctionsService(service) - location := fmt.Sprintf("projects/%s/locations/%s", gceProject, localization) - functionName := fmt.Sprintf("%s/functions/%s", location, name) - - cloudFunction := &cloudfunctions.CloudFunction{ - AvailableMemoryMb: 128, - EntryPoint: "Authorization", - EnvironmentVariables: environmentVariables, - HttpsTrigger: &cloudfunctions.HttpsTrigger{}, - MaxInstances: 1, - Name: functionName, - Runtime: "go111", - SourceArchiveUrl: applocation, - } - - //getCall := projectsLocationsFunctionsService.Get(fmt.Sprintf("%s/functions/function-5", location)) - //resp, err := getCall.Do() - - createCall := projectsLocationsFunctionsService.Create(location, cloudFunction) - _, err = createCall.Do() - if err != nil { - log.Println("Failed creating new function. Attempting patch, as it might exist already") - - createCall := projectsLocationsFunctionsService.Patch(fmt.Sprintf("%s/functions/%s", location, name), cloudFunction) - _, err = createCall.Do() - if err != nil { - log.Println("Failed patching function") - return err - } - - log.Printf("Successfully patched %s to %s", name, localization) - } else { - log.Printf("Successfully deployed %s to %s", name, localization) - } - - // FIXME - use response to define the HTTPS entrypoint. It's default to an easy one tho - - return nil -} - -// Deploy to google cloud function :) -func deployWebhookFunction(ctx context.Context, name, localization, applocation string, environmentVariables map[string]string) error { - service, err := cloudfunctions.NewService(ctx) - if err != nil { - return err - } - - // ProjectsLocationsListCall - projectsLocationsFunctionsService := cloudfunctions.NewProjectsLocationsFunctionsService(service) - location := fmt.Sprintf("projects/%s/locations/%s", gceProject, localization) - functionName := fmt.Sprintf("%s/functions/%s", location, name) - - cloudFunction := &cloudfunctions.CloudFunction{ - AvailableMemoryMb: 128, - EntryPoint: "Authorization", - EnvironmentVariables: environmentVariables, - HttpsTrigger: &cloudfunctions.HttpsTrigger{}, - MaxInstances: 1, - Name: functionName, - Runtime: "go111", - SourceArchiveUrl: applocation, - } - - //getCall := projectsLocationsFunctionsService.Get(fmt.Sprintf("%s/functions/function-5", location)) - //resp, err := getCall.Do() - - createCall := projectsLocationsFunctionsService.Create(location, cloudFunction) - _, err = createCall.Do() - if err != nil { - log.Println("Failed creating new function. Attempting patch, as it might exist already") - - createCall := projectsLocationsFunctionsService.Patch(fmt.Sprintf("%s/functions/%s", location, name), cloudFunction) - _, err = createCall.Do() - if err != nil { - log.Println("Failed patching function") - return err - } - - log.Printf("Successfully patched %s to %s", name, localization) - } else { - log.Printf("Successfully deployed %s to %s", name, localization) - } - - // FIXME - use response to define the HTTPS entrypoint. It's default to an easy one tho - - return nil -} - func loadGithubWorkflows(url, username, password, userId, branch, orgId string) error { fs := memfs.New() @@ -4104,10 +3006,12 @@ func handleAppHotloadRequest(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - cacheKey := fmt.Sprintf("workflowapps-sorted-100") + cacheKey := fmt.Sprintf("workflowapps-sorted-1000") shuffle.DeleteCache(ctx, cacheKey) cacheKey = fmt.Sprintf("workflowapps-sorted-500") shuffle.DeleteCache(ctx, cacheKey) + cacheKey = fmt.Sprintf("workflowapps-sorted-0") + shuffle.DeleteCache(ctx, cacheKey) // Just need to be logged in // FIXME - should have some permissions? @@ -4145,6 +3049,8 @@ func handleAppHotloadRequest(resp http.ResponseWriter, request *http.Request) { shuffle.DeleteCache(ctx, cacheKey) cacheKey = fmt.Sprintf("workflowapps-sorted-500") shuffle.DeleteCache(ctx, cacheKey) + cacheKey = fmt.Sprintf("workflowapps-sorted-1000") + shuffle.DeleteCache(ctx, cacheKey) resp.WriteHeader(200) resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) @@ -4160,7 +3066,7 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { // FIXME - should have some permissions? _, err := shuffle.HandleApiAuthentication(resp, request) if err != nil { - log.Printf("Api authentication failed in load specific apps: %s", err) + log.Printf("[WARNING] Api authentication failed in load specific apps: %s", err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false}`)) return @@ -4230,9 +3136,9 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { _ = r if tmpBody.ForceUpdate { - log.Printf("Running with force update!") + log.Printf("[INFO] Running with force update!") } else { - log.Printf("Updating apps with updates") + log.Printf("[INFO] Updating apps with updates (no force)") } if tmpBody.ForceUpdate { @@ -4277,6 +3183,8 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { shuffle.DeleteCache(ctx, cacheKey) cacheKey = fmt.Sprintf("workflowapps-sorted-500") shuffle.DeleteCache(ctx, cacheKey) + cacheKey = fmt.Sprintf("workflowapps-sorted-1000") + shuffle.DeleteCache(ctx, cacheKey) resp.WriteHeader(200) resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) @@ -4285,7 +3193,7 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string) error { ctx := context.Background() - workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 500) + workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) appCounter := 0 if err != nil { log.Printf("Failed to get existing generated apps") @@ -4344,14 +3252,14 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, readFile, err := ioutil.ReadAll(fileReader) if err != nil { - log.Printf("Filereader error yaml for %s: %s", filename, err) + log.Printf("[WARNING] Filereader error yaml for %s: %s", filename, err) continue } // 1. This parses OpenAPI v2 to v3 etc, for use. parsedOpenApi, err := handleSwaggerValidation(readFile) if err != nil { - log.Printf("Validation error for %s: %s", filename, err) + log.Printf("[WARNING] Validation error for %s: %s", filename, err) continue } @@ -4363,7 +3271,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, //log.Printf("%s", string(readFile)) swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData([]byte(parsedOpenApi.Body)) if err != nil { - log.Printf("Swagger validation error in loop (%s): %s", filename, err) + log.Printf("[WARNING] Swagger validation error in loop (%s): %s. Continuing.", filename, err) continue } @@ -4374,7 +3282,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, //log.Printf("Should generate yaml") swagger, api, _, err := shuffle.GenerateYaml(swagger, parsedOpenApi.ID) if err != nil { - log.Printf("Failed building and generating yaml in loop (%s): %s", filename, err) + log.Printf("Failed building and generating yaml in loop (2) (%s): %s. Continuing.", filename, err) continue } @@ -4399,14 +3307,14 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, if !found { err = shuffle.SetWorkflowAppDatastore(ctx, api, api.ID) if err != nil { - log.Printf("Failed setting workflowapp in loop: %s", err) + log.Printf("[WARNING] Failed setting workflowapp in loop: %s", err) continue } else { appCounter += 1 - log.Printf("Added %s:%s to the database from OpenAPI repo", api.Name, api.AppVersion) + log.Printf("[INFO] Added %s:%s to the database from OpenAPI repo", api.Name, api.AppVersion) // Set OpenAPI datastore - err = setOpenApiDatastore(ctx, parsedOpenApi.ID, parsedOpenApi) + err = shuffle.SetOpenApiDatastore(ctx, parsedOpenApi.ID, parsedOpenApi) if err != nil { log.Printf("Failed uploading openapi to datastore in loop: %s", err) continue @@ -4416,6 +3324,8 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string, shuffle.DeleteCache(ctx, cacheKey) cacheKey = fmt.Sprintf("workflowapps-sorted-500") shuffle.DeleteCache(ctx, cacheKey) + cacheKey = fmt.Sprintf("workflowapps-sorted-1000") + shuffle.DeleteCache(ctx, cacheKey) } } else { //log.Printf("Skipped upload of %s (%s)", api.Name, api.ID) @@ -4502,11 +3412,11 @@ func iterateWorkflowGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra workflow.ID = uuid.NewV4().String() workflow.OrgId = orgId - workflow.ExecutingOrg = shuffle.Org{ + workflow.ExecutingOrg = shuffle.OrgMini{ Id: orgId, } - workflow.Org = append(workflow.Org, shuffle.Org{ + workflow.Org = append(workflow.Org, shuffle.OrgMini{ Id: orgId, }) workflow.IsValid = false @@ -4638,20 +3548,20 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin appPython := fmt.Sprintf("%s/src/app.py", extra) appPythonReader, err := fs.Open(appPython) if err != nil { - log.Printf("Failed to read %s", appPython) + log.Printf("Failed to read python app %s", appPython) continue } appPythonData, err := ioutil.ReadAll(appPythonReader) if err != nil { - log.Printf("Failed reading %s: %s", appPython, err) + log.Printf("Failed reading appdata %s: %s", appPython, err) continue } dockerFp := fmt.Sprintf("%s/Dockerfile", extra) dockerfile, err := fs.Open(dockerFp) if err != nil { - log.Printf("Failed to read %s", appPython) + log.Printf("Failed to read dockerfil %s", appPython) continue } @@ -4683,9 +3593,9 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin } if len(allapps) == 0 { - allapps, err = shuffle.GetAllWorkflowApps(ctx, 500) + allapps, err = shuffle.GetAllWorkflowApps(ctx, 0) if err != nil { - log.Printf("Failed getting apps to verify: %s", err) + log.Printf("[WARNING] Failed getting apps to verify: %s", err) continue } } @@ -4714,7 +3624,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin // Fixes (appends) authentication parameters if they're required if workflowapp.Authentication.Required { - log.Printf("[INFO] Checking authentication fields and appending for %s!", workflowapp.Name) + //log.Printf("[INFO] Checking authentication fields and appending for %s!", workflowapp.Name) // FIXME: // Might require reflection into the python code to append the fields as well for index, action := range workflowapp.Actions { @@ -4753,7 +3663,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin } if len(appendParams) > 0 { - log.Printf("[AUTH] Appending %d params to the START of %s", len(appendParams), action.Name) + //log.Printf("[AUTH] Appending %d params to the START of %s", len(appendParams), action.Name) workflowapp.Actions[index].Parameters = append(appendParams, workflowapp.Actions[index].Parameters...) } @@ -4762,14 +3672,14 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin err = checkWorkflowApp(workflowapp) if err != nil { - log.Printf("%s for app %s:%s", err, workflowapp.Name, workflowapp.AppVersion) + log.Printf("[DEBUG] %s for app %s:%s", err, workflowapp.Name, workflowapp.AppVersion) continue } if len(removeApps) > 0 { for _, item := range removeApps { log.Printf("[WARNING] Removing duplicate app: %s", item) - err = DeleteKey(ctx, "workflowapp", item) + err = shuffle.DeleteKey(ctx, "workflowapp", item) if err != nil { log.Printf("[ERROR] Failed deleting duplicate %s: %s", item, err) } @@ -4786,7 +3696,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin err = shuffle.SetWorkflowAppDatastore(ctx, workflowapp, workflowapp.ID) if err != nil { - log.Printf("Failed setting workflowapp: %s", err) + log.Printf("[WARNING] Failed setting workflowapp in intro: %s", err) continue } @@ -4840,6 +3750,8 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin shuffle.DeleteCache(ctx, cacheKey) cacheKey = fmt.Sprintf("workflowapps-sorted-500") shuffle.DeleteCache(ctx, cacheKey) + cacheKey = fmt.Sprintf("workflowapps-sorted-1000") + shuffle.DeleteCache(ctx, cacheKey) //log.Printf("BUILDLATERFIRST: %d, BUILDLATERLIST: %d", len(buildLaterFirst), len(buildLaterList)) if len(extra) == 0 { @@ -4910,7 +3822,7 @@ func setNewWorkflowApp(resp http.ResponseWriter, request *http.Request) { } ctx := context.Background() - allapps, err := shuffle.GetAllWorkflowApps(ctx, 500) + allapps, err := shuffle.GetAllWorkflowApps(ctx, 1000) if err != nil { log.Printf("Failed getting apps to verify: %s", err) resp.WriteHeader(401) @@ -4946,6 +3858,54 @@ func setNewWorkflowApp(resp http.ResponseWriter, request *http.Request) { // workflowapp.Environment = baseEnvironment //} + // Fixes (appends) authentication parameters if they're required + if workflowapp.Authentication.Required { + //log.Printf("[INFO] Checking authentication fields and appending for %s!", workflowapp.Name) + // FIXME: + // Might require reflection into the python code to append the fields as well + for index, action := range workflowapp.Actions { + if action.AuthNotRequired { + log.Printf("Skipping auth setup: %s", action.Name) + continue + } + + // 1. Check if authentication params exists at all + // 2. Check if they're present in the action + // 3. Add them IF they DONT exist + // 4. Fix python code with reflection (FIXME) + appendParams := []shuffle.WorkflowAppActionParameter{} + for _, fieldname := range workflowapp.Authentication.Parameters { + found := false + for index, param := range action.Parameters { + if param.Name == fieldname.Name { + found = true + + action.Parameters[index].Configuration = true + //log.Printf("Set config to true for field %s!", param.Name) + break + } + } + + if !found { + appendParams = append(appendParams, shuffle.WorkflowAppActionParameter{ + Name: fieldname.Name, + Description: fieldname.Description, + Example: fieldname.Example, + Required: fieldname.Required, + Configuration: true, + Schema: fieldname.Schema, + }) + } + } + + if len(appendParams) > 0 { + //log.Printf("[AUTH] Appending %d params to the START of %s", len(appendParams), action.Name) + workflowapp.Actions[index].Parameters = append(appendParams, workflowapp.Actions[index].Parameters...) + } + + } + } + workflowapp.ID = uuid.NewV4().String() workflowapp.IsValid = true workflowapp.Generated = false @@ -4958,572 +3918,20 @@ func setNewWorkflowApp(resp http.ResponseWriter, request *http.Request) { resp.Write([]byte(`{"success": false}`)) return } else { - log.Printf("Added %s:%s to the database", workflowapp.Name, workflowapp.AppVersion) + log.Printf("[INFO] Added %s:%s to the database", workflowapp.Name, workflowapp.AppVersion) } cacheKey := fmt.Sprintf("workflowapps-sorted-100") shuffle.DeleteCache(ctx, cacheKey) cacheKey = fmt.Sprintf("workflowapps-sorted-500") shuffle.DeleteCache(ctx, cacheKey) + cacheKey = fmt.Sprintf("workflowapps-sorted-1000") + shuffle.DeleteCache(ctx, cacheKey) resp.WriteHeader(200) resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) } -func getWorkflowExecutions(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in getting specific workflow: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - location := strings.Split(request.URL.String(), "/") - - var fileId string - if location[1] == "api" { - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - fileId = location[4] - } - - if len(fileId) != 36 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Workflow ID when getting workflow executions is not valid"}`)) - return - } - - ctx := context.Background() - workflow, err := shuffle.GetWorkflow(ctx, fileId) - if err != nil { - log.Printf("Failed getting the workflow %s locally (get executions): %s", fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - // FIXME - have a check for org etc too.. - if user.Id != workflow.Owner { - log.Printf("Wrong user (%s) for workflow %s (get execution)", user.Username, workflow.ID) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - // Query for the specifci workflowId - maxAmount := 30 - q := datastore.NewQuery("workflowexecution").Filter("workflow_id =", fileId).Order("-started_at").Limit(maxAmount) - var workflowExecutions []shuffle.WorkflowExecution - _, err = dbclient.GetAll(ctx, q, &workflowExecutions) - if err != nil { - - if strings.Contains(fmt.Sprintf("%s", err), "ResourceExhausted") { - q = datastore.NewQuery("workflowexecution").Filter("workflow_id =", fileId).Order("-started_at").Limit(1) - /* - _, err = dbclient.GetAll(ctx, q, &workflowExecutions) - if err != nil { - log.Printf("Error getting workflowexec (2): %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed getting all workflowexecutions for %s"}`, fileId))) - return - } - */ - - cursorStr := "" - for { - it := dbclient.Run(ctx, q) - //_, err = it.Next(&app) - for { - var workflowExecution shuffle.WorkflowExecution - _, err := it.Next(&workflowExecution) - if err != nil { - break - } - - workflowExecutions = append(workflowExecutions, workflowExecution) - } - - //log.Printf("Len: %d", len(workflowExecutions)) - if len(workflowExecutions) > maxAmount { - break - } - - nextCursor, err := it.Cursor() - if err != iterator.Done && err != nil { - if strings.Contains(fmt.Sprintf("%s", err), "ResourceExhausted") { - //log.Printf("NEXT!") - nextStr := fmt.Sprintf("%s", nextCursor) - if cursorStr == nextStr { - break - } - - cursorStr = nextStr - - continue - } else { - log.Printf("BREAK: %s", err) - break - } - } - - if err != nil { - if strings.Contains(fmt.Sprintf("%s", err), "ResourceExhausted") { - log.Printf("[WARNING] Cursorerror in app grab WARNING: %s", err) - } else { - log.Printf("[ERROR] Cursorerror in app grab: %s", err) - break - } - } else { - //log.Printf("NEXTCURSOR: %s", nextCursor) - nextStr := fmt.Sprintf("%s", nextCursor) - if cursorStr == nextStr { - break - } - - cursorStr = nextStr - q = q.Start(nextCursor) - //cursorStr = nextCursor - //break - } - } - } else { - log.Printf("Error getting workflowexec: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed getting all workflowexecutions for %s"}`, fileId))) - return - } - } - - if len(workflowExecutions) == 0 { - resp.WriteHeader(200) - resp.Write([]byte("[]")) - return - } - - newjson, err := json.Marshal(workflowExecutions) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking workflow executions"}`))) - return - } - - resp.WriteHeader(200) - resp.Write(newjson) -} - -func getAllSchedules(ctx context.Context, orgId string) ([]ScheduleOld, error) { - var schedules []ScheduleOld - - q := datastore.NewQuery("schedules").Filter("org = ", orgId) - if orgId == "ALL" { - q = datastore.NewQuery("schedules") - } - - _, err := dbclient.GetAll(ctx, q, &schedules) - if err != nil { - return []ScheduleOld{}, err - } - - return schedules, nil -} - -//FIXME: Add cursor -//func shuffle.GetAllWorkflowApps(ctx context.Context, maxLen int) ([]shuffle.WorkflowApp, error) { -// var apps []WorkflowApp -// query := datastore.NewQuery("workflowapp").Order("-edited").Limit(10) -// //query := datastore.NewQuery("workflowapp").Order("-edited").Limit(40) -// -// cacheKey := fmt.Sprintf("workflowapps-sorted-%d", maxLen) -// if value, found := requestCache.Get(cacheKey); found { -// parsedValue := value.(*[]WorkflowApp) -// log.Printf("[INFO] Returning %d apps from cache", len(*parsedValue)) -// return *parsedValue, nil -// } -// -// cursorStr := "" -// -// // NOT BEING UPDATED -// // FIXME: Update the app with the correct actions. HOW DOES THIS WORK?? -// // Seems like only actions are wrong. Could get the app individually. -// // Guessing it's a memory issue. -// //Actions []WorkflowAppAction `json:"actions" yaml:"actions" required:true datastore:"actions,noindex"` -// //errors.New(nil) -// var err error -// for { -// it := dbclient.Run(ctx, query) -// //_, err = it.Next(&app) -// for { -// var app WorkflowApp -// _, err := it.Next(&app) -// if err != nil { -// break -// } -// -// if app.Name == "Shuffle Subflow" { -// continue -// } -// -// found := false -// //log.Printf("ACTIONS: %d - %s", len(app.Actions), app.Name) -// for _, innerapp := range apps { -// if innerapp.Name == app.Name { -// found = true -// break -// } -// } -// -// if !found { -// apps = append(apps, app) -// } -// } -// -// if err != iterator.Done { -// //log.Printf("[INFO] Failed fetching results: %v", err) -// //break -// } -// -// // Get the cursor for the next page of results. -// nextCursor, err := it.Cursor() -// if err != nil { -// log.Printf("Cursorerror: %s", err) -// break -// } else { -// //log.Printf("NEXTCURSOR: %s", nextCursor) -// nextStr := fmt.Sprintf("%s", nextCursor) -// if cursorStr == nextStr { -// break -// } -// -// cursorStr = nextStr -// query = query.Start(nextCursor) -// //cursorStr = nextCursor -// //break -// } -// -// if len(apps) > maxLen { -// break -// } -// } -// -// if len(apps) > 20 { -// log.Printf("[INFO] Setting %d apps in cache", len(apps)) -// requestCache.Set(cacheKey, &apps, cache.DefaultExpiration) -// } -// -// //var allworkflowapps []WorkflowApp -// //_, err := dbclient.GetAll(ctx, query, &allworkflowapps) -// //if err != nil { -// // if strings.Contains(fmt.Sprintf("%s", err), "ResourceExhausted") { -// // //datastore.NewQuery("workflowapp").Limit(30).Order("-edited") -// // query = datastore.NewQuery("workflowapp").Order("-edited").Limit(25) -// // //q := q.Limit(25) -// // _, err := dbclient.GetAll(ctx, query, &allworkflowapps) -// // if err != nil { -// // return []WorkflowApp{}, err -// // } -// // } else { -// // return []WorkflowApp{}, err -// // } -// //} -// -// return apps, nil -//} - -//func shuffle.GetAllWorkflowAppAuth(ctx context.Context, OrgId string) ([]shuffle.AppAuthenticationStorage, error) { -// var allworkflowapps []AppAuthenticationStorage -// q := datastore.NewQuery("workflowappauth").Filter("org_id = ", OrgId) -// -// _, err := dbclient.GetAll(ctx, q, &allworkflowapps) -// if err != nil { -// return []AppAuthenticationStorage{}, err -// } -// -// return allworkflowapps, nil -//} -// -//func getWorkflowAppAuthDatastore(ctx context.Context, id string) (*AppAuthenticationStorage, error) { -// -// key := datastore.NameKey("workflowappauth", id, nil) -// appAuth := &AppAuthenticationStorage{} -// // New struct, to not add body, author etc -// if err := dbclient.Get(ctx, key, appAuth); err != nil { -// return &AppAuthenticationStorage{}, err -// } -// -// return appAuth, nil -//} -// -//func shuffle.SetWorkflowAppAuthDatastore(ctx context.Context, workflowappauth AppAuthenticationStorage, id string) error { -// timeNow := int64(time.Now().Unix()) -// if workflowappauth.Created == 0 { -// workflowappauth.Created = timeNow -// } -// -// workflowappauth.Edited = timeNow -// -// key := datastore.NameKey("workflowappauth", id, nil) -// -// // New struct, to not add body, author etc -// if _, err := dbclient.Put(ctx, key, &workflowappauth); err != nil { -// log.Printf("Error adding workflow app auth: %s", err) -// return err -// } -// -// return nil -//} -// -//// Hmm, so I guess this should use uuid :( -//// Consistency PLX -//func SetWorkflowAppDatastore(ctx context.Context, workflowapp WorkflowApp, id string) error { -// timeNow := int64(time.Now().Unix()) -// if workflowapp.Created == 0 { -// workflowapp.Created = timeNow -// } -// -// workflowapp.Edited = timeNow -// key := datastore.NameKey("workflowapp", id, nil) -// -// // New struct, to not add body, author etc -// if _, err := dbclient.Put(ctx, key, &workflowapp); err != nil { -// log.Printf("Error adding workflow app: %s", err) -// return err -// } -// -// return nil -//} - -// Starts a new webhook -func handleStopHook(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in set new workflowhandler: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - location := strings.Split(request.URL.String(), "/") - - var fileId string - if location[1] == "api" { - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - fileId = location[4] - } - - if len(fileId) != 32 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Workflow ID when stopping hook is not valid"}`)) - return - } - - ctx := context.Background() - hook, err := getHook(ctx, fileId) - if err != nil { - log.Printf("Failed getting hook %s (stop): %s", fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - if user.Id != hook.Owner { - log.Printf("Wrong user (%s) for workflow %s", user.Username, hook.Id) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - log.Printf("Status: %s", hook.Status) - log.Printf("Running: %t", hook.Running) - if !hook.Running { - message := fmt.Sprintf("Error: %s isn't running", hook.Id) - log.Println(message) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, message))) - return - } - - hook.Status = "stopped" - hook.Running = false - hook.Actions = []HookAction{} - err = setHook(ctx, *hook) - if err != nil { - log.Printf("Failed setting hook: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - image := "webhook" - - // This is here to force stop and remove the old webhook - // FIXME - err = removeWebhookFunction(ctx, fileId) - if err != nil { - log.Printf("Container stop issue for %s-%s: %s", image, fileId, err) - } - - resp.WriteHeader(200) - resp.Write([]byte(`{"success": true, "reason": "Stopped webhook"}`)) -} - -func removeWebhookFunction(ctx context.Context, hookid string) error { - service, err := cloudfunctions.NewService(ctx) - if err != nil { - return err - } - - // ProjectsLocationsListCall - projectsLocationsFunctionsService := cloudfunctions.NewProjectsLocationsFunctionsService(service) - location := fmt.Sprintf("projects/%s/locations/%s", gceProject, defaultLocation) - functionName := fmt.Sprintf("%s/functions/webhook_%s", location, hookid) - - deleteCall := projectsLocationsFunctionsService.Delete(functionName) - resp, err := deleteCall.Do() - if err != nil { - log.Printf("Failed to delete %s from %s: %s", hookid, defaultLocation, err) - return err - } else { - log.Printf("Successfully deleted %s from %s", hookid, defaultLocation) - } - - _ = resp - return nil -} - -func handleStartHook(resp http.ResponseWriter, request *http.Request) { - cors := handleCors(resp, request) - if cors { - return - } - - user, err := shuffle.HandleApiAuthentication(resp, request) - if err != nil { - log.Printf("Api authentication failed in set new workflowhandler: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - location := strings.Split(request.URL.String(), "/") - - var fileId string - if location[1] == "api" { - if len(location) <= 4 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - fileId = location[4] - } - - if len(fileId) != 36 { - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false, "reason": "Workflow ID when starting hook is not valid"}`)) - return - } - - ctx := context.Background() - hook, err := getHook(ctx, fileId) - if err != nil { - log.Printf("Failed getting hook %s (start): %s", fileId, err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - if user.Id != hook.Owner { - log.Printf("Wrong user (%s) for workflow %s", user.Username, hook.Id) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - log.Printf("Status: %s", hook.Status) - log.Printf("Running: %t", hook.Running) - if hook.Running || hook.Status == "Running" { - message := fmt.Sprintf("Error: %s is already running", hook.Id) - log.Println(message) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, message))) - return - } - - environmentVariables := map[string]string{ - "FUNCTION_APIKEY": user.ApiKey, - "CALLBACKURL": syncUrl, - "HOOKID": fileId, - } - - applocation := fmt.Sprintf("gs://%s/triggers/webhook.zip", bucketName) - hookname := fmt.Sprintf("webhook_%s", fileId) - err = deployWebhookFunction(ctx, hookname, "europe-west2", applocation, environmentVariables) - if err != nil { - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err))) - return - } - - hook.Status = "running" - hook.Running = true - err = setHook(ctx, *hook) - if err != nil { - log.Printf("Failed setting hook: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) - return - } - - log.Printf("Starting function %s?", fileId) - resp.WriteHeader(200) - resp.Write([]byte(`{"success": true, "reason": "Started webhook"}`)) - return -} - -func removeOutlookTriggerFunction(ctx context.Context, triggerId string) error { - service, err := cloudfunctions.NewService(ctx) - if err != nil { - return err - } - - // ProjectsLocationsListCall - projectsLocationsFunctionsService := cloudfunctions.NewProjectsLocationsFunctionsService(service) - location := fmt.Sprintf("projects/%s/locations/%s", gceProject, defaultLocation) - functionName := fmt.Sprintf("%s/functions/outlooktrigger_%s", location, triggerId) - - deleteCall := projectsLocationsFunctionsService.Delete(functionName) - resp, err := deleteCall.Do() - if err != nil { - log.Printf("Failed to delete %s from %s: %s", triggerId, defaultLocation, err) - return err - } else { - log.Printf("Successfully deleted %s from %s", triggerId, defaultLocation) - } - - _ = resp - return nil -} - func handleUserInput(trigger shuffle.Trigger, organizationId string, workflowId string, referenceExecution string) error { // E.g. check email sms := "" @@ -5574,7 +3982,7 @@ func handleUserInput(trigger shuffle.Trigger, organizationId string, workflowId return err } - log.Printf("Should send email to %s during execution.", email) + log.Printf("[INFO] Should send email to %s during execution.", email) } if strings.Contains(triggerType, "sms") { action := shuffle.CloudSyncJob{ @@ -5605,3 +4013,83 @@ func handleUserInput(trigger shuffle.Trigger, organizationId string, workflowId return nil } + +func executeSingleAction(resp http.ResponseWriter, request *http.Request) { + cors := shuffle.HandleCors(resp, request) + if cors { + return + } + + user, err := shuffle.HandleApiAuthentication(resp, request) + if err != nil { + log.Printf("[WARNING] Api authentication failed in execute SINGLE workflow - CONTINUING ANYWAY: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "You need to sign up to try it out}`)) + return + } + + location := strings.Split(request.URL.String(), "/") + var fileId string + if location[1] == "api" { + if len(location) <= 4 { + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + fileId = location[4] + } + + body, err := ioutil.ReadAll(request.Body) + if err != nil { + log.Printf("[INFO] Failed workflowrequest POST read: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + ctx := context.Background() + workflowExecution, err := shuffle.PrepareSingleAction(ctx, user, fileId, body) + if err != nil { + log.Printf("[INFO] Failed workflowrequest POST read: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + environments, err := shuffle.GetEnvironments(ctx, user.ActiveOrg.Id) + environment := "Shuffle" + if len(environments) >= 1 { + environment = environments[0].Name + } else { + log.Printf("[ERROR] No environments found for org %s. Exiting", user.ActiveOrg.Id) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + log.Printf("[INFO] Execution: %s should execute onprem with execution environment \"%s\". Workflow: %s", workflowExecution.ExecutionId, environment, workflowExecution.Workflow.ID) + + executionRequest := shuffle.ExecutionRequest{ + ExecutionId: workflowExecution.ExecutionId, + WorkflowId: workflowExecution.Workflow.ID, + Authorization: workflowExecution.Authorization, + Environments: []string{environment}, + } + + err = shuffle.SetWorkflowQueue(ctx, executionRequest, environment) + if err != nil { + log.Printf("[ERROR] Failed adding execution to db: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + time.Sleep(2 * time.Second) + log.Printf("[INFO] Starting validation of execution %s", workflowExecution.ExecutionId) + + returnBytes := shuffle.HandleRetValidation(ctx, workflowExecution) + + resp.WriteHeader(200) + resp.Write(returnBytes) +} diff --git a/backend/tests/cache.sh b/backend/tests/cache.sh new file mode 100644 index 00000000..401d9ce1 --- /dev/null +++ b/backend/tests/cache.sh @@ -0,0 +1,15 @@ +curl -XPOST http://192.168.3.8:5001/api/v1/orgs/6a6a99f5-6630-4f91-88ff-571c9f030ea0/set_cache -H "Authorization: Bearer e663cf93-7f10-4560-bef0-303f14aad982" -d '{ + "workflow_id": "61825389-a125-43a5-9119-97c401e9934b", + "execution_id": "2c8ca1b7-6658-4742-86a1-105c9467702d", + "org_id": "6a6a99f5-6630-4f91-88ff-571c9f030ea0", + "key": "test", + "value": "THIS IS SOME DATA HELLO" +}' + +curl -XPOST http://192.168.3.8:5001/api/v1/orgs/6a6a99f5-6630-4f91-88ff-571c9f030ea0/get_cache -H "Authorization: Bearer e663cf93-7f10-4560-bef0-303f14aad982" -d '{ + "workflow_id": "61825389-a125-43a5-9119-97c401e9934b", + "execution_id": "2c8ca1b7-6658-4742-86a1-105c9467702d", + "org_id": "6a6a99f5-6630-4f91-88ff-571c9f030ea0", + "key": "test" +}' + diff --git a/backend/tests/dockerpull.sh b/backend/tests/dockerpull.sh index 3df0d1e5..24c5f391 100644 --- a/backend/tests/dockerpull.sh +++ b/backend/tests/dockerpull.sh @@ -1,2 +1,5 @@ #!/bin/sh -curl -XPOST http://localhost:5001/api/v1/get_docker_image -d '{"name":"frikky/shuffle:Testing_1.0.0"}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" +#curl -XPOST http://localhost:5001/api/v1/get_docker_image -d '{"name":"frikky/shuffle:testing_1.0.0"}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" --output tarball.tgz +#curl -XPOST http://localhost:5001/api/v1/get_docker_image -d '{"name":"frikky/shuffle:testing_1.0.0"}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" -O -J +#curl -XPOST http://localhost:5001/api/v1/get_docker_image -d '{"name":"frikky/shuffle:testing_1.0.0"}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" --output tarball.tgz +curl -XPOST http://localhost:5001/api/v1/get_docker_image -d '{"name":"frikky/shuffle:shuffle-tools_1.0.0"}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4" --output tarball.tgz diff --git a/backend/tests/migrate_db.sh b/backend/tests/migrate_db.sh new file mode 100644 index 00000000..23293b1e --- /dev/null +++ b/backend/tests/migrate_db.sh @@ -0,0 +1,2 @@ +curl -XPOST -v localhost:5001/api/v1/migrate_database -H 'Authorization: Bearer 0184d7be-33c1-4391-bf9c-dfb8508a4ea2' + diff --git a/backend/tests/test_wrappers.py b/backend/tests/test_wrappers.py new file mode 100644 index 00000000..d6ec96c6 --- /dev/null +++ b/backend/tests/test_wrappers.py @@ -0,0 +1,210 @@ +import re +import json + +def parse_nested_param(string, level): + """ + Generate strings contained in nested (), indexing i = level + """ + if len(re.findall("\(", string)) == len(re.findall("\)", string)): + LeftRightIndex = [x for x in zip( + [Left.start()+1 for Left in re.finditer('\(', string)], + reversed([Right.start() for Right in re.finditer('\)', string)]))] + + elif len(re.findall("\(", string)) > len(re.findall("\)", string)): + return parse_nested_param(string + ')', level) + elif len(re.findall("\(", string)) < len(re.findall("\)", string)): + return parse_nested_param('(' + string, level) + + else: + return 'Failed to parse params' + + try: + return [string[LeftRightIndex[level][0]:LeftRightIndex[level][1]]] + except IndexError: + return [string[LeftRightIndex[level+1][0]:LeftRightIndex[level+1][1]]] + +# Parses the deepest part +def maxDepth(S): + current_max = 0 + max = 0 + n = len(S) + + # Traverse the input string + for i in range(n): + if S[i] == '(': + current_max += 1 + + if current_max > max: + max = current_max + elif S[i] == ')': + if current_max > 0: + current_max -= 1 + else: + return -1 + + # finally check for unbalanced string + if current_max != 0: + return -1 + + return max-1 + +def parse_type(data, thistype): + if data == None: + return "Empty" + + if "int" in thistype: + try: + return int(data) + except ValueError: + print("ValueError while casting %s" % data) + return data + if "lower" in thistype: + return data.lower() + if "upper" in thistype: + return data.upper() + if "trim" in thistype: + return data.strip() + if "strip" in thistype: + return data.strip() + if "split" in thistype: + # Should be able to split anything + return data.split() + if "len" in thistype or "length" in thistype: + return len(data) + if "parse" in thistype: + splitvalues = [] + default_error = """Error. Expected syntax: parse(["hello","test1"],0:1)""" + if "," in data: + splitvalues = data.split(",") + + for item in range(len(splitvalues)): + splitvalues[item] = splitvalues[item].strip() + else: + return default_error + + lastsplit = [] + if ":" in splitvalues[-1]: + lastsplit = splitvalues[-1].split(":") + else: + try: + lastsplit = [int(splitvalues[-1])] + except ValueError: + return default_error + + try: + parsedlist = ",".join(splitvalues[0:-1]) + print(parsedlist) + print(lastsplit) + + if len(lastsplit) > 1: + tmp = json.loads(parsedlist)[int(lastsplit[0]):int(lastsplit[1])] + else: + tmp = json.loads(parsedlist)[lastsplit[0]] + + print(tmp) + return tmp + except IndexError as e: + return default_error + +# Parses the INNER value and recurses until everything is done +def parse_wrapper(data): + try: + if "(" not in data or ")" not in data: + return data + except TypeError: + return data + + print("Running %s" % data) + + # Look for the INNER wrapper first, then move out + wrappers = ["int", "number", "lower", "upper", "trim", "strip", "split", "parse", "len", "length"] + found = False + for wrapper in wrappers: + if wrapper not in data.lower(): + continue + + found = True + break + + if not found: + return data + + # Do stuff here. + innervalue = parse_nested_param(data, maxDepth(data)-0) + outervalue = parse_nested_param(data, maxDepth(data)-1) + print("INNER: ", outervalue) + print("OUTER: ", outervalue) + + if outervalue != innervalue: + #print("Outer: ", outervalue, " inner: ", innervalue) + for key in range(len(innervalue)): + # Replace OUTERVALUE[key] with INNERVALUE[key] in data. + print("Replace %s with %s in %s" % (outervalue[key], innervalue[key], data)) + data = data.replace(outervalue[key], innervalue[key]) + else: + for thistype in wrappers: + if thistype not in data.lower(): + continue + + parsed_value = parse_type(innervalue[0], thistype) + return parsed_value + + print("DATA: %s\n" % data) + return parse_wrapper(data) + +def parse_wrapper_start(data): + newdata = [] + newstring = "" + record = True + paranCnt = 0 + for char in data: + if char == "(": + paranCnt += 1 + + if not record: + record = True + + if record: + newstring += char + + if paranCnt == 0 and char == " ": + newdata.append(newstring) + newstring = "" + record = True + + if char == ")": + paranCnt -= 1 + + if paranCnt == 0: + record = False + + if len(newstring) > 0: + newdata.append(newstring) + + parsedlist = [] + non_string = False + for item in newdata: + ret = parse_wrapper(item) + if not isinstance(ret, str): + non_string = True + + parsedlist.append(ret) + + if len(parsedlist) > 0 and not non_string: + return " ".join(parsedlist) + elif len(parsedlist) == 1 and non_string: + return parsedlist[0] + else: + print("Casting back to string because multi: ", parsedlist) + newlist = [] + for item in parsedlist: + try: + newlist.append(str(item)) + except ValueError: + newlist.append("parsing_error") + return " ".join(newlist) + +data = "split(hello there)" +data = """parse(["testing", "what", "is this"], 0:2)""" +#data = "int(int(2))" +print("RET: ", parse_wrapper_start(data)) diff --git a/backend/tests/validate_app_values.sh b/backend/tests/validate_app_values.sh new file mode 100644 index 00000000..69cf9d50 --- /dev/null +++ b/backend/tests/validate_app_values.sh @@ -0,0 +1,14 @@ +# ExecutionOrg MUST be executing. +curl -XPOST http://localhost:5001/api/v1/orgs/b199646b-16d2-456d-9fd6-b9972e929466/validate_app_values -d '{ + "append": true, + "workflow_check": true, + "authorization": "1aae630c-ccaf-4cb5-87f9-8a9e0a9afd11", + "execution_ref": "c59ff288-4f02-4d02-b839-133d55c7fdf0", + "org_id": "b199646b-16d2-456d-9fd6-b9972e929466", + "values": [{ + "app": "testing", + "action": "repeat_back_to_me", + "parameternames": ["call"], + "parametervalues": ["hey", "ho", "lets", "go"] + }] +}' diff --git a/docker-compose.yml b/docker-compose.yml index 56fd9a3c..78e6ae61 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: frontend: #build: ./frontend - image: ghcr.io/frikky/shuffle-frontend:0.8.71 + image: ghcr.io/frikky/shuffle-frontend:nightly container_name: shuffle-frontend hostname: shuffle-frontend ports: @@ -17,7 +17,7 @@ services: - backend backend: #build: ./backend - image: ghcr.io/frikky/shuffle-backend:0.8.71 + image: ghcr.io/frikky/shuffle-backend:nightly container_name: shuffle-backend hostname: ${BACKEND_HOSTNAME} # Here for debugging: @@ -29,25 +29,18 @@ services: - /var/run/docker.sock:/var/run/docker.sock - ${SHUFFLE_APP_HOTLOAD_LOCATION}:/shuffle-apps - ${SHUFFLE_FILE_LOCATION}:/shuffle-files + #- ${SHUFFLE_OPENSEARCH_CERTIFICATE_FILE}:/shuffle-files/es_certificate + env_file: .env environment: - - DATASTORE_EMULATOR_HOST=shuffle-database:8000 - SHUFFLE_APP_HOTLOAD_FOLDER=/shuffle-apps - SHUFFLE_FILE_LOCATION=/shuffle-files - - ORG_ID=${ORG_ID} - - SHUFFLE_APP_DOWNLOAD_LOCATION=${SHUFFLE_APP_DOWNLOAD_LOCATION} - - SHUFFLE_DOWNLOAD_AUTH_BRANCH=${SHUFFLE_DOWNLOAD_AUTH_BRANCH} - - SHUFFLE_DEFAULT_USERNAME=${SHUFFLE_DEFAULT_USERNAME} - - SHUFFLE_DEFAULT_PASSWORD=${SHUFFLE_DEFAULT_PASSWORD} - - SHUFFLE_DEFAULT_APIKEY=${SHUFFLE_DEFAULT_APIKEY} - - SHUFFLE_APP_FORCE_UPDATE=${SHUFFLE_APP_FORCE_UPDATE} - - HTTP_PROXY=${SHUFFLE_HTTP_PROXY} - - HTTPS_PROXY=${SHUFFLE_HTTPS_PROXY} restart: unless-stopped - depends_on: - - database + #depends_on: + #- opensearch + #- database orborus: #build: ./functions/onprem/orborus - image: ghcr.io/frikky/shuffle-orborus:0.8.71 + image: ghcr.io/frikky/shuffle-orborus:nightly container_name: shuffle-orborus hostname: shuffle-orborus networks: @@ -55,33 +48,65 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - - SHUFFLE_APP_SDK_VERSION=0.8.60 - - SHUFFLE_WORKER_VERSION=0.8.71 + - SHUFFLE_APP_SDK_VERSION=0.8.97 + - SHUFFLE_WORKER_VERSION=nightly - ORG_ID=${ORG_ID} - ENVIRONMENT_NAME=${ENVIRONMENT_NAME} - BASE_URL=http://${OUTER_HOSTNAME}:${BACKEND_PORT} - - DOCKER_API_VERSION=1.40 - - HTTP_PROXY=${SHUFFLE_HTTP_PROXY} - - HTTPS_PROXY=${SHUFFLE_HTTPS_PROXY} - - SHUFFLE_PASS_WORKER_PROXY=${SHUFFLE_PASS_WORKER_PROXY} - - SHUFFLE_ORBORUS_EXECUTION_TIMEOUT=600 + - DOCKER_API_VERSION=1.35 - SHUFFLE_BASE_IMAGE_NAME=${SHUFFLE_BASE_IMAGE_NAME} - SHUFFLE_BASE_IMAGE_REGISTRY=${SHUFFLE_BASE_IMAGE_REGISTRY} - SHUFFLE_BASE_IMAGE_TAG_SUFFIX=${SHUFFLE_BASE_IMAGE_TAG_SUFFIX} + - HTTP_PROXY=${HTTP_PROXY} + - HTTPS_PROXY=${HTTPS_PROXY} + - SHUFFLE_PASS_WORKER_PROXY=${SHUFFLE_PASS_WORKER_PROXY} + - SHUFFLE_PASS_APP_PROXY=${SHUFFLE_PASS_APP_PROXY} + - SHUFFLE_ORBORUS_EXECUTION_TIMEOUT=600 + - SHUFFLE_ORBORUS_EXECUTION_CONCURRENCY=50 - CLEANUP=${SHUFFLE_CONTAINER_AUTO_CLEANUP} restart: unless-stopped - database: - #build: ./backend/database - image: frikky/shuffle:database - container_name: shuffle-database - hostname: shuffle-database + opensearch: + image: opensearchproject/opensearch:1.0.0-beta1 + hostname: shuffle-opensearch + container_name: shuffle-opensearch + environment: + - bootstrap.memory_lock=true + - "OPENSEARCH_JAVA_OPTS=-Xms1024m -Xmx1024m" # minimum and maximum Java heap size, recommend setting both to 50% of system RAM + - opendistro_security.disabled=true + - cluster.routing.allocation.disk.threshold_enabled=false + - cluster.name=shuffle-cluster + - node.name=shuffle-opensearch + - discovery.seed_hosts=shuffle-opensearch + - cluster.initial_master_nodes=shuffle-opensearch + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems + hard: 65536 + volumes: + - ${DB_LOCATION}:/usr/share/opensearch/data:rw ports: - - "8000:8000" + - 9200:9200 networks: - shuffle restart: unless-stopped - volumes: - - ${DB_LOCATION}:/etc/shuffle + #database: + # #build: ./backend/database + # image: frikky/shuffle:database + # container_name: shuffle-database + # hostname: shuffle-database + # ports: + # - "8000:8000" + # networks: + # - shuffle + # environment: + # - _JAVA_OPTIONS="-Xmx2g" + # restart: unless-stopped + # volumes: + # - ${DB_LOCATION}:/etc/shuffle + networks: shuffle: driver: bridge diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 4204651c..ab5940b1 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -21,7 +21,7 @@ COPY ./*.json /usr/src/app/ RUN yarn build # Production environment -FROM nginx:1.19 +FROM nginx:1.21 RUN mkdir -p /usr/share/nginx/html/build RUN mkdir -p /usr/share/nginx/html/css diff --git a/frontend/confd/templates/nginx.conf b/frontend/confd/templates/nginx.conf index 6b61364a..bd2219a4 100644 --- a/frontend/confd/templates/nginx.conf +++ b/frontend/confd/templates/nginx.conf @@ -28,6 +28,28 @@ http { server { listen 80; server_name "localhost"; + + #location /static/js/* { + # # avoid clickjacking + # add_header X-Frame-Options DENY; + # add_header X-Content-Type-Options nosniff; + # add_header ; + # # block MIME sniffing + + # # security headers + # add_header X-XSS-Protection "1; mode=block"; + # # add_header Content-Security-Policy "default-src 'self'"; + # add_header Referrer-Policy "no-referrer"; + # server_tokens off; + + # root /usr/share/nginx/html; + # gzip_static on; + # expires 1y; + # add_header Cache-Control public; + # add_header ETag ""; + # try_files $uri /index.html; + #} + location / { # avoid clickjacking add_header X-Frame-Options DENY; diff --git a/frontend/package-lock.json b/frontend/package-lock.json deleted file mode 100644 index e5e02309..00000000 --- a/frontend/package-lock.json +++ /dev/null @@ -1,20920 +0,0 @@ -{ - "name": "shuffler", - "version": "0.8.53", - "lockfileVersion": 1, - "requires": true, - "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==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/compat-data": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz", - "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==", - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } - }, - "@babel/core": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.0", - "@babel/parser": "^7.9.0", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", - "requires": { - "@babel/types": "^7.10.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/generator": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", - "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", - "requires": { - "@babel/types": "^7.4.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz", - "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==", - "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-builder-react-jsx": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.1.tgz", - "integrity": "sha512-KXzzpyWhXgzjXIlJU1ZjIXzUPdej1suE6vzqgImZ/cpAsR/CC8gUcX4EWRmDfWz/cs6HOCPMBIJ3nKoXt3BFuw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-builder-react-jsx-experimental": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.1.tgz", - "integrity": "sha512-irQJ8kpQUV3JasXPSFQ+LCCtJSc5ceZrPFVj6TElR6XCHssi3jV8ch3odIrNtjJFRZZVbrOEfJMI79TPU/h1pQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-module-imports": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz", - "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==", - "requires": { - "@babel/compat-data": "^7.10.1", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", - "semver": "^5.5.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz", - "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==", - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/core": {}, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz", - "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-regex": "^7.10.1", - "regexpu-core": "^4.7.0" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-define-map": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz", - "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==", - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/types": "^7.10.1", - "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz", - "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==", - "requires": { - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", - "requires": { - "@babel/types": "^7.10.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@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==", - "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz", - "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==", - "requires": { - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", - "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", - "requires": { - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "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==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-module-transforms": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", - "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", - "requires": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1", - "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", - "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", - "requires": { - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-plugin-utils": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", - "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==" - }, - "@babel/helper-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz", - "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==", - "requires": { - "lodash": "^4.17.13" - } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz", - "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-wrap-function": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", - "requires": { - "@babel/types": "^7.10.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-replace-supers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", - "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", - "requires": { - "@babel/types": "^7.10.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-simple-access": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", - "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", - "requires": { - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", - "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==" - }, - "@babel/helper-wrap-function": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz", - "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==", - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", - "requires": { - "@babel/types": "^7.10.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helpers": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", - "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", - "requires": { - "@babel/template": "^7.10.1", - "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/generator": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", - "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", - "requires": { - "@babel/types": "^7.10.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/traverse": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", - "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", - "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz", - "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-remap-async-to-generator": "^7.10.1", - "@babel/plugin-syntax-async-generators": "^7.8.0" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz", - "integrity": "sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-proposal-decorators": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz", - "integrity": "sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-decorators": "^7.8.3" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz", - "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz", - "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-json-strings": "^7.8.0" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz", - "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz", - "integrity": "sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-numeric-separator": "^7.10.1" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz", - "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.1" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz", - "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz", - "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz", - "integrity": "sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz", - "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", - "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-decorators": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.1.tgz", - "integrity": "sha512-a9OAbQhKOwSle1Vr0NJu/ISg1sPfdEkfRKWpgPuzhnWWzForou2gIeUIIwjAMHRekhhpJ7eulZlYs0H14Cbi+g==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-flow": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.10.1.tgz", - "integrity": "sha512-b3pWVncLBYoPP60UOTc7NMlbtsHQ6ITim78KQejNHK6WJ2mzV5kCcg4mIWpasAfJEgwVTibwo2e+FU7UEIKQUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz", - "integrity": "sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", - "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz", - "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.1.tgz", - "integrity": "sha512-X/d8glkrAtra7CaQGMiGs/OGa6XgUzqPcBXCIGFCpCqnfGlT0Wfbzo/B89xHhnInTaItPK8LALblVXcUOEh95Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz", - "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz", - "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==", - "requires": { - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-remap-async-to-generator": "^7.10.1" - }, - "dependencies": { - "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz", - "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz", - "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "lodash": "^4.17.13" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz", - "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-define-map": "^7.10.1", - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-optimise-call-expression": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1", - "@babel/helper-split-export-declaration": "^7.10.1", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", - "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz", - "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz", - "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz", - "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz", - "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz", - "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==", - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.9.0.tgz", - "integrity": "sha512-7Qfg0lKQhEHs93FChxVLAvhBshOPQDtJUTVHr/ZwQNRccCm4O9D79r9tVSoV8iNwjP1YgfD+e/fgHcPkN1qEQg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-flow": "^7.8.3" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz", - "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz", - "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==", - "requires": { - "@babel/helper-function-name": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", - "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", - "requires": { - "@babel/highlight": "^7.10.1" - } - }, - "@babel/helper-function-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", - "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/template": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", - "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" - }, - "@babel/template": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", - "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", - "requires": { - "@babel/code-frame": "^7.10.1", - "@babel/parser": "^7.10.1", - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/plugin-transform-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz", - "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz", - "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz", - "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==", - "requires": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz", - "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==", - "requires": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-simple-access": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz", - "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==", - "requires": { - "@babel/helper-hoist-variables": "^7.10.1", - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz", - "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==", - "requires": { - "@babel/helper-module-transforms": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", - "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz", - "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz", - "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-replace-supers": "^7.10.1" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz", - "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "dependencies": { - "@babel/helper-get-function-arity": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", - "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz", - "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-react-constant-elements": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.10.1.tgz", - "integrity": "sha512-V4os6bkWt/jbrzfyVcZn2ZpuHZkvj3vyBU0U/dtS8SZuMS7Rfx5oknTrtfyXJ2/QZk8gX7Yls5Z921ItNpE30Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.1.tgz", - "integrity": "sha512-rBjKcVwjk26H3VX8pavMxGf33LNlbocMHdSeldIEswtQ/hrjyTG8fKKILW1cSkODyRovckN/uZlGb2+sAV9JUQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.1.tgz", - "integrity": "sha512-MBVworWiSRBap3Vs39eHt+6pJuLUAaK4oxGc8g+wY+vuSJvLiEQjW1LSTqKb8OUPtDvHCkdPhk7d6sjC19xyFw==", - "requires": { - "@babel/helper-builder-react-jsx": "^7.10.1", - "@babel/helper-builder-react-jsx-experimental": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-jsx": "^7.10.1" - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.1.tgz", - "integrity": "sha512-XwDy/FFoCfw9wGFtdn5Z+dHh6HXKHkC6DwKNWpN74VWinUagZfDcEJc3Y8Dn5B3WMVnAllX8Kviaw7MtC5Epwg==", - "requires": { - "@babel/helper-builder-react-jsx-experimental": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-jsx": "^7.10.1" - } - }, - "@babel/plugin-transform-react-jsx-self": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.1.tgz", - "integrity": "sha512-4p+RBw9d1qV4S749J42ZooeQaBomFPrSxa9JONLHJ1TxCBo3TzJ79vtmG2S2erUT8PDDrPdw4ZbXGr2/1+dILA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-jsx": "^7.10.1" - } - }, - "@babel/plugin-transform-react-jsx-source": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.1.tgz", - "integrity": "sha512-neAbaKkoiL+LXYbGDvh6PjPG+YeA67OsZlE78u50xbWh2L1/C81uHiNP5d1fw+uqUIoiNdCC8ZB+G4Zh3hShJA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-jsx": "^7.10.1" - } - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.1.tgz", - "integrity": "sha512-mfhoiai083AkeewsBHUpaS/FM1dmUENHBMpS/tugSJ7VXqXO5dCN1Gkint2YvM1Cdv1uhmAKt1ZOuAjceKmlLA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz", - "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==", - "requires": { - "regenerator-transform": "^0.14.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz", - "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz", - "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz", - "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz", - "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/helper-regex": "^7.10.1" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz", - "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", - "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz", - "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.10.1.tgz", - "integrity": "sha512-v+QWKlmCnsaimLeqq9vyCsVRMViZG1k2SZTlcZvB+TqyH570Zsij8nvVUZzOASCRiQFUxkLrn9Wg/kH0zgy5OQ==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-typescript": "^7.10.1" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz", - "integrity": "sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz", - "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1" - } - }, - "@babel/preset-env": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.2.tgz", - "integrity": "sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==", - "requires": { - "@babel/compat-data": "^7.10.1", - "@babel/helper-compilation-targets": "^7.10.2", - "@babel/helper-module-imports": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-proposal-async-generator-functions": "^7.10.1", - "@babel/plugin-proposal-class-properties": "^7.10.1", - "@babel/plugin-proposal-dynamic-import": "^7.10.1", - "@babel/plugin-proposal-json-strings": "^7.10.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1", - "@babel/plugin-proposal-numeric-separator": "^7.10.1", - "@babel/plugin-proposal-object-rest-spread": "^7.10.1", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.1", - "@babel/plugin-proposal-optional-chaining": "^7.10.1", - "@babel/plugin-proposal-private-methods": "^7.10.1", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.1", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.1", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.1", - "@babel/plugin-transform-arrow-functions": "^7.10.1", - "@babel/plugin-transform-async-to-generator": "^7.10.1", - "@babel/plugin-transform-block-scoped-functions": "^7.10.1", - "@babel/plugin-transform-block-scoping": "^7.10.1", - "@babel/plugin-transform-classes": "^7.10.1", - "@babel/plugin-transform-computed-properties": "^7.10.1", - "@babel/plugin-transform-destructuring": "^7.10.1", - "@babel/plugin-transform-dotall-regex": "^7.10.1", - "@babel/plugin-transform-duplicate-keys": "^7.10.1", - "@babel/plugin-transform-exponentiation-operator": "^7.10.1", - "@babel/plugin-transform-for-of": "^7.10.1", - "@babel/plugin-transform-function-name": "^7.10.1", - "@babel/plugin-transform-literals": "^7.10.1", - "@babel/plugin-transform-member-expression-literals": "^7.10.1", - "@babel/plugin-transform-modules-amd": "^7.10.1", - "@babel/plugin-transform-modules-commonjs": "^7.10.1", - "@babel/plugin-transform-modules-systemjs": "^7.10.1", - "@babel/plugin-transform-modules-umd": "^7.10.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", - "@babel/plugin-transform-new-target": "^7.10.1", - "@babel/plugin-transform-object-super": "^7.10.1", - "@babel/plugin-transform-parameters": "^7.10.1", - "@babel/plugin-transform-property-literals": "^7.10.1", - "@babel/plugin-transform-regenerator": "^7.10.1", - "@babel/plugin-transform-reserved-words": "^7.10.1", - "@babel/plugin-transform-shorthand-properties": "^7.10.1", - "@babel/plugin-transform-spread": "^7.10.1", - "@babel/plugin-transform-sticky-regex": "^7.10.1", - "@babel/plugin-transform-template-literals": "^7.10.1", - "@babel/plugin-transform-typeof-symbol": "^7.10.1", - "@babel/plugin-transform-unicode-escapes": "^7.10.1", - "@babel/plugin-transform-unicode-regex": "^7.10.1", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.10.2", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" - }, - "dependencies": { - "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-react": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.10.1.tgz", - "integrity": "sha512-Rw0SxQ7VKhObmFjD/cUcKhPTtzpeviEFX1E6PgP+cYOhQ98icNqtINNFANlsdbQHrmeWnqdxA4Tmnl1jy5tp3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-transform-react-display-name": "^7.10.1", - "@babel/plugin-transform-react-jsx": "^7.10.1", - "@babel/plugin-transform-react-jsx-development": "^7.10.1", - "@babel/plugin-transform-react-jsx-self": "^7.10.1", - "@babel/plugin-transform-react-jsx-source": "^7.10.1", - "@babel/plugin-transform-react-pure-annotations": "^7.10.1" - } - }, - "@babel/preset-typescript": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz", - "integrity": "sha512-S4cueFnGrIbvYJgwsVFKdvOmpiL0XGw9MFW9D0vgRys5g36PBhZRL8NX8Gr2akz8XRtzq6HuDXPD/1nniagNUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-transform-typescript": "^7.9.0" - } - }, - "@babel/runtime": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", - "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/runtime-corejs3": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.2.tgz", - "integrity": "sha512-+a2M/u7r15o3dV1NEizr9bRi+KUVnrs/qYxF0Z06DAPx/4VCWaz1WA7EcbE+uqGgt39lp5akWGmHsTseIkHkHg==", - "requires": { - "core-js-pure": "^3.0.0", - "regenerator-runtime": "^0.13.4" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" - } - } - }, - "@babel/template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", - "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.4", - "@babel/types": "^7.4.4" - } - }, - "@babel/traverse": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", - "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.4", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.4.5", - "@babel/types": "^7.4.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "@babel/types": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", - "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - } - } - }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, - "@csstools/convert-colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", - "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==" - }, - "@csstools/normalize.css": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", - "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" - }, - "@date-io/moment": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-1.3.5.tgz", - "integrity": "sha512-b0JQb10Lie07iW2/9uKCQSrXif262d6zfYBstCLLJUk0JVA+7o/yLDg5p2+GkjgJbmodjHozIXs4Bi34RRhL8Q==" - }, - "@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" - }, - "@emotion/is-prop-valid": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.3.tgz", - "integrity": "sha512-We7VBiltAJ70KQA0dWkdPMXnYoizlxOXpvtjmu5/MBnExd+u0PGgV27WCYanmLAbCwAU30Le/xA0CQs/F/Otig==", - "requires": { - "@emotion/memoize": "0.7.3" - } - }, - "@emotion/memoize": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.3.tgz", - "integrity": "sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow==" - }, - "@emotion/unitless": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.4.tgz", - "integrity": "sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ==" - }, - "@fortawesome/fontawesome-free": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.11.2.tgz", - "integrity": "sha512-XiUPoS79r1G7PcpnNtq85TJ7inJWe0v+b5oZJZKb0pGHNIV6+UiNeQWiFGmuQ0aj7GEhnD/v9iqxIsjuRKtEnQ==" - }, - "@hapi/address": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", - "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==" - }, - "@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" - }, - "@hapi/hoek": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", - "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" - }, - "@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", - "requires": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" - } - }, - "@hapi/topo": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", - "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", - "requires": { - "@hapi/hoek": "^8.3.0" - } - }, - "@jest/console": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", - "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", - "requires": { - "@jest/source-map": "^24.9.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@jest/core": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", - "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", - "requires": { - "@jest/console": "^24.7.1", - "@jest/reporters": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-changed-files": "^24.9.0", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-resolve-dependencies": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "jest-watcher": "^24.9.0", - "micromatch": "^3.1.10", - "p-each-series": "^1.0.0", - "realpath-native": "^1.1.0", - "rimraf": "^2.5.4", - "slash": "^2.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@jest/environment": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", - "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", - "requires": { - "@jest/fake-timers": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, - "@jest/fake-timers": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", - "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", - "requires": { - "@jest/types": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, - "@jest/reporters": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", - "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", - "requires": { - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.2", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.2.6", - "jest-haste-map": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "node-notifier": "^5.4.2", - "slash": "^2.0.0", - "source-map": "^0.6.0", - "string-length": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" - }, - "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", - "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/test-sequencer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", - "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", - "requires": { - "@jest/test-result": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0" - } - }, - "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", - "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" - } - }, - "@material-ui/core": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.10.0.tgz", - "integrity": "sha512-yVlHe4b8AaoiTHhCOZeszHZ+T2iHU5DncdMGeNcQaaaO+q/Qrq0hxP3iFzTbgjRWnWwftEVQL668GRxcPJVRaQ==", - "requires": { - "@babel/runtime": "^7.4.4", - "@material-ui/styles": "^4.10.0", - "@material-ui/system": "^4.9.14", - "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.9.12", - "@types/react-transition-group": "^4.2.0", - "clsx": "^1.0.4", - "hoist-non-react-statics": "^3.3.2", - "popper.js": "^1.16.1-lts", - "prop-types": "^15.7.2", - "react-is": "^16.8.0", - "react-transition-group": "^4.4.0" - }, - "dependencies": { - "csstype": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz", - "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==" - }, - "dom-helpers": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz", - "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==", - "requires": { - "@babel/runtime": "^7.8.7", - "csstype": "^2.6.7" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.1.tgz", - "integrity": "sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - } - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "jss": { - "dependencies": { - "warning": {} - } - }, - "jss-nested": { - "dependencies": { - "warning": {} - } - }, - "popper.js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" - }, - "react-transition-group": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", - "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", - "requires": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.1.tgz", - "integrity": "sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - } - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" - } - } - }, - "@material-ui/icons": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.5.1.tgz", - "integrity": "sha512-YZ/BgJbXX4a0gOuKWb30mBaHaoXRqPanlePam83JQPZ/y4kl+3aW0Wv9tlR70hB5EGAkEJGW5m4ktJwMgxQAeA==", - "requires": { - "@babel/runtime": "^7.4.4" - } - }, - "@material-ui/styles": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz", - "integrity": "sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==", - "requires": { - "@babel/runtime": "^7.4.4", - "@emotion/hash": "^0.8.0", - "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.9.6", - "clsx": "^1.0.4", - "csstype": "^2.5.2", - "hoist-non-react-statics": "^3.3.2", - "jss": "^10.0.3", - "jss-plugin-camel-case": "^10.0.3", - "jss-plugin-default-unit": "^10.0.3", - "jss-plugin-global": "^10.0.3", - "jss-plugin-nested": "^10.0.3", - "jss-plugin-props-sort": "^10.0.3", - "jss-plugin-rule-value-function": "^10.0.3", - "jss-plugin-vendor-prefixer": "^10.0.3", - "prop-types": "^15.7.2" - }, - "dependencies": { - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - } - } - }, - "@material-ui/system": { - "version": "4.9.14", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz", - "integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==", - "requires": { - "@babel/runtime": "^7.4.4", - "@material-ui/utils": "^4.9.6", - "csstype": "^2.5.2", - "prop-types": "^15.7.2" - } - }, - "@material-ui/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", - "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==" - }, - "@material-ui/utils": { - "version": "4.9.12", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.9.12.tgz", - "integrity": "sha512-/0rgZPEOcZq5CFA4+4n6Q6zk7fi8skHhH2Bcra8R3epoJEYy5PL55LuMazPtPH1oKeRausDV/Omz4BbgFsn1HQ==", - "requires": { - "@babel/runtime": "^7.4.4", - "prop-types": "^15.7.2", - "react-is": "^16.8.0" - } - }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - } - }, - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" - }, - "@reach/auto-id": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.2.0.tgz", - "integrity": "sha512-lVK/svL2HuQdp7jgvlrLkFsUx50Az9chAhxpiPwBqcS83I2pVWvXp98FOcSCCJCV++l115QmzHhFd+ycw1zLBg==" - }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", - "integrity": "sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig==" - }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz", - "integrity": "sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ==" - }, - "@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz", - "integrity": "sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w==" - }, - "@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz", - "integrity": "sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w==" - }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz", - "integrity": "sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w==" - }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz", - "integrity": "sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w==" - }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz", - "integrity": "sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw==" - }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz", - "integrity": "sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw==" - }, - "@svgr/babel-preset": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-4.3.3.tgz", - "integrity": "sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A==", - "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "^4.2.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^4.2.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^4.2.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^4.2.0", - "@svgr/babel-plugin-svg-dynamic-title": "^4.3.3", - "@svgr/babel-plugin-svg-em-dimensions": "^4.2.0", - "@svgr/babel-plugin-transform-react-native-svg": "^4.2.0", - "@svgr/babel-plugin-transform-svg-component": "^4.2.0" - } - }, - "@svgr/core": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-4.3.3.tgz", - "integrity": "sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w==", - "requires": { - "@svgr/plugin-jsx": "^4.3.3", - "camelcase": "^5.3.1", - "cosmiconfig": "^5.2.1" - } - }, - "@svgr/hast-util-to-babel-ast": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz", - "integrity": "sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg==", - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@svgr/plugin-jsx": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz", - "integrity": "sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w==", - "requires": { - "@babel/core": "^7.4.5", - "@svgr/babel-preset": "^4.3.3", - "@svgr/hast-util-to-babel-ast": "^4.3.2", - "svg-parser": "^2.0.0" - } - }, - "@svgr/plugin-svgo": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz", - "integrity": "sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w==", - "requires": { - "cosmiconfig": "^5.2.1", - "merge-deep": "^3.0.2", - "svgo": "^1.2.2" - } - }, - "@svgr/webpack": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-4.3.3.tgz", - "integrity": "sha512-bjnWolZ6KVsHhgyCoYRFmbd26p8XVbulCzSG53BDQqAr+JOAderYK7CuYrB3bDjHJuF6LJ7Wrr42+goLRV9qIg==", - "requires": { - "@babel/core": "^7.4.5", - "@babel/plugin-transform-react-constant-elements": "^7.0.0", - "@babel/preset-env": "^7.4.5", - "@babel/preset-react": "^7.0.0", - "@svgr/core": "^4.3.3", - "@svgr/plugin-jsx": "^4.3.3", - "@svgr/plugin-svgo": "^4.3.1", - "loader-utils": "^1.2.3" - } - }, - "@types/babel__core": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", - "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", - "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, - "@types/cookie": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.3.tgz", - "integrity": "sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==" - }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==" - }, - "@types/glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/json-schema": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", - "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==" - }, - "@types/jss": { - "version": "9.5.8", - "resolved": "https://registry.npmjs.org/@types/jss/-/jss-9.5.8.tgz", - "integrity": "sha512-bBbHvjhm42UKki+wZpR89j73ykSXg99/bhuKuYYePtpma3ZAnmeGnl0WxXiZhPGsIfzKwCUkpPC0jlrVMBfRxA==", - "requires": { - "csstype": "^2.0.0", - "indefinite-observable": "^1.0.1" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" - }, - "@types/node": { - "version": "14.0.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.24.tgz", - "integrity": "sha512-btt/oNOiDWcSuI721MdL8VQGnjsKjlTMdrKyTcLCKeQp/n4AAMFJ961wMbp+09y8WuGPClDEv07RIItdXKIXAA==" - }, - "@types/object-assign": { - "version": "4.0.30", - "resolved": "https://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz", - "integrity": "sha1-iUk3HVqZ9Dge4PHfCpt6GH4H5lI=" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" - }, - "@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" - }, - "@types/react": { - "version": "16.9.43", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.43.tgz", - "integrity": "sha512-PxshAFcnJqIWYpJbLPriClH53Z2WlJcVZE+NP2etUtWQs2s7yIMj3/LDKZT/5CHJ/F62iyjVCDu2H3jHEXIxSg==", - "requires": { - "@types/prop-types": "*", - "csstype": "^2.2.0" - } - }, - "@types/react-text-mask": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/@types/react-text-mask/-/react-text-mask-5.4.6.tgz", - "integrity": "sha512-0KkER9oXZY/v1x8aoMTHwANlWnKT5tnmV7Zz+g81gBvcHRtcIHotcpY4KgWRwx0T5JMcsYmEh7wGOz0lwdONew==", - "requires": { - "@types/react": "*" - } - }, - "@types/react-transition-group": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz", - "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==", - "requires": { - "@types/react": "*" - } - }, - "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" - }, - "@types/yargs": { - "version": "13.0.9", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", - "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" - }, - "@typescript-eslint/eslint-plugin": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", - "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", - "requires": { - "@typescript-eslint/experimental-utils": "2.34.0", - "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", - "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", - "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", - "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.34.0", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-visitor-keys": "^1.1.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", - "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - } - } - }, - "@use-it/interval": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@use-it/interval/-/interval-0.1.3.tgz", - "integrity": "sha512-chshdtDZTFoWA9aszBz1Cc04Ca9NBD2JTi/GMjdJ+HGm4q7Vy1v71+2mm22r7Kfb2nYW+lTRsPcEHdB/VFVHsQ==" - }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==" - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==" - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==" - }, - "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", - "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" - } - } - }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" - }, - "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" - }, - "adjust-sourcemap-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz", - "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==", - "requires": { - "assert": "1.4.1", - "camelcase": "5.0.0", - "loader-utils": "1.2.3", - "object-path": "0.11.4", - "regex-parser": "2.2.10" - }, - "dependencies": { - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==" - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - } - } - }, - "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", - "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" - }, - "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "requires": { - "type-fest": "^0.11.0" - }, - "dependencies": { - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" - } - } - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=" - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", - "requires": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" - } - }, - "arity-n": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", - "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=" - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" - }, - "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "is-string": "^1.0.5" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" - } - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "attr-accept": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.3.tgz", - "integrity": "sha512-iT40nudw8zmCweivz6j58g+RT33I4KbaIvRUhjNmDwO2WmsQUxFEZZYZ5w3vXe5x5MX9D7mfvA/XaLOZYFR9EQ==", - "requires": { - "core-js": "^2.5.0" - } - }, - "autoprefixer": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", - "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==", - "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001061", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.30", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" - }, - "axobject-query": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.2.tgz", - "integrity": "sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ==" - }, - "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=", - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" - } - } - }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", - "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", - "requires": { - "@babel/types": "^7.11.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", - "requires": { - "@babel/types": "^7.11.0" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", - "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==" - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "requires": { - "@babel/highlight": "^7.10.4" - } - } - } - }, - "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "requires": { - "@babel/highlight": "^7.10.4" - } - } - } - }, - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "babel-extract-comments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", - "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", - "requires": { - "babylon": "^6.18.0" - } - }, - "babel-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", - "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", - "requires": { - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.9.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" - }, - "dependencies": { - "@babel/core": {}, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-istanbul": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", - "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.3.0", - "test-exclude": "^5.2.3" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - } - } - }, - "babel-plugin-jest-hoist": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", - "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", - "requires": { - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", - "requires": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz", - "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - } - } - }, - "babel-plugin-named-asset-import": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz", - "integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA==" - }, - "babel-plugin-styled-components": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz", - "integrity": "sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-module-imports": "^7.0.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11" - } - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" - }, - "babel-preset-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", - "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", - "requires": { - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.9.0" - } - }, - "babel-preset-react-app": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz", - "integrity": "sha512-k58RtQOKH21NyKtzptoAvtAODuAJJs3ZhqBMl456/GnXEQ/0La92pNmwgWoMn5pBTrsvk3YYXdY7zpY4e3UIxA==", - "requires": { - "@babel/core": "7.9.0", - "@babel/plugin-proposal-class-properties": "7.8.3", - "@babel/plugin-proposal-decorators": "7.8.3", - "@babel/plugin-proposal-nullish-coalescing-operator": "7.8.3", - "@babel/plugin-proposal-numeric-separator": "7.8.3", - "@babel/plugin-proposal-optional-chaining": "7.9.0", - "@babel/plugin-transform-flow-strip-types": "7.9.0", - "@babel/plugin-transform-react-display-name": "7.8.3", - "@babel/plugin-transform-runtime": "7.9.0", - "@babel/preset-env": "7.9.0", - "@babel/preset-react": "7.9.1", - "@babel/preset-typescript": "7.9.0", - "@babel/runtime": "7.9.0", - "babel-plugin-macros": "2.8.0", - "babel-plugin-transform-react-remove-prop-types": "0.4.24" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/core": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.0", - "@babel/parser": "^7.9.0", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "requires": { - "@babel/types": "^7.12.11", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", - "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", - "requires": { - "@babel/types": "^7.12.10" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", - "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "regexpu-core": "^4.7.1" - } - }, - "@babel/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "requires": { - "@babel/types": "^7.12.10" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", - "requires": { - "@babel/types": "^7.12.7" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-module-imports": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", - "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", - "requires": { - "@babel/types": "^7.10.1" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "requires": { - "@babel/types": "^7.12.10" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "requires": { - "@babel/types": "^7.12.11" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - } - } - }, - "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", - "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", - "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - }, - "@babel/plugin-transform-parameters": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", - "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - } - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", - "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" - } - }, - "@babel/plugin-syntax-async-generators": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-syntax-json-strings": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - } - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-transform-classes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", - "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - } - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", - "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - } - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-transform-new-target": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz", - "integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-transform-react-jsx": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-transform-react-jsx-self": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-transform-react-jsx-source": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-transform-regenerator": { - "dependencies": { - "@babel/core": {} - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz", - "integrity": "sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw==", - "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "resolve": "^1.8.1", - "semver": "^5.5.1" - } - }, - "@babel/preset-env": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz", - "integrity": "sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==", - "requires": { - "@babel/compat-data": "^7.9.0", - "@babel/helper-compilation-targets": "^7.8.7", - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-proposal-async-generator-functions": "^7.8.3", - "@babel/plugin-proposal-dynamic-import": "^7.8.3", - "@babel/plugin-proposal-json-strings": "^7.8.3", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-proposal-numeric-separator": "^7.8.3", - "@babel/plugin-proposal-object-rest-spread": "^7.9.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", - "@babel/plugin-proposal-optional-chaining": "^7.9.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.8.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.8.3", - "@babel/plugin-transform-async-to-generator": "^7.8.3", - "@babel/plugin-transform-block-scoped-functions": "^7.8.3", - "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.9.0", - "@babel/plugin-transform-computed-properties": "^7.8.3", - "@babel/plugin-transform-destructuring": "^7.8.3", - "@babel/plugin-transform-dotall-regex": "^7.8.3", - "@babel/plugin-transform-duplicate-keys": "^7.8.3", - "@babel/plugin-transform-exponentiation-operator": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.9.0", - "@babel/plugin-transform-function-name": "^7.8.3", - "@babel/plugin-transform-literals": "^7.8.3", - "@babel/plugin-transform-member-expression-literals": "^7.8.3", - "@babel/plugin-transform-modules-amd": "^7.9.0", - "@babel/plugin-transform-modules-commonjs": "^7.9.0", - "@babel/plugin-transform-modules-systemjs": "^7.9.0", - "@babel/plugin-transform-modules-umd": "^7.9.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", - "@babel/plugin-transform-new-target": "^7.8.3", - "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.8.7", - "@babel/plugin-transform-property-literals": "^7.8.3", - "@babel/plugin-transform-regenerator": "^7.8.7", - "@babel/plugin-transform-reserved-words": "^7.8.3", - "@babel/plugin-transform-shorthand-properties": "^7.8.3", - "@babel/plugin-transform-spread": "^7.8.3", - "@babel/plugin-transform-sticky-regex": "^7.8.3", - "@babel/plugin-transform-template-literals": "^7.8.3", - "@babel/plugin-transform-typeof-symbol": "^7.8.4", - "@babel/plugin-transform-unicode-regex": "^7.8.3", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.9.0", - "browserslist": "^4.9.1", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" - }, - "dependencies": { - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", - "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", - "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - } - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", - "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", - "requires": { - "regenerator-transform": "^0.14.2" - } - } - } - }, - "@babel/preset-react": { - "version": "7.9.1", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.9.1.tgz", - "integrity": "sha512-aJBYF23MPj0RNdp/4bHnAP0NVqqZRr9kl0NAOP4nJCex6OYVio59+dnQzsAWFuogdLyeaKA1hmfUIVZkY5J+TQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-transform-react-display-name": "^7.8.3", - "@babel/plugin-transform-react-jsx": "^7.9.1", - "@babel/plugin-transform-react-jsx-development": "^7.9.0", - "@babel/plugin-transform-react-jsx-self": "^7.9.0", - "@babel/plugin-transform-react-jsx-source": "^7.9.0" - }, - "dependencies": { - "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "requires": { - "@babel/types": "^7.12.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", - "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - } - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz", - "integrity": "sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.12.10", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.12.1", - "@babel/types": "^7.12.12" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - } - } - }, - "@babel/plugin-transform-react-jsx-self": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.1.tgz", - "integrity": "sha512-FbpL0ieNWiiBB5tCldX17EtXgmzeEZjFrix72rQYeq9X6nUK38HCaxexzVQrZWXanxKJPKVVIU37gFjEQYkPkA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - } - } - }, - "@babel/plugin-transform-react-jsx-source": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.1.tgz", - "integrity": "sha512-keQ5kBfjJNRc6zZN1/nVHCd6LLIHq4aUKcVnvE/2l+ZZROSbqoiGFRtT5t3Is89XJxBQaP7NLZX2jgGHdZvvFQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - } - } - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/runtime": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.0.tgz", - "integrity": "sha512-cTIudHnzuWLS56ik4DnRnqqNf8MkdUzV4iFFI1h7Jo9xvrpQROYaAnaSd2mHLQAzzZAPfATynX5ord6YlNYNMA==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/types": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", - "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "babel-loader": {}, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" - }, - "regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - } - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "bail": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz", - "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "base16": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", - "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=" - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" - }, - "bootstrap-css-only": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/bootstrap-css-only/-/bootstrap-css-only-4.3.1.tgz", - "integrity": "sha512-xPQNmTR6skX7boM3Q/K2vWDL8RFhfHm5PbTcn/vd7nZtkzg9tc6ScNreIIsMaP9QLUxeqvUx+OGnDaiK4KBRiQ==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brcast": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.1.tgz", - "integrity": "sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg==" - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" - }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" - } - } - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", - "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", - "requires": { - "caniuse-lite": "^1.0.30001043", - "electron-to-chromium": "^1.3.413", - "node-releases": "^1.1.53", - "pkg-up": "^2.0.0" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - } - } - }, - "buffer-from": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", - "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "cacache": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", - "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", - "requires": { - "chownr": "^1.1.2", - "figgy-pudding": "^3.5.1", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.2", - "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "minipass": "^3.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "p-map": "^3.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^2.7.1", - "ssri": "^7.0.0", - "unique-filename": "^1.1.1" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "requires": { - "callsites": "^2.0.0" - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" - }, - "camel-case": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", - "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", - "requires": { - "pascal-case": "^3.1.1", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, - "can-use-dom": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/can-use-dom/-/can-use-dom-0.1.0.tgz", - "integrity": "sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo=" - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001084", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001084.tgz", - "integrity": "sha512-ftdc5oGmhEbLUuMZ/Qp3mOpzfZLCxPYKcvGv6v2dJJ+8EdqcvZRbAGOiLmkM/PV1QGta/uwBs8/nCl6sokDW6w==" - }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "requires": { - "rsvp": "^4.8.4" - } - }, - "case-sensitive-paths-webpack-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", - "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "change-emitter": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz", - "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=" - }, - "character-entities": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz", - "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==" - }, - "character-entities-legacy": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz", - "integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww==" - }, - "character-reference-invalid": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz", - "integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg==" - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "chart.js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.8.0.tgz", - "integrity": "sha512-Di3wUL4BFvqI5FB5K26aQ+hvWh8wnP9A3DWGvXHVkO13D3DSnaSsdZx29cXlEsYKVkn1E2az+ZYFS4t0zi8x0w==", - "requires": { - "chartjs-color": "^2.1.0", - "moment": "^2.10.2" - } - }, - "chartjs-color": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.3.0.tgz", - "integrity": "sha512-hEvVheqczsoHD+fZ+tfPUE+1+RbV6b+eksp2LwAhwRTVXEjCSEavvk+Hg3H6SZfGlPh/UfmWKGIvZbtobOEm3g==", - "requires": { - "chartjs-color-string": "^0.6.0", - "color-convert": "^0.5.3" - } - }, - "chartjs-color-string": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", - "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", - "requires": { - "color-name": "^1.0.0" - } - }, - "chokidar": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", - "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-transformer": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.3.1.tgz", - "integrity": "sha512-cKFwohpJbuMovS8xVLmn8N2AUbAuc8pVo4zEfsUVo8qgECOogns1WVk/FkOZoxhOPTyTYFckuoH+13FO+MQ8GA==" - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" - }, - "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "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", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "clone-deep": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz", - "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=", - "requires": { - "for-own": "^0.1.3", - "is-plain-object": "^2.0.1", - "kind-of": "^3.0.2", - "lazy-cache": "^1.0.3", - "shallow-clone": "^0.1.2" - } - }, - "clsx": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.0.4.tgz", - "integrity": "sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg==" - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collapse-white-space": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz", - "integrity": "sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - }, - "dependencies": { - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - } - } - }, - "color-convert": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=" - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==" - }, - "common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "compose-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", - "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", - "requires": { - "arity-n": "^1.0.4" - } - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - } - }, - "compute-scroll-into-view": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.11.tgz", - "integrity": "sha512-uUnglJowSe0IPmWOdDtrlHXof5CTIJitfJEyITHBW6zDVOGu9Pjk5puaLM73SLcwak0L4hEjO7Td88/a6P5i7A==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "confusing-browser-globals": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", - "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==" - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" - }, - "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", - "requires": { - "browserslist": "^4.8.5", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" - } - } - }, - "core-js-pure": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", - "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "create-react-app": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/create-react-app/-/create-react-app-2.1.8.tgz", - "integrity": "sha512-osHOZ3fw4BT4+L3CnhGsr/92CXEczQ/0fl/vd1Tbud4gT1ykt3a+zQlNJpOchDCnZjSqpHOxoWaH0XljFOhJLg==", - "requires": { - "chalk": "1.1.3", - "commander": "2.18.0", - "cross-spawn": "4.0.2", - "envinfo": "5.11.1", - "fs-extra": "5.0.0", - "hyperquest": "2.1.3", - "semver": "5.5.1", - "tar-pack": "3.4.1", - "tmp": "0.0.33", - "validate-npm-package-name": "3.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - } - } - }, - "create-react-class": { - "version": "15.6.3", - "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", - "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", - "requires": { - "fbjs": "^0.8.9", - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, - "create-react-context": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", - "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", - "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "requires": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-blank-pseudo": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", - "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", - "requires": { - "postcss": "^7.0.5" - } - }, - "css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" - }, - "css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "requires": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - } - }, - "css-has-pseudo": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", - "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^5.0.0-rc.4" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "css-loader": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz", - "integrity": "sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA==", - "requires": { - "camelcase": "^5.3.1", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^1.2.3", - "normalize-path": "^3.0.0", - "postcss": "^7.0.23", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.2", - "postcss-modules-scope": "^2.1.1", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.0.2", - "schema-utils": "^2.6.0" - }, - "dependencies": { - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - } - } - }, - "css-prefers-color-scheme": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", - "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", - "requires": { - "postcss": "^7.0.5" - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "css-to-react-native": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", - "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", - "requires": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^3.3.0" - } - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-vendor": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", - "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", - "requires": { - "@babel/runtime": "^7.8.3", - "is-in-browser": "^1.0.2" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.1.tgz", - "integrity": "sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" - } - } - }, - "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==" - }, - "cssdb": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", - "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", - "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", - "postcss-unique-selectors": "^4.0.1" - } - }, - "cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=" - }, - "cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=" - }, - "cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "requires": { - "postcss": "^7.0.0" - } - }, - "cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" - }, - "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", - "requires": { - "css-tree": "1.0.0-alpha.39" - }, - "dependencies": { - "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", - "requires": { - "mdn-data": "2.0.6", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - }, - "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", - "requires": { - "cssom": "0.3.x" - } - }, - "csstype": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.5.tgz", - "integrity": "sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA==" - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" - }, - "cytoscape": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.11.0.tgz", - "integrity": "sha512-xA9S5UiTjwFwZjxZCTIJjDU5ef2XSqw+/gk+bLcqdOZ496EoPSfnbozGRnKZhxKIVT++NNyWtT7fW1eLU7denQ==", - "requires": { - "heap": "^0.2.6", - "lodash.debounce": "^4.0.8" - } - }, - "cytoscape-clipboard": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cytoscape-clipboard/-/cytoscape-clipboard-2.2.1.tgz", - "integrity": "sha512-9TUSA138FZFBqEKmwDwpx4BRIScJkZRZUfxaiQIzek01rOYObOhH2NOIFbvDiitGtBUoW2bQjAizQW+vDDm9Qw==" - }, - "cytoscape-cxtmenu": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/cytoscape-cxtmenu/-/cytoscape-cxtmenu-3.1.1.tgz", - "integrity": "sha512-Rttr61Z3YP71GpCaN34IekO3rQJrf8fLv8ImCfQJ0J0ROGFMgk431WxXXStG40izZxZuspqi374x/3kSlT2idg==" - }, - "cytoscape-edgehandles": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/cytoscape-edgehandles/-/cytoscape-edgehandles-3.6.0.tgz", - "integrity": "sha512-XUzz+zmK42cN6l8uV7b66uUIZruAGgtgrfj/iuUOoCDWHMExARCS23bUju3Pqxywafe75Te3prXH0jrnZ+fYxw==", - "requires": { - "lodash.memoize": "^4.1.2", - "lodash.throttle": "^4.1.1" - } - }, - "cytoscape-grid-guide": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cytoscape-grid-guide/-/cytoscape-grid-guide-2.1.2.tgz", - "integrity": "sha512-PgyvTsIFL9jgoG3EBYfuMeg6ugTimg2UJPLYj3uJ6FMu+LUrUO93DaL07f9I4/bBGVlkSK1uH79oYjf18AyC1Q==", - "requires": { - "functional-red-black-tree": "^1.0.1" - } - }, - "cytoscape-node-html-label": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/cytoscape-node-html-label/-/cytoscape-node-html-label-1.1.5.tgz", - "integrity": "sha512-ztclrtuinJdJ0KwKTmd7Dgmqw+0WWXdZpRmxLUYU56DHIVek7Ma5Eh4FTGht0iyQUOakAPM0aZv3A4ifwMTW2Q==" - }, - "cytoscape-panzoom": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/cytoscape-panzoom/-/cytoscape-panzoom-2.5.3.tgz", - "integrity": "sha512-//qLOqbbFUCGddarNKHDZArItOJHgnkQ1TvxI9nV2/8aOOl/5wuEOHmra3fL/aWSjB4AYpYTG4LX7w96uWfRTQ==", - "requires": { - "jquery": "^1.4 || ^2.0 || ^3.0" - } - }, - "cytoscape-undo-redo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/cytoscape-undo-redo/-/cytoscape-undo-redo-1.3.2.tgz", - "integrity": "sha512-RnJI0uWc19gyWx/qWY2Q/vg159MR32dpXHk+QmQih2buLoC7fxYRBPSPgNGUkF8QIxSmkavQEic1ARQO7GBTtg==" - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "d3": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/d3/-/d3-4.10.2.tgz", - "integrity": "sha512-0PxXZbD+Remq9x4wdes1gs6rYcGJKA3+e0xwbma0r4ricKOKBHUHfDWcxKQICS3ZZxhzwNYWl196pxDqcAgRpw==", - "requires": { - "d3-array": "1.2.0", - "d3-axis": "1.0.8", - "d3-brush": "1.0.4", - "d3-chord": "1.0.4", - "d3-collection": "1.0.4", - "d3-color": "1.0.3", - "d3-dispatch": "1.0.3", - "d3-drag": "1.1.1", - "d3-dsv": "1.0.7", - "d3-ease": "1.0.3", - "d3-force": "1.0.6", - "d3-format": "1.2.0", - "d3-geo": "1.6.4", - "d3-hierarchy": "1.1.5", - "d3-interpolate": "1.1.5", - "d3-path": "1.0.5", - "d3-polygon": "1.0.3", - "d3-quadtree": "1.0.3", - "d3-queue": "3.0.7", - "d3-random": "1.1.0", - "d3-request": "1.0.6", - "d3-scale": "1.0.6", - "d3-selection": "1.1.0", - "d3-shape": "1.2.0", - "d3-time": "1.0.7", - "d3-time-format": "2.0.5", - "d3-timer": "1.0.7", - "d3-transition": "1.1.0", - "d3-voronoi": "1.1.2", - "d3-zoom": "1.5.0" - } - }, - "d3-array": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.0.tgz", - "integrity": "sha1-FH0mlyDhdMQFen9CvosPPyulMQg=" - }, - "d3-axis": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.8.tgz", - "integrity": "sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=" - }, - "d3-brush": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz", - "integrity": "sha1-AMLyOAGfJPbAoZSibUGhUw/+e8Q=", - "requires": { - "d3-dispatch": "1", - "d3-drag": "1", - "d3-interpolate": "1", - "d3-selection": "1", - "d3-transition": "1" - } - }, - "d3-chord": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.4.tgz", - "integrity": "sha1-fexPC6iG9xP+ERxF92NBT290yiw=", - "requires": { - "d3-array": "1", - "d3-path": "1" - } - }, - "d3-collection": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", - "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=" - }, - "d3-color": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.0.3.tgz", - "integrity": "sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=" - }, - "d3-dispatch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", - "integrity": "sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=" - }, - "d3-drag": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.1.1.tgz", - "integrity": "sha512-51aazbUuZZhPZzXv9xxwPOJTeDSVv8cXNd8oFxqJyR8ZBD9yLd09CFGSDSm3ArViHg2D5Wo1qCaKl7Efj/qchg==", - "requires": { - "d3-dispatch": "1", - "d3-selection": "1" - } - }, - "d3-dsv": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.7.tgz", - "integrity": "sha512-12szKhDhM/tM5U/Ch3hyJ7sMdcwPqMRmrUWitLLdPBMKO9Wuox95ezKZvemy/fxFbefLF/HIPKUmJMBLLuFDaQ==", - "requires": { - "commander": "2", - "iconv-lite": "0.4", - "rw": "1" - } - }, - "d3-ease": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.3.tgz", - "integrity": "sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=" - }, - "d3-force": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.0.6.tgz", - "integrity": "sha1-6n4bdzDiZkzTFPWU1nGMV8wTK3k=", - "requires": { - "d3-collection": "1", - "d3-dispatch": "1", - "d3-quadtree": "1", - "d3-timer": "1" - } - }, - "d3-format": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.2.0.tgz", - "integrity": "sha1-a0gLqohohdRlHcJIqPSsnaFtsHo=" - }, - "d3-geo": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.6.4.tgz", - "integrity": "sha1-8g4eRhyxhF9ai+Vatvh2VCp+MZk=", - "requires": { - "d3-array": "1" - } - }, - "d3-hierarchy": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz", - "integrity": "sha1-ochFxC+Eoga88cAcAQmOpN2qeiY=" - }, - "d3-interpolate": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.1.5.tgz", - "integrity": "sha1-aeCZ/zkhRxblY8muw+qdHqS4p58=", - "requires": { - "d3-color": "1" - } - }, - "d3-path": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", - "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" - }, - "d3-polygon": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.3.tgz", - "integrity": "sha1-FoiOkCZGCTPysXllKtN4Ik04LGI=" - }, - "d3-quadtree": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.3.tgz", - "integrity": "sha1-rHmH4+I/6AWpkPKOG1DTj8uCJDg=" - }, - "d3-queue": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/d3-queue/-/d3-queue-3.0.7.tgz", - "integrity": "sha1-yTouVLQXwJWRKdfXP2z31Ckudhg=" - }, - "d3-random": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.0.tgz", - "integrity": "sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=" - }, - "d3-request": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-request/-/d3-request-1.0.6.tgz", - "integrity": "sha512-FJj8ySY6GYuAJHZMaCQ83xEYE4KbkPkmxZ3Hu6zA1xxG2GD+z6P+Lyp+zjdsHf0xEbp2xcluDI50rCS855EQ6w==", - "requires": { - "d3-collection": "1", - "d3-dispatch": "1", - "d3-dsv": "1", - "xmlhttprequest": "1" - } - }, - "d3-scale": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-1.0.6.tgz", - "integrity": "sha1-vOGdqA06DPQiyVQ64zIghiILNO0=", - "requires": { - "d3-array": "^1.2.0", - "d3-collection": "1", - "d3-color": "1", - "d3-format": "1", - "d3-interpolate": "1", - "d3-time": "1", - "d3-time-format": "2" - } - }, - "d3-selection": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.1.0.tgz", - "integrity": "sha1-GZhoSJZIj4OcoDchI9o08dMYgJw=" - }, - "d3-shape": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.0.tgz", - "integrity": "sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=", - "requires": { - "d3-path": "1" - } - }, - "d3-time": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.7.tgz", - "integrity": "sha1-lMr27bt4ebuAnQ0fdXK8SEgvcnA=" - }, - "d3-time-format": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.0.5.tgz", - "integrity": "sha1-nXeAIE98kRnJFwsaVttN6aivly4=", - "requires": { - "d3-time": "1" - } - }, - "d3-timer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.7.tgz", - "integrity": "sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==" - }, - "d3-transition": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.0.tgz", - "integrity": "sha1-z8hcdOUjkyQpBUZiNXKZBWDDlm8=", - "requires": { - "d3-color": "1", - "d3-dispatch": "1", - "d3-ease": "1", - "d3-interpolate": "1", - "d3-selection": "^1.1.0", - "d3-timer": "1" - } - }, - "d3-voronoi": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", - "integrity": "sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=" - }, - "d3-zoom": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.5.0.tgz", - "integrity": "sha512-tc/ONeSUVuwHczjjK4jQPd0T1iZ+lfsz8TbguAAceY5qs057hp4WLglkPWValkuVjCyeGpqiA2iTm8S++NJ84w==", - "requires": { - "d3-dispatch": "1", - "d3-drag": "1", - "d3-interpolate": "1", - "d3-selection": "1", - "d3-transition": "1" - } - }, - "damerau-levenshtein": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", - "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - }, - "dependencies": { - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } - } - }, - "debounce": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz", - "integrity": "sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg==" - }, - "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" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "deepmerge": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", - "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==" - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" - }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==" - }, - "detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - } - }, - "diff-sequences": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", - "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" - } - } - }, - "dir-glob": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", - "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", - "requires": { - "arrify": "^1.0.1", - "path-type": "^3.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "requires": { - "utila": "~0.4" - } - }, - "dom-helpers": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", - "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", - "requires": { - "@babel/runtime": "^7.1.2" - } - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "requires": { - "webidl-conversions": "^4.0.2" - } - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz", - "integrity": "sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==", - "requires": { - "no-case": "^3.0.3", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - } - } - }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "requires": { - "is-obj": "^2.0.0" - } - }, - "dotenv": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", - "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, - "downshift": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/downshift/-/downshift-3.3.5.tgz", - "integrity": "sha512-OLBKLfP8cUaB7/wF0Al74v+znYOV/BG6hMGIj/JMuPcnNHQ/1WrF3btCZx+KnJcYtfMdQHEwWv0yC1cdPinyXw==", - "requires": { - "@babel/runtime": "^7.4.5", - "@reach/auto-id": "^0.2.0", - "compute-scroll-into-view": "^1.0.9", - "prop-types": "^15.7.2", - "react-is": "^16.9.0" - }, - "dependencies": { - "react-is": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.10.2.tgz", - "integrity": "sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA==" - } - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "requires": { - "readable-stream": "~1.1.9" - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "electron-to-chromium": { - "version": "1.3.475", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.475.tgz", - "integrity": "sha512-vcTeLpPm4+ccoYFXnepvkFt0KujdyrBU19KNEO40Pnkhta6mUi2K0Dn7NmpRcNz7BvysnSqeuIYScP003HWuYg==" - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", - "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==" - }, - "envinfo": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.11.1.tgz", - "integrity": "sha512-rmEr5fZLYYSRCj3kDhriz6ju/oMgEzC92MwF3mggFba2EMjK+CUE13MQo17Ua2CDT+KFFPAGFosodUoL/wxjug==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escodegen": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.2.tgz", - "integrity": "sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==", - "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true - } - } - }, - "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "requires": { - "type-fest": "^0.8.1" - } - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "eslint-config-react-app": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz", - "integrity": "sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ==", - "requires": { - "confusing-browser-globals": "^1.0.9" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - } - }, - "eslint-loader": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-3.0.3.tgz", - "integrity": "sha512-+YRqB95PnNvxNp1HEjQmvf9KNvCin5HXYYseOXVC2U0KEcw4IkQ2IQEBG46j7+gW39bMzeu0GsUhVbBY3Votpw==", - "requires": { - "fs-extra": "^8.1.0", - "loader-fs-cache": "^1.0.2", - "loader-utils": "^1.2.3", - "object-hash": "^2.0.1", - "schema-utils": "^2.6.1" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" - } - } - }, - "eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", - "requires": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "requires": { - "find-up": "^2.1.0" - } - } - } - }, - "eslint-plugin-flowtype": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.6.0.tgz", - "integrity": "sha512-W5hLjpFfZyZsXfo5anlu7HM970JBDqbEshAJUkeczP6BFCIfJXuiIBQXyberLRtOStT0OGPF8efeTbxlHk4LpQ==", - "requires": { - "lodash": "^4.17.15" - } - }, - "eslint-plugin-import": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", - "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", - "requires": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - } - } - }, - "eslint-plugin-jsx-a11y": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", - "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", - "requires": { - "@babel/runtime": "^7.4.5", - "aria-query": "^3.0.0", - "array-includes": "^3.0.3", - "ast-types-flow": "^0.0.7", - "axobject-query": "^2.0.2", - "damerau-levenshtein": "^1.0.4", - "emoji-regex": "^7.0.2", - "has": "^1.0.3", - "jsx-ast-utils": "^2.2.1" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - } - } - }, - "eslint-plugin-react": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz", - "integrity": "sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ==", - "requires": { - "array-includes": "^3.1.1", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.2.3", - "object.entries": "^1.1.1", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", - "prop-types": "^15.7.2", - "resolve": "^1.15.1", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.2", - "xregexp": "^4.3.0" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "requires": { - "esutils": "^2.0.2" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "eslint-plugin-react-hooks": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", - "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==" - }, - "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz", - "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==" - }, - "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", - "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==" - } - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" - }, - "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==" - }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", - "requires": { - "original": "^1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==" - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "exenv": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", - "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expect": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", - "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", - "requires": { - "@jest/types": "^24.9.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.9.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - } - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - } - } - }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "requires": { - "bser": "2.1.1" - } - }, - "fbemitter": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-2.1.1.tgz", - "integrity": "sha1-Uj4U/a9SSIBbsC9i78M75wP1GGU=", - "requires": { - "fbjs": "^0.8.4" - } - }, - "fbjs": { - "version": "0.8.17", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", - "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", - "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - }, - "dependencies": { - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" - } - } - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "requires": { - "flat-cache": "^2.0.1" - } - }, - "file-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz", - "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==", - "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^2.5.0" - } - }, - "file-selector": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.1.12.tgz", - "integrity": "sha512-Kx7RTzxyQipHuiqyZGf+Nz4vY9R1XGxuQl/hLoJwq+J4avk/9wxxgZyHKtbyIPJmbD4A66DWGYfyykWNpcYutQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "filesize": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz", - "integrity": "sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg==" - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" - }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==" - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "flux": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/flux/-/flux-3.1.3.tgz", - "integrity": "sha1-0jvtUVp5oi2TOrU6tK2hnQWy8Io=", - "requires": { - "fbemitter": "^2.0.0", - "fbjs": "^0.8.0" - } - }, - "follow-redirects": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.0.tgz", - "integrity": "sha512-JgawlbfBQKjbKegPn8vUsvJqplE7KHJuhGO4yPcb+ZOIYKSr+xobMVlfRBToZwZUUxy7lFiKBdFNloz9ui368Q==" - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "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" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "fork-ts-checker-webpack-plugin": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz", - "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==", - "requires": { - "babel-code-frame": "^6.22.0", - "chalk": "^2.4.1", - "chokidar": "^3.3.0", - "micromatch": "^3.1.10", - "minimatch": "^3.0.4", - "semver": "^5.6.0", - "tapable": "^1.0.0", - "worker-rpc": "^0.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "optional": true - }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", - "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", - "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "github-markdown-css": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-3.0.1.tgz", - "integrity": "sha512-9G5CIPsHoyk5ObDsb/H4KTi23J8KE1oDd4KYU51qwqeM+lKWAiO7abpSgCkyWswgmSKBiuE7/4f8xUz7f2qAiQ==" - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "globby": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", - "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", - "requires": { - "array-union": "^1.0.1", - "dir-glob": "2.0.0", - "fast-glob": "^2.0.2", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - }, - "dependencies": { - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" - } - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" - }, - "gud": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", - "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" - }, - "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", - "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - } - } - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "harmony-reflect": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.1.tgz", - "integrity": "sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "heap": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz", - "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=" - }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" - }, - "history": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/history/-/history-4.9.0.tgz", - "integrity": "sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^2.2.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^0.4.0" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", - "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", - "requires": { - "react-is": "^16.7.0" - } - }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" - }, - "html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "requires": { - "whatwg-encoding": "^1.0.1" - } - }, - "html-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", - "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", - "requires": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", - "he": "^1.2.0", - "param-case": "^3.0.3", - "relateurl": "^0.2.7", - "terser": "^4.6.3" - }, - "dependencies": { - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" - } - } - }, - "html-to-react": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.4.1.tgz", - "integrity": "sha512-Ys2gGxF8LBF9bD8tbnsU0xgEDOTC3Sy81mtpIH/61hSqGE1l4QetnN1yv0oAK/PuvwABmiNS+ggqvuzo+GfoiA==", - "requires": { - "domhandler": "^3.0", - "htmlparser2": "^4.0", - "lodash.camelcase": "^4.3.0", - "ramda": "^0.26" - }, - "dependencies": { - "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" - }, - "domhandler": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.0.0.tgz", - "integrity": "sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==", - "requires": { - "domelementtype": "^2.0.1" - } - }, - "domutils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.0.0.tgz", - "integrity": "sha512-n5SelJ1axbO636c2yUtOGia/IcJtVtlhQbFiVDBZHKV5ReJO1ViX7sFEemtuyoAnBxk5meNSYgA8V4s0271efg==", - "requires": { - "dom-serializer": "^0.2.1", - "domelementtype": "^2.0.1", - "domhandler": "^3.0.0" - } - }, - "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" - }, - "htmlparser2": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.0.0.tgz", - "integrity": "sha512-cChwXn5Vam57fyXajDtPXL1wTYc8JtLbr2TN76FYu05itVVVealxLowe2B3IEznJG4p9HAYn/0tJaRlGuEglFQ==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^3.0.0", - "domutils": "^2.0.0", - "entities": "^2.0.0" - } - } - } - }, - "html-webpack-plugin": { - "version": "4.0.0-beta.11", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz", - "integrity": "sha512-4Xzepf0qWxf8CGg7/WQM5qBB2Lc/NFI7MhU59eUDTkuQp3skZczH4UA1d6oQyDEIoMDgERVhRyTdtUPZ5s5HBg==", - "requires": { - "html-minifier-terser": "^5.0.1", - "loader-utils": "^1.2.3", - "lodash": "^4.17.15", - "pretty-error": "^2.1.1", - "tapable": "^1.1.3", - "util.promisify": "1.0.0" - }, - "dependencies": { - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - } - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "http-parser-js": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz", - "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==" - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" - }, - "hyperquest": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-2.1.3.tgz", - "integrity": "sha512-fUuDOrB47PqNK/BAMOS13v41UoaqIxqSLHX6CAbOD7OfT+/GCWO1/vPLfTNutOeXrv1ikuaZ3yux+33Z9vh+rw==", - "requires": { - "buffer-from": "^0.1.1", - "duplexer2": "~0.0.2", - "through2": "~0.6.3" - } - }, - "hyphenate-style-name": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz", - "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "requires": { - "postcss": "^7.0.14" - } - }, - "identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", - "requires": { - "harmony-reflect": "^1.4.6" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - }, - "immer": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz", - "integrity": "sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==" - }, - "import": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/import/-/import-0.0.6.tgz", - "integrity": "sha1-0Ot534aqJnfG22FXilISswMeYEI=", - "requires": { - "optimist": "0.3.x" - }, - "dependencies": { - "optimist": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", - "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", - "requires": { - "wordwrap": "~0.0.2" - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - } - } - }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "requires": { - "import-from": "^2.1.0" - } - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "requires": { - "resolve-from": "^3.0.0" - } - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "indefinite-observable": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-1.0.2.tgz", - "integrity": "sha512-Mps0898zEduHyPhb7UCgNmfzlqNZknVmaFz5qzr0mm04YQ5FGLhAyK/dJ+NaRxGyR6juQXIxh5Ev0xx+qq0nYA==", - "requires": { - "symbol-observable": "1.2.0" - } - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "inquirer": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", - "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, - "internal-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", - "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", - "requires": { - "es-abstract": "^1.17.0-next.1", - "has": "^1.0.3", - "side-channel": "^1.0.2" - } - }, - "interweave": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/interweave/-/interweave-11.2.0.tgz", - "integrity": "sha512-33h9LOXbT52tMin3IyLBPcd5RbiwroP/Sxr0OamnJJU7A/jh0XtZKGvdcSNKYRC7sLZuDk+ZJ2XVrmkcMU5i6w==", - "requires": { - "@types/react": "*", - "escape-html": "^1.0.3", - "prop-types": "^15.7.2" - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-alphabetical": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", - "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==" - }, - "is-alphanumerical": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz", - "integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==", - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-decimal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz", - "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==" - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" - }, - "is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==" - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hexadecimal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz", - "integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA==" - }, - "is-in-browser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", - "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" - }, - "is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" - }, - "is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", - "requires": { - "html-comment-regex": "^1.1.0" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-what": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.3.1.tgz", - "integrity": "sha512-seFn10yAXy+yJlTRO+8VfiafC+0QJanGLMPTBWLrJm/QPauuchy0UXh8B6H5o9VA8BAzk0iYievt6mNp6gfaqA==" - }, - "is-whitespace-character": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz", - "integrity": "sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-word-character": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.3.tgz", - "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==" - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==" - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "requires": { - "html-escaper": "^2.0.0" - } - }, - "jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", - "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", - "requires": { - "import-local": "^2.0.0", - "jest-cli": "^24.9.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "jest-cli": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", - "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", - "requires": { - "@jest/core": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "import-local": "^2.0.0", - "is-ci": "^2.0.0", - "jest-config": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "prompts": "^2.0.1", - "realpath-native": "^1.1.0", - "yargs": "^13.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-changed-files": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", - "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", - "requires": { - "@jest/types": "^24.9.0", - "execa": "^1.0.0", - "throat": "^4.0.0" - } - }, - "jest-config": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", - "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.9.0", - "@jest/types": "^24.9.0", - "babel-jest": "^24.9.0", - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^24.9.0", - "jest-environment-node": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.9.0", - "realpath-native": "^1.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-diff": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", - "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "requires": { - "detect-newline": "^2.1.0" - } - }, - "jest-each": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", - "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", - "requires": { - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-environment-jsdom": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", - "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0", - "jsdom": "^11.5.1" - } - }, - "jest-environment-jsdom-fourteen": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz", - "integrity": "sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q==", - "requires": { - "@jest/environment": "^24.3.0", - "@jest/fake-timers": "^24.3.0", - "@jest/types": "^24.3.0", - "jest-mock": "^24.0.0", - "jest-util": "^24.0.0", - "jsdom": "^14.1.0" - }, - "dependencies": { - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" - }, - "jsdom": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.1.0.tgz", - "integrity": "sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng==", - "requires": { - "abab": "^2.0.0", - "acorn": "^6.0.4", - "acorn-globals": "^4.3.0", - "array-equal": "^1.0.0", - "cssom": "^0.3.4", - "cssstyle": "^1.1.1", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.0", - "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.1.3", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.5", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.5.0", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^6.1.2", - "xml-name-validator": "^3.0.0" - } - }, - "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, - "jest-environment-node": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", - "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0" - } - }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==" - }, - "jest-haste-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", - "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", - "requires": { - "@jest/types": "^24.9.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.9.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - }, - "dependencies": { - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - } - } - }, - "jest-jasmine2": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", - "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "co": "^4.6.0", - "expect": "^24.9.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0", - "throat": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-leak-detector": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", - "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", - "requires": { - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-matcher-utils": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", - "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-message-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", - "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-mock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", - "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", - "requires": { - "@jest/types": "^24.9.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==" - }, - "jest-regex-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==" - }, - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-resolve-dependencies": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", - "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", - "requires": { - "@jest/types": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-snapshot": "^24.9.0" - } - }, - "jest-runner": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", - "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.4.2", - "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-leak-detector": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "source-map-support": "^0.5.6", - "throat": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-runtime": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", - "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^13.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-serializer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==" - }, - "jest-snapshot": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", - "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "expect": "^24.9.0", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^24.9.0", - "semver": "^6.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", - "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", - "requires": { - "@jest/console": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/source-map": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-watch-typeahead": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz", - "integrity": "sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q==", - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^2.4.1", - "jest-regex-util": "^24.9.0", - "jest-watcher": "^24.3.0", - "slash": "^3.0.0", - "string-length": "^3.1.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "string-length": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", - "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-watcher": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", - "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", - "requires": { - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "jest-util": "^24.9.0", - "string-length": "^2.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jquery": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", - "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", - "requires": { - "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.1", - "escodegen": "^1.9.1", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==" - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" - }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jss": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.1.1.tgz", - "integrity": "sha512-Xz3qgRUFlxbWk1czCZibUJqhVPObrZHxY3FPsjCXhDld4NOj1BgM14Ir5hVm+Qr6OLqVljjGvoMcCdXNOAbdkQ==", - "requires": { - "@babel/runtime": "^7.3.1", - "csstype": "^2.6.5", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - }, - "jss-camel-case": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz", - "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==", - "requires": { - "hyphenate-style-name": "^1.0.2" - } - }, - "jss-default-unit": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz", - "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg==" - }, - "jss-global": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz", - "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q==" - }, - "jss-plugin-camel-case": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.1.1.tgz", - "integrity": "sha512-MDIaw8FeD5uFz1seQBKz4pnvDLnj5vIKV5hXSVdMaAVq13xR6SVTVWkIV/keyTs5txxTvzGJ9hXoxgd1WTUlBw==", - "requires": { - "@babel/runtime": "^7.3.1", - "hyphenate-style-name": "^1.0.3", - "jss": "10.1.1" - } - }, - "jss-plugin-default-unit": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.1.1.tgz", - "integrity": "sha512-UkeVCA/b3QEA4k0nIKS4uWXDCNmV73WLHdh2oDGZZc3GsQtlOCuiH3EkB/qI60v2MiCq356/SYWsDXt21yjwdg==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.1.1" - } - }, - "jss-plugin-global": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.1.1.tgz", - "integrity": "sha512-VBG3wRyi3Z8S4kMhm8rZV6caYBegsk+QnQZSVmrWw6GVOT/Z4FA7eyMu5SdkorDlG/HVpHh91oFN56O4R9m2VA==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.1.1" - } - }, - "jss-plugin-nested": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.1.1.tgz", - "integrity": "sha512-ozEu7ZBSVrMYxSDplPX3H82XHNQk2DQEJ9TEyo7OVTPJ1hEieqjDFiOQOxXEj9z3PMqkylnUbvWIZRDKCFYw5Q==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.1.1", - "tiny-warning": "^1.0.2" - } - }, - "jss-plugin-props-sort": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.1.1.tgz", - "integrity": "sha512-g/joK3eTDZB4pkqpZB38257yD4LXB0X15jxtZAGbUzcKAVUHPl9Jb47Y7lYmiGsShiV4YmQRqG1p2DHMYoK91g==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.1.1" - } - }, - "jss-plugin-rule-value-function": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.1.1.tgz", - "integrity": "sha512-ClV1lvJ3laU9la1CUzaDugEcwnpjPTuJ0yGy2YtcU+gG/w9HMInD5vEv7xKAz53Bk4WiJm5uLOElSEshHyhKNw==", - "requires": { - "@babel/runtime": "^7.3.1", - "jss": "10.1.1" - } - }, - "jss-plugin-vendor-prefixer": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.1.1.tgz", - "integrity": "sha512-09MZpQ6onQrhaVSF6GHC4iYifQ7+4YC/tAP6D4ZWeZotvCMq1mHLqNKRIaqQ2lkgANjlEot2JnVi1ktu4+L4pw==", - "requires": { - "@babel/runtime": "^7.3.1", - "css-vendor": "^2.0.7", - "jss": "10.1.1" - } - }, - "jss-props-sort": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz", - "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g==" - }, - "jss-vendor-prefixer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz", - "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==", - "requires": { - "css-vendor": "^0.3.8" - }, - "dependencies": { - "css-vendor": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", - "integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=", - "requires": { - "is-in-browser": "^1.0.2" - } - } - } - }, - "jsx-ast-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", - "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", - "requires": { - "array-includes": "^3.1.1", - "object.assign": "^4.1.0" - } - }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" - }, - "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" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" - }, - "last-call-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "requires": { - "lodash": "^4.17.5", - "webpack-sources": "^1.1.0" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "requires": { - "invert-kv": "^2.0.0" - } - }, - "left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" - }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "requires": { - "leven": "^3.1.0" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "loader-fs-cache": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz", - "integrity": "sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==", - "requires": { - "find-cache-dir": "^0.1.1", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "find-cache-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", - "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", - "requires": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "requires": { - "find-up": "^1.0.0" - } - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "lodash.curry": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", - "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA=" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" - }, - "lodash.flow": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", - "integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=" - }, - "lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" - }, - "lodash.isobject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", - "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=" - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" - }, - "lodash.tonumber": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz", - "integrity": "sha1-C5azGzVnJ5Prf1pj7nkfG56QJdk=" - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" - }, - "loglevel": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", - "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz", - "integrity": "sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==", - "requires": { - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - } - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "requires": { - "tmpl": "1.0.x" - } - }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==" - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown-escapes": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz", - "integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==" - }, - "material-icons": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-0.3.1.tgz", - "integrity": "sha512-5Hbj76A6xDPcDZEbM4oxTknhWuMwGWnAHVLLPCEq9eVlcHb0fn4koU9ZeyMy1wjARtDEPAHfd5ZdL2Re5hf0zQ==" - }, - "material-icons-react": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/material-icons-react/-/material-icons-react-1.0.4.tgz", - "integrity": "sha512-ZTCD0Nl+/hTyvONWz8N6gCrpLWfbkOF77NWbD9ThYdkBK8gtvFMc/ORS8nfU0qlmS1wNdVXf1oTaBRWLCiNkxw==", - "requires": { - "prop-types": "^15.6.1", - "react": "^15.0.0", - "react-dom": "^15.0.0", - "webfontloader": "^1.6.28" - }, - "dependencies": { - "react": { - "version": "15.6.2", - "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz", - "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=", - "requires": { - "create-react-class": "^15.6.0", - "fbjs": "^0.8.9", - "loose-envify": "^1.1.0", - "object-assign": "^4.1.0", - "prop-types": "^15.5.10" - } - }, - "react-dom": { - "version": "15.6.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz", - "integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=", - "requires": { - "fbjs": "^0.8.9", - "loose-envify": "^1.1.0", - "object-assign": "^4.1.0", - "prop-types": "^15.5.10" - } - } - } - }, - "material-ui-chip-input": { - "version": "2.0.0-beta.2", - "resolved": "https://registry.npmjs.org/material-ui-chip-input/-/material-ui-chip-input-2.0.0-beta.2.tgz", - "integrity": "sha512-E+Jxv9FdAvYUsZIPohoqxqdW7LwFYOCunInJGh2WSDJ2IlCUdpCOEVazqgLQH6thaFarKDu44uGYpD1v3RdqDg==", - "requires": { - "clsx": "^1.0.4", - "prop-types": "^15.6.1" - } - }, - "material-ui-nested-menu-item": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/material-ui-nested-menu-item/-/material-ui-nested-menu-item-1.0.2.tgz", - "integrity": "sha512-LZb8xI0FrAI/A3P2vT3CB9bmSoOFWOK0dikTc1t9VvEpp1a8hZkbVUz7VhETnoLUYu3NXCkgulmXcl3zitqI9A==" - }, - "md5-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-4.0.0.tgz", - "integrity": "sha512-UC0qFwyAjn4YdPpKaDNw6gNxRf7Mcx7jC1UGCY4boCzgvU2Aoc1mOGzTtrjjLKhM5ivsnhoKpQVxKPp+1j1qwg==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdast-add-list-metadata": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz", - "integrity": "sha512-fB/VP4MJ0LaRsog7hGPxgOrSL3gE/2uEdZyDuSEnKCv/8IkYHiDkIQSbChiJoHyxZZXZ9bzckyRk+vNxFzh8rA==", - "requires": { - "unist-util-visit-parents": "1.1.2" - } - }, - "mdbreact": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/mdbreact/-/mdbreact-4.21.1.tgz", - "integrity": "sha512-UmgLQh2WRXMdHrfhwavtMg2Gw/sq1gfBpU7+ukDEzU43wnBMZxll5dqGUS9ReSWKIJwHXhxM+8xxwFa2dsYEHg==", - "requires": { - "@date-io/moment": "1.3.5", - "@fortawesome/fontawesome-free": "^5.10.2", - "@material-ui/core": "3.9.3", - "bootstrap-css-only": "4.3.1", - "chart.js": "2.8.0", - "classnames": "2.2.6", - "material-ui-pickers": "2.2.4", - "moment": "2.24.0", - "perfect-scrollbar": "1.4.0", - "raf": "3.4.1", - "react-chartjs-2": "2.7.6", - "react-image-lightbox": "5.1.0", - "react-numeric-input": "2.2.3", - "react-popper": "^1.3.4", - "react-router-dom": "^5.0.1", - "react-scroll": "1.7.11", - "react-toastify": "5.1.0", - "react-transition-group": "4.0.1" - }, - "dependencies": { - "@material-ui/core": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-3.9.3.tgz", - "integrity": "sha512-REIj62+zEvTgI/C//YL4fZxrCVIySygmpZglsu/Nl5jPqy3CDjZv1F9ubBYorHqmRgeVPh64EghMMWqk4egmfg==", - "requires": { - "@babel/runtime": "^7.2.0", - "@material-ui/system": "^3.0.0-alpha.0", - "@material-ui/utils": "^3.0.0-alpha.2", - "@types/jss": "^9.5.6", - "@types/react-transition-group": "^2.0.8", - "brcast": "^3.0.1", - "classnames": "^2.2.5", - "csstype": "^2.5.2", - "debounce": "^1.1.0", - "deepmerge": "^3.0.0", - "dom-helpers": "^3.2.1", - "hoist-non-react-statics": "^3.2.1", - "is-plain-object": "^2.0.4", - "jss": "^9.8.7", - "jss-camel-case": "^6.0.0", - "jss-default-unit": "^8.0.2", - "jss-global": "^3.0.0", - "jss-nested": "^6.0.1", - "jss-props-sort": "^6.0.0", - "jss-vendor-prefixer": "^7.0.0", - "normalize-scroll-left": "^0.1.2", - "popper.js": "^1.14.1", - "prop-types": "^15.6.0", - "react-event-listener": "^0.6.2", - "react-transition-group": "^2.2.1", - "recompose": "0.28.0 - 0.30.0", - "warning": "^4.0.1" - }, - "dependencies": { - "jss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz", - "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==", - "requires": { - "warning": "^3.0.0" - }, - "dependencies": { - "warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, - "react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", - "requires": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - } - } - } - }, - "@material-ui/system": { - "version": "3.0.0-alpha.2", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-3.0.0-alpha.2.tgz", - "integrity": "sha512-odmxQ0peKpP7RQBQ8koly06YhsPzcoVib1vByVPBH4QhwqBXuYoqlCjt02846fYspAqkrWzjxnWUD311EBbxOA==", - "requires": { - "@babel/runtime": "^7.2.0", - "deepmerge": "^3.0.0", - "prop-types": "^15.6.0", - "warning": "^4.0.1" - } - }, - "@material-ui/utils": { - "version": "3.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-3.0.0-alpha.3.tgz", - "integrity": "sha512-rwMdMZptX0DivkqBuC+Jdq7BYTXwqKai5G5ejPpuEDKpWzi1Oxp+LygGw329FrKpuKeiqpcymlqJTjmy+quWng==", - "requires": { - "@babel/runtime": "^7.2.0", - "prop-types": "^15.6.0", - "react-is": "^16.6.3" - } - }, - "@types/react-transition-group": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.9.2.tgz", - "integrity": "sha512-5Fv2DQNO+GpdPZcxp2x/OQG/H19A01WlmpjVD9cKvVFmoVLOZ9LvBgSWG6pSXIU4og5fgbvGPaCV5+VGkWAEHA==", - "requires": { - "@types/react": "*" - } - }, - "jss": { - "version": "9.8.7", - "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", - "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", - "requires": { - "is-in-browser": "^1.1.3", - "symbol-observable": "^1.1.0", - "warning": "^3.0.0" - }, - "dependencies": { - "warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, - "jss-nested": { - "dependencies": { - "warning": {} - } - }, - "material-ui-pickers": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/material-ui-pickers/-/material-ui-pickers-2.2.4.tgz", - "integrity": "sha512-QCQh08Ylmnt+o4laW+rPs92QRAcESv3sPXl50YadLm++rAZAXAOh3K8lreGdynCMYFgZfdyu81Oz9xzTlAZNfw==", - "requires": { - "@types/react-text-mask": "^5.4.3", - "clsx": "^1.0.2", - "react-event-listener": "^0.6.6", - "react-text-mask": "^5.4.3", - "react-transition-group": "^2.5.3", - "tslib": "^1.9.3" - }, - "dependencies": { - "react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", - "requires": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - } - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "react-chartjs-2": { - "version": "2.7.6", - "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.7.6.tgz", - "integrity": "sha512-xDr0jhgt/o26atftXxTVsepz+QYZI2GNKBYpxtLvYgwffLUm18a9n562reUJAHvuwKsy2v+qMlK5HyjFtSW0mg==", - "requires": { - "lodash": "^4.17.4", - "prop-types": "^15.5.8" - } - }, - "react-router": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.2.tgz", - "integrity": "sha512-yjEuMFy1ONK246B+rsa0cUam5OeAQ8pyclRDgpxuSCrAlJ1qN9uZ5IgyKC7gQg0w8OM50NXHEegPh/ks9YuR2A==", - "requires": { - "@babel/runtime": "^7.1.2", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "mini-create-react-context": "^0.3.0", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-router-dom": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.1.2.tgz", - "integrity": "sha512-7BPHAaIwWpZS074UKaw1FjVdZBSVWEk8IuDXdB+OkLb8vd/WRQIpA4ag9WQk61aEfQs47wHyjWUoUGGZxpQXew==", - "requires": { - "@babel/runtime": "^7.1.2", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.1.2", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-transition-group": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.0.1.tgz", - "integrity": "sha512-SsLcBYhO4afXJC9esL8XMxi/y0ZvEc7To0TvtrBELqzpjXQHPZOTxvuPh2/4EhYc0uSMfp2SExIxsyJ0pBdNzg==", - "requires": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - } - }, - "sass-loader": {} - } - }, - "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "memoize-one": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", - "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==" - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "merge-anything": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.1.tgz", - "integrity": "sha512-dYOIAl9GFCJNctSIHWOj9OJtarCjsD16P8ObCl6oxrujAG+kOvlwJuOD9/O9iYZ9aTi1RGpGTG9q9etIvuUikQ==", - "requires": { - "is-what": "^3.3.1" - } - }, - "merge-deep": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.2.tgz", - "integrity": "sha512-T7qC8kg4Zoti1cFd8Cr0M+qaZfOwjlPDEdZIIPPB2JZctjaPM4fX+i7HOId69tAti2fvO6X5ldfYUONDODsrkA==", - "requires": { - "arr-union": "^3.1.0", - "clone-deep": "^0.2.4", - "kind-of": "^3.0.2" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "microevent.ts": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", - "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" - } - } - }, - "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" - }, - "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" - }, - "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "requires": { - "mime-db": "1.44.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mini-create-react-context": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz", - "integrity": "sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw==", - "requires": { - "@babel/runtime": "^7.4.0", - "gud": "^1.0.0", - "tiny-warning": "^1.0.2" - } - }, - "mini-css-extract-plugin": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", - "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", - "requires": { - "loader-utils": "^1.1.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz", - "integrity": "sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ==", - "requires": { - "minipass": "^3.0.0" - } - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mixin-object": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", - "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", - "requires": { - "for-in": "^0.1.3", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-in": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", - "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=" - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - } - } - }, - "moment": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", - "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==" - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "no-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.3.tgz", - "integrity": "sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==", - "requires": { - "lower-case": "^2.0.1", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - } - } - }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==" - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "requires": { - "inherits": "2.0.3" - } - } - } - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" - }, - "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", - "requires": { - "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", - "shellwords": "^0.1.1", - "which": "^1.3.0" - } - }, - "node-releases": { - "version": "1.1.58", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", - "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==" - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" - }, - "normalize-scroll-left": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-scroll-left/-/normalize-scroll-left-0.1.2.tgz", - "integrity": "sha512-F9YMRls0zCF6BFIE2YnXDRpHPpfd91nOIaNdDgrx5YMoPLo8Wqj+6jNXHQsYBavJeXP4ww8HCt0xQAKc5qk2Fg==" - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "requires": { - "boolbase": "~1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" - }, - "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=" - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-hash": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", - "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==" - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" - }, - "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object-path": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", - "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.entries": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", - "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "has": "^1.0.3" - } - }, - "object.fromentries": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", - "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - } - }, - "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/open/-/open-7.0.4.tgz", - "integrity": "sha512-brSA+/yq+b08Hsr4c8fsEW2CRzk1BmfN3SAK/5VCHQ9bdoZJ4qa/+AfR0xHjlbbZUyPkUHs1b8x1RqdyZdkVqQ==", - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "dependencies": { - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "requires": { - "is-docker": "^2.0.0" - } - } - } - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimize-css-assets-webpack-plugin": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", - "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", - "requires": { - "cssnano": "^4.1.10", - "last-call-webpack-plugin": "^3.0.0" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "requires": { - "url-parse": "^1.4.3" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "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=" - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" - }, - "p-each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", - "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", - "requires": { - "p-reduce": "^1.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-reduce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", - "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=" - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "requires": { - "retry": "^0.12.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "param-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.3.tgz", - "integrity": "sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA==", - "requires": { - "dot-case": "^3.0.3", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - } - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - }, - "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - } - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascal-case": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz", - "integrity": "sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==", - "requires": { - "no-case": "^3.0.3", - "tslib": "^1.10.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - } - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "requires": { - "isarray": "0.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "requires": { - "pify": "^3.0.0" - } - }, - "pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "perfect-scrollbar": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.4.0.tgz", - "integrity": "sha512-/2Sk/khljhdrsamjJYS5NjrH+GKEHEwh7zFSiYyxROyYKagkE4kSn2zDQDRTOMo8mpT2jikxx6yI1dG7lNP/hw==" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - } - } - }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "requires": { - "find-up": "^2.1.0" - } - }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" - }, - "pnp-webpack-plugin": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", - "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", - "requires": { - "ts-pnp": "^1.1.6" - } - }, - "popper.js": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz", - "integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA==" - }, - "portfinder": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", - "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, - "postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-attribute-case-insensitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", - "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^6.0.2" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", - "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1", - "util-deprecate": "^1.0.2" - } - } - } - }, - "postcss-browser-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz", - "integrity": "sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig==", - "requires": { - "postcss": "^7" - } - }, - "postcss-calc": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", - "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", - "requires": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", - "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1", - "util-deprecate": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - } - } - }, - "postcss-color-functional-notation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", - "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-color-gray": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", - "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-color-hex-alpha": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", - "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", - "requires": { - "postcss": "^7.0.14", - "postcss-values-parser": "^2.0.1" - } - }, - "postcss-color-mod-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", - "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-color-rebeccapurple": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", - "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "requires": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-custom-media": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", - "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", - "requires": { - "postcss": "^7.0.14" - } - }, - "postcss-custom-properties": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", - "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", - "requires": { - "postcss": "^7.0.17", - "postcss-values-parser": "^2.0.1" - } - }, - "postcss-custom-selectors": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", - "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-dir-pseudo-class": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", - "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-double-position-gradients": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", - "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", - "requires": { - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-env-function": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", - "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-flexbugs-fixes": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.1.0.tgz", - "integrity": "sha512-jr1LHxQvStNNAHlgco6PzY308zvLklh7SJVYuWUwyUQncofaAlD2l+P/gxKHOdqWKe7xJSkVLFF/2Tp+JqMSZA==", - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-focus-visible": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", - "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-focus-within": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", - "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-font-variant": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz", - "integrity": "sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-gap-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", - "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-image-set-function": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", - "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-initial": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.2.tgz", - "integrity": "sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA==", - "requires": { - "lodash.template": "^4.5.0", - "postcss": "^7.0.2" - } - }, - "postcss-lab-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", - "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", - "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", - "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - } - }, - "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "postcss-logical": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", - "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-media-minmax": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", - "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "requires": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - } - }, - "postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "requires": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - } - }, - "postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "requires": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "requires": { - "postcss": "^7.0.5" - } - }, - "postcss-modules-local-by-default": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", - "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", - "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.16", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - } - } - }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - } - }, - "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", - "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" - } - }, - "postcss-nesting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", - "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-normalize": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-8.0.1.tgz", - "integrity": "sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ==", - "requires": { - "@csstools/normalize.css": "^10.1.0", - "browserslist": "^4.6.2", - "postcss": "^7.0.17", - "postcss-browser-comments": "^3.0.0", - "sanitize.css": "^10.0.0" - } - }, - "postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "requires": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" - } - } - }, - "postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-overflow-shorthand": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", - "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-page-break": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", - "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-place": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", - "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - } - }, - "postcss-preset-env": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", - "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", - "requires": { - "autoprefixer": "^9.6.1", - "browserslist": "^4.6.4", - "caniuse-lite": "^1.0.30000981", - "css-blank-pseudo": "^0.1.4", - "css-has-pseudo": "^0.10.0", - "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.4.0", - "postcss": "^7.0.17", - "postcss-attribute-case-insensitive": "^4.0.1", - "postcss-color-functional-notation": "^2.0.1", - "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.3", - "postcss-color-mod-function": "^3.0.3", - "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.8", - "postcss-custom-properties": "^8.0.11", - "postcss-custom-selectors": "^5.1.2", - "postcss-dir-pseudo-class": "^5.0.0", - "postcss-double-position-gradients": "^1.0.0", - "postcss-env-function": "^2.0.2", - "postcss-focus-visible": "^4.0.0", - "postcss-focus-within": "^3.0.0", - "postcss-font-variant": "^4.0.0", - "postcss-gap-properties": "^2.0.0", - "postcss-image-set-function": "^3.0.1", - "postcss-initial": "^3.0.0", - "postcss-lab-function": "^2.0.1", - "postcss-logical": "^3.0.0", - "postcss-media-minmax": "^4.0.0", - "postcss-nesting": "^7.0.0", - "postcss-overflow-shorthand": "^2.0.0", - "postcss-page-break": "^2.0.0", - "postcss-place": "^4.0.1", - "postcss-pseudo-class-any-link": "^6.0.0", - "postcss-replace-overflow-wrap": "^3.0.0", - "postcss-selector-matches": "^4.0.0", - "postcss-selector-not": "^4.0.0" - } - }, - "postcss-pseudo-class-any-link": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", - "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "requires": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - } - }, - "postcss-replace-overflow-wrap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", - "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-safe-parser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz", - "integrity": "sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ==", - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-selector-matches": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", - "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", - "requires": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - } - }, - "postcss-selector-not": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz", - "integrity": "sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ==", - "requires": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - } - }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", - "requires": { - "is-svg": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - } - }, - "postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "requires": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "postcss-values-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", - "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "pretty-bytes": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", - "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==" - }, - "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", - "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" - } - }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - } - } - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "requires": { - "asap": "~2.0.3" - } - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "promise-window": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/promise-window/-/promise-window-1.2.1.tgz", - "integrity": "sha512-fDU8dCyw/nAY7Ccy6gOkEXUDijJC+rT3ZBEIAmMjB73WaWXZpbOtBwaUPeYmsN6SISuf/rvl/fSy1Dq7VZu29Q==", - "dev": true - }, - "prompts": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", - "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.4" - } - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "pure-color": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz", - "integrity": "sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" - }, - "raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "requires": { - "performance-now": "^2.1.0" - } - }, - "ramda": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz", - "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - } - } - }, - "react": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", - "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "react-alert": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-alert/-/react-alert-5.5.0.tgz", - "integrity": "sha512-PzB6ktBmtNZkmgZVdPp/Wbe/zjIBzqBu9QHLTrfquUVVPCVVfn3lPWOebejEg6VOxGepIPOSAsb1bd3ESMyC0Q==" - }, - "react-alert-template-basic": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/react-alert-template-basic/-/react-alert-template-basic-1.0.0.tgz", - "integrity": "sha512-6x5Us0oc+jj8BDNkvSWfQMESk5SdyGKitXdLb7CwIlIlecyATjCTKSWpLABg8tpKAPOSJu4Dv/fYUqxXEio/XA==" - }, - "react-app-polyfill": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz", - "integrity": "sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g==", - "requires": { - "core-js": "^3.5.0", - "object-assign": "^4.1.1", - "promise": "^8.0.3", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.3", - "whatwg-fetch": "^3.0.0" - }, - "dependencies": { - "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" - }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "requires": { - "asap": "~2.0.6" - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" - } - } - }, - "react-base16-styling": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.6.0.tgz", - "integrity": "sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=", - "requires": { - "base16": "^1.0.0", - "lodash.curry": "^4.0.1", - "lodash.flow": "^3.3.0", - "pure-color": "^1.2.0" - } - }, - "react-beforeunload": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-beforeunload/-/react-beforeunload-2.2.1.tgz", - "integrity": "sha512-qydpYQuGUaB1C5EP2EFN0YjPo9kgV10Z4suIZ79GIhp0DWNJxHyuR8BiTViOBltTIn9PwlpSqX4fE3uprsdqKA==", - "requires": { - "prop-types": "^15.7.2" - } - }, - "react-chartjs-2": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.8.0.tgz", - "integrity": "sha512-BPpC+qfnh37DkcXvxRwA1rdD9rX/0AQrwru4VZTLofCCuZBwRsc7PbfxjilvoB6YlHhorwZu40YDWEQkoz7xfQ==", - "requires": { - "lodash": "^4.17.4", - "prop-types": "^15.5.8" - } - }, - "react-cookie": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.0.1.tgz", - "integrity": "sha512-h61qAtSXvfjNa81h3XCFdFoyFaF+nb7gjK0cxQuTiCPMPAe50D950FjLCFhaIfSpAesQFAmkxf5XFpWoEVBDAA==", - "requires": { - "@types/hoist-non-react-statics": "^3.0.1", - "hoist-non-react-statics": "^3.0.0", - "universal-cookie": "^4.0.0" - } - }, - "react-cytoscapejs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/react-cytoscapejs/-/react-cytoscapejs-1.2.0.tgz", - "integrity": "sha512-VhOhICJbI+X377RvTX7X+lpMSLWiI2Y7O6xJOc82u2dIF2qrtksP9H4IMGoo2TYL6otLuYV81RfFyywk4KCxBg==", - "requires": { - "cytoscape": "^3.2.19", - "prop-types": "^15.6.2" - } - }, - "react-dev-utils": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz", - "integrity": "sha512-XxTbgJnYZmxuPtY3y/UV0D8/65NKkmaia4rXzViknVnZeVlklSh8u6TnaEYPfAi/Gh1TP4mEOXHI6jQOPbeakQ==", - "requires": { - "@babel/code-frame": "7.8.3", - "address": "1.1.2", - "browserslist": "4.10.0", - "chalk": "2.4.2", - "cross-spawn": "7.0.1", - "detect-port-alt": "1.1.6", - "escape-string-regexp": "2.0.0", - "filesize": "6.0.1", - "find-up": "4.1.0", - "fork-ts-checker-webpack-plugin": "3.1.1", - "global-modules": "2.0.0", - "globby": "8.0.2", - "gzip-size": "5.1.1", - "immer": "1.10.0", - "inquirer": "7.0.4", - "is-root": "2.1.0", - "loader-utils": "1.2.3", - "open": "^7.0.2", - "pkg-up": "3.1.0", - "react-error-overlay": "^6.0.7", - "recursive-readdir": "2.2.2", - "shell-quote": "1.7.2", - "strip-ansi": "6.0.0", - "text-table": "0.2.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", - "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.1", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "browserslist": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.10.0.tgz", - "integrity": "sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA==", - "requires": { - "caniuse-lite": "^1.0.30001035", - "electron-to-chromium": "^1.3.378", - "node-releases": "^1.1.52", - "pkg-up": "^3.1.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "dependencies": { - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - } - } - }, - "inquirer": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", - "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^2.4.2", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.2.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - } - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "react-device-detect": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/react-device-detect/-/react-device-detect-1.9.10.tgz", - "integrity": "sha512-Rb618NuNwJojJeIgI5UoONwztbd4wMT4TBofzvYOHnPNu61LYYz8b78cXQb7kXRrPn6iI5T1gFtNQh0GxHEPxw==", - "requires": { - "ua-parser-js": "^0.7.20" - }, - "dependencies": { - "ua-parser-js": { - "version": "0.7.20", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", - "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==" - } - } - }, - "react-dom": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", - "integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.1" - }, - "dependencies": { - "scheduler": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.1.tgz", - "integrity": "sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - } - } - }, - "react-draggable": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-3.3.2.tgz", - "integrity": "sha512-oaz8a6enjbPtx5qb0oDWxtDNuybOylvto1QLydsXgKmwT7e3GXC2eMVDwEMIUYJIFqVG72XpOv673UuuAq6LhA==", - "requires": { - "classnames": "^2.2.5", - "prop-types": "^15.6.0" - } - }, - "react-dropzone": { - "version": "10.1.10", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-10.1.10.tgz", - "integrity": "sha512-vcLBdkYo7wgZpw1o4cz7uk8/Mmm+sYHeiTfFSshA/EGthz/TjjrTOrKwvFHm3o1p1LPk+x+KbDDlw5OeIo6eYA==", - "requires": { - "attr-accept": "^1.1.3", - "file-selector": "^0.1.11", - "prop-types": "^15.7.2" - } - }, - "react-error-overlay": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz", - "integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==" - }, - "react-event-listener": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.6.tgz", - "integrity": "sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw==", - "requires": { - "@babel/runtime": "^7.2.0", - "prop-types": "^15.6.0", - "warning": "^4.0.1" - } - }, - "react-ga": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/react-ga/-/react-ga-2.7.0.tgz", - "integrity": "sha512-AjC7UOZMvygrWTc2hKxTDvlMXEtbmA0IgJjmkhgmQQ3RkXrWR11xEagLGFGaNyaPnmg24oaIiaNPnEoftUhfXA==" - }, - "react-iframe": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/react-iframe/-/react-iframe-1.8.0.tgz", - "integrity": "sha512-NYi89+rEqREwQxW9sDf+akh6/dtwWd3bOjByoVEIQ7SicOxVawRMer3pLdWjFaHXpuxTB9NqobPf/Ohj2iAKkg==", - "requires": { - "object-assign": "^4.1.1" - } - }, - "react-image-lightbox": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-image-lightbox/-/react-image-lightbox-5.1.0.tgz", - "integrity": "sha512-R46QvffoDBscLQgTl4s3kFxVbnP7a+nIh7AXJNS0EXVeDaa6zKDKtIT+jFeEvs+F9oUHtZfenG1NHhTkO4hEOA==", - "requires": { - "prop-types": "^15.6.2", - "react-modal": "^3.6.1" - } - }, - "react-is": { - "version": "16.8.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", - "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" - }, - "react-json-pretty": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/react-json-pretty/-/react-json-pretty-2.2.0.tgz", - "integrity": "sha512-3UMzlAXkJ4R8S4vmkRKtvJHTewG4/rn1Q18n0zqdu/ipZbUPLVZD+QwC7uVcD/IAY3s8iNVHlgR2dMzIUS0n1A==", - "requires": { - "prop-types": "^15.6.2" - } - }, - "react-json-view": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/react-json-view/-/react-json-view-1.19.1.tgz", - "integrity": "sha512-u5e0XDLIs9Rj43vWkKvwL8G3JzvXSl6etuS5G42a8klMohZuYFQzSN6ri+/GiBptDqlrXPTdExJVU7x9rrlXhg==", - "requires": { - "flux": "^3.1.3", - "react-base16-styling": "^0.6.0", - "react-lifecycles-compat": "^3.0.4", - "react-textarea-autosize": "^6.1.0" - } - }, - "react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "react-markdown": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-4.2.2.tgz", - "integrity": "sha512-/STJiRFmJuAIUdeBPp/VyO5bcenTIqP3LXuC3gYvregmYGKjnszGiFc2Ph0LsWC17Un3y/CT8TfxnwJT7v9EJw==", - "requires": { - "html-to-react": "^1.3.4", - "mdast-add-list-metadata": "1.0.1", - "prop-types": "^15.7.2", - "react-is": "^16.8.6", - "remark-parse": "^5.0.0", - "unified": "^6.1.5", - "unist-util-visit": "^1.3.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "unified": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", - "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-string": "^0.1.0" - } - }, - "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", - "requires": { - "is-buffer": "^1.1.4", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - } - } - }, - "react-markdown-github": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/react-markdown-github/-/react-markdown-github-3.3.1.tgz", - "integrity": "sha512-7svOrx7lZ1EdqqmcCXEWFY/Bdj9MgtAxFvpXRcvKNDz8Dt9lkZzii17qhE/qnc446NI5LamifayHILhj/70iAA==", - "requires": { - "react-markdown": "^4.0.8", - "url-parse": "^1.4.0" - } - }, - "react-modal": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.10.1.tgz", - "integrity": "sha512-2DKIfdOc8+WY+SYJ/xf/WBwOYMmNAYAyGkYlc4e1TCs9rk1xY4QBz04hB3UHGcrLChh7ce77rHAe6VPNmuLYsQ==", - "requires": { - "exenv": "^1.2.0", - "prop-types": "^15.5.10", - "react-lifecycles-compat": "^3.0.0", - "warning": "^4.0.3" - } - }, - "react-numeric-input": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/react-numeric-input/-/react-numeric-input-2.2.3.tgz", - "integrity": "sha1-S/WRjD6v7YUagN8euZLZQQArtVI=" - }, - "react-popper": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.4.tgz", - "integrity": "sha512-9AcQB29V+WrBKk6X7p0eojd1f25/oJajVdMZkywIoAV6Ag7hzE1Mhyeup2Q1QnvFRtGQFQvtqfhlEoDAPfKAVA==", - "requires": { - "@babel/runtime": "^7.1.2", - "create-react-context": "^0.3.0", - "popper.js": "^1.14.4", - "prop-types": "^15.6.1", - "typed-styles": "^0.0.7", - "warning": "^4.0.2" - } - }, - "react-powerhooks": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/react-powerhooks/-/react-powerhooks-0.0.7.tgz", - "integrity": "sha512-Z5vke2LBcmGkTIA986DNvudONetmgDo11WYlzolew/+1HYAsb4d5NTBipKq+/oAl1AoajFwn1wHkzA8J3yCd2g==" - }, - "react-router": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", - "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==", - "requires": { - "history": "^4.7.2", - "hoist-non-react-statics": "^2.5.0", - "invariant": "^2.2.4", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.1", - "warning": "^4.0.1" - }, - "dependencies": { - "hoist-non-react-statics": { - "version": "2.5.5", - "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==" - } - } - }, - "react-router-dom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.3.1.tgz", - "integrity": "sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==", - "requires": { - "history": "^4.7.2", - "invariant": "^2.2.4", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.1", - "react-router": "^4.3.1", - "warning": "^4.0.1" - } - }, - "react-scripts": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz", - "integrity": "sha512-JpTdi/0Sfd31mZA6Ukx+lq5j1JoKItX7qqEK4OiACjVQletM1P38g49d9/D0yTxp9FrSF+xpJFStkGgKEIRjlQ==", - "requires": { - "@babel/core": "7.9.0", - "@svgr/webpack": "4.3.3", - "@typescript-eslint/eslint-plugin": "^2.10.0", - "@typescript-eslint/parser": "^2.10.0", - "babel-eslint": "10.1.0", - "babel-jest": "^24.9.0", - "babel-loader": "8.1.0", - "babel-plugin-named-asset-import": "^0.3.6", - "babel-preset-react-app": "^9.1.2", - "camelcase": "^5.3.1", - "case-sensitive-paths-webpack-plugin": "2.3.0", - "css-loader": "3.4.2", - "dotenv": "8.2.0", - "dotenv-expand": "5.1.0", - "eslint": "^6.6.0", - "eslint-config-react-app": "^5.2.1", - "eslint-loader": "3.0.3", - "eslint-plugin-flowtype": "4.6.0", - "eslint-plugin-import": "2.20.1", - "eslint-plugin-jsx-a11y": "6.2.3", - "eslint-plugin-react": "7.19.0", - "eslint-plugin-react-hooks": "^1.6.1", - "file-loader": "4.3.0", - "fs-extra": "^8.1.0", - "fsevents": "2.1.2", - "html-webpack-plugin": "4.0.0-beta.11", - "identity-obj-proxy": "3.0.0", - "jest": "24.9.0", - "jest-environment-jsdom-fourteen": "1.0.1", - "jest-resolve": "24.9.0", - "jest-watch-typeahead": "0.4.2", - "mini-css-extract-plugin": "0.9.0", - "optimize-css-assets-webpack-plugin": "5.0.3", - "pnp-webpack-plugin": "1.6.4", - "postcss-flexbugs-fixes": "4.1.0", - "postcss-loader": "3.0.0", - "postcss-normalize": "8.0.1", - "postcss-preset-env": "6.7.0", - "postcss-safe-parser": "4.0.1", - "react-app-polyfill": "^1.0.6", - "react-dev-utils": "^10.2.1", - "resolve": "1.15.0", - "resolve-url-loader": "3.1.1", - "sass-loader": "8.0.2", - "semver": "6.3.0", - "style-loader": "0.23.1", - "terser-webpack-plugin": "2.3.5", - "ts-pnp": "1.1.6", - "url-loader": "2.3.0", - "webpack": "4.42.0", - "webpack-dev-server": "3.10.3", - "webpack-manifest-plugin": "2.2.0", - "workbox-webpack-plugin": "4.3.1" - }, - "dependencies": { - "@babel/core": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.0", - "@babel/parser": "^7.9.0", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", - "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", - "requires": { - "@babel/types": "^7.11.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", - "requires": { - "@babel/types": "^7.11.0" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", - "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==" - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "requires": { - "@babel/highlight": "^7.10.4" - } - } - } - }, - "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "requires": { - "@babel/highlight": "^7.10.4" - } - } - } - }, - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==" - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==" - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - } - }, - "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", - "requires": { - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", - "schema-utils": "^2.6.5" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "webpack": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", - "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.2.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.0", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - } - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, - "react-scroll": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/react-scroll/-/react-scroll-1.7.11.tgz", - "integrity": "sha512-MCWtt8KWTBzBlo9oFE7xgAhGcgbslsfQAuGZAfYlBTt3Pxi2CX+kh8OoTUVAuOwNlt9XkoWcvDTWQwtHzm2uOg==", - "requires": { - "lodash.throttle": "^4.1.1", - "prop-types": "^15.5.8" - } - }, - "react-text-mask": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.4.3.tgz", - "integrity": "sha1-mR77QpnjDC5sLEbRP2FxaUY+DS0=", - "requires": { - "prop-types": "^15.5.6" - } - }, - "react-textarea-autosize": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-6.1.0.tgz", - "integrity": "sha512-F6bI1dgib6fSvG8so1HuArPUv+iVEfPliuLWusLF+gAKz0FbB4jLrWUrTAeq1afnPT2c9toEZYUdz/y1uKMy4A==", - "requires": { - "prop-types": "^15.6.0" - } - }, - "react-toastify": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-5.1.0.tgz", - "integrity": "sha512-0kVAAE7VO609EeXLVaFHDTc6Bnd/OUAb7rrRAwMsHeaThKEhH+WEQEPftTjuA4rP59K0QhCnWu4Ds2hXAcFxaw==", - "requires": { - "@babel/runtime": "^7.4.2", - "classnames": "^2.2.6", - "prop-types": "^15.7.2", - "react-transition-group": "^2.6.1" - }, - "dependencies": { - "react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", - "requires": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - } - } - } - }, - "react-transition-group": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", - "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", - "requires": { - "dom-helpers": "^3.4.0", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2", - "react-lifecycles-compat": "^3.0.4" - } - }, - "reactstrap": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-7.1.0.tgz", - "integrity": "sha512-wtc4RkgnGn1TsZ0AxOZ2OqT+b8YmCWZj/tErPujWLepxzlEEhveZGC+uDerdaHVSAzJUP2DTk605iper7hutQQ==", - "requires": { - "@babel/runtime": "^7.2.0", - "classnames": "^2.2.3", - "lodash.isfunction": "^3.0.9", - "lodash.isobject": "^3.0.2", - "lodash.tonumber": "^4.0.3", - "prop-types": "^15.5.8", - "react-lifecycles-compat": "^3.0.4", - "react-popper": "^0.10.4", - "react-transition-group": "^2.3.1" - }, - "dependencies": { - "react-popper": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-0.10.4.tgz", - "integrity": "sha1-rypBXqIike3VBGeNev2opu4ylao=", - "requires": { - "popper.js": "^1.14.1", - "prop-types": "^15.6.1" - } - } - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - } - } - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "realpath-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", - "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", - "requires": { - "util.promisify": "^1.0.0" - } - }, - "recompose": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.30.0.tgz", - "integrity": "sha512-ZTrzzUDa9AqUIhRk4KmVFihH0rapdCSMFXjhHbNrjAWxBuUD/guYlyysMnuHjlZC/KRiOKRtB4jf96yYSkKE8w==", - "requires": { - "@babel/runtime": "^7.0.0", - "change-emitter": "^0.1.2", - "fbjs": "^0.8.1", - "hoist-non-react-statics": "^2.3.1", - "react-lifecycles-compat": "^3.0.2", - "symbol-observable": "^1.0.4" - }, - "dependencies": { - "hoist-non-react-statics": { - "version": "2.5.5", - "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==" - } - } - }, - "recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "requires": { - "minimatch": "3.0.4" - } - }, - "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==" - }, - "regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" - }, - "regenerator-transform": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", - "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", - "requires": { - "@babel/runtime": "^7.8.4", - "private": "^0.1.8" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz", - "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" - } - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regex-parser": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", - "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==" - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" - }, - "regexpu-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", - "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" - } - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" - }, - "regjsparser": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", - "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" - }, - "remark-parse": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", - "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, - "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=" - }, - "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", - "requires": { - "css-select": "^1.1.0", - "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" - }, - "dependencies": { - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - } - } - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", - "requires": { - "lodash": "^4.17.15" - } - }, - "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", - "requires": { - "request-promise-core": "1.1.3", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" - }, - "resolve": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", - "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" - }, - "resolve-pathname": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz", - "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==" - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "resolve-url-loader": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz", - "integrity": "sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ==", - "requires": { - "adjust-sourcemap-loader": "2.0.0", - "camelcase": "5.3.1", - "compose-function": "3.0.3", - "convert-source-map": "1.7.0", - "es6-iterator": "2.0.3", - "loader-utils": "1.2.3", - "postcss": "7.0.21", - "rework": "1.0.1", - "rework-visit": "1.0.0", - "source-map": "0.6.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } - }, - "postcss": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", - "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" - }, - "rework": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", - "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", - "requires": { - "convert-source-map": "^0.3.3", - "css": "^2.0.0" - }, - "dependencies": { - "convert-source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", - "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=" - } - } - }, - "rework-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", - "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=" - }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "requires": { - "aproba": "^1.1.1" - } - }, - "rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" - }, - "rxjs": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", - "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - } - }, - "sanitize.css": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", - "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==" - }, - "sass-loader": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", - "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", - "requires": { - "clone-deep": "^4.0.1", - "loader-utils": "^1.2.3", - "neo-async": "^2.6.1", - "schema-utils": "^2.6.1", - "semver": "^6.3.0" - }, - "dependencies": { - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - } - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", - "requires": { - "xmlchars": "^2.1.1" - } - }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" - }, - "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", - "requires": { - "node-forge": "0.9.0" - } - }, - "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==" - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==" - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", - "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", - "requires": { - "is-extendable": "^0.1.1", - "kind-of": "^2.0.1", - "lazy-cache": "^0.2.3", - "mixin-object": "^2.0.1" - }, - "dependencies": { - "kind-of": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", - "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", - "requires": { - "is-buffer": "^1.0.2" - } - }, - "lazy-cache": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", - "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=" - } - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" - }, - "side-channel": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", - "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", - "requires": { - "es-abstract": "^1.17.0-next.1", - "object-inspect": "^1.7.0" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - } - } - }, - "simplebar": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/simplebar/-/simplebar-4.2.3.tgz", - "integrity": "sha512-9no0pK7/1y+8/oTF3sy/+kx0PjQ3uk4cYwld5F1CJGk2gx+prRyUq8GRfvcVLq5niYWSozZdX73a2wIr1o9l/g==", - "requires": { - "can-use-dom": "^0.1.0", - "core-js": "^3.0.1", - "lodash.debounce": "^4.0.8", - "lodash.memoize": "^4.1.2", - "lodash.throttle": "^4.1.1", - "resize-observer-polyfill": "^1.5.1" - }, - "dependencies": { - "core-js": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.3.3.tgz", - "integrity": "sha512-0xmD4vUJRY8nfLyV9zcpC17FtSie5STXzw+HyYw2t8IIvmDnbq7RJUULECCo+NstpJtwK9kx8S+898iyqgeUow==" - } - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "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", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - } - }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" - } - }, - "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", - "requires": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "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==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz", - "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==", - "requires": { - "figgy-pudding": "^3.5.1", - "minipass": "^3.1.1" - } - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" - }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" - }, - "state-toggle": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.2.tgz", - "integrity": "sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-each": { - "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" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string-length": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "string.prototype.matchall": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", - "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "has-symbols": "^1.0.1", - "internal-slot": "^1.0.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.2" - } - }, - "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "dependencies": { - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - }, - "strip-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", - "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", - "requires": { - "babel-extract-comments": "^1.0.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-json-comments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", - "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==" - }, - "style-loader": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", - "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", - "requires": { - "loader-utils": "^1.1.0", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "styled-components": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.0.tgz", - "integrity": "sha512-xQ6vTI/0zNjZ1BBDRxyjvBddrxhQ3DxjeCdaLM1lSn5FDnkTOQgRkmWvcUiTajqc5nJqKVl+7sUioMqktD0+Zw==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@emotion/is-prop-valid": "^0.8.1", - "@emotion/unitless": "^0.7.0", - "babel-plugin-styled-components": ">= 1", - "css-to-react-native": "^2.2.2", - "memoize-one": "^5.0.0", - "merge-anything": "^2.2.4", - "prop-types": "^15.5.4", - "react-is": "^16.6.0", - "stylis": "^3.5.0", - "stylis-rule-sheet": "^0.0.10", - "supports-color": "^5.5.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "stylis": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", - "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" - }, - "stylis-rule-sheet": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", - "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==" - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "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", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - }, - "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" - } - }, - "tar-pack": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", - "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", - "requires": { - "debug": "^2.2.0", - "fstream": "^1.0.10", - "fstream-ignore": "^1.0.5", - "once": "^1.3.3", - "readable-stream": "^2.1.4", - "rimraf": "^2.5.1", - "tar": "^2.2.1", - "uid-number": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "terser-webpack-plugin": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz", - "integrity": "sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w==", - "requires": { - "cacache": "^13.0.1", - "find-cache-dir": "^3.2.0", - "jest-worker": "^25.1.0", - "p-limit": "^2.2.2", - "schema-utils": "^2.6.4", - "serialize-javascript": "^2.1.2", - "source-map": "^0.6.1", - "terser": "^4.4.3", - "webpack-sources": "^1.4.3" - }, - "dependencies": { - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "requires": { - "setimmediate": "^1.0.4" - } - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" - }, - "tiny-invariant": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.4.tgz", - "integrity": "sha512-lMhRd/djQJ3MoaHEBrw8e2/uM4rs9YMNk0iOr8rHQ0QdbM7D4l0gFl3szKdeixrlyfm9Zqi4dxHCM2qVG8ND5g==" - }, - "tiny-warning": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.2.tgz", - "integrity": "sha512-rru86D9CpQRLvsFG5XFdy0KdLAvjdQDyZCsRcuu60WtzFylDM3eAWSxEVz5kzL2Gp544XiUvPbVKtOA/txLi9Q==" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "requires": { - "punycode": "^2.1.0" - } - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" - }, - "trim-trailing-lines": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz", - "integrity": "sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==" - }, - "trough": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", - "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==" - }, - "ts-pnp": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.6.tgz", - "integrity": "sha512-CrG5GqAAzMT7144Cl+UIFP7mz/iIhiy+xQ6GGcnjTezhALT02uPMRw7tgDSESgB5MsfKt55+GPWw4ir1kVtMIQ==" - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" - }, - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "requires": { - "tslib": "^1.8.1" - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typed-styles": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", - "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "ua-parser-js": { - "version": "0.7.19", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", - "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==" - }, - "uid-number": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", - "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" - }, - "unherit": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz", - "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==", - "requires": { - "inherits": "^2.0.1", - "xtend": "^4.0.1" - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==" - }, - "unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" - }, - "unique-filename": { - "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.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" - }, - "unist-util-remove-position": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz", - "integrity": "sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA==", - "requires": { - "unist-util-visit": "^1.1.0" - } - }, - "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==" - }, - "unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "requires": { - "unist-util-visit-parents": "^2.0.0" - }, - "dependencies": { - "unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "requires": { - "unist-util-is": "^3.0.0" - } - } - } - }, - "unist-util-visit-parents": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-1.1.2.tgz", - "integrity": "sha512-yvo+MMLjEwdc3RhhPYSximset7rwjMrdt9E41Smmvg25UQIenzrN83cRnF1JMzoMi9zZOQeYXHSDf7p+IQkW3Q==" - }, - "universal-cookie": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-4.0.2.tgz", - "integrity": "sha512-n14lhA//lQeYRweP9j9uXsshN9Cs4LunVSnvAGmnA69SofwsjpUU03geaCaPC9LlsH2rkBy99o3zxQyVOldGvA==", - "requires": { - "@types/cookie": "^0.3.3", - "@types/object-assign": "^4.0.30", - "cookie": "^0.4.0", - "object-assign": "^4.1.1" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } - } - }, - "url-loader": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz", - "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==", - "requires": { - "loader-utils": "^1.2.3", - "mime": "^2.4.4", - "schema-utils": "^2.5.0" - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", - "requires": { - "builtins": "^1.0.3" - } - }, - "value-equal": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz", - "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vfile-location": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.5.tgz", - "integrity": "sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==" - }, - "vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", - "requires": { - "unist-util-stringify-position": "^1.1.1" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", - "requires": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "requires": { - "makeerror": "1.0.x" - } - }, - "warning": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", - "requires": { - "chokidar": "^3.4.1", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" - }, - "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "optional": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "optional": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", - "optional": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "optional": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "optional": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "optional": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "optional": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", - "optional": true, - "requires": { - "chokidar": "^2.1.8" - }, - "dependencies": { - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "optional": true - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "optional": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "optional": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "optional": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "optional": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "optional": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webfontloader": { - "version": "1.6.28", - "resolved": "https://registry.npmjs.org/webfontloader/-/webfontloader-1.6.28.tgz", - "integrity": "sha1-23hhKSU8tujq5UwvsF+HCvZnW64=" - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "webpack": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", - "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.2.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.0", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, - "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - } - }, - "webpack-dev-server": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz", - "integrity": "sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==", - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.2.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.6", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.25", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "0.3.19", - "sockjs-client": "1.4.0", - "spdy": "^4.0.1", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "12.0.5" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^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", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "requires": { - "async-limiter": "~1.0.0" - } - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "webpack-manifest-plugin": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", - "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", - "requires": { - "fs-extra": "^7.0.0", - "lodash": ">=3.5 <5", - "object.entries": "^1.1.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "websocket": { - "version": "1.0.30", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.30.tgz", - "integrity": "sha512-aO6klgaTdSMkhfl5VVJzD5fm+Srhh5jLYbS15+OiI1sN6h/RU/XW6WN9J1uVIpUKNmsTvT3Hs35XAFjn9NMfOw==", - "requires": { - "debug": "^2.2.0", - "nan": "^2.14.0", - "typedarray-to-buffer": "^3.1.5", - "yaeti": "^0.0.6" - } - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" - }, - "workbox-background-sync": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", - "integrity": "sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-broadcast-update": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz", - "integrity": "sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-build": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-4.3.1.tgz", - "integrity": "sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==", - "requires": { - "@babel/runtime": "^7.3.4", - "@hapi/joi": "^15.0.0", - "common-tags": "^1.8.0", - "fs-extra": "^4.0.2", - "glob": "^7.1.3", - "lodash.template": "^4.4.0", - "pretty-bytes": "^5.1.0", - "stringify-object": "^3.3.0", - "strip-comments": "^1.0.2", - "workbox-background-sync": "^4.3.1", - "workbox-broadcast-update": "^4.3.1", - "workbox-cacheable-response": "^4.3.1", - "workbox-core": "^4.3.1", - "workbox-expiration": "^4.3.1", - "workbox-google-analytics": "^4.3.1", - "workbox-navigation-preload": "^4.3.1", - "workbox-precaching": "^4.3.1", - "workbox-range-requests": "^4.3.1", - "workbox-routing": "^4.3.1", - "workbox-strategies": "^4.3.1", - "workbox-streams": "^4.3.1", - "workbox-sw": "^4.3.1", - "workbox-window": "^4.3.1" - }, - "dependencies": { - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "workbox-cacheable-response": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz", - "integrity": "sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-core": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-4.3.1.tgz", - "integrity": "sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==" - }, - "workbox-expiration": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-4.3.1.tgz", - "integrity": "sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-google-analytics": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz", - "integrity": "sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==", - "requires": { - "workbox-background-sync": "^4.3.1", - "workbox-core": "^4.3.1", - "workbox-routing": "^4.3.1", - "workbox-strategies": "^4.3.1" - } - }, - "workbox-navigation-preload": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz", - "integrity": "sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-precaching": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-4.3.1.tgz", - "integrity": "sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-range-requests": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz", - "integrity": "sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-routing": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-4.3.1.tgz", - "integrity": "sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-strategies": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-4.3.1.tgz", - "integrity": "sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-streams": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-4.3.1.tgz", - "integrity": "sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "workbox-sw": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-4.3.1.tgz", - "integrity": "sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==" - }, - "workbox-webpack-plugin": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-4.3.1.tgz", - "integrity": "sha512-gJ9jd8Mb8wHLbRz9ZvGN57IAmknOipD3W4XNE/Lk/4lqs5Htw4WOQgakQy/o/4CoXQlMCYldaqUg+EJ35l9MEQ==", - "requires": { - "@babel/runtime": "^7.0.0", - "json-stable-stringify": "^1.0.1", - "workbox-build": "^4.3.1" - } - }, - "workbox-window": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-4.3.1.tgz", - "integrity": "sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==", - "requires": { - "workbox-core": "^4.3.1" - } - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "requires": { - "errno": "~0.1.7" - } - }, - "worker-rpc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", - "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", - "requires": { - "microevent.ts": "~0.1.1" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "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", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "requires": { - "mkdirp": "^0.5.1" - } - }, - "write-file-atomic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", - "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "requires": { - "async-limiter": "~1.0.0" - } - }, - "x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=" - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" - }, - "xregexp": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", - "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", - "requires": { - "@babel/runtime-corejs3": "^7.8.3" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yaml": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", - "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", - "requires": { - "@babel/runtime": "^7.6.3" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.2.tgz", - "integrity": "sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==", - "requires": { - "regenerator-runtime": "^0.13.2" - } - } - } - }, - "yamljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", - "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", - "requires": { - "argparse": "^1.0.7", - "glob": "^7.0.5" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.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", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "zone.js": { - "version": "0.8.29", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.29.tgz", - "integrity": "sha512-mla2acNCMkWXBD+c+yeUrBUrzOxYMNFdQ6FGfigGGtEVBPJx07BQeJekjt9DmH1FtZek4E9rE1eRR9qQpxACOQ==" - } - } -} diff --git a/frontend/package.json b/frontend/package.json index d2b2ef26..5b290522 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,12 +1,13 @@ { "name": "shuffler", "homepage": "https://shuffler.io", - "version": "0.8.53", + "version": "0.8.92", "private": true, "dependencies": { "@material-ui/core": "^4.5.2", "@material-ui/data-grid": "^4.0.0-alpha.22", "@material-ui/icons": "^4.5.1", + "@material-ui/lab": "^4.0.0-alpha.58", "@material-ui/styles": "^4.5.2", "@use-it/interval": "^1.0.0", "babel-eslint": "^10.1.0", diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 99465936..70df8462 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -115,8 +115,8 @@ const App = (message, props) => { } /> } /> } /> - } /> } /> + } /> } /> } /> } /> @@ -125,7 +125,6 @@ const App = (message, props) => { { window.location.pathname = "/docs/about" }} /> } /> } /> - } /> } /> diff --git a/frontend/src/assets/img/github_phishing_email.png b/frontend/src/assets/img/github_phishing_email.png new file mode 100644 index 00000000..0899141d Binary files /dev/null and b/frontend/src/assets/img/github_phishing_email.png differ diff --git a/frontend/src/components/ConfigureWorkflow.jsx b/frontend/src/components/ConfigureWorkflow.jsx index 0e83f81b..0cc6182a 100644 --- a/frontend/src/components/ConfigureWorkflow.jsx +++ b/frontend/src/components/ConfigureWorkflow.jsx @@ -1,13 +1,26 @@ import React, {useState} from 'react'; -import {Typography, } from '@material-ui/core'; +import { InputAdornment, Tooltip, TextField, CircularProgress, ButtonGroup, Button, Avatar, ListItemAvatar, Typography, List, ListItem, ListItemText} from '@material-ui/core'; +import {FavoriteBorder as FavoriteBorderIcon} from '@material-ui/icons'; +import { FixName } from "../views/Apps.jsx"; +// Handles workflow updates on first open to highlight the issues of the workflow +// Variables +// Action (exists, missing fields) +// Action auth +// Triggers +// +// Specifically used for UNSAVED workflows only? const Workflow = (props) => { - const { workflow, appAuthentication, apps } = props + const { globalUrl, theme, workflow, appAuthentication, setSelectedAction, setAuthenticationModalOpen, setSelectedApp, apps, selectedAction,setConfigureWorkflowModalOpen, saveWorkflow, newWebhook, submitSchedule, referenceUrl, isCloud, } = props const [requiredActions, setRequiredActions] = React.useState([]) + const [requiredVariables, setRequiredVariables] = React.useState([]) + const [requiredTriggers, setRequiredTriggers] = React.useState([]) + const [previousAuth, setPreviousAuth] = React.useState(appAuthentication) const [firstLoad, setFirstLoad] = React.useState("") - - // Rofl + const [itemChanged, setItemChanged] = React.useState(false) + var finished = false + if (workflow === undefined || workflow === null) { return null } @@ -20,76 +33,436 @@ const Workflow = (props) => { return null } + const getApp = (actionId, appId) => { + fetch(globalUrl+"/api/v1/apps/"+appId+"/config?openapi=false", { + headers: { + 'Accept': 'application/json', + }, + credentials: "include", + }) + .then((response) => { + if (response.status === 200) { + //alert.success("Successfully GOT app "+appId) + } else { + alert.error("Failed getting app") + } + + return response.json() + }) + .then((responseJson) => { + console.log("ACTION: ", responseJson) + if (responseJson.actions !== undefined && responseJson.actions !== null) { + } + }) + .catch(error => { + alert.error(error.toString()) + }); + } + if (firstLoad.length === 0 || firstLoad !== workflow.id) { + if (finished) { + setConfigureWorkflowModalOpen(false) + return null + } + + if (apps === undefined || apps === null || apps.length === 0) { + console.log("No apps loaded: ", apps) + setConfigureWorkflowModalOpen(false) + return null + } + setFirstLoad(workflow.id) const newactions = [] for (var key in workflow.actions) { + const action = workflow.actions[key] var newaction = { - "large_image": "", - "app_name": "", - "app_version": "", + "large_image": action.large_image, + "app_name": action.app_name, + "app_version": action.app_version, + "activation_done": false, "must_activate": false, "must_authenticate": false, + "auth_done": false, "action_ids": [], + "action": action, + "app": {}, } - const action = workflow.actions[key] - console.log(action) - const app = apps.find(app => app.name === action.app_name && app.app_version === action.app_version) + const app = apps.find(app => app.name === action.app_name && (app.app_version === action.app_version || (app.loop_versions !== null && app.loop_versions.includes(action.app_version)))) if (app === undefined || app === null) { - console.log("COULDNT FIND APP - SEARCH BACKEND") + console.log("App not found!") - newaction.app_name = action.app_name - newaction.app_version = action.app_version + newaction.must_activate = true } else { - newaction.app_name = app.name - newaction.app_version = app.app_version - - console.log("APP: ", app) if (action.authentication_id === "" && app.authentication.required === true) { - console.log("Requires auth!") - newaction.must_authenticate = true - newaction.action_ids.push(action.id) + // Check if configuration is filled or not + var filled = true + for (var key in action.parameters) { + if (action.parameters[key].configuration) { + //console.log("Found config: ", action.parameters[key]) + if (action.parameters[key].value === null || action.parameters[key].value.length === 0) { + filled = false + break + } + } + } + + if (!filled) { + newaction.must_authenticate = true + newaction.action_ids.push(action.id) + } } - //newaction.app_name = action.app_name - //newaction.app_name = action.app_version + newaction.app = app } if (action.errors !== undefined && action.errors !== null && action.errors.length > 0) { - console.log("Has errors!") + //console.log("Node has errors!: ", action.errors) } - console.log("NEWACTION: ", newaction) - if (newaction.must_authenticate || newaction.must_activate) { - newactions.push(newaction) + if (newaction.must_authenticate) { + var authenticationOptions = [] + for (var key in appAuthentication) { + const auth = appAuthentication[key] + if (auth.app.name === app.name && auth.active) { + //console.log("Found auth: ", auth) + authenticationOptions.push(auth) + newaction.authenticationId = auth.id + break + } + } + + if (newaction.authenticationId === null || newaction.authenticationId === undefined || newaction.authenticationId.length === "") { + //console.log("FAILED to authenticate node!") + + if (newactions.find(tmpaction => tmpaction.app_id === newaction.app_id && tmpaction.app_name === newaction.app_name) !== undefined) { + console.log("Action already found.") + } else { + newactions.push(newaction) + } + } else { + //console.log("Skipping node as it's already authenticated.") + newaction.authentication = authenticationOptions + workflow.actions[key] = newaction + } + } else if (newaction.must_activate) { + + if (newactions.find(tmpaction => tmpaction.app_id === newaction.app_id && tmpaction.app_name === newaction.app_name) !== undefined) { + console.log("Action already found.") + } else { + newactions.push(newaction) + } } } - console.log("ACTIONS: ", newactions) + for (var key in workflow.workflow_variables) { + const variable = workflow.workflow_variables[key] + if (variable.value === undefined || variable.value === undefined || variable.value.length < 2) { + variable.value = "" + variable.index = key + requiredVariables.push(variable) + } + } + + for (var key in workflow.triggers) { + var trigger = workflow.triggers[key] + trigger.index = key + + if (trigger.status === "running") { + continue + } + + if (trigger.trigger_type === "SUBFLOW" || trigger.trigger_type === "USERINPUT") { + continue + } + + requiredTriggers.push(trigger) + } + + if (requiredTriggers.length === 0 && requiredVariables.length === 0 && newactions.length === 0) { + setConfigureWorkflowModalOpen(false) + } + + setRequiredTriggers(requiredTriggers) + setRequiredVariables(requiredVariables) setRequiredActions(newactions) } + if (appAuthentication.length !== previousAuth.length) { + var newactions = [] + for (var actionkey in requiredActions) { + var newaction = requiredActions[actionkey] + const app = newaction.app + + for (var key in appAuthentication) { + const auth = appAuthentication[key] + if (auth.app.name === app.name && auth.active) { + newaction.auth_done = true + break + } + } + + newactions.push(newaction) + } + + setRequiredActions(newactions) + setPreviousAuth(appAuthentication) + // Set auth done to true + //"auth_done": false + } + + const TriggerSection = (props) => { + const {trigger} = props + + return ( + + + + {trigger.label} + + + + {trigger.trigger_type === "WEBHOOK" && trigger.status !== "running" ? + + : + trigger.trigger_type === "SCHEDULE" && trigger.status !== "running" ? + + : + null} + {/* + + + ) + }} + fullWidth + color="primary" + type={"text"} + placeholder={`New value for ${trigger.name}`} + onChange={(event) => { + console.log("NEW VALUE ON INDEX", trigger.value) + }} + onBlur={(event) => { + //workflow.variables[variable.index] = event.target.value + }} + /> + } + style={{}} + /> + */} + + ) + } + + const VariableSection = (props) => { + const {variable} = props + + //Name: {variable.name} - {variable.value}. + return ( + + + + + + + + + + ) + }} + fullWidth + color="primary" + type={"text"} + placeholder={`New value for ${variable.name}`} + onChange={(event) => { + console.log("NEW VALUE ON INDEX", variable.index, variable.value) + }} + onBlur={(event) => { + workflow.workflow_variables[variable.index].value = event.target.value + }} + /> + } + style={{}} + /> + + ) + } + const AppSection = (props) => { const {action} = props return ( -
- Name: {action.app_name}:{action.app_version}. -
+ + + + {action.app_name} + + + + {action.must_authenticate ? + action.auth_done ? + + : + selectedAction.app_name === action.app_name ? + + : + + : + null} + {action.must_activate ? + + : null} + ) } - console.log(requiredActions) - return (
- Workflow: {workflow.id} - {requiredActions.map((data, index) => { - return ( - - ) - })} + {workflow.name} + + The following configuration makes the workflow ready immediately. + + {requiredActions.length > 0 ? + + Actions + + {requiredActions.map((data, index) => { + return ( + + ) + })} + + + : null} + + {requiredVariables.length > 0 ? + + Variables + + {requiredVariables.map((data, index) => { + return ( + + ) + })} + + + : null} + + + {requiredTriggers.length > 0 ? + + Triggers + + {requiredTriggers.map((data, index) => { + return ( + + ) + })} + + + : null } +
+ + {/* + + */} + + +
) } diff --git a/frontend/src/components/NestedMenu.jsx b/frontend/src/components/NestedMenu.jsx new file mode 100644 index 00000000..cabf1b24 --- /dev/null +++ b/frontend/src/components/NestedMenu.jsx @@ -0,0 +1,207 @@ +import React, {useState, useRef, useImperativeHandle} from 'react' +import {makeStyles} from '@material-ui/core/styles' +import Menu, {MenuProps} from '@material-ui/core/Menu' +import MenuItem, {MenuItemProps} from '@material-ui/core/MenuItem' +import ArrowRight from '@material-ui/icons/ArrowRight' +import clsx from 'clsx' + +// + +//export interface NestedMenuItemProps { +// /** +// * Open state of parent ``, used to close decendent menus when the +// * root menu is closed. +// */ +// parentMenuOpen: boolean; +// /** +// * Component for the container element. +// * @default 'div' +// */ +// component: React.ElementType; +// /** +// * Effectively becomes the `children` prop passed to the `` +// * element. +// */ +// label: React.ReactNode; +// /** +// * @default +// */ +// rightIcon: React.ReactNode; +// /** +// * Props passed to container element. +// */ +// ContainerProps: React.HTMLAttributes; +// // &React.RefAttributes +// /** +// * Props passed to sub `` element +// */ +// MenuProps: Omit; +// /** +// * @see https://material-ui.com/api/list-item/ +// */ +// button: true; +//} + +const TRANSPARENT = 'rgba(0,0,0,0)' +const useMenuItemStyles = makeStyles((theme) => ({ + root: (props: any) => ({ + backgroundColor: props.open ? theme.palette.action.hover : TRANSPARENT + }) +})) + +/** + * Use as a drop-in replacement for `` when you need to add cascading + * menu elements as children to this component. + */ +//const NestedMenuItem = React.forwardRef( +const NestedMenuItem = (props, ref) => { + console.log(props, ref) + //function NestedMenuItem(props, ref) { + const { + parentMenuOpen, + component = 'div', + label, + rightIcon = , + children, + className, + tabIndex: tabIndexProp, + MenuProps = {}, + ContainerProps: ContainerPropsProp = {}, + ...MenuItemProps + } = props + + const [isSubMenuOpen, setIsSubMenuOpen] = useState(false) + + const {ref: containerRefProp, ...ContainerProps} = ContainerPropsProp + + + const menuItemRef = useRef(null) + useImperativeHandle(ref, () => menuItemRef.current) + const containerRef = useRef(null) + useImperativeHandle(containerRefProp, () => containerRef.current) + const menuContainerRef = useRef(null) + + console.log("PAST THIS: ", containerRefProp, menuItemRef, containerRef, menuContainerRef, ContainerProps) + + const handleMouseEnter = (event: React.MouseEvent) => { + setIsSubMenuOpen(true) + + if (ContainerProps?.onMouseEnter) { + ContainerProps.onMouseEnter(event) + } + } + const handleMouseLeave = (event: React.MouseEvent) => { + setIsSubMenuOpen(false) + + if (ContainerProps?.onMouseLeave) { + ContainerProps.onMouseLeave(event) + } + } + + // Check if any immediate children are active + const isSubmenuFocused = () => { + const active = containerRef.current?.ownerDocument?.activeElement + for (const child of menuContainerRef.current?.children ?? []) { + if (child === active) { + return true + } + } + return false + } + + const handleFocus = (event: React.FocusEvent) => { + if (event.target === containerRef.current) { + setIsSubMenuOpen(true) + } + + if (ContainerProps?.onFocus) { + ContainerProps.onFocus(event) + } + } + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.key === 'Escape') { + return + } + + if (isSubmenuFocused()) { + event.stopPropagation() + } + + const active = containerRef.current?.ownerDocument?.activeElement + + if (event.key === 'ArrowLeft' && isSubmenuFocused()) { + containerRef.current?.focus() + } + + if ( + event.key === 'ArrowRight' && + event.target === containerRef.current && + event.target === active + ) { + console.log("MENU: ", menuContainerRef) + const firstChild = menuContainerRef.current.children[0] + console.log("FIRST: ", firstChild) + firstChild.focus() + } + } + + const open = isSubMenuOpen && parentMenuOpen + const menuItemClasses = useMenuItemStyles({open}) + + // Root element must have a `tabIndex` attribute for keyboard navigation + let tabIndex + if (!props.disabled) { + tabIndex = tabIndexProp !== undefined ? tabIndexProp : -1 + } + + console.log("PAST 2! ", tabIndex) + + return ( +
+ + {label} + {rightIcon} + + { + setIsSubMenuOpen(false) + }} + > +
+ {children} +
+
+
+ ) +} + +export default NestedMenuItem diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx new file mode 100644 index 00000000..05cf9fb1 --- /dev/null +++ b/frontend/src/components/ParsedAction.jsx @@ -0,0 +1,1643 @@ +import React, {useState, useEffect, useLayoutEffect} from 'react'; +import { makeStyles, createStyles } from '@material-ui/core/styles'; + +import { GetParsedPaths } from "../views/Apps.jsx"; +import { GetIconInfo } from "../views/Workflows.jsx"; +import { sortByKey } from "../views/AngularWorkflow.jsx"; +import { useTheme } from '@material-ui/core/styles'; +import NestedMenuItem from "material-ui-nested-menu-item"; +//import NestedMenuItem from "./NestedMenu.jsx"; + +import {Popper, TextField, Drawer, Button, Paper, Grid, Tabs, InputAdornment, Tab, ButtonBase, Tooltip, Select, MenuItem, Divider, Dialog, Modal, DialogActions, DialogTitle, InputLabel, DialogContent, FormControl, IconButton, Menu, Input, FormGroup, FormControlLabel, Typography, Checkbox, Breadcrumbs, CircularProgress, Switch, Fade} from '@material-ui/core'; +import {GetApp as GetAppIcon, Search as SearchIcon, ArrowUpward as ArrowUpwardIcon, Visibility as VisibilityIcon, Done as DoneIcon, Close as CloseIcon, Error as ErrorIcon, FindReplace as FindreplaceIcon, ArrowLeft as ArrowLeftIcon, Cached as CachedIcon, DirectionsRun as DirectionsRunIcon, Add as AddIcon, Polymer as PolymerIcon, FormatListNumbered as FormatListNumberedIcon, Create as CreateIcon, PlayArrow as PlayArrowIcon, AspectRatio as AspectRatioIcon, MoreVert as MoreVertIcon, Apps as AppsIcon, Schedule as ScheduleIcon, FavoriteBorder as FavoriteBorderIcon, Pause as PauseIcon, Delete as DeleteIcon, AddCircleOutline as AddCircleOutlineIcon, Save as SaveIcon, KeyboardArrowLeft as KeyboardArrowLeftIcon, KeyboardArrowRight as KeyboardArrowRightIcon, ArrowBack as ArrowBackIcon, Settings as SettingsIcon, LockOpen as LockOpenIcon, ExpandMore as ExpandMoreIcon, VpnKey as VpnKeyIcon} from '@material-ui/icons'; +import Autocomplete from '@material-ui/lab/Autocomplete'; + + +const useStyles = makeStyles({ + notchedOutline: { + borderColor: "#f85a3e !important" + }, + root: { + "& .MuiAutocomplete-listbox": { + border: "2px solid grey", + color: "white", + fontSize: 18, + "& li:nth-child(even)": { + backgroundColor: "#CCC" + }, + "& li:nth-child(odd)": { + backgroundColor: "#FFF" + } + } + }, + inputRoot: { + color: "white", + // This matches the specificity of the default styles at https://github.com/mui-org/material-ui/blob/v4.11.3/packages/material-ui-lab/src/Autocomplete/Autocomplete.js#L90 + "&:hover .MuiOutlinedInput-notchedOutline": { + borderColor: "#f86a3e" + }, + } +}) +//const useStyles = makeStyles((theme) => +// createStyles({ +// notchedOutline: { +// borderColor: "#f85a3e !important" +// }, +//) + +const ParsedAction = (props) => { + const {workflow, setWorkflow, setAction, setSelectedAction, setUpdate, appActionArguments, selectedApp, workflowExecutions, setSelectedResult, selectedAction, setSelectedApp, setSelectedTrigger, setSelectedEdge, setCurrentView, cy, setAuthenticationModalOpen,setVariablesModalOpen, setCodeModalOpen, selectedNameChange, rightsidebarStyle, showEnvironment, selectedActionEnvironment, environments, setNewSelectedAction, appApiViewStyle, globalUrl, setSelectedActionEnvironment, requiresAuthentication, hideExtraTypes, scrollConfig, setScrollConfig } = props + + const theme = useTheme(); + const classes = useStyles() + const keywords = ["len(", "lower(", "upper(", "trim(", "split(", "length(", "number(", "parse(", "join("] + const getParents = (action) => { + if (cy === undefined) { + return [] + } + + var allkeys = [action.id] + var handled = [] + var results = [] + + while(true) { + for (var key in allkeys) { + var currentnode = cy.getElementById(allkeys[key]) + if (currentnode === undefined) { + continue + } + + if (handled.includes(currentnode.data("id"))) { + continue + } else { + // Get the name / label here too? + handled.push(currentnode.data("id")) + results.push(currentnode.data()) + } + + if (currentnode.length === 0) { + continue + } + + const incomingEdges = currentnode.incomers('edge') + if (incomingEdges.length === 0) { + continue + } + + for (var i = 0; i < incomingEdges.length; i++) { + var tmp = incomingEdges[i] + if (!allkeys.includes(tmp.data().source)) { + allkeys.push(tmp.data().source) + } + } + } + if (results.length === allkeys.length) { + break + } + } + + // Some obscure bug made this have to be done.. zz + results = results.filter(data => data !== undefined && action !== undefined && data.id !== action.id) + results = results.filter(data => data !== undefined && data.type !== "TRIGGER") + results.push({"label": "Execution Argument", "type": "INTERNAL"}) + return results + } + + + const getApp = (appId, setApp) => { + fetch(globalUrl+"/api/v1/apps/"+appId+"/config?openapi=false", { + headers: { + 'Accept': 'application/json', + }, + credentials: "include", + }) + .then((response) => { + if (response.status === 200) { + //alert.success("Successfully GOT app "+appId) + } else { + alert.error("Failed getting app") + } + + return response.json() + }) + .then((responseJson) => { + console.log("RESPONSE: ", responseJson) + + const parsedapp = responseJson.app !== undefined && responseJson.app !== null ? JSON.parse(atob(responseJson.app)) : {} + console.log("PARSED: ", parsedapp) + //data = parsedapp.body === undefined ? parsedapp : parsedapp.body + + if (setApp && parsedapp.actions !== undefined && parsedapp.actions !== null) { + console.log("Inside first if") + if (selectedApp.versions !== undefined && selectedApp.versions !== null) { + parsedapp.versions = selectedApp.versions + } + + if (selectedApp.loop_versions !== undefined && selectedApp.loop_versions !== null) { + parsedapp.loop_versions = selectedApp.loop_versions + } + + // Find authentication, and if it works? + // If authentication has less OR more fields, it has to change + //console.log(selected + + console.log("Inside first if2") + var foundAction = parsedapp.actions.find(action => action.name.toLowerCase() === selectedAction.name.toLowerCase()) + console.log("FOUNDACTION: ", foundAction) + if (foundAction !== null && foundAction !== undefined) { + var foundparams = [] + for (var paramkey in foundAction.parameters) { + const param = foundAction.parameters[paramkey] + + const foundParam = selectedAction.parameters.find(item => item.name.toLowerCase() === param.name.toLowerCase()) + if (foundParam === undefined) { + console.log("COULDNT find Param: ", param) + } else { + foundAction.parameters[paramkey] = foundParam + } + //foundparams.push(param.name) + } + } else { + alert.error("Couldn't find action "+selectedAction.name) + } + + + selectedAction.errors = [] + selectedAction.is_valid = true + + // Updating params for the new action + selectedAction.parameters = foundAction.parameters + selectedAction.app_id = appId + selectedAction.app_version = parsedapp.app_version + + setSelectedAction(selectedAction) + setSelectedApp(parsedapp) + } + }) + .catch(error => { + alert.error(error.toString()) + }); + } + + const defineStartnode = () => { + if (cy === undefined) { + return + } + + var oldstartnode = cy.getElementById(workflow.start) + if (oldstartnode.length > 0) { + oldstartnode[0].data("isStartNode", false) + var oldnodecnt = workflow.actions.findIndex(a => a.id === workflow.start) + if (workflow.actions[oldnodecnt] !== undefined) { + workflow.actions[oldnodecnt].isStartNode = false + } + } + + var newstartnode = cy.getElementById(selectedAction.id) + if (newstartnode.length > 0) { + newstartnode[0].data("isStartNode", true) + var newnodecnt = workflow.actions.findIndex(a => a.id === selectedAction.id) + console.log("NEW NODE CNT: ", newnodecnt) + if (workflow.actions[newnodecnt] !== undefined) { + workflow.actions[newnodecnt].isStartNode = true + console.log(workflow.actions[newnodecnt]) + } + } + + // Find branches with triggers as source nodes + // Move these targets to be the new node + // Set arrows pointing to new startnode with errors + //for (var key in workflow.branches) { + // var item = workflow.branches[key] + // if (item.destination_id === oldstartnode[0].data()["id"]) { + // var curbranch = cy.getElementById(item.id) + // if (curbranch.length > 0) { + // //console.log(curbranch[0].data()) + // //curbranch[0].data("target", selectedAction.id) + // //curbranch[0].data("hasErrors", true) + // //workflow.branches[key].destination_id = selectedAction.id + // //console.log(curbranch[0].data()) + // } + // } + //} + + setUpdate("start_node"+selectedAction.id) + workflow.start = selectedAction.id + setWorkflow(workflow) + //setStartNode(selectedAction.id) + } + + const AppActionArguments = (props) => { + const [selectedActionParameters, setSelectedActionParameters] = React.useState([]) + const [selectedVariableParameter, setSelectedVariableParameter] = React.useState("") + const [actionlist, setActionlist] = React.useState([]) + const [jsonList, setJsonList] = React.useState([]) + const [showDropdown, setShowDropdown] = React.useState(false) + const [showDropdownNumber, setShowDropdownNumber] = React.useState(0) + const [showAutocomplete, setShowAutocomplete] = React.useState(false) + const [menuPosition, setMenuPosition] = useState(null) + + useEffect(() => { + if (selectedActionParameters !== null && selectedActionParameters.length === 0) { + if (selectedAction.parameters !== null && selectedAction.parameters.length > 0) { + setSelectedActionParameters(selectedAction.parameters) + } + } + + if ((selectedVariableParameter === null || selectedVariableParameter === undefined) && (workflow.workflow_variables !== null && workflow.workflow_variables.length > 0)) { + // FIXME - this is the bad thing + setSelectedVariableParameter(workflow.workflow_variables[0].name) + } + + if (actionlist.length === 0) { + // FIXME: Have previous execution values in here + actionlist.push({"type": "Execution Argument", "name": "Execution Argument", "value": "$exec", "highlight": "exec", "autocomplete": "exec", "example": "hello"}) + if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) { + for (var key in workflow.workflow_variables) { + const item = workflow.workflow_variables[key] + actionlist.push({"type": "workflow_variable", "name": item.name, "value": item.value, "id": item.id, "autocomplete": `${item.name.split(" ").join("_")}`, "example": item.value}) + } + } + + // FIXME: Add values from previous executions if they exist + if (workflow.execution_variables !== null && workflow.execution_variables !== undefined && workflow.execution_variables.length > 0) { + for (var key in workflow.execution_variables) { + const item = workflow.execution_variables[key] + actionlist.push({"type": "execution_variable", "name": item.name, "value": item.value, "id": item.id, "autocomplete": `${item.name.split(" ").join("_")}`, "example": ""}) + } + } + + // Loops parent nodes' old results to fix autocomplete + var parents = getParents(selectedAction) + if (parents.length > 1) { + for (var key in parents) { + const item = parents[key] + if (item.label === "Execution Argument") { + continue + } + + var exampledata = item.example === undefined ? "" : item.example + // Find previous execution and their variables + //exampledata === "" && + if (workflowExecutions.length > 0) { + // Look for the ID + const found = false + for (var key in workflowExecutions) { + if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) { + continue + } + + var foundResult = workflowExecutions[key].results.find(result => result.action.id === item.id) + if (foundResult === undefined) { + continue + } + + foundResult.result = foundResult.result.trim() + foundResult.result = foundResult.result.split(" None").join(" \"None\"") + foundResult.result = foundResult.result.split(" False").join(" false") + foundResult.result = foundResult.result.split(" True").join(" true") + + var jsonvalid = true + try { + const tmp = String(JSON.parse(foundResult.result)) + if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { + jsonvalid = false + } + } catch (e) { + try { + foundResult.result = foundResult.result.split("\'").join("\"") + const tmp = String(JSON.parse(foundResult.result)) + if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { + jsonvalid = false + } + } catch (e) { + jsonvalid = false + } + } + + // Finds the FIRST json only + if (jsonvalid) { + exampledata = JSON.parse(foundResult.result) + break + } + //else { + // console.log("Invalid JSON: ", foundResult.result) + //} + } + } + + // 1. Take + const actionvalue = {"type": "action", "id": item.id, "name": item.label, "autocomplete": `${item.label.split(" ").join("_")}`, "example": exampledata} + actionlist.push(actionvalue) + } + } + + setActionlist(actionlist) + } + }) + + const changeActionParameter = (event, count, data) => { + if (data.name.startsWith("${") && data.name.endsWith("}")) { + // PARAM FIX - Gonna use the ID field, even though it's a hack + const paramcheck = selectedAction.parameters.find(param => param.name === "body") + if (paramcheck !== undefined) { + // Escapes all double quotes + const toReplace = event.target.value.trim().replaceAll("\\\"", "\"").replaceAll("\"", "\\\"") + console.log("REPLACE WITH: ", toReplace) + if (paramcheck["value_replace"] === undefined || paramcheck["value_replace"] === null) { + paramcheck["value_replace"] = [{ + "key": data.name, + "value": toReplace, + }] + + console.log("IN IF: ", paramcheck) + + } else { + const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name) + if (subparamindex === -1) { + paramcheck["value_replace"].push({ + "key": data.name, + "value": toReplace, + }) + } else { + paramcheck["value_replace"][subparamindex]["value"] = toReplace + } + + console.log("IN ELSE: ", paramcheck) + } + //console.log("PARAM: ", paramcheck) + //if (paramcheck.id === undefined) { + // console.log("Normal paramcheck") + //} else { + // selectedActionParameters[count]["value_replace"] = paramcheck + // selectedAction.parameters[count]["value_replace"] = paramcheck + //} + + if (paramcheck["value_replace"] === undefined) { + selectedActionParameters[count]["value_replace"] = paramcheck + selectedAction.parameters[count]["value_replace"] = paramcheck + } else { + selectedActionParameters[count]["value_replace"] = paramcheck["value_replace"] + selectedAction.parameters[count]["value_replace"] = paramcheck["value_replace"] + } + console.log("RESULT: ", selectedAction) + setSelectedAction(selectedAction) + //setUpdate(Math.random()) + return + } + } + + if (event.target.value[event.target.value.length-1] === "$") { + if (!showDropdown) { + setShowAutocomplete(false) + setShowDropdown(true) + setShowDropdownNumber(count) + } + } else { + if (showDropdown) { + setShowDropdown(false) + } + } + + // bad detection mechanism probably + if (event.target.value[event.target.value.length-1] === "." && actionlist.length > 0) { + console.log("GET THE LAST ARGUMENT FOR NODE!") + // THIS IS AN EXAMPLE OF SHOWING IT + /* + const inputdata = {"data": "1.2.3.4", "dataType": "4.5.6.6"} + setJsonList(GetParsedPaths(inputdata, "")) + if (!showDropdown) { + setShowAutocomplete(false) + setShowDropdown(true) + setShowDropdownNumber(count) + } + console.log(jsonList) + */ + + // Search for the item backwards + // 1. Reverse search backwards from . -> $ + // 2. Search the actionlist for the item + // 3. Find the data for the specific item + + var curstring = "" + var record = false + for (var key in selectedActionParameters[count].value) { + const item = selectedActionParameters[count].value[key] + if (record) { + curstring += item + } + + if (item === "$") { + record = true + curstring = "" + } + } + + //console.log("CURSTRING: ", curstring) + if (curstring.length > 0 && actionlist !== null) { + // Search back in the action list + curstring = curstring.split(" ").join("_").toLowerCase() + var actionItem = actionlist.find(data => data.autocomplete.split(" ").join("_").toLowerCase() === curstring) + if (actionItem !== undefined) { + console.log("Found item: ", actionItem) + + //actionItem.example = actionItem.example.trim() + //actionItem.example = actionItem.example.split(" None").join(" \"None\"") + //actionItem.example = actionItem.example.split("\'").join("\"") + + var jsonvalid = true + try { + const tmp = String(JSON.parse(actionItem.example)) + if (!actionItem.example.includes("{") && !actionItem.example.includes("[")) { + jsonvalid = false + } + } catch (e) { + jsonvalid = false + } + + if (jsonvalid) { + setJsonList(GetParsedPaths(JSON.parse(actionItem.example), "")) + + if (!showDropdown) { + setShowAutocomplete(false) + setShowDropdown(true) + setShowDropdownNumber(count) + } + } + } + } + } else { + if (jsonList.length > 0) { + setJsonList([]) + } + } + + selectedActionParameters[count].value = event.target.value + selectedAction.parameters[count].value = event.target.value + setSelectedAction(selectedAction) + //setUpdate(Math.random()) + //setUpdate(event.target.value) + } + + const changeActionParameterVariable = (fieldvalue, count) => { + //console.log("CALLED THIS ONE WITH VALUE!", fieldvalue) + //if (selectedVariableParameter === fieldvalue) { + // return + //} + + setSelectedVariableParameter(fieldvalue) + + selectedActionParameters[count].action_field = fieldvalue + selectedAction.parameters = selectedActionParameters + + setSelectedApp(selectedApp) + setSelectedAction(selectedAction) + setUpdate(fieldvalue) + } + + // Sets ACTION_RESULT things + const changeActionParameterActionResult = (fieldvalue, count) => { + //cy.nodes().forEach(function( ele ) { + // if (ele.data()["label"] === fieldvalue) { + // selectedActionParameters[count].action_field = ele.id() + // return + // } + //}); + + selectedActionParameters[count].action_field = fieldvalue + selectedAction.parameters = selectedActionParameters + + // FIXME - check if startnode + + // Set value + setSelectedApp(selectedApp) + + setSelectedAction(selectedAction) + setUpdate(Math.random()) + } + + const changeActionParameterVariant = (data, count) => { + selectedActionParameters[count].variant = data + selectedActionParameters[count].value = "" + + if (data === "ACTION_RESULT") { + var parents = getParents(selectedAction) + if (parents.length > 0) { + selectedActionParameters[count].action_field = parents[0].label + } else { + selectedActionParameters[count].action_field = "" + } + } else if (data === "WORKFLOW_VARIABLE") { + if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) { + selectedActionParameters[count].action_field = workflow.workflow_variables[0].name + } + } + + selectedAction.parameters = selectedActionParameters + + // This is a stupid workaround to make it refresh rofl + setSelectedAction({}) + + if (setSelectedTrigger !== undefined) { + setSelectedTrigger({}) + setSelectedApp({}) + setSelectedEdge({}) + } + // FIXME - check if startnode + + // Set value + setSelectedApp(selectedApp) + setSelectedAction(selectedAction) + setUpdate(Math.random()) + } + + // FIXME: Issue #40 - selectedActionParameters not reset + if (Object.getOwnPropertyNames(selectedAction).length > 0 && selectedActionParameters.length > 0) { + var authWritten = false + return ( +
+ Parameters + {selectedActionParameters.map((data, count) => { + if (data.variant === "") { + data.variant = "STATIC_VALUE" + } + + + // selectedAction.selectedAuthentication = e.target.value + // selectedAction.authentication_id = e.target.value.id + if (!selectedAction.auth_not_required && selectedAction.selectedAuthentication !== undefined && selectedAction.selectedAuthentication.fields !== undefined && selectedAction.selectedAuthentication.fields[data.name] !== undefined) { + // This sets the placeholder in the frontend. (Replaced in backend) + selectedActionParameters[count].value = selectedAction.selectedAuthentication.fields[data.name] + selectedAction.parameters[count].value = selectedAction.selectedAuthentication.fields[data.name] + setSelectedAction(selectedAction) + //setUpdate(Math.random()) + + if (authWritten) { + return null + } + + authWritten = true + return ( + + Authentication fields are hidden + + ) + } + + var staticcolor = "inherit" + var actioncolor = "inherit" + var varcolor = "inherit" + var multiline + if (data.multiline !== undefined && data.multiline !== null && data.multiline === true) { + multiline = true + } + + if (data.value !== undefined && data.value !== null && data.value.startsWith("{") && data.value.endsWith("}")) { + multiline = true + } + + var placeholder = "Static value" + if (data.example !== undefined && data.example !== null && data.example.length > 0) { + placeholder = data.example + } + + if (data.name.startsWith("${") && data.name.endsWith("}")) { + const paramcheck = selectedAction.parameters.find(param => param.name === "body") + if (paramcheck !== undefined && paramcheck !== null) { + if (paramcheck["value_replace"] !== undefined && paramcheck["value_replace"] !== null) { + //console.log("IN THE VALUE REPLACE: ", paramcheck["value_replace"]) + const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name) + if (subparamindex !== -1) { + data.value = paramcheck["value_replace"][subparamindex]["value"] + } + } + } + } + + var disabled = false + var rows = "5" + var openApiHelperText = "This is an OpenAPI specific field" + if (selectedApp.generated && data.name === "url" && data.required && data.configuration && hideExtraTypes) { + console.log("GENERATED WITH DATA: ", data) + return null + } + + if (selectedApp.generated && data.name === "headers") { + //console.log("HEADER: ", data) + //if (data.value.length === 0) { + + //} + //setSelectedActionParameters(selectedActionParameters) + } + + if (selectedApp.generated && data.name === "body") { + const regex = /\${(\w+)}/g + const found = placeholder.match(regex) + if (found === null) { + //setExtraBodyFields([]) + } else { + rows = "1" + disabled = true + openApiHelperText = "OpenAPI spec: fill the following fields." + //console.log("SHOULD ADD TO selectedActionParameters!: ", found, selectedActionParameters) + var changed = false + for (var specKey in found) { + const tmpitem = found[specKey] + var skip = false + for (var innerkey in selectedActionParameters) { + if (selectedActionParameters[innerkey].name === tmpitem) { + skip = true + break + } + } + + if (skip) { + //console.log("SKIPPING ", tmpitem) + continue + } + + changed = true + selectedActionParameters.push({ + action_field: "", + configuration: false, + description: "Generated by OpenAPI body example", + example: "", + id: "", + multiline: false, + name: tmpitem, + options: null, + required: false, + schema: {type: "string"}, + skip_multicheck: false, + tags: null, + value: "", + variant: "STATIC_VALUE", + }) + } + + if (changed) { + setSelectedActionParameters(selectedActionParameters) + } + + return + } + } + + const clickedFieldId = "rightside_field_"+count + var datafield = + + + { + setMenuPosition({ + top: event.pageY+10, + left: event.pageX+10, + }) + setShowDropdownNumber(count) + setShowDropdown(true) + setShowAutocomplete(true) + }}/> + + + + ) + }} + fullWidth + multiline={multiline} + onClick={() => { + //console.log("Clicked field: ", clickedFieldId) + if (setScrollConfig !== undefined && scrollConfig !== null && scrollConfig !== undefined && scrollConfig.selected !== clickedFieldId) { + scrollConfig.selected = clickedFieldId + setScrollConfig(scrollConfig) + //console.log("Change field id!") + } + }} + id={clickedFieldId} + rows={rows} + color="primary" + defaultValue={data.value} + type={placeholder.includes("***") || (data.configuration && (data.name.toLowerCase().includes("api") || data.name.toLowerCase().includes("key") || data.name.toLowerCase().includes("pass"))) ? "password" : "text"} + placeholder={placeholder} + onChange={(event) => { + changeActionParameter(event, count, data) + }} + helperText={selectedApp.generated && selectedApp.activated && data.name === "body" ? + + {openApiHelperText} + + : + data.name.startsWith("${") && data.name.endsWith("}") ? + + OpenAPI helperfield + + : + null + } + onBlur={(event) => { + // Super basic check + //if (event.target.value.startsWith("{")) { + // console.log("VALIDATING JSON") + // try { + // JSON.parse(event.target.value) + // } catch (e) { + // alert.error("Failed to parse json: ", e) + // } + //} + }} + /> + + //console.log("FIELD VALUE: ", data.value) + //const regexp = new RegExp("\W+\.", "g") + //let match + //while ((match = regexp.exec(data.value)) !== null) { + // console.log(`Found ${match[0]} start=${match.index} end=${regexp.lastIndex}.`); + //} + + //const str = = data.value.search(submatch) + //console.log("FOUND? ", n) + //for (var key in keywords) { + // const keyword = keywords[key] + // if (data.value.includes(keyword)) { + // console.log("INCLUDED: ", keyword) + // } + //} + + //const keywords = ["len", "lower", "upper", "trim", "split", "length", "number", "parse", "join"] + if (selectedActionParameters[count].schema !== undefined && selectedActionParameters[count].schema !== null && selectedActionParameters[count].schema.type === "file") { + datafield = + + + { + setMenuPosition({ + top: event.pageY+10, + left: event.pageX+10, + }) + setShowDropdownNumber(count) + setShowDropdown(true) + setShowAutocomplete(true) + }}/> + + + ) + }} + fullWidth + multiline={multiline} + rows="5" + color="primary" + defaultValue={data.value} + type={"text"} + placeholder={"The file ID to get"} + id={"rightside_field_"+count} + onChange={(event) => { + changeActionParameter(event, count, data) + }} + onBlur={(event) => { + }} + /> + //const fileId = "6daabec1-892b-469c-b603-c902e47223a9" + //datafield = `SHOW FILES FROM OTHER NODES? Filename: ${selectedActionParameters[count].value}` + /* + if (selectedActionParameters[count].value != fileId) { + changeActionParameter(fileId, count, data) + setUpdate(Math.random()) + + } + */ + } else if (selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0) { + if (selectedActionParameters[count].value === "" && selectedActionParameters[count].required) { + // Rofl, dirty workaround :) + const e = { + target: { + value: selectedActionParameters[count].options[0], + } + } + + changeActionParameter(e, count, data) + } + + datafield = + + + } else if (data.variant === "STATIC_VALUE") { + staticcolor = "#f85a3e" + } + + // Shows nested list of nodes > their JSON lists + const ActionlistWrapper = (props) => { + + const handleMenuClose = () => { + setShowAutocomplete(false) + + if (!selectedActionParameters[count].value[selectedActionParameters[count].value.length-1] === "$") { + setShowDropdown(false) + } + + setUpdate(Math.random()) + setMenuPosition(null) + } + + const handleItemClick = (values) => { + if (values === undefined || values === null || values.length === 0) { + return + } + + console.log("AUTOCOMPLETE1: ", values) + + var toComplete = selectedActionParameters[count].value.trim().endsWith("$") ? values[0].autocomplete : "$"+values[0].autocomplete + toComplete = toComplete.toLowerCase().replaceAll(" ", "_") + console.log("AUTOCOMPLETE: ", toComplete) + for (var key in values) { + if (key == 0 || values[key].autocomplete.length === 0) { + continue + } + + toComplete += values[key].autocomplete + } + + // Handles the fields under OpenAPI body to be parsed. + if (data.name.startsWith("${") && data.name.endsWith("}")) { + console.log("INSIDE VALUE REPLACE: ", data.name, toComplete) + // PARAM FIX - Gonna use the ID field, even though it's a hack + const paramcheck = selectedAction.parameters.find(param => param.name === "body") + if (paramcheck !== undefined) { + if (paramcheck["value_replace"] === undefined || paramcheck["value_replace"] === null) { + paramcheck["value_replace"] = [{ + "key": data.name, + "value": toComplete, + }] + + } else { + const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name) + if (subparamindex === -1) { + paramcheck["value_replace"].push({ + "key": data.name, + "value": toComplete, + }) + } else { + paramcheck["value_replace"][subparamindex]["value"] += toComplete + } + } + + + selectedActionParameters[count]["value_replace"] = paramcheck + selectedAction.parameters[count]["value_replace"] = paramcheck + setSelectedAction(selectedAction) + setUpdate(Math.random()) + + setShowDropdown(false) + setMenuPosition(null) + return + } + } + + selectedActionParameters[count].value += toComplete + selectedAction.parameters[count].value = selectedActionParameters[count].value + setSelectedAction(selectedAction) + setUpdate(Math.random()) + + setShowDropdown(false) + setMenuPosition(null) + } + + const iconStyle = { + marginRight: 15, + } + + return ( + { + handleMenuClose() + }} + open={!!menuPosition} + style={{ + color: "white", + marginTop: 2, + maxHeight: 650, + }} + > + {actionlist.map(innerdata => { + const icon = innerdata.type === "action" ? : innerdata.type === "workflow_variable" || innerdata.type === "execution_variable" ? : + + const handleExecArgumentHover = (inside) => { + var exec_text_field = document.getElementById("execution_argument_input_field") + if (exec_text_field !== null) { + if (inside) { + exec_text_field.style.border = "2px solid #f85a3e" + } else { + exec_text_field.style.border = "" + } + } + + // Also doing arguments + if (workflow.triggers !== undefined && workflow.triggers !== null && workflow.triggers.length > 0) { + for (var key in workflow.triggers) { + const item = workflow.triggers[key] + + if (cy !== undefined) { + var node = cy.getElementById(item.id) + if (node.length > 0) { + if (inside) { + node.addClass('shuffle-hover-highlight') + } else { + node.removeClass('shuffle-hover-highlight') + } + } + } + } + } + } + + const handleActionHover = (inside, actionId) => { + if (cy !== undefined) { + var node = cy.getElementById(actionId) + if (node.length > 0) { + if (inside) { + node.addClass('shuffle-hover-highlight') + } else { + node.removeClass('shuffle-hover-highlight') + } + } + } + } + + const handleMouseover = () => { + if (innerdata.type === "Execution Argument") { + handleExecArgumentHover(true) + } else if (innerdata.type === "action") { + handleActionHover(true, innerdata.id) + } + } + + const handleMouseOut = () => { + if (innerdata.type === "Execution Argument") { + handleExecArgumentHover(false) + } else if (innerdata.type === "action") { + handleActionHover(false, innerdata.id) + } + } + + var parsedPaths = [] + if (typeof(innerdata.example) === "object") { + parsedPaths = GetParsedPaths(innerdata.example, "") + } + + return ( + parsedPaths.length > 0 ? + + {icon} {innerdata.name} +
+ } + parentMenuOpen={!!menuPosition} + style={{backgroundColor: theme.palette.inputColor, color: "white", minWidth: 250, maxWidth: 250, maxHeight: 650, scrollX: "", }} + //PaperProps={{ + // style: { + // maxHeight: 400, + // width: 250, + // } + //}} + onClick={() => { + console.log("CLICKED: ", innerdata) + handleItemClick([innerdata]) + }} + > + {parsedPaths.map((pathdata, index) => { + // FIXME: Should be recursive in here + const icon = pathdata.type === "value" ? : pathdata.type === "list" ? : + return ( + {console.log("HOVER: ", pathdata)}} + onClick={() => { + handleItemClick([innerdata, pathdata]) + }} + > + +
+ {icon} {pathdata.name} +
+
+
+ ) + + })} + + : + handleMouseover()} onMouseOut={() => {handleMouseOut()}} + onClick={() => { + handleItemClick([innerdata]) + }} + > + +
+ {icon} {innerdata.name} +
+
+
+ + ) + })} +
+ ) + } + + + var tmpitem = data.name.valueOf() + if (data.name.startsWith("${") && data.name.endsWith("}")) { + tmpitem = tmpitem.slice(2, data.name.length-1) + } + + tmpitem = (tmpitem.charAt(0).toUpperCase()+tmpitem.substring(1)).replaceAll("_", " ") + const description = data.description === undefined ? "" : data.description + const tooltipDescription = + + - Required: {data.required === true || data.configuration === true ? "True" : "False"} + - Example: {data.example} + - Description: {description} + + + //var itemColor = "#f85a3e" + //if (!data.required) { + // itemColor = "#ffeb3b" + //} + {/*
*/} + return ( +
+
+ {data.configuration === true ? + + { + setAuthenticationModalOpen(true) + }}/> + + : + null + } +
+ + {tmpitem} + +
+ + {/*selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 ? null : +
+ +
{ + e.preventDefault() + changeActionParameterVariant("STATIC_VALUE", count) + }}> + +
+
+  |  + +
{ + e.preventDefault() + changeActionParameterVariant("ACTION_RESULT", count) + }}> + +
+
+  |  + +
{ + e.preventDefault() + changeActionParameterVariant("WORKFLOW_VARIABLE", count) + }}> + +
+
+
+ */} + {(selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 && selectedActionParameters[count].required === true && selectedActionParameters[count].unique_toggled !== undefined) || hideExtraTypes ? null : +
+ +
{}}> + { + //console.log("CHECKED!: ", selectedActionParameters[count]) + selectedActionParameters[count].unique_toggled = !selectedActionParameters[count].unique_toggled + selectedAction.parameters[count].unique_toggled = selectedActionParameters[count].unique_toggled + setSelectedActionParameters(selectedActionParameters) + setSelectedAction(selectedAction) + setUpdate(Math.random()) + }} + name="requires_unique" + /> +
+
+
+ } +
+ {datafield} + {showDropdown && showDropdownNumber === count && data.variant === "STATIC_VALUE" && jsonList.length > 0 ? + + Autocomplete + + + : null} + {showDropdown && showDropdownNumber === count && data.variant === "STATIC_VALUE" && jsonList.length === 0 ? + + : null} + + +
+ )})} +
+ ) + } + return null + } + + //const CustomPopper = function (props) { + // const classes = useStyles() + // return + //} + + const baselabel = selectedAction.label + return ( +
+ {hideExtraTypes === true ? null : + +
+
+

{(selectedAction.app_name.charAt(0).toUpperCase()+selectedAction.app_name.substring(1)).replaceAll("_", " ")}

+
+ { + console.log("FIND EXAMPLE RESULTS FOR ", selectedAction) + if (workflowExecutions.length > 0) { + // Look for the ID + const found = false + for (var key in workflowExecutions) { + if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) { + continue + } + + var foundResult = workflowExecutions[key].results.find(result => result.action.id === selectedAction.id) + if (foundResult === undefined || foundResult === null) { + continue + } + + setSelectedResult(foundResult) + + if (setCodeModalOpen !== undefined) { + setCodeModalOpen(true) + } + break + } + } + }}> + + + + + + What are actions? + {selectedAction.errors !== undefined && selectedAction.errors !== null && selectedAction.errors.length > 0 ? +
+ Errors: {selectedAction.errors.join("\n")} +
+ : null + } +
+
+
+
+ {selectedAction.id === workflow.start ? null : + + + + } + {selectedApp.versions !== null && selectedApp.versions !== undefined && selectedApp.versions.length > 1 ? + + : null } +
+
+ + + Name + + { + const name = e.target.value + console.log("CHANGED FROM2: ", baselabel) + console.log("CHANGED TO: ", name) + for (var key in workflow.actions) { + for (var subkey in workflow.actions[key].parameters) { + const param = workflow.actions[key].parameters[subkey] + if (param.value.includes(baselabel)) { + //if (param.value.toLowerCase().includes(baselabel)) { + console.log("FOUND: ", param) + workflow.actions[key].parameters[subkey].value.replaceAll(baselabel, e.target.value) + } + } + } + + console.log("DID REPLACE ACTUALLY WORK?? - Something is buggy.") + setWorkflow(workflow) + }} + /> +
+ } + {selectedApp.name !== undefined && selectedAction.authentication !== null && selectedAction.authentication !== undefined && selectedAction.authentication.length === 0 && requiresAuthentication ? +
+ + + + + +
+ : null} + {selectedAction.authentication !== undefined && selectedAction.authentication !== null && selectedAction.authentication.length > 0 ? +
+ Authentication +
+ + + {/* + + + curaction.authentication = authenticationOptions + if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "") + */} + + { + setAuthenticationModalOpen(true) + }}> + + + +
+
+ : null} + + {showEnvironment !== undefined && showEnvironment ? +
+ + Environment + + +
+ : null} + + {workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > 0 ? +
+ + Set execution variable (optional) + + +
+ : null} + + +
+ {/*hideExtraTypes ? null : +
+ Actions +
+ */} + + {setNewSelectedAction !== undefined ? + { + if (option === undefined || option === null || option.name === undefined || option.name === undefined) { + return null + } + + const newname = (option.name.charAt(0).toUpperCase()+option.name.substring(1)).replaceAll("_", " ") + return newname + }} + options={sortByKey(selectedApp.actions, "label")} + fullWidth + style={{backgroundColor: theme.palette.inputColor, height: 50, borderRadius: theme.palette.borderRadius,}} + onChange={(event, newValue) => { + // Workaround with event lol + if (newValue !== undefined && newValue !== null) { + setNewSelectedAction({"target": {"value": newValue.name}}) + } + + }} + renderOption={(data) => { + var newActionname = data.name + if (data.label !== undefined && data.label !== null && data.label.length > 0) { + newActionname = data.label + } + + const iconInfo = GetIconInfo({"name": data.name}) + const useIcon = iconInfo.originalIcon + + newActionname = (newActionname.charAt(0).toUpperCase()+newActionname.substring(1)).replaceAll("_", " ") + + return ( +
+ {useIcon} + {newActionname} +
+ ) + }} + renderInput={(params) => { + return ( + + ) + }} + /> + + : null} + + {/*setNewSelectedAction !== undefined ? + + : null*/} + + {selectedAction.description !== undefined && selectedAction.description.length > 0 && hideExtraTypes !== true ? +
+ {selectedAction.description} +
: null} + +
+ +
+
+
+ ) + } + + +export default ParsedAction; diff --git a/frontend/src/defaultCytoscapeStyle.js b/frontend/src/defaultCytoscapeStyle.js index 8fd5d326..48642d60 100644 --- a/frontend/src/defaultCytoscapeStyle.js +++ b/frontend/src/defaultCytoscapeStyle.js @@ -24,7 +24,7 @@ const data = [{ 'curve-style': 'unbundled-bezier', 'label': 'data(label)', 'text-margin-y': '-15px', - 'width': '2px', + 'width': '5px', "color": "white", "line-fill": "linear-gradient", "line-gradient-stop-positions": ["0.0", "100"], @@ -40,6 +40,7 @@ const data = [{ 'background-width': '100%', 'background-height': '100%', 'border-radius': '5px', + 'z-index': 5001, }, }, { @@ -47,13 +48,23 @@ const data = [{ css: { 'width': '30px', 'height': '30px', - }, + 'z-index': 5000, + 'font-size': '0px', + 'background-width': '75%', + 'background-height': '75%', + 'background-color': 'data(iconBackground)', + 'background-fill': 'data(fillstyle)', + 'background-gradient-direction': 'to-right', + 'background-gradient-stop-colors': 'data(fillGradient)', + } }, { selector: `node[app_name="Testing"]`, css: { 'width': '30px', 'height': '30px', + 'z-index': 5000, + 'font-size': '0px', }, }, { @@ -112,6 +123,37 @@ const data = [{ 'background-color': '#edbd21', }, }, + { + selector: 'node[?isButton]', + css: { + 'shape': 'ellipse', + 'width': '15px', + 'height': '15px', + 'z-index': '5002', + 'font-size': '0px', + 'border': '1px solid rgba(255,255,255,0.9)', + 'background-image': 'data(icon)', + 'background-color': 'data(iconBackground)', + }, + }, + { + selector: 'node[?isDescriptor]', + css: { + 'shape': 'ellipse', + 'border-color': '#80deea', + 'width': '5px', + 'height': '5px', + 'z-index': '5002', + 'font-size': '10px', + 'text-valign': 'center', + 'text-halign': 'center', + 'border': '1px solid black', + 'margin-right': '0px', + 'text-margin-x': '0px', + 'background-color': 'data(imageColor)', + 'background-image': 'data(image)', + }, + }, { selector: 'node[?isStartNode]', css: { @@ -119,6 +161,9 @@ const data = [{ 'border-color': '#80deea', 'width': '80px', 'height': '80px', + 'font-size': '18px', + 'background-width': '100%', + 'background-height': '100%', }, }, { @@ -204,8 +249,9 @@ const data = [{ 'border-width': '12px', 'transition-property': 'border-width', 'transition-duration': '0.25s', - 'font-size': '30px', 'label': 'data(label)', + 'font-size': '18px', + 'color': 'white', }, }, { @@ -227,6 +273,17 @@ const data = [{ 'transition-duration': '0.25s', }, }, + { + selector: `edge[?decorator]`, + css: { + 'width': '1px', + 'line-style': 'dashed', + "line-fill": "linear-gradient", + 'target-arrow-color': '#f34079', + "line-gradient-stop-positions": ["0.0", "100"], + "line-gradient-stop-colors": ["#f86a3e", "#f34079"], + }, + }, { selector: 'edge.success-highlight', css: { @@ -240,17 +297,6 @@ const data = [{ "line-gradient-stop-colors": ["#41dcab", "#41dcab"], }, }, - { - selector: 'edge[?hasErrors]', - css: { - 'target-arrow-color': '#991818', - 'line-color': '#991818', - 'line-style': 'dashed', - "line-fill": "linear-gradient", - "line-gradient-stop-positions": ["0.0", "100"], - "line-gradient-stop-colors": ["#991818", "#991818"], - }, - }, { selector: '.eh-handle', style: { @@ -290,7 +336,34 @@ const data = [{ css: { 'target-arrow-color': '#f85a3e', }, - } - ] + }, + { + selector: `edge[?source_workflow]`, + css: { + "background-opacity": "1", + 'font-size': '0px', + }, + }, + { + selector: `node[?source_workflow]`, + css: { + "background-opacity": "0", + 'font-size': '0px', + }, + }, +] + +//{ +// selector: 'edge[?hasErrors]', +// css: { +// 'target-arrow-color': '#991818', +// 'line-color': '#991818', +// 'line-style': 'dashed', +// "line-fill": "linear-gradient", +// "line-gradient-stop-positions": ["0.0", "100"], +// "line-gradient-stop-colors": ["#991818", "#991818"], +// }, +//}, + export default data diff --git a/frontend/src/theme.js b/frontend/src/theme.js index 13b47d64..f5424ea8 100644 --- a/frontend/src/theme.js +++ b/frontend/src/theme.js @@ -26,7 +26,13 @@ const theme = createMuiTheme({ maxWidth: "95%", fontSize: "1em", borderRadius: 5, - } + }, + tooltip: { + backgroundColor: "white", + color: 'rgba(0, 0, 0, 0.87)', + boxShadow: 1, + fontSize: 11, + }, }, typography: { "fontFamily": `"Roboto", "Helvetica", "Arial", sans-serif`, diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx index dfefcd5f..f32040fb 100644 --- a/frontend/src/views/Admin.jsx +++ b/frontend/src/views/Admin.jsx @@ -66,7 +66,7 @@ const Admin = (props) => { const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" const getApps = () => { - fetch(globalUrl+"/api/v1/workflows/apps", { + fetch(globalUrl+"/api/v1/apps", { method: 'GET', headers: { 'Content-Type': 'application/json', @@ -149,9 +149,12 @@ const Admin = (props) => { response.json().then(responseJson => { console.log("RESP: ", responseJson) if (responseJson["success"] === false) { - alert.error("Failed stopping schedule") + alert.error("Failed deleting auth") } else { - getAppAuthentication() + // Need to wait because query in ES is too fast + setTimeout(() => { + getAppAuthentication() + }, 1000) alert.success("Successfully deleted authentication!") } }), @@ -223,7 +226,9 @@ const Admin = (props) => { return response.json() }) .then((responseJson) => { - handleGetOrg(org_id) + setTimeout(() => { + handleGetOrg(org_id) + }, 1000) }) .catch(error => { alert.error("Err: " + error.toString()) @@ -260,9 +265,12 @@ const Admin = (props) => { } return response.json() + //setTimeout(() => { + //}, 1000) }) .then((responseJson) => { - if (!responseJson.success && responseJson.reason !== undefined) { + console.log("RESP: ", responseJson) + if (responseJson.success === false && responseJson.reason !== undefined) { setOrgSyncResponse(responseJson.reason) alert.error("Failed to handle sync: "+responseJson.reason) } else if (!responseJson.success) { @@ -346,7 +354,9 @@ const Admin = (props) => { } else { alert.success("Successfully updated auth everywhere!") setSelectedUserModalOpen(false) - getAppAuthentication() + setTimeout(() => { + getAppAuthentication() + }, 1000) } }), ) @@ -373,7 +383,11 @@ const Admin = (props) => { .then(response => response.json().then(responseJson => { if (responseJson["success"] === false) { - alert.error("Failed setting new password") + if (responseJson.reason !== undefined) { + alert.error(responseJson.reason) + } else { + alert.error("Failed setting new password") + } } else { alert.success("Successfully updated password!") setSelectedUserModalOpen(false) @@ -387,7 +401,7 @@ const Admin = (props) => { const deleteUser = (data) => { // Just use this one? - const userId = isCloud ? data.username : data.id + const userId = data.id const url = globalUrl + '/api/v1/users/' + userId fetch(url, { @@ -459,9 +473,9 @@ const Admin = (props) => { // FIXME: Set up features - Object.keys(responseJson.sync_features).map(function(key, index) { - //console.log(responseJson.sync_features[key]) - }) + //Object.keys(responseJson.sync_features).map(function(key, index) { + // //console.log(responseJson.sync_features[key]) + //}) //setOrgName(responseJson.name) //setOrgDescription(responseJson.description) @@ -474,6 +488,41 @@ const Admin = (props) => { }); } + const inviteUser = (data) => { + console.log("INPUT: ", data) + setLoginInfo("") + + // Just use this one? + var data = { "username": data.Username, "type": "invite", "org_id": selectedOrganization.id} + var baseurl = globalUrl + const url = baseurl + '/api/v1/users/register_org'; + + fetch(url, { + method: 'POST', + credentials: "include", + body: JSON.stringify(data), + headers: { + 'Content-Type': 'application/json', + }, + }) + .then(response => + response.json().then(responseJson => { + if (responseJson["success"] === false) { + setLoginInfo("Error: " + responseJson.reason) + } else { + setLoginInfo("") + setModalOpen(false) + setTimeout(() => { + getUsers() + }, 1000) + } + }), + ) + .catch(error => { + console.log("Error in userdata: ", error) + }); + } + const submitUser = (data) => { console.log("INPUT: ", data) setLoginInfo("") @@ -498,7 +547,9 @@ const Admin = (props) => { } else { setLoginInfo("") setModalOpen(false) - getUsers() + setTimeout(() => { + getUsers() + }, 1000) } }), ) @@ -816,7 +867,6 @@ const Admin = (props) => { return response.json() }) .then((responseJson) => { - console.log(responseJson) setSchedules(responseJson) }) .catch(error => { @@ -844,7 +894,7 @@ const Admin = (props) => { .then((responseJson) => { if (responseJson.success) { //console.log(responseJson.data) - console.log(responseJson) + //console.log(responseJson) setAuthentication(responseJson.data) } else { alert.error("Failed getting authentications") @@ -955,34 +1005,45 @@ const Admin = (props) => { }); } + const views = { + 0: "organization", + 1: "users", + 2: "app_auth", + 3: "files", + 4: "schedules", + 5: "environments", + 6: "categories", + } const setConfig = (event, newValue) => { + //console.log("Value: ", newValue) + + setCurTab(parseInt(newValue)) if (newValue === 1) { + document.title = "Shuffle - admin - users" getUsers() } else if (newValue === 2) { + document.title = "Shuffle - admin - app authentication" getAppAuthentication() } else if (newValue === 3) { + document.title = "Shuffle - admin - files" getFiles() } else if (newValue === 4) { + document.title = "Shuffle - admin - schedules" getSchedules() } else if (newValue === 5) { + document.title = "Shuffle - admin - environments" getEnvironments() } else if (newValue === 6) { + document.title = "Shuffle - admin - orgs" getOrgs() + } else { + document.title = "Shuffle - admin" } if (newValue === 6) { console.log("Should get apps for categories.") } - const views = { - 0: "organization", - 1: "users", - 2: "app_auth", - 3: "environments", - 4: "schedules", - 5: "files", - 6: "categories", - } //var theURL = window.location.pathname //FIXME: Add url edits @@ -994,33 +1055,21 @@ const Admin = (props) => { //window.location.pathame = newpath setModalUser({}) - setCurTab(newValue) } if (firstRequest) { setFirstRequest(false) + document.title = "Shuffle - admin" if (!isCloud) { getUsers() } else { getSettings() } - const views = { - "organization": 0, - "users": 1, - "app_auth": 2, - "environments": 3, - "schedules": 4, - "files": 5, - } - if (props.match.params.key !== undefined) { - const tmpitem = views[props.match.params.key] - if (tmpitem !== undefined) { - //setCurTab(tmpitem) - setConfig("", tmpitem) - } + //const tmpitem = views[props.match.params.key] + setConfig("", props.match.params.key) } } @@ -1045,7 +1094,6 @@ const Admin = (props) => { const setUser = (userId, field, value) => { const data = { "user_id": userId } data[field] = value - console.log("DATA: ", data) fetch(globalUrl + "/api/v1/users/updateuser", { method: 'PUT', @@ -1080,7 +1128,7 @@ const Admin = (props) => { const generateApikey = (user) => { - const userId = isCloud ? user.username : user.id + const userId = user.id const data = { "user_id": userId } fetch(globalUrl + "/api/v1/generateapikey", { @@ -1207,37 +1255,41 @@ const Admin = (props) => { }, }} > - Edit user + Editing {selectedUser.username} -
- setNewPassword(e.target.value)} - /> - -
+ {isCloud ? + null + : +
+ setNewPassword(e.target.value)} + /> + +
+ } +
diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index bb6e1d40..a40590d9 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -1,16 +1,17 @@ -import React, {useState, useEffect, useLayoutEffect} from 'react'; +import React, {useRef, useState, useEffect, useLayoutEffect} from 'react'; import { useInterval } from 'react-powerhooks'; import { useTheme } from '@material-ui/core/styles'; import uuid from "uuid"; import {Link} from 'react-router-dom'; import { Prompt } from 'react-router' -import ReactJson from 'react-json-view' import { useBeforeunload } from 'react-beforeunload'; +import ReactJson from 'react-json-view' import NestedMenuItem from "material-ui-nested-menu-item"; + import {TextField, Drawer, Button, Paper, Grid, Tabs, InputAdornment, Tab, ButtonBase, Tooltip, Select, MenuItem, Divider, Dialog, Modal, DialogActions, DialogTitle, InputLabel, DialogContent, FormControl, IconButton, Menu, Input, FormGroup, FormControlLabel, Typography, Checkbox, Breadcrumbs, CircularProgress, Switch, Fade} from '@material-ui/core'; -import {GetApp as GetAppIcon, Search as SearchIcon, ArrowUpward as ArrowUpwardIcon, Visibility as VisibilityIcon, Done as DoneIcon, Close as CloseIcon, Error as ErrorIcon, FindReplace as FindreplaceIcon, ArrowLeft as ArrowLeftIcon, Cached as CachedIcon, DirectionsRun as DirectionsRunIcon, Add as AddIcon, Polymer as PolymerIcon, FormatListNumbered as FormatListNumberedIcon, Create as CreateIcon, PlayArrow as PlayArrowIcon, AspectRatio as AspectRatioIcon, MoreVert as MoreVertIcon, Apps as AppsIcon, Schedule as ScheduleIcon, FavoriteBorder as FavoriteBorderIcon, Pause as PauseIcon, Delete as DeleteIcon, AddCircleOutline as AddCircleOutlineIcon, Save as SaveIcon, KeyboardArrowLeft as KeyboardArrowLeftIcon, KeyboardArrowRight as KeyboardArrowRightIcon, ArrowBack as ArrowBackIcon, Settings as SettingsIcon, LockOpen as LockOpenIcon, ExpandMore as ExpandMoreIcon, VpnKey as VpnKeyIcon} from '@material-ui/icons'; +import {OpenInNew as OpenInNewIcon,Undo as UndoIcon, FileCopy as FileCopyIcon, GetApp as GetAppIcon, Search as SearchIcon, ArrowUpward as ArrowUpwardIcon, Visibility as VisibilityIcon, Done as DoneIcon, Close as CloseIcon, Error as ErrorIcon, FindReplace as FindreplaceIcon, ArrowLeft as ArrowLeftIcon, Cached as CachedIcon, DirectionsRun as DirectionsRunIcon, Add as AddIcon, Polymer as PolymerIcon, FormatListNumbered as FormatListNumberedIcon, Create as CreateIcon, PlayArrow as PlayArrowIcon, AspectRatio as AspectRatioIcon, MoreVert as MoreVertIcon, Apps as AppsIcon, Schedule as ScheduleIcon, FavoriteBorder as FavoriteBorderIcon, Pause as PauseIcon, Delete as DeleteIcon, AddCircleOutline as AddCircleOutlineIcon, Save as SaveIcon, KeyboardArrowLeft as KeyboardArrowLeftIcon, KeyboardArrowRight as KeyboardArrowRightIcon, ArrowBack as ArrowBackIcon, Settings as SettingsIcon, LockOpen as LockOpenIcon, ExpandMore as ExpandMoreIcon, VpnKey as VpnKeyIcon} from '@material-ui/icons'; import * as cytoscape from 'cytoscape'; import * as edgehandles from 'cytoscape-edgehandles'; @@ -24,9 +25,12 @@ import cxtmenu from 'cytoscape-cxtmenu'; import { w3cwebsocket as W3CWebSocket } from "websocket"; import { useAlert } from "react-alert"; -import { validateJson } from "./Workflows.jsx"; +import { validateJson, GetIconInfo } from "./Workflows.jsx"; import { GetParsedPaths } from "./Apps.jsx"; import ConfigureWorkflow from '../components/ConfigureWorkflow.jsx'; +import ParsedAction from '../components/ParsedAction.jsx'; +import Scroll from 'react-scroll' +import { Element as ScrollElement, animateScroll as scroll, scrollSpy, scroller } from 'react-scroll' const surfaceColor = "#27292D" const inputColor = "#383B40" @@ -35,7 +39,12 @@ const inputColor = "#383B40" cytoscape.use(edgehandles); cytoscape.use(clipboard); cytoscape.use(undoRedo); -cytoscape.use( cxtmenu ); +cytoscape.use(cxtmenu); + +// Adds specific text to items +//import popper from 'cytoscape-popper'; +//cytoscape.use(popper); + // https://stackoverflow.com/questions/19014250/rerender-view-on-browser-resize-with-react function useWindowSize() { @@ -51,6 +60,25 @@ function useWindowSize() { return size; } +export function sortByKey(array, key) { + if (array === undefined) { + return [] + } + + if (key.startsWith("-") && key.length > 2) { + key = key.slice(1, key.length) + return array.sort(function(a, b) { + var x = a[key]; var y = b[key] + return ((x < y) ? -1 : ((x > y) ? 1 : 0)) + }).reverse() + } + + return array.sort(function(a, b) { + var x = a[key]; var y = b[key] + return ((x < y) ? -1 : ((x > y) ? 1 : 0)) + }) +} + function removeParam(key, sourceURL) { if (sourceURL === undefined) { return @@ -80,14 +108,30 @@ function removeParam(key, sourceURL) { } const splitter = "|~|" +const svgSize = 24 //const referenceUrl = "https://shuffler.io/functions/webhooks/" //const referenceUrl = window.location.origin+"/api/v1/hooks/" +function useTraceUpdate(props) { + const prev = useRef(props) + useEffect(() => { + const changedProps = Object.entries(props).reduce((ps, [k, v]) => { + if (prev.current[k] !== v) { + ps[k] = [prev.current[k], v]; + } + return ps; + }, {}); + if (Object.keys(changedProps).length > 0) { + console.log('Changed props:', changedProps); + } + prev.current = props; + }); +} + const AngularWorkflow = (props) => { const { globalUrl, isLoggedIn, isLoaded, userdata } = props; const referenceUrl = globalUrl+"/api/v1/hooks/" const alert = useAlert() - const borderRadius = 5 const theme = useTheme(); const green = "#86c142" const yellow = "#FECC00" @@ -112,6 +156,14 @@ const AngularWorkflow = (props) => { const [leftBarSize, setLeftBarSize] = React.useState(350) const [executionText, setExecutionText] = React.useState(""); const [executionRequestStarted, setExecutionRequestStarted] = React.useState(false); + const [scrollConfig, setScrollConfig] = React.useState({ + top: 0, + left: 0, + selected: "", + }) + + const [history, setHistory] = React.useState([]) + const [historyIndex, setHistoryIndex] = React.useState(history.length) const [appAuthentication, setAppAuthentication] = React.useState([]); const [variablesModalOpen, setVariablesModalOpen] = React.useState(false); @@ -204,16 +256,15 @@ const AngularWorkflow = (props) => { } }) - const [elements, setElements] = useState([]) // No point going as fast, as the nodes aren't realtime anymore, but bulk updated. // Set it from 2500 to 6000 to reduce overall load const { start, stop } = useInterval({ - duration: 6000, - startImmediate: false, - callback: () => { - fetchUpdates() - } + duration: 3000, + startImmediate: false, + callback: () => { + fetchUpdates() + } }) const getAvailableWorkflows = (trigger_index) => { @@ -236,6 +287,7 @@ const AngularWorkflow = (props) => { if (responseJson !== undefined) { setWorkflows(responseJson) + // Sets up subflow trigger with the right info if (trigger_index > -1) { var outersub = {} const trigger = workflow.triggers[trigger_index] @@ -243,15 +295,20 @@ const AngularWorkflow = (props) => { for (var key in trigger.parameters) { const param = trigger.parameters[key] if (param.name === "workflow") { - const sub = responseJson.find(data => data.id === param.value) - if (sub !== undefined && subworkflow.id !== sub.id) { - setSubworkflow(sub) - outersub = sub + if (param.value === workflow.id) { + setSubworkflow(workflow) + outersub = workflow + } else { + const sub = responseJson.find(data => data.id === param.value) + if (sub !== undefined && subworkflow.id !== sub.id) { + setSubworkflow(sub) + outersub = sub + } } } if (param.name === "startnode" && outersub.id !== undefined) { - console.log("SHOULD SET STARTNODE: ", outersub) + console.log("SHOULD SET STARTNODE IN SUBFLOW SELECTION: ", outersub) const innernode = outersub.actions.find(action => action.id === param.value) console.log("FOUND NODE: ", innernode) if (innernode !== undefined && subworkflowStartnode.id !== innernode.id) { @@ -460,7 +517,7 @@ const AngularWorkflow = (props) => { console.log("Error: ", error) //alert.error(error.toString()) stop() - }); + }) } const abortExecution = () => { @@ -479,7 +536,7 @@ const AngularWorkflow = (props) => { if (response.status !== 200) { console.log("Status not 200 for ABORT EXECUTION :O!") } else { - alert.success("Execution aborted") + //alert.success("Execution aborted") } return response.json() @@ -499,9 +556,19 @@ const AngularWorkflow = (props) => { if (JSON.stringify(responseJson) !== JSON.stringify(executionData)) { // FIXME: If another is selected, don't edit.. // Doesn't work because this is some async garbage - if (executionData.execution_id === undefined || responseJson.execution_id === executionData.execution_id) { - setExecutionData(responseJson) + if (executionData.execution_id === undefined || (responseJson.execution_id === executionData.execution_id && responseJson.results !== undefined && responseJson.results !== null)) { + + if (executionData.status !== responseJson.status || executionData.result !== responseJson.result || executionData.results.length !== responseJson.results.length) { + //console.log("Updated state with this data:") + //console.log(responseJson) + //console.log(executionData) + setExecutionData(responseJson) + } else { + console.log("NOT updating state.") + } } + } else { + //console.log("JSON is same") } //console.log("PRE LOOPING RESULTS: !", responseJson.execution_id, executionRequest.execution_id) @@ -513,7 +580,7 @@ const AngularWorkflow = (props) => { //console.log("LOOPING RESULTS!") - if (responseJson.results !== null && responseJson.results !== []) { + if (responseJson.results !== null && responseJson.results.length > 0) { for (var key in responseJson.results) { var item = responseJson.results[key] var currentnode = cy.getElementById(item.action.id) @@ -607,7 +674,9 @@ const AngularWorkflow = (props) => { break case "FAILURE": //When status comes as failure, allow user to start workflow execution - setExecutionRunning(false) + if (executionRunning) { + setExecutionRunning(false) + } currentnode.removeClass('not-executing-highlight') currentnode.removeClass('executing-highlight') @@ -642,7 +711,10 @@ const AngularWorkflow = (props) => { if (responseJson.status === "ABORTED" || responseJson.status === "STOPPED" || responseJson.status === "FAILURE" || responseJson.status == "WAITING") { stop() - setExecutionRunning(false) + if (executionRunning) { + setExecutionRunning(false) + } + var curelements = cy.elements() for (var i = 0; i < curelements.length; i++) { if (curelements[i].classes().includes("executing-highlight")) { @@ -664,11 +736,20 @@ const AngularWorkflow = (props) => { stop() getWorkflowExecution(props.match.params.key, "") setUpdate(Math.random()) + } else { + //console.log("Nothing to update") } } const saveWorkflow = (curworkflow) => { var success = false + + if (isCloud && !isLoggedIn) { + console.log("Should redirect to register with redirect.") + window.location.href = `/register?view=/workflows/${props.match.params.key}&message=You need sign up to use workflows with Shuffle` + return + } + setSavingState(2) // This might not be the right course of action, but seems logical, as items could be running already @@ -685,6 +766,7 @@ const AngularWorkflow = (props) => { var newActions = [] var newTriggers = [] var newBranches = [] + var newVBranches = [] for (var key in cyelements) { if (cyelements[key].data === undefined) { continue @@ -702,13 +784,20 @@ const AngularWorkflow = (props) => { source_id: cyelements[key].data().source, destination_id: cyelements[key].data().target, conditions: cyelements[key].data().conditions, + decorator: cyelements[key].data().decorator, } - newBranches.push(parsedElement) + if (parsedElement.decorator) { + newVBranches.push(parsedElement) + } else { + newBranches.push(parsedElement) + } } else { if (type === "ACTION") { - // FIXME - check whether position is new to not fuck up params etc. - var curworkflowAction = useworkflow.actions.find(a => a.id === cyelements[key].data()["id"]) + const cyelement = cyelements[key].data() + const elementid = cyelement.id === undefined || cyelement.id === null ? cyelement["_id"] : cyelement.id + + var curworkflowAction = useworkflow.actions.find(a => a !== undefined && (a["id"] === elementid || a["_id"] === elementid)) if (curworkflowAction === undefined) { curworkflowAction = cyelements[key].data() } @@ -761,9 +850,11 @@ const AngularWorkflow = (props) => { useworkflow.actions = newActions useworkflow.triggers = newTriggers useworkflow.branches = newBranches + useworkflow.visual_branches = newVBranches // Errors are backend defined useworkflow.errors = [] + useworkflow.previously_saved = true setLastSaved(true) fetch(globalUrl+"/api/v1/workflows/"+props.match.params.key, { @@ -1017,10 +1108,10 @@ const AngularWorkflow = (props) => { // This can be used to only show prioritzed ones later // Right now, it can prioritize authenticated ones + //"Testing", const internalIds = [ "Shuffle Tools", - "Testing", - "Http", + "http", ] const getAppAuthentication = (reset) => { @@ -1055,7 +1146,6 @@ const AngularWorkflow = (props) => { // Remove the old listener for select, run with new one cy.removeListener('select') - cy.on('select', 'node', (e) => onNodeSelect(e, newauth)) cy.on('select', 'edge', (e) => onEdgeSelect(e)) } @@ -1096,7 +1186,7 @@ const AngularWorkflow = (props) => { //var tmpapps = [] //tmpapps = tmpapps.concat(getExtraApps()) //tmpapps = tmpapps.concat(responseJson) - //console.log("APPS: ", responseJson) + console.log("APPS: ", responseJson) setApps(responseJson) if (isCloud) { @@ -1112,15 +1202,17 @@ const AngularWorkflow = (props) => { }); } - const getWorkflow = () => { - fetch(globalUrl+"/api/v1/workflows/"+props.match.params.key, { - method: 'GET', + const getWorkflow = (workflow_id, sourcenode) => { + console.log(`Getting workflow ${workflow_id} with append value ${sourcenode}`) + + fetch(globalUrl+"/api/v1/workflows/"+workflow_id, { + method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, - credentials: "include", - }) + credentials: "include", + }) .then((response) => { if (response.status !== 200) { console.log("Status not 200 for workflows :O!") @@ -1141,11 +1233,129 @@ const AngularWorkflow = (props) => { if (responseJson.public) { alert.info("This workflow is public. You will have to save it to make it your own!") - setLastSaved(false) + //setLastSaved(false) } - setWorkflow(responseJson) - setWorkflowDone(true) + // Appends SUBFLOWS. Does NOT run during normal grabbing of workflows. + if (sourcenode.id !== undefined) { + console.log("WORKFLOW: ", responseJson) + + var nodefound = false + const target = sourcenode.parameters.find(item => item.name === "startnode") + console.log(sourcenode.parameters) + console.log(target) + const target_id = target === undefined ? "" : target.value + const actions = responseJson.actions.map(action => { + const node = { + group: "nodes", + } + + // Set it dynamically? + node.position = { + x: sourcenode.position.x+action.position.x, + y: sourcenode.position.y+action.position.y, + } + + node.data = action + + node.data._id = action["id"] + node.data.type = "ACTION" + node.data.source_workflow = responseJson.id + if (action.id === target_id) { + nodefound = true + } + + var example = "" + if (action.example !== undefined && action.example !== null && action.example.length > 0) { + example = action.example + } + + node.data.example = example + return node; + }) + + var edges = responseJson.branches.map((branch, index) => { + const edge = { }; + var conditions = responseJson.branches[index].conditions + if (conditions === undefined || conditions === null) { + conditions = [] + } + + var label = "" + if (conditions.length === 1) { + label = conditions.length+" condition" + } else if (conditions.length > 1) { + label = conditions.length+" conditions" + } + + const sourceFound = actions.findIndex(action => action.data.id === branch.source_id) + if (sourceFound < 0) { + return null + } + + const destinationFound = actions.findIndex(action => action.data.id === branch.destination_id) + if (destinationFound < 0) { + return null + } + + edge.data = { + id: branch.id, + _id: branch.id, + source: branch.source_id, + target: branch.destination_id, + label: label, + conditions: conditions, + hasErrors: branch.has_errors, + decorator: false, + source_workflow: responseJson.id, + } + + return edge; + }) + + + //console.log("Adding node: ", node) + //cy.on('add', 'node', (e) => onNodeAdded(e)) + edges = edges.filter(edge => edge !== null) + cy.removeListener('add') + cy.add(actions) + cy.add(edges) + + if (nodefound === true) { + const newId = uuid.v4() + cy.add({ + group: "edges", + data: { + id: newId, + _id: newId, + source: sourcenode.id, + target: target_id, + label: "Subflow", + decorator: true, + source_workflow: responseJson.id, + } + }) + } + + cy.fit(null, 100) + //cy.zoom(2.0) + cy.on('add', 'node', (e) => onNodeAdded(e)) + cy.on('add', 'edge', (e) => onEdgeAdded(e)) + + //for (var key in + } else { + setWorkflow(responseJson) + setWorkflowDone(true) + + //console.log(responseJson) + // Add error checks + console.log("Workflow: ", responseJson) + if (!responseJson.public) { + if ((!responseJson.previously_saved || (!responseJson.is_valid || (responseJson.errors !== undefined || responseJson.errors !== null || responseJson.errors !== responseJson.errors.length > 0)))) { + setConfigureWorkflowModalOpen(true) + } + } + } }) .catch(error => { alert.error(error.toString()) @@ -1155,6 +1365,13 @@ const AngularWorkflow = (props) => { const onUnselect = (event) => { console.time("UNSELECT") + const nodedata = event.target.data() + if (nodedata.app_name === undefined && nodedata.source === undefined) { + return + } + event.target.removeClass("selected") + + // Attempt at rewrite of name in other actions in following nodes. // Should probably be done in the onBlur for the textfield instead /* @@ -1208,6 +1425,11 @@ const AngularWorkflow = (props) => { // Can be used for right side view setRightSideBarOpen(false) + setScrollConfig({ + top: 0, + left: 0, + selected: "", + }) console.timeEnd("UNSELECT") } @@ -1220,8 +1442,13 @@ const AngularWorkflow = (props) => { const triggercheck = workflow.triggers.find(trigger => trigger.id === event.target.data()["source"]) if (triggercheck === undefined) { */ - setSelectedEdgeIndex(workflow.branches.findIndex(data => data.id === event.target.data()["id"])) - setSelectedEdge(event.target.data()) + //console.log(event.target.data()) + if (event.target.data().decorator) { + alert.info("This edge can't be edited.") + } else { + setSelectedEdgeIndex(workflow.branches.findIndex(data => data.id === event.target.data()["id"])) + setSelectedEdge(event.target.data()) + } /* } else { @@ -1235,21 +1462,284 @@ const AngularWorkflow = (props) => { } // Comparing locations between nodes and setting views - const onNodeDrag = (event) => { - //console.log("DRAGGING: ", event.target) - //console.log("LEN2: ", event.target.edges.length) + var styledElements = [] + var originalLocation = { + x: 0, + y: 0, + } + + const onCtxTap = (event) => { const nodedata = event.target.data() + console.log(nodedata) + if (nodedata.type === "TRIGGER" && nodedata.app_name === "Shuffle Workflow") { + if (nodedata.parameters === null) { + alert.error("Set a workflow first") + return + } + + const workflow_id = nodedata.parameters.find(param => param.name === "workflow") + if (workflow.id === workflow_id.valu) { + return + } + + cy.animation({ + zoom: 0, + center: { + eles: event.target, + }, + }) + .play() + .promise() + .then( () => { + console.log("DONE: ", workflow_id) + //cy.elements().remove() + getWorkflow(workflow_id.value, nodedata) + cy.fit(null, 50) + //props.match.params.key + //cy.animation({ + // zoom: 500, + // center: { + // eles: cy.nodes(), + // }, + //}) + //.play() + //.promise() + }) + + //const animationDuration = 150 + //style: { + //maxZoom={2.00} + //cy.animate({ + // fit: 100, + //}, { + // duration: 500, + //}) + } + } + //cy.on('cxttap', "node", (e) => onCtxTap(e)) + + var hiddenNodes = [] + const onNodeDragStop = (event, selectedAction) => { + const nodedata = event.target.data() + console.log("IN NODE DRAG STOP: ", nodedata) + if (nodedata.id === selectedAction.id) { + return + } + + if (nodedata.finished === false) { + return + } + + //console.log("Drag: ", nodedata) + //return + + //console.log("DRAGGED NODE: ", nodedata) + //console.log("TARGET NODE: ", selectedAction) + if (styledElements.length === 1) { + console.log("Should reset location and autofill: ", styledElements, selectedAction) + //event.target.position = originalLocation + //curworkflowTrigger.position = cyelements[key].position() + if (originalLocation.x !== 0 || originalLocation.y !== 0) { + const currentnode = cy.getElementById(nodedata.id) + if (currentnode !== null && currentnode !== undefined) { + //currentnode.position = originalLocation + currentnode.position("x", originalLocation.x) + currentnode.position("y", originalLocation.y) + } + + originalLocation = {x: 0, y: 0} + } + + const curElement = document.getElementById(styledElements[0]) + if (curElement !== null && curElement !== undefined) { + //console.log("ELE: ", curElement) + curElement.style.border = curElement.style.original_border + var newValue = "$"+nodedata.label.toLowerCase().replaceAll(" ", "_") + var paramname = "" + var idnumber = -1 + if (curElement.id.startsWith("rightside_field_")) { + console.log("FOUND FIELD WITH NUMBER: ", curElement.id) + const idsplit = curElement.id.split("_") + console.log(idsplit) + if (idsplit.length === 3 && !isNaN(idsplit[2])) { + console.log("ADDING TO PARAM ", idsplit[2]) + console.log("PARAM: ", selectedAction) + + selectedAction.parameters[idsplit[2]].value = newValue + paramname = selectedAction.parameters[idsplit[2]].name + idnumber = idsplit[2] + } + } + + if (idnumber >= 0 && paramname.length > 0) { + const exampledata = GetExampleResult(nodedata) + const parsedname = paramname.toLowerCase().trim().replaceAll("_", " ") + + const foundresult = GetParamMatch(parsedname, exampledata, "") + if (foundresult.length > 0) { + console.log("FOUND RESULT: ", paramname, foundresult) + newValue = `${newValue}${foundresult}` + } + + selectedAction.parameters[idnumber].value = newValue + } + + curElement.value = newValue + } + } + + const skipnames = [] + if (nodedata.app_name !== undefined && (( + nodedata.app_name !== "Shuffle Tools" && + nodedata.app_name !== "Testing" && + nodedata.app_name !== "Shuffle Workflow" && + nodedata.app_name !== "User Input" && + nodedata.app_name !== "Webhook" && + nodedata.app_name !== "Schedule" && + nodedata.app_name !== "Email") || nodedata.isStartNode) + ) { + const allNodes = cy.nodes().jsons() + var found = false + for (var key in allNodes) { + const currentNode = allNodes[key] + if (currentNode.data.attachedTo === nodedata.id && currentNode.data.isDescriptor) { + found = true + console.log("FOUND THE NODE!") + break + } + } + + // Readding the icon after moving the node + if (!found) { + //console.log("Node wasn't found") + const iconInfo = GetIconInfo(nodedata) + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + + const offset = nodedata.isStartNode ? 36 : 44 + //console.log(event.target.position()) + const decoratorNode = { + position: { + x: event.target.position().x+offset, + y: event.target.position().y+offset, + }, + locked: true, + data: { + "isDescriptor": true, + "isValid": true, + "is_valid": true, + "label": "", + "image": svgpin_Url, + "imageColor": iconInfo.iconBackgroundColor, + "attachedTo": nodedata.id, + }, + } + + cy.add(decoratorNode).unselectify() + } else { + console.log("Node already exists - don't add descriptor node") + } + } else { + //console.log("Shouldnt re-add info? ") + } + + originalLocation = { + x: 0, + y: 0, + } + } + + const onNodeDrag = (event, selectedAction) => { + //if (Object.getOwnPropertyNames(selectedAction).length === 0) { + // return + //} + const nodedata = event.target.data() + //console.log("Dragging: ", nodedata) + if (nodedata.finished === false) { + return + } + + //console.log("Dragging node!!") if (nodedata.app_name == "Shuffle Tools" || nodedata.app_name == "Testing") { //console.log("NODE: ", //selector: `node[app_name="Shuffle Tools"]`, - console.log(event.target) + //console.log(event.target) // 1. Find location of node // 2. Check if it's within view of another node (inside) // 3. If it is, then hide text } + if (nodedata.app_name !== undefined) { + //console.log("Trying to remove friendly nodes") + const allNodes = cy.nodes().jsons() + for (var key in allNodes) { + const currentNode = allNodes[key] + if (currentNode.data.attachedTo === nodedata.id) { + cy.getElementById(currentNode.data.id).remove() + } + } + } else { + console.log("No appid? ", nodedata) + } + + if (nodedata.id === selectedAction.id) { + return + } + + if (originalLocation.x === 0 && originalLocation.y === 0 && nodedata.position !== undefined) { + //console.log("Updating location!: ", nodedata) + originalLocation.x = nodedata.position.x + originalLocation.y = nodedata.position.y + } + + // Part of autocomplete. Styles elements in frontend to indicate + // what and where we may input data for the user. + const onMouseUpdate = (e) => { + const x = e.pageX; + const y = e.pageY; + + const elementMouseIsOver = document.elementFromPoint(x, y) + if (elementMouseIsOver !== undefined && elementMouseIsOver !== null) { + // Color for #f85a3e translated to rgb + const newBorder = "3px solid rgb(248, 90, 62)" + if (elementMouseIsOver.style.border != newBorder && elementMouseIsOver.id.includes("rightside")) { + //console.log(elementMouseIsOver.style.border) + if (elementMouseIsOver.style.border !== undefined) { + elementMouseIsOver.style.original_border = elementMouseIsOver.style.border + } else { + elementMouseIsOver.style.original_border = "" + } + + elementMouseIsOver.style.border = newBorder + console.log("STYLED: ", styledElements) + for (var key in styledElements) { + const curElement = document.getElementById(styledElements[key]) + if (curElement !== null && curElement !== undefined) { + curElement.style.border = curElement.style.original_border + } + } + + styledElements = [] + styledElements.push(elementMouseIsOver.id) + } else if (elementMouseIsOver.id === "cytoscape_view" || elementMouseIsOver.id === "") { + for (var key in styledElements) { + const curElement = document.getElementById(styledElements[key]) + if (curElement !== null && curElement !== undefined) { + curElement.style.border = curElement.style.original_border + } + } + + styledElements = [] + } + } + + // Ensure it only happens once + document.removeEventListener('mousemove', onMouseUpdate, false) + } + + document.addEventListener('mousemove', onMouseUpdate, false); /* event.target.animate({ @@ -1274,43 +1764,176 @@ const AngularWorkflow = (props) => { // Nodeselectbatching: // https://stackoverflow.com/questions/16677856/cy-onselect-callback-only-once const onNodeSelect = (event, newAppAuth) => { - const data = event.target.data() - setLastSaved(false) - + if (data.isButton) { + //console.log("BUTTON CLICKED: ", data) + if (data.buttonType === "delete") { + //console.log("DELETE!") + const parentNode = cy.getElementById(data.attachedTo) + if (parentNode !== null && parentNode !== undefined) { + parentNode.remove() + } + + //for (var key in allNodes) { + // const currentNode = allNodes[key] + // if (currentNode.data.attachedTo === data.attachedTo) { + // cy.getElementById(currentNode.data.id).remove() + // } + //} + } else if (data.buttonType === "copy") { + console.log("COPY!") + // 1. Find parent + // 2. Find branches for parent + // 3. Make a new node that's moved a little bit + const parentNode = cy.getElementById(data.attachedTo) + if (parentNode !== null && parentNode !== undefined) { + //parentNode.data() + var newNodeData = JSON.parse(JSON.stringify(parentNode.data())) + newNodeData.id = uuid.v4() + if (newNodeData.position !== undefined) { + newNodeData.position = { + "x": newNodeData.position.x+100, + "y": newNodeData.position.y+100, + } + } + + newNodeData.isStartNode = false + newNodeData.errors = [] + newNodeData.is_valid = true + newNodeData.isValid = true + + cy.add({ + group: 'nodes', + data: newNodeData, + position: newNodeData.position, + }) + + // Readding the icon after moving the node + //console.log("Node wasn't found") + if (newNodeData.app_name !== "Testing" || newNodeData.app_name !== "Shuffle Workflow") { + } else { + const iconInfo = GetIconInfo(newNodeData) + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + + const offset = newNodeData.isStartNode ? 36 : 44 + //console.log(event.target.position()) + const decoratorNode = { + position: { + x: newNodeData.position.x+offset, + y: newNodeData.position.y+offset, + }, + locked: true, + data: { + "isDescriptor": true, + "isValid": true, + "is_valid": true, + "label": "", + "image": svgpin_Url, + "imageColor": iconInfo.iconBackgroundColor, + "attachedTo": newNodeData.id, + }, + } + + cy.add(decoratorNode).unselectify() + } + + workflow.actions.push(newNodeData) + + const sourcebranches = workflow.branches.filter(foundbranch => foundbranch.source_id === parentNode.data("id")) + const destinationbranches = workflow.branches.filter(foundbranch => foundbranch.destination_id === parentNode.data("id")) + + //for (var key in sourcebranches) { + // var newbranch = JSON.parse(JSON.stringify(sourcebranches[key])) + // newbranch.id = uuid.v4() + // newbranch.source_id = newNodeData.id + // cy.add({ + // group: "edges", + // data: newbranch, + // }) + //} + + for (var key in sourcebranches) { + var newbranch = JSON.parse(JSON.stringify(sourcebranches[key])) + newbranch.id = uuid.v4() + newbranch.source_id = newNodeData.id + + newbranch._id = newbranch.id + newbranch.source = newbranch.source_id + newbranch.target = newbranch.destination_id + cy.add({ + group: "edges", + data: newbranch, + }) + } + + for (var key in destinationbranches) { + var newbranch = JSON.parse(JSON.stringify(destinationbranches[key])) + newbranch.id = uuid.v4() + newbranch.destination_id = newNodeData.id + + newbranch._id = newbranch.id + newbranch.source = newbranch.source_id + newbranch.target = newbranch.destination_id + cy.add({ + group: "edges", + data: newbranch, + }) + } + } + } + + event.target.unselect() + return + } else if (data.isDescriptor) { + console.log("Can't select descriptor") + event.target.unselect() + return + } + //const node = cy.getElementById(data.id) //if (node.length > 0) { // node.addClass('shuffle-hover-highlight') //} //const branch = workflow.branches.filter(branch => branch.source_id === data.id || branch.destination_id === data.id) - console.log("NODE: ", data) //console.log("APPAUTH: ", newAppAuth) //console.log("BRANCHES: ", branch) if (data.type === "ACTION") { - - - // FIXME - unselect - //console.log(cy.elements('[_id!="${data._id}"]`)) - // Does it choose the wrong action? var curaction = workflow.actions.find(a => a.id === data.id) + //console.log("INSIDE CURACTION: ", curaction) if (!curaction || curaction === undefined) { //event.target.unselect() //alert.error("Action not found. Please remake it.") return } - - const curapp = apps.find(a => a.name === curaction.app_name && a.app_version === curaction.app_version) + const curapp = apps.find(a => a.name === curaction.app_name && ((a.app_version === curaction.app_version || (a.loop_versions !== null && a.loop_versions.includes(curaction.app_version))))) + //console.log("APP: ", curapp) if (!curapp || curapp === undefined) { - alert.error("App "+curaction.app_name+" not found. Is it activated?") + alert.error(`App ${curaction.app_name}:${curaction.app_version} not found. Is it activated?`) + + const tmpapp = { + name: curaction.app_name, + app_name: curaction.app_name, + app_version: curaction.app_version, + id: curaction.app_id, + actions: [curaction], + } + + console.log(tmpapp) + console.log(curaction) + setSelectedApp(tmpapp) + //setSelectedAction(JSON.parse(JSON.stringify(curaction))) + setSelectedAction(curaction) //return } else { - console.log("AUTHENTICATION: ", curapp.authentication) + //console.log("AUTHENTICATION: ", curapp.authentication) setRequiresAuthentication(curapp.authentication.required && curapp.authentication.parameters !== undefined && curapp.authentication.parameters !== null) if (curapp.authentication.required) { + //console.log("App requires auth.") // Setup auth here :) const authenticationOptions = [] var findAuthId = "" @@ -1319,7 +1942,7 @@ const AngularWorkflow = (props) => { } var tmpAuth = JSON.parse(JSON.stringify(newAppAuth)) - console.log("FOUND AUTH: ", tmpAuth) + //console.log("FOUND AUTH: ", tmpAuth) //console.log("Checking authentication: ", tmpAuth) for (var key in tmpAuth) { @@ -1339,7 +1962,7 @@ const AngularWorkflow = (props) => { } } - console.log("OPTIONS: ", authenticationOptions) + //console.log("OPTIONS: ", authenticationOptions) curaction.authentication = authenticationOptions //console.log("Authentication: ", authenticationOptions) if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "") { @@ -1351,8 +1974,15 @@ const AngularWorkflow = (props) => { curaction.selectedAuthentication = {} } + //setSelectedAction(JSON.parse(JSON.stringify(curaction))) + //console.log("CURAPP: ", curapp, selectedApp) setSelectedApp(curapp) setSelectedAction(curaction) + + cy.removeListener('drag') + cy.removeListener('free') + cy.on('drag', 'node', (e) => onNodeDrag(e, curaction)) + cy.on('free', 'node', (e) => onNodeDragStop(e, curaction)) } if (environments !== undefined && environments !== null) { @@ -1380,13 +2010,325 @@ const AngularWorkflow = (props) => { alert.error("Can't handle "+data.type) } + //console.log("BAR: ", rightSideBarOpen, "SAVE: ", lastSaved) setRightSideBarOpen(true) + setLastSaved(false) + + // Refresh listeners + //cy.removeListener('select') + //cy.on('select', 'node', (e) => onNodeSelect(e, newAppAuth, curapp, rightSideBarOpen, lastSaved)) + //cy.on('select', 'edge', (e) => onEdgeSelect(e)) + + setScrollConfig({ + top: 0, + left: 0, + selected: "", + }) } + const GetExampleResult = (item) => { + var exampledata = item.example === undefined ? "" : item.example + if (workflowExecutions.length > 0) { + // Look for the ID + const found = false + for (var key in workflowExecutions) { + if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) { + continue + } + + var foundResult = {"result": ""} + if (item.id === "exec") { + //console.log("EXEC: ", workflowExecutions[key].execution_argument) + if (workflowExecutions[key].execution_argument !== undefined && workflowExecutions[key].execution_argument !== null && workflowExecutions[key].execution_argument.length > 0) { + foundResult.result = workflowExecutions[key].execution_argument + } else { + continue + } + } else { + foundResult = workflowExecutions[key].results.find(result => result.action.id === item.id) + if (foundResult === undefined) { + continue + } + } + + foundResult.result = foundResult.result.trim() + foundResult.result = foundResult.result.split(" None").join(" \"None\"") + foundResult.result = foundResult.result.split(" False").join(" false") + foundResult.result = foundResult.result.split(" True").join(" true") + + var jsonvalid = true + try { + const tmp = String(JSON.parse(foundResult.result)) + if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { + jsonvalid = false + } + } catch (e) { + try { + foundResult.result = foundResult.result.split("\'").join("\"") + const tmp = String(JSON.parse(foundResult.result)) + if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { + jsonvalid = false + } + } catch (e) { + jsonvalid = false + } + } + + // Finds the FIRST json only + if (jsonvalid) { + //console.log("VALID!") + exampledata = JSON.parse(foundResult.result) + break + } else { + //console.log("INVALID: ", foundResult.result) + } + } + } + + //console.log("EXAMPLE: ", exampledata) + return exampledata + } + + const GetParamMatch = (paramname, exampledata, basekey) => { + const splitkey = "." + //console.log(typeof(exampledata)) + //console.log("MATCHING WITH: ", exampledata) + if (typeof(exampledata) !== "object") { + return "" + } + + if (exampledata === null) { + return "" + } + + // Basically just a stupid if-else :) + const synonyms = { + "id": ["id", "ref", "sourceref", "reference", "sourcereference", "alert id", "case id", "incident id", "service id", "sid", "uid", "uuid", "team id"], + "title": ["title", "name", "message"], + "description": ["description", "explanation", "story", "details",], + "email": ["mail", "email", "sender", "receiver", "recipient"], + "data": ["data", "ip", "domain", "url", "hash", "md5", "sha2", "sha256", "value", "item",], + } + + // 1. Find the right synonym + // 2. + var selectedsynonyms = [paramname] + for (const [key, value] of Object.entries(synonyms)) { + if (key === paramname || value.includes(paramname)) { + if (!value.includes(key)) { + value.push(key.toLowerCase()) + } + + selectedsynonyms = value + break + } + } + //console.log("SELECTED: ", selectedsynonyms) + + //console.log("SYNONYMS FOR ", paramname, selectedsynonyms) + var toreturn = "" + + for (const [key, value] of Object.entries(exampledata)) { + // Check if loop or JSON + const extra = basekey.length > 0 ? splitkey : "" + const basekeyname = `${basekey.slice(1, basekey.length).split(".").join(splitkey)}${extra}${key}` + + // Handle direct loop! + //if (!isNaN(key) && basekey === "") { + // //console.log("Handling direct loop: ", key, value) + // //parsedValues.push({"type": "object", "name": "Node", "autocomplete": `${basekey}`}) + // //parsedValues.push({"type": "list", "name": `${splitkey}list`, "autocomplete": `${basekey}.#`}) + // //for (var subkey in returnValues) { + // // parsedValues.push(returnValues[subkey]) + // //} + + // toreturn = GetParsedPaths(paramname, value, `${basekey}.#`) + // console.log("LIST, TORETURN: ", value, toreturn) + // if (toreturn.length > 0) { + // break + // } + //} + + //console.log("KEY: ", key, "VALUE: ", value, "BASEKEY: ", basekeyname) + if (typeof(value) === 'object') { + if (Array.isArray(value)) { + //console.log("LIST!!: ", value, key) + var selectedkey = "" + if (isNaN(key)) { + selectedkey = `.${key}` + } + + for (var subitem in value) { + toreturn = GetParamMatch(paramname, value[subitem], `${basekey}${selectedkey}.#`) + if (toreturn.length > 0) { + break + } + } + + if (toreturn.length > 0) { + break + } + } else { + var selectedkey = "" + if (isNaN(key)) { + selectedkey = `.${key}` + } + + toreturn = GetParamMatch(paramname, value, `${basekey}${selectedkey}`) + //console.log("OBJECT: ", value, toreturn, key) + if (toreturn.length > 0) { + break + } + } + //console.log("VALUE IS OBJECT: ", key, value) + } else { + //console.log("SINGLE ITEM: ", key) + if (selectedsynonyms.includes(key.toLowerCase())) { + //parsedValues.push({"type": "value", "name": basekeyname, "autocomplete": `${basekey}.${key}`, "value": value,}) + //console.log("STRING: ", key, value) + toreturn = `${basekey}.${key}` + //toreturn = basekeyname + break + } + } + } + + return toreturn + } + + // Takes an action as input, then runs through and updates the relevant fields + // based on previous actions' + const RunAutocompleter = (dstdata) => { + // **PS: The right action should already be set here** + // 1. Check execution argument + // 2. Check parents in order + var exampledata = GetExampleResult({"id": "exec", "name": "exec",}) + //console.log("EXAMPLE RETURN: ", exampledata) + var parentlabel = "exec" + for (var paramkey in dstdata.parameters) { + const param = dstdata.parameters[paramkey] + // Skip authentication params + if (param.configuration) { + continue + } + + const paramname = param.name.toLowerCase().trim().replaceAll("_", " ") + //console.log("PARAM: ", param) + //console.log("PARAMNAME: ", paramname) + + const foundresult = GetParamMatch(paramname, exampledata, "") + if (foundresult.length > 0) { + //console.log("FOUND: ", paramname, foundresult) + + if (dstdata.parameters[paramkey].value.length === 0) { + dstdata.parameters[paramkey].value = `$${parentlabel}${foundresult}` + } else { + //console.log("Skipping ", dstdata.parameters[paramkey], " because it already has a value") + } + } + } + + var parents = getParents(dstdata) + //console.log("PARENTS: ", parents) + if (parents.length > 1) { + for (var key in parents) { + const item = parents[key] + if (item.label === "Execution Argument") { + continue + } + + parentlabel = item.label.toLowerCase().trim().replaceAll(" ", "_") + exampledata = GetExampleResult(item) + for (var paramkey in dstdata.parameters) { + const param = dstdata.parameters[paramkey] + // Skip authentication params + if (param.configuration) { + continue + } + + const paramname = param.name.toLowerCase().trim().replaceAll("_", " ") + //console.log("PARAM: ", param) + //console.log("PARAMNAME: ", paramname) + + const foundresult = GetParamMatch(paramname, exampledata, "") + if (foundresult.length > 0) { + //console.log("FOUND: ", paramname, foundresult) + + if (dstdata.parameters[paramkey].value.length === 0) { + dstdata.parameters[paramkey].value = `$${parentlabel}${foundresult}` + } else { + //console.log("Skipping ", dstdata.parameters[paramkey], " because it already has a value") + } + } + } + // Check agains every param + } + } + + return dstdata + } + + //const FixNameUpdater = (sourcenode) => { + //} + // Checks for errors in edges when they're added const onEdgeAdded = (event) => { - setLastSaved(false) const edge = event.target.data() + console.log("EDGE ADDED: ", edge) + //setLastSaved(false) + var targetnode = workflow.triggers.findIndex(data => data.id === edge.target) + if (targetnode !== -1) { + console.log("TARGETNODE: ", targetnode) + if (workflow.triggers[targetnode].app_name === "User Input" || workflow.triggers[targetnode].app_name === "Shuffle Workflow") { + } else { + alert.error("Can't have triggers as target of branch") + event.target.remove() + } + } + + console.log("TARGET: ", event.target.target().data()) + if (event.target.target().data("isButton") === true || event.target.target().data("isDescriptor") === true) { + event.target.remove() + return + } + + targetnode = -1 + var sourcenode = workflow.triggers.findIndex(data => data.id === edge.source) + console.log("SOURCENODE: ", sourcenode) + if (sourcenode !== -1) { + if (workflow.triggers[sourcenode].app_name === "User Input" || workflow.triggers[sourcenode].app_name === "Shuffle Workflow") { + //console.log("NORMAL TRIGGER") + } else { + //var currentnode = cy.getElementById(workflow.triggers[sourcenode].id) + //console.log("NODE: ", currentnode) + //if (currentnode !== null && currentnode !== undefined) { + // console.log("SHOULD CHECK IF TRIGGER HAS MULTIPLE EDGES: ", currentnode) + //if (workflow.branches !== undefined && workflow.branches !== null) { + // const found_branches = workflow.branches.filter(branch => branch.source == workflow.triggers[sourcenode].id) + // console.log("FOUND BRANCHES: ", found_branches) + // if (found_branches.length > 0) { + // alert.error("Can't have multiple branches from this trigger") + // event.target.remove() + // } + //} + + //if (cy.edges().size() === 1) { + // https://js.cytoscape.org/#edges.connectedNodes + //console.log("CURRENTNODE: ", currentnode) + //console.log("EDGES: ", currentnode.connectedEdges(`node[id=${workflow.triggers[sourcenode].id}]`)) + //console.log("EDGES2: ", currentnode.connectedEdges()) + //currentnode.connectedEdges().animate({style: {lineColor: "red"}}) + //console.log("OUTGOERS: ", currentnode.outgoers()) + + //console.log("LEN2: ", currentnode.edges().length) + //if (currentnode.connectedNodes().length > 0) { + // alert.error("Can't have multiple branches from this trigger") + // event.target.remove() + //} + } + } + + //console.log(workflow.branches) // Check if: @@ -1407,7 +2349,7 @@ const AngularWorkflow = (props) => { found = true break } else if (edge.target === workflow.start) { - var targetnode = workflow.triggers.findIndex(data => data.id === edge.source) + targetnode = workflow.triggers.findIndex(data => data.id === edge.source) if (targetnode === -1) { alert.error("Can't make arrow to starting node") event.target.remove() @@ -1428,10 +2370,14 @@ const AngularWorkflow = (props) => { // break // } } else { + //console.log("INSIDE LAST CHECK: ", edge) + // Find the targetnode and check if its a trigger // FIXME - do this for both actions and other types? + /* targetnode = workflow.triggers.findIndex(data => data.id === edge.target) if (targetnode !== -1) { + console.log("TARGETNODE: ", targetnode) if (workflow.triggers[targetnode].app_name === "User Input" || workflow.triggers[targetnode].app_name === "Shuffle Workflow") { } else { alert.error("Can't have triggers as target of branch") @@ -1440,15 +2386,32 @@ const AngularWorkflow = (props) => { break } } + */ + + } } + + // 1. Guess what the next node's action should be + // 2. Get result from previous nodes (if any) + // 3. TRY to automatically map them in based on synonyms + const newsource = cy.getElementById(edge.source) + const newdst = cy.getElementById(edge.target) + if (newsource !== undefined && newsource !== null && newdst !== undefined && newdst !== null) { + //const srcdata = newsource.data() + //console.log("EDGE: ", edge) + const dstdata = RunAutocompleter(newdst.data()) + console.log("DST: ", dstdata) + } + var newbranch = { "source_id": edge.source, "destination_id": edge.target, "id_": edge.id, "id": edge.id, "hasErrors": false, + "decorator": false, } if (!found) { @@ -1457,16 +2420,29 @@ const AngularWorkflow = (props) => { workflow.branches.push(newbranch) setWorkflow(workflow) } + + history.push({ + "type": "edge", + "action": "added", + "data": edge, + }) + setHistory(history) + setHistoryIndex(history.length) } const onNodeAdded = (event) => { - setLastSaved(false) const node = event.target + const nodedata = event.target.data() + if (nodedata.finished === false || (nodedata.id !== undefined && nodedata.is_valid === undefined)) { + console.log("RETURNING (NOT ADDING) NODE ADD FOR: ", nodedata) + return + } + //console.log("IS IT ADDED TO THE WORKFLOW?: ", nodedata) if (node.isNode() && cy.nodes().size() === 1) { //setStartNode(node.data('id')) workflow.start = node.data('id') - setWorkflow(workflow) + nodedata.isStartNode = true } else { if (workflow.actions === null) { return @@ -1480,9 +2456,152 @@ const AngularWorkflow = (props) => { action.isStartNode = false } } + } + + if (nodedata.type === "ACTION") { + if (workflow.actions.length === 1 && workflow.actions[0].id === workflow.start) { + const newEdgeUuid = uuid.v4() + const newcybranch = { + "source": workflow.start, + "target": nodedata.id, + "_id": newEdgeUuid, + "id": newEdgeUuid, + "hasErrors": false, + } + + const edgeToBeAdded = { + group: "edges", + data: newcybranch, + } + + console.log("SHOULD STITCH WITH STARTNODE") + cy.add(edgeToBeAdded) + } + + if (nodedata.app_name === "Shuffle Tools") { + const iconInfo = GetIconInfo(nodedata) + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + nodedata.large_image = svgpin_Url + nodedata.fillGradient = iconInfo.fillGradient + nodedata.fillstyle = "solid" + if (nodedata.fillGradient !== undefined && nodedata.fillGradient !== null && nodedata.fillGradient.length > 0) { + nodedata.fillstyle = 'linear-gradient' + } else { + nodedata.iconBackground = iconInfo.iconBackgroundColor + } + } + + if (workflow.actions === undefined || workflow.actions === null) { + workflow.actions = [nodedata] + } else { + workflow.actions.push(nodedata) + } + + setWorkflow(workflow) + } else if (nodedata.type === "TRIGGER") { + if (workflow.triggers === undefined) { + workflow.triggers = [nodedata] + } else { + workflow.triggers.push(nodedata) + } + + const newEdgeUuid = uuid.v4() + const newcybranch = { + "source": nodedata.id, + "target": workflow.start, + "source_id": nodedata.id, + "destination_id": workflow.start, + "_id": newEdgeUuid, + "id": newEdgeUuid, + "hasErrors": false, + "decorator": false, + } + + const edgeToBeAdded = { + group: "edges", + data: newcybranch, + } + + if (nodedata.name !== "User Input" && nodedata.name !== "Shuffle Workflow") { + //workflow.branches.push(newbranch) + if (workflow.actions !== undefined && workflow.actions !== null && workflow.actions.length > 0) { + cy.add(edgeToBeAdded) + } + } + + //if (data.trigger_type === "WEBHOOK") { + // newWebhook(newAppData) + // saveWorkflow(workflow) + //} setWorkflow(workflow) } + + + if (nodedata.app_name !== undefined) { + history.push({ + "type": "node", + "action": "added", + "data": nodedata, + }) + setHistory(history) + setHistoryIndex(history.length) + } + + //if (nodedata.app_name !== undefined && (( + // nodedata.app_name !== "Shuffle Tools" && + // nodedata.app_name !== "Testing" && + // nodedata.app_name !== "Shuffle Workflow" && + // nodedata.app_name !== "User Input" && + // nodedata.app_name !== "Webhook" && + // nodedata.app_name !== "Schedule" && + // nodedata.app_name !== "Email") || nodedata.isStartNode) + //) { + // const allNodes = cy.nodes().jsons() + // var found = false + // for (var key in allNodes) { + // const currentNode = allNodes[key] + // if (currentNode.data.attachedTo === nodedata.id && currentNode.data.isDescriptor) { + // found = true + // console.log("FOUND THE NODE!") + // break + // } + // } + + // // Readding the icon after moving the node + // if (!found) { + // console.log("Node wasn't found") + // const iconInfo = GetIconInfo(nodedata) + // const svg_pin = `` + // const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + + // const offset = nodedata.isStartNode ? 36 : 44 + // const decoratorNode = { + // position: { + // x: event.target.position().x+offset, + // y: event.target.position().y+offset, + // }, + // locked: true, + // data: { + // "isDescriptor": true, + // "isValid": true, + // "is_valid": true, + // "label": "", + // "image": svgpin_Url, + // "imageColor": iconInfo.iconBackgroundColor, + // "attachedTo": nodedata.id, + // }, + // } + + // cy.add(decoratorNode) + // } else { + // console.log("Node already exists - don't add descriptor node") + // } + //} else { + // //console.log("Shouldnt re-add info? ") + //} + } const onEdgeRemoved = (event) => { @@ -1491,6 +2610,7 @@ const AngularWorkflow = (props) => { workflow.branches = workflow.branches.filter(a => a.id !== edge.data().id) setWorkflow(workflow) + event.target.remove() // trigger as source check const indexcheck = workflow.triggers.findIndex(data => edge.data()["source"] === data.id) @@ -1502,33 +2622,80 @@ const AngularWorkflow = (props) => { // data: newcybranch, //} } + + if (edge.data().source !== undefined) { + history.push({ + "type": "edge", + "action": "removed", + "data": edge.data().source, + }) + setHistory(history) + setHistoryIndex(history.length) + } } const onNodeRemoved = (event) => { const node = event.target const data = node.data() - setLastSaved(false) - //var currentnode = cy.getElementById(data.id) - //if (currentnode.length === 0) { - //} - if (workflow.start === data.id && workflow.actions.length > 1) { - // FIXME - should check branches connected to startnode, as picking random - // might just be confusing - cy.nodes().some(function( ele ) { - if (ele.id() !== workflow.start && ele.data()["label"] !== undefined) { - //alert.success("Changed startnode to "+ele.data()["label"]) - ele.data("isStartNode", true) - workflow.start = ele.id() - //throw BreakException - return false - } - }) + if (data.finished === false) { + return } + //setLastSaved(false) workflow.actions = workflow.actions.filter(a => a.id !== data.id) workflow.triggers = workflow.triggers.filter(a => a.id !== data.id) + if (workflow.start === data.id && workflow.actions.length > 0) { + // FIXME - should check branches connected to startnode, as picking random + // is just confusing + if (workflow.actions[0].id !== data.id) { + const ele = cy.getElementById(workflow.actions[0].id) + if (ele !== undefined && ele !== null) { + ele.data("isStartNode", true) + workflow.start = ele.id() + } + } else { + if (workflow.actions.length > 1) { + const ele = cy.getElementById(workflow.actions[1].id) + if (ele !== undefined && ele !== null) { + ele.data("isStartNode", true) + workflow.start = ele.id() + } + } + } + + //cy.nodes().some(function( ele ) { + // if (ele.id() !== workflow.start && ele.data()["label"] !== undefined) { + // //alert.success("Changed startnode to "+ele.data()["label"]) + // ele.data("isStartNode", true) + // workflow.start = ele.id() + // throw BreakException + // return false + // } + //}) + } + + if (data.app_name !== undefined) { + //console.log("Trying to remove friendly nodes") + const allNodes = cy.nodes().jsons() + //console.log("NOT UNDEFINED IN HOVEROUT!", allNodes) + for (var key in allNodes) { + const currentNode = allNodes[key] + if (currentNode.data.attachedTo === data.id) { + cy.getElementById(currentNode.data.id).remove() + } + } + + history.push({ + "type": "node", + "action": "removed", + "data": data, + }) + setHistory(history) + setHistoryIndex(history.length) + } + setWorkflow(workflow) if (data.type === "TRIGGER") { @@ -1544,6 +2711,9 @@ const AngularWorkflow = (props) => { switch( event.keyCode ) { case 27: console.log("ESCAPE") + if (configureWorkflowModalOpen === true) { + setConfigureWorkflowModalOpen(false) + } break; case 46: //removeNode() @@ -1551,42 +2721,60 @@ const AngularWorkflow = (props) => { break; case 38: console.log("UP") - break; + break; case 37: console.log("LEFT") - break; + break; case 40: console.log("DOWN") - break; + break; case 39: console.log("RIGHT") - break; + break; case 90: if (previouskey === 17) { console.log("CTRL+Z") + //handleHistoryUndo() } - break; + + break; case 67: if (previouskey === 17) { console.log("CTRL+C") + const filteredelements = cy.filter(function(element, i){ + return element.hasClass('selected') + }) + + for (var key in filteredelements) { + } + + var copyText = document.getElementById("copy_element_shuffle") + if (copyText !== undefined && copyText !== null) { + const clipboard = navigator.clipboard + if (clipboard === undefined) { + alert.error("Can only copy over HTTPS (port 3443)") + return + } + } + console.log("FILTERED: ", filteredelements) } - break; + break; case 86: if (previouskey === 17) { console.log("CTRL+V") } - break; + break; case 88: if (previouskey === 17) { console.log("CTRL+V") } - break; + break; case 83: if (previouskey === 17) { event.preventDefault() saveWorkflow() } - break; + break; case 70: //if (previouskey === 17) { // event.preventDefault() @@ -1690,7 +2878,7 @@ const AngularWorkflow = (props) => { useEffect(() => { if (firstrequest) { setFirstrequest(false) - getWorkflow() + getWorkflow(props.match.params.key, {}) getApps() getAppAuthentication() getEnvironments() @@ -1726,19 +2914,48 @@ const AngularWorkflow = (props) => { //console.log("IN ESTABLISHED!") setEstablished(true) + // Validate if the node is just a node lol + console.log("CY: ", cy) + //console.log("CY: ", cy.edgehandles()) + //try { cy.edgehandles({ - handleNodes: (el) => el.isNode(), + handleNodes: (el) => el.isNode() && !el.data("isButton") && !el.data("isDescriptor"), preview: false, toggleOffOnLeave: false, loopAllowed: function( node ){ return false; }, }) + //} catch (e) { + // console.log("Error in edgehandles: ", e) + //} cy.fit(null, 200) - cy.on('select', 'node', (e) => onNodeSelect(e, appAuthentication)) + cy.on('boxselect', 'node', (e) => { + if (e.target.data("isButton") || e.target.data("isDescriptor")) { + e.target.unselect() + } + + e.target.addClass("selected") + }) + + cy.on('boxstart', (e) => { + console.log("START") + cy.removeListener('select') + //onNodeSelect(e, appAuthentication) + }) + cy.on('boxend', (e) => { + console.log("END") + cy.removeListener('select') + //onNodeSelect(e, appAuthentication) + }) + + cy.on('select', 'node', (e) => { + onNodeSelect(e, appAuthentication) + }) cy.on('select', 'edge', (e) => onEdgeSelect(e)) + cy.on('unselect', (e) => onUnselect(e)) cy.on('add', 'node', (e) => onNodeAdded(e)) @@ -1752,7 +2969,46 @@ const AngularWorkflow = (props) => { cy.on('mouseout', 'node', (e) => onNodeHoverOut(e)) // Handles dragging - cy.on('drag', 'node', (e) => onNodeDrag(e)) + cy.on('drag', 'node', (e) => onNodeDrag(e, selectedAction)) + cy.on('free', 'node', (e) => onNodeDragStop(e, selectedAction)) + + cy.on('cxttap', "node", (e) => onCtxTap(e)) + + //let popper2 = cy.popper({ + // content: () => { + // let div = document.createElement('div'); + // + // div.innerHTML = 'Popper content' + // + // document.body.appendChild(div) + // + // return div + // }, + // renderedPosition: () => ({ x: 100, y: 200 }), + // popper: {} // my popper options here + //}); + + //let popper1 = cy.nodes()[0].popper({ + // content: () => { + // let div = document.createElement('div') + // + // div.innerHTML = 'Popper content' + // document.body.appendChild(div) + // + // return div + // }, + // popper: {} // my popper options here + //}) + //let update = () => { + // popper.update() + //} + + //let node = cy.nodes().first() + //node.on('position', update) + + + + //cy.on('mouseover', 'node', () => $(targetElement).addClass('mouseover')); @@ -1761,8 +3017,6 @@ const AngularWorkflow = (props) => { //cy.on('cxtdragover', 'node', (e) => edgeHandler.preview(e.target)) //cy.on('cxtdragout', 'node', (e) => edgeHandler.unpreview(e.target)) - // RIGHT HERE..? - // This is wrong sometimes.. I'm mad document.title = "Workflow - "+workflow.name registerKeys() //setStartNode(workflow.start) @@ -1772,25 +3026,165 @@ const AngularWorkflow = (props) => { } }) + //}, [selectedAction]) + var previousnodecolor = "" //var previousedgecolor = "" const animationDuration = 150 const onNodeHoverOut = (event) => { - event.target.animate({ - style: { - "border-width": "1px", + const nodedata = event.target.data() + if (nodedata.app_name !== undefined) { + const allNodes = cy.nodes().jsons() + for (var key in allNodes) { + const currentNode = allNodes[key] + if (currentNode.data.isButton && currentNode.data.attachedTo !== nodedata.id) { + cy.getElementById(currentNode.data.id).remove() + } } + } + + var parsedStyle = { + "border-width": "1px", + 'font-size': '18px', + } + + if ((nodedata.app_name === "Testing" || nodedata.app_name === "Shuffle Tools") && !nodedata.isStartNode) { + parsedStyle = { + "border-width": "1px", + 'font-size': '0px', + } + } + + event.target.animate({ + style: parsedStyle, }, { duration: animationDuration, }) } + const buttonColor = "rgba(255,255,255,0.9)" + const buttonBackgroundColor = "#1f2023" + const addCopyButton = (event) => { + var parentNode = cy.$('#' + event.target.data("id")); + if (parentNode.data('isButton') || parentNode.data('buttonId')) + return + + //parentNode.lock() + const px = parentNode.position('x') - 65 + const py = parentNode.position('y') - 25 + const circleId = newNodeId = uuid.v4() + + parentNode.data('circleId', circleId) + + const iconInfo = { + "icon": "M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z", + "iconColor": buttonColor, + "iconBackgroundColor": buttonBackgroundColor, + } + + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + + cy.add({ + group: 'nodes', + data: { + weight: 30, + id: circleId, + name: "TEEEXT", + isButton: true, + buttonType: "copy", + attachedTo: event.target.data("id"), + icon: svgpin_Url, + iconBackground: iconInfo.iconBackgroundColor, + is_valid: true, + }, + position: { x: px, y: py }, + locked: true + }) + //.unselectify() + } + + const addDeleteButton = (event) => { + var parentNode = cy.$('#' + event.target.data("id")); + if (parentNode.data('isButton') || parentNode.data('buttonId')) + return + + //parentNode.lock() + const px = parentNode.position('x') - 65 + const py = parentNode.position('y') + 25 + const circleId = newNodeId = uuid.v4() + + parentNode.data('circleId', circleId) + + const iconInfo = { + "icon": "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z", + "iconColor": buttonColor, + "iconBackgroundColor": buttonBackgroundColor, + } + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + + cy.add({ + group: 'nodes', + data: { + weight: 30, + id: circleId, + name: "TEEEXT", + isButton: true, + buttonType: "delete", + attachedTo: event.target.data("id"), + icon: svgpin_Url, + iconBackground: iconInfo.iconBackgroundColor, + is_valid: true, + }, + position: { x: px, y: py }, + locked: true + }) + //.unselectify() + } + const onNodeHover = (event) => { - event.target.animate({ - style: { - "border-width": "7px", - "border-opacity": ".7", + //console.log("TAR: ", event.target) + const nodedata = event.target.data() + if (nodedata.finished === false) { + return + } + + var parentNode = cy.$('#' + event.target.data("id")); + if (parentNode.data('isButton') || parentNode.data('buttonId')) + return + + if (nodedata.app_name !== undefined) { + const allNodes = cy.nodes().jsons() + + var found = false + for (var key in allNodes) { + const currentNode = allNodes[key] + if (currentNode.data.isButton && currentNode.data.attachedTo !== nodedata.id) { + cy.getElementById(currentNode.data.id).remove() + } + + if (currentNode.data.isButton && currentNode.data.attachedTo === nodedata.id) { + found = true + } } + + if (!found) { + addDeleteButton(event) + addCopyButton(event) + } + } + + + const parsedStyle = { + "border-width": "7px", + "border-opacity": ".7", + 'font-size': '25px', + 'color': 'white', + } + + event.target.animate({ + style: parsedStyle }, { duration: animationDuration, }) @@ -1799,6 +3193,16 @@ const AngularWorkflow = (props) => { } const onEdgeHoverOut = (event) => { + if (event === null || event === undefined) { + event.target.removeStyle() + return + } + + const edgeData = event.target.data() + if (edgeData.decorator === true) { + return + } + event.target.removeStyle() } @@ -1808,13 +3212,18 @@ const AngularWorkflow = (props) => { return } + const edgeData = event.target.data() + if (edgeData.decorator === true) { + return + } + const sourcecolor = cy.getElementById(event.target.data("source")).style("border-color") const targetcolor = cy.getElementById(event.target.data("target")).style("border-color") if (sourcecolor !== null && sourcecolor !== undefined && targetcolor !== null && targetcolor !== undefined) { event.target.animate({ style: { - "line-fill": "linear-gradient", 'target-arrow-color': targetcolor, + "line-fill": "linear-gradient", "line-gradient-stop-colors": [sourcecolor, targetcolor], "line-gradient-stop-positions": [0, 1], }, @@ -1823,10 +3232,28 @@ const AngularWorkflow = (props) => { } } - const setupGraph = () => { const actions = workflow.actions.map(action => { const node = {} + + if (!action.isStartNode && action.app_name === "Shuffle Tools") { + const iconInfo = GetIconInfo(action) + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + action.large_image = svgpin_Url + action.fillGradient = iconInfo.fillGradient + action.fillstyle = "solid" + if (action.fillGradient !== undefined && action.fillGradient !== null && action.fillGradient.length > 0) { + action.fillstyle = 'linear-gradient' + //console.log("GRADIENT!: ", action) + //action.fillstyle = + //'background-fill': 'data(fillstyle)', + } else { + action.iconBackground = iconInfo.iconBackgroundColor + } + //console.log("FOUND NODE INFO: ", action) + } + node.position = action.position node.data = action @@ -1842,11 +3269,43 @@ const AngularWorkflow = (props) => { node.data.example = example - //node.data.is_valid = false - return node; }) + const decoratorNodes = workflow.actions.map(action => { + if (!action.isStartNode) { + if (action.app_name === "Testing") { + return null + } else if (action.app_name === "Shuffle Tools") { + return null + } + } + + const iconInfo = GetIconInfo(action) + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + + const offset = action.isStartNode ? 36 : 44 + const decoratorNode = { + position: { + x: action.position.x+offset, + y: action.position.y+offset, + }, + locked: true, + data: { + "isDescriptor": true, + "isValid": true, + "is_valid": true, + "label": "", + "image": svgpin_Url, + "imageColor": iconInfo.iconBackgroundColor, + "attachedTo": action.id, + }, + } + return decoratorNode + return null + }) + const triggers = workflow.triggers.map(trigger => { const node = {} node.position = trigger.position @@ -1859,8 +3318,10 @@ const AngularWorkflow = (props) => { }) // FIXME - tmp branch update - var insertedNodes = [].concat(actions, triggers) - const edges = workflow.branches.map((branch, index) => { + var insertedNodes = [].concat(actions, triggers, decoratorNodes) + insertedNodes = insertedNodes.filter(node => node !== null) + + var edges = workflow.branches.map((branch, index) => { //workflow.branches[index].conditions = [{ const edge = { }; @@ -1883,8 +3344,9 @@ const AngularWorkflow = (props) => { target: branch.destination_id, label: label, conditions: conditions, - hasErrors: branch.has_errors - }; + hasErrors: branch.has_errors, + decorator: false, + } // This is an attempt at prettier edges. The numbers are weird to work with. /* @@ -1913,12 +3375,44 @@ const AngularWorkflow = (props) => { return edge; }) + if (workflow.visual_branches !== undefined && workflow.visual_branches !== null && workflow.visual_branches.length > 0) { + const visualedges = workflow.visual_branches.map((branch, index) => { + const edge = { }; + + if (workflow.branches[index] === undefined) { + return {} + } + + var conditions = workflow.branches[index].conditions + if (conditions === undefined || conditions === null) { + conditions = [] + } + + const label = "Subflow" + edge.data = { + id: branch.id, + _id: branch.id, + source: branch.source_id, + target: branch.destination_id, + label: label, + decorator: true, + } + + return edge; + }) + + edges = edges.concat(visualedges) + } + setWorkflow(workflow) // Verifies if a branch is valid and skips others var newedges = [] for (var key in edges) { var item = edges[key] + if (item.data === undefined) { + continue + } const sourcecheck = insertedNodes.find(data => data.data.id === item.data.source) const destcheck = insertedNodes.find(data => data.data.id === item.data.target) @@ -1960,7 +3454,12 @@ const AngularWorkflow = (props) => { } - selectedNode.remove() + if (selectedNode.data().decorator === true) { + alert.info("This edge can't be deleted.") + } else { + selectedNode.remove() + } + setSelectedTrigger({}) setSelectedTriggerIndex({}) } @@ -1985,7 +3484,9 @@ const AngularWorkflow = (props) => { .then((responseJson) => { // No matter what, it's being stopped. if (!responseJson.success) { - alert.WARNING("Failed to stop schedule: " + responseJson.reason) + if (responseJson.reason !== undefined) { + alert.error("Failed to stop schedule: " + responseJson.reason) + } } else { alert.success("Successfully stopped schedule") } @@ -2067,7 +3568,7 @@ const AngularWorkflow = (props) => { const paperAppStyle = { - borderRadius: borderRadius, + borderRadius: theme.palette.borderRadius, minHeight: 100, maxHeight: 100, minWidth: "100%", @@ -2080,7 +3581,7 @@ const AngularWorkflow = (props) => { } const paperVariableStyle = { - borderRadius: borderRadius, + borderRadius: theme.palette.borderRadius, minHeight: 50, maxHeight: 50, minWidth: "100%", @@ -2102,6 +3603,7 @@ const AngularWorkflow = (props) => { } const deleteVariable = (variableName) => { + console.log("Delete:" ,variableName) workflow.workflow_variables = workflow.workflow_variables.filter(data => data.name !== variableName) setWorkflow(workflow) } @@ -2125,9 +3627,9 @@ const AngularWorkflow = (props) => {
What are WORKFLOW variables? {workflow.workflow_variables === null ? - null : workflow.workflow_variables.map(variable=> { + null : workflow.workflow_variables.map((variable, index) => { return ( -
+
{ }}>
@@ -2163,7 +3665,7 @@ const AngularWorkflow = (props) => { setOpen(false) setAnchorEl(null) }} - > + > { setOpen(false) @@ -2390,7 +3892,7 @@ const AngularWorkflow = (props) => { "description": "Add your email provider", "trigger_type": "EMAIL", "errors": null, - "is_valid": (cloudSyncEnabled && !isCloud) ? true : false, + "is_valid": cloudSyncEnabled || isCloud ? true : false, "label": "Email", "environment": "cloud", "large_image": 'data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/hAytodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Nzg4QTJBMjVEMDI1MTFFN0EwQUVDODc5QjYyQkFCMUQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6Nzg4QTJBMjZEMDI1MTFFN0EwQUVDODc5QjYyQkFCMUQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3ODhBMkEyM0QwMjUxMUU3QTBBRUM4NzlCNjJCQUIxRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3ODhBMkEyNEQwMjUxMUU3QTBBRUM4NzlCNjJCQUIxRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/bAEMAAwICAgICAwICAgMDAwMEBgQEBAQECAYGBQYJCAoKCQgJCQoMDwwKCw4LCQkNEQ0ODxAQERAKDBITEhATDxAQEP/AAAsIAGQAZAEBEQD/xAAeAAABAwUBAQAAAAAAAAAAAAAAAQgJAgQFBwoGA//EAEoQAAECBAMEBwMDEQgDAAAAAAECAwAEBREGBxIIITFRCRMiMkFSYRRicSNCQxUWGBk2U1dYc3WBlJWzwdLTJDNjZXKDkeEmgqH/2gAIAQEAAD8Ak8JKipSlBwuDSpSeDw8qeRguQQrUAQNAV4JH3s+sA7OnT8n1fcv9Bfzc7wWAAToIAOsJ8Uq++H0gI1XSUlYWdSkji6fMnkBAdS9SidesWUpI3OjyjkYXtXCgbEDSFW3JT5D6+sIOzp0/J9X3NX0F/NzvBYABOggA6wnxSr74fSAjVdJSVhZ1KSOLp8yeQEBJUSVKCysaVKHB0eVPIwXIIVqAIGgK8Ej72fWFS640kNtzjcukcGli6k/GENwVagAQO0EcEjmj1g33AATe1wD3SnmffgG/Tp337mv535T+EaB2k9tzInZilVyuMq+up4iUjWxh+mFLs8s23dbv0stnmsgnwBiNPOHpddozHExMSmWsrSsA0tZIaMs0JudCfV50FKf/AFQPjDYsT7S+0LjJ8zGJc68aTqiSrSqtPoQD6ISoJH6BGFkM5c3qW8Jim5qYvlXArUFNVuZSb89y43Tlv0ju15ltMtKZzUmsRSbZGuSxC0mebcHIrV8r/wALEP02c+l2ywzAmZXDGeND+saqvEIRVWXFP0x1Z3AOE9thPx1JHioQ/un1Kn1eQZqtLn2ZuSmkJdamZVwOIWlQuktKTuUg8xFybgnUACB2gjgkc0e9BvuAAm9rgHulPM+/CpDik3bal1p8FPd8/GEtp7Ojq+r36OPUe96wWv2dF79vR5/8T/qI/ukM6RMZMGcyWyUqDMzjZ5vRWKwmy26UlQ3IQOBmLHx3IFibncIeqvWKtiCqTVbrtSmahUJ11T0zNTLqnHXnFG5UpSiSSeZi0ggggh2GxRt8Y92X69K4cr83N1zLuadCZumLXrcp4Ue0/KXPZPiW+6r0O+JxsF4zwvmFhSl42wXV5eo0Sqy6ZySmWFakJbUO/wDHiCk7wQQd4jN2v2dF79vR5v8AE/6g6rrflPYfar/S69Or9EIAAE6QoAHshfFJ5r9Ibpt3bTrOzBkbPYhpb7f11V5aqZh9le8iZUm65i3i20ntcirQPGIA6nU6jWqlNVirzr05PTzy5iZmHllTjrqyVKWoneSSSSYtoIIIIIIkI6J/axmsA4+Rs84yqZ+tvFb5VQ1vL7EjVCNyN/Bt4C1vOEn5xiYndYghVr3IHeKuY9yKVJbJu63MrV4qY7h+EVA6rEKKwvclSuLp8quQiDnpWM5ZnMrafn8HS04pykZfy6KMw2D2BNEByZUPXWQj/aEM0h3uwvk5PYmoeLM4HcnqHmth/CU1KytdwrNy5M+uUdQtZmZBYIu83oN2z3wbcbWk7ym2Zej6zuwXJ49y5yXwbUqXNgpUPZlpelnh32XmyrU24k7ik7/0WMey+wI2OPxesJfqyv5oPsCNjj8XrCX6sr+aD7AjY4/F6wl+rq/mhs2b2SGzXjPGc3s9bKuzngiq4zZGjEWJ3pRTlKwkyrcVOKCrOzVr6GRex73AiIe65TvqRWqhSet632Kadl9enTq0LKb28L24R86ZUp6jVKUrFMmVy85IvtzMu8g2U24hQUlQPMEAx0h7O+abGdWR+DM0mnAF16lMuzRTxamgNDzQHIOJWI2IpxDZ0Lm3ZdQ4tti6U/CEdeDaHJhxYWAklahwdAF9KeRjmXzRxJMYxzLxXiyacUt2sVqdnlFRuflHlq/jHmIlv6D37is1T/mlM/cvQ5zNnZ7xtl/jWc2htlFUtIYrfs7iXCLy+rpeLGk7zcDczN2vpdFrnvcSTsrIPaHwNtBYcmKlhsv02t0h4ydfw7UE9XUKPOJJC2Xmzv3KBAWNyrbvEDaDjjbTa3XVpQhAKlKUbBIHEk+ENLxdnDj/AGr8T1LJ7Zgra6NgymPmSxhmU0LhB+kkaV4OPkGynu6gG4PAlwGUuT2AMjsDy2BMuqGin06XBcdWTrfm3j3333D2nHFHeVH/AOCwjmnxr92Ve/Oc1+9VGGibDogMVP1vZWmKI+4b4dxJOybS1G4S06ht7QPipxf/ADD4kurbGhE21LpHBtwXUn4xbVNpb9OnGAAFrl3EkI4JukgFHrHMFWpdyUrE/KvAhxmZdbUDxBCyDFnEuHQej/wjNU/5rTP3L0PQ2hs1cR4f+pOUWU/VTGZeOtbFK1jW3SZNO6YqkwPBtlJ7IPfcKUi++NdYh2H5LB1CoWLtnXFD2Fs1sLS6rV+ZUXG8SqWouPtVVP0yXnCo6+8gqFtwAGAbkdpzbFcTgXNLB1Qyay9pBEri1iXm9VQxPNo/vJeVdT/dyJ3XcG9YNgTvt6TFODKZsY4nlc2MsaEmRypn25em45oMi2eqpiUANsVllA8gsiYtvUiyzcpJhz8rOylSkGqjITTUzKzTKXmHmlhSHG1C6VJI3EEEEGOXnGv3ZV785zX71UYaJjehfk3mdn/GM4oHRM4sWEBfcsiUZ1Eeu+JBUhxSbttS60+Cnu+fjCAaDbR1fV9rRx6n3vW8c5+2Bl1MZV7TGYmDXmlIaZrkxNyhIsFy0wrr2lD00OJjT0SfdE5mphvJnIrOXHmJutdalatSmZSSlxqmKhNuNOpYlWU8VOOLISAOdzuBiQLZ5yrxJQTVs382Q0/mVjrQ9VAk6m6RJp3y9Llz4NtA9ojvuFSjfdG54N8fGekZOpyUxTajKtTMrNNLYfYdSFIdbULKSpJ3EEEgiG4ZXz07s0Zis7OuJpp1zAmJFvP5cVSYWSJVYut2hurPzkC62Ce83dHFFogGxr92Ve/Oc1+9VGGiezo0MupnLzY/wezPy5bm8RqmMROsqFiUvr+SWf8AaQ2besOl6rrflPYfar/S69Or9EIAAE6QoAHshfFJ5r9Ii76Y7Z4mJgUHaSw7IqWhlCKHiLQN6RcmWmP9Nypsn8mIizj3GWGdOY2T9Xka1gSuJlH6bO/VKWbflm5hlubDam0v9U4lSC4lClBKiLp1G1iY3v8AbSdtr8LTP7Ekf6UL9tJ22vwss/sOR/pQfbSdtr8LLP7Dkf6UH20nba/C0z+w5H+lHmMxOkB2qc1MOKwrjjMNmfkPaGZxrTSZRl1iYZWFtPNOobC21pULhSSDx8DDe5uamJ6aenZt1Tr8w4p11auKlqNyT8SY2ZszZH1raIzqw1ldSG1hqozSXKlMAHTKyLZCn3VHwsi4HvKSPGOjSj0im0CjyVBpMqJen06XalZZhG7Q22kJQE+4AAIulJbJu63MrV4qY7h+EVA6rEKKwvclSuLp8quQjB45wVhrMbB9YwNjGnIn6JW5VyQnWVjihYtoTysbEKHAgGOf7a72U8abKeZszhStMOzVAnVreoNXCfk5uXvuSojcHUAgLTz3jcRGi4IIIIIuqVSqnXKnK0ajSD89PzzyJeWlpdsrcecUbJQlI3kkkAAROd0eGxqjZiy7XiLF8sy5j/FjaFVEiyhJMDeiSB9D2lkbiqw4JEO58CrUQAdJV4pPkHu+sIpxDZ0Lm3ZdQ4tti6U/CFJKiVKUFle5Sk8HR5U8jBcghWoAgaArwSPIfe9Y8PnJkvl1nzgScy7zMoDVQpMyLtlXZekHfmvNucULHgR8DcEiIZtqro1s58gZucxFg6QmsbYJQVOonpFkqnJNrw9pYTcgAfSJuk8Tp4Qz9SSklKgQQbEHwgggjYeTOz9m7n/iFGHMq8Fz1YdCgJiZSjRKSiT8955XYQB6m58AYmN2LejtwJsyoYxri52XxVmC43unA3/ZpAEb0ygVvv4F09ojgEgm7wSSq5Kgsr3KUODo8qeRguQQrUAQNAV4JHkPvesKl1bY0Im2pdI4NuC6k/GENwVagAQO0EcEjmj1g33AATe1wD3SnmffgG/Tp337mv535T+EG4i4KiCbAnvE8j7kaHzf2Hdl/O1+YqONcraexU3jd6p0i8jNFfPU1ZLnxWlUNjxL0LOTs6+tzC+bWLKSkHUWpmXl5xKR4BJAbJjD0/oTcEoeH1Uz5rbzfe0sUZlolH+pTigFelo3Nlr0UuyZgSYZn6vQ6zjKaQQpr6uz3yBI462WQhNvRVxDscMYVwvgujMYfwfh+n0Wly/ZZlJCVQw2k8tCABp9YypsL6iQAe0U8Unkj3YDcE6gAQO0EcEjmj3oN9wAE3tcA90p5n34VIcUm7bUutPgp7vn4wOpS05MNtiyZdAW0PKo+MASkuIbIulbPXKHNfOEa+V9m6zf7Vq633rcIpSoqbQ6T2lvdQo80coVxRbRMLRuVLuBts+VJ4iKnEhtb6ECwl0BxseVR8YAlJcQ2RdK2euUOa+cI18r7N1m/wBq1db71uEUpUVNodJ7S3uoUeaOUK4otomFo3Kl3A22fKk8RFTiQ2t9CBYS6A42PKo+MASkuIbIulbPXKHNfOPtKSkvNy6JiYaC3F71KJO+P//Z', @@ -2421,7 +3923,9 @@ const AngularWorkflow = (props) => { {handleTriggerDrag(e, trigger)}} - onStop={(e) => {handleDragStop(e)}} + onStop={(e) => { + handleDragStop(e) + }} dragging={false} position={{ x: 0, @@ -2456,6 +3960,7 @@ const AngularWorkflow = (props) => { } var newNodeId = "" + var parsedApp = {} const handleTriggerDrag = (e, data) => { const cycontainer = cy.container() // Chrome lol @@ -2470,14 +3975,13 @@ const AngularWorkflow = (props) => { currentnode[0].renderedPosition("x", e.pageX-cycontainer.offsetLeft) currentnode[0].renderedPosition("y", e.pageY-cycontainer.offsetTop) } else{ - console.log(workflow) if (workflow.start === "" || workflow.start === undefined) { alert.error("Define a starting action first.") return } if (data.is_valid === false) { - alert.error(data.name+" trigger isn't available yet") + alert.error(data.name+" requires hybrid version of Shuffle") return } @@ -2489,7 +3993,6 @@ const AngularWorkflow = (props) => { "y": e.pageY-cycontainer.offsetTop, } - console.log(data) const newAppData = { app_name: data.name, app_version: "1.0.0", @@ -2500,6 +4003,7 @@ const AngularWorkflow = (props) => { id_: newNodeId, _id_: newNodeId, id: newNodeId, + finished: false, label: triggerLabel, type: data.type, is_valid: true, @@ -2523,63 +4027,128 @@ const AngularWorkflow = (props) => { } cy.add(nodeToBeAdded) - - if (workflow.triggers === undefined) { - workflow.triggers = [newAppData] - } else { - workflow.triggers.push(newAppData) - } - - const newEdgeUuid = uuid.v4() - const newbranch = { - "source_id": newNodeId, - "destination_id": workflow.start, - "id_": newEdgeUuid, - "id": newEdgeUuid, - "hasErrors": false, - } - - const newcybranch = { - "source": newNodeId, - "target": workflow.start, - "_id": newEdgeUuid, - "id": newEdgeUuid, - "hasErrors": false, - } - - const edgeToBeAdded = { - group: "edges", - data: newcybranch, - } - - if (data.name !== "User Input" && data.name !== "Shuffle Workflow") { - //workflow.branches.push(newbranch) - cy.add(edgeToBeAdded) - } - - setWorkflow(workflow) - //if (data.trigger_type === "WEBHOOK") { - // newWebhook(newAppData) - // saveWorkflow(workflow) - //} + parsedApp = nodeToBeAdded + return } } } + const handleDragStop = (e, app) => { + //console.log("STOP!: ", e) + //console.log("APP!: ", parsedApp) + //const onNodeAdded = (event) => { + //const node = event.target + //const nodedata = event.target.data() + var currentnode = cy.getElementById(newNodeId) + if (currentnode === undefined || currentnode === null || currentnode.length === 0) { + return + } + + // Using remove & replace, as this triggers the function + // onNodeAdded() with this node after it's added + + currentnode.remove() + parsedApp.data.finished = true + parsedApp.data.position = currentnode.renderedPosition() + parsedApp.position = currentnode.renderedPosition() + parsedApp.renderedPosition = currentnode.renderedPosition() + + var newAppData = parsedApp.data + if (newAppData.type === "ACTION") { + // AUTHENTICATION + if (app.authentication.required) { + // Setup auth here :) + const authenticationOptions = [] + var findAuthId = "" + if (newAppData.authentication_id !== null && newAppData.authentication_id !== undefined && newAppData.authentication_id.length > 0) { + findAuthId = newAppData.authentication_id + } + + var tmpAuth = JSON.parse(JSON.stringify(appAuthentication)) + for (var key in tmpAuth) { + var item = tmpAuth[key] + + const newfields = {} + for (var filterkey in item.fields) { + newfields[item.fields[filterkey].key] = item.fields[filterkey].value + } + + item.fields = newfields + if (item.app.name === app.name) { + authenticationOptions.push(item) + if (item.id === findAuthId) { + newAppData.selectedAuthentication = item + } + } + } + + if (authenticationOptions !== undefined && authenticationOptions !== null && authenticationOptions.length > 0) { + for (var key in authenticationOptions) { + const option = authenticationOptions[key] + if (option.active) { + newAppData.selectedAuthentication = option + newAppData.authentication_id = option.id + break + } + } + } + + //newAppData.authentication = authenticationOptions + //if (newAppData.selectedAuthentication === null || newAppData.selectedAuthentication === undefined || newAppData.selectedAuthentication.length === "") { + // newAppData.selectedAuthentication = {} + //} else { + // console.log("CAN WE SELECT AUTH?: ", authenticationOptions) + //} + // + // + + //console.log(parsedApp) + } else { + newAppData.authentication = [] + newAppData.authentication_id = "" + newAppData.selectedAuthentication = {} + } + + parsedApp.data = newAppData + cy.add(parsedApp) + } else if (newAppData.type === "TRIGGER") { + cy.add(parsedApp) + + } + + newNodeId = "" + parsedApp = {} + } + + const appScrollStyle = { + overflow: "scroll", + maxHeight: bodyHeight-appBarSize-55-50, + minHeight: bodyHeight-appBarSize-55-50, + marginTop: 1, + overflowY: "auto", + overflowX: "hidden", + } + const handleAppDrag = (e, app) => { const cycontainer = cy.container() + // Chrome lol //if (e.srcElement !== undefined && e.srcElement.localName === "canvas") { if (e.pageX > cycontainer.offsetLeft && e.pageX < cycontainer.offsetLeft+cycontainer.offsetWidth && e.pageY > cycontainer.offsetTop && e.pageY < cycontainer.offsetTop+cycontainer.offsetHeight) { if (newNodeId.length > 0) { var currentnode = cy.getElementById(newNodeId) - if (currentnode.length === 0) { + if (currentnode === undefined || currentnode === null || currentnode.length === 0) { return } currentnode[0].renderedPosition("x", e.pageX-cycontainer.offsetLeft) currentnode[0].renderedPosition("y", e.pageY-cycontainer.offsetTop) - } else{ + } else { + if (workflow.public) { + console.log("workflow is public - not adding") + return + } + if (app.actions === undefined || app.actions === null || app.actions.length === 0) { alert.error("App "+app.name+" currently has no actions to perform. Please go to https://shuffler.io/apps to edit it.") return @@ -2598,23 +4167,14 @@ const AngularWorkflow = (props) => { example = app.actions[0].returns.example } - var newAppPopup = false - - /* - FIXME: Add auth. - selectedAction.selectedAuthentication = e.target.value - selectedAction.authentication_id = e.target.value.id - setSelectedAction(selectedAction) - setUpdate(Math.random()) - */ - + const parsedEnvironments = environments === null || environments === [] ? "cloud" : environments[defaultEnvironmentIndex] === undefined ? "cloud" : environments[defaultEnvironmentIndex].Name const newAppData = { app_name: app.name, app_version: app.app_version, app_id: app.id, sharing: app.sharing, private_id: app.private_id, - environment: environments === null ? "cloud" : environments[defaultEnvironmentIndex].Name, + environment: parsedEnvironments, errors: [], id_: newNodeId, _id_: newNodeId, @@ -2631,146 +4191,35 @@ const AngularWorkflow = (props) => { example: example, category: app.categories !== null && app.categories !== undefined && app.categories.length > 0 ? app.categories[0] : "", authentication_id: "", + finished: false, } // FIXME: overwrite category if the ACTION chosen has a different category // const image = "url("+app.large_image+")" - // FIXME - find the cytoscape offset position // Can this be done with zoom calculations? const nodeToBeAdded = { group: "nodes", data: newAppData, renderedPosition: { - x: e.layerX, - y: e.layerY, + //x: e.layerX, + //y: e.layerY, + x: e.pageX-cycontainer.offsetLeft, + y: e.pageY-cycontainer.offsetTop, } } + parsedApp = nodeToBeAdded cy.add(nodeToBeAdded) - - if (workflow.actions === undefined || workflow.actions.length === 0) { - workflow.start = newAppData.id - workflow.actions = [] - newAppData.isStartNode = true - //setStartNode(newAppData.id) - } - - if (workflow.actions.length > 0 && elements.length === 0) { - const actions = workflow.actions.map(action => { - const node = {} - node.position = action.position - node.data = action - - node.data._id = action["id"] - node.data.type = "ACTION" - node.isStartNode = action["id"] === workflow.start - - return node - }) - - const tmpelements = [].concat(actions) - setElements(tmpelements) - } - - if (workflow.actions.length === 1 && workflow.actions[0].id === workflow.start) { - const newEdgeUuid = uuid.v4() - const newcybranch = { - "source": workflow.start, - "target": newNodeId, - "_id": newEdgeUuid, - "id": newEdgeUuid, - "hasErrors": false, - } - - const edgeToBeAdded = { - group: "edges", - data: newcybranch, - } - console.log("SHOULD STITCH WITH STARTNODE") - cy.add(edgeToBeAdded) - } - - // AUTHENTICATION - if (app.authentication.required) { - // Setup auth here :) - const authenticationOptions = [] - var findAuthId = "" - if (newAppData.authentication_id !== null && newAppData.authentication_id !== undefined && newAppData.authentication_id.length > 0) { - findAuthId = newAppData.authentication_id - } - - var tmpAuth = JSON.parse(JSON.stringify(appAuthentication)) - for (var key in tmpAuth) { - var item = tmpAuth[key] - - const newfields = {} - for (var filterkey in item.fields) { - newfields[item.fields[filterkey].key] = item.fields[filterkey].value - } - - item.fields = newfields - if (item.app.name === app.name) { - authenticationOptions.push(item) - if (item.id === findAuthId) { - newAppData.selectedAuthentication = item - } - } - } - - if (authenticationOptions !== undefined && authenticationOptions !== null && authenticationOptions.length > 0) { - for (var key in authenticationOptions) { - const option = authenticationOptions[key] - if (option.active) { - newAppData.selectedAuthentication = option - newAppData.authentication_id = option.id - break - } - } - } - - //newAppData.authentication = authenticationOptions - //if (newAppData.selectedAuthentication === null || newAppData.selectedAuthentication === undefined || newAppData.selectedAuthentication.length === "") { - // newAppData.selectedAuthentication = {} - //} else { - // console.log("CAN WE SELECT AUTH?: ", authenticationOptions) - //} - } else { - newAppData.authentication = [] - newAppData.authentication_id = "" - newAppData.selectedAuthentication = {} - } - - workflow.actions.push(newAppData) - setWorkflow(workflow) - - if (newAppPopup) { - //alert.error("SHOULD MAKE USER AUTHENTICATE THE APP OR SET hasError") - //alert.info("Remember: set the authentication for the user itself, not the app") + return } } } - } - - const handleDragStop = (e, app) => { - newNodeId = "" - console.log("STOP!: ", e) - console.log("APP!: ", app) - } - - const appScrollStyle = { - overflow: "scroll", - maxHeight: bodyHeight-appBarSize-55-50, - minHeight: bodyHeight-appBarSize-55-50, - marginTop: 1, - overflowY: "auto", - overflowX: "hidden", - } const AppView = (props) => { const { allApps, prioritizedApps, filteredApps } = props; - const [visibleApps, setVisibleApps] = React.useState(prioritizedApps.concat(filteredApps.filter(innerapp => !internalIds.includes(innerapp.id)))) + const [visibleApps, setVisibleApps] = React.useState(prioritizedApps.concat(filteredApps.filter(innerapp => !internalIds.includes(innerapp.id)))) const ParsedAppPaper = (props) => { const app = props.app @@ -2782,7 +4231,7 @@ const AngularWorkflow = (props) => { if (newAppname.length > maxlen) { newAppname = newAppname.slice(0, maxlen)+".." } - app.name.replaceAll("_", " ", -1) + newAppname = newAppname.replaceAll("_", " ") //const image = "url("+app.large_image+")" const image = app.large_image @@ -2793,7 +4242,9 @@ const AngularWorkflow = (props) => { return ( {handleAppDrag(e, app)}} - onStop={(e) => {handleDragStop(e, app)}} + onStop={(e) => { + handleDragStop(e, app) + }} key={app.id} dragging={false} position={{ @@ -2804,11 +4255,13 @@ const AngularWorkflow = (props) => { {setHover(true)}} onMouseOut={() => {setHover(false)}}> - {newAppname} + {newAppname} - {newAppname} + + {newAppname} + @@ -2827,9 +4280,28 @@ const AngularWorkflow = (props) => { ) } - const runSearch = (event) => { - if (event.target.value.length > 0) { - setVisibleApps(allApps.filter(app => app.name.toLowerCase().includes(event.target.value.trim().toLowerCase()))) + const runSearch = (value) => { + if (value.length > 0) { + var newApps = allApps.filter(app => (app.name.toLowerCase().includes(value.trim().toLowerCase() || app.description.toLowerCase().includes(value.trim().toLowerCase()))) && !(!app.activated && app.generated)) + + // Extend search + if (newApps.length === 0) { + const searchvalue = value.trim().toLowerCase() + newApps = allApps.filter(app => { + for (var key in app.actions) { + const inneraction = app.actions[key] + if (inneraction.name.toLowerCase().includes(searchvalue)) { + return true + } + } + + return false + }) + } + + //setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name) && !(!app.activated && app.generated))) + //console.log("FOUND: ", newApps) + setVisibleApps(newApps) } else { setVisibleApps(prioritizedApps.concat(filteredApps.filter(innerapp => !internalIds.includes(innerapp.id)))) } @@ -2839,7 +4311,7 @@ const AngularWorkflow = (props) => {
{ color="primary" placeholder={"Search Active Apps"} id="appsearch" + onKeyPress={(event) => { + if (event.key === "Enter") { + event.target.blur(event) + } + }} onBlur={(event) => { - runSearch(event) + console.log("BLUR: ", event.target.value) + runSearch(event.target.value) }} /> {visibleApps.length > 0 ? @@ -2877,12 +4355,19 @@ const AngularWorkflow = (props) => { })}
: -
- - - Loading apps - -
+ apps.length > 0 ? +
+ + Couldn't find app. Is it active? + +
+ : +
+ + + Loading apps + +
}
@@ -2912,13 +4397,51 @@ const AngularWorkflow = (props) => { const setNewSelectedAction = (e) => { const newaction = selectedApp.actions.find(a => a.name === e.target.value) + if (newaction === undefined || newaction === null) { + alert.error("Failed to find the action") + return + } // Does this one find the wrong one? - selectedAction.name = newaction.name - selectedAction.parameters = JSON.parse(JSON.stringify(newaction.parameters)) + var newSelectedAction = selectedAction + newSelectedAction.name = newaction.name + newSelectedAction.parameters = JSON.parse(JSON.stringify(newaction.parameters)) + newSelectedAction.errors = [] + newSelectedAction.isValid = true + newSelectedAction.is_valid = true + + if (newSelectedAction.app_name === "Shuffle Tools") { + const iconInfo = GetIconInfo(newSelectedAction) + console.log("ICONINFO: ", iconInfo) + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + newSelectedAction.large_image = svgpin_Url + newSelectedAction.fillGradient = iconInfo.fillGradient + newSelectedAction.fillstyle = "solid" + if (newSelectedAction.fillGradient !== undefined && newSelectedAction.fillGradient !== null && newSelectedAction.fillGradient.length > 0) { + newSelectedAction.fillstyle = 'linear-gradient' + console.log("GRADIENT!: ", newSelectedAction) + //action.fillstyle = + //'background-fill': 'data(fillstyle)', + } else { + newSelectedAction.iconBackground = iconInfo.iconBackgroundColor + } + + const foundnode = cy.getElementById(newSelectedAction.id) + if (foundnode !== null && foundnode !== undefined) { + console.log("UPDATING NODE!") + foundnode.data(newSelectedAction) + } + } + + // Takes an action as input, then runs through and updates the relevant fields + // based on previous actions' + newSelectedAction = RunAutocompleter(newSelectedAction) + + console.log("ACTION: ", newSelectedAction) if (newaction.returns.example !== undefined && newaction.returns.example !== null && newaction.returns.example.length > 0) { - selectedAction.example = newaction.returns.example + newSelectedAction.example = newaction.returns.example } // FIXME - this is broken sometimes lol @@ -2928,8 +4451,26 @@ const AngularWorkflow = (props) => { //} //setSelectedActionEnvironment(env) - setSelectedAction(selectedAction) + setSelectedAction(newSelectedAction) setUpdate(Math.random()) + + // FIXME - should change icon-node (descriptor) as well + const allNodes = cy.nodes().jsons() + for (var key in allNodes) { + const currentNode = allNodes[key] + if (currentNode.data.attachedTo === selectedAction.id && currentNode.data.isDescriptor) { + const foundnode = cy.getElementById(currentNode.data.id) + if (foundnode !== null && foundnode !== undefined) { + const iconInfo = GetIconInfo(newaction) + const svg_pin = `` + const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin) + foundnode.data("image", svgpin_Url) + foundnode.data("imageColor", iconInfo.iconBackgroundColor) + } + + break + } + } } // APPSELECT at top @@ -2941,7 +4482,17 @@ const AngularWorkflow = (props) => { //console.log("OLDNAME: ", selectedAction.name) event.target.value = event.target.value.replaceAll("(", "") event.target.value = event.target.value.replaceAll(")", "") + event.target.value = event.target.value.replaceAll("]", "") + event.target.value = event.target.value.replaceAll("[", "") + event.target.value = event.target.value.replaceAll("{", "") + event.target.value = event.target.value.replaceAll("}", "") + event.target.value = event.target.value.replaceAll("*", "") + event.target.value = event.target.value.replaceAll("!", "") + event.target.value = event.target.value.replaceAll("@", "") + event.target.value = event.target.value.replaceAll("#", "") event.target.value = event.target.value.replaceAll("$", "") + event.target.value = event.target.value.replaceAll("%", "") + event.target.value = event.target.value.replaceAll("&", "") event.target.value = event.target.value.replaceAll("#", "") event.target.value = event.target.value.replaceAll(".", "") event.target.value = event.target.value.replaceAll(",", "") @@ -2984,22 +4535,38 @@ const AngularWorkflow = (props) => { setSelectedTrigger(selectedTrigger) } + // Starts on current node and climbs UP the tree to the root object. + // Sends back everything in it's path const getParents = (action) => { var allkeys = [action.id] var handled = [] var results = [] + // maxiter = max amount of parent nodes to loop + // also handles breaks if there are issues + var iterations = 0 + var maxiter = 10 while(true) { for (var key in allkeys) { var currentnode = cy.getElementById(allkeys[key]) - if (handled.includes(currentnode.data().id)) { + if (currentnode === undefined || currentnode === null) { continue + } + + if (currentnode.data() === undefined) { + //console.log("Node doesn't have any data (getParents)! Probably a trigger.") + handled.push(allkeys[key]) + results.push({"id": allkeys[key], "type": "TRIGGER"}) } else { - // Get the name / label here too? - handled.push(currentnode.data().id) - results.push(currentnode.data()) + if (handled.includes(currentnode.data().id)) { + continue + } else { + handled.push(currentnode.data().id) + results.push(currentnode.data()) + } } + // Get the name / label here too? if (currentnode.length === 0) { continue } @@ -3016,9 +4583,12 @@ const AngularWorkflow = (props) => { } } } - if (results.length === allkeys.length) { + + if (results.length === allkeys.length || iterations === maxiter) { break } + + iterations += 1 } // Remove self @@ -3033,1041 +4603,7 @@ const AngularWorkflow = (props) => { // Dropdown -> static, action, local env, global env // VALUE (JSON) // {data.name}, {data.description}, {data.required}, {data.schema.type} - const AppActionArguments = (props) => { - const [selectedActionParameters, setSelectedActionParameters] = React.useState([]) - const [selectedVariableParameter, setSelectedVariableParameter] = React.useState("") - const [actionlist, setActionlist] = React.useState([]) - const [jsonList, setJsonList] = React.useState([]) - const [showDropdown, setShowDropdown] = React.useState(false) - const [showDropdownNumber, setShowDropdownNumber] = React.useState(0) - const [showAutocomplete, setShowAutocomplete] = React.useState(false) - const [menuPosition, setMenuPosition] = useState(null) - - useEffect(() => { - if (selectedActionParameters !== null && selectedActionParameters.length === 0) { - if (selectedAction.parameters !== null && selectedAction.parameters.length > 0) { - setSelectedActionParameters(selectedAction.parameters) - } - } - - if ((selectedVariableParameter === null || selectedVariableParameter === undefined) && (workflow.workflow_variables !== null && workflow.workflow_variables.length > 0)) { - // FIXME - this is the bad thing - setSelectedVariableParameter(workflow.workflow_variables[0].name) - } - - if (actionlist.length === 0) { - // FIXME: Have previous execution values in here - actionlist.push({"type": "Execution Argument", "name": "Execution Argument", "value": "$exec", "highlight": "exec", "autocomplete": "exec", "example": "hello"}) - if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) { - for (var key in workflow.workflow_variables) { - const item = workflow.workflow_variables[key] - actionlist.push({"type": "workflow_variable", "name": item.name, "value": item.value, "id": item.id, "autocomplete": `${item.name.split(" ").join("_")}`, "example": item.value}) - } - } - - // FIXME: Add values from previous executions if they exist - if (workflow.execution_variables !== null && workflow.execution_variables !== undefined && workflow.execution_variables.length > 0) { - for (var key in workflow.execution_variables) { - const item = workflow.execution_variables[key] - actionlist.push({"type": "execution_variable", "name": item.name, "value": item.value, "id": item.id, "autocomplete": `${item.name.split(" ").join("_")}`, "example": ""}) - } - } - - // Loops parent nodes' old results to fix autocomplete - var parents = getParents(selectedAction) - if (parents.length > 1) { - for (var key in parents) { - const item = parents[key] - if (item.label === "Execution Argument") { - continue - } - - var exampledata = item.example === undefined ? "" : item.example - // Find previous execution and their variables - //exampledata === "" && - if (workflowExecutions.length > 0) { - // Look for the ID - const found = false - for (var key in workflowExecutions) { - if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) { - continue - } - - var foundResult = workflowExecutions[key].results.find(result => result.action.id === item.id) - if (foundResult === undefined) { - continue - } - - foundResult.result = foundResult.result.trim() - foundResult.result = foundResult.result.split(" None").join(" \"None\"") - foundResult.result = foundResult.result.split(" False").join(" false") - foundResult.result = foundResult.result.split(" True").join(" true") - - var jsonvalid = true - try { - const tmp = String(JSON.parse(foundResult.result)) - if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { - jsonvalid = false - } - } catch (e) { - try { - foundResult.result = foundResult.result.split("\'").join("\"") - const tmp = String(JSON.parse(foundResult.result)) - if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { - jsonvalid = false - } - } catch (e) { - jsonvalid = false - } - } - - // Finds the FIRST json only - if (jsonvalid) { - exampledata = JSON.parse(foundResult.result) - break - } - //else { - // console.log("Invalid JSON: ", foundResult.result) - //} - } - } - - // 1. Take - const actionvalue = {"type": "action", "id": item.id, "name": item.label, "autocomplete": `${item.label.split(" ").join("_")}`, "example": exampledata} - actionlist.push(actionvalue) - } - } - - setActionlist(actionlist) - } - }) - - const changeActionParameter = (event, count, data) => { - if (data.name.startsWith("${") && data.name.endsWith("}")) { - // PARAM FIX - Gonna use the ID field, even though it's a hack - const paramcheck = selectedAction.parameters.find(param => param.name === "body") - if (paramcheck !== undefined) { - if (paramcheck["value_replace"] === undefined || paramcheck["value_replace"] === null) { - paramcheck["value_replace"] = [{ - "key": data.name, - "value": event.target.value, - }] - - } else { - const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name) - if (subparamindex === -1) { - paramcheck["value_replace"].push({ - "key": data.name, - "value": event.target.value, - }) - } else { - paramcheck["value_replace"][subparamindex]["value"] = event.target.value - } - } - //console.log("PARAM: ", paramcheck) - - selectedActionParameters[count]["value_replace"] = paramcheck - selectedAction.parameters[count]["value_replace"] = paramcheck - setSelectedAction(selectedAction) - //setUpdate(Math.random()) - return - } - } - - if (event.target.value[event.target.value.length-1] === "$") { - if (!showDropdown) { - setShowAutocomplete(false) - setShowDropdown(true) - setShowDropdownNumber(count) - } - } else { - if (showDropdown) { - setShowDropdown(false) - } - } - - // bad detection mechanism probably - if (event.target.value[event.target.value.length-1] === "." && actionlist.length > 0) { - console.log("GET THE LAST ARGUMENT FOR NODE!") - // THIS IS AN EXAMPLE OF SHOWING IT - /* - const inputdata = {"data": "1.2.3.4", "dataType": "4.5.6.6"} - setJsonList(GetParsedPaths(inputdata, "")) - if (!showDropdown) { - setShowAutocomplete(false) - setShowDropdown(true) - setShowDropdownNumber(count) - } - console.log(jsonList) - */ - - // Search for the item backwards - // 1. Reverse search backwards from . -> $ - // 2. Search the actionlist for the item - // 3. Find the data for the specific item - - var curstring = "" - var record = false - for (var key in selectedActionParameters[count].value) { - const item = selectedActionParameters[count].value[key] - if (record) { - curstring += item - } - - if (item === "$") { - record = true - curstring = "" - } - } - - //console.log("CURSTRING: ", curstring) - if (curstring.length > 0 && actionlist !== null) { - // Search back in the action list - curstring = curstring.split(" ").join("_").toLowerCase() - var actionItem = actionlist.find(data => data.autocomplete.split(" ").join("_").toLowerCase() === curstring) - if (actionItem !== undefined) { - console.log("Found item: ", actionItem) - - //actionItem.example = actionItem.example.trim() - //actionItem.example = actionItem.example.split(" None").join(" \"None\"") - //actionItem.example = actionItem.example.split("\'").join("\"") - - var jsonvalid = true - try { - const tmp = String(JSON.parse(actionItem.example)) - if (!actionItem.example.includes("{") && !actionItem.example.includes("[")) { - jsonvalid = false - } - } catch (e) { - jsonvalid = false - } - - if (jsonvalid) { - setJsonList(GetParsedPaths(JSON.parse(actionItem.example), "")) - - if (!showDropdown) { - setShowAutocomplete(false) - setShowDropdown(true) - setShowDropdownNumber(count) - } - } - } - } - } else { - if (jsonList.length > 0) { - setJsonList([]) - } - } - - selectedActionParameters[count].value = event.target.value - selectedAction.parameters[count].value = event.target.value - setSelectedAction(selectedAction) - //setUpdate(Math.random()) - //setUpdate(event.target.value) - } - - const changeActionParameterVariable = (fieldvalue, count) => { - //console.log("CALLED THIS ONE WITH VALUE!", fieldvalue) - //if (selectedVariableParameter === fieldvalue) { - // return - //} - - setSelectedVariableParameter(fieldvalue) - - selectedActionParameters[count].action_field = fieldvalue - selectedAction.parameters = selectedActionParameters - - setSelectedApp(selectedApp) - setSelectedAction(selectedAction) - setUpdate(fieldvalue) - } - - // Sets ACTION_RESULT things - const changeActionParameterActionResult = (fieldvalue, count) => { - //cy.nodes().forEach(function( ele ) { - // if (ele.data()["label"] === fieldvalue) { - // selectedActionParameters[count].action_field = ele.id() - // return - // } - //}); - - selectedActionParameters[count].action_field = fieldvalue - selectedAction.parameters = selectedActionParameters - - // FIXME - check if startnode - - // Set value - setSelectedApp(selectedApp) - - setSelectedAction(selectedAction) - setUpdate(Math.random()) - } - - const changeActionParameterVariant = (data, count) => { - selectedActionParameters[count].variant = data - selectedActionParameters[count].value = "" - - if (data === "ACTION_RESULT") { - var parents = getParents(selectedAction) - if (parents.length > 0) { - selectedActionParameters[count].action_field = parents[0].label - } else { - selectedActionParameters[count].action_field = "" - } - } else if (data === "WORKFLOW_VARIABLE") { - if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) { - selectedActionParameters[count].action_field = workflow.workflow_variables[0].name - } - } - - selectedAction.parameters = selectedActionParameters - - // This is a stupid workaround to make it refresh rofl - setSelectedAction({}) - setSelectedTrigger({}) - setSelectedApp({}) - setSelectedEdge({}) - // FIXME - check if startnode - - // Set value - setSelectedApp(selectedApp) - setSelectedAction(selectedAction) - setUpdate(Math.random()) - } - - // FIXME: Issue #40 - selectedActionParameters not reset - if (Object.getOwnPropertyNames(selectedAction).length > 0 && selectedActionParameters.length > 0) { - return ( -
- Parameters - {selectedActionParameters.map((data, count) => { - if (data.variant === "") { - data.variant = "STATIC_VALUE" - } - - - // selectedAction.selectedAuthentication = e.target.value - // selectedAction.authentication_id = e.target.value.id - if (!selectedAction.auth_not_required && selectedAction.selectedAuthentication !== undefined && selectedAction.selectedAuthentication.fields !== undefined && selectedAction.selectedAuthentication.fields[data.name] !== undefined) { - // This sets the placeholder in the frontend. (Replaced in backend) - selectedActionParameters[count].value = selectedAction.selectedAuthentication.fields[data.name] - selectedAction.parameters[count].value = selectedAction.selectedAuthentication.fields[data.name] - setSelectedAction(selectedAction) - //setUpdate(Math.random()) - - return null - } - - var staticcolor = "inherit" - var actioncolor = "inherit" - var varcolor = "inherit" - var multiline - if (data.multiline !== undefined && data.multiline !== null && data.multiline === true) { - multiline = true - } - - if (data.value !== undefined && data.value !== null && data.value.startsWith("{") && data.value.endsWith("}")) { - multiline = true - } - - var placeholder = "Static value" - if (data.example !== undefined && data.example !== null && data.example.length > 0) { - placeholder = data.example - } - - if (data.name.startsWith("${") && data.name.endsWith("}")) { - const paramcheck = selectedAction.parameters.find(param => param.name === "body") - if (paramcheck !== undefined && paramcheck !== null) { - if (paramcheck["value_replace"] !== undefined && paramcheck["value_replace"] !== null) { - //console.log("IN THE VALUE REPLACE: ", paramcheck["value_replace"]) - const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name) - if (subparamindex !== -1) { - data.value = paramcheck["value_replace"][subparamindex]["value"] - } - } - } - } - - var disabled = false - var rows = "5" - var openApiHelperText = "This is an OpenAPI specific field" - if (selectedApp.generated && selectedApp.activated && data.name === "body") { - const regex = /\${(\w+)}/g - const found = placeholder.match(regex) - if (found === null) { - //setExtraBodyFields([]) - } else { - rows = "1" - disabled = true - openApiHelperText = "OpenAPI spec: fill the following fields." - //console.log("SHOULD ADD TO selectedActionParameters!: ", found, selectedActionParameters) - var changed = false - for (var specKey in found) { - const tmpitem = found[specKey] - var skip = false - for (var innerkey in selectedActionParameters) { - if (selectedActionParameters[innerkey].name === tmpitem) { - skip = true - break - } - } - - if (skip) { - //console.log("SKIPPING ", tmpitem) - continue - } - - changed = true - selectedActionParameters.push({ - action_field: "", - configuration: false, - description: "Generated by OpenAPI body example", - example: "", - id: "", - multiline: false, - name: tmpitem, - options: null, - required: false, - schema: {type: "string"}, - skip_multicheck: false, - tags: null, - value: "", - variant: "STATIC_VALUE", - }) - } - - if (changed) { - setSelectedActionParameters(selectedActionParameters) - } - - return - } - } - - //console.log("Data: ", data) - var datafield = - - - { - setMenuPosition({ - top: event.pageY+10, - left: event.pageX+10, - }) - setShowDropdownNumber(count) - setShowDropdown(true) - setShowAutocomplete(true) - }}/> - - - ) - }} - fullWidth - multiline={multiline} - rows={rows} - color="primary" - defaultValue={data.value} - type={placeholder.includes("***") ? "password" : "text"} - placeholder={placeholder} - onChange={(event) => { - changeActionParameter(event, count, data) - }} - helperText={selectedApp.generated && selectedApp.activated && data.name === "body" ? - - {openApiHelperText} - - : - data.name.startsWith("${") && data.name.endsWith("}") ? - - OpenAPI helperfield - - : - null - } - onBlur={(event) => { - // Super basic check - //if (event.target.value.startsWith("{")) { - // console.log("VALIDATING JSON") - // try { - // JSON.parse(event.target.value) - // } catch (e) { - // alert.error("Failed to parse json: ", e) - // } - //} - }} - /> - - if (selectedActionParameters[count].schema !== undefined && selectedActionParameters[count].schema !== null && selectedActionParameters[count].schema.type === "file") { - datafield = - - - { - setMenuPosition({ - top: event.pageY+10, - left: event.pageX+10, - }) - setShowDropdownNumber(count) - setShowDropdown(true) - setShowAutocomplete(true) - }}/> - - - ) - }} - fullWidth - multiline={multiline} - rows="5" - color="primary" - defaultValue={data.value} - type={"text"} - placeholder={"The file ID to get"} - onChange={(event) => { - changeActionParameter(event, count, data) - }} - onBlur={(event) => { - }} - /> - //const fileId = "6daabec1-892b-469c-b603-c902e47223a9" - //datafield = `SHOW FILES FROM OTHER NODES? Filename: ${selectedActionParameters[count].value}` - /* - if (selectedActionParameters[count].value != fileId) { - changeActionParameter(fileId, count, data) - setUpdate(Math.random()) - - } - */ - } else if (selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0) { - if (selectedActionParameters[count].value === "" && selectedActionParameters[count].required) { - // Rofl, dirty workaround :) - const e = { - target: { - value: selectedActionParameters[count].options[0], - } - } - - changeActionParameter(e, count, data) - } - - datafield = - - - } else if (data.variant === "STATIC_VALUE") { - staticcolor = "#f85a3e" - } else if (data.variant === "ACTION_RESULT") { - // Gets the parents of the current node - var parents = getParents(selectedAction) - actioncolor = "#f85a3e" - // set the datafield - //var datafieldvalue = "Error: No parents. Action not eligible" - //if (parents.length > 0) { - // datafieldvalue = parents[0].label - //} - const fixedActionText = selectedActionParameters[count].value - - datafield = -
- - Example: $.body will get "data" from {'{"body": "data"}'}
} - placeholder="Action variable ($.)" - onChange={(event) => { - changeActionParameter(event, count, data) - }} - /> -
- - } else if (data.variant === "WORKFLOW_VARIABLE") { - varcolor = "#f85a3e" - if ((workflow.workflow_variables === null || workflow.workflow_variables === undefined || workflow.workflow_variables.length === 0) && (workflow.execution_variables === null || workflow.execution_variables === undefined || workflow.execution_variables.length === 0)) { - setCurrentView(2) - datafield = -
-
- Looks like you don't have any variables yet. -
-
- -
-
- } else { - // FIXME - this is a shitty solution that needs re-renders all the time - datafield = - - } - } - - // Shows nested list of nodes > their JSON lists - const ActionlistWrapper = (props) => { - - const handleMenuClose = () => { - setShowAutocomplete(false) - - if (!selectedActionParameters[count].value[selectedActionParameters[count].value.length-1] === "$") { - setShowDropdown(false) - } - - setUpdate(Math.random()) - setMenuPosition(null) - } - - const handleItemClick = (values) => { - if (values === undefined || values === null || values.length === 0) { - return - } - - var toComplete = selectedActionParameters[count].value.trim().endsWith("$") ? values[0].autocomplete : "$"+values[0].autocomplete - for (var key in values) { - if (key == 0 || values[key].autocomplete.length === 0) { - continue - } - - toComplete += values[key].autocomplete - } - - // Handles the fields under OpenAPI body to be parsed. - if (data.name.startsWith("${") && data.name.endsWith("}")) { - console.log("INSIDE VALUE REPLACE: ", data.name, toComplete) - // PARAM FIX - Gonna use the ID field, even though it's a hack - const paramcheck = selectedAction.parameters.find(param => param.name === "body") - if (paramcheck !== undefined) { - if (paramcheck["value_replace"] === undefined || paramcheck["value_replace"] === null) { - paramcheck["value_replace"] = [{ - "key": data.name, - "value": toComplete, - }] - - } else { - const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name) - if (subparamindex === -1) { - paramcheck["value_replace"].push({ - "key": data.name, - "value": toComplete, - }) - } else { - paramcheck["value_replace"][subparamindex]["value"] += toComplete - } - } - - selectedActionParameters[count]["value_replace"] = paramcheck - selectedAction.parameters[count]["value_replace"] = paramcheck - setSelectedAction(selectedAction) - setUpdate(Math.random()) - - setShowDropdown(false) - setMenuPosition(null) - return - } - } - - selectedActionParameters[count].value += toComplete - selectedAction.parameters[count].value = selectedActionParameters[count].value - setSelectedAction(selectedAction) - setUpdate(Math.random()) - - setShowDropdown(false) - setMenuPosition(null) - } - - const iconStyle = { - marginRight: 15, - } - - return ( - { - handleMenuClose() - }} - open={!!menuPosition} - style={{ - border: `2px solid #f85a3e`, - color: "white", - marginTop: 2, - }} - > - {actionlist.map(innerdata => { - const icon = innerdata.type === "action" ? : innerdata.type === "workflow_variable" || innerdata.type === "execution_variable" ? : - - const handleExecArgumentHover = (inside) => { - var exec_text_field = document.getElementById("execution_argument_input_field") - if (exec_text_field !== null) { - if (inside) { - exec_text_field.style.border = "2px solid #f85a3e" - } else { - exec_text_field.style.border = "" - } - } - - // Also doing arguments - if (workflow.triggers !== undefined && workflow.triggers !== null && workflow.triggers.length > 0) { - for (var key in workflow.triggers) { - const item = workflow.triggers[key] - - var node = cy.getElementById(item.id) - if (node.length > 0) { - if (inside) { - node.addClass('shuffle-hover-highlight') - } else { - node.removeClass('shuffle-hover-highlight') - } - } - - } - } - } - - const handleActionHover = (inside, actionId) => { - var node = cy.getElementById(actionId) - if (node.length > 0) { - if (inside) { - node.addClass('shuffle-hover-highlight') - } else { - node.removeClass('shuffle-hover-highlight') - } - } - } - - const handleMouseover = () => { - if (innerdata.type === "Execution Argument") { - handleExecArgumentHover(true) - } else if (innerdata.type === "action") { - handleActionHover(true, innerdata.id) - } - } - - const handleMouseOut = () => { - if (innerdata.type === "Execution Argument") { - handleExecArgumentHover(false) - } else if (innerdata.type === "action") { - handleActionHover(false, innerdata.id) - } - } - - var parsedPaths = [] - if (typeof(innerdata.example) === "object") { - parsedPaths = GetParsedPaths(innerdata.example, "") - } - - return ( - parsedPaths.length > 0 ? - - {icon} {innerdata.name} -
- } - parentMenuOpen={!!menuPosition} - style={{backgroundColor: inputColor, color: "white", minWidth: 250,}} - onClick={() => { - handleItemClick([innerdata]) - }} - > - {parsedPaths.map((pathdata, index) => { - // FIXME: Should be recursive in here - const icon = pathdata.type === "value" ? : pathdata.type === "list" ? : - return ( - {}} - onClick={() => { - handleItemClick([innerdata, pathdata]) - }} - > - -
- {icon} {pathdata.name} -
-
-
- ) - - })} - - : - handleMouseover()} onMouseOut={() => {handleMouseOut()}} - onClick={() => { - handleItemClick([innerdata]) - }} - > - -
- {icon} {innerdata.name} -
-
-
- - ) - })} -
- ) - } - - var itemColor = "#f85a3e" - if (!data.required) { - itemColor = "#ffeb3b" - } - - var tmpitem = data.name.valueOf() - if (data.name.startsWith("${") && data.name.endsWith("}")) { - tmpitem = tmpitem.slice(2, data.name.length-1) - } - - tmpitem = tmpitem.charAt(0).toUpperCase()+tmpitem.substring(1) - tmpitem = tmpitem.replaceAll("_", " ") - const description = data.description === undefined ? "" : data.description - - return ( -
-
- - - {data.configuration === true ? - - { - setAuthenticationModalOpen(true) - }}/> - - : -
- } -
- - {tmpitem} - -
- - {/*selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 ? null : -
- -
{ - e.preventDefault() - changeActionParameterVariant("STATIC_VALUE", count) - }}> - -
-
-  |  - -
{ - e.preventDefault() - changeActionParameterVariant("ACTION_RESULT", count) - }}> - -
-
-  |  - -
{ - e.preventDefault() - changeActionParameterVariant("WORKFLOW_VARIABLE", count) - }}> - -
-
-
- */} - {selectedActionParameters[count].options !== undefined && selectedActionParameters[count].options !== null && selectedActionParameters[count].options.length > 0 && selectedActionParameters[count].required === true && selectedActionParameters[count].unique_toggled !== undefined ? null : -
- -
{}}> - { - //console.log("CHECKED!: ", selectedActionParameters[count]) - selectedActionParameters[count].unique_toggled = !selectedActionParameters[count].unique_toggled - selectedAction.parameters[count].unique_toggled = selectedActionParameters[count].unique_toggled - setSelectedActionParameters(selectedActionParameters) - setSelectedAction(selectedAction) - setUpdate(Math.random()) - }} - name="requires_unique" - /> -
-
-
- } -
- {datafield} - {showDropdown && showDropdownNumber === count && data.variant === "STATIC_VALUE" && jsonList.length > 0 ? - - Autocomplete - - - : null} - {showDropdown && showDropdownNumber === count && data.variant === "STATIC_VALUE" && jsonList.length === 0 ? - - : null} - - -
- )})} -
- ) - } - return null - } - + //height: "100%", const appApiViewStyle = { display: "flex", @@ -4082,70 +4618,7 @@ const AngularWorkflow = (props) => { overflow: "auto", } - const defineStartnode = () => { - var oldstartnode = cy.getElementById(workflow.start) - if (oldstartnode.length > 0) { - oldstartnode[0].data("isStartNode", false) - var oldnodecnt = workflow.actions.findIndex(a => a.id === workflow.start) - if (workflow.actions[oldnodecnt] !== undefined) { - workflow.actions[oldnodecnt].isStartNode = false - } - } - - var newstartnode = cy.getElementById(selectedAction.id) - if (newstartnode.length > 0) { - newstartnode[0].data("isStartNode", true) - var newnodecnt = workflow.actions.findIndex(a => a.id === selectedAction.id) - console.log("NEW NODE CNT: ", newnodecnt) - if (workflow.actions[newnodecnt] !== undefined) { - workflow.actions[newnodecnt].isStartNode = true - console.log(workflow.actions[newnodecnt]) - } - } - - // Find branches with triggers as source nodes - // Move these targets to be the new node - // Set arrows pointing to new startnode with errors - //for (var key in workflow.branches) { - // var item = workflow.branches[key] - // if (item.destination_id === oldstartnode[0].data()["id"]) { - // var curbranch = cy.getElementById(item.id) - // if (curbranch.length > 0) { - // //console.log(curbranch[0].data()) - // //curbranch[0].data("target", selectedAction.id) - // //curbranch[0].data("hasErrors", true) - // //workflow.branches[key].destination_id = selectedAction.id - // //console.log(curbranch[0].data()) - // } - // } - //} - - setUpdate("start_node"+selectedAction.id) - workflow.start = selectedAction.id - setWorkflow(workflow) - //setStartNode(selectedAction.id) - } - - function sortByKey(array, key) { - if (array === undefined) { - return [] - } - - if (key.startsWith("-") && key.length > 2) { - key = key.slice(1, key.length) - return array.sort(function(a, b) { - var x = a[key]; var y = b[key] - return ((x < y) ? -1 : ((x > y) ? 1 : 0)) - }).reverse() - } - - return array.sort(function(a, b) { - var x = a[key]; var y = b[key] - return ((x < y) ? -1 : ((x > y) ? 1 : 0)) - }) - } - - const rightsidebarStyle = { + var rightsidebarStyle = { position: "fixed", right: 0, top: appBarSize+1, @@ -4160,273 +4633,6 @@ const AngularWorkflow = (props) => { zIndex: 1000, } - const textFieldStyle = { - backgroundColor: inputColor, - borderRadius: borderRadius, - } - - - const innerTextfieldStyle = { - color: "white", - minHeight: 50, - marginLeft: "5px", - maxWidth: "95%", - fontSize: "1em", - borderRadius: borderRadius, - } - - const appApiView = Object.getOwnPropertyNames(selectedAction).length > 0 ? -
-
-
-

{selectedAction.app_name.replaceAll("_", " ")}

-
- { - console.log("FIND EXAMPLE RESULTS FOR ", selectedAction) - if (workflowExecutions.length > 0) { - // Look for the ID - const found = false - for (var key in workflowExecutions) { - if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) { - continue - } - - var foundResult = workflowExecutions[key].results.find(result => result.action.id === selectedAction.id) - if (foundResult === undefined || foundResult === null) { - continue - } - - setSelectedResult(foundResult) - setCodeModalOpen(true) - break - } - } - }}> - - - - - - What are actions? - {selectedAction.errors !== null && selectedAction.errors.length > 0 ? -
- Errors: {selectedAction.errors.join("\n")} -
- : null - } -
-
-
-
- {selectedAction.id === workflow.start ? null : - - - - } -
-
- - - Name - - - {selectedApp.name !== undefined && selectedAction.authentication !== undefined && selectedAction.authentication.length === 0 && requiresAuthentication ? -
- - - - - -
- : null} - {selectedAction.authentication !== undefined && selectedAction.authentication.length > 0 ? -
- Authentication -
- - - {/* - - - curaction.authentication = authenticationOptions - if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "") - */} - - { - setAuthenticationModalOpen(true) - }}> - - - -
-
- : null} - {showEnvironment ? -
- - Environment - - -
- : null} - {workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > 0 ? -
- Set execution variable (optional) - -
- : null} - -
-
- Actions -
- - {selectedAction.description !== undefined && selectedAction.description.length > 0 ? -
- {selectedAction.description} -
: null} -
- - -
-
- -
-
-
- : null - - const setTriggerFolderWrapperMulti = event => { const { options } = event.target const value = [] @@ -4616,7 +4822,7 @@ const AngularWorkflow = (props) => { var datafield = { color="primary" onClick={() => { const redirectUri = isCloud ? "https%3A%2F%2Fshuffler.io%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" : "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" + //const redirectUri = isCloud ? "http%3A%2F%2Flocalhost:5002%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" : "http%3A%2F%2Flocalhost:5001%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister" + const client_id = "fd55c175-aa30-4fa6-b303-09a29fb3f750" const username = isCloud ? userdata.username : userdata.id console.log(redirectUri) @@ -5291,7 +5499,7 @@ const AngularWorkflow = (props) => { native rows="10" value={selectedTrigger.parameters[0].value.split(splitter)} - style={{backgroundColor: inputColor, color: "white"}} + style={{backgroundColor: inputColor, color: "white", height: 50,}} disabled={selectedTrigger.status === "running"} SelectDisplayProps={{ style: { @@ -5369,7 +5577,7 @@ const AngularWorkflow = (props) => { Name {
Environment: { const [showDropdown, setShowDropdown] = React.useState(false) const [showDropdownNumber, setShowDropdownNumber] = React.useState(0) const [showAutocomplete, setShowAutocomplete] = React.useState(false) + const [actionlist, setActionlist] = React.useState([]) + + if (actionlist.length === 0) { + // FIXME: Have previous execution values in here + actionlist.push({"type": "Execution Argument", "name": "Execution Argument", "value": "$exec", "highlight": "exec", "autocomplete": "exec", "example": "hello"}) + if (workflow.workflow_variables !== null && workflow.workflow_variables !== undefined && workflow.workflow_variables.length > 0) { + for (var key in workflow.workflow_variables) { + const item = workflow.workflow_variables[key] + actionlist.push({"type": "workflow_variable", "name": item.name, "value": item.value, "id": item.id, "autocomplete": `${item.name.split(" ").join("_")}`, "example": item.value}) + } + } + + // FIXME: Add values from previous executions if they exist + if (workflow.execution_variables !== null && workflow.execution_variables !== undefined && workflow.execution_variables.length > 0) { + for (var key in workflow.execution_variables) { + const item = workflow.execution_variables[key] + actionlist.push({"type": "execution_variable", "name": item.name, "value": item.value, "id": item.id, "autocomplete": `${item.name.split(" ").join("_")}`, "example": ""}) + } + } + + var parents = getParents(selectedAction) + if (parents.length > 1) { + for (var key in parents) { + const item = parents[key] + if (item.label === "Execution Argument") { + continue + } + + var exampledata = item.example === undefined ? "" : item.example + // Find previous execution and their variables + //exampledata === "" && + if (workflowExecutions.length > 0) { + // Look for the ID + const found = false + for (var key in workflowExecutions) { + if (workflowExecutions[key].results === undefined || workflowExecutions[key].results === null) { + continue + } + + var foundResult = workflowExecutions[key].results.find(result => result.action.id === item.id) + if (foundResult === undefined) { + continue + } + + foundResult.result = foundResult.result.trim() + foundResult.result = foundResult.result.split(" None").join(" \"None\"") + foundResult.result = foundResult.result.split(" False").join(" false") + foundResult.result = foundResult.result.split(" True").join(" true") + + var jsonvalid = true + try { + const tmp = String(JSON.parse(foundResult.result)) + if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { + jsonvalid = false + } + } catch (e) { + try { + foundResult.result = foundResult.result.split("\'").join("\"") + const tmp = String(JSON.parse(foundResult.result)) + if (!foundResult.result.includes("{") && !foundResult.result.includes("[")) { + jsonvalid = false + } + } catch (e) { + jsonvalid = false + } + } + + // Finds the FIRST json only + if (jsonvalid) { + exampledata = JSON.parse(foundResult.result) + break + } + //else { + // console.log("Invalid JSON: ", foundResult.result) + //} + } + } + + // 1. Take + const actionvalue = {"type": "action", "id": item.id, "name": item.label, "autocomplete": `${item.label.split(" ").join("_")}`, "example": exampledata} + actionlist.push(actionvalue) + } + + } + + //console.log("ACTIONS: ", actionlist) + setActionlist(actionlist) + } + + // Shows nested list of nodes > their JSON lists + const ActionlistWrapper = (props) => { + const { data } = props; + + const handleMenuClose = () => { + setShowAutocomplete(false) + + //if (!selectedActionParameters[count].value[selectedActionParameters[count].value.length-1] === "$") { + // setShowDropdown(false) + //} + + setUpdate(Math.random()) + setMenuPosition(null) + } + + const handleItemClick = (values) => { + if (values === undefined || values === null || values.length === 0) { + return + } + + var toComplete = workflow.triggers[selectedTriggerIndex].parameters[1].value.trim().endsWith("$") ? values[0].autocomplete : "$"+values[0].autocomplete + for (var key in values) { + if (key == 0 || values[key].autocomplete.length === 0) { + continue + } + + toComplete += values[key].autocomplete + } + + // Handles the fields under OpenAPI body to be parsed. + if (data.name.startsWith("${") && data.name.endsWith("}")) { + console.log("INSIDE VALUE REPLACE: ", data.name, toComplete) + // PARAM FIX - Gonna use the ID field, even though it's a hack + const paramcheck = selectedAction.parameters.find(param => param.name === "body") + if (paramcheck !== undefined) { + if (paramcheck["value_replace"] === undefined || paramcheck["value_replace"] === null) { + paramcheck["value_replace"] = [{ + "key": data.name, + "value": toComplete, + }] + + } else { + const subparamindex = paramcheck["value_replace"].findIndex(param => param.key === data.name) + if (subparamindex === -1) { + paramcheck["value_replace"].push({ + "key": data.name, + "value": toComplete, + }) + } else { + paramcheck["value_replace"][subparamindex]["value"] += toComplete + } + } + + workflow.triggers[selectedTriggerIndex].parameters[1]["value_replace"] = paramcheck + setSelectedAction(selectedAction) + setUpdate(Math.random()) + + setShowDropdown(false) + setMenuPosition(null) + return + } + } + + //workflow.triggers[selectedTriggerIndex].parameters[1].value = selectedActionParameters[count].value + setSelectedAction(selectedAction) + setUpdate(Math.random()) + + setShowDropdown(false) + setMenuPosition(null) + } + + const iconStyle = { + marginRight: 15, + } + + return ( + { + handleMenuClose() + }} + open={!!menuPosition} + style={{ + border: `2px solid #f85a3e`, + color: "white", + marginTop: 2, + }} + > + {actionlist.map(innerdata => { + const icon = innerdata.type === "action" ? : innerdata.type === "workflow_variable" || innerdata.type === "execution_variable" ? : + + const handleExecArgumentHover = (inside) => { + var exec_text_field = document.getElementById("execution_argument_input_field") + if (exec_text_field !== null) { + if (inside) { + exec_text_field.style.border = "2px solid #f85a3e" + } else { + exec_text_field.style.border = "" + } + } + + // Also doing arguments + if (workflow.triggers !== undefined && workflow.triggers !== null && workflow.triggers.length > 0) { + for (var key in workflow.triggers) { + const item = workflow.triggers[key] + + if (cy !== undefined) { + var node = cy.getElementById(item.id) + if (node.length > 0) { + if (inside) { + node.addClass('shuffle-hover-highlight') + } else { + node.removeClass('shuffle-hover-highlight') + } + } + } + } + } + } + + const handleActionHover = (inside, actionId) => { + if (cy !== undefined) { + var node = cy.getElementById(actionId) + if (node.length > 0) { + if (inside) { + node.addClass('shuffle-hover-highlight') + } else { + node.removeClass('shuffle-hover-highlight') + } + } + } + } + + const handleMouseover = () => { + if (innerdata.type === "Execution Argument") { + handleExecArgumentHover(true) + } else if (innerdata.type === "action") { + handleActionHover(true, innerdata.id) + } + } + + const handleMouseOut = () => { + if (innerdata.type === "Execution Argument") { + handleExecArgumentHover(false) + } else if (innerdata.type === "action") { + handleActionHover(false, innerdata.id) + } + } + + var parsedPaths = [] + if (typeof(innerdata.example) === "object") { + parsedPaths = GetParsedPaths(innerdata.example, "") + } + + return ( + parsedPaths.length > 0 ? + + {icon} {innerdata.name} +
+ } + parentMenuOpen={!!menuPosition} + style={{backgroundColor: theme.palette.inputColor, color: "white", minWidth: 250,}} + onClick={() => { + handleItemClick([innerdata]) + }} + > + {parsedPaths.map((pathdata, index) => { + // FIXME: Should be recursive in here + const icon = pathdata.type === "value" ? : pathdata.type === "list" ? : + return ( + {}} + onClick={() => { + handleItemClick([innerdata, pathdata]) + }} + > + +
+ {icon} {pathdata.name} +
+
+
+ ) + + })} + + : + handleMouseover()} onMouseOut={() => {handleMouseOut()}} + onClick={() => { + handleItemClick([innerdata]) + }} + > + +
+ {icon} {innerdata.name} +
+
+
+ + ) + })} + + ) + } if (Object.getOwnPropertyNames(selectedTrigger).length > 0) { if (workflow.triggers[selectedTriggerIndex] === undefined) { @@ -5445,6 +5949,7 @@ const AngularWorkflow = (props) => { workflow.triggers[selectedTriggerIndex].parameters[1] = {"name": "argument", "value": ""} workflow.triggers[selectedTriggerIndex].parameters[2] = {"name": "user_apikey", "value": ""} workflow.triggers[selectedTriggerIndex].parameters[3] = {"name": "startnode", "value": ""} + workflow.triggers[selectedTriggerIndex].parameters[4] = {"name": "check_result", "value": "true"} console.log("SETTINGS: ", userSettings) if (userSettings !== undefined && userSettings !== null && userSettings.apikey !== null && userSettings.apikey !== undefined && userSettings.apikey.length > 0) { @@ -5453,7 +5958,7 @@ const AngularWorkflow = (props) => { } return( -
+

{selectedTrigger.app_name}

@@ -5465,7 +5970,7 @@ const AngularWorkflow = (props) => { Name
{ placeholder={selectedTrigger.label} onChange={selectedTriggerChange} /> + { + const newvalue = workflow.triggers[selectedTriggerIndex].parameters[4] === undefined || workflow.triggers[selectedTriggerIndex].parameters[4].value === "false" ? "true" : "false" + workflow.triggers[selectedTriggerIndex].parameters[4] = { + "name": "check_result", + "value": newvalue, + } + + setWorkflow(workflow) + setUpdate(Math.random()) + }} + color="primary" + value="Wait for results" + /> + } + style={{marginTop: 10}} + label={
Wait for results
} + />
@@ -5501,14 +6027,15 @@ const AngularWorkflow = (props) => { }} fullWidth onChange={(e) => { - setSubworkflow(e.target.value) setUpdate(Math.random()) workflow.triggers[selectedTriggerIndex].parameters[0].value = e.target.value.id - setWorkflow(workflow) setSubworkflowStartnode(e.target.value.start) // Sets the startnode if (e.target.value.id !== workflow.id) { + console.log("WORKFLOW: ", e.target.value) + + setSubworkflow(e.target.value) const startnode = e.target.value.actions.find(action => action.id === e.target.value.start) if (startnode !== undefined && startnode !== null) { //ddsetSubworkflowStartnode(innernode) @@ -5524,16 +6051,20 @@ const AngularWorkflow = (props) => { } } console.log("STARTNODE: ", startnode) + } else { + console.log("WORKFLOW: ", workflow) + setSubworkflow(e.target.value) } + + setWorkflow(workflow) }} - style={{backgroundColor: inputColor, color: "white", height: "50px"}} + style={{backgroundColor: inputColor, color: "white", height: 50}} > {workflows.map((data, index) => { - /* if (data.id === workflow.id) { - return null + //return null + data = workflow } - */ return ( @@ -5567,6 +6098,51 @@ const AngularWorkflow = (props) => { fullWidth onChange={(e) => { setSubworkflowStartnode(e.target.value) + //console.log("WF: ", workflow) + + const branchId = uuid.v4() + const newbranch = { + "source_id": workflow.triggers[selectedTriggerIndex].id, + "destination_id": e.target.value.id, + "source": workflow.triggers[selectedTriggerIndex].id, + "target": e.target.value.id, + "has_errors": false, + "id": branchId, + "_id": branchId, + "label": "Subflow", + "decorator": true, + } + + if (workflow.visual_branches !== undefined) { + if (workflow.visual_branches === null) { + workflow.visual_branches = [newbranch] + } else if (workflow.visual_branches.length === 0) { + workflow.visual_branches.push(newbranch) + } else { + const foundIndex = workflow.visual_branches.findIndex(branch => branch.source_id === newbranch.source_id) + if (foundIndex !== -1) { + const currentEdge = cy.getElementById(workflow.visual_branches[foundIndex].id) + if (currentEdge !== undefined && currentEdge !== null) { + currentEdge.remove() + } + } + + workflow.visual_branches.splice(foundIndex, 1) + workflow.visual_branches.push(newbranch) + } + } + + if (workflow.id == subworkflow.id) { + const cybranch = { + group: "edges", + source: newbranch.source_id, + target: newbranch.destination_id, + id: branchId, + data: newbranch, + } + + cy.add(cybranch) + } try { workflow.triggers[selectedTriggerIndex].parameters[3].value = e.target.value.id @@ -5580,12 +6156,12 @@ const AngularWorkflow = (props) => { setWorkflow(workflow) //setUpdate(Math.random()) }} - style={{backgroundColor: inputColor, color: "white", height: "50px"}} + style={{backgroundColor: inputColor, color: "white", height: 50}} > {subworkflow.actions.map((action, index) => { //console.log(action) return ( - parent.id === action.id)} key={index} style={{backgroundColor: inputColor, color: "white"}} value={action}> + parent.id === action.id) ? "red" : "white"}} value={action}> {action.label} ) @@ -5600,7 +6176,7 @@ const AngularWorkflow = (props) => {
{ top: event.pageY+10, left: event.pageX+10, }) - //setShowDropdownNumber(count) + //setShowDropdownNumber(3) setShowDropdown(true) setShowAutocomplete(true) }}/> @@ -5636,14 +6212,17 @@ const AngularWorkflow = (props) => { setWorkflow(workflow) }} /> + {showDropdown ? + + : null}
- API-key: + API-key
{ workflow.triggers[selectedTriggerIndex].parameters = [] workflow.triggers[selectedTriggerIndex].parameters[0] = {"name": "url", "value": referenceUrl+"webhook_"+selectedTrigger.id} workflow.triggers[selectedTriggerIndex].parameters[1] = {"name": "tmp", "value": "webhook_"+selectedTrigger.id} + workflow.triggers[selectedTriggerIndex].parameters[2] = {"name": "auth_headers", "value": ""} setWorkflow(workflow) } + + const trigger_header_auth = workflow.triggers[selectedTriggerIndex].parameters.length > 2 ? workflow.triggers[selectedTriggerIndex].parameters[2].value : "" //const cronValue = "*/15 * * * *" return( @@ -5698,7 +6280,7 @@ const AngularWorkflow = (props) => { Name
{ setWorkflow(workflow) setUpdate(Math.random()) }} - style={{backgroundColor: inputColor, color: "white", height: "50px"}} + style={{backgroundColor: inputColor, color: "white", height: 50}} > {triggerEnvironments.map(data => { if (data.archived) { @@ -5771,17 +6353,28 @@ const AngularWorkflow = (props) => {
{ - var copyText = document.getElementById("webhook_uri_field"); - navigator.clipboard.writeText(copyText.value) - copyText.select(); - copyText.setSelectionRange(0, 99999); /* For mobile devices */ + var copyText = document.getElementById("webhook_uri_field") + if (copyText !== undefined && copyText !== null) { + console.log("NAVIGATOR: ", navigator) + const clipboard = navigator.clipboard + if (clipboard === undefined) { + alert.error("Can only copy over HTTPS (port 3443)") + return + } - /* Copy the text inside the text field */ - document.execCommand("copy"); - alert.success("Copied Webhook URL") + navigator.clipboard.writeText(copyText.value) + copyText.select() + copyText.setSelectionRange(0, 99999) /* For mobile devices */ + + /* Copy the text inside the text field */ + document.execCommand("copy") + alert.success("Copied Webhook URL") + } else { + console.log("Couldn't find webhook URI field: ", copyText) + } }} InputProps={{ style:{ @@ -5801,18 +6394,56 @@ const AngularWorkflow = (props) => { setTriggerCronWrapper(e.target.value) }} /> +
+
+
+ Required headers +
+
+
+ {}} + InputProps={{ + style:{ + color: "white", + marginLeft: "5px", + maxWidth: "95%", + fontSize: "1em", + }, + }} + fullWidth + multiline + rows="4" + defaultValue={trigger_header_auth} + color="primary" + disabled={selectedTrigger.status === "running"} + placeholder={"AUTH_HEADER=AUTH_VALUE1"} + onBlur={(e) => { + const value = e.target.value + if (selectedTrigger.parameters === null) { + selectedTrigger.parameters = [] + } + + workflow.triggers[selectedTriggerIndex].parameters[2] = {"value": value, "name": "auth_headers"} + //setSelectedTrigger(workflow.triggers[selectedTr + setWorkflow(workflow) + }} + /> +
+ Start + + Stop +
@@ -5840,7 +6471,7 @@ const AngularWorkflow = (props) => { // }) // .catch(error => { // console.log(error.toString()) - // }); + // }) //} const stopMailSub = (trigger, triggerindex) => { @@ -5895,7 +6526,7 @@ const AngularWorkflow = (props) => { const item = splitItem[key] const curfolder = triggerFolders.find(a => a.displayName === item) if (curfolder === undefined) { - alert.error("Something went wrong with outlook folder "+item) + alert.error("Something went wrong with outlook folder: "+item) return } @@ -5967,6 +6598,14 @@ const AngularWorkflow = (props) => { startNode = branch.destination_id } + const param = trigger.parameters.find(param => param.name === "auth_headers") + console.log("PARAM: ", param) + var auth = "" + if (param !== undefined && param !== null) { + auth = param.value + } + + console.log("TRIG: ", trigger) const data = { "name": hookname, "type": "webhook", @@ -5974,6 +6613,7 @@ const AngularWorkflow = (props) => { "workflow": workflow.id, "start": startNode, "environment": trigger.environment, + "auth": auth, } fetch(globalUrl+"/api/v1/hooks/new", { @@ -6077,7 +6717,7 @@ const AngularWorkflow = (props) => { Name {
Environment: {
{ {workflow.triggers[selectedTriggerIndex].parameters[2] !== undefined && workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("email") ? { } {workflow.triggers[selectedTriggerIndex].parameters[2] !== undefined && workflow.triggers[selectedTriggerIndex].parameters[2].value.includes("sms") ? { Name { setWorkflow(workflow) setUpdate(Math.random()) }} - style={{backgroundColor: inputColor, color: "white", height: "50px"}} + style={{backgroundColor: inputColor, color: "white", height: 50}} > {triggerEnvironments.map(data => { if (data.archived) { @@ -6332,7 +6972,7 @@ const AngularWorkflow = (props) => { { { */ } - const TopCytoscapeBar = () => { + const TopCytoscapeBar = (props) => { return (
@@ -6468,7 +7108,7 @@ const AngularWorkflow = (props) => { } const FileMenu = () => { - const [newAnchor, setNewAnchor] = React.useState(null); + const [newAnchor, setNewAnchor] = React.useState(null) const [showShuffleMenu, setShowShuffleMenu] = React.useState(false) { /*const [showShuffleMenu, setShowShuffleMenu] = React.useState(true) */} @@ -6526,7 +7166,7 @@ const AngularWorkflow = (props) => { } const WorkflowMenu = () => { - const [newAnchor, setNewAnchor] = React.useState(null); + const [newAnchor, setNewAnchor] = React.useState(null) const [showShuffleMenu, setShowShuffleMenu] = React.useState(false) { /*const [showShuffleMenu, setShowShuffleMenu] = React.useState(true) */} @@ -6583,8 +7223,42 @@ const AngularWorkflow = (props) => { ) } + const handleHistoryUndo = () => { + console.log("history: ", history, "index: ", historyIndex) + var item = history[historyIndex-1] + if (historyIndex === 0) { + item = history[historyIndex] + } + + if (item === undefined) { + console.log("Couldn't find the action you're looking for") + return + } + + console.log("HANDLE: ", item) + if (item.type === "node" && item.action === "removed") { + // Re-add the node + + cy.add({ + group: 'nodes', + data: item.data, + position: item.data.position, + }) + } else if (item.action === "added") { + console.log("Should remove item!") + const currentitem = cy.getElementById(item.data.id) + if (currentitem !== undefined && currentitem !== null) { + currentitem.remove() + } + } + + if (historyIndex > 0) { + setHistoryIndex(historyIndex-1) + } + } + const BottomCytoscapeBar = () => { - const [anchorEl, setAnchorEl] = React.useState(null); + const [anchorEl, setAnchorEl] = React.useState(null) const boxSize = 100 const executionButton = executionRunning ? @@ -6612,29 +7286,53 @@ const AngularWorkflow = (props) => {
{executionButton}
- - { - setExecutionText(e.target.value) - }} - /> - + {workflow.public ? null : + + { + setExecutionText(e.target.value) + }} + /> + + } - + {workflow.public ? + + + + + + : null} - + + + + + + - - - {workflow.public ? - - - - - - : null} + {/* */} {workflow.configuration !== null && workflow.configuration !== undefined && workflow.configuration.exit_on_error !== undefined ? : null}
@@ -6690,18 +7375,58 @@ const AngularWorkflow = (props) => { ) } - const RightSideBar = () => { + const RightSideBar = (props) => { + const {workflow, setWorkflow, setAction, setSelectedAction, setUpdate, appActionArguments, selectedApp, workflowExecutions, setSelectedResult, selectedAction, setSelectedApp, setSelectedTrigger, setSelectedEdge, setCurrentView, cy, setAuthenticationModalOpen,setVariablesModalOpen, setCodeModalOpen, selectedNameChange, rightsidebarStyle, showEnvironment, selectedActionEnvironment, environments, setNewSelectedAction, appApiViewStyle, globalUrl, setSelectedActionEnvironment, requiresAuthentication, hideExtraTypes, scrollConfig, setScrollConfig } = props + if (!rightSideBarOpen) { return null } if (Object.getOwnPropertyNames(selectedAction).length > 0) { - //console.time('ACTIONSTART') - return( -
- {appApiView} + if (Object.getOwnPropertyNames(selectedAction).length === 0) { + return null + } + + return ( +
+
) + } else if (Object.getOwnPropertyNames(selectedTrigger).length > 0) { if (selectedTrigger.trigger_type === "SCHEDULE") { //console.log("SCHEDULE") @@ -6811,6 +7536,9 @@ const AngularWorkflow = (props) => { theme="solarized" collapsed={true} displayDataTypes={false} + enableClipboard={(copy) => { + handleReactJsonClipboard(copy) + }} onSelect={(select) => { HandleJsonCopy(showResult, select, "exec") console.log("SELECTED!: ", select) @@ -6858,10 +7586,45 @@ const AngularWorkflow = (props) => { ) } + const handleReactJsonClipboard = (copy) => { + console.log("COPY: ", copy) + + const elementName = "copy_element_shuffle" + var copyText = document.getElementById(elementName); + if (copyText !== null && copyText !== undefined) { + if (copy.namespace !== undefined && copy.name !== undefined && copy.src !== undefined) { + copy = copy.src + } + + console.log("NEW: ", copy) + console.log("NAVIGATOR: ", navigator) + + const clipboard = navigator.clipboard + if (clipboard === undefined) { + alert.error("Can only copy over HTTPS (port 3443)") + return + } + + navigator.clipboard.writeText(JSON.stringify(copy)) + copyText.select() + copyText.setSelectionRange(0, 99999) /* For mobile devices */ + + /* Copy the text inside the text field */ + document.execCommand("copy") + //alert.success("Copied data") + } else { + console.log("Failed to copy from "+elementName+": ", copyText) + } + } + const HandleJsonCopy = (base, copy, base_node_name) => { + if (typeof(copy.name) === "string") { + copy.name = copy.name.replaceAll(" ", "_") + } + console.log("COPY: ", copy) var newitem = JSON.parse(base) - to_be_copied = "$"+base_node_name + to_be_copied = "$"+base_node_name.toLowerCase().replaceAll(" ", "_") for (var key in copy.namespace) { if (copy.namespace[key].includes("Results for")) { continue @@ -6893,15 +7656,22 @@ const AngularWorkflow = (props) => { to_be_copied.replaceAll(" ", "_") const elementName = "copy_element_shuffle" - var copyText = document.getElementById(elementName); + var copyText = document.getElementById(elementName) if (copyText !== null && copyText !== undefined) { + console.log("NAVIGATOR: ", navigator) + const clipboard = navigator.clipboard + if (clipboard === undefined) { + alert.error("Can only copy over HTTPS (port 3443)") + return + } + navigator.clipboard.writeText(to_be_copied) - copyText.select(); + copyText.select() copyText.setSelectionRange(0, 99999); /* For mobile devices */ /* Copy the text inside the text field */ document.execCommand("copy"); - alert.success("Copied "+to_be_copied) + //alert.success("Copied "+to_be_copied) console.log("COPYING!") } else { console.log("Couldn't find element ", elementName) @@ -6938,7 +7708,7 @@ const AngularWorkflow = (props) => { const timestamp = new Date(data.started_at*1000).toISOString().split('.')[0].split("T").join(" ") - var calculatedResult = data.workflow.actions.length + var calculatedResult = data.workflow.actions !== undefined && data.workflow.actions !== null ? data.workflow.actions.length : 0 for (var key in data.workflow.triggers) { const trigger = data.workflow.triggers[key] if ((trigger.app_name === "User Input" && trigger.trigger_type === "USERINPUT") || (trigger.app_name === "Shuffle Workflow" && trigger.trigger_type === "SUBFLOW")) { @@ -7035,11 +7805,22 @@ const AngularWorkflow = (props) => { + {executionData.status === "EXECUTING" ? + + + + + + : null}
{executionData.status !== undefined && executionData.status.length > 0 ?
- Status   + Status    {executionData.status} @@ -7153,7 +7934,8 @@ const AngularWorkflow = (props) => { if (triggers.length > 2) { if (data.action.app_name === "shuffle-subflow") { - actionimg = {"Shuffle + const parsedImage = triggers[1].large_image + actionimg = {"Shuffle } if (data.action.app_name === "User Input") { @@ -7161,12 +7943,44 @@ const AngularWorkflow = (props) => { } } + if (data.action.app_name === "Shuffle Tools") { + //console.log("APP (TOOLS): ", data.action) + + const nodedata = cy.getElementById(data.action.id).data() + if (nodedata !== undefined && nodedata !== null && nodedata.fillstyle === "linear-gradient") { + //console.log("LINEAR :D") + var imgStyle = { + marginRight: 20, + width: imgsize, + height: imgsize, + border: `2px solid ${statusColor}`, + borderRadius: executionData.start === data.action.id ? 25 : 5, + background: `linear-gradient(to right, ${nodedata.fillGradient})` + } + + //console.log("STYLE: ", imgStyle) + + actionimg = {nodedata.label} + } + } + + if (validate.valid && typeof(validate.result) === "string") { validate.result = JSON.parse(validate.result) + } + + if (validate.valid && typeof(validate.result) === "object") { + if (validate.result.result !== undefined && validate.result.result !== null) { + try { + validate.result.result = JSON.parse(validate.result.result) + } catch (e) { + //console.log("ERROR PARSING: ", e) + } + } } return ( -
{ +
{ var currentnode = cy.getElementById(data.action.id) if (currentnode.length !== 0) { currentnode.addClass('shuffle-hover-highlight') @@ -7177,46 +7991,28 @@ const AngularWorkflow = (props) => { currentnode.removeClass('shuffle-hover-highlight') } }}> -
- { - setSelectedResult(data) - setCodeModalOpen(true) - }}> - - - - - {actionimg} -
-
{data.action.label}
-
- - {data.action.name} - +
+
+ { + setSelectedResult(data) + setCodeModalOpen(true) + }}> + + + + + {actionimg} +
+
{data.action.label}
+
+ + {data.action.name} + +
-
-
- - Status   - - - {data.status} - -
- {validate.valid ? { - HandleJsonCopy(showResult, select, data.action.label) - console.log("SELECTED!: ", select) - }} - name={"Results for "+data.action.label} - /> {data.action.app_name === "shuffle-subflow" && validate.result.success !== undefined && validate.result.success === true ? - + {validate.valid && data.action.parameters !== undefined && data.action.parameters !== null ? data.action.parameters[0].value === props.match.params.key ? { @@ -7226,13 +8022,39 @@ const AngularWorkflow = (props) => { : { - }}>See subflow execution + }}> + + : "TBD: Load subexecution result for" } : null } +
+
+ + Status  + + + {data.status} + +
+ {validate.valid ? + { + handleReactJsonClipboard(copy) + }} + displayDataTypes={false} + onSelect={(select) => { + HandleJsonCopy(showResult, select, data.action.label) + console.log("SELECTED!: ", select) + }} + name={"Results for "+data.action.label} + /> :
@@ -7392,8 +8214,11 @@ const AngularWorkflow = (props) => { {validate.valid ? { + handleReactJsonClipboard(copy) + }} onSelect={(select) => { HandleJsonCopy(JSON.stringify(validate.result), select, selectedResult.action.label) }} @@ -7409,13 +8234,21 @@ const AngularWorkflow = (props) => { console.log("PRECOPY: ", to_be_copied) if (copyText !== null && copyText !== undefined) { console.log("COPY: ", copyText) + console.log("NAVIGATOR: ", navigator) + const clipboard = navigator.clipboard + if (clipboard === undefined) { + alert.error("Can only copy over HTTPS (port 3443)") + return + } + navigator.clipboard.writeText(to_be_copied) + copyText.select(); copyText.setSelectionRange(0, 99999); /* For mobile devices */ /* Copy the text inside the text field */ document.execCommand("copy"); - alert.success("Copied "+to_be_copied) + //alert.success("Copied "+to_be_copied) } else { console.log("Failed to copy. copy_element_shuffle is undefined") } @@ -7426,7 +8259,7 @@ const AngularWorkflow = (props) => { - const newView = //isLoggedIn ? + const newView =
{leftView} @@ -7439,6 +8272,7 @@ const AngularWorkflow = (props) => { boxSelectionEnabled={true} autounselectify={false} showGrid={true} + id="cytoscape_view" cy={(incy) => { // FIXME: There's something specific loading when // you do the first hover of a node. Why is this different? @@ -7448,7 +8282,40 @@ const AngularWorkflow = (props) => { />
{executionModal} - +
@@ -7460,6 +8327,7 @@ const AngularWorkflow = (props) => {
*/ + const executionVariableModal = executionVariablesModalOpen ? { //return } + // Automatically mapping fields that already exist (predefined). + // Warning if fields are NOT filled for (var key in selectedApp.authentication.parameters) { if (authenticationOption.fields[selectedApp.authentication.parameters[key].name].length === 0) { - alert.info("Field "+selectedApp.authentication.parameters[key].name+" can't be empty") - return + if (selectedApp.authentication.parameters[key].value !== undefined && selectedApp.authentication.parameters[key].value !== null && selectedApp.authentication.parameters[key].value.length > 0) { + authenticationOption.fields[selectedApp.authentication.parameters[key].name] = selectedApp.authentication.parameters[key].value + } else { + alert.info("Field "+selectedApp.authentication.parameters[key].name+" can't be empty") + return + } } } + console.log("Action: ", selectedAction) selectedAction.authentication_id = authenticationOption.id selectedAction.selectedAuthentication = authenticationOption - selectedAction.authentication.push(authenticationOption) + if (selectedAction.authentication === undefined || selectedAction.authentication === null) { + selectedAction.authentication = [authenticationOption] + } else { + selectedAction.authentication.push(authenticationOption) + } + setSelectedAction(selectedAction) var newAuthOption = JSON.parse(JSON.stringify(authenticationOption)) @@ -7736,6 +8616,12 @@ const AngularWorkflow = (props) => { setNewAppAuth(newAuthOption) //appAuthentication.push(newAuthOption) //setAppAuthentication(appAuthentication) + // + + if (configureWorkflowModalOpen) { + setSelectedAction({}) + } + setUpdate(authenticationOption.id) /* @@ -7757,7 +8643,7 @@ const AngularWorkflow = (props) => {
Name - what is this used for? { authenticationOption.label = event.target.value }} /> - {selectedApp.link.length > 0 ?
: null} + {/*selectedApp.link.length > 0 ?
: null*/}
{selectedApp.authentication.parameters.map((data, index) => { - return ( -
- - {data.name} - { - authenticationOption.fields[data.name] = event.target.value - }} - /> -
- ) - })} + //console.log("AUTH: ", data) + + return ( +
+ + {data.name} + + {data.schema !== undefined && data.schema !== null && data.schema.type === "bool" ? + + : + { + authenticationOption.fields[data.name] = event.target.value + }} + /> + } +
+ ) + })}
: null @@ -7918,14 +8848,54 @@ const AngularWorkflow = (props) => {
+ // Awful way of handling scroll + if (scrollConfig !== undefined && setScrollConfig !== undefined && Object.getOwnPropertyNames(selectedAction).length !== 0) { + //console.log("SET CONFIG: ", scrollConfig) + const rightSideActionView = document.getElementById("rightside_actions") + if (rightSideActionView !== undefined && rightSideActionView !== null) { + //console.log("FOUND RIGHTSIDE: ", rightSideActionView.scrollTop, scrollConfig) + if (scrollConfig.top !== 0 && scrollConfig.top !== undefined && scrollConfig.top !== 0) { + //console.log("SCROLL IS NOT 0: ", scrollConfig.top) + //rightSideActionView.scrollTop = scrollConfig.top + setTimeout(() => { + scroller.scrollTo('elements_wrapper', { + containerId: 'rightside_actions', + offset: scrollConfig.top, + }) + + if (scrollConfig.selected !== undefined && scrollConfig.selected !== null) { + const selectedField = document.getElementById(scrollConfig.selected) + if (selectedField !== undefined && selectedField !== null) { + selectedField.focus() + //const val = selectedField.value + //console.log("VAL: ", val) + //selectedField.value = '' + //selectedField.value = val + } + } + }, 5) + } else { + //console.log("SCROLL IS 0: ", scrollConfig.top, rightSideActionView.scrollTop) + if (rightSideActionView.scrollTop !== scrollConfig.top) { + setScrollConfig({ + top: rightSideActionView.scrollTop, + left: 0, + selected: "", + }) + } + } + } + } return (
- - {loadedCheck} + + + {loadedCheck} +
) } diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx index bbf85301..24006b3a 100644 --- a/frontend/src/views/AppCreator.jsx +++ b/frontend/src/views/AppCreator.jsx @@ -1,11 +1,12 @@ import React, {useState, useEffect} from 'react'; import { makeStyles } from '@material-ui/styles'; +import { useTheme } from '@material-ui/core/styles'; import {BrowserView, MobileView} from "react-device-detect"; import {Paper, Typography, FormControlLabel, Button, Divider, Select, MenuItem, FormControl, Switch, Dialog, DialogTitle, DialogContent, DialogActions, TextField, Tooltip, Breadcrumbs, CircularProgress, Chip} from '@material-ui/core'; -import {CheckCircle as CheckCircleIcon, AttachFile as AttachFileIcon, Apps as AppsIcon, ErrorOutline as ErrorOutlineIcon} from '@material-ui/icons'; - +import {LockOpen as LockOpenIcon, FileCopy as FileCopyIcon, Delete as DeleteIcon, Remove as RemoveIcon, Add as AddIcon, CheckCircle as CheckCircleIcon, AttachFile as AttachFileIcon, Apps as AppsIcon, ErrorOutline as ErrorOutlineIcon} from '@material-ui/icons'; +import uuid from "uuid"; import {Link} from 'react-router-dom'; import YAML from 'yaml' import ChipInput from 'material-ui-chip-input' @@ -193,12 +194,14 @@ const AppCreator = (props) => { const { globalUrl, isLoaded } = props; const classes = useStyles(); const alert = useAlert() + const theme = useTheme(); var upload = "" const increaseAmount = 50 const actionNonBodyRequest = ["GET", "HEAD", "DELETE", "CONNECT"] const actionBodyRequest = ["POST", "PUT", "PATCH",] - const authenticationOptions = ["No authentication", "API key", "Bearer auth", "Basic auth", ] + //const authenticationOptions = ["No authentication", "API key", "Bearer auth", "Basic auth", "JWT", "Oauth2"] + const authenticationOptions = ["No authentication", "API key", "Bearer auth", "Basic auth"] const apikeySelection = ["Header", "Query",] const [name, setName] = useState(""); @@ -230,6 +233,18 @@ const AppCreator = (props) => { const [extraBodyFields, setExtraBodyFields] = useState([]) const [fileUploadEnabled, setFileUploadEnabled] = useState(false) const [actionAmount, setActionAmount] = useState(increaseAmount) + const defaultAuth = { + "name": "", + "type": "header", + "example": "", + } + const [extraAuth, setExtraAuth] = useState([]) + + + const [app, setApp] = useState({}) + const [appAuthentication, setAppAuthentication] = React.useState([]); + const [selectedAction, setSelectedAction] = useState({}) + const [authLoaded, setAuthLoaded] = useState(false) //const [actions, setActions] = useState([{ // "name": "Get workflows", @@ -301,12 +316,12 @@ const AppCreator = (props) => { return response.json() }) .then((responseJson) => { - if (!responseJson.success) { + if (responseJson.success === false) { alert.error("Failed to get the app") setIsAppLoaded(true) + window.location.pathname = "/search" } else { - const data = JSON.parse(responseJson.body) - parseIncomingOpenapiData(data) + parseIncomingOpenapiData(responseJson) } }) .catch(error => { @@ -338,7 +353,6 @@ const AppCreator = (props) => { throw new Error("NOT 200 :O") } - //console.log("DATA: ", response.text()) return response.json() }) .then((responseJson) => { @@ -346,27 +360,8 @@ const AppCreator = (props) => { if (!responseJson.success) { alert.error("Failed to verify") } else{ - var jsonvalid = false - var tmpvalue = "" - try { - tmpvalue = JSON.parse(responseJson.body) - jsonvalid = true - } catch (e) { - console.log("Error JSON: ", e) - } - - if (!jsonvalid) { - try { - tmpvalue = YAML.parse(responseJson.body, ) - jsonvalid = true - } catch(e) { - console.log("Error YAML: ", e) - } - } - - if (jsonvalid) { - parseIncomingOpenapiData(tmpvalue) - } + parseIncomingOpenapiData(responseJson) + } }) .catch(error => { @@ -391,7 +386,13 @@ const AppCreator = (props) => { const handleGetRef = (parameter, data) => { - if (parameter["$ref"] === undefined) { + try { + if (parameter === null || parameter["$ref"] === undefined) { + console.log("$ref not found in getref: ") + return parameter + } + } catch (e) { + console.log("Failed getting $ref of ", parameter) return parameter } @@ -427,11 +428,42 @@ const AppCreator = (props) => { // Sets the data up as it should be at later points // This is the data FROM the database, not what's being saved const parseIncomingOpenapiData = (data) => { - //console.log("DATA: ", data.info) - setBasedata(data) + const parsedapp = data.openapi === undefined ? data : JSON.parse(atob(data.openapi)) + data = parsedapp.body === undefined ? parsedapp : parsedapp.body + var jsonvalid = false + var tmpvalue = "" + try { + data = JSON.parse(data) + jsonvalid = true + } catch (e) { + console.log("Error JSON: ", e) + } + + if (!jsonvalid) { + try { + data = YAML.parse(data) + jsonvalid = true + } catch(e) { + console.log("Error YAML: ", e) + } + } + + if (!jsonvalid) { + alert.info("OpenAPI data is invalid.") + return + } + + setBasedata(data) if (data.info !== null && data.info !== undefined) { - setName(data.info.title) + if (data.info.title !== undefined && data.info.title !== null) { + if (data.info.title.length > 29) { + setName(data.info.title.slice(0, 29)) + } else { + setName(data.info.title) + } + } + setDescription(data.info.description) document.title = "Apps - "+data.info.title @@ -490,209 +522,353 @@ const AppCreator = (props) => { "PUT", ] - // FIXME - headers? var newActions = [] var wordlist = {} - for (let [path, pathvalue] of Object.entries(data.paths)) { - for (let [method, methodvalue] of Object.entries(pathvalue)) { - if (methodvalue === null) { - alert.info("Skipped method (null)"+method) - continue - } + if (data.paths !== null && data.paths !== undefined) { + for (let [path, pathvalue] of Object.entries(data.paths)) { + for (let [method, methodvalue] of Object.entries(pathvalue)) { + if (methodvalue === null) { + alert.info("Skipped method (null)"+method) + continue + } - if (!allowedfunctions.includes(method.toUpperCase())) { - alert.info("Skipped method (not allowed) "+method) - continue - } + if (!allowedfunctions.includes(method.toUpperCase())) { + console.log("Invalid method: ", method, "data: ", methodvalue) + alert.info("Skipped method (not allowed): "+method) + continue + } - var tmpname = methodvalue.summary - if (methodvalue.operationId !== undefined && methodvalue.operationId !== null && methodvalue.operationId.length > 0 && (tmpname === undefined || tmpname.length === 0)) { - tmpname = methodvalue.operationId - } + var tmpname = methodvalue.summary + if (methodvalue.operationId !== undefined && methodvalue.operationId !== null && methodvalue.operationId.length > 0 && (tmpname === undefined || tmpname.length === 0)) { + tmpname = methodvalue.operationId + } - var newaction = { - "name": tmpname, - "description": methodvalue.description, - "url": path, - "file_field": "", - "method": method.toUpperCase(), - "headers": "", - "queries": [], - "paths": [], - "body": "", - "errors": [], - "example_response": "", - } + var newaction = { + "name": tmpname, + "description": methodvalue.description, + "url": path, + "file_field": "", + "method": method.toUpperCase(), + "headers": "", + "queries": [], + "paths": [], + "body": "", + "errors": [], + "example_response": "", + } - if (methodvalue["requestBody"] !== undefined) { - //console.log("Handle requestbody: ", methodvalue["requestBody"]) - if (methodvalue["requestBody"]["content"] !== undefined) { - if (methodvalue["requestBody"]["content"]["application/json"] !== undefined) { - if (methodvalue["requestBody"]["content"]["application/json"]["schema"] !== undefined && methodvalue["requestBody"]["content"]["application/json"]["schema"] !== null) { - if (methodvalue["requestBody"]["content"]["application/json"]["schema"]["properties"] !== undefined) { - var tmpobject = {} - for (let [prop, propvalue] of Object.entries(methodvalue["requestBody"]["content"]["application/json"]["schema"]["properties"])) { - tmpobject[prop] = `\$\{${prop}\}` + //console.log("Schema is application/json: ", methodvalue) + //console.log("DATA", data) + if (methodvalue["requestBody"] !== undefined) { + //console.log("Handle requestbody: ", methodvalue["requestBody"]) + if (methodvalue["requestBody"]["content"] !== undefined) { + if (methodvalue["requestBody"]["content"]["application/json"] !== undefined) { + newaction["headers"] = "Content-Type=application/json\nAccept=application/json" + if (methodvalue["requestBody"]["content"]["application/json"]["schema"] !== undefined && methodvalue["requestBody"]["content"]["application/json"]["schema"] !== null) { + if (methodvalue["requestBody"]["content"]["application/json"]["schema"]["properties"] !== undefined) { + var tmpobject = {} + for (let [prop, propvalue] of Object.entries(methodvalue["requestBody"]["content"]["application/json"]["schema"]["properties"])) { + tmpobject[prop] = `\$\{${prop}\}` + } + + //console.log("Data: ", data) + for (var subkey in methodvalue["requestBody"]["content"]["application/json"]["schema"]["required"]) { + const tmpitem = methodvalue["requestBody"]["content"]["application/json"]["schema"]["required"][subkey] + tmpobject[tmpitem] = `\$\{${tmpitem}\}` + } + + newaction["body"] = JSON.stringify(tmpobject, null, 2) + } else if (methodvalue["requestBody"]["content"]["application/json"]["schema"]["$ref"] !== undefined && methodvalue["requestBody"]["content"]["application/json"]["schema"]["$ref"] !== null) { + const retRef = handleGetRef(methodvalue["requestBody"]["content"]["application/json"]["schema"], data) + var newbody = {} + // Can handle default, required, description and type + for (var propkey in retRef.properties) { + const parsedkey = propkey.replaceAll(" ", "_").toLowerCase() + newbody[parsedkey] = "${"+parsedkey+"}" + } + + newaction["body"] = JSON.stringify(newbody, null, 2) } - - for (var subkey in methodvalue["requestBody"]["content"]["application/json"]["schema"]["required"]) { - const tmpitem = methodvalue["requestBody"]["content"]["application/json"]["schema"]["required"][subkey] - tmpobject[tmpitem] = `\$\{${tmpitem}\}` - } - - newaction["body"] = JSON.stringify(tmpobject, null, 2) } - } - } else if (methodvalue["requestBody"]["content"]["application/xml"] !== undefined) { - console.log("METHOD XML: ", methodvalue) - if (methodvalue["requestBody"]["content"]["application/xml"]["schema"] !== undefined && methodvalue["requestBody"]["content"]["application/xml"]["schema"] !== null) { - if (methodvalue["requestBody"]["content"]["application/xml"]["schema"]["properties"] !== undefined) { - var tmpobject = {} - for (let [prop, propvalue] of Object.entries(methodvalue["requestBody"]["content"]["application/xml"]["schema"]["properties"])) { - tmpobject[prop] = `\$\{${prop}\}` + } else if (methodvalue["requestBody"]["content"]["application/xml"] !== undefined) { + console.log("METHOD XML: ", methodvalue) + newaction["headers"] = "Content-Type=application/xml\nAccept=application/xml" + if (methodvalue["requestBody"]["content"]["application/xml"]["schema"] !== undefined && methodvalue["requestBody"]["content"]["application/xml"]["schema"] !== null) { + if (methodvalue["requestBody"]["content"]["application/xml"]["schema"]["properties"] !== undefined) { + var tmpobject = {} + for (let [prop, propvalue] of Object.entries(methodvalue["requestBody"]["content"]["application/xml"]["schema"]["properties"])) { + tmpobject[prop] = `\$\{${prop}\}` + } + + for (var subkey in methodvalue["requestBody"]["content"]["application/xml"]["schema"]["required"]) { + const tmpitem = methodvalue["requestBody"]["content"]["application/xml"]["schema"]["required"][subkey] + tmpobject[tmpitem] = `\$\{${tmpitem}\}` + } + + //console.log("OBJ XML: ", tmpobject) + //newaction["body"] = XML.stringify(tmpobject, null, 2) } - - for (var subkey in methodvalue["requestBody"]["content"]["application/xml"]["schema"]["required"]) { - const tmpitem = methodvalue["requestBody"]["content"]["application/xml"]["schema"]["required"][subkey] - tmpobject[tmpitem] = `\$\{${tmpitem}\}` + } + } else { + if (methodvalue["requestBody"]["content"]["example"] !== undefined) { + if (methodvalue["requestBody"]["content"]["example"]["example"] !== undefined) { + newaction["body"] = methodvalue["requestBody"]["content"]["example"]["example"] + //JSON.stringify(tmpobject, null, 2) } - - //console.log("OBJ XML: ", tmpobject) - //newaction["body"] = XML.stringify(tmpobject, null, 2) } - } - } else { - if (methodvalue["requestBody"]["content"]["example"] !== undefined) { - if (methodvalue["requestBody"]["content"]["example"]["example"] !== undefined) { - newaction["body"] = methodvalue["requestBody"]["content"]["example"]["example"] - //JSON.stringify(tmpobject, null, 2) - } - } - //console.log(methodvalue["requestBody"]["content"]) - if (methodvalue["requestBody"]["content"]["multipart/form-data"] !== undefined) { - if (methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"] !== undefined && methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"] !== null) { - if (methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"]["type"] === "object") { - const fieldname = methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"]["properties"]["fieldname"] - if (fieldname !== undefined) { - console.log("FIELDNAME: ", fieldname) - newaction.file_field = fieldname["value"] + //console.log(methodvalue["requestBody"]["content"]) + if (methodvalue["requestBody"]["content"]["multipart/form-data"] !== undefined) { + if (methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"] !== undefined && methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"] !== null) { + if (methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"]["type"] === "object") { + const fieldname = methodvalue["requestBody"]["content"]["multipart/form-data"]["schema"]["properties"]["fieldname"] + if (fieldname !== undefined) { + console.log("FIELDNAME: ", fieldname) + newaction.file_field = fieldname["value"] + } } } } } } } - } - // HAHAHA wtf is this. - if (methodvalue.responses !== undefined && methodvalue.responses !== null) { - if (methodvalue.responses.default !== undefined) { - if (methodvalue.responses.default.content !== undefined) { - if (methodvalue.responses.default.content["text/plain"] !== undefined) { - if (methodvalue.responses.default.content["text/plain"]["schema"] !== undefined) { - if (methodvalue.responses.default.content["text/plain"]["schema"]["example"] !== undefined) { - newaction.example_response = methodvalue.responses.default.content["text/plain"]["schema"]["example"] + // HAHAHA wtf is this. + if (methodvalue.responses !== undefined && methodvalue.responses !== null) { + if (methodvalue.responses.default !== undefined) { + if (methodvalue.responses.default.content !== undefined) { + if (methodvalue.responses.default.content["text/plain"] !== undefined) { + if (methodvalue.responses.default.content["text/plain"]["schema"] !== undefined) { + if (methodvalue.responses.default.content["text/plain"]["schema"]["example"] !== undefined) { + newaction.example_response = methodvalue.responses.default.content["text/plain"]["schema"]["example"] + } + } + } + } + } else { + var selectedReturn = "" + if (methodvalue.responses["200"] !== undefined) { + selectedReturn = "200" + } else if (methodvalue.responses["201"] !== undefined) { + selectedReturn = "201" + } + + // Parsing examples. This should be standardized lol + if (methodvalue.responses[selectedReturn] !== undefined) { + const selectedExample = methodvalue.responses[selectedReturn] + if (selectedExample["content"] !== undefined) { + if (selectedExample["content"]["application/json"] !== undefined) { + if (selectedExample["content"]["application/json"]["schema"] !== undefined && selectedExample["content"]["application/json"]["schema"] !== null) { + if (selectedExample["content"]["application/json"]["schema"]["$ref"] !== undefined) { + //console.log("REF EXAMPLE: ", selectedExample["content"]["application/json"]["schema"]) + const parameter = handleGetRef(selectedExample["content"]["application/json"]["schema"], data) + //console.log("GOT REF RETURN AS EXAMPLE: ", parameter) + + if (parameter.properties !== undefined && parameter["type"] === "object") { + var newbody = {} + for (var propkey in parameter.properties) { + const parsedkey = propkey.replaceAll(" ", "_").toLowerCase() + if (parameter.properties[propkey].type === undefined) { + console.log("Skipping: ", parameter.properties[propkey]) + continue + } + + if (parameter.properties[propkey].type === "string") { + if (parameter.properties[propkey].description !== undefined) { + newbody[parsedkey] = parameter.properties[propkey].description + } else { + newbody[parsedkey] = "" + } + } else if (parameter.properties[propkey].type.includes("int")) { + newbody[parsedkey] = 0 + } else { + console.log("CANT HANDLE JSON TYPE ", parameter.properties[propkey].type, parameter.properties[propkey]) + newbody[parsedkey] = [] + } + } + newaction.example_response = JSON.stringify(newbody, null, 2) + } else { + console.log("CANT HANDLE PARAM: (1) ", parameter.properties) + } + } else { + // Just selecting the first one. bleh. + if (selectedExample["content"]["application/json"]["schema"]["allOf"] !== undefined) { + //console.log("ALLOF: ", selectedExample["content"]["application/json"]["schema"]["allOf"]) + //console.log("BAD EXAMPLE: (SKIP ALLOF) ", selectedExample["content"]["application/json"]["schema"]["allOf"]) + var selectedComponent = selectedExample["content"]["application/json"]["schema"]["allOf"] + if (selectedComponent.length >= 1) { + selectedComponent = selectedComponent[0] + + const parameter = handleGetRef(selectedComponent, data) + if (parameter.properties !== undefined && parameter["type"] === "object") { + var newbody = {} + for (var propkey in parameter.properties) { + const parsedkey = propkey.replaceAll(" ", "_").toLowerCase() + if (parameter.properties[propkey].type === undefined) { + console.log("Skipping: ", parameter.properties[propkey]) + continue + } + + if (parameter.properties[propkey].type === "string") { + if (parameter.properties[propkey].description !== undefined) { + newbody[parsedkey] = parameter.properties[propkey].description + } else { + newbody[parsedkey] = "" + } + } else if (parameter.properties[propkey].type.includes("int")) { + newbody[parsedkey] = 0 + } else { + console.log("CANT HANDLE JSON TYPE (2) ", parameter.properties[propkey].type) + newbody[parsedkey] = [] + } + } + + newaction.example_response = JSON.stringify(newbody, null, 2) + //newaction.example_response = JSON.stringify(parameter.properties, null, 2) + } else { + //newaction.example_response = parameter.properties + console.log("CANT HANDLE PARAM: (3) ", parameter.properties) + } + } else { + + } + } else if (selectedExample["content"]["application/json"]["schema"]["properties"] !== undefined) { + if (selectedExample["content"]["application/json"]["schema"]["properties"]["data"] !== undefined) { + const parameter = handleGetRef(selectedExample["content"]["application/json"]["schema"]["properties"]["data"], data) + if (parameter.properties !== undefined && parameter["type"] === "object") { + var newbody = {} + for (var propkey in parameter.properties) { + const parsedkey = propkey.replaceAll(" ", "_").toLowerCase() + if (parameter.properties[propkey].type === undefined) { + console.log("Skipping: ", parameter.properties[propkey]) + continue + } + + if (parameter.properties[propkey].type === "string") { + if (parameter.properties[propkey].description !== undefined) { + newbody[parsedkey] = parameter.properties[propkey].description + } else { + newbody[parsedkey] = "" + } + console.log(parameter.properties[propkey]) + } else if (parameter.properties[propkey].type.includes("int")) { + newbody[parsedkey] = 0 + } else { + console.log("CANT HANDLE JSON TYPE (3) ", parameter.properties[propkey].type) + newbody[parsedkey] = [] + } + } + + newaction.example_response = JSON.stringify(newbody, null, 2) + //newaction.example_response = JSON.stringify(parameter.properties, null, 2) + } else { + //newaction.example_response = parameter.properties + console.log("CANT HANDLE PARAM: (2) ", parameter.properties) + } + } + } + } + } } } } } } - } - for (var key in methodvalue.parameters) { - const parameter = handleGetRef(methodvalue.parameters[key], data) - if (parameter.in === "query") { - var tmpaction = { - "description": parameter.description, - "name": parameter.name, - "required": parameter.required, - "in": "query", + for (var key in methodvalue.parameters) { + const parameter = handleGetRef(methodvalue.parameters[key], data) + if (parameter.in === "query") { + var tmpaction = { + "description": parameter.description, + "name": parameter.name, + "required": parameter.required, + "in": "query", + } + + if (parameter.required === undefined) { + tmpaction.required = false + } + + newaction.queries.push(tmpaction) + } else if (parameter.in === "path") { + // FIXME - parse this to the URL too + newaction.paths.push(parameter.name) + + // FIXME: This doesn't follow OpenAPI3 exactly. + // https://swagger.io/docs/specification/describing-request-body/ + // https://swagger.io/docs/specification/describing-parameters/ + // Need to split the data. + } else if (parameter.in === "body") { + // FIXME: Add tracking for components + // E.G: https://raw.githubusercontent.com/owentl/Shuffle/master/gosecure.yaml + if (parameter.example !== undefined) { + newaction.body = parameter.example + } + } else if (parameter.in === "header") { + newaction.headers += `${parameter.name}=${parameter.example}\n` + } else { + console.log("WARNING: don't know how to handle this param: ", parameter) } - - if (parameter.required === undefined) { - tmpaction.required = false - } - - newaction.queries.push(tmpaction) - } else if (parameter.in === "path") { - // FIXME - parse this to the URL too - newaction.paths.push(parameter.name) - - // FIXME: This doesn't follow OpenAPI3 exactly. - // https://swagger.io/docs/specification/describing-request-body/ - // https://swagger.io/docs/specification/describing-parameters/ - // Need to split the data. - } else if (parameter.in === "body") { - // FIXME: Add tracking for components - // E.G: https://raw.githubusercontent.com/owentl/Shuffle/master/gosecure.yaml - if (parameter.example !== undefined) { - newaction.body = parameter.example - } - } else if (parameter.in === "header") { - newaction.headers += `${parameter.name}=${parameter.example}\n` - } else { - console.log("WARNING: don't know how to handle this param: ", parameter) } - } - if (newaction.name === "" || newaction.name === undefined) { - // Find a unique part of the string - // FIXME: Looks for length between /, find the one where they differ - // Should find others with the same START to their path - // Make a list of reserved names? Aka things that show up only once - if (Object.getOwnPropertyNames(wordlist).length === 0) { - for (let [newpath, pathvalue] of Object.entries(data.paths)) { - const newpathsplit = newpath.split("/") - for(var key in newpathsplit) { - const pathitem = newpathsplit[key].toLowerCase() - if (wordlist[pathitem] === undefined) { - wordlist[pathitem] = 1 - } else { - wordlist[pathitem] += 1 + if (newaction.name === "" || newaction.name === undefined) { + // Find a unique part of the string + // FIXME: Looks for length between /, find the one where they differ + // Should find others with the same START to their path + // Make a list of reserved names? Aka things that show up only once + if (Object.getOwnPropertyNames(wordlist).length === 0) { + for (let [newpath, pathvalue] of Object.entries(data.paths)) { + const newpathsplit = newpath.split("/") + for(var key in newpathsplit) { + const pathitem = newpathsplit[key].toLowerCase() + if (wordlist[pathitem] === undefined) { + wordlist[pathitem] = 1 + } else { + wordlist[pathitem] += 1 + } } } - } - } + } - //console.log("WORDLIST: ", wordlist) + //console.log("WORDLIST: ", wordlist) - // Remove underscores and make it normal with upper case etc - const urlsplit = path.split("/") - if (urlsplit.length > 0) { - var curname = "" - for(var key in urlsplit) { - var subpath = urlsplit[key] - if (wordlist[subpath] > 2 || subpath.length < 1) { - continue + // Remove underscores and make it normal with upper case etc + const urlsplit = path.split("/") + if (urlsplit.length > 0) { + var curname = "" + for(var key in urlsplit) { + var subpath = urlsplit[key] + if (wordlist[subpath] > 2 || subpath.length < 1) { + continue + } + + curname = subpath + break } - - curname = subpath - break - } - // FIXME: If name exists, - // FIXME: Check if first part of parsedname is verb, otherwise use method - const parsedname = curname.split("_").join(" ").split("-").join(" ").split("{").join(" ").split("}").join(" ").trim() - if (parsedname.length === 0) { - newaction.errors.push("Missing name") - } else { - const newname = method.charAt(0).toUpperCase() + method.slice(1) + " " + parsedname - const searchactions = newActions.find(data => data.name === newname) - console.log("SEARCH: ", searchactions) - if (searchactions !== undefined) { + // FIXME: If name exists, + // FIXME: Check if first part of parsedname is verb, otherwise use method + const parsedname = curname.split("_").join(" ").split("-").join(" ").split("{").join(" ").split("}").join(" ").trim() + if (parsedname.length === 0) { newaction.errors.push("Missing name") } else { - newaction.name = newname + const newname = method.charAt(0).toUpperCase() + method.slice(1) + " " + parsedname + const searchactions = newActions.find(data => data.name === newname) + console.log("SEARCH: ", searchactions) + if (searchactions !== undefined) { + newaction.errors.push("Missing name") + } else { + newaction.name = newname + } } - } - } else { - newaction.errors.push("Missing name") + } else { + newaction.errors.push("Missing name") + } } + newActions.push(newaction) } - newActions.push(newaction) } if (data.servers !== undefined && data.servers.length > 0) { @@ -720,15 +896,20 @@ const AppCreator = (props) => { } } - - // FIXME: Have multiple authentication options? + + console.log("SECURITYSCHEMES: ", securitySchemes) if (securitySchemes !== undefined) { + // FIXME: Should add Oauth2 (Microsoft) and JWT (Wazuh) + //console.log("SECURITY: ", securitySchemes) + //if (Object.entries(securitySchemes) > 1 && + var newauth = [] for (const [key, value] of Object.entries(securitySchemes)) { if (value.scheme === "bearer") { setAuthenticationOption("Bearer auth") setAuthenticationRequired(true) - break - } else if (value.type === "apiKey") { + } else if (key === "oauth2") { + alert.info("Can't handle Oauth2 auth yet.") + } else if (key === "ApiKeyAuth") { setAuthenticationOption("API key") value.in = value.in.charAt(0).toUpperCase() + value.in.slice(1); @@ -741,13 +922,24 @@ const AppCreator = (props) => { console.log("PARAM NAME: ", value.name) setParameterName(value.name) setAuthenticationRequired(true) - break } else if (value.scheme === "basic") { setAuthenticationOption("Basic auth") setAuthenticationRequired(true) - break + } else if (value.scheme === "oauth2") { + setAuthenticationOption("Oauth2") + setAuthenticationRequired(true) + } else { + newauth.push({ + "name": key, + "type": value.in, + "example": "", + }) } } + + if (newauth.length > 0) { + setExtraAuth(newauth) + } } if (newActions.length > increaseAmount-1) { @@ -778,7 +970,7 @@ const AppCreator = (props) => { const basePath = "/"+(splitBase.slice(3, )).join("/") const data = { - "swagger": "3.0", + "openapi": "3.0", "info": { "title": name, "description": description, @@ -1098,12 +1290,37 @@ const AppCreator = (props) => { "scheme": "bearer", "bearerFormat": "UUID", } - + } else if (authenticationOption === "JWT") { + data.components.securitySchemes["BearerAuth"] = { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + } } else if (authenticationOption === "Basic auth") { data.components.securitySchemes["BasicAuth"] = { "type": "http", "scheme": "basic", } + } else if (authenticationOption === "Oauth2") { + data.components.securitySchemes["Oauth2"] = { + "type": "oauth2", + "flow": { + "authorizationCode": { + + }, + }, + } + } + + if (setExtraAuth.length > 0) { + for (var key in extraAuth) { + const curauth = extraAuth[key] + data.components.securitySchemes[curauth.name] = { + "type": "apiKey", + "in": curauth.type, + "name": curauth.name, + } + } } fetch(globalUrl+"/api/v1/verify_openapi", { @@ -1112,7 +1329,7 @@ const AppCreator = (props) => { 'Content-Type': 'application/json', 'Accept': 'application/json', }, - body: JSON.stringify(data), + body: JSON.stringify(data, null, 4), credentials: "include", }) .then((response) => { @@ -1267,12 +1484,136 @@ const AppCreator = (props) => { //console.log("Option: ", authenticationOption) //console.log("Location: ", parameterLocation) //console.log("Name: ", parameterName) + const extraKeys = +
+
+ Extra configuration items + {extraAuth.length === 0 ? + + : } +
+ {extraAuth.map((value, index) => { + return ( + + { + extraAuth[index].name = e.target.value + setExtraAuth(extraAuth) + }} + InputProps={{ + classes: { + notchedOutline: classes.notchedOutline, + }, + style:{ + color: "white", + minHeight: 50, + marginLeft: 5, + maxWidth: "95%", + fontSize: "1em", + }, + }} + /> + { + extraAuth[index].example = e.target.value + setExtraAuth(extraAuth) + }} + InputProps={{ + style:{ + color: "white", + minHeight: 50, + marginLeft: 5, + maxWidth: "95%", + fontSize: "1em", + }, + }} + /> + +
+ {index === extraAuth.length-1 ? + + : } + +
+
+ ) + })} +
+ + const oauth2Auth = authenticationOption === "Oauth2" ? +
+ Oauth2 authentication + + Add the URL to redirect to + +
+ : null + const apiKey = authenticationOption === "API key" ? -
-

API key

+
+ API key authentication + + Add the name of the field used for authentication, e.g. "X-APIKEY" + { setParameterLocation(e.target.value) }} value={parameterLocation} - style={{backgroundColor: inputColor, paddingLeft: "10px", color: "white", height: "50px"}} + style={{borderRadius: 5, backgroundColor: inputColor, paddingLeft: "10px", color: "white", height: "50px"}} inputProps={{ name: 'age', id: 'outlined-age-simple', @@ -1435,12 +1776,12 @@ const AppCreator = (props) => {
{ duplicateAction(index) }}> - Duplicate +
{deleteAction(index)}}> - Delete +
@@ -1530,9 +1871,6 @@ const AppCreator = (props) => { } key={currentAction} InputProps={{ - classes: { - notchedOutline: classes.notchedOutline, - }, style:{ color: "white", }, @@ -1720,7 +2058,7 @@ const AppCreator = (props) => {
New action
- Learn more about actions + Learn more about actions
Name { defaultValue={currentAction["description"]} onChange={e => setActionField("description", e.target.value)} InputProps={{ - classes: { - notchedOutline: classes.notchedOutline, - }, style:{ color: "white", }, @@ -1853,7 +2188,7 @@ const AppCreator = (props) => { setUpdate(Math.random()) } else if (parsedurl.startsWith("curl")) { const request = parseCurl(event.target.value) - if (request !== event.target.value) { + if (request !== event.target.value && request.method !== undefined && request.method !== null) { if (request.method.toUpperCase() !== currentAction.Method) { setCurrentActionMethod(request.method.toUpperCase()) setActionField("method", request.method.toUpperCase()) @@ -1973,9 +2308,6 @@ const AppCreator = (props) => { onChange={e => setActionField("headers", e.target.value)} helperText={Headers that are part of the request. Default: EMPTY} InputProps={{ - classes: { - notchedOutline: classes.notchedOutline, - }, style:{ color: "white", }, @@ -2093,6 +2425,402 @@ const AppCreator = (props) => { />
+ const ParsedActionHandler = () => { + const passedOrg = {"id": "", "name": ""} + const owner = "" + const passedTags = ["single test"] + + const [, setUpdate] = useState() + const [authenticationModalOpen, setAuthenticationModalOpen] = useState(false); + const [selectedApp, setSelectedApp] = useState({ + versions: [{ + "id": selectedAction.app_id, + "version": selectedAction.app_version, + }], + loop_versions: [selectedAction.app_version], + id: selectedAction.app_id, + name: selectedAction.app_name, + version: selectedAction.app_version, + }) + + const [requiresAuthentication, setRequiresAuthentication] = useState(app.authentication !== null && app.authentication !== undefined && app.authentication.required && app.authentication.parameters !== undefined && app.authentication.parameters !== null ? true : false) + const [workflow, setWorkflow] = useState({ + name: "", + description: "", + actions: [selectedAction], + start: selectedAction.id, + tags: passedTags, + execution_org: passedOrg, + org_id: passedOrg.id, + id: uuid.v4(), + isValid: true, + owner: owner, + created: Date.now(), + }) + + const EndpointData = () => { + const [tmpVar, setTmpVar] = React.useState("") + + return ( +
+ The API endpoint to use (URL) - predefined in the app + { + setTmpVar(event.target.value) + }} + onBlur={() => { + selectedApp.link = tmpVar + console.log("LINK: ", selectedApp.link) + setSelectedApp(selectedApp) + }} + /> +
+ ) + } + + const setAppActionAuthentication = (newauth) => { + if (app.authentication.required) { + var findAuthId = "" + if (selectedAction.authentication_id !== null && selectedAction.authentication_id !== undefined && selectedAction.authentication_id.length > 0) { + findAuthId = selectedAction.authentication_id + } + + var baseAuthOptions = [] + for (var key in newauth) { + var item = newauth[key] + + const newfields = {} + for (var filterkey in item.fields) { + newfields[item.fields[filterkey].key] = item.fields[filterkey].value + } + + item.fields = newfields + if (item.app.name === app.name) { + baseAuthOptions.push(item) + + if (item.id === findAuthId) { + selectedAction.selectedAuthentication = item + } + } + } + + selectedAction.authentication = baseAuthOptions + //console.log("Authentication: ", authenticationOptions) + if (selectedAction.selectedAuthentication === null || selectedAction.selectedAuthentication === undefined || selectedAction.selectedAuthentication.length === "") { + selectedAction.selectedAuthentication = {} + } + } else { + selectedAction.authentication = [] + selectedAction.authentication_id = "" + selectedAction.selectedAuthentication = {} + } + + setSelectedAction(selectedAction) + console.log(selectedAction) + } + + //{selectedAction.authentication !== undefined && selectedAction.authentication.length > 0 ? + const getAppAuthentication = () => { + fetch(globalUrl+"/api/v1/apps/authentication", { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Status not 200 for apps :O!") + } + + return response.json() + }) + .then((responseJson) => { + if (responseJson.success && responseJson.data !== undefined && responseJson.data !== null && responseJson.data.length !== 0) { + var newauth = [] + for (var key in responseJson.data) { + if (responseJson.data[key].defined === false) { + continue + } + + newauth.push(responseJson.data[key]) + } + + setAppAuthentication(newauth) + setAppActionAuthentication(newauth) + } else { + if (app.authentication.required) { + const tmpParams = selectedAction.parameters + selectedAction.parameters = [] + + for (var paramkey in app.authentication.parameters) { + var item = app.authentication.parameters[paramkey] + item.configuration = true + + const found = selectedAction.parameters.find(param => param.name === item.name) + if (found === null || found === undefined) { + selectedAction.parameters.push(item) + } + } + + for (var paramkey in tmpParams) { + var item = tmpParams[paramkey] + //item.configuration = true + + const found = selectedAction.parameters.find(param => param.name === item.name) + if (found === null || found === undefined) { + selectedAction.parameters.push(item) + } + } + + setSelectedAction(selectedAction) + } + + //alert.error("Failed getting authentications") + } + }) + .catch(error => { + alert.error("Auth loading error: "+error.toString()) + }) + } + + if (!authLoaded && appAuthentication.length === 0 && selectedAction.id !== undefined) { + setAuthLoaded(true) + getAppAuthentication() + } else if (selectedAction.id === undefined && currentAction.name !== undefined && currentAction.name !== null && currentAction.name.length > 0) { + var methodName = `${currentAction.method}_${currentAction.name}` + if (currentAction.method.toLowerCase() === "custom" || currentAction.name.toLowerCase().startsWith(currentAction.method.toLowerCase())) { + methodName = currentAction.name + } + + methodName = methodName.toLowerCase().replaceAll(" ", "_") + if (app.actions !== null && app.actions !== undefined) { + var newselectedaction = app.actions.find(item => item.name.toLowerCase().replaceAll(" ", "_") === methodName) + if (newselectedaction !== undefined && newselectedaction !== null) { + newselectedaction.app_id = app.id + newselectedaction.app_name = app.name + newselectedaction.app_version = app.app_version + newselectedaction.authentication = [] + newselectedaction.authentication_id = "" + newselectedaction.selectedAuthentication = {} + setSelectedAction(newselectedaction) + } + } + } + + const setNewAppAuth = (appAuthData) => { + //console.log("DAta: ", appAuthData) + fetch(globalUrl+"/api/v1/apps/authentication", { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + body: JSON.stringify(appAuthData), + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Status not 200 for setting app auth :O!") + } + + return response.json() + }) + .then((responseJson) => { + if (!responseJson.success) { + alert.error("Failed to set app auth: "+responseJson.reason) + } else { + getAppAuthentication(true) + setAuthenticationModalOpen(false) + + // Needs a refresh with the new authentication.. + //alert.success("Successfully saved new app auth") + } + }) + .catch(error => { + alert.error(error.toString()) + }) + } + + const AuthenticationData = (props) => { + const selectedApp = props.app + console.log("APP: ", selectedApp) + + const [authenticationOption, setAuthenticationOptions] = React.useState({ + app: JSON.parse(JSON.stringify(selectedApp)), + fields: {}, + label: "", + usage: [{ + workflow_id: workflow.id, + }], + id: uuid.v4(), + active: true, + }) + + if (selectedApp.authentication === undefined) { + return null + } + + if (selectedApp.authentication.parameters === null || selectedApp.authentication.parameters === undefined || selectedApp.authentication.parameters.length === 0) { + return null + } + + authenticationOption.app.actions = [] + + for (var key in selectedApp.authentication.parameters) { + if (authenticationOption.fields[selectedApp.authentication.parameters[key].name] === undefined) { + authenticationOption.fields[selectedApp.authentication.parameters[key].name] = "" + } + } + + const handleSubmitCheck = () => { + console.log("NEW AUTH: ", authenticationOption) + if (authenticationOption.label.length === 0) { + authenticationOption.label = `Auth for ${selectedApp.name}` + //alert.info("Label can't be empty") + //return + } + + for (var key in selectedApp.authentication.parameters) { + if (authenticationOption.fields[selectedApp.authentication.parameters[key].name].length === 0) { + alert.info("Field "+selectedApp.authentication.parameters[key].name+" can't be empty") + return null + } + } + + console.log("Action: ", selectedAction) + selectedAction.authentication_id = authenticationOption.id + selectedAction.selectedAuthentication = authenticationOption + if (selectedAction.authentication === undefined || selectedAction.authentication === null) { + selectedAction.authentication = [authenticationOption] + } else { + selectedAction.authentication.push(authenticationOption) + } + + setSelectedAction(selectedAction) + + var newAuthOption = JSON.parse(JSON.stringify(authenticationOption)) + var newFields = [] + for (const key in newAuthOption.fields) { + const value = newAuthOption.fields[key] + newFields.push({ + key: key, + value: value, + }) + } + + console.log("FIELDS: ", newFields) + newAuthOption.fields = newFields + setNewAppAuth(newAuthOption) + //appAuthentication.push(newAuthOption) + //setAppAuthentication(appAuthentication) + // + + setUpdate(authenticationOption.id) + + /* + {selectedAction.authentication.map(data => ( + + */ + + } + + if (authenticationOption.label === null || authenticationOption.label === undefined) { + authenticationOption.label = selectedApp.name+" authentication" + } + + console.log("PRE RETURN") + return ( +
+ + What is this?
+ These are required fields for authenticating with {selectedApp.name} +
+ Name - what is this used for? + { + authenticationOption.label = event.target.value + }} + /> + {selectedApp.link.length > 0 ?
: null} + +
+ {selectedApp.authentication.parameters.map((data, index) => { + return ( +
+ + {data.name} + { + authenticationOption.fields[data.name] = event.target.value + }} + /> +
+ ) + })} + + + + + +
+ ) + } + } + const actionView =
@@ -2112,8 +2840,7 @@ const AppCreator = (props) => { : null}

Actions {actionAmount > 0 ? ({actionAmount} / {actions.length}) : null}

- Actions are the tasks performed by an app. Read more about actions and apps - here. + Actions are the tasks performed by an app - usually single URL paths for REST API's.
{loopActions}
@@ -2144,7 +2871,7 @@ const AppCreator = (props) => {

Test

Test an action to see whether it performs in an expected way. -  TBD: Click here to learn more about testing. +  TBD: Click here to learn more about testing.
Test :)
@@ -2300,11 +3027,12 @@ const AppCreator = (props) => { Cancel + {/**/} : null; @@ -2327,7 +3055,7 @@ const AppCreator = (props) => { upload = ref} onChange={editHeaderImage} />

General information

- Click here to learn more about app creation + Click here to learn more about app creation
{ @@ -2366,13 +3094,18 @@ const AppCreator = (props) => { } } - if (e.target.value.length > 100) { - alert.error("Choose a shorter name.") + if (e.target.value.length > 29) { + alert.error("Choose a shorter name (max 29).") return } + //e.target.value.trim() + setName(e.target.value) }} + onBlur={e => { + setName(e.target.value.trim()) + }} color="primary" InputProps={{ style:{ @@ -2409,9 +3142,9 @@ const AppCreator = (props) => { />
- -

API information

- Base URL - leave empty if user changeable + + API information + Base URL - used as suggestion to the user { setBaseUrl(tmpstring) }} /> - -
Authentication -
+ + Authentication type { + console.log("Changing version to index "+event.target.value) + const newversion = selectedApp.versions.find(tmpApp => tmpApp.version == event.target.value) + console.log("New version: ", newversion) + selectedApp.app_version = selectedApp.app_version + setSelectedApp(selectedApp) + + if (newversion !== undefined && newversion !== null) { + getApp(newversion.id, true) + } + }} + style={{position: "absolute", top: -10, right: isCloud ? 50 : 0, backgroundColor: theme.palette.surfaceColor, backgroundColor: inputColor, color: "white", height: 35, marginleft: 10,}} + SelectDisplayProps={{ + style: { + marginLeft: 10, + } + }} + > + {selectedApp.versions.map((data, index) => { + return ( + + {data.version} + + + ) + })} + + : null } {isCloud ? @@ -755,9 +820,14 @@ const Apps = (props) => { const circleSize = 10 return ( -
+ {data.configuration === true ? + + + + : +
+ } {data.name} - ) })} @@ -831,11 +901,11 @@ const Apps = (props) => { } const searchfield = search.toLowerCase() - var newapps = apps.filter(data => data.name.toLowerCase().includes(searchfield) || data.description.toLowerCase().includes(searchfield)) - var tmpapps = searchableApps.filter(data => data.name.toLowerCase().includes(searchfield) || data.description.toLowerCase().includes(searchfield)) + var newapps = apps.filter(data => data.name.toLowerCase().includes(searchfield) || data.description.toLowerCase().includes(searchfield) || (data.tags !== null && data.tags.includes(search))) + var tmpapps = searchableApps.filter(data => data.name.toLowerCase().includes(searchfield) || data.description.toLowerCase().includes(searchfield) || (data.tags !== null && data.tags.includes(search))) newapps.push(...tmpapps) - console.log(newapps) + //console.log(newapps) setFilteredApps(newapps) //if ((newapps.length === 0 || searchBackend) && !appSearchLoading) { @@ -940,26 +1010,30 @@ const Apps = (props) => { }
- { - handleSearchChange(event.target.value) - setCursearch(event.target.value) - }} - /> +
+ { + handleSearchChange(event.target.value) + setCursearch(event.target.value) + }} + /> +
{apps.length > 0 ? filteredApps.length > 0 ? @@ -1083,7 +1157,7 @@ const Apps = (props) => { .then((response) => { setIsLoading(false) if (response.status === 200) { - alert.success("Hotloaded apps!") + //alert.success("Hotloaded apps!") getApps() } @@ -1108,7 +1182,7 @@ const Apps = (props) => { setValidation(true) var cors = "cors" - if (openApi.includes("localhost")) { + if (openApi.includes("= localhost")) { cors = "no-cors" } @@ -1126,6 +1200,48 @@ const Apps = (props) => { }); } + const getApp = (appId, setApp) => { + fetch(globalUrl+"/api/v1/apps/"+appId+"/config?openapi=false", { + headers: { + 'Accept': 'application/json', + }, + credentials: "include", + }) + .then((response) => { + if (response.status === 200) { + //alert.success("Successfully GOT app "+appId) + } else { + alert.error("Failed getting app") + } + + return response.json() + }) + .then((responseJson) => { + console.log(responseJson) + + if (setApp) { + if (selectedApp.versions !== undefined && selectedApp.versions !== null) { + responseJson.versions = selectedApp.versions + } + + if (selectedApp.loop_versions !== undefined && selectedApp.loop_versions !== null) { + responseJson.loop_versions = selectedApp.loop_versions + } + + //alert.info("Should set app to selected") + if (responseJson.actions !== undefined && responseJson.actions !== null && responseJson.actions.length > 0) { + setSelectedAction(responseJson.actions[0]) + } else { + setSelectedAction({}) + } + setSelectedApp(responseJson) + } + }) + .catch(error => { + alert.error(error.toString()) + }); + } + const deleteApp = (appId) => { alert.info("Attempting to delete app") fetch(globalUrl+"/api/v1/apps/"+appId, { @@ -1133,12 +1249,14 @@ const Apps = (props) => { headers: { 'Accept': 'application/json', }, - credentials: "include", + credentials: "include", }) .then((response) => { if (response.status === 200) { alert.success("Successfully deleted app") - getApps() + setTimeout(() => { + getApps() + }, 1000); } else { alert.error("Failed deleting app") } @@ -1380,7 +1498,7 @@ const Apps = (props) => { style={{backgroundColor: inputColor}} variant="outlined" margin="normal" - defaultValue={userdata.active_org.defaults.app_download_repo !== undefined && userdata.active_org.defaults.app_download_repo.length > 0 ? userdata.active_org.defaults.app_download_repo : "https://github.com/frikky/shuffle-apps"} + defaultValue={"https://github.com/frikky/shuffle-apps"} InputProps={{ style:{ color: "white", @@ -1398,7 +1516,7 @@ const Apps = (props) => { style={{backgroundColor: inputColor}} variant="outlined" margin="normal" - defaultValue={userdata.active_org.defaults.app_download_branch !== undefined && userdata.active_org.defaults.app_download_branch.length > 0 ? userdata.active_org.defaults.app_download_branch : downloadBranch} + defaultValue={downloadBranch} InputProps={{ style:{ color: "white", @@ -1521,7 +1639,7 @@ const Apps = (props) => { hidden type="file" ref={upload} - accept="application/JSON, text/yaml, text/x-yaml, application/x-yaml, application/vnd.yaml" + accept="application/JSON, application/YAML, text/yaml, text/x-yaml, application/x-yaml, application/vnd.yaml" multiple={false} onChange={uploadFile} /> diff --git a/frontend/src/views/LoginPage.jsx b/frontend/src/views/LoginPage.jsx index b365336f..dac41677 100644 --- a/frontend/src/views/LoginPage.jsx +++ b/frontend/src/views/LoginPage.jsx @@ -2,9 +2,7 @@ import React, { useState } from 'react'; import { makeStyles } from '@material-ui/styles'; -import TextField from '@material-ui/core/TextField'; -import Button from '@material-ui/core/Button'; -import Paper from '@material-ui/core/Paper'; +import {CircularProgress, TextField, Button, Paper, Typography} from '@material-ui/core' import { useTheme } from '@material-ui/core/styles'; @@ -15,7 +13,7 @@ const hrefStyle = { const bodyDivStyle = { margin: "auto", - marginTop: "100px", + marginTop: 150, width: "500px", } @@ -33,6 +31,7 @@ const LoginDialog = props => { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [firstRequest, setFirstRequest] = useState(true); + const [loginLoading, setLoginLoading] = useState(false); // Used to swap from login to register. True = login, false = register @@ -69,7 +68,7 @@ const LoginDialog = props => { }), ) .catch(error => { - setLoginInfo("Error logging in: ", error) + setLoginInfo("Error logging in - please refresh in a minute ", error) }) } @@ -79,6 +78,7 @@ const LoginDialog = props => { } const onSubmit = (e) => { + setLoginLoading(true) e.preventDefault() setLoginInfo("") // FIXME - add some check here ROFL @@ -101,6 +101,7 @@ const LoginDialog = props => { }) .then(response => response.json().then(responseJson => { + setLoginLoading(false) if (responseJson["success"] === false) { setLoginInfo(responseJson["reason"]) } else { @@ -110,11 +111,13 @@ const LoginDialog = props => { } setIsLoggedIn(true) + window.location.pathname = "/workflows" } }), ) .catch(error => { + setLoginLoading(false) setLoginInfo("Error logging in: " + error) }); } else { @@ -136,7 +139,7 @@ const LoginDialog = props => { }), ) .catch(error => { - setLoginInfo("Error in userdata: ", error) + setLoginInfo("Error in from backend: ", error) }); } } @@ -161,6 +164,7 @@ const LoginDialog = props => { //var loginChange = register ? (

Want to register? Click here.

) : (

Go back to login? Click here.

); var formtitle = register ?
Login
:
Register
+ const imgsize = 100 const basedata =
{ paddingRight: "30px", paddingBottom: "30px", paddingTop: "30px", + position: "relative", backgroundColor: theme.palette.surfaceColor, }}> +
+ +

{formtitle}

Username @@ -225,8 +233,9 @@ const LoginDialog = props => { />
- - +
{loginInfo} diff --git a/frontend/src/views/SettingsPage.jsx b/frontend/src/views/SettingsPage.jsx index b1f53c1c..6a1cdd4a 100644 --- a/frontend/src/views/SettingsPage.jsx +++ b/frontend/src/views/SettingsPage.jsx @@ -29,6 +29,7 @@ const Settings = (props) => { const [userInfo, ] = useState(userdata) const [userSettings, setUserSettings] = useState({}) + const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" const bodyDivStyle = { margin: "auto", @@ -421,7 +422,7 @@ const Settings = (props) => { />
+ + + + + : null + const deleteModal = deleteModalOpen ? { >
- Are you sure?
Other workflows relying on this one may stop working + Are you sure you want to delete this workflow?
Other workflows relying on this one may stop working
@@ -271,7 +529,9 @@ const Workflows = (props) => { console.log("Editing: ", editingWorkflow) if (selectedWorkflowId) { deleteWorkflow(selectedWorkflowId) - getAvailableWorkflows() + setTimeout(() => { + getAvailableWorkflows() + }, 1000) } setDeleteModalOpen(false) }} color="primary"> @@ -314,7 +574,7 @@ const Workflows = (props) => { const ret = setNewWorkflow(data.name, data.description, data.tags, data, false) .then((response) => { if (response !== undefined) { - alert.success("Successfully imported "+data.name) + alert.success(`Successfully imported ${data.name}`) } }) } @@ -438,6 +698,8 @@ const Workflows = (props) => { const paperAppStyle = { minHeight: 130, + maxHeight: 130, + overflow: "hidden", width: "100%", color: "white", backgroundColor: surfaceColor, @@ -448,6 +710,7 @@ const Workflows = (props) => { position: "relative", } + const gridContainer = { height: "auto", color: "white", @@ -480,7 +743,7 @@ const Workflows = (props) => { return response.json() }) - .then((responseJson) => { + .then((responseJson) => { if (!responseJson.success) { alert.error(responseJson.reason) } @@ -500,9 +763,7 @@ const Workflows = (props) => { } } - const sanitizeWorkflow = (data) => { - data["owner"] = "" - console.log("Sanitize start: ", data) + const deduplicateIds = (data) => { if (data.triggers !== null && data.triggers !== undefined) { for (var key in data.triggers) { const trigger = data.triggers[key] @@ -517,15 +778,27 @@ const Workflows = (props) => { } const newId = uuid.v4() + if (trigger.trigger_type === "WEBHOOK") { + const hookname = "webhook_"+newId + if (trigger.parameters !== undefined && trigger.parameters !== null && trigger.parameters.length === 2) { + trigger.parameters[0].value = referenceUrl+"webhook_"+trigger.id + trigger.parameters[1].value = "webhook_"+trigger.id + } else if (trigger.parameters !== undefined && trigger.parameters !== null && trigger.parameters.length === 3) { + trigger.parameters[0].value = referenceUrl+"webhook_"+trigger.id + trigger.parameters[1].value = "webhook_"+trigger.id + // FIXME: Add auth here? + } else { + alert.info("Something is wrong with the webhook in the copy") + } + } + for (var branchkey in data.branches) { const branch = data.branches[branchkey] if (branch.source_id === trigger.id) { - //console.log("CHANGING SOURCE ID") branch.source_id = newId } if (branch.destination_id === trigger.id) { - //console.log("CHANGING DESTINATION ID") branch.destination_id = newId } } @@ -541,7 +814,7 @@ const Workflows = (props) => { for (var subkey in data.actions[key].parameters) { const param = data.actions[key].parameters[subkey] - if (param.name.includes("key") || param.name.includes("user") || param.name.includes("pass") || param.name.includes("api") || param.name.includes("auth") || param.name.includes("secret")) { + if (param.name.includes("key") || param.name.includes("user") || param.name.includes("pass") || param.name.includes("api") || param.name.includes("auth") || param.name.includes("secret") || param.name.includes("domain") || param.name.includes("url") || param.name.includes("mail")) { // FIXME: This may be a vuln if api-keys are generated that start with $ if (param.value.startsWith("$")) { console.log("Skipping field, as it's referencing a variable") @@ -556,16 +829,18 @@ const Workflows = (props) => { for (var branchkey in data.branches) { const branch = data.branches[branchkey] if (branch.source_id === data.actions[key].id) { - //console.log("CHANGING SOURCE ID IN ACTION") branch.source_id = newId } if (branch.destination_id === data.actions[key].id) { - //console.log("CHANGING DESTINATION ID IN ACTION") branch.destination_id = newId } } + if (data.actions[key].id === data.start) { + data.start = newId + } + //data.actions[key].environment = isCloud ? "cloud" : "Shuffle" data.actions[key].environment = "" data.actions[key].id = newId @@ -575,15 +850,20 @@ const Workflows = (props) => { if (data.workflow_variables !== null && data.workflow_variables !== undefined) { for (var key in data.workflow_variables) { const param = data.workflow_variables[key] - if (param.name.includes("key") || param.name.includes("user") || param.name.includes("pass") || param.name.includes("api") || param.name.includes("auth") || param.name.includes("secret")) { + if (param.name.includes("key") || param.name.includes("user") || param.name.includes("pass") || param.name.includes("api") || param.name.includes("auth") || param.name.includes("secret") || param.name.includes("email")) { param.value = "" param.is_valid = false } } } - //console.log(data) - //return + return data + } + + const sanitizeWorkflow = (data) => { + data["owner"] = "" + console.log("Sanitize start: ", data) + data = deduplicateIds(data) data["org"] = [] data["org_id"] = "" @@ -600,10 +880,11 @@ const Workflows = (props) => { const exportWorkflow = (data) => { let exportFileDefaultName = data.name+'.json'; data = sanitizeWorkflow(data) - - //console.log("EXPORT: ", data) //return + // Add correct ID's for triggers + // Add mag + let dataStr = JSON.stringify(data) let dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr); let linkElement = document.createElement('a'); @@ -657,7 +938,8 @@ const Workflows = (props) => { alert.success("Copying workflow "+data.name) data.id = "" data.name = data.name+"_copy" - console.log("COPIED DATA: ", data) + data = deduplicateIds(data) + //console.log("COPIED DATA: ", data) //return fetch(globalUrl+"/api/v1/workflows", { @@ -677,7 +959,9 @@ const Workflows = (props) => { return response.json() }) .then((responseJson) => { - getAvailableWorkflows() + setTimeout(() => { + getAvailableWorkflows() + }, 1000) }) .catch(error => { alert.error(error.toString()) @@ -705,7 +989,9 @@ const Workflows = (props) => { return response.json() }) .then((responseJson) => { - getAvailableWorkflows() + setTimeout(() => { + getAvailableWorkflows() + }, 1000) }) .catch(error => { alert.error(error.toString()) @@ -717,6 +1003,39 @@ const Workflows = (props) => { addFilter(e.target.innerHTML) } + + const NewWorkflowPaper = (props) => { + const [hover, setHover] = React.useState(false) + + const innerColor = "rgba(255,255,255,0.3)" + const setupPaperStyle = { + minHeight: paperAppStyle.minHeight, + width: paperAppStyle.width, + color: innerColor, + padding: paperAppStyle.padding, + borderRadius: paperAppStyle.borderRadius, + display: "flex", + boxSizing: "border-box", + position: "relative", + border: `2px solid ${innerColor}`, + cursor: "pointer", + backgroundColor: hover ? "rgba(39,41,45,0.5)" : "rgba(39,41,45,1)", + } + + return( + + setModalOpen(true)} onMouseOver={() => {setHover(true)}} onMouseOut={() => {setHover(false)}}> + + + + + + + + ) + } + + const WorkflowPaper = (props) => { const { data } = props; const [open, setOpen] = React.useState(false); @@ -888,7 +1207,8 @@ const Workflows = (props) => { {"Change details"} { - publishWorkflow(data) + setSelectedWorkflow(data) + setPublishModalOpen(true) }} key={"publish"}> {"Publish Workflow"} @@ -956,7 +1276,7 @@ const Workflows = (props) => { const resultsPaper = (data) => { var boxWidth = "2px" - var boxColor = "orange" + var boxColor = "orange" if (data.status === "ABORTED" || data.status === "UNFINISHED" || data.status === "FAILURE"){ boxColor = "red" } else if (data.status === "FINISHED" || data.status === "SUCCESS") { @@ -1177,7 +1497,9 @@ const Workflows = (props) => { window.location.pathname = "/workflows/"+responseJson["id"] } else if (!redirect) { // Update :) - getAvailableWorkflows() + setTimeout(() => { + getAvailableWorkflows() + }, 1000) setImportLoading(false) } else { alert.info("Successfully changed basic info for workflow") @@ -1287,7 +1609,8 @@ const Workflows = (props) => { const data = params.row.record; let [triggers, schedules, webhooks, subflows] = getWorkflowMeta(data); - return + return ( + { : null} - } + ) + } }, - { field: 'tags', headerName: 'Tags', width: 390, sortable: false, + { field: 'tags', headerName: 'Tags', maxHeight: 15, width: 390, sortable: false, disableClickEventBubbling: true, renderCell: (params) => { const data = params.row.record; - return + return ( + {data.tags !== undefined ? data.tags.map((tag, index) => { if (index >= 3) { @@ -1338,17 +1663,24 @@ const Workflows = (props) => { }) : null} + ) } }, ]; let rows = []; rows = workflows.map((data, index) => { - let obj = {"id":index+1, "title":data.name, "record":data,}; + let obj = { + "id":index+1, + "title":data.name, + "record":data, + } + return obj; }); - workflowData = + workflowData = + } return (
@@ -1406,6 +1738,8 @@ const Workflows = (props) => { color="primary" defaultValue={newWorkflowDescription} placeholder="Description" + rows="6" + multiline margin="dense" fullWidth /> @@ -1481,11 +1815,11 @@ const Workflows = (props) => { const workflowButtons = - {workflows.length > 0 ? + {/*workflows.length > 0 ? - : null} + : null*/} {importLoading ?