diff options
author | Max Meinhold <mxmeinhold@gmail.com> | 2020-08-22 14:43:58 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-22 14:43:58 -0400 |
commit | 35fb475e8fa721bccca871dd9ffd8fae7f0a9a5d (patch) | |
tree | 4287764b45f1561faf33aa9b359279bdcb57e513 | |
parent | 1ff8d94f052a860f0f6426fd7f0f40372420e8eb (diff) | |
parent | 3a4d8e2bb32faa5f255a28faa3e0c523084aa892 (diff) |
Merge Version 3.5.0 (#208)v3.5.0
34 files changed, 1391 insertions, 750 deletions
@@ -103,6 +103,9 @@ ENV/ # JetBrains .idea/ +# vscode +.vscode + # Configurations config.py @@ -128,3 +131,5 @@ packet/static/safari-pinned-tab.svg packet/static/site.webmanifest faviconData.json +# csvs +*.csv diff --git a/.travis.yml b/.travis.yml index 6d2ad6f..d0cbb08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,16 @@ language: python python: - "3.7" +services: + - "docker" install: - "pip install -r requirements.txt" + - "curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.3/install.sh | bash" + - "nvm install" + - "nvm use" + - "npm install -g gulp" + - "npm install" script: - - "pylint --load-plugins pylint_quotes packet/routes packet" + - "gulp lint" + - "docker build -t packet ." @@ -106,7 +106,7 @@ fail blocking you from merging. To make your life easier just run it before maki To run pylint use this command: ```bash -pylint packet +pylint --load-plugins pylint_quotes packet/routes packet ``` All python files should have a top-level docstring explaining the contents of the file and complex functions should diff --git a/frontend/scss/components/code.scss b/frontend/scss/components/code.scss new file mode 100644 index 0000000..b082276 --- /dev/null +++ b/frontend/scss/components/code.scss @@ -0,0 +1,3 @@ +pre{ + white-space: pre-wrap; +} diff --git a/frontend/scss/packet.scss b/frontend/scss/packet.scss index d89fc83..193e09f 100644 --- a/frontend/scss/packet.scss +++ b/frontend/scss/packet.scss @@ -7,3 +7,4 @@ $csh-pink: #b0197e; @import "components/buttons"; @import "components/signatures"; @import "components/badges"; +@import "components/code"; diff --git a/frontend/scss/partials/_global.scss b/frontend/scss/partials/_global.scss index 6e9695d..7ffbd89 100644 --- a/frontend/scss/partials/_global.scss +++ b/frontend/scss/partials/_global.scss @@ -103,4 +103,8 @@ tr { .eval-user-img { border-radius: 50%; -}
\ No newline at end of file +} + +select.form-control:not([size]):not([multiple]) { + height: calc(3rem + 2px); +} diff --git a/gulpfile.js/index.js b/gulpfile.js/index.js index 8123803..d191d57 100644 --- a/gulpfile.js/index.js +++ b/gulpfile.js/index.js @@ -19,4 +19,5 @@ requireDir('./tasks', {recurse: true}); // Default task gulp.task('default', gulp.parallel('css', 'js')); -gulp.task('production', gulp.parallel('css', 'js', 'generate-favicon', 'pylint')); +gulp.task('production', gulp.parallel('css', 'js', 'generate-favicon')); +gulp.task('lint', gulp.parallel('pylint')); diff --git a/gulpfile.js/tasks/pylint.js b/gulpfile.js/tasks/pylint.js index 6a82ab5..2e93f75 100644 --- a/gulpfile.js/tasks/pylint.js +++ b/gulpfile.js/tasks/pylint.js @@ -2,7 +2,7 @@ const gulp = require('gulp'); const exec = require('child_process').exec; let pylintTask = (cb) => { - exec('pylint packet', function (err, stdout, stderr) { + exec('pylint --load-plugins pylint_quotes packet/routes packet', function (err, stdout, stderr) { console.log(stdout); console.log(stderr); cb(err); diff --git a/package.json b/package.json index 5a382e9..f1a93e4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "title": "CSH Packet", "name": "csh-packet", - "version": "3.4.0", + "version": "3.5.0", "description": "A web app implementation of the CSH introductory packet.", "bugs": { "url": "https://github.com/ComputerScienceHouse/packet/issues", @@ -20,10 +20,10 @@ "devDependencies": { "gulp": "^4.0.2", "gulp-clean-css": "^4.2.0", + "gulp-minify": "^3.1.0", "gulp-real-favicon": "^0.3.2", "gulp-rename": "^1.4.0", "gulp-sass": "^4.0.2", - "gulp-minify": "^3.1.0", "require-dir": "^1.2.0" } } diff --git a/packet/__init__.py b/packet/__init__.py index c369efd..32e9fe7 100644 --- a/packet/__init__.py +++ b/packet/__init__.py @@ -80,6 +80,7 @@ from .routes import api, shared if app.config['REALM'] == 'csh': from .routes import upperclassmen + from .routes import admin else: from .routes import freshmen diff --git a/packet/commands.py b/packet/commands.py index d4654f7..32dac8e 100644 --- a/packet/commands.py +++ b/packet/commands.py @@ -5,17 +5,13 @@ Defines command-line utilities for use with packet import sys from secrets import token_hex -from datetime import datetime, time, timedelta +from datetime import datetime, time import csv import click -from packet.mail import send_start_packet_mail -from packet.notifications import packet_starting_notification, packets_starting_notification from . import app, db -from .models import Freshman, Packet, FreshSignature, UpperSignature, MiscSignature -from .ldap import ldap_get_eboard_role, ldap_get_active_rtps, ldap_get_3das, ldap_get_webmasters, \ - ldap_get_drink_admins, ldap_get_constitutional_maintainers, ldap_is_intromember, ldap_get_active_members, \ - ldap_is_on_coop +from .models import Packet, FreshSignature, UpperSignature, MiscSignature +from .utils import sync_freshman, create_new_packets, sync_with_ldap @app.cli.command('create-secret') @@ -66,40 +62,7 @@ def sync_freshmen(freshmen_csv): freshmen_in_csv = parse_csv(freshmen_csv) print('Syncing contents with the DB...') - freshmen_in_db = {freshman.rit_username: freshman for freshman in Freshman.query.all()} - - for csv_freshman in freshmen_in_csv.values(): - if csv_freshman.rit_username not in freshmen_in_db: - # This is a new freshman so add them to the DB - freshmen_in_db[csv_freshman.rit_username] = Freshman(rit_username=csv_freshman.rit_username, - name=csv_freshman.name, onfloor=csv_freshman.onfloor) - db.session.add(freshmen_in_db[csv_freshman.rit_username]) - else: - # This freshman is already in the DB so just update them - freshmen_in_db[csv_freshman.rit_username].onfloor = csv_freshman.onfloor - freshmen_in_db[csv_freshman.rit_username].name = csv_freshman.name - - # Update all freshmen entries that represent people who are no longer freshmen - for freshman in filter(lambda freshman: freshman.rit_username not in freshmen_in_csv, freshmen_in_db.values()): - freshman.onfloor = False - - # Update the freshmen signatures of each open or future packet - for packet in Packet.query.filter(Packet.end > datetime.now()).all(): - # Handle the freshmen that are no longer onfloor - for fresh_sig in filter(lambda fresh_sig: not fresh_sig.freshman.onfloor, packet.fresh_signatures): - FreshSignature.query.filter_by(packet_id=fresh_sig.packet_id, - freshman_username=fresh_sig.freshman_username).delete() - - # Add any new onfloor freshmen - # pylint: disable=cell-var-from-loop - current_fresh_sigs = set(map(lambda fresh_sig: fresh_sig.freshman_username, packet.fresh_signatures)) - for csv_freshman in filter(lambda csv_freshman: csv_freshman.rit_username not in current_fresh_sigs and - csv_freshman.onfloor and - csv_freshman.rit_username != packet.freshman_username, - freshmen_in_csv.values()): - db.session.add(FreshSignature(packet=packet, freshman=freshmen_in_db[csv_freshman.rit_username])) - - db.session.commit() + sync_freshman(freshmen_in_csv) print('Done!') @@ -115,46 +78,8 @@ def create_packets(freshmen_csv): # Collect the necessary data base_date = input_date('Input the first day of packet season') - start = datetime.combine(base_date, packet_start_time) - end = datetime.combine(base_date, packet_end_time) + timedelta(days=14) - - print('Fetching data from LDAP...') - all_upper = list(filter( - lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())) - - rtp = ldap_get_active_rtps() - three_da = ldap_get_3das() - webmaster = ldap_get_webmasters() - c_m = ldap_get_constitutional_maintainers() - drink = ldap_get_drink_admins() - - # Packet starting notifications - packets_starting_notification(start) - - # Create the new packets and the signatures for each freshman in the given CSV freshmen_in_csv = parse_csv(freshmen_csv) - print('Creating DB entries and sending emails...') - for freshman in Freshman.query.filter(Freshman.rit_username.in_(freshmen_in_csv)).all(): - packet = Packet(freshman=freshman, start=start, end=end) - db.session.add(packet) - send_start_packet_mail(packet) - packet_starting_notification(packet) - - for member in all_upper: - sig = UpperSignature(packet=packet, member=member.uid) - sig.eboard = ldap_get_eboard_role(member) - sig.active_rtp = member.uid in rtp - sig.three_da = member.uid in three_da - sig.webmaster = member.uid in webmaster - sig.c_m = member.uid in c_m - sig.drink_admin = member.uid in drink - db.session.add(sig) - - for onfloor_freshman in Freshman.query.filter_by(onfloor=True).filter(Freshman.rit_username != - freshman.rit_username).all(): - db.session.add(FreshSignature(packet=packet, freshman=onfloor_freshman)) - - db.session.commit() + create_new_packets(base_date, freshmen_in_csv) print('Done!') @@ -163,60 +88,7 @@ def ldap_sync(): """ Updates the upper and misc sigs in the DB to match ldap. """ - print('Fetching data from LDAP...') - all_upper = {member.uid: member for member in filter( - lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())} - - rtp = ldap_get_active_rtps() - three_da = ldap_get_3das() - webmaster = ldap_get_webmasters() - c_m = ldap_get_constitutional_maintainers() - drink = ldap_get_drink_admins() - - print('Applying updates to the DB...') - for packet in Packet.query.filter(Packet.end > datetime.now()).all(): - # Update the role state of all UpperSignatures - for sig in filter(lambda sig: sig.member in all_upper, packet.upper_signatures): - sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) - sig.active_rtp = sig.member in rtp - sig.three_da = sig.member in three_da - sig.webmaster = sig.member in webmaster - sig.c_m = sig.member in c_m - sig.drink_admin = sig.member in drink - - # Migrate UpperSignatures that are from accounts that are not active anymore - for sig in filter(lambda sig: sig.member not in all_upper, packet.upper_signatures): - UpperSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete() - if sig.signed: - sig = MiscSignature(packet=packet, member=sig.member) - db.session.add(sig) - - # Migrate MiscSignatures that are from accounts that are now active members - for sig in filter(lambda sig: sig.member in all_upper, packet.misc_signatures): - MiscSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete() - sig = UpperSignature(packet=packet, member=sig.member, signed=True) - sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) - sig.active_rtp = sig.member in rtp - sig.three_da = sig.member in three_da - sig.webmaster = sig.member in webmaster - sig.c_m = sig.member in c_m - sig.drink_admin = sig.member in drink - db.session.add(sig) - - # Create UpperSignatures for any new active members - # pylint: disable=cell-var-from-loop - upper_sigs = set(map(lambda sig: sig.member, packet.upper_signatures)) - for member in filter(lambda member: member not in upper_sigs, all_upper): - sig = UpperSignature(packet=packet, member=member) - sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) - sig.active_rtp = sig.member in rtp - sig.three_da = sig.member in three_da - sig.webmaster = sig.member in webmaster - sig.c_m = sig.member in c_m - sig.drink_admin = sig.member in drink - db.session.add(sig) - - db.session.commit() + sync_with_ldap() print('Done!') diff --git a/packet/context_processors.py b/packet/context_processors.py index 604d931..935106b 100644 --- a/packet/context_processors.py +++ b/packet/context_processors.py @@ -43,7 +43,7 @@ def get_roles(sig): # pylint: disable=bare-except -@lru_cache(maxsize=128) +@lru_cache(maxsize=256) def get_rit_name(username): try: freshman = Freshman.query.filter_by(rit_username=username).first() @@ -53,7 +53,7 @@ def get_rit_name(username): # pylint: disable=bare-except -@lru_cache(maxsize=128) +@lru_cache(maxsize=256) def get_rit_image(username): if username: addresses = [username + '@rit.edu', username + '@g.rit.edu'] diff --git a/packet/ldap.py b/packet/ldap.py index 30b2f28..02a38dc 100644 --- a/packet/ldap.py +++ b/packet/ldap.py @@ -149,8 +149,8 @@ def ldap_get_eboard_role(member): return return_val -# Status checkers +# Status checkers def ldap_is_eboard(member): """ :param member: A CSHMember instance @@ -158,6 +158,14 @@ def ldap_is_eboard(member): return _ldap_is_member_of_group(member, 'eboard') +def ldap_is_evals(member): + return _ldap_is_member_of_group(member, 'eboard-evaluations') + + +def ldap_is_rtp(member): + return _ldap_is_member_of_group(member, 'rtp') + + def ldap_is_intromember(member): """ :param member: A CSHMember instance diff --git a/packet/models.py b/packet/models.py index 6f8cbb6..355a997 100644 --- a/packet/models.py +++ b/packet/models.py @@ -49,6 +49,13 @@ class Freshman(db.Model): """ return cls.query.filter_by(rit_username=username).first() + @classmethod + def get_all(cls): + """ + Helper method to get all freshmen easily + """ + return cls.query.all() + class Packet(db.Model): __tablename__ = 'packet' diff --git a/packet/routes/admin.py b/packet/routes/admin.py new file mode 100644 index 0000000..96a877b --- /dev/null +++ b/packet/routes/admin.py @@ -0,0 +1,43 @@ +from flask import render_template + +from packet import app +from packet.models import Packet, Freshman +from packet.routes.shared import packet_sort_key +from packet.utils import before_request, packet_auth, admin_auth +from packet.log_utils import log_cache, log_time + + +@app.route('/admin/packets') +@log_cache +@packet_auth +@admin_auth +@before_request +@log_time +def admin_packets(info=None): + open_packets = Packet.open_packets() + + # Pre-calculate and store the return values of did_sign(), signatures_received(), and signatures_required() + for packet in open_packets: + packet.did_sign_result = packet.did_sign(info['uid'], app.config['REALM'] == 'csh') + packet.signatures_received_result = packet.signatures_received() + packet.signatures_required_result = packet.signatures_required() + + open_packets.sort(key=packet_sort_key, reverse=True) + + return render_template('admin_packets.html', + open_packets=open_packets, + info=info) + + +@app.route('/admin/freshmen') +@log_cache +@packet_auth +@admin_auth +@before_request +@log_time +def admin_freshmen(info=None): + all_freshmen = Freshman.get_all() + + return render_template('admin_freshmen.html', + all_freshmen=all_freshmen, + info=info) diff --git a/packet/routes/api.py b/packet/routes/api.py index f3d2f0f..828ac96 100644 --- a/packet/routes/api.py +++ b/packet/routes/api.py @@ -1,22 +1,28 @@ """ Shared API endpoints """ -from datetime import datetime, timedelta +from datetime import datetime from json import dumps from flask import session, request from packet import app, db from packet.context_processors import get_rit_name -from packet.commands import packet_start_time, packet_end_time -from packet.ldap import ldap_get_eboard_role, ldap_get_active_rtps, ldap_get_3das, ldap_get_webmasters, \ - ldap_get_drink_admins, ldap_get_constitutional_maintainers, ldap_is_intromember, ldap_get_active_members, \ - ldap_is_on_coop, _ldap_is_member_of_group, ldap_get_member -from packet.mail import send_report_mail, send_start_packet_mail -from packet.utils import before_request, packet_auth, notify_slack -from packet.models import Packet, MiscSignature, NotificationSubscription, Freshman, FreshSignature, UpperSignature -from packet.notifications import packet_signed_notification, packet_100_percent_notification, \ - packet_starting_notification, packets_starting_notification +from packet.ldap import _ldap_is_member_of_group, ldap_get_member +from packet.log_utils import log_time +from packet.mail import send_report_mail +from packet.utils import before_request, packet_auth, notify_slack, sync_freshman as sync_freshman_list, \ + create_new_packets, sync_with_ldap +from packet.models import Packet, MiscSignature, NotificationSubscription, Freshman +from packet.notifications import packet_signed_notification, packet_100_percent_notification +import packet.stats as stats + + +class POSTFreshman: + def __init__(self, freshman): + self.name = freshman['name'].strip() + self.rit_username = freshman['rit_username'].strip() + self.onfloor = freshman['onfloor'].strip() == 'TRUE' @app.route('/api/v1/freshmen', methods=['POST']) @@ -39,47 +45,14 @@ def sync_freshman(): if not _ldap_is_member_of_group(ldap_get_member(username), 'eboard-evaluations'): return 'Forbidden: not Evaluations Director', 403 - freshmen = request.json - results = list() - - packets = Packet.query.filter(Packet.end > datetime.now()).all() - - for freshman in freshmen: - rit_username = freshman['rit_username'] - name = freshman['name'] - onfloor = freshman['onfloor'] - - frosh = Freshman.query.filter_by(rit_username=rit_username).first() - if frosh: - if onfloor and not frosh.onfloor: - # Add new onfloor signature - for packet in packets: - db.session.add(FreshSignature(packet=packet, freshman=frosh)) - elif not onfloor and frosh.onfloor: - # Remove outdated onfloor signature - for packet in packets: - FreshSignature.query.filter_by(packet_id=packet.id, freshman_username=frosh.rit_username).delete() - - frosh.name = name - frosh.onfloor = onfloor - - results.append(f"'{name} ({rit_username})' updated") - else: - frosh = Freshman(rit_username=rit_username, name=name, onfloor=onfloor) - db.session.add(frosh) - if onfloor: - # Add onfloor signature - for packet in packets: - db.session.add(FreshSignature(packet=packet, freshman=frosh)) - - results.append(f"Freshman '{name} ({rit_username})' created") - - db.session.commit() - return dumps(results), 200 + freshmen_in_post = {freshman.rit_username: freshman for freshman in map(POSTFreshman, request.json)} + sync_freshman_list(freshmen_in_post) + return dumps('Done'), 200 @app.route('/api/v1/packets', methods=['POST']) @packet_auth +@log_time def create_packet(): """ Create a new packet. @@ -87,7 +60,11 @@ def create_packet(): Body parameters: { start_date: the start date of the packets in MM/DD/YYYY format freshmen: [ - rit_username: string + { + rit_username: string + name: string + onfloor: boolean + } ] } """ @@ -99,56 +76,23 @@ def create_packet(): base_date = datetime.strptime(request.json['start_date'], '%m/%d/%Y').date() - start = datetime.combine(base_date, packet_start_time) - end = datetime.combine(base_date, packet_end_time) + timedelta(days=14) - - frosh = request.json['freshmen'] - results = list() - - # Gather upperclassmen data from LDAP - all_upper = list(filter( - lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())) - - rtp = ldap_get_active_rtps() - three_da = ldap_get_3das() - webmaster = ldap_get_webmasters() - c_m = ldap_get_constitutional_maintainers() - drink = ldap_get_drink_admins() - - # Packet starting notifications - packets_starting_notification(start) - - for frosh_rit_username in frosh: - # Create the packet and signatures - freshman = Freshman.query.filter_by(rit_username=frosh_rit_username).first() - if freshman is None: - results.append(f"Freshman '{frosh_rit_username}' not found") - continue - - packet = Packet(freshman=freshman, start=start, end=end) - db.session.add(packet) - send_start_packet_mail(packet) - packet_starting_notification(packet) - - for member in all_upper: - sig = UpperSignature(packet=packet, member=member.uid) - sig.eboard = ldap_get_eboard_role(member) - sig.active_rtp = member.uid in rtp - sig.three_da = member.uid in three_da - sig.webmaster = member.uid in webmaster - sig.c_m = member.uid in c_m - sig.drink_admin = member.uid in drink - db.session.add(sig) - - for onfloor_freshman in Freshman.query.filter_by(onfloor=True).filter(Freshman.rit_username != - freshman.rit_username).all(): - db.session.add(FreshSignature(packet=packet, freshman=onfloor_freshman)) - - results.append(f'Packet created for {frosh_rit_username}') + freshmen_in_post = {freshman.rit_username: freshman for freshman in map(POSTFreshman, request.json['freshmen'])} - db.session.commit() + create_new_packets(base_date, freshmen_in_post) - return dumps(results), 201 + return dumps('Done'), 201 + + +@app.route('/api/v1/sync', methods=['POST']) +@packet_auth +@log_time +def sync_ldap(): + # Only allow evals to sync ldap + username = str(session['userinfo'].get('preferred_username', '')) + if not _ldap_is_member_of_group(ldap_get_member(username), 'eboard-evaluations'): + return 'Forbidden: not Evaluations Director', 403 + sync_with_ldap() + return dumps('Done'), 201 @app.route('/api/v1/packets/<username>', methods=['GET']) @@ -162,7 +106,7 @@ def get_packets_by_user(username: str) -> dict: return {packet.id: { 'start': packet.start, 'end': packet.end, - } for packet in frosh.packets} + } for packet in frosh.packets} @app.route('/api/v1/packets/<username>/newest', methods=['GET']) @@ -176,13 +120,13 @@ def get_newest_packet_by_user(username: str) -> dict: packet = frosh.packets[-1] return { - packet.id: { - 'start': packet.start, - 'end': packet.end, - 'required': vars(packet.signatures_required()), - 'received': vars(packet.signatures_received()), - } - } + packet.id: { + 'start': packet.start, + 'end': packet.end, + 'required': vars(packet.signatures_required()), + 'received': vars(packet.signatures_received()), + } + } @app.route('/api/v1/packet/<packet_id>', methods=['GET']) @@ -195,9 +139,10 @@ def get_packet_by_id(packet_id: int) -> dict: packet = Packet.by_id(packet_id) return { - 'required': vars(packet.signatures_required()), - 'received': vars(packet.signatures_received()), - } + 'required': vars(packet.signatures_required()), + 'received': vars(packet.signatures_received()), + } + @app.route('/api/v1/sign/<packet_id>/', methods=['POST']) @packet_auth @@ -255,80 +200,14 @@ def report(info): @app.route('/api/v1/stats/packet/<packet_id>') @packet_auth def packet_stats(packet_id): - packet = Packet.by_id(packet_id) - - dates = [packet.start.date() + timedelta(days=x) for x in range(0, (packet.end-packet.start).days + 1)] - - print(dates) - - upper_stats = {date: list() for date in dates} - for uid, date in map(lambda sig: (sig.member, sig.updated), - filter(lambda sig: sig.signed, packet.upper_signatures)): - upper_stats[date.date()].append(uid) - - fresh_stats = {date: list() for date in dates} - for username, date in map(lambda sig: (sig.freshman_username, sig.updated), - filter(lambda sig: sig.signed, packet.fresh_signatures)): - fresh_stats[date.date()].append(username) - - misc_stats = {date: list() for date in dates} - for uid, date in map(lambda sig: (sig.member, sig.updated), packet.misc_signatures): - misc_stats[date.date()].append(uid) - - total_stats = dict() - for date in dates: - total_stats[date.isoformat()] = { - 'upper': upper_stats[date], - 'fresh': fresh_stats[date], - 'misc': misc_stats[date], - } - - return { - 'packet_id': packet_id, - 'dates': total_stats, - } - - -def sig2dict(sig): - """ - A utility function for upperclassman stats. - Converts an UpperSignature to a dictionary with the date and the packet. - """ - packet = Packet.by_id(sig.packet_id) - return { - 'date': sig.updated.date(), - 'packet': { - 'id': packet.id, - 'freshman_username': packet.freshman_username, - }, - } + return stats.packet_stats(packet_id) @app.route('/api/v1/stats/upperclassman/<uid>') @packet_auth def upperclassman_stats(uid): + return stats.upperclassman_stats(uid) - sigs = UpperSignature.query.filter( - UpperSignature.signed, - UpperSignature.member == uid - ).all() + MiscSignature.query.filter(MiscSignature.member == uid).all() - - sig_dicts = list(map(sig2dict, sigs)) - - dates = set(map(lambda sd: sd['date'], sig_dicts)) - - return { - 'member': uid, - 'signatures': { - date.isoformat() : list( - map(lambda sd: sd['packet'], - filter(lambda sig, d=date: sig['date'] == d, - sig_dicts - ) - ) - ) for date in dates - } - } def commit_sig(packet, was_100, uid): packet_signed_notification(packet, uid) diff --git a/packet/routes/shared.py b/packet/routes/shared.py index bebb4ca..5b87278 100644 --- a/packet/routes/shared.py +++ b/packet/routes/shared.py @@ -13,7 +13,7 @@ from packet.log_utils import log_cache, log_time @app.route('/logout/') @auth.oidc_logout def logout(): - return redirect('http://csh.rit.edu') + return redirect('https://csh.rit.edu') @app.route('/packet/<packet_id>/') @@ -80,3 +80,17 @@ def service_worker(): @app.route('/OneSignalSDKUpdaterWorker.js', methods=['GET']) def update_service_worker(): return app.send_static_file('js/update-sw.js') + + +@app.errorhandler(404) +@packet_auth +@before_request +def not_found(e, info=None): + return render_template('not_found.html', e=e, info=info), 404 + + +@app.errorhandler(500) +@packet_auth +@before_request +def error(e, info=None): + return render_template('error.html', e=e, info=info), 500 diff --git a/packet/routes/upperclassmen.py b/packet/routes/upperclassmen.py index c8cdd7c..11bc2b1 100644 --- a/packet/routes/upperclassmen.py +++ b/packet/routes/upperclassmen.py @@ -1,6 +1,7 @@ """ Routes available to CSH users only """ +import json from itertools import chain from operator import itemgetter @@ -10,6 +11,7 @@ from packet import app from packet.models import Packet, MiscSignature from packet.utils import before_request, packet_auth from packet.log_utils import log_cache, log_time +from packet.stats import packet_stats @app.route('/') @@ -61,3 +63,44 @@ def upperclassmen_total(info=None): return render_template('upperclassmen_totals.html', info=info, num_open_packets=len(open_packets), upperclassmen=sorted(upperclassmen.items(), key=itemgetter(1), reverse=True)) + + +@app.route('/stats/packet/<packet_id>') +@packet_auth +@before_request +def packet_graphs(packet_id, info=None): + stats = packet_stats(packet_id) + fresh = [] + misc = [] + upper = [] + + + # Make a rolling sum of signatures over time + agg = lambda l, attr, date: l.append((l[-1] if l else 0) + len(stats['dates'][date][attr])) + dates = list(stats['dates'].keys()) + for date in dates: + agg(fresh, 'fresh', date) + agg(misc, 'misc', date) + agg(upper, 'upper', date) + + # Stack misc and upper on top of fresh for a nice stacked line graph + for i in range(len(dates)): + misc[i] = misc[i] + fresh[i] + upper[i] = upper[i] + misc[i] + + return render_template('packet_stats.html', + info=info, + data=json.dumps({ + 'dates':dates, + 'accum': { + 'fresh':fresh, + 'misc':misc, + 'upper':upper, + }, + 'daily': { + + } + }), + fresh=stats['freshman'], + packet=Packet.by_id(packet_id), + ) diff --git a/packet/static/js/admin.js b/packet/static/js/admin.js new file mode 100644 index 0000000..2cde58e --- /dev/null +++ b/packet/static/js/admin.js @@ -0,0 +1,158 @@ +$(document).ready(function () { + + let openPacketsTable = $('#open_packets_table'); + openPacketsTable.DataTable({ + "searching": true, + "order": [], + "scrollX": false, + "paging": true, + "info": false, + "columnDefs": [ + { + "targets": 0, + "max-width": "50%", + }, + { + "type": "num-fmt", + "targets": 1, + "visible": true, + "max-width": "15%", + } + ] + }); + + let allFreshmenTable = $('#all_freshmen_table'); + allFreshmenTable.DataTable({ + "searching": true, + "order": [], + "scrollX": false, + "paging": true, + "info": false, + }); + + $("#create-packets").click(() => { + makePackets(); + }); + + $("#sync-freshmen").click(() => { + syncFreshmen(); + }) + + $("#sync-ldap").click(() => { + syncLdap(); + }) + +}); + +// Is this gross, yes. Do I feel like cleaning it up yet, no. + +let makePackets = () => { + let freshmen = []; + let fileUpload = document.getElementById("newPacketsFile"); + let regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/; + if (regex.test(fileUpload.value.toLowerCase())) { + if (typeof (FileReader) != "undefined") { + let reader = new FileReader(); + reader.onload = (e) => { + let rows = e.target.result.split("\n"); + for (let i = 0; i < rows.length; i++) { + let cells = rows[i].split(","); + if (cells.length > 1) { + freshmen.push({ + rit_username: cells[3], + name: cells[0], + onfloor: cells[1] + }); + } + } + const payload = {start_date: $('#packet-start-date').val(), freshmen: freshmen} + if (freshmen.length >= 1) { + $("#create-packets").append(" <span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>"); + $("#create-packets").attr('disabled', true); + fetch('/api/v1/packets', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(payload) + } + ).then(response => { + if (response.status < 300) { + $('#new-packets-modal').modal('hide'); + location.reload(); + } else { + alert("There was an error creating packets") + } + }) + } + } + reader.readAsText(fileUpload.files[0]); + } + } +} + + +let syncFreshmen = () => { + let freshmen = []; + let fileUpload = document.getElementById("currentFroshFile"); + let regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/; + if (regex.test(fileUpload.value.toLowerCase())) { + if (typeof (FileReader) != "undefined") { + let reader = new FileReader(); + reader.onload = (e) => { + let rows = e.target.result.split("\n"); + for (let i = 0; i < rows.length; i++) { + let cells = rows[i].split(","); + if (cells.length > 1) { + freshmen.push({ + rit_username: cells[3], + name: cells[0], + onfloor: cells[1] + }); + } + } + if (freshmen.length >= 1) { + $("#sync-freshmen").append(" <span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>"); + $("#sync-freshmen").attr('disabled', true); + fetch('/api/v1/freshmen', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(freshmen) + } + ).then(response => { + if (response.status < 300) { + $('#sync-freshmen-modal').modal('hide'); + location.reload(); + } else { + alert("There was an error syncing freshmen") + } + }) + } + } + reader.readAsText(fileUpload.files[0]); + } + } +} + +let syncLdap = () => { + $("#sync-ldap").append(" <span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>"); + $("#sync-ldap").attr('disabled', true); + fetch('/api/v1/sync', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + } + ).then(response => { + if (response.status < 300) { + location.reload(); + } else { + alert("There was an error syncing with ldap") + } + }) +} diff --git a/packet/stats.py b/packet/stats.py new file mode 100644 index 0000000..2ac5fb2 --- /dev/null +++ b/packet/stats.py @@ -0,0 +1,113 @@ +from datetime import timedelta + +from packet.models import Packet, MiscSignature, UpperSignature + + +def packet_stats(packet_id): + """ + Gather statistics for a packet in the form of number of signatures per day + + Return format: { + packet_id, + freshman: { + name, + rit_username, + }, + dates: { + <date>: { + upper: [ uid ], + misc: [ uid ], + fresh: [ freshman_username ], + }, + }, + } + """ + packet = Packet.by_id(packet_id) + + dates = [packet.start.date() + timedelta(days=x) for x in range(0, (packet.end-packet.start).days + 1)] + + print(dates) + + upper_stats = {date: list() for date in dates} + for uid, date in map(lambda sig: (sig.member, sig.updated), + filter(lambda sig: sig.signed, packet.upper_signatures)): + upper_stats[date.date()].append(uid) + + fresh_stats = {date: list() for date in dates} + for username, date in map(lambda sig: (sig.freshman_username, sig.updated), + filter(lambda sig: sig.signed, packet.fresh_signatures)): + fresh_stats[date.date()].append(username) + + misc_stats = {date: list() for date in dates} + for uid, date in map(lambda sig: (sig.member, sig.updated), packet.misc_signatures): + misc_stats[date.date()].append(uid) + + total_stats = dict() + for date in dates: + total_stats[date.isoformat()] = { + 'upper': upper_stats[date], + 'fresh': fresh_stats[date], + 'misc': misc_stats[date], + } + + return { + 'packet_id': packet_id, + 'freshman': { + 'name': packet.freshman.name, + 'rit_username': packet.freshman.rit_username, + }, + 'dates': total_stats, + } + + +def sig2dict(sig): + """ + A utility function for upperclassman stats. + Converts an UpperSignature to a dictionary with the date and the packet. + """ + packet = Packet.by_id(sig.packet_id) + return { + 'date': sig.updated.date(), + 'packet': { + 'id': packet.id, + 'freshman_username': packet.freshman_username, + }, + } + + +def upperclassman_stats(uid): + """ + Gather statistics for an upperclassman's signature habits + + Return format: { + member: <uid>, + signautes: { + <date>: [{ + id: <packet_id>, + freshman_username, + }], + }, + } + """ + + sigs = UpperSignature.query.filter( + UpperSignature.signed, + UpperSignature.member == uid + ).all() + MiscSignature.query.filter(MiscSignature.member == uid).all() + + sig_dicts = list(map(sig2dict, sigs)) + + dates = set(map(lambda sd: sd['date'], sig_dicts)) + + return { + 'member': uid, + 'signatures': { + date.isoformat() : list( + map(lambda sd: sd['packet'], + filter(lambda sig, d=date: sig['date'] == d, + sig_dicts + ) + ) + ) for date in dates + } + } diff --git a/packet/templates/admin_freshmen.html b/packet/templates/admin_freshmen.html new file mode 100644 index 0000000..e922375 --- /dev/null +++ b/packet/templates/admin_freshmen.html @@ -0,0 +1,27 @@ +{% extends "extend/base.html" %} + +{% block body %} + <div class="container main"> + <div class="ml-4"> + <div class="row justify-content-between w-100"> + <div class="col-xs-10"> + <h4 class="page-title">All Freshmen</h4> + </div> + <div class="col-xs-2"> + <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#sync-freshmen-modal"> + Sync Freshmen + </button> + {% include 'include/admin/sync_freshmen.html' %} + </div> + </div> + </div> + <div id="eval-blocks"> + {% include 'include/admin/all_freshmen.html' %} + </div> + </div> +{% endblock %} + +{% block scripts %} + {{ super() }} + <script src="{{ url_for('static', filename='js/admin.min.js') }}"></script> +{% endblock %} diff --git a/packet/templates/admin_packets.html b/packet/templates/admin_packets.html new file mode 100644 index 0000000..9db36fd --- /dev/null +++ b/packet/templates/admin_packets.html @@ -0,0 +1,30 @@ +{% extends "extend/base.html" %} + +{% block body %} + <div class="container main"> + <div class="ml-4"> + <div class="row justify-content-between w-100"> + <div class="col-xs-10"> + <h4 class="page-title">Active Packets</h4> + </div> + <div class="col-xs-2"> + <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#new-packets-modal"> + Create new Packets + </button> + <button type="button" id="sync-ldap" class="btn btn-primary"> + Sync with LDAP + </button> + {% include 'include/admin/new_packets.html' %} + </div> + </div> + </div> + <div id="eval-blocks"> + {% include 'include/admin/open_packets.html' %} + </div> + </div> +{% endblock %} + +{% block scripts %} + {{ super() }} + <script src="{{ url_for('static', filename='js/admin.min.js') }}"></script> +{% endblock %} diff --git a/packet/templates/error.html b/packet/templates/error.html new file mode 100644 index 0000000..de33536 --- /dev/null +++ b/packet/templates/error.html @@ -0,0 +1,20 @@ +{% extends 'extend/base.html' %} + +{% block body %} + <div class="container main"> + <h1 class="card-title">Oops!</h1> + <div class="card mb-3"> + <div class="card-body" style="text-align: left;"> + <h5 class="card-text"> + I guess this is what you get when you trust a bunch of college kids. + </h5> + <p class="card-text"> + <pre><code>{{ e }}</code></pre> + </p> + <h5 class="card-text"> + Do us a favor, try again. If you end up here on the second try, <a href="mailto:rtp@csh.rit.edu">shoot us an email</a>. + </h5> + </div> + </div> + </div> +{% endblock %} diff --git a/packet/templates/include/admin/all_freshmen.html b/packet/templates/include/admin/all_freshmen.html new file mode 100644 index 0000000..a3e79e3 --- /dev/null +++ b/packet/templates/include/admin/all_freshmen.html @@ -0,0 +1,33 @@ +<div id="eval-table"> + <div class="card"> + <div class="card-body table-fill"> + <div class="table-responsive"> + <table id="all_freshmen_table" class="table table-striped no-bottom-margin"> + <thead> + <tr> + <th>Name</th> + <th>On-Floor</th> + </tr> + </thead> + <tbody> + {% for freshman in all_freshmen %} + {% set freshman_name = freshman.name + ' (' + freshman.rit_username + ')' %} + <tr> + <td data-priority="1"> + <img class="eval-user-img" + alt="{{ freshman_name }}" + src="{{ get_rit_image(freshman.rit_username) }}" + width="25" + height="25"/> {{ freshman_name }} + </td> + <td data-priority="2"> + {{ freshman.onfloor }} + </td> + </tr> + {% endfor %} + </tbody> + </table> + </div> + </div> + </div> +</div> diff --git a/packet/templates/include/admin/new_packets.html b/packet/templates/include/admin/new_packets.html new file mode 100644 index 0000000..c6dd307 --- /dev/null +++ b/packet/templates/include/admin/new_packets.html @@ -0,0 +1,23 @@ +<div class="modal fade" id="new-packets-modal" tabindex="-1" role="dialog" aria-labelledby="new-packets-modal-label" + aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="new-packets-modal-label">New Packets</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <div class="form-group"> + <input type="text" class="form-control" placeholder="Date Packets start (MM/DD/YYYY)" id="packet-start-date" required> + <input type="file" class="form-control custom-file" id="newPacketsFile" required> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> + <button type="submit" id="create-packets" class="btn btn-primary">Create Packets</button> + </div> + </div> + </div> +</div> diff --git a/packet/templates/include/admin/open_packets.html b/packet/templates/include/admin/open_packets.html new file mode 100644 index 0000000..275b622 --- /dev/null +++ b/packet/templates/include/admin/open_packets.html @@ -0,0 +1,39 @@ +<div id="eval-table"> + <div class="card"> + <div class="card-body table-fill"> + <div class="table-responsive"> + <table id="open_packets_table" class="table table-striped no-bottom-margin"> + <thead> + <tr> + <th>Name</th> + <th>Signatures</th> + </tr> + </thead> + <tbody> + {% for packet in open_packets %} + <tr> + <td data-priority="1"> + <a href="{{ url_for('freshman_packet', packet_id=packet.id) }}"> + <img class="eval-user-img" + alt="{{ get_rit_name(packet.freshman_username) }}" + src="{{ get_rit_image(packet.freshman_username) }}" + width="25" + height="25"/> {{ get_rit_name(packet.freshman_username) }} + </a> + </td> + <td data-sort="{{ packet.signatures_received_result.total }}"> + {% if packet.signatures_received_result.total == packet.signatures_required_result.total %} + 💯 {# 100% emoji #} + {% else %} + {{ packet.signatures_received_result.total }} / + {{ packet.signatures_required_result.total }} + {% endif %} + </td> + </tr> + {% endfor %} + </tbody> + </table> + </div> + </div> + </div> +</div> diff --git a/packet/templates/include/admin/sync_freshmen.html b/packet/templates/include/admin/sync_freshmen.html new file mode 100644 index 0000000..6f9b480 --- /dev/null +++ b/packet/templates/include/admin/sync_freshmen.html @@ -0,0 +1,22 @@ +<div class="modal fade" id="sync-freshmen-modal" tabindex="-1" role="dialog" aria-labelledby="sync-freshmen-modal-label" + aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="sync-freshmen-modal-label">Sync Freshmen</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <div class="form-group"> + <input type="file" class="form-control custom-file" id="currentFroshFile" required> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> + <button type="submit" id="sync-freshmen" class="btn btn-primary">Sync Freshmen</button> + </div> + </div> + </div> +</div> diff --git a/packet/templates/include/nav.html b/packet/templates/include/nav.html index fb8f2a6..470764d 100644 --- a/packet/templates/include/nav.html +++ b/packet/templates/include/nav.html @@ -18,6 +18,18 @@ <li class="nav-item"> <a class="nav-link" href="{{ url_for("upperclassmen_total") }}">Signatures</a> </li> + {% if info.admin %} + <li class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" + data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Admin + </a> + <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> + <a class="dropdown-item" href="{{ url_for("admin_freshmen") }}">Freshmen</a> + <a class="dropdown-item" href="{{ url_for("admin_packets") }}">Packets</a> + </div> + </li> + {% endif %} {% else %} <li class="nav-item"> <button id="freshman-report" class="btn btn-sm btn-default report-button">Report</button> diff --git a/packet/templates/not_found.html b/packet/templates/not_found.html new file mode 100644 index 0000000..e7cd876 --- /dev/null +++ b/packet/templates/not_found.html @@ -0,0 +1,17 @@ +{% extends 'extend/base.html' %} + +{% block body %} + <div class="container main"> + <h1 class="card-title">Page Not Found</h1> + <div class="card mb-3"> + <div class="card-body" style="text-align: left;"> + <h4 class="card-text"> + Not sure what you're looking for, but it's not here. + </h4> + <h5 class="card-text"> + Do us a favor, check your spelling. If you can't find what you're looking for, <a href="mailto:rtp@csh.rit.edu">shoot us an email</a>. + </h5> + </div> + </div> + </div> +{% endblock %} diff --git a/packet/templates/packet.html b/packet/templates/packet.html index 62708a7..8e30376 100644 --- a/packet/templates/packet.html +++ b/packet/templates/packet.html @@ -20,11 +20,19 @@ class="fa fa-check"></i> Signed </button> {% endif %} + {% if info.realm == "csh" %} + <a class="btn btn-primary" + style="float: right; margin-right: 5px" + href="{{ url_for('packet_graphs', packet_id=packet.id) }}"> + Graphs + </a> + {% endif %} </div> </div> <div class="row"> <div class="col ml-1 mb-1"> - <h6>Signatures: <span class="badge badge-secondary">{{ received.total }}/{{ required.total }}</span></h6> + <h6>Signatures: <span class="badge badge-secondary">{{ received.total }}/{{ required.total }}</span> + </h6> </div> <div class="col mr-1 mb-1"> <h6 class="right-align">Ends: <span class="badge badge-secondary">{{ packet_end }}</span></h6> diff --git a/packet/templates/packet_stats.html b/packet/templates/packet_stats.html new file mode 100644 index 0000000..7742397 --- /dev/null +++ b/packet/templates/packet_stats.html @@ -0,0 +1,84 @@ +{% extends "extend/base.html" %} + +{% block head %} +{{ super() }} +<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script> +{% endblock %} + +{% block body %} +<div class="container main"> + <div class="card"> + <h5 class="card-header bg-primary text-white">Cumulative Signatures Over Time for + <a class="text-white" href="{{ url_for('freshman_packet', packet_id=packet.id) }}"> + <img class="eval-user-img" + alt="{{ get_rit_name(packet.freshman_username) }}" + src="{{ get_rit_image(packet.freshman_username) }}" + width="25" + height="25"/> {{ get_rit_name(packet.freshman_username) }} + </a> +</h5> + <tr> + <td data-priority="1"> + </td> + </tr> + <div class="card-body"> + <canvas id="myChart" width="400" height="400"></canvas> + <script> +var data = {{ data|safe }}; +// Stack the lines +var ctx = document.getElementById('myChart'); +var myChart = new Chart(ctx, { + type: 'line', + data: { + labels: data.dates, + datasets: [ + { + fill: 'origin', + label: 'Fresh Sigs', + data: data.accum.fresh, + backgroundColor: '#b0197e80', + borderColor: '#b0197e', + borderWidth: 1, + lineTension: 0 + }, + { + fill: '-1', + label: 'Misc Sigs', + data: data.accum.misc, + backgroundColor: '#0000ff80', + borderColor: 'blue', + borderWidth: 1, + lineTension: 0 + }, + { + fill: '-1', + label: 'Upper Sigs', + data: data.accum.upper, + backgroundColor: '#00ff0080', + borderColor: 'green', + borderWidth: 1, + lineTension: 0 + } + ] + }, + options: { + scales: { + xAxes: [{ + type: 'time', + time: { + unit: 'day', + }, + }], + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } +}); + </script> + </div> + </div> +</div> +{% endblock %} diff --git a/packet/utils.py b/packet/utils.py index 317ef36..a01a1e3 100644 --- a/packet/utils.py +++ b/packet/utils.py @@ -1,37 +1,45 @@ """ General utilities and decorators for supporting the Python logic """ - +from datetime import datetime, time, timedelta, date from functools import wraps, lru_cache import requests from flask import session, redirect -from packet import auth, app -from packet.models import Freshman -from packet.ldap import ldap_get_member, ldap_is_intromember +from packet import auth, app, db +from packet.mail import send_start_packet_mail +from packet.models import Freshman, FreshSignature, Packet, UpperSignature, MiscSignature +from packet.ldap import ldap_get_member, ldap_is_intromember, ldap_is_evals, ldap_is_on_coop, \ + ldap_get_active_members, ldap_get_active_rtps, ldap_get_3das, ldap_get_webmasters, \ + ldap_get_constitutional_maintainers, ldap_get_drink_admins, ldap_get_eboard_role +from packet.notifications import packets_starting_notification, packet_starting_notification INTRO_REALM = 'https://sso.csh.rit.edu/auth/realms/intro' + def before_request(func): """ Credit to Liam Middlebrook and Ram Zallan https://github.com/liam-middlebrook/gallery """ + @wraps(func) def wrapped_function(*args, **kwargs): uid = str(session['userinfo'].get('preferred_username', '')) - if session['id_token']['iss'] == INTRO_REALM: info = { 'realm': 'intro', 'uid': uid, - 'onfloor': is_freshman_on_floor(uid) + 'onfloor': is_freshman_on_floor(uid), + 'admin': False # It's always false if frosh } else: + member = ldap_get_member(uid) info = { 'realm': 'csh', - 'uid': uid + 'uid': uid, + 'admin': ldap_is_evals(member) } kwargs['info'] = info @@ -56,6 +64,7 @@ def packet_auth(func): """ Decorator for easily configuring oidc """ + @auth.oidc_auth('app') @wraps(func) def wrapped_function(*args, **kwargs): @@ -70,6 +79,28 @@ def packet_auth(func): return wrapped_function +def admin_auth(func): + """ + Decorator for easily configuring oidc + """ + + @auth.oidc_auth('app') + @wraps(func) + def wrapped_function(*args, **kwargs): + if app.config['REALM'] == 'csh': + username = str(session['userinfo'].get('preferred_username', '')) + member = ldap_get_member(username) + if not ldap_is_evals(member): + app.logger.warn('Stopped member {} from accessing admin UI'.format(username)) + return redirect(app.config['PROTOCOL'] + app.config['PACKET_UPPER'], code=301) + else: + return redirect(app.config['PROTOCOL'] + app.config['PACKET_INTRO'], code=301) + + return func(*args, **kwargs) + + return wrapped_function + + def notify_slack(name: str): """ Sends a congratulate on sight decree to Slack @@ -79,5 +110,144 @@ def notify_slack(name: str): return msg = f':pizza-party: {name} got :100: on packet! :pizza-party:' - requests.put(app.config['SLACK_WEBHOOK_URL'], json={'text':msg}) + requests.put(app.config['SLACK_WEBHOOK_URL'], json={'text': msg}) app.logger.info('Posted 100% notification to slack for ' + name) + + +def sync_freshman(freshmen_list: dict): + freshmen_in_db = {freshman.rit_username: freshman for freshman in Freshman.query.all()} + + for list_freshman in freshmen_list.values(): + if list_freshman.rit_username not in freshmen_in_db: + # This is a new freshman so add them to the DB + freshmen_in_db[list_freshman.rit_username] = Freshman(rit_username=list_freshman.rit_username, + name=list_freshman.name, + onfloor=list_freshman.onfloor) + db.session.add(freshmen_in_db[list_freshman.rit_username]) + else: + # This freshman is already in the DB so just update them + freshmen_in_db[list_freshman.rit_username].onfloor = list_freshman.onfloor + freshmen_in_db[list_freshman.rit_username].name = list_freshman.name + + # Update all freshmen entries that represent people who are no longer freshmen + for freshman in filter(lambda freshman: freshman.rit_username not in freshmen_list, freshmen_in_db.values()): + freshman.onfloor = False + + # Update the freshmen signatures of each open or future packet + for packet in Packet.query.filter(Packet.end > datetime.now()).all(): + # Handle the freshmen that are no longer onfloor + for fresh_sig in filter(lambda fresh_sig: not fresh_sig.freshman.onfloor, packet.fresh_signatures): + FreshSignature.query.filter_by(packet_id=fresh_sig.packet_id, + freshman_username=fresh_sig.freshman_username).delete() + + # Add any new onfloor freshmen + # pylint: disable=cell-var-from-loop + current_fresh_sigs = set(map(lambda fresh_sig: fresh_sig.freshman_username, packet.fresh_signatures)) + for list_freshman in filter(lambda list_freshman: list_freshman.rit_username not in current_fresh_sigs and + list_freshman.onfloor and + list_freshman.rit_username != packet.freshman_username, + freshmen_list.values()): + db.session.add(FreshSignature(packet=packet, freshman=freshmen_in_db[list_freshman.rit_username])) + + db.session.commit() + + +def create_new_packets(base_date: date, freshmen_list: dict): + packet_start_time = time(hour=19) + packet_end_time = time(hour=21) + start = datetime.combine(base_date, packet_start_time) + end = datetime.combine(base_date, packet_end_time) + timedelta(days=14) + + print('Fetching data from LDAP...') + all_upper = list(filter( + lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())) + + rtp = ldap_get_active_rtps() + three_da = ldap_get_3das() + webmaster = ldap_get_webmasters() + c_m = ldap_get_constitutional_maintainers() + drink = ldap_get_drink_admins() + + # Packet starting notifications + packets_starting_notification(start) + + # Create the new packets and the signatures for each freshman in the given CSV + print('Creating DB entries and sending emails...') + for freshman in Freshman.query.filter(Freshman.rit_username.in_(freshmen_list)).all(): + packet = Packet(freshman=freshman, start=start, end=end) + db.session.add(packet) + send_start_packet_mail(packet) + packet_starting_notification(packet) + + for member in all_upper: + sig = UpperSignature(packet=packet, member=member.uid) + sig.eboard = ldap_get_eboard_role(member) + sig.active_rtp = member.uid in rtp + sig.three_da = member.uid in three_da + sig.webmaster = member.uid in webmaster + sig.c_m = member.uid in c_m + sig.drink_admin = member.uid in drink + db.session.add(sig) + + for onfloor_freshman in Freshman.query.filter_by(onfloor=True).filter(Freshman.rit_username != + freshman.rit_username).all(): + db.session.add(FreshSignature(packet=packet, freshman=onfloor_freshman)) + + db.session.commit() + + +def sync_with_ldap(): + print('Fetching data from LDAP...') + all_upper = {member.uid: member for member in filter( + lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())} + + rtp = ldap_get_active_rtps() + three_da = ldap_get_3das() + webmaster = ldap_get_webmasters() + c_m = ldap_get_constitutional_maintainers() + drink = ldap_get_drink_admins() + + print('Applying updates to the DB...') + for packet in Packet.query.filter(Packet.end > datetime.now()).all(): + # Update the role state of all UpperSignatures + for sig in filter(lambda sig: sig.member in all_upper, packet.upper_signatures): + sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) + sig.active_rtp = sig.member in rtp + sig.three_da = sig.member in three_da + sig.webmaster = sig.member in webmaster + sig.c_m = sig.member in c_m + sig.drink_admin = sig.member in drink + + # Migrate UpperSignatures that are from accounts that are not active anymore + for sig in filter(lambda sig: sig.member not in all_upper, packet.upper_signatures): + UpperSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete() + if sig.signed: + sig = MiscSignature(packet=packet, member=sig.member) + db.session.add(sig) + + # Migrate MiscSignatures that are from accounts that are now active members + for sig in filter(lambda sig: sig.member in all_upper, packet.misc_signatures): + MiscSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete() + sig = UpperSignature(packet=packet, member=sig.member, signed=True) + sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) + sig.active_rtp = sig.member in rtp + sig.three_da = sig.member in three_da + sig.webmaster = sig.member in webmaster + sig.c_m = sig.member in c_m + sig.drink_admin = sig.member in drink + db.session.add(sig) + + # Create UpperSignatures for any new active members + # pylint: disable=cell-var-from-loop + upper_sigs = set(map(lambda sig: sig.member, packet.upper_signatures)) + for member in filter(lambda member: member not in upper_sigs, all_upper): + sig = UpperSignature(packet=packet, member=member) + sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) + sig.active_rtp = sig.member in rtp + sig.three_da = sig.member in three_da + sig.webmaster = sig.member in webmaster + sig.c_m = sig.member in c_m + sig.drink_admin = sig.member in drink + db.session.add(sig) + + db.session.commit() diff --git a/requirements.txt b/requirements.txt index 77e5d98..d97e06f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,4 +10,4 @@ gunicorn~=19.7.1 csh_ldap~=2.1.0 onesignal-sdk~=1.0.0 pylint-quotes~=0.2.1 -sentry-sdk==0.13.1 +sentry-sdk~=0.14.2 @@ -7,12 +7,12 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -ajv@^6.5.5: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== +ajv@^6.12.3: + version "6.12.4" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" + integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== dependencies: - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" @@ -60,12 +60,17 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -246,16 +251,16 @@ async-settle@^1.0.0: async-done "^1.2.2" async@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.1.0.tgz#42b3b12ae1b74927b5217d8c0016baaf62463772" - integrity sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ== + version "3.2.0" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" + integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -atob@^2.1.1: +atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== @@ -266,9 +271,9 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + version "1.10.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428" + integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA== axios@^0.18.0: version "0.18.1" @@ -331,6 +336,13 @@ binary@~0.3.0: buffers "~0.1.1" chainsaw "~0.1.0" +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" @@ -415,6 +427,11 @@ camelcase@^3.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -470,9 +487,9 @@ cheerio@*: lodash.some "^4.4.0" chokidar@^2.0.0: - version "2.1.6" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" - integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" async-each "^1.0.1" @@ -488,11 +505,6 @@ chokidar@^2.0.0: optionalDependencies: fsevents "^1.2.7" -chownr@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -503,10 +515,10 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -clean-css@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" - integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== +clean-css@4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== dependencies: source-map "~0.6.0" @@ -519,6 +531,15 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + clone-buffer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" @@ -590,9 +611,9 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: delayed-stream "~1.0.0" commander@^2.19.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== component-emitter@^1.2.1: version "1.3.0" @@ -620,9 +641,9 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= convert-source-map@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" @@ -674,7 +695,7 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" -d@1: +d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== @@ -703,14 +724,7 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -decamelize@^1.1.1, decamelize@^1.1.2: +decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -720,11 +734,6 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - default-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" @@ -781,15 +790,10 @@ detect-file@^1.0.0: resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - dom-serializer@0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.1.tgz#13650c850daffea35d8b626a4cfc4d3a17643fdb" - integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q== + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== dependencies: domelementtype "^2.0.1" entities "^2.0.0" @@ -861,10 +865,15 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" @@ -874,9 +883,9 @@ entities@^1.1.1, entities@~1.1.1: integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" - integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== error-ex@^1.2.0: version "1.3.2" @@ -885,14 +894,14 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@~0.10.14: - version "0.10.50" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778" - integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw== +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== dependencies: es6-iterator "~2.0.3" - es6-symbol "~3.1.1" - next-tick "^1.0.0" + es6-symbol "~3.1.3" + next-tick "~1.0.0" es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3: version "2.0.3" @@ -903,13 +912,13 @@ es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-symbol@^3.1.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== dependencies: - d "1" - es5-ext "~0.10.14" + d "^1.0.1" + ext "^1.1.2" es6-weak-map@^2.0.1: version "2.0.3" @@ -946,6 +955,13 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + extend-shallow@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" @@ -1007,15 +1023,25 @@ fancy-log@^1.3.2: parse-node-version "^1.0.0" time-stamp "^1.0.0" -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9" + integrity sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk= + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== fill-range@^4.0.0: version "4.0.0" @@ -1035,6 +1061,13 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + findup-sync@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" @@ -1119,13 +1152,6 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fs-minipass@^1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" - integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== - dependencies: - minipass "^2.2.1" - fs-mkdirp-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" @@ -1140,12 +1166,12 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: - version "1.2.9" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" - integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== dependencies: + bindings "^1.5.0" nan "^2.12.1" - node-pre-gyp "^0.12.0" fstream@^1.0.0, fstream@^1.0.12, fstream@^1.0.2, fstream@~1.0.12: version "1.0.12" @@ -1188,6 +1214,11 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -1230,21 +1261,22 @@ glob-stream@^6.1.0: unique-stream "^2.0.2" glob-watcher@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.3.tgz#88a8abf1c4d131eb93928994bc4a593c2e5dd626" - integrity sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg== + version "5.0.5" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.5.tgz#aa6bce648332924d9a8489be41e3e5c52d4186dc" + integrity sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw== dependencies: anymatch "^2.0.0" async-done "^1.2.0" chokidar "^2.0.0" is-negated-glob "^1.0.0" just-debounce "^1.0.0" + normalize-path "^3.0.0" object.defaults "^1.1.0" glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -1274,9 +1306,9 @@ global-prefix@^1.0.1: which "^1.2.14" globule@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" - integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.2.tgz#d8bdd9e9e4eef8f96e245999a5dee7eb5d8529c4" + integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA== dependencies: glob "~7.1.1" lodash "~4.17.10" @@ -1290,24 +1322,24 @@ glogg@^1.0.0: sparkles "^1.0.0" graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.2.1" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.1.tgz#1c1f0c364882c868f5bff6512146328336a11b1d" - integrity sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw== + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== gulp-clean-css@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/gulp-clean-css/-/gulp-clean-css-4.2.0.tgz#915ec258dc6d3e6a50043f610066d5c2eac4f54e" - integrity sha512-r4zQsSOAK2UYUL/ipkAVCTRg/2CLZ2A+oPVORopBximRksJ6qy3EX1KGrIWT4ZrHxz3Hlobb1yyJtqiut7DNjA== + version "4.3.0" + resolved "https://registry.yarnpkg.com/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz#5b1e73f2fca46703eb636014cdd4553cea65146d" + integrity sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg== dependencies: - clean-css "4.2.1" + clean-css "4.2.3" plugin-error "1.0.1" through2 "3.0.1" vinyl-sourcemaps-apply "0.2.1" gulp-cli@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.2.0.tgz#5533126eeb7fe415a7e3e84a297d334d5cf70ebc" - integrity sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f" + integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A== dependencies: ansi-colors "^1.0.1" archy "^1.0.0" @@ -1317,7 +1349,7 @@ gulp-cli@^2.2.0: copy-props "^2.0.1" fancy-log "^1.3.2" gulplog "^1.0.0" - interpret "^1.1.0" + interpret "^1.4.0" isobject "^3.0.1" liftoff "^3.1.0" matchdep "^2.0.0" @@ -1325,7 +1357,7 @@ gulp-cli@^2.2.0: pretty-hrtime "^1.0.0" replace-homedir "^1.0.0" semver-greatest-satisfied-range "^1.1.0" - v8flags "^3.0.1" + v8flags "^3.2.0" yargs "^7.1.0" gulp-minify@^3.1.0: @@ -1357,12 +1389,12 @@ gulp-rename@^1.4.0: integrity sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg== gulp-sass@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-4.0.2.tgz#cfb1e3eff2bd9852431c7ce87f43880807d8d505" - integrity sha512-q8psj4+aDrblJMMtRxihNBdovfzGrXJp1l4JU0Sz4b/Mhsi2DPrKFYCGDwjIWRENs04ELVHxdOJQ7Vs98OFohg== + version "4.1.0" + resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-4.1.0.tgz#486d7443c32d42bf31a6b1573ebbdaa361de7427" + integrity sha512-xIiwp9nkBLcJDpmYHbEHdoWZv+j+WtYaKD6Zil/67F3nrAaZtWYN5mDwerdo7EvcdBenSAj7Xb2hx2DqURLGdA== dependencies: chalk "^2.3.0" - lodash.clonedeep "^4.3.2" + lodash "^4.17.11" node-sass "^4.8.3" plugin-error "^1.0.1" replace-ext "^1.0.0" @@ -1392,12 +1424,12 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== dependencies: - ajv "^6.5.5" + ajv "^6.12.3" har-schema "^2.0.0" has-ansi@^2.0.0: @@ -1413,9 +1445,9 @@ has-flag@^3.0.0: integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== has-unicode@^2.0.0: version "2.0.1" @@ -1461,11 +1493,9 @@ homedir-polyfill@^1.0.1: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: - version "2.8.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.2.tgz#a35c3f355ac1249f1093c0c2a542ace8818c171a" - integrity sha512-CyjlXII6LMsPMyUzxpTt8fzh5QwzGqPmQXgY/Jyf4Zfp27t/FvfhwoE/8laaMUcMy816CkWF20I7NeQhwwY88w== - dependencies: - lru-cache "^5.1.1" + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== htmlparser2@^3.9.1: version "3.10.1" @@ -1488,24 +1518,10 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" -iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - in-publish@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" - integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= + version "2.0.1" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" + integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== indent-string@^2.1.0: version "2.1.0" @@ -1527,15 +1543,15 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.4, ini@~1.3.0: +ini@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== -interpret@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== +interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== invert-kv@^1.0.0: version "1.0.0" @@ -1582,9 +1598,9 @@ is-buffer@^1.1.5: integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-buffer@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" - integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" + integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== is-data-descriptor@^0.1.4: version "0.1.4" @@ -1636,11 +1652,9 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= - dependencies: - number-is-nan "^1.0.0" + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== is-fullwidth-code-point@^1.0.0: version "1.0.0" @@ -1759,9 +1773,9 @@ isstream@~0.1.2: integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= js-base64@^2.1.8: - version "2.5.1" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" - integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== + version "2.6.4" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" + integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== jsbn@~0.1.0: version "0.1.1" @@ -1828,9 +1842,9 @@ kind-of@^5.0.0, kind-of@^5.0.2: integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== last-run@^1.1.0: version "1.1.1" @@ -1886,6 +1900,14 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash.assignin@^4.0.9: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" @@ -1896,11 +1918,6 @@ lodash.bind@^4.1.4: resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= -lodash.clonedeep@^4.3.2: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.defaults@^4.0.1: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -1951,10 +1968,10 @@ lodash.some@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= -lodash@^4.0.0, lodash@^4.17.11, lodash@~4.17.10: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.15, lodash@~4.17.10: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== loud-rejection@^1.0.0: version "1.6.0" @@ -1972,13 +1989,6 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - make-iterator@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" @@ -2066,17 +2076,17 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -mime-db@1.40.0: - version "1.40.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" - integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.24" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" - integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: - mime-db "1.40.0" + mime-db "1.44.0" minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" @@ -2085,30 +2095,10 @@ minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.2.1, minipass@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== - dependencies: - minipass "^2.2.1" +minimist@^1.1.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== mixin-deep@^1.2.0: version "1.3.2" @@ -2118,32 +2108,32 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@*, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= +mkdirp@*: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: - minimist "0.0.8" + minimist "^1.2.5" ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - mute-stdout@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== nan@^2.12.1, nan@^2.13.2: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== nanomatch@^1.2.9: version "1.2.13" @@ -2162,16 +2152,7 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -needle@^2.2.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - -next-tick@^1.0.0: +next-tick@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= @@ -2194,26 +2175,10 @@ node-gyp@^3.8.0: tar "^2.0.0" which "1" -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - node-sass@^4.8.3: - version "4.12.0" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017" - integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ== + version "4.14.1" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.14.1.tgz#99c87ec2efb7047ed638fb4c9db7f3a42e2217b5" + integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g== dependencies: async-foreach "^0.1.3" chalk "^1.1.1" @@ -2222,14 +2187,14 @@ node-sass@^4.8.3: get-stdin "^4.0.1" glob "^7.0.3" in-publish "^2.0.0" - lodash "^4.17.11" + lodash "^4.17.15" meow "^3.7.0" mkdirp "^0.5.1" nan "^2.13.2" node-gyp "^3.8.0" npmlog "^4.0.0" request "^2.88.0" - sass-graph "^2.2.4" + sass-graph "2.2.5" stdout-stream "^1.4.0" "true-case-path" "^1.0.2" @@ -2252,14 +2217,6 @@ node-unzip-2@^0.2.7: dependencies: abbrev "1" -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -2289,20 +2246,7 @@ now-and-later@^2.0.0: dependencies: once "^1.3.2" -npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== - -npm-packlist@^1.1.6: - version "1.4.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" - integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -2355,7 +2299,7 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.0.4: +object.assign@^4.0.4, object.assign@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== @@ -2429,7 +2373,7 @@ os-tmpdir@^1.0.0: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@0, osenv@^0.1.4: +osenv@0: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -2442,6 +2386,25 @@ osenv@0, osenv@^0.1.4: resolved "https://registry.yarnpkg.com/over/-/over-0.0.5.tgz#f29852e70fd7e25f360e013a8ec44c82aedb5708" integrity sha1-8phS5w/X4l82DgE6jsRMgq7bVwg= +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + parse-filepath@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" @@ -2485,6 +2448,11 @@ path-exists@^2.0.0: dependencies: pinkie-promise "^2.0.0" +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -2579,10 +2547,10 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.24: - version "1.3.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.3.0.tgz#e1ebf6a3b5564fa8376f3da2275da76d875ca1bd" - integrity sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag== +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== pullstream@~0.4.0: version "0.4.1" @@ -2611,12 +2579,7 @@ pumpify@^1.3.5: inherits "^2.0.3" pump "^2.0.0" -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -2626,16 +2589,6 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -2654,18 +2607,18 @@ read-pkg@^1.0.0: path-type "^1.0.0" "readable-stream@2 || 3", readable-stream@^3.1.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -2757,9 +2710,9 @@ repeating@^2.0.0: is-finite "^1.0.0" replace-ext@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== replace-homedir@^1.0.0: version "1.0.0" @@ -2771,9 +2724,9 @@ replace-homedir@^1.0.0: remove-trailing-separator "^1.1.0" request@^2.87.0, request@^2.88.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -2782,7 +2735,7 @@ request@^2.87.0, request@^2.88.0: extend "~3.0.2" forever-agent "~0.6.1" form-data "~2.3.2" - har-validator "~5.1.0" + har-validator "~5.1.3" http-signature "~1.2.0" is-typedarray "~1.0.0" isstream "~0.1.2" @@ -2792,7 +2745,7 @@ request@^2.87.0, request@^2.88.0: performance-now "^2.1.0" qs "~6.5.2" safe-buffer "^5.1.2" - tough-cookie "~2.4.3" + tough-cookie "~2.5.0" tunnel-agent "^0.6.0" uuid "^3.3.2" @@ -2811,6 +2764,11 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" @@ -2832,9 +2790,9 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.4.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" - integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: path-parse "^1.0.6" @@ -2844,9 +2802,9 @@ ret@~0.1.10: integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== rfg-api@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/rfg-api/-/rfg-api-0.5.0.tgz#8916dcc75df93e5880f64878affe00b5fe84ace8" - integrity sha512-wd6BcVoBsEHlbfsaB1WD4Z/Xis4uEP+Qctd3u2jxXR5yTkCYENaB/m3Jsk0G2qToKgAeE+6tbsN6T0n8DHcSaw== + version "0.5.1" + resolved "https://registry.yarnpkg.com/rfg-api/-/rfg-api-0.5.1.tgz#6465f45ebe6434f7dc0ff2b1bb0504a2ef3abbdd" + integrity sha512-F4JJDx7gTFcGNybw+0trDFSYjuy2hbdqDqdaNBkMdSVlasglkfwyTWHTFqSUOLszbpZLwatLy0dxAJonNZi6hw== dependencies: axios "^0.18.0" fstream "^1.0.2" @@ -2854,17 +2812,17 @@ rfg-api@^0.5.0: mkdirp "^0.5.0" node-unzip-2 "^0.2.7" -rimraf@2, rimraf@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== +rimraf@2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" @@ -2878,25 +2836,20 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass-graph@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" - integrity sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k= +sass-graph@2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.5.tgz#a981c87446b8319d96dce0671e487879bd24c2e8" + integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag== dependencies: glob "^7.0.0" lodash "^4.0.0" scss-tokenizer "^0.2.3" - yargs "^7.0.0" - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + yargs "^13.3.2" scss-tokenizer@^0.2.3: version "0.2.3" @@ -2913,10 +2866,10 @@ semver-greatest-satisfied-range@^1.1.0: dependencies: sver-compat "^1.5.0" -"semver@2 || 3 || 4 || 5", semver@^5.3.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== +"semver@2 || 3 || 4 || 5": + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@~5.3.0: version "5.3.0" @@ -2944,9 +2897,9 @@ set-value@^2.0.0, set-value@^2.0.1: integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== "slice-stream@>= 1.0.0 < 2": version "1.0.0" @@ -2986,20 +2939,20 @@ snapdragon@^0.8.1: use "^3.1.0" source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: - atob "^2.1.1" + atob "^2.1.2" decode-uri-component "^0.2.0" resolve-url "^0.2.1" source-map-url "^0.4.0" urix "^0.1.0" source-map-support@~0.5.10: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -3032,22 +2985,22 @@ sparkles@^1.0.0: integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" @@ -3105,9 +3058,9 @@ stream-exhaust@^1.0.1: integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" @@ -3126,6 +3079,15 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -3159,6 +3121,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -3173,11 +3142,6 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -3207,19 +3171,6 @@ tar@^2.0.0: fstream "^1.0.12" inherits "2" -tar@^4: - version "4.4.10" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" - integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.5" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - terser@^3.7.6: version "3.17.0" resolved "https://registry.yarnpkg.com/terser/-/terser-3.17.0.tgz#f88ffbeda0deb5637f9d24b0da66f4e15ab10cb2" @@ -3297,13 +3248,13 @@ to-through@^2.0.0: dependencies: through2 "^2.0.3" -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== dependencies: - psl "^1.1.24" - punycode "^1.4.1" + psl "^1.1.28" + punycode "^2.1.1" "traverse@>=0.3.0 <0.4": version "0.3.9" @@ -3335,9 +3286,14 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= type@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/type/-/type-1.0.3.tgz#16f5d39f27a2d28d86e48f8981859e9d3296c179" - integrity sha512-51IMtNfVcee8+9GJvj0spSuFcZHe9vSib6Xtgsny1Km9ugyz2mbS08I3rsUIRYgJohFRFU1160sgRodYz378Hg== + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" + integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA== typedarray@^0.0.6: version "0.0.6" @@ -3350,9 +3306,9 @@ unc-path-regex@^0.1.2: integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= underscore@*: - version "1.9.1" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" - integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== + version "1.10.2" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf" + integrity sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg== undertaker-registry@^1.0.0: version "1.0.1" @@ -3360,15 +3316,16 @@ undertaker-registry@^1.0.0: integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA= undertaker@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.2.1.tgz#701662ff8ce358715324dfd492a4f036055dfe4b" - integrity sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.3.0.tgz#363a6e541f27954d5791d6fa3c1d321666f86d18" + integrity sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg== dependencies: arr-flatten "^1.0.1" arr-map "^2.0.0" bach "^1.0.0" collection-map "^1.0.0" es6-weak-map "^2.0.1" + fast-levenshtein "^1.0.0" last-run "^1.1.0" object.defaults "^1.0.0" object.reduce "^1.0.0" @@ -3401,9 +3358,9 @@ unset-value@^1.0.0: isobject "^3.0.0" upath@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" - integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: version "4.2.2" @@ -3428,14 +3385,14 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= uuid@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -v8flags@^3.0.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.3.tgz#fc9dc23521ca20c5433f81cc4eb9b3033bb105d8" - integrity sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w== +v8flags@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" + integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== dependencies: homedir-polyfill "^1.0.1" @@ -3521,6 +3478,11 @@ which-module@^1.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + which@1, which@^1.2.14, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -3543,6 +3505,15 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -3558,27 +3529,52 @@ y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== - -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= +yargs-parser@5.0.0-security.0: + version "5.0.0-security.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz#4ff7271d25f90ac15643b86076a2ab499ec9ee24" + integrity sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ== dependencies: camelcase "^3.0.0" + object.assign "^4.1.0" + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + 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" -yargs@^7.0.0, yargs@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" - integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= +yargs@^7.1.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.1.tgz#67f0ef52e228d4ee0d6311acede8850f53464df6" + integrity sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g== dependencies: camelcase "^3.0.0" cliui "^3.2.0" @@ -3592,4 +3588,4 @@ yargs@^7.0.0, yargs@^7.1.0: string-width "^1.0.2" which-module "^1.0.0" y18n "^3.2.1" - yargs-parser "^5.0.0" + yargs-parser "5.0.0-security.0" |