`, and ``.
+$font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace !default;
+$font-family-base: $font-family-sans-serif !default;
+
+$font-size-base: 14px !default;
+$font-size-large: ceil(($font-size-base * 1.25)) !default; // ~18px
+$font-size-small: ceil(($font-size-base * 0.85)) !default; // ~12px
+
+$font-size-h1: floor(($font-size-base * 2.6)) !default; // ~36px
+$font-size-h2: floor(($font-size-base * 2.15)) !default; // ~30px
+$font-size-h3: ceil(($font-size-base * 1.7)) !default; // ~24px
+$font-size-h4: ceil(($font-size-base * 1.25)) !default; // ~18px
+$font-size-h5: $font-size-base !default;
+$font-size-h6: ceil(($font-size-base * 0.85)) !default; // ~12px
+
+//** Unit-less `line-height` for use in components like buttons.
+$line-height-base: 1.428571429 !default; // 20/14
+//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
+$line-height-computed: floor(($font-size-base * $line-height-base)) !default; // ~20px
+
+//** By default, this inherits from the ``.
+$headings-font-family: inherit !default;
+$headings-font-weight: 500 !default;
+$headings-line-height: 1.1 !default;
+$headings-color: inherit !default;
+
+
+//== Iconography
+//
+//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
+
+//** Load fonts from this directory.
+
+// [converter] If $bootstrap-sass-asset-helper if used, provide path relative to the assets load path.
+// [converter] This is because some asset helpers, such as Sprockets, do not work with file-relative paths.
+$icon-font-path: if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/") !default;
+
+//** File name for all font files.
+$icon-font-name: "glyphicons-halflings-regular" !default;
+//** Element ID within SVG icon file.
+$icon-font-svg-id: "glyphicons_halflingsregular" !default;
+
+
+//== Components
+//
+//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
+
+$padding-base-vertical: 6px !default;
+$padding-base-horizontal: 12px !default;
+
+$padding-large-vertical: 10px !default;
+$padding-large-horizontal: 16px !default;
+
+$padding-small-vertical: 5px !default;
+$padding-small-horizontal: 10px !default;
+
+$padding-xs-vertical: 1px !default;
+$padding-xs-horizontal: 5px !default;
+
+$line-height-large: 1.3333333 !default; // extra decimals for Win 8.1 Chrome
+$line-height-small: 1.5 !default;
+
+$border-radius-base: 4px !default;
+$border-radius-large: 6px !default;
+$border-radius-small: 3px !default;
+
+//** Global color for active items (e.g., navs or dropdowns).
+$component-active-color: #fff !default;
+//** Global background color for active items (e.g., navs or dropdowns).
+$component-active-bg: $brand-primary !default;
+
+//** Width of the `border` for generating carets that indicate dropdowns.
+$caret-width-base: 4px !default;
+//** Carets increase slightly in size for larger components.
+$caret-width-large: 5px !default;
+
+
+//== Tables
+//
+//## Customizes the `.table` component with basic values, each used across all table variations.
+
+//** Padding for ``s and ` `s.
+$table-cell-padding: 8px !default;
+//** Padding for cells in `.table-condensed`.
+$table-condensed-cell-padding: 5px !default;
+
+//** Default background color used for all tables.
+$table-bg: transparent !default;
+//** Background color used for `.table-striped`.
+$table-bg-accent: #f9f9f9 !default;
+//** Background color used for `.table-hover`.
+$table-bg-hover: #f5f5f5 !default;
+$table-bg-active: $table-bg-hover !default;
+
+//** Border color for table and cell borders.
+$table-border-color: #ddd !default;
+
+
+//== Buttons
+//
+//## For each of Bootstrap's buttons, define text, background and border color.
+
+$btn-font-weight: normal !default;
+
+$btn-default-color: #333 !default;
+$btn-default-bg: #fff !default;
+$btn-default-border: #ccc !default;
+
+$btn-primary-color: #fff !default;
+$btn-primary-bg: $brand-primary !default;
+$btn-primary-border: darken($btn-primary-bg, 5%) !default;
+
+$btn-success-color: #fff !default;
+$btn-success-bg: $brand-success !default;
+$btn-success-border: darken($btn-success-bg, 5%) !default;
+
+$btn-info-color: #fff !default;
+$btn-info-bg: $brand-info !default;
+$btn-info-border: darken($btn-info-bg, 5%) !default;
+
+$btn-warning-color: #fff !default;
+$btn-warning-bg: $brand-warning !default;
+$btn-warning-border: darken($btn-warning-bg, 5%) !default;
+
+$btn-danger-color: #fff !default;
+$btn-danger-bg: $brand-danger !default;
+$btn-danger-border: darken($btn-danger-bg, 5%) !default;
+
+$btn-link-disabled-color: $gray-light !default;
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius-base: $border-radius-base !default;
+$btn-border-radius-large: $border-radius-large !default;
+$btn-border-radius-small: $border-radius-small !default;
+
+
+//== Forms
+//
+//##
+
+//** ` ` background color
+$input-bg: #fff !default;
+//** ` ` background color
+$input-bg-disabled: $gray-lighter !default;
+
+//** Text color for ` `s
+$input-color: $gray !default;
+//** ` ` border color
+$input-border: #ccc !default;
+
+// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
+//** Default `.form-control` border radius
+// This has no effect on ``s in some browsers, due to the limited stylability of ``s in CSS.
+$input-border-radius: $border-radius-base !default;
+//** Large `.form-control` border radius
+$input-border-radius-large: $border-radius-large !default;
+//** Small `.form-control` border radius
+$input-border-radius-small: $border-radius-small !default;
+
+//** Border color for inputs on focus
+$input-border-focus: #66afe9 !default;
+
+//** Placeholder text color
+$input-color-placeholder: #999 !default;
+
+//** Default `.form-control` height
+$input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2) !default;
+//** Large `.form-control` height
+$input-height-large: (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default;
+//** Small `.form-control` height
+$input-height-small: (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default;
+
+//** `.form-group` margin
+$form-group-margin-bottom: 15px !default;
+
+$legend-color: $gray-dark !default;
+$legend-border-color: #e5e5e5 !default;
+
+//** Background color for textual input addons
+$input-group-addon-bg: $gray-lighter !default;
+//** Border color for textual input addons
+$input-group-addon-border-color: $input-border !default;
+
+//** Disabled cursor for form controls and buttons.
+$cursor-disabled: not-allowed !default;
+
+
+//== Dropdowns
+//
+//## Dropdown menu container and contents.
+
+//** Background for the dropdown menu.
+$dropdown-bg: #fff !default;
+//** Dropdown menu `border-color`.
+$dropdown-border: rgba(0,0,0,.15) !default;
+//** Dropdown menu `border-color` **for IE8**.
+$dropdown-fallback-border: #ccc !default;
+//** Divider color for between dropdown items.
+$dropdown-divider-bg: #e5e5e5 !default;
+
+//** Dropdown link text color.
+$dropdown-link-color: $gray-dark !default;
+//** Hover color for dropdown links.
+$dropdown-link-hover-color: darken($gray-dark, 5%) !default;
+//** Hover background for dropdown links.
+$dropdown-link-hover-bg: #f5f5f5 !default;
+
+//** Active dropdown menu item text color.
+$dropdown-link-active-color: $component-active-color !default;
+//** Active dropdown menu item background color.
+$dropdown-link-active-bg: $component-active-bg !default;
+
+//** Disabled dropdown menu item background color.
+$dropdown-link-disabled-color: $gray-light !default;
+
+//** Text color for headers within dropdown menus.
+$dropdown-header-color: $gray-light !default;
+
+//** Deprecated `$dropdown-caret-color` as of v3.1.0
+$dropdown-caret-color: #000 !default;
+
+
+//-- Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+//
+// Note: These variables are not generated into the Customizer.
+
+$zindex-navbar: 1000 !default;
+$zindex-dropdown: 1000 !default;
+$zindex-popover: 1060 !default;
+$zindex-tooltip: 1070 !default;
+$zindex-navbar-fixed: 1030 !default;
+$zindex-modal-background: 1040 !default;
+$zindex-modal: 1050 !default;
+
+
+//== Media queries breakpoints
+//
+//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
+
+// Extra small screen / phone
+//** Deprecated `$screen-xs` as of v3.0.1
+$screen-xs: 480px !default;
+//** Deprecated `$screen-xs-min` as of v3.2.0
+$screen-xs-min: $screen-xs !default;
+//** Deprecated `$screen-phone` as of v3.0.1
+$screen-phone: $screen-xs-min !default;
+
+// Small screen / tablet
+//** Deprecated `$screen-sm` as of v3.0.1
+$screen-sm: 768px !default;
+$screen-sm-min: $screen-sm !default;
+//** Deprecated `$screen-tablet` as of v3.0.1
+$screen-tablet: $screen-sm-min !default;
+
+// Medium screen / desktop
+//** Deprecated `$screen-md` as of v3.0.1
+$screen-md: 992px !default;
+$screen-md-min: $screen-md !default;
+//** Deprecated `$screen-desktop` as of v3.0.1
+$screen-desktop: $screen-md-min !default;
+
+// Large screen / wide desktop
+//** Deprecated `$screen-lg` as of v3.0.1
+$screen-lg: 1200px !default;
+$screen-lg-min: $screen-lg !default;
+//** Deprecated `$screen-lg-desktop` as of v3.0.1
+$screen-lg-desktop: $screen-lg-min !default;
+
+// So media queries don't overlap when required, provide a maximum
+$screen-xs-max: ($screen-sm-min - 1) !default;
+$screen-sm-max: ($screen-md-min - 1) !default;
+$screen-md-max: ($screen-lg-min - 1) !default;
+
+
+//== Grid system
+//
+//## Define your custom responsive grid.
+
+//** Number of columns in the grid.
+$grid-columns: 12 !default;
+//** Padding between columns. Gets divided in half for the left and right.
+$grid-gutter-width: 30px !default;
+// Navbar collapse
+//** Point at which the navbar becomes uncollapsed.
+$grid-float-breakpoint: $screen-sm-min !default;
+//** Point at which the navbar begins collapsing.
+$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default;
+
+
+//== Container sizes
+//
+//## Define the maximum width of `.container` for different screen sizes.
+
+// Small screen / tablet
+$container-tablet: (720px + $grid-gutter-width) !default;
+//** For `$screen-sm-min` and up.
+$container-sm: $container-tablet !default;
+
+// Medium screen / desktop
+$container-desktop: (940px + $grid-gutter-width) !default;
+//** For `$screen-md-min` and up.
+$container-md: $container-desktop !default;
+
+// Large screen / wide desktop
+$container-large-desktop: (1140px + $grid-gutter-width) !default;
+//** For `$screen-lg-min` and up.
+$container-lg: $container-large-desktop !default;
+
+
+//== Navbar
+//
+//##
+
+// Basics of a navbar
+$navbar-height: 50px !default;
+$navbar-margin-bottom: $line-height-computed !default;
+$navbar-border-radius: $border-radius-base !default;
+$navbar-padding-horizontal: floor(($grid-gutter-width / 2)) !default;
+$navbar-padding-vertical: (($navbar-height - $line-height-computed) / 2) !default;
+$navbar-collapse-max-height: 340px !default;
+
+$navbar-default-color: #777 !default;
+$navbar-default-bg: #f8f8f8 !default;
+$navbar-default-border: darken($navbar-default-bg, 6.5%) !default;
+
+// Navbar links
+$navbar-default-link-color: #777 !default;
+$navbar-default-link-hover-color: #333 !default;
+$navbar-default-link-hover-bg: transparent !default;
+$navbar-default-link-active-color: #555 !default;
+$navbar-default-link-active-bg: darken($navbar-default-bg, 6.5%) !default;
+$navbar-default-link-disabled-color: #ccc !default;
+$navbar-default-link-disabled-bg: transparent !default;
+
+// Navbar brand label
+$navbar-default-brand-color: $navbar-default-link-color !default;
+$navbar-default-brand-hover-color: darken($navbar-default-brand-color, 10%) !default;
+$navbar-default-brand-hover-bg: transparent !default;
+
+// Navbar toggle
+$navbar-default-toggle-hover-bg: #ddd !default;
+$navbar-default-toggle-icon-bar-bg: #888 !default;
+$navbar-default-toggle-border-color: #ddd !default;
+
+
+//=== Inverted navbar
+// Reset inverted navbar basics
+$navbar-inverse-color: lighten($gray-light, 15%) !default;
+$navbar-inverse-bg: #222 !default;
+$navbar-inverse-border: darken($navbar-inverse-bg, 10%) !default;
+
+// Inverted navbar links
+$navbar-inverse-link-color: lighten($gray-light, 15%) !default;
+$navbar-inverse-link-hover-color: #fff !default;
+$navbar-inverse-link-hover-bg: transparent !default;
+$navbar-inverse-link-active-color: $navbar-inverse-link-hover-color !default;
+$navbar-inverse-link-active-bg: darken($navbar-inverse-bg, 10%) !default;
+$navbar-inverse-link-disabled-color: #444 !default;
+$navbar-inverse-link-disabled-bg: transparent !default;
+
+// Inverted navbar brand label
+$navbar-inverse-brand-color: $navbar-inverse-link-color !default;
+$navbar-inverse-brand-hover-color: #fff !default;
+$navbar-inverse-brand-hover-bg: transparent !default;
+
+// Inverted navbar toggle
+$navbar-inverse-toggle-hover-bg: #333 !default;
+$navbar-inverse-toggle-icon-bar-bg: #fff !default;
+$navbar-inverse-toggle-border-color: #333 !default;
+
+
+//== Navs
+//
+//##
+
+//=== Shared nav styles
+$nav-link-padding: 10px 15px !default;
+$nav-link-hover-bg: $gray-lighter !default;
+
+$nav-disabled-link-color: $gray-light !default;
+$nav-disabled-link-hover-color: $gray-light !default;
+
+//== Tabs
+$nav-tabs-border-color: #ddd !default;
+
+$nav-tabs-link-hover-border-color: $gray-lighter !default;
+
+$nav-tabs-active-link-hover-bg: $body-bg !default;
+$nav-tabs-active-link-hover-color: $gray !default;
+$nav-tabs-active-link-hover-border-color: #ddd !default;
+
+$nav-tabs-justified-link-border-color: #ddd !default;
+$nav-tabs-justified-active-link-border-color: $body-bg !default;
+
+//== Pills
+$nav-pills-border-radius: $border-radius-base !default;
+$nav-pills-active-link-hover-bg: $component-active-bg !default;
+$nav-pills-active-link-hover-color: $component-active-color !default;
+
+
+//== Pagination
+//
+//##
+
+$pagination-color: $link-color !default;
+$pagination-bg: #fff !default;
+$pagination-border: #ddd !default;
+
+$pagination-hover-color: $link-hover-color !default;
+$pagination-hover-bg: $gray-lighter !default;
+$pagination-hover-border: #ddd !default;
+
+$pagination-active-color: #fff !default;
+$pagination-active-bg: $brand-primary !default;
+$pagination-active-border: $brand-primary !default;
+
+$pagination-disabled-color: $gray-light !default;
+$pagination-disabled-bg: #fff !default;
+$pagination-disabled-border: #ddd !default;
+
+
+//== Pager
+//
+//##
+
+$pager-bg: $pagination-bg !default;
+$pager-border: $pagination-border !default;
+$pager-border-radius: 15px !default;
+
+$pager-hover-bg: $pagination-hover-bg !default;
+
+$pager-active-bg: $pagination-active-bg !default;
+$pager-active-color: $pagination-active-color !default;
+
+$pager-disabled-color: $pagination-disabled-color !default;
+
+
+//== Jumbotron
+//
+//##
+
+$jumbotron-padding: 30px !default;
+$jumbotron-color: inherit !default;
+$jumbotron-bg: $gray-lighter !default;
+$jumbotron-heading-color: inherit !default;
+$jumbotron-font-size: ceil(($font-size-base * 1.5)) !default;
+$jumbotron-heading-font-size: ceil(($font-size-base * 4.5)) !default;
+
+
+//== Form states and alerts
+//
+//## Define colors for form feedback states and, by default, alerts.
+
+$state-success-text: #3c763d !default;
+$state-success-bg: #dff0d8 !default;
+$state-success-border: darken(adjust-hue($state-success-bg, -10), 5%) !default;
+
+$state-info-text: #31708f !default;
+$state-info-bg: #d9edf7 !default;
+$state-info-border: darken(adjust-hue($state-info-bg, -10), 7%) !default;
+
+$state-warning-text: #8a6d3b !default;
+$state-warning-bg: #fcf8e3 !default;
+$state-warning-border: darken(adjust-hue($state-warning-bg, -10), 5%) !default;
+
+$state-danger-text: #a94442 !default;
+$state-danger-bg: #f2dede !default;
+$state-danger-border: darken(adjust-hue($state-danger-bg, -10), 5%) !default;
+
+
+//== Tooltips
+//
+//##
+
+//** Tooltip max width
+$tooltip-max-width: 200px !default;
+//** Tooltip text color
+$tooltip-color: #fff !default;
+//** Tooltip background color
+$tooltip-bg: #000 !default;
+$tooltip-opacity: .9 !default;
+
+//** Tooltip arrow width
+$tooltip-arrow-width: 5px !default;
+//** Tooltip arrow color
+$tooltip-arrow-color: $tooltip-bg !default;
+
+
+//== Popovers
+//
+//##
+
+//** Popover body background color
+$popover-bg: #fff !default;
+//** Popover maximum width
+$popover-max-width: 276px !default;
+//** Popover border color
+$popover-border-color: rgba(0,0,0,.2) !default;
+//** Popover fallback border color
+$popover-fallback-border-color: #ccc !default;
+
+//** Popover title background color
+$popover-title-bg: darken($popover-bg, 3%) !default;
+
+//** Popover arrow width
+$popover-arrow-width: 10px !default;
+//** Popover arrow color
+$popover-arrow-color: $popover-bg !default;
+
+//** Popover outer arrow width
+$popover-arrow-outer-width: ($popover-arrow-width + 1) !default;
+//** Popover outer arrow color
+$popover-arrow-outer-color: fade_in($popover-border-color, 0.05) !default;
+//** Popover outer arrow fallback color
+$popover-arrow-outer-fallback-color: darken($popover-fallback-border-color, 20%) !default;
+
+
+//== Labels
+//
+//##
+
+//** Default label background color
+$label-default-bg: $gray-light !default;
+//** Primary label background color
+$label-primary-bg: $brand-primary !default;
+//** Success label background color
+$label-success-bg: $brand-success !default;
+//** Info label background color
+$label-info-bg: $brand-info !default;
+//** Warning label background color
+$label-warning-bg: $brand-warning !default;
+//** Danger label background color
+$label-danger-bg: $brand-danger !default;
+
+//** Default label text color
+$label-color: #fff !default;
+//** Default text color of a linked label
+$label-link-hover-color: #fff !default;
+
+
+//== Modals
+//
+//##
+
+//** Padding applied to the modal body
+$modal-inner-padding: 15px !default;
+
+//** Padding applied to the modal title
+$modal-title-padding: 15px !default;
+//** Modal title line-height
+$modal-title-line-height: $line-height-base !default;
+
+//** Background color of modal content area
+$modal-content-bg: #fff !default;
+//** Modal content border color
+$modal-content-border-color: rgba(0,0,0,.2) !default;
+//** Modal content border color **for IE8**
+$modal-content-fallback-border-color: #999 !default;
+
+//** Modal backdrop background color
+$modal-backdrop-bg: #000 !default;
+//** Modal backdrop opacity
+$modal-backdrop-opacity: .5 !default;
+//** Modal header border color
+$modal-header-border-color: #e5e5e5 !default;
+//** Modal footer border color
+$modal-footer-border-color: $modal-header-border-color !default;
+
+$modal-lg: 900px !default;
+$modal-md: 600px !default;
+$modal-sm: 300px !default;
+
+
+//== Alerts
+//
+//## Define alert colors, border radius, and padding.
+
+$alert-padding: 15px !default;
+$alert-border-radius: $border-radius-base !default;
+$alert-link-font-weight: bold !default;
+
+$alert-success-bg: $state-success-bg !default;
+$alert-success-text: $state-success-text !default;
+$alert-success-border: $state-success-border !default;
+
+$alert-info-bg: $state-info-bg !default;
+$alert-info-text: $state-info-text !default;
+$alert-info-border: $state-info-border !default;
+
+$alert-warning-bg: $state-warning-bg !default;
+$alert-warning-text: $state-warning-text !default;
+$alert-warning-border: $state-warning-border !default;
+
+$alert-danger-bg: $state-danger-bg !default;
+$alert-danger-text: $state-danger-text !default;
+$alert-danger-border: $state-danger-border !default;
+
+
+//== Progress bars
+//
+//##
+
+//** Background color of the whole progress component
+$progress-bg: #f5f5f5 !default;
+//** Progress bar text color
+$progress-bar-color: #fff !default;
+//** Variable for setting rounded corners on progress bar.
+$progress-border-radius: $border-radius-base !default;
+
+//** Default progress bar color
+$progress-bar-bg: $brand-primary !default;
+//** Success progress bar color
+$progress-bar-success-bg: $brand-success !default;
+//** Warning progress bar color
+$progress-bar-warning-bg: $brand-warning !default;
+//** Danger progress bar color
+$progress-bar-danger-bg: $brand-danger !default;
+//** Info progress bar color
+$progress-bar-info-bg: $brand-info !default;
+
+
+//== List group
+//
+//##
+
+//** Background color on `.list-group-item`
+$list-group-bg: #fff !default;
+//** `.list-group-item` border color
+$list-group-border: #ddd !default;
+//** List group border radius
+$list-group-border-radius: $border-radius-base !default;
+
+//** Background color of single list items on hover
+$list-group-hover-bg: #f5f5f5 !default;
+//** Text color of active list items
+$list-group-active-color: $component-active-color !default;
+//** Background color of active list items
+$list-group-active-bg: $component-active-bg !default;
+//** Border color of active list elements
+$list-group-active-border: $list-group-active-bg !default;
+//** Text color for content within active list items
+$list-group-active-text-color: lighten($list-group-active-bg, 40%) !default;
+
+//** Text color of disabled list items
+$list-group-disabled-color: $gray-light !default;
+//** Background color of disabled list items
+$list-group-disabled-bg: $gray-lighter !default;
+//** Text color for content within disabled list items
+$list-group-disabled-text-color: $list-group-disabled-color !default;
+
+$list-group-link-color: #555 !default;
+$list-group-link-hover-color: $list-group-link-color !default;
+$list-group-link-heading-color: #333 !default;
+
+
+//== Panels
+//
+//##
+
+$panel-bg: #fff !default;
+$panel-body-padding: 15px !default;
+$panel-heading-padding: 10px 15px !default;
+$panel-footer-padding: $panel-heading-padding !default;
+$panel-border-radius: $border-radius-base !default;
+
+//** Border color for elements within panels
+$panel-inner-border: #ddd !default;
+$panel-footer-bg: #f5f5f5 !default;
+
+$panel-default-text: $gray-dark !default;
+$panel-default-border: #ddd !default;
+$panel-default-heading-bg: #f5f5f5 !default;
+
+$panel-primary-text: #fff !default;
+$panel-primary-border: $brand-primary !default;
+$panel-primary-heading-bg: $brand-primary !default;
+
+$panel-success-text: $state-success-text !default;
+$panel-success-border: $state-success-border !default;
+$panel-success-heading-bg: $state-success-bg !default;
+
+$panel-info-text: $state-info-text !default;
+$panel-info-border: $state-info-border !default;
+$panel-info-heading-bg: $state-info-bg !default;
+
+$panel-warning-text: $state-warning-text !default;
+$panel-warning-border: $state-warning-border !default;
+$panel-warning-heading-bg: $state-warning-bg !default;
+
+$panel-danger-text: $state-danger-text !default;
+$panel-danger-border: $state-danger-border !default;
+$panel-danger-heading-bg: $state-danger-bg !default;
+
+
+//== Thumbnails
+//
+//##
+
+//** Padding around the thumbnail image
+$thumbnail-padding: 4px !default;
+//** Thumbnail background color
+$thumbnail-bg: $body-bg !default;
+//** Thumbnail border color
+$thumbnail-border: #ddd !default;
+//** Thumbnail border radius
+$thumbnail-border-radius: $border-radius-base !default;
+
+//** Custom text color for thumbnail captions
+$thumbnail-caption-color: $text-color !default;
+//** Padding around the thumbnail caption
+$thumbnail-caption-padding: 9px !default;
+
+
+//== Wells
+//
+//##
+
+$well-bg: #f5f5f5 !default;
+$well-border: darken($well-bg, 7%) !default;
+
+
+//== Badges
+//
+//##
+
+$badge-color: #fff !default;
+//** Linked badge text color on hover
+$badge-link-hover-color: #fff !default;
+$badge-bg: $gray-light !default;
+
+//** Badge text color in active nav link
+$badge-active-color: $link-color !default;
+//** Badge background color in active nav link
+$badge-active-bg: #fff !default;
+
+$badge-font-weight: bold !default;
+$badge-line-height: 1 !default;
+$badge-border-radius: 10px !default;
+
+
+//== Breadcrumbs
+//
+//##
+
+$breadcrumb-padding-vertical: 8px !default;
+$breadcrumb-padding-horizontal: 15px !default;
+//** Breadcrumb background color
+$breadcrumb-bg: #f5f5f5 !default;
+//** Breadcrumb text color
+$breadcrumb-color: #ccc !default;
+//** Text color of current page in the breadcrumb
+$breadcrumb-active-color: $gray-light !default;
+//** Textual separator for between breadcrumb elements
+$breadcrumb-separator: "/" !default;
+
+
+//== Carousel
+//
+//##
+
+$carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6) !default;
+
+$carousel-control-color: #fff !default;
+$carousel-control-width: 15% !default;
+$carousel-control-opacity: .5 !default;
+$carousel-control-font-size: 20px !default;
+
+$carousel-indicator-active-bg: #fff !default;
+$carousel-indicator-border-color: #fff !default;
+
+$carousel-caption-color: #fff !default;
+
+
+//== Close
+//
+//##
+
+$close-font-weight: bold !default;
+$close-color: #000 !default;
+$close-text-shadow: 0 1px 0 #fff !default;
+
+
+//== Code
+//
+//##
+
+$code-color: #c7254e !default;
+$code-bg: #f9f2f4 !default;
+
+$kbd-color: #fff !default;
+$kbd-bg: #333 !default;
+
+$pre-bg: #f5f5f5 !default;
+$pre-color: $gray-dark !default;
+$pre-border-color: #ccc !default;
+$pre-scrollable-max-height: 340px !default;
+
+
+//== Type
+//
+//##
+
+//** Horizontal offset for forms and lists.
+$component-offset-horizontal: 180px !default;
+//** Text muted color
+$text-muted: $gray-light !default;
+//** Abbreviations and acronyms border color
+$abbr-border-color: $gray-light !default;
+//** Headings small color
+$headings-small-color: $gray-light !default;
+//** Blockquote small color
+$blockquote-small-color: $gray-light !default;
+//** Blockquote font size
+$blockquote-font-size: ($font-size-base * 1.25) !default;
+//** Blockquote border color
+$blockquote-border-color: $gray-lighter !default;
+//** Page header border color
+$page-header-border-color: $gray-lighter !default;
+//** Width of horizontal description list titles
+$dl-horizontal-offset: $component-offset-horizontal !default;
+//** Point at which .dl-horizontal becomes horizontal
+$dl-horizontal-breakpoint: $grid-float-breakpoint !default;
+//** Horizontal line color.
+$hr-border: $gray-lighter !default;
diff --git a/votrfront/css/_votr-bootstrap.scss b/votrfront/css/src/_votr-bootstrap.scss
similarity index 96%
rename from votrfront/css/_votr-bootstrap.scss
rename to votrfront/css/src/_votr-bootstrap.scss
index e990523..5cebc60 100644
--- a/votrfront/css/_votr-bootstrap.scss
+++ b/votrfront/css/src/_votr-bootstrap.scss
@@ -1,3 +1,4 @@
+@import "votr-variables";
// Core variables and mixins
@import "bootstrap/variables";
@import "bootstrap/mixins";
@@ -27,7 +28,7 @@
// Components
//@import "bootstrap/component-animations";
-//@import "bootstrap/dropdowns";
+@import "bootstrap/dropdowns";
@import "bootstrap/button-groups";
//@import "bootstrap/input-groups";
@import "bootstrap/navs";
diff --git a/votrfront/css/src/_votr-variables.scss b/votrfront/css/src/_votr-variables.scss
new file mode 100644
index 0000000..cbe1ac7
--- /dev/null
+++ b/votrfront/css/src/_votr-variables.scss
@@ -0,0 +1,18 @@
+$uniba-color: #B3231B;
+$brand-primary: $uniba-color;
+$link-color: $uniba-color;
+
+$font-size-base: 13px;
+$font-size-h4: 18px;
+$font-family-monospace: 9pt monospace;
+
+$code-color: #333; // $text-color
+$code-bg: #F5F5F5;
+
+$nav-link-padding: 8px 13px;
+
+$navbar-inverse-bg: #535250;
+$navbar-inverse-color: #ADADAD;
+$navbar-inverse-link-color: #ADADAD;
+
+$table-condensed-cell-padding: 4px;
diff --git a/votrfront/css/main.scss b/votrfront/css/src/main.scss
similarity index 92%
rename from votrfront/css/main.scss
rename to votrfront/css/src/main.scss
index f050e8e..05ae049 100644
--- a/votrfront/css/main.scss
+++ b/votrfront/css/src/main.scss
@@ -1,25 +1,10 @@
+@import "votr-variables";
-$uniba-color: #B3231B;
-$brand-primary: $uniba-color;
-$link-color: $uniba-color;
+// Contain some used variables from bootstrap
+@import "mixins";
+@import "variables";
-$font-size-base: 13px;
-$font-size-h4: 18px;
-$font-family-monospace: 9pt monospace;
-
-$code-color: #333; // $text-color
-$code-bg: #F5F5F5;
-
-$nav-link-padding: 8px 13px;
-
-$navbar-inverse-bg: #535250;
-$navbar-inverse-color: #ADADAD;
-$navbar-inverse-link-color: #ADADAD;
-
-$table-condensed-cell-padding: 4px;
-
-
-@import "votr-bootstrap";
+// Here continues custom SCSS
@import "layout";
@import "forms";
@import "spinner";
diff --git a/votrfront/css/src/mixins/_alerts.scss b/votrfront/css/src/mixins/_alerts.scss
new file mode 100644
index 0000000..3faf0b5
--- /dev/null
+++ b/votrfront/css/src/mixins/_alerts.scss
@@ -0,0 +1,14 @@
+// Alerts
+
+@mixin alert-variant($background, $border, $text-color) {
+ background-color: $background;
+ border-color: $border;
+ color: $text-color;
+
+ hr {
+ border-top-color: darken($border, 5%);
+ }
+ .alert-link {
+ color: darken($text-color, 10%);
+ }
+}
diff --git a/votrfront/css/src/mixins/_background-variant.scss b/votrfront/css/src/mixins/_background-variant.scss
new file mode 100644
index 0000000..4c7769e
--- /dev/null
+++ b/votrfront/css/src/mixins/_background-variant.scss
@@ -0,0 +1,12 @@
+// Contextual backgrounds
+
+// [converter] $parent hack
+@mixin bg-variant($parent, $color) {
+ #{$parent} {
+ background-color: $color;
+ }
+ a#{$parent}:hover,
+ a#{$parent}:focus {
+ background-color: darken($color, 10%);
+ }
+}
diff --git a/votrfront/css/src/mixins/_border-radius.scss b/votrfront/css/src/mixins/_border-radius.scss
new file mode 100644
index 0000000..ce19499
--- /dev/null
+++ b/votrfront/css/src/mixins/_border-radius.scss
@@ -0,0 +1,18 @@
+// Single side border-radius
+
+@mixin border-top-radius($radius) {
+ border-top-right-radius: $radius;
+ border-top-left-radius: $radius;
+}
+@mixin border-right-radius($radius) {
+ border-bottom-right-radius: $radius;
+ border-top-right-radius: $radius;
+}
+@mixin border-bottom-radius($radius) {
+ border-bottom-right-radius: $radius;
+ border-bottom-left-radius: $radius;
+}
+@mixin border-left-radius($radius) {
+ border-bottom-left-radius: $radius;
+ border-top-left-radius: $radius;
+}
diff --git a/votrfront/css/src/mixins/_buttons.scss b/votrfront/css/src/mixins/_buttons.scss
new file mode 100644
index 0000000..b93f84b
--- /dev/null
+++ b/votrfront/css/src/mixins/_buttons.scss
@@ -0,0 +1,65 @@
+// Button variants
+//
+// Easily pump out default styles, as well as :hover, :focus, :active,
+// and disabled options for all buttons
+
+@mixin button-variant($color, $background, $border) {
+ color: $color;
+ background-color: $background;
+ border-color: $border;
+
+ &:focus,
+ &.focus {
+ color: $color;
+ background-color: darken($background, 10%);
+ border-color: darken($border, 25%);
+ }
+ &:hover {
+ color: $color;
+ background-color: darken($background, 10%);
+ border-color: darken($border, 12%);
+ }
+ &:active,
+ &.active,
+ .open > &.dropdown-toggle {
+ color: $color;
+ background-color: darken($background, 10%);
+ border-color: darken($border, 12%);
+
+ &:hover,
+ &:focus,
+ &.focus {
+ color: $color;
+ background-color: darken($background, 17%);
+ border-color: darken($border, 25%);
+ }
+ }
+ &:active,
+ &.active,
+ .open > &.dropdown-toggle {
+ background-image: none;
+ }
+ &.disabled,
+ &[disabled],
+ fieldset[disabled] & {
+ &:hover,
+ &:focus,
+ &.focus {
+ background-color: $background;
+ border-color: $border;
+ }
+ }
+
+ .badge {
+ color: $background;
+ background-color: $color;
+ }
+}
+
+// Button sizes
+@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
+ padding: $padding-vertical $padding-horizontal;
+ font-size: $font-size;
+ line-height: $line-height;
+ border-radius: $border-radius;
+}
diff --git a/votrfront/css/src/mixins/_center-block.scss b/votrfront/css/src/mixins/_center-block.scss
new file mode 100644
index 0000000..e06fb5e
--- /dev/null
+++ b/votrfront/css/src/mixins/_center-block.scss
@@ -0,0 +1,7 @@
+// Center-align a block level element
+
+@mixin center-block() {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
diff --git a/votrfront/css/src/mixins/_clearfix.scss b/votrfront/css/src/mixins/_clearfix.scss
new file mode 100644
index 0000000..dc3e2ab
--- /dev/null
+++ b/votrfront/css/src/mixins/_clearfix.scss
@@ -0,0 +1,22 @@
+// Clearfix
+//
+// For modern browsers
+// 1. The space content is one way to avoid an Opera bug when the
+// contenteditable attribute is included anywhere else in the document.
+// Otherwise it causes space to appear at the top and bottom of elements
+// that are clearfixed.
+// 2. The use of `table` rather than `block` is only necessary if using
+// `:before` to contain the top-margins of child elements.
+//
+// Source: http://nicolasgallagher.com/micro-clearfix-hack/
+
+@mixin clearfix() {
+ &:before,
+ &:after {
+ content: " "; // 1
+ display: table; // 2
+ }
+ &:after {
+ clear: both;
+ }
+}
diff --git a/votrfront/css/src/mixins/_forms.scss b/votrfront/css/src/mixins/_forms.scss
new file mode 100644
index 0000000..277aa5f
--- /dev/null
+++ b/votrfront/css/src/mixins/_forms.scss
@@ -0,0 +1,88 @@
+// Form validation states
+//
+// Used in forms.less to generate the form validation CSS for warnings, errors,
+// and successes.
+
+@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) {
+ // Color the label and help text
+ .help-block,
+ .control-label,
+ .radio,
+ .checkbox,
+ .radio-inline,
+ .checkbox-inline,
+ &.radio label,
+ &.checkbox label,
+ &.radio-inline label,
+ &.checkbox-inline label {
+ color: $text-color;
+ }
+ // Set the border and box shadow on specific inputs to match
+ .form-control {
+ border-color: $border-color;
+ @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
+ &:focus {
+ border-color: darken($border-color, 10%);
+ $shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%);
+ @include box-shadow($shadow);
+ }
+ }
+ // Set validation states also for addons
+ .input-group-addon {
+ color: $text-color;
+ border-color: $border-color;
+ background-color: $background-color;
+ }
+ // Optional feedback icon
+ .form-control-feedback {
+ color: $text-color;
+ }
+}
+
+
+// Form control focus state
+//
+// Generate a customized focus state and for any input with the specified color,
+// which defaults to the `$input-border-focus` variable.
+//
+// We highly encourage you to not customize the default value, but instead use
+// this to tweak colors on an as-needed basis. This aesthetic change is based on
+// WebKit's default styles, but applicable to a wider range of browsers. Its
+// usability and accessibility should be taken into account with any change.
+//
+// Example usage: change the default blue border and shadow to white for better
+// contrast against a dark gray background.
+@mixin form-control-focus($color: $input-border-focus) {
+ $color-rgba: rgba(red($color), green($color), blue($color), .6);
+ &:focus {
+ border-color: $color;
+ outline: 0;
+ @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px $color-rgba);
+ }
+}
+
+// Form control sizing
+//
+// Relative text size, padding, and border-radii changes for form controls. For
+// horizontal sizing, wrap controls in the predefined grid classes. ``
+// element gets special love because it's special, and that's a fact!
+// [converter] $parent hack
+@mixin input-size($parent, $input-height, $padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
+ #{$parent} {
+ height: $input-height;
+ padding: $padding-vertical $padding-horizontal;
+ font-size: $font-size;
+ line-height: $line-height;
+ border-radius: $border-radius;
+ }
+
+ select#{$parent} {
+ height: $input-height;
+ line-height: $input-height;
+ }
+
+ textarea#{$parent},
+ select[multiple]#{$parent} {
+ height: auto;
+ }
+}
diff --git a/votrfront/css/src/mixins/_gradients.scss b/votrfront/css/src/mixins/_gradients.scss
new file mode 100644
index 0000000..a8939f5
--- /dev/null
+++ b/votrfront/css/src/mixins/_gradients.scss
@@ -0,0 +1,58 @@
+// Gradients
+
+
+
+// Horizontal gradient, from left to right
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+// Color stops are not available in IE9 and below.
+@mixin gradient-horizontal($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
+ background-image: -webkit-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+
+ background-image: -o-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // Opera 12
+ background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down
+}
+
+// Vertical gradient, from top to bottom
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+// Color stops are not available in IE9 and below.
+@mixin gradient-vertical($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
+ background-image: -webkit-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+
+ background-image: -o-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Opera 12
+ background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down
+}
+
+@mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) {
+ background-repeat: repeat-x;
+ background-image: -webkit-linear-gradient($deg, $start-color, $end-color); // Safari 5.1-6, Chrome 10+
+ background-image: -o-linear-gradient($deg, $start-color, $end-color); // Opera 12
+ background-image: linear-gradient($deg, $start-color, $end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
+}
+@mixin gradient-horizontal-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
+ background-image: -webkit-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color);
+ background-image: -o-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color);
+ background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
+ background-repeat: no-repeat;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down, gets no color-stop at all for proper fallback
+}
+@mixin gradient-vertical-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
+ background-image: -webkit-linear-gradient($start-color, $mid-color $color-stop, $end-color);
+ background-image: -o-linear-gradient($start-color, $mid-color $color-stop, $end-color);
+ background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
+ background-repeat: no-repeat;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down, gets no color-stop at all for proper fallback
+}
+@mixin gradient-radial($inner-color: #555, $outer-color: #333) {
+ background-image: -webkit-radial-gradient(circle, $inner-color, $outer-color);
+ background-image: radial-gradient(circle, $inner-color, $outer-color);
+ background-repeat: no-repeat;
+}
+@mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) {
+ background-image: -webkit-linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+ background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+}
diff --git a/votrfront/css/src/mixins/_grid-framework.scss b/votrfront/css/src/mixins/_grid-framework.scss
new file mode 100644
index 0000000..16d038c
--- /dev/null
+++ b/votrfront/css/src/mixins/_grid-framework.scss
@@ -0,0 +1,81 @@
+// Framework grid generation
+//
+// Used only by Bootstrap to generate the correct number of grid classes given
+// any value of `$grid-columns`.
+
+// [converter] This is defined recursively in LESS, but Sass supports real loops
+@mixin make-grid-columns($i: 1, $list: ".col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}") {
+ @for $i from (1 + 1) through $grid-columns {
+ $list: "#{$list}, .col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}";
+ }
+ #{$list} {
+ position: relative;
+ // Prevent columns from collapsing when empty
+ min-height: 1px;
+ // Inner gutter via padding
+ padding-left: ceil(($grid-gutter-width / 2));
+ padding-right: floor(($grid-gutter-width / 2));
+ }
+}
+
+
+// [converter] This is defined recursively in LESS, but Sass supports real loops
+@mixin float-grid-columns($class, $i: 1, $list: ".col-#{$class}-#{$i}") {
+ @for $i from (1 + 1) through $grid-columns {
+ $list: "#{$list}, .col-#{$class}-#{$i}";
+ }
+ #{$list} {
+ float: left;
+ }
+}
+
+
+@mixin calc-grid-column($index, $class, $type) {
+ @if ($type == width) and ($index > 0) {
+ .col-#{$class}-#{$index} {
+ width: percentage(($index / $grid-columns));
+ }
+ }
+ @if ($type == push) and ($index > 0) {
+ .col-#{$class}-push-#{$index} {
+ left: percentage(($index / $grid-columns));
+ }
+ }
+ @if ($type == push) and ($index == 0) {
+ .col-#{$class}-push-0 {
+ left: auto;
+ }
+ }
+ @if ($type == pull) and ($index > 0) {
+ .col-#{$class}-pull-#{$index} {
+ right: percentage(($index / $grid-columns));
+ }
+ }
+ @if ($type == pull) and ($index == 0) {
+ .col-#{$class}-pull-0 {
+ right: auto;
+ }
+ }
+ @if ($type == offset) {
+ .col-#{$class}-offset-#{$index} {
+ margin-left: percentage(($index / $grid-columns));
+ }
+ }
+}
+
+// [converter] This is defined recursively in LESS, but Sass supports real loops
+@mixin loop-grid-columns($columns, $class, $type) {
+ @for $i from 0 through $columns {
+ @include calc-grid-column($i, $class, $type);
+ }
+}
+
+
+// Create grid for specific class
+@mixin make-grid($class) {
+ @include float-grid-columns($class);
+ @include loop-grid-columns($grid-columns, $class, width);
+ @include loop-grid-columns($grid-columns, $class, pull);
+ @include loop-grid-columns($grid-columns, $class, push);
+ @include loop-grid-columns($grid-columns, $class, offset);
+}
diff --git a/votrfront/css/src/mixins/_grid.scss b/votrfront/css/src/mixins/_grid.scss
new file mode 100644
index 0000000..59551da
--- /dev/null
+++ b/votrfront/css/src/mixins/_grid.scss
@@ -0,0 +1,122 @@
+// Grid system
+//
+// Generate semantic grid columns with these mixins.
+
+// Centered container element
+@mixin container-fixed($gutter: $grid-gutter-width) {
+ margin-right: auto;
+ margin-left: auto;
+ padding-left: floor(($gutter / 2));
+ padding-right: ceil(($gutter / 2));
+ @include clearfix;
+}
+
+// Creates a wrapper for a series of columns
+@mixin make-row($gutter: $grid-gutter-width) {
+ margin-left: ceil(($gutter / -2));
+ margin-right: floor(($gutter / -2));
+ @include clearfix;
+}
+
+// Generate the extra small columns
+@mixin make-xs-column($columns, $gutter: $grid-gutter-width) {
+ position: relative;
+ float: left;
+ width: percentage(($columns / $grid-columns));
+ min-height: 1px;
+ padding-left: ($gutter / 2);
+ padding-right: ($gutter / 2);
+}
+@mixin make-xs-column-offset($columns) {
+ margin-left: percentage(($columns / $grid-columns));
+}
+@mixin make-xs-column-push($columns) {
+ left: percentage(($columns / $grid-columns));
+}
+@mixin make-xs-column-pull($columns) {
+ right: percentage(($columns / $grid-columns));
+}
+
+// Generate the small columns
+@mixin make-sm-column($columns, $gutter: $grid-gutter-width) {
+ position: relative;
+ min-height: 1px;
+ padding-left: ($gutter / 2);
+ padding-right: ($gutter / 2);
+
+ @media (min-width: $screen-sm-min) {
+ float: left;
+ width: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-sm-column-offset($columns) {
+ @media (min-width: $screen-sm-min) {
+ margin-left: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-sm-column-push($columns) {
+ @media (min-width: $screen-sm-min) {
+ left: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-sm-column-pull($columns) {
+ @media (min-width: $screen-sm-min) {
+ right: percentage(($columns / $grid-columns));
+ }
+}
+
+// Generate the medium columns
+@mixin make-md-column($columns, $gutter: $grid-gutter-width) {
+ position: relative;
+ min-height: 1px;
+ padding-left: ($gutter / 2);
+ padding-right: ($gutter / 2);
+
+ @media (min-width: $screen-md-min) {
+ float: left;
+ width: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-md-column-offset($columns) {
+ @media (min-width: $screen-md-min) {
+ margin-left: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-md-column-push($columns) {
+ @media (min-width: $screen-md-min) {
+ left: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-md-column-pull($columns) {
+ @media (min-width: $screen-md-min) {
+ right: percentage(($columns / $grid-columns));
+ }
+}
+
+// Generate the large columns
+@mixin make-lg-column($columns, $gutter: $grid-gutter-width) {
+ position: relative;
+ min-height: 1px;
+ padding-left: ($gutter / 2);
+ padding-right: ($gutter / 2);
+
+ @media (min-width: $screen-lg-min) {
+ float: left;
+ width: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-lg-column-offset($columns) {
+ @media (min-width: $screen-lg-min) {
+ margin-left: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-lg-column-push($columns) {
+ @media (min-width: $screen-lg-min) {
+ left: percentage(($columns / $grid-columns));
+ }
+}
+@mixin make-lg-column-pull($columns) {
+ @media (min-width: $screen-lg-min) {
+ right: percentage(($columns / $grid-columns));
+ }
+}
diff --git a/votrfront/css/src/mixins/_hide-text.scss b/votrfront/css/src/mixins/_hide-text.scss
new file mode 100644
index 0000000..1767e02
--- /dev/null
+++ b/votrfront/css/src/mixins/_hide-text.scss
@@ -0,0 +1,21 @@
+// CSS image replacement
+//
+// Heads up! v3 launched with only `.hide-text()`, but per our pattern for
+// mixins being reused as classes with the same name, this doesn't hold up. As
+// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.
+//
+// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
+
+// Deprecated as of v3.0.1 (has been removed in v4)
+@mixin hide-text() {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+// New mixin to use as of v3.0.1
+@mixin text-hide() {
+ @include hide-text;
+}
diff --git a/votrfront/css/src/mixins/_image.scss b/votrfront/css/src/mixins/_image.scss
new file mode 100644
index 0000000..c8dcf5e
--- /dev/null
+++ b/votrfront/css/src/mixins/_image.scss
@@ -0,0 +1,33 @@
+// Image Mixins
+// - Responsive image
+// - Retina image
+
+
+// Responsive image
+//
+// Keep images from scaling beyond the width of their parents.
+@mixin img-responsive($display: block) {
+ display: $display;
+ max-width: 100%; // Part 1: Set a maximum relative to the parent
+ height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
+}
+
+
+// Retina image
+//
+// Short retina mixin for setting background-image and -size. Note that the
+// spelling of `min--moz-device-pixel-ratio` is intentional.
+@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
+ background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-1x}"), "#{$file-1x}"));
+
+ @media
+ only screen and (-webkit-min-device-pixel-ratio: 2),
+ only screen and ( min--moz-device-pixel-ratio: 2),
+ only screen and ( -o-min-device-pixel-ratio: 2/1),
+ only screen and ( min-device-pixel-ratio: 2),
+ only screen and ( min-resolution: 192dpi),
+ only screen and ( min-resolution: 2dppx) {
+ background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-2x}"), "#{$file-2x}"));
+ background-size: $width-1x $height-1x;
+ }
+}
diff --git a/votrfront/css/src/mixins/_labels.scss b/votrfront/css/src/mixins/_labels.scss
new file mode 100644
index 0000000..eda6dfd
--- /dev/null
+++ b/votrfront/css/src/mixins/_labels.scss
@@ -0,0 +1,12 @@
+// Labels
+
+@mixin label-variant($color) {
+ background-color: $color;
+
+ &[href] {
+ &:hover,
+ &:focus {
+ background-color: darken($color, 10%);
+ }
+ }
+}
diff --git a/votrfront/css/src/mixins/_list-group.scss b/votrfront/css/src/mixins/_list-group.scss
new file mode 100644
index 0000000..c478eeb
--- /dev/null
+++ b/votrfront/css/src/mixins/_list-group.scss
@@ -0,0 +1,32 @@
+// List Groups
+
+@mixin list-group-item-variant($state, $background, $color) {
+ .list-group-item-#{$state} {
+ color: $color;
+ background-color: $background;
+
+ // [converter] extracted a&, button& to a.list-group-item-#{$state}, button.list-group-item-#{$state}
+ }
+
+ a.list-group-item-#{$state},
+ button.list-group-item-#{$state} {
+ color: $color;
+
+ .list-group-item-heading {
+ color: inherit;
+ }
+
+ &:hover,
+ &:focus {
+ color: $color;
+ background-color: darken($background, 5%);
+ }
+ &.active,
+ &.active:hover,
+ &.active:focus {
+ color: #fff;
+ background-color: $color;
+ border-color: $color;
+ }
+ }
+}
diff --git a/votrfront/css/src/mixins/_nav-divider.scss b/votrfront/css/src/mixins/_nav-divider.scss
new file mode 100644
index 0000000..2e6da02
--- /dev/null
+++ b/votrfront/css/src/mixins/_nav-divider.scss
@@ -0,0 +1,10 @@
+// Horizontal dividers
+//
+// Dividers (basically an hr) within dropdowns and nav lists
+
+@mixin nav-divider($color: #e5e5e5) {
+ height: 1px;
+ margin: (($line-height-computed / 2) - 1) 0;
+ overflow: hidden;
+ background-color: $color;
+}
diff --git a/votrfront/css/src/mixins/_nav-vertical-align.scss b/votrfront/css/src/mixins/_nav-vertical-align.scss
new file mode 100644
index 0000000..c8fbf1a
--- /dev/null
+++ b/votrfront/css/src/mixins/_nav-vertical-align.scss
@@ -0,0 +1,9 @@
+// Navbar vertical align
+//
+// Vertically center elements in the navbar.
+// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
+
+@mixin navbar-vertical-align($element-height) {
+ margin-top: (($navbar-height - $element-height) / 2);
+ margin-bottom: (($navbar-height - $element-height) / 2);
+}
diff --git a/votrfront/css/src/mixins/_opacity.scss b/votrfront/css/src/mixins/_opacity.scss
new file mode 100644
index 0000000..88e9a57
--- /dev/null
+++ b/votrfront/css/src/mixins/_opacity.scss
@@ -0,0 +1,8 @@
+// Opacity
+
+@mixin opacity($opacity) {
+ opacity: $opacity;
+ // IE8 filter
+ $opacity-ie: ($opacity * 100);
+ filter: alpha(opacity=$opacity-ie);
+}
diff --git a/votrfront/css/src/mixins/_pagination.scss b/votrfront/css/src/mixins/_pagination.scss
new file mode 100644
index 0000000..d4a5404
--- /dev/null
+++ b/votrfront/css/src/mixins/_pagination.scss
@@ -0,0 +1,24 @@
+// Pagination
+
+@mixin pagination-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
+ > li {
+ > a,
+ > span {
+ padding: $padding-vertical $padding-horizontal;
+ font-size: $font-size;
+ line-height: $line-height;
+ }
+ &:first-child {
+ > a,
+ > span {
+ @include border-left-radius($border-radius);
+ }
+ }
+ &:last-child {
+ > a,
+ > span {
+ @include border-right-radius($border-radius);
+ }
+ }
+ }
+}
diff --git a/votrfront/css/src/mixins/_panels.scss b/votrfront/css/src/mixins/_panels.scss
new file mode 100644
index 0000000..3ff31ae
--- /dev/null
+++ b/votrfront/css/src/mixins/_panels.scss
@@ -0,0 +1,24 @@
+// Panels
+
+@mixin panel-variant($border, $heading-text-color, $heading-bg-color, $heading-border) {
+ border-color: $border;
+
+ & > .panel-heading {
+ color: $heading-text-color;
+ background-color: $heading-bg-color;
+ border-color: $heading-border;
+
+ + .panel-collapse > .panel-body {
+ border-top-color: $border;
+ }
+ .badge {
+ color: $heading-bg-color;
+ background-color: $heading-text-color;
+ }
+ }
+ & > .panel-footer {
+ + .panel-collapse > .panel-body {
+ border-bottom-color: $border;
+ }
+ }
+}
diff --git a/votrfront/css/src/mixins/_progress-bar.scss b/votrfront/css/src/mixins/_progress-bar.scss
new file mode 100644
index 0000000..90a62af
--- /dev/null
+++ b/votrfront/css/src/mixins/_progress-bar.scss
@@ -0,0 +1,10 @@
+// Progress bars
+
+@mixin progress-bar-variant($color) {
+ background-color: $color;
+
+ // Deprecated parent class requirement as of v3.2.0
+ .progress-striped & {
+ @include gradient-striped;
+ }
+}
diff --git a/votrfront/css/src/mixins/_reset-filter.scss b/votrfront/css/src/mixins/_reset-filter.scss
new file mode 100644
index 0000000..bf73051
--- /dev/null
+++ b/votrfront/css/src/mixins/_reset-filter.scss
@@ -0,0 +1,8 @@
+// Reset filters for IE
+//
+// When you need to remove a gradient background, do not forget to use this to reset
+// the IE filter for IE9 and below.
+
+@mixin reset-filter() {
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
diff --git a/votrfront/css/src/mixins/_reset-text.scss b/votrfront/css/src/mixins/_reset-text.scss
new file mode 100644
index 0000000..c9c2841
--- /dev/null
+++ b/votrfront/css/src/mixins/_reset-text.scss
@@ -0,0 +1,18 @@
+@mixin reset-text() {
+ font-family: $font-family-base;
+ // We deliberately do NOT reset font-size.
+ font-style: normal;
+ font-weight: normal;
+ letter-spacing: normal;
+ line-break: auto;
+ line-height: $line-height-base;
+ text-align: left; // Fallback for where `start` is not supported
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ white-space: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+}
diff --git a/votrfront/css/src/mixins/_resize.scss b/votrfront/css/src/mixins/_resize.scss
new file mode 100644
index 0000000..83fa637
--- /dev/null
+++ b/votrfront/css/src/mixins/_resize.scss
@@ -0,0 +1,6 @@
+// Resize anything
+
+@mixin resizable($direction) {
+ resize: $direction; // Options: horizontal, vertical, both
+ overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
+}
diff --git a/votrfront/css/src/mixins/_responsive-visibility.scss b/votrfront/css/src/mixins/_responsive-visibility.scss
new file mode 100644
index 0000000..cbdf777
--- /dev/null
+++ b/votrfront/css/src/mixins/_responsive-visibility.scss
@@ -0,0 +1,21 @@
+// Responsive utilities
+
+//
+// More easily include all the states for responsive-utilities.less.
+// [converter] $parent hack
+@mixin responsive-visibility($parent) {
+ #{$parent} {
+ display: block !important;
+ }
+ table#{$parent} { display: table !important; }
+ tr#{$parent} { display: table-row !important; }
+ th#{$parent},
+ td#{$parent} { display: table-cell !important; }
+}
+
+// [converter] $parent hack
+@mixin responsive-invisibility($parent) {
+ #{$parent} {
+ display: none !important;
+ }
+}
diff --git a/votrfront/css/src/mixins/_size.scss b/votrfront/css/src/mixins/_size.scss
new file mode 100644
index 0000000..abbe246
--- /dev/null
+++ b/votrfront/css/src/mixins/_size.scss
@@ -0,0 +1,10 @@
+// Sizing shortcuts
+
+@mixin size($width, $height) {
+ width: $width;
+ height: $height;
+}
+
+@mixin square($size) {
+ @include size($size, $size);
+}
diff --git a/votrfront/css/src/mixins/_tab-focus.scss b/votrfront/css/src/mixins/_tab-focus.scss
new file mode 100644
index 0000000..f16ed64
--- /dev/null
+++ b/votrfront/css/src/mixins/_tab-focus.scss
@@ -0,0 +1,9 @@
+// WebKit-style focus
+
+@mixin tab-focus() {
+ // WebKit-specific. Other browsers will keep their default outline style.
+ // (Initially tried to also force default via `outline: initial`,
+ // but that seems to erroneously remove the outline in Firefox altogether.)
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
diff --git a/votrfront/css/src/mixins/_table-row.scss b/votrfront/css/src/mixins/_table-row.scss
new file mode 100644
index 0000000..1367950
--- /dev/null
+++ b/votrfront/css/src/mixins/_table-row.scss
@@ -0,0 +1,28 @@
+// Tables
+
+@mixin table-row-variant($state, $background) {
+ // Exact selectors below required to override `.table-striped` and prevent
+ // inheritance to nested tables.
+ .table > thead > tr,
+ .table > tbody > tr,
+ .table > tfoot > tr {
+ > td.#{$state},
+ > th.#{$state},
+ &.#{$state} > td,
+ &.#{$state} > th {
+ background-color: $background;
+ }
+ }
+
+ // Hover states for `.table-hover`
+ // Note: this is not available for cells or rows within `thead` or `tfoot`.
+ .table-hover > tbody > tr {
+ > td.#{$state}:hover,
+ > th.#{$state}:hover,
+ &.#{$state}:hover > td,
+ &:hover > .#{$state},
+ &.#{$state}:hover > th {
+ background-color: darken($background, 5%);
+ }
+ }
+}
diff --git a/votrfront/css/src/mixins/_text-emphasis.scss b/votrfront/css/src/mixins/_text-emphasis.scss
new file mode 100644
index 0000000..3b446c4
--- /dev/null
+++ b/votrfront/css/src/mixins/_text-emphasis.scss
@@ -0,0 +1,12 @@
+// Typography
+
+// [converter] $parent hack
+@mixin text-emphasis-variant($parent, $color) {
+ #{$parent} {
+ color: $color;
+ }
+ a#{$parent}:hover,
+ a#{$parent}:focus {
+ color: darken($color, 10%);
+ }
+}
diff --git a/votrfront/css/src/mixins/_text-overflow.scss b/votrfront/css/src/mixins/_text-overflow.scss
new file mode 100644
index 0000000..1593b25
--- /dev/null
+++ b/votrfront/css/src/mixins/_text-overflow.scss
@@ -0,0 +1,8 @@
+// Text overflow
+// Requires inline-block or block for proper styling
+
+@mixin text-overflow() {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
diff --git a/votrfront/css/src/mixins/_vendor-prefixes.scss b/votrfront/css/src/mixins/_vendor-prefixes.scss
new file mode 100644
index 0000000..b3d0371
--- /dev/null
+++ b/votrfront/css/src/mixins/_vendor-prefixes.scss
@@ -0,0 +1,222 @@
+// Vendor Prefixes
+//
+// All vendor mixins are deprecated as of v3.2.0 due to the introduction of
+// Autoprefixer in our Gruntfile. They have been removed in v4.
+
+// - Animations
+// - Backface visibility
+// - Box shadow
+// - Box sizing
+// - Content columns
+// - Hyphens
+// - Placeholder text
+// - Transformations
+// - Transitions
+// - User Select
+
+
+// Animations
+@mixin animation($animation) {
+ -webkit-animation: $animation;
+ -o-animation: $animation;
+ animation: $animation;
+}
+@mixin animation-name($name) {
+ -webkit-animation-name: $name;
+ animation-name: $name;
+}
+@mixin animation-duration($duration) {
+ -webkit-animation-duration: $duration;
+ animation-duration: $duration;
+}
+@mixin animation-timing-function($timing-function) {
+ -webkit-animation-timing-function: $timing-function;
+ animation-timing-function: $timing-function;
+}
+@mixin animation-delay($delay) {
+ -webkit-animation-delay: $delay;
+ animation-delay: $delay;
+}
+@mixin animation-iteration-count($iteration-count) {
+ -webkit-animation-iteration-count: $iteration-count;
+ animation-iteration-count: $iteration-count;
+}
+@mixin animation-direction($direction) {
+ -webkit-animation-direction: $direction;
+ animation-direction: $direction;
+}
+@mixin animation-fill-mode($fill-mode) {
+ -webkit-animation-fill-mode: $fill-mode;
+ animation-fill-mode: $fill-mode;
+}
+
+// Backface visibility
+// Prevent browsers from flickering when using CSS 3D transforms.
+// Default value is `visible`, but can be changed to `hidden`
+
+@mixin backface-visibility($visibility) {
+ -webkit-backface-visibility: $visibility;
+ -moz-backface-visibility: $visibility;
+ backface-visibility: $visibility;
+}
+
+// Drop shadows
+//
+// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
+// supported browsers that have box shadow capabilities now support it.
+
+@mixin box-shadow($shadow...) {
+ -webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1
+ box-shadow: $shadow;
+}
+
+// Box sizing
+@mixin box-sizing($boxmodel) {
+ -webkit-box-sizing: $boxmodel;
+ -moz-box-sizing: $boxmodel;
+ box-sizing: $boxmodel;
+}
+
+// CSS3 Content Columns
+@mixin content-columns($column-count, $column-gap: $grid-gutter-width) {
+ -webkit-column-count: $column-count;
+ -moz-column-count: $column-count;
+ column-count: $column-count;
+ -webkit-column-gap: $column-gap;
+ -moz-column-gap: $column-gap;
+ column-gap: $column-gap;
+}
+
+// Optional hyphenation
+@mixin hyphens($mode: auto) {
+ word-wrap: break-word;
+ -webkit-hyphens: $mode;
+ -moz-hyphens: $mode;
+ -ms-hyphens: $mode; // IE10+
+ -o-hyphens: $mode;
+ hyphens: $mode;
+}
+
+// Placeholder text
+@mixin placeholder($color: $input-color-placeholder) {
+ // Firefox
+ &::-moz-placeholder {
+ color: $color;
+ opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
+ }
+ &:-ms-input-placeholder { color: $color; } // Internet Explorer 10+
+ &::-webkit-input-placeholder { color: $color; } // Safari and Chrome
+}
+
+// Transformations
+@mixin scale($ratio...) {
+ -webkit-transform: scale($ratio);
+ -ms-transform: scale($ratio); // IE9 only
+ -o-transform: scale($ratio);
+ transform: scale($ratio);
+}
+
+@mixin scaleX($ratio) {
+ -webkit-transform: scaleX($ratio);
+ -ms-transform: scaleX($ratio); // IE9 only
+ -o-transform: scaleX($ratio);
+ transform: scaleX($ratio);
+}
+@mixin scaleY($ratio) {
+ -webkit-transform: scaleY($ratio);
+ -ms-transform: scaleY($ratio); // IE9 only
+ -o-transform: scaleY($ratio);
+ transform: scaleY($ratio);
+}
+@mixin skew($x, $y) {
+ -webkit-transform: skewX($x) skewY($y);
+ -ms-transform: skewX($x) skewY($y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
+ -o-transform: skewX($x) skewY($y);
+ transform: skewX($x) skewY($y);
+}
+@mixin translate($x, $y) {
+ -webkit-transform: translate($x, $y);
+ -ms-transform: translate($x, $y); // IE9 only
+ -o-transform: translate($x, $y);
+ transform: translate($x, $y);
+}
+@mixin translate3d($x, $y, $z) {
+ -webkit-transform: translate3d($x, $y, $z);
+ transform: translate3d($x, $y, $z);
+}
+@mixin rotate($degrees) {
+ -webkit-transform: rotate($degrees);
+ -ms-transform: rotate($degrees); // IE9 only
+ -o-transform: rotate($degrees);
+ transform: rotate($degrees);
+}
+@mixin rotateX($degrees) {
+ -webkit-transform: rotateX($degrees);
+ -ms-transform: rotateX($degrees); // IE9 only
+ -o-transform: rotateX($degrees);
+ transform: rotateX($degrees);
+}
+@mixin rotateY($degrees) {
+ -webkit-transform: rotateY($degrees);
+ -ms-transform: rotateY($degrees); // IE9 only
+ -o-transform: rotateY($degrees);
+ transform: rotateY($degrees);
+}
+@mixin perspective($perspective) {
+ -webkit-perspective: $perspective;
+ -moz-perspective: $perspective;
+ perspective: $perspective;
+}
+@mixin perspective-origin($perspective) {
+ -webkit-perspective-origin: $perspective;
+ -moz-perspective-origin: $perspective;
+ perspective-origin: $perspective;
+}
+@mixin transform-origin($origin) {
+ -webkit-transform-origin: $origin;
+ -moz-transform-origin: $origin;
+ -ms-transform-origin: $origin; // IE9 only
+ transform-origin: $origin;
+}
+
+
+// Transitions
+
+@mixin transition($transition...) {
+ -webkit-transition: $transition;
+ -o-transition: $transition;
+ transition: $transition;
+}
+@mixin transition-property($transition-property...) {
+ -webkit-transition-property: $transition-property;
+ transition-property: $transition-property;
+}
+@mixin transition-delay($transition-delay) {
+ -webkit-transition-delay: $transition-delay;
+ transition-delay: $transition-delay;
+}
+@mixin transition-duration($transition-duration...) {
+ -webkit-transition-duration: $transition-duration;
+ transition-duration: $transition-duration;
+}
+@mixin transition-timing-function($timing-function) {
+ -webkit-transition-timing-function: $timing-function;
+ transition-timing-function: $timing-function;
+}
+@mixin transition-transform($transition...) {
+ -webkit-transition: -webkit-transform $transition;
+ -moz-transition: -moz-transform $transition;
+ -o-transition: -o-transform $transition;
+ transition: transform $transition;
+}
+
+
+// User select
+// For selecting text on the page
+
+@mixin user-select($select) {
+ -webkit-user-select: $select;
+ -moz-user-select: $select;
+ -ms-user-select: $select; // IE10+
+ user-select: $select;
+}
diff --git a/votrfront/front.py b/votrfront/front.py
index 577690a..f725523 100644
--- a/votrfront/front.py
+++ b/votrfront/front.py
@@ -15,8 +15,8 @@
Votr
-
+%(css)s
'.format(static_url(css))
+ for css in ['bootstrap.custom.css', 'votr.css']
+ ),
scripts='\n'.join(
''.format(static_url(script))
- for script in scripts),
+ for script in ['votr.bundle.js']
+ ),
analytics=('' if not request.app.settings.ua_code else
analytics_template % dict(ua_code=request.app.settings.ua_code)))
diff --git a/votrfront/js/.babelrc b/votrfront/js/.babelrc
new file mode 100644
index 0000000..93a74f0
--- /dev/null
+++ b/votrfront/js/.babelrc
@@ -0,0 +1,15 @@
+{
+ "presets": [
+ ["@babel/preset-env", {
+ "targets": {
+ "browsers": ["last 2 versions", "IE >= 11"]
+ }
+ }],
+ "@babel/preset-react"
+ ],
+ "plugins": [
+ "@babel/plugin-proposal-class-properties",
+ "@babel/plugin-proposal-object-rest-spread",
+ "lodash"
+ ]
+}
diff --git a/votrfront/js/.eslintrc b/votrfront/js/.eslintrc
new file mode 100644
index 0000000..f8e357b
--- /dev/null
+++ b/votrfront/js/.eslintrc
@@ -0,0 +1,202 @@
+{
+ "parser": "babel-eslint",
+ "parserOptions":{
+ "ecmaFeatures": {
+ "jsx": true
+ }
+ },
+ "settings": {
+ "import/parser": "babel-eslint",
+ "import/ignore": ["node_modules", "\\.(scss|less|css)$"]
+ },
+ "rules": {
+ "array-bracket-spacing": [2, "never"],
+ "arrow-parens": [2, "always"],
+ "arrow-spacing": 2,
+ "block-spacing": [2, "never"],
+ "brace-style": [2, "1tbs", {"allowSingleLine": true}],
+ "camelcase": [2, {"properties": "never"}],
+ "comma-dangle": [2, "always-multiline"],
+ "comma-spacing": [2, {"before": false, "after": true}],
+ "comma-style": [2, "last"],
+ "computed-property-spacing": [2, "never"],
+ "consistent-this": [2, "self"],
+ "constructor-super": 2,
+ "curly": [2, "multi-line", "consistent"],
+ "default-case": 2,
+ "dot-location": [2, "property"],
+ "dot-notation": [2],
+ "eol-last": 2,
+ "eqeqeq": [2, "allow-null"],
+ "guard-for-in": 2,
+ "indent": [2, 2, {"SwitchCase": 1}],
+ "jsx-quotes": [2, "prefer-double"],
+ "key-spacing": [2, {"beforeColon": false, "afterColon": true}],
+ "keyword-spacing": [2, {"before": true, "after": true, "overrides": {}}],
+ "linebreak-style": [2, "unix"],
+ "max-len": [2, 115, 2],
+ "new-cap": [2, {"capIsNew": false, "newIsCap": true}],
+ "new-parens": 2,
+ "no-alert": 1,
+ "no-array-constructor": 2,
+ "no-bitwise": 2,
+ "no-caller": 2,
+ "no-case-declarations": 2,
+ "no-class-assign": 2,
+ "no-cond-assign": 2,
+ "no-console": [1, {"allow": ["error"]}],
+ "no-const-assign": 2,
+ "no-constant-condition": 2,
+ "no-debugger": 2,
+ "no-delete-var": 2,
+ "no-dupe-args": 2,
+ "no-dupe-class-members": 2,
+ "no-dupe-keys": 2,
+ "no-duplicate-case": 2,
+ "no-duplicate-imports": 2,
+ "no-empty": 2,
+ "no-empty-character-class": 2,
+ "no-empty-function": 2,
+ "no-empty-pattern": 2,
+ "no-eval": 2,
+ "no-ex-assign": 2,
+ "no-extend-native": 2,
+ "no-extra-boolean-cast": 2,
+ "no-extra-parens": 0,
+ "no-fallthrough": 2,
+ "no-floating-decimal": 2,
+ "no-func-assign": 2,
+ "no-implied-eval": 2,
+ "no-inner-declarations": 2,
+ "no-invalid-regexp": 2,
+ "no-irregular-whitespace": 2,
+ "no-iterator": 2,
+ "no-labels": 2,
+ "no-lone-blocks": 2,
+ "no-lonely-if": 0,
+ "no-loop-func": 2,
+ "no-mixed-spaces-and-tabs": 2,
+ "no-multi-spaces": 2,
+ "no-multi-str": 2,
+ "no-multiple-empty-lines": 2,
+ "no-native-reassign": 2,
+ "no-negated-in-lhs": 2,
+ "no-new": 2,
+ "no-new-func": 2,
+ "no-new-object": 2,
+ "no-new-wrappers": 2,
+ "no-obj-calls": 2,
+ "no-octal": 2,
+ "no-octal-escape": 2,
+ "no-plusplus": 0,
+ "no-proto": 2,
+ "no-redeclare": 2,
+ "no-regex-spaces": 2,
+ "no-return-assign": 2,
+ "no-script-url": 2,
+ "no-self-assign": 2,
+ "no-self-compare": 2,
+ "no-sequences": 2,
+ "no-shadow": 0,
+ "no-shadow-restricted-names": 2,
+ "no-spaced-func": 2,
+ "no-sparse-arrays": 2,
+ "no-this-before-super": 2,
+ "no-throw-literal": 2,
+ "no-trailing-spaces": 2,
+ "no-undef": 2,
+ "no-undef-init": 2,
+ "no-undefined": 0,
+ "no-underscore-dangle": 0,
+ "no-unexpected-multiline": 2,
+ "no-unmodified-loop-condition": 2,
+ "no-unneeded-ternary": [2, {"defaultAssignment": false}],
+ "no-unreachable": 2,
+ "no-unsafe-finally": 2,
+ "no-unused-expressions": [2, {"allowShortCircuit": true, "allowTernary": true}],
+ "no-unused-vars": [2, {"vars": "all", "args": "none"}],
+ "no-use-before-define": [2, "nofunc"],
+ "no-useless-call": 2,
+ "no-useless-computed-key": 2,
+ "no-useless-concat": 2,
+ "no-useless-constructor": 2,
+ "no-useless-escape": 2,
+ "no-useless-rename": 2,
+ "no-var": 2,
+ "no-void": 2,
+ "no-warning-comments": [0, {"terms": ["todo", "fixme"]}],
+ "no-whitespace-before-property": 2,
+ "no-with": 2,
+ "object-curly-spacing": [2, "always"],
+ "prefer-arrow-callback": 2,
+ "prefer-rest-params": 2,
+ "prefer-spread": 2,
+ "quote-props": [2, "consistent-as-needed"],
+ "quotes": [2, "single", "avoid-escape"],
+ "radix": 2,
+ "rest-spread-spacing": 2,
+ "semi": [2, "always"],
+ "semi-spacing": [2, {"before": false, "after": true}],
+ "space-before-blocks": [2, "always"],
+ "space-before-function-paren": [2, "never"],
+ "space-in-parens": [2, "never"],
+ "space-infix-ops": 2,
+ "space-unary-ops": [2, {"words": true, "nonwords": false}],
+ "strict": [2, "never"],
+ "template-curly-spacing": 2,
+ "use-isnan": 2,
+ "valid-typeof": 2,
+ "vars-on-top": 2,
+ "wrap-iife": [2, "inside"],
+ "yoda": 2,
+ // Node.js specific
+ "handle-callback-err": [2, "^(err|error)$"],
+ "no-mixed-requires": 2,
+ "no-new-require": 2,
+ "no-path-concat": 2,
+ // React
+ "react/jsx-boolean-value": 2,
+ "react/jsx-curly-spacing": [2, "never"],
+ "react/jsx-equals-spacing": [2, "never"],
+ "react/jsx-indent": [2, 2],
+ "react/jsx-indent-props": [2, 2],
+ "react/jsx-no-duplicate-props": 2,
+ "react/jsx-no-undef": 2,
+ "react/jsx-sort-prop-types": 0,
+ "react/jsx-sort-props": 0,
+ "react/jsx-tag-spacing": ["error", { "beforeSelfClosing": "always" }],
+ "react/jsx-uses-react": 2,
+ "react/jsx-uses-vars": 2,
+ "react/jsx-wrap-multilines": 2,
+ "react/no-did-mount-set-state": 2,
+ "react/no-did-update-set-state": 2,
+ "react/no-multi-comp": 0,
+ "react/no-unknown-property": 2,
+ "react/prop-types": 0,
+ "react/react-in-jsx-scope": 2,
+ "react/self-closing-comp": 2,
+ // Not ready yet. "react/sort-comp": 1,
+ // Import
+ "import/default": 0,
+ "import/export": 2,
+ "import/imports-first": 2,
+ "import/named": 2,
+ "import/no-unresolved": [2, {"commonjs": true, "amd": true}],
+ },
+ "plugins": [
+ "react",
+ "import",
+ "babel"
+ ],
+ "env": {
+ "node": true,
+ "browser": true
+ },
+ "globals": {
+ "Promise": true,
+ "Map": true,
+ "Set": true,
+ "Votr": true,
+ "ga": true
+ }
+}
diff --git a/votrfront/js/.nvmrc b/votrfront/js/.nvmrc
new file mode 100644
index 0000000..641c7df
--- /dev/null
+++ b/votrfront/js/.nvmrc
@@ -0,0 +1 @@
+v8.9.4
diff --git a/votrfront/js/About.js b/votrfront/js/About.js
deleted file mode 100644
index d258fab..0000000
--- a/votrfront/js/About.js
+++ /dev/null
@@ -1,102 +0,0 @@
-
-import { Modal, PageLayout } from './layout';
-
-
-export var AboutModal = React.createClass({
- render() {
- var github = "https://github.com/fmfi-svt/votr";
- return
-
- Len málokto sa vyzná v AISe. Kým sa študent dostane k tomu, čo
- potrebuje, musí sa prebiť cez hŕbu okien a menu. A ani pravidelné
- činnosti, ako zapisovanie sa na skúšky, nie sú výnimkou. Preto sme
- vytvorili aplikáciu Votr. Vybrali sme tie najdôležitejšie informácie z
- AISu a sprístupnili sme ich na jeden klik.
-
-
- Cez Votr si študenti môžu zapísať skúšky, pozrieť hodnotenia,
- skontrolovať počet kreditov a podobne. Votr používa tie isté dáta, ako
- AIS, ale podáva ich prehľadnejším spôsobom.
-
- Pomoc a technická podpora
-
- Ak vám Votr nefunguje alebo máte akékoľvek otázky, nápady či
- pripomienky, napíšte nám na
- fmfi-svt@googlegroups.com a radi vám pomôžeme. Alebo ak chcete,
- môžete zavolať na
- hotline CePIT .
-
-
- Cez Votr sa nedá robiť všetko to, čo v AISe — sústredí sa na
- zjednodušenie tých najčastejších činností. Ak hľadáte záverečné práce,
- štátne skúšky a ďalšie menej časté veci, musíte ísť cez AIS.
-
- Autori projektu
-
- Votr je projektom Študentského vývojového tímu z Fakulty matematiky,
- fyziky a informatiky UK. Naprogramovali ho Tomáš Belan, Dušan Plavák a ďalší spoluautori . Vývoj prebieha
- verejne na stránke {github} . Ak sa
- vám Votr páči a chceli by ste sa zapojiť, napíšte nám!
-
- Meno projektu
-
- Čo znamená meno "Votr"? Je to fonetický prepis anglického slova "water".
- V tejto slovnej hračke začal už predchodca Votru, ktorý sa volal "FAJR"
- (pretože "fajr" a "ais" sú protiklady). Keď sme sa neskôr rozhodli
- prebudovať FAJR na novom základe, nazvali sme ho "Votr", lebo má ku AISu
- bližšie a vie s ním plynule narábať. Aj mená interných súčastí Votru
- pokračujú v tejto téme.
-
- ;
- }
-});
-
-
-export var IndexPage = React.createClass({
- render() {
- // TODO: Use PageTitle, but show different h1.
- return
- Vitajte
-
- Votr je alternatívne rozhranie pre systém AIS2. Cez menu sa dostanete
- k týmto informáciám:
-
-
-
- Moje predmety — predmety, ktoré máte zapísané
- v tomto alebo minulom akademickom roku, a získané hodnotenia
-
-
- Moje skúšky — termíny skúšok, na ktoré ste
- prihlásení resp. na ktoré sa môžete prihlásiť
-
-
- Moje hodnotenia — hodnotenia predmetov a
- získané študijné priemery za celé štúdium
-
-
- Priebežné hodnotenia — priebežné hodnotenia
- predmetov počas semestra
-
-
- Zápis predmetov — pridávanie a odoberanie
- predmetov zo súčasného zápisného listu
-
-
- Prehľad štúdia — zoznam vašich štúdií a
- zápisných listov
-
-
- Register osôb — vyhľadávanie zamestnancov,
- študentov a absolventov univerzity, e-mailové kontakty
-
-
- Register predmetov — vyhľadávanie predmetov,
- informácie o ich učiteľoch a zoznamy zapísaných študentov
-
-
-
- }
-});
diff --git a/votrfront/js/AnketaPopup.js b/votrfront/js/AnketaPopup.js
deleted file mode 100644
index 1847861..0000000
--- a/votrfront/js/AnketaPopup.js
+++ /dev/null
@@ -1,80 +0,0 @@
-
-import { CacheRequester, Loading } from './ajax';
-
-var dropCookie = true; // false disables the Cookie, allowing you to style the banner
-var cookieDurationClose = 3;
-var cookieDurationVote = 60;
-var cookieName = 'anketaKolacik'; // Name of our cookie
-var cookieValue = 'on'; // Value of cookie
-var cookieHideDate = Date.parse('19 February 2018'); // Starting this day the cookie won't be visible
-
-
-export var AnketaPopup = React.createClass({
-
- getInitialState() {
- var today = new Date();
- if ((checkCookie(cookieName) != cookieValue) && (cookieHideDate > today)) {
- return {showPopup: true}
- }
- return {showPopup: false}
- },
-
- onClosePopup(action) {
- if(action == 0) {
- createCookie(cookieName, cookieValue, cookieDurationVote); // Create vote cookie
- } else {
- createCookie(cookieName, cookieValue, cookieDurationClose); // Create close cookie
- }
- this.setState({showPopup: false})
- },
-
- render() {
- if (!this.state.showPopup) return null;
-
- var cache = new CacheRequester();
- var studia = cache.get('get_studia');
- if (!studia) return
;
- if (!studia.some(s => s.organizacna_jednotka == 'FMFI')) return null;
-
- return
-
-
-
-
Daj semestru ešte chvíľu
-
-
-
-
;
- }
-});
-
-
-function createCookie(name, value, days) {
- if (days) {
- var date = new Date();
- date.setTime(date.getTime()+(days*24*60*60*1000));
- var expires = "; expires="+date.toGMTString();
- }
- else var expires = "";
- if(dropCookie) {
- document.cookie = name+"="+value+expires+"; path=/";
- }
-}
-
-function checkCookie(name) {
- var nameEQ = name + "=";
- var ca = document.cookie.split(';');
- for(var i=0;i < ca.length;i++) {
- var c = ca[i];
- while (c.charAt(0)==' ') c = c.substring(1,c.length);
- if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
- }
- return null;
-}
-
-function eraseCookie(name) {
- createCookie(name,"",-1);
-}
diff --git a/votrfront/js/DetailPredmetu.js b/votrfront/js/DetailPredmetu.js
deleted file mode 100644
index 9ee8046..0000000
--- a/votrfront/js/DetailPredmetu.js
+++ /dev/null
@@ -1,147 +0,0 @@
-
-import { ZoznamPrihlasenychNaTerminColumns } from './ZoznamPrihlasenychNaTermin';
-import { CacheRequester, Loading } from './ajax';
-import { Modal } from './layout';
-import { sortAs, sortTable } from './sorting';
-
-
-export var DetailPredmetuUciteliaColumns = [
- ["Meno", 'plne_meno', sortAs.personName],
- ["Typ", 'typ']
-];
-DetailPredmetuUciteliaColumns.defaultOrder = 'a0';
-
-export var DetailPredmetuStudentiColumns = ZoznamPrihlasenychNaTerminColumns.slice();
-DetailPredmetuStudentiColumns.defaultOrder = 'a0';
-
-export var DetailPredmetuModal = React.createClass({
- getZapisaniStudenti(cache, predmetKey, akademickyRok){
- return cache.get('get_studenti_zapisani_na_predmet', predmetKey, akademickyRok);
- },
-
- renderInformacnyListPredmetu() {
- var cache = new CacheRequester();
- var {modalAkademickyRok, modalPredmetKey} = this.props.query;
-
- var data = cache.get('get_informacny_list', modalPredmetKey, modalAkademickyRok);
-
- if (!data) {
- return ;
- }
-
- var url = "data:application/pdf;base64," + escape(data);
- return Stiahnuť ;
- },
-
- renderUcitelia() {
- var cache = new CacheRequester();
- var {modalAkademickyRok, modalPredmetKey} = this.props.query;
-
- var data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok);
-
- if (!data) {
- return ;
- }
-
- var [studenti, predmet] = data;
-
- if (!predmet) {
- return "Dáta pre predmet neboli nájdené.";
- }
-
- var ucitelia = cache.get('get_ucitelia_predmetu', modalPredmetKey, modalAkademickyRok, predmet.semester, predmet.fakulta);
-
- if (!ucitelia) {
- return ;
- }
-
- var [ucitelia, header] = sortTable(
- ucitelia, DetailPredmetuUciteliaColumns, this.props.query, 'modalUciteliaSort');
-
- var message = ucitelia.length ? null : "Predmet nemá v AISe žiadnych učiteľov.";
-
- return
- {header}
-
- {ucitelia.map((ucitel, index) =>
-
- {ucitel.plne_meno}
- {ucitel.typ}
-
- )}
-
- {message && {message} }
-
;
- },
-
- renderZapisaniStudenti() {
- var cache = new CacheRequester();
- var {modalAkademickyRok, modalPredmetKey} = this.props.query;
-
- var data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok);
-
- if (!data) {
- return ;
- }
-
- var [studenti, predmet] = data;
-
- if (!predmet) {
- return "Dáta pre predmet neboli nájdené.";
- }
-
- var [studenti, header] = sortTable(
- studenti, DetailPredmetuStudentiColumns, this.props.query, 'modalStudentiSort');
-
- var message = studenti.length ? null : "Predmet nemá v AISe žiadnych zapísaných študentov.";
-
- return
- {header}
-
- {studenti.map((student, index) =>
-
- {student.plne_meno}
- {student.sp_skratka}
- {student.rocnik}
- {student.email &&
- {student.email} }
-
- {student.datum_prihlasenia}
-
- )}
-
- {message && {message} }
-
;
- },
-
- renderTitle() {
- var cache = new CacheRequester();
- var {modalAkademickyRok, modalPredmetKey} = this.props.query;
-
- var data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok);
-
- if (!data) {
- return ;
- }
-
- var [studenti, predmet] = data;
-
- if (!predmet) {
- return "Dáta nenájdené";
- }
-
- return predmet.nazov;
- },
-
- render() {
- return
-
- Informačný list predmetu
- {this.renderInformacnyListPredmetu()}
- Učitelia
- {this.renderUcitelia()}
- Zapísaní študenti
- {this.renderZapisaniStudenti()}
- ;
- }
-});
diff --git a/votrfront/js/ErrorPage.js b/votrfront/js/ErrorPage.js
deleted file mode 100644
index b0f7c1a..0000000
--- a/votrfront/js/ErrorPage.js
+++ /dev/null
@@ -1,98 +0,0 @@
-
-import { goLogout, goReset, goResetHome } from './ajax';
-import { Modal, ModalBase } from './layout';
-import { AnalyticsMixin, FakeLink } from './router';
-
-
-export var ErrorModal = React.createClass({
- getInitialState() {
- return {
- open: false
- }
- },
-
- handleIgnore() {
- Votr.ajaxError = null;
- Votr.appRoot.forceUpdate();
- },
-
- handleDetails() {
- this.setState({ open: true });
- },
-
- render() {
- var error = Votr.settings.error || Votr.ajaxError;
- var lastLine = _.last(error.trim("\n").split("\n"));
- var type = lastLine.split(":")[0]
-
- var title = "Chyba";
- var description = "Vyskytla sa chyba a vaša požiadavka nebola spracovaná.";
- var contact = true;
-
- if (type == "aisikl.exceptions.LoggedOutError") {
- title = "Prihlásenie vypršalo";
- description = "Vaše prihlásenie vypršalo. Skúste znova.";
- contact = false;
- } else if (Votr.settings.error || type.match(/^requests\.exceptions\./)) {
- title = "Chyba pripojenia";
- description = "Votr sa nevie pripojiť na AIS.";
- contact = false;
- } else {
- if (type == "aisikl.exceptions.AISParseError") {
- description = "Votr nerozumie, čo spravil AIS. V novej verzii AISu sa asi niečo zmenilo.";
- }
- if (type == "aisikl.exceptions.AISBehaviorError") {
- if (lastLine.match(/args=\['(Nie je connection|Nastala SQL chyba)/)) {
- description = "AIS sa nevie pripojiť na svoju databázu.";
- contact = false;
- } else {
- description = "AIS spravil niečo nečakané a Votr si s tým nevie poradiť.";
- }
- }
- }
-
- // Some errors are caused by a malformed URL, so resetting won't help. If
- // we haven't navigated since the last full reload (the user has probably
- // reset just now), we redirect to the front page instead.
- var goHome = !Votr.didNavigate && !Votr.settings.error && location.search.substring(1);
-
- return
- {description}
- {contact &&
-
- Ak problém pretrváva, napíšte nám na fmfi-svt@googlegroups.com .
-
}
-
-
- {goHome ?
- Späť na začiatok :
- Skúsiť znova }
- Odhlásiť
-
-
- {this.state.open ?
- {error} :
-
- Technické detaily: {lastLine}
{" "}
- Viac detailov...
-
}
- {!Votr.settings.error && this.state.open &&
- Ignorovať chybu }
- ;
- }
-});
-
-
-export var ErrorPage = React.createClass({
- mixins: [AnalyticsMixin],
-
- render() {
- // TODO: ModalBase should probably use transferPropsTo() instead of requiring query.
- return
- }
-});
diff --git a/votrfront/js/LocalSettings.js b/votrfront/js/LocalSettings.js
deleted file mode 100644
index 8689521..0000000
--- a/votrfront/js/LocalSettings.js
+++ /dev/null
@@ -1,11 +0,0 @@
-
-export var LocalSettings = {
- get(key) {
- return localStorage.getItem(Votr.settings.instance_name + "_" + key);
- },
-
- set(key, value) {
- localStorage.setItem(Votr.settings.instance_name + "_" + key, value);
- Votr.appRoot.forceUpdate();
- }
-};
diff --git a/votrfront/js/LogViewer.js b/votrfront/js/LogViewer.js
deleted file mode 100644
index b7faa59..0000000
--- a/votrfront/js/LogViewer.js
+++ /dev/null
@@ -1,168 +0,0 @@
-
-import { LocalSettings } from './LocalSettings';
-import { logs } from './ajax';
-
-
-export var LogViewerContent = React.createClass({
- getInitialState() {
- return {
- benchmark: true,
- http: true,
- table: true
- }
- },
-
- handleChange(e) {
- var update = {};
- update[e.target.name] = !e.target.checked;
- this.setState(update);
- },
-
- componentDidUpdate() {
- var div = this.refs.scroll;
- var time = _.last(logs).time;
- if (time != this.lastTime) {
- this.lastTime = time;
- div.scrollTop = div.scrollHeight;
- }
- },
-
- render() {
- var types = _.countBy(logs, 'log');
-
- return
-
- {this.props.closeButton}
- {this.props.modeButton}
-
-
-
-
-
-
- {logs.map((entry, index) => !this.state[entry.log] &&
-
- {(entry.time - logs[0].time).toFixed(3)}
- {entry.log}
- {entry.message}
-
- )}
-
-
-
-
;
- }
-});
-
-
-export var LogViewerBenchmarkContent = React.createClass({
- computeBenchmarks() {
- var sums = {};
- var beginnings = {};
-
- function start(what, time) {
- beginnings[what] = time;
- }
- function end(what, time) {
- if (!beginnings[what]) return;
- if (!sums[what]) sums[what] = 0;
- sums[what] += time - beginnings[what];
- delete beginnings[what];
- }
-
- logs.forEach((entry) => {
- if (entry.log == 'benchmark' && entry.message.substr(0, 6) == 'Begin ') {
- start(entry.message.substr(6), entry.time);
- }
- if (entry.log == 'benchmark' && entry.message.substr(0, 4) == 'End ') {
- end(entry.message.substr(4), entry.time);
- }
- if (entry.log == 'rpc' && entry.message.substr(-8) == ' started') {
- start('total RPC time', entry.time);
- }
- if (entry.log == 'rpc' && entry.message.substr(-9) == ' finished') {
- end('total RPC time', entry.time);
- }
- });
-
- return _(sums).pairs().sortBy(1).reverse().valueOf();
- },
-
- render() {
- var benchmarks = this.computeBenchmarks();
-
- return
-
- {this.props.closeButton}
- {this.props.modeButton}
-
-
-
-
-
- {benchmarks.map(([message, sum], index) =>
-
- {sum.toFixed(3)}
- {message}
-
- )}
-
-
-
-
;
- }
-});
-
-
-export var LogViewer = React.createClass({
- toggle() {
- LocalSettings.set("logViewer",
- LocalSettings.get("logViewer") ? "" : "log");
- },
-
- toggleMode() {
- LocalSettings.set("logViewer",
- LocalSettings.get("logViewer") == "log" ? "benchmark" : "log");
- },
-
- handleKeypress(e) {
- if (e.ctrlKey && e.altKey && e.shiftKey && e.which == 76) { // Ctrl+Alt+Shift+L
- this.toggle();
- e.preventDefault();
- }
- },
-
- componentDidMount() {
- $(window).on('keydown.logViewer', this.handleKeypress);
- },
-
- componentWillUnmount() {
- $(window).off('keydown.logViewer');
- },
-
- render() {
- var mode = LocalSettings.get("logViewer");
-
- if (mode != "log" && mode != "benchmark") return null;
-
- var modeButton = {mode} ;
-
- var closeButton =
- ×
- Close
- ;
-
- var C = mode == "log" ? LogViewerContent : LogViewerBenchmarkContent;
- return ;
- }
-});
diff --git a/votrfront/js/LoginPage.js b/votrfront/js/LoginPage.js
deleted file mode 100644
index 48919e1..0000000
--- a/votrfront/js/LoginPage.js
+++ /dev/null
@@ -1,197 +0,0 @@
-
-import { AboutModal } from './About';
-import { Modal, ModalBase } from './layout';
-import { AnalyticsMixin, FakeLink } from './router';
-
-
-var TYPE_NAMES = {
- 'cosignproxy': 'Cosign (automatické)',
- 'cosignpassword': 'Cosign (meno a heslo)',
- 'cosigncookie': 'Cosign (manuálne cookie)',
- 'plainpassword': 'Meno a heslo',
- 'demo': 'Demo'
-};
-
-
-export var LoginForm = React.createClass({
- getInitialState() {
- return {
- server: Votr.settings.server || 0,
- type: Votr.settings.type
- };
- },
-
- handleServerChange(event) {
- var server = event.target.value;
- var newTypes = Votr.settings.servers[server].login_types;
- var type = _.includes(newTypes, this.state.type) ? this.state.type : null;
- this.setState({ server, type });
- },
-
- handleTypeChange(event) {
- this.setState({ type: event.target.value });
- },
-
- render() {
- var serverConfig = Votr.settings.servers[this.state.server];
- var currentType = this.state.type || serverConfig.login_types[0];
-
- return ;
- }
-});
-
-
-export var LoginErrorModal = React.createClass({
- render() {
- return
- {Votr.settings.error}
- ;
- }
-});
-
-
-export var LoginPage = React.createClass({
- mixins: [AnalyticsMixin],
-
- getInitialState() {
- return {};
- },
-
- openAbout() {
- this.setState({ modal: 'about' });
- },
-
- openError() {
- this.setState({ modal: 'error' });
- },
-
- closeModal() {
- this.setState({ modal: null });
- },
-
- render() {
- var content =
-
-
-
- Votr ponúka študentom jednoduchší a pohodlnejší
- spôsob, ako robiť najčastejšie činnosti zo systému AIS. Zapíšte sa na
- skúšky, prezrite si vaše hodnotenia a skontrolujte si počet kreditov
- bez zbytočného klikania.
-
-
-
-
-
-
;
-
- var modals = { 'about': AboutModal, 'error': LoginErrorModal };
- var modalComponent = modals[this.state.modal];
-
- return
- {content}
-
- ;
- }
-});
diff --git a/votrfront/js/MojeHodnoteniaPage.js b/votrfront/js/MojeHodnoteniaPage.js
deleted file mode 100644
index 978f259..0000000
--- a/votrfront/js/MojeHodnoteniaPage.js
+++ /dev/null
@@ -1,158 +0,0 @@
-
-import { MojePredmetyColumns } from './MojePredmetyPage';
-import { StudiumSelector } from './StudiumSelector';
-import { CacheRequester, Loading } from './ajax';
-import { coursesStats, renderWeightedStudyAverage } from './coursesStats';
-import { classForSemester, humanizeNazovPriemeru, humanizeTerminHodnotenia, humanizeTypVyucby, plural } from './humanizeAISData';
-import { PageLayout, PageTitle } from './layout';
-import { Link } from './router';
-import { sortAs, sortTable } from './sorting';
-
-
-export var MojeHodnoteniaColumns = [
- ["Akademický rok", 'akademicky_rok']
-].concat(MojePredmetyColumns);
-MojeHodnoteniaColumns.defaultOrder = 'a0d1a2';
-
-
-export var MojePriemeryColumns = [
- ["Dátum výpočtu priemeru", 'datum_vypoctu', sortAs.date],
- ["Názov priemeru", 'nazov'],
- ["Akademický rok", 'akademicky_rok'],
- ["Semester", 'semester', null, true],
- ["Získaný kredit", 'ziskany_kredit', sortAs.number],
- ["Celkový počet predmetov", 'predmetov', sortAs.number],
- ["Počet neabsolvovaných predmetov", 'neabsolvovanych', sortAs.number],
- ["Študijný priemer", 'studijny_priemer', sortAs.number],
- ["Vážený priemer", 'vazeny_priemer', sortAs.number]
-];
-MojePriemeryColumns.defaultOrder = 'a0a2a1';
-
-
-export var MojeHodnoteniaPageContent = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- renderHodnotenia() {
- var cache = new CacheRequester();
- var {studiumKey} = this.props.query;
- var [hodnotenia, message] = cache.get('get_prehlad_kreditov', studiumKey) || [];
-
- if (!hodnotenia) {
- return ;
- }
-
- var [hodnotenia, header] = sortTable(
- hodnotenia, MojeHodnoteniaColumns, this.props.query, 'predmetySort');
-
- var stats = coursesStats(hodnotenia);
-
- return
- {header}
-
- {hodnotenia.map((hodnotenie) =>
-
- {hodnotenie.akademicky_rok}
- {hodnotenie.semester}
-
- {hodnotenie.nazov}
-
- {hodnotenie.skratka}
- {hodnotenie.kredit}
- {humanizeTypVyucby(hodnotenie.typ_vyucby)}
-
- {hodnotenie.hodn_znamka}
- {hodnotenie.hodn_znamka ? " - " : null}
- {hodnotenie.hodn_znamka_popis}
-
- {hodnotenie.hodn_datum}
- {humanizeTerminHodnotenia(hodnotenie.hodn_termin)}
-
- )}
-
-
-
- Celkom {stats.spolu.count} {plural(stats.spolu.count, "predmet", "predmety", "predmetov")}
- {stats.spolu.creditsCount}
-
- {renderWeightedStudyAverage(hodnotenia)}
-
-
-
- {message && {message} }
-
-
;
- },
-
- renderPriemery() {
- var cache = new CacheRequester();
- var {studiumKey} = this.props.query;
-
- var priemery, message;
- var zapisneListy = cache.get('get_zapisne_listy', studiumKey);
-
- if (zapisneListy && zapisneListy.length == 0) {
- priemery = [];
- } else if (zapisneListy) {
- var zapisnyListKey = _.max(zapisneListy,
- (zapisnyList) => sortAs.date(zapisnyList.datum_zapisu)).zapisny_list_key;
- [priemery, message] = cache.get('get_priemery', zapisnyListKey) || [];
- }
-
- if (!priemery) {
- return ;
- }
-
- var [priemery, header] = sortTable(
- priemery, MojePriemeryColumns, this.props.query, 'priemerySort');
-
- if (!message && !priemery.length) {
- message = "V AISe zatiaľ nie sú vypočítané žiadne priemery.";
- }
-
- return
- {header}
-
- {priemery.map((priemer, index) =>
-
- {priemer.datum_vypoctu}
- {humanizeNazovPriemeru(priemer.nazov)}
- {priemer.akademicky_rok}
- {priemer.semester}
- {priemer.ziskany_kredit}
- {priemer.predmetov}
- {priemer.neabsolvovanych}
- {priemer.studijny_priemer}
- {priemer.vazeny_priemer}
-
- )}
-
- {message && {message} }
-
;
- },
-
- render() {
- return
-
- {this.renderHodnotenia()}
-
Moje priemery
- {this.renderPriemery()}
-
;
- }
-});
-
-
-export var MojeHodnoteniaPage = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- render() {
- return
-
- ;
- }
-});
diff --git a/votrfront/js/MojePredmetyPage.js b/votrfront/js/MojePredmetyPage.js
deleted file mode 100644
index 269e51e..0000000
--- a/votrfront/js/MojePredmetyPage.js
+++ /dev/null
@@ -1,104 +0,0 @@
-
-import { ZapisnyListSelector } from './ZapisnyListSelector';
-import { CacheRequester, Loading } from './ajax';
-import { coursesStats, renderWeightedStudyAverage } from './coursesStats';
-import { classForSemester, humanizeTerminHodnotenia, humanizeTypVyucby, plural } from './humanizeAISData';
-import { PageLayout, PageTitle } from './layout';
-import { Link } from './router';
-import { sortAs, sortTable } from './sorting';
-
-
-export var MojePredmetyColumns = [
- [Sem. , 'semester', null, true],
- ["Názov predmetu", 'nazov'],
- ["Skratka predmetu", 'skratka'],
- ["Kredit", 'kredit', sortAs.number],
- ["Typ výučby", 'typ_vyucby'],
- ["Hodnotenie", 'hodn_znamka'],
- ["Dátum hodnotenia", 'hodn_datum', sortAs.date],
- ["Termín hodnotenia", 'hodn_termin']
-];
-MojePredmetyColumns.defaultOrder = 'd0a1';
-
-
-export var MojePredmetyPageContent = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- renderContent() {
- var cache = new CacheRequester();
- var {zapisnyListKey} = this.props.query;
- var [hodnotenia, message] = cache.get('get_hodnotenia', zapisnyListKey) || [];
-
- if (!hodnotenia) {
- return ;
- }
-
- var [hodnotenia, header] = sortTable(
- hodnotenia, MojePredmetyColumns, this.props.query, 'predmetySort');
-
- var stats = coursesStats(hodnotenia);
-
- return
- {header}
-
- {hodnotenia.map((hodnotenie) =>
-
- {hodnotenie.semester}
-
- {hodnotenie.nazov}
-
- {hodnotenie.skratka}
- {hodnotenie.kredit}
- {humanizeTypVyucby(hodnotenie.typ_vyucby)}
-
- {hodnotenie.hodn_znamka}
- {hodnotenie.hodn_znamka ? " - " : null}
- {hodnotenie.hodn_znamka_popis}
-
- {hodnotenie.hodn_datum}
- {humanizeTerminHodnotenia(hodnotenie.hodn_termin)}
-
- )}
-
-
-
-
- Celkom {stats.spolu.count} {plural(stats.spolu.count, "predmet", "predmety", "predmetov")}
- {" ("}{stats.zima.count} v zime, {stats.leto.count} v lete)
-
- {stats.spolu.creditsCount} ({stats.zima.creditsCount}+{stats.leto.creditsCount})
-
- {renderWeightedStudyAverage(hodnotenia)}
-
-
-
- {message && {message} }
-
-
;
- },
-
- render() {
- var {zapisnyListKey} = this.props.query;
- return
-
- {this.renderContent()}
-
;
- }
-});
-
-
-export var MojePredmetyPage = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- render() {
- return
-
- ;
- }
-});
diff --git a/votrfront/js/MojeSkuskyPage.js b/votrfront/js/MojeSkuskyPage.js
deleted file mode 100644
index dd818d4..0000000
--- a/votrfront/js/MojeSkuskyPage.js
+++ /dev/null
@@ -1,252 +0,0 @@
-
-import { ZapisnyListSelector } from './ZapisnyListSelector';
-import { CacheRequester, Loading, RequestCache, sendRpc } from './ajax';
-import { PageLayout, PageTitle } from './layout';
-import { Link } from './router';
-import { sortAs, sortTable } from './sorting';
-
-
-// TODO: Oddelit Aktualne terminy hodnotenia vs Stare terminy hodnotenia
-
-export var MojeSkuskyColumns = [
- ["Moje?", null, (termin) => !termin.datum_prihlasenia || termin.datum_odhlasenia ? 'N' : 'A'],
- ["Predmet", 'nazov_predmetu'],
- ["Dátum", 'datum', sortAs.date],
- ["Čas", 'cas'],
- ["Miestnosť", 'miestnost'],
- ["Hodnotiaci", 'hodnotiaci', sortAs.personName],
- ["Prihlásení", 'pocet_prihlasenych', sortAs.number],
- ["Poznámka", 'poznamka'],
- ["Prihlasovanie", 'prihlasovanie', sortAs.interval],
- ["Odhlasovanie", 'odhlasovanie', sortAs.interval],
- ["Známka", null, (termin) => termin.hodnotenie_terminu || termin.hodnotenie_predmetu]
-];
-
-function convertToICAL(terminy) {
- // standard: https://tools.ietf.org/html/rfc5545
- // verificator: http://severinghaus.org/projects/icv/
-
- // header
- var lines = [
- "BEGIN:VCALENDAR",
- "VERSION:2.0",
- "PRODID:-//svt.fmph.uniba.sk//NONSGML votr-2017//EN",
- "X-WR-CALNAME:Moje skúšky",
- "X-WR-CALDESC:Kalendár skúšok vyexportovaný z aplikácie Votr",
- "X-WR-TIMEZONE:Europe/Bratislava",
- ];
-
- var dtstamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+/, '');
-
- // VEVENTs
- for (var termin of terminy) {
- if (!termin.datum_prihlasenia || termin.datum_odhlasenia) {
- // nie je prihlaseny
- continue;
- }
- lines.push("BEGIN:VEVENT");
-
- lines.push("SUMMARY:" + termin.nazov_predmetu);
-
- // unique identificator for each event (so we can identify copies of the same event)
- var uid = termin.termin_key + "@votr.uniba.sk";
- lines.push("UID:" + uid);
-
- // DTSTAMP is when this VEVENT was created (exported), must be YYYYMMDDTHHMMSSZ
- lines.push("DTSTAMP:" + dtstamp);
-
- // DTSTART, DTEND
- var [den, mesiac, rok] = termin.datum.split(".");
- var [hodina, minuty] = termin.cas.split(":");
- var dtstart = `${rok}${mesiac}${den}T${hodina}${minuty}00`;
-
- // as for there is no info about duration, we'll set it for 4 hours
- var hodina_koniec = (parseInt(hodina) + 4).toString();
- // add leading zero
- if (hodina_koniec.length == 1) {
- hodina_koniec = "0" + hodina_koniec;
- }
- var dtend = `${rok}${mesiac}${den}T${hodina_koniec}${minuty}00`;
- lines.push("DTSTART;TZID=Europe/Bratislava:" + dtstart);
- lines.push("DTEND;TZID=Europe/Bratislava:" + dtend);
-
- // LOCATION
- if (termin.miestnost) {
- lines.push("LOCATION:" + termin.miestnost);
- }
-
- // DESCRIPTION
- //@TODO ake vsetky informacie chceme zobrazovat v popise eventu? (zatial su take, ako vo FAJR)
- var desc = "Prihlasovanie: " + termin.prihlasovanie + "\n" +
- "Odhlasovanie: " + termin.odhlasovanie + "\n" +
- "Poznámka: " + termin.poznamka;
- lines.push("DESCRIPTION:" + desc);
-
- lines.push("END:VEVENT");
- }
-
- // footer
- lines.push("END:VCALENDAR");
-
- return lines.map((l) => l.replace(/\n/g, "\\n")).join("\r\n");
-}
-
-export var MojeSkuskyPageContent = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- renderContent() {
- var cache = new CacheRequester();
- var {zapisnyListKey} = this.props.query;
-
- var vidim = cache.get('get_vidim_terminy_hodnotenia', zapisnyListKey);
-
- if (!cache.loadedAll) {
- return ;
- }
-
- if (!vidim) {
- return Skúšky pre tento zápisný list už nie sú k dispozícii.
;
- }
-
- var terminyPrihlasene = cache.get('get_prihlasene_terminy', zapisnyListKey);
- var terminyVypisane = cache.get('get_vypisane_terminy', zapisnyListKey);
-
- if (!terminyPrihlasene || !terminyVypisane) {
- return ;
- }
-
- var terminy = {};
- terminyVypisane.forEach((termin) => terminy[termin.termin_key] = termin);
- terminyPrihlasene.forEach((termin) => terminy[termin.termin_key] = termin);
- terminy = _.values(terminy);
-
- var [terminy, header] = sortTable(
- terminy, MojeSkuskyColumns, this.props.query, 'skuskySort');
-
- var message = terminy.length ? null : "Zatiaľ nie sú vypísané žiadne termíny.";
-
- function handleClickICal() {
- var icalText = convertToICAL(terminyPrihlasene);
- var blob = new Blob([icalText], {type: "text/calendar;charset=utf-8"});
- saveAs(blob, "MojeTerminy.ics", true);
- }
-
- return
-
- {header}
-
- {terminy.map((termin) =>
-
- {!termin.datum_prihlasenia || termin.datum_odhlasenia ?
- {"\u2718"} :
- {"\u2714"} }
-
- {termin.nazov_predmetu}
-
- {termin.datum}
- {termin.cas}
- {termin.miestnost}
- {termin.hodnotiaci}
-
- {termin.pocet_prihlasenych +
- (termin.maximalne_prihlasenych ? "/" + termin.maximalne_prihlasenych : "")}
-
- {termin.poznamka}
- {termin.prihlasovanie}
- {termin.odhlasovanie}
-
- {termin.hodnotenie_terminu ? termin.hodnotenie_terminu :
- termin.hodnotenie_predmetu ? termin.hodnotenie_predmetu + ' (nepriradená k termínu)' :
- null}
-
-
-
- )}
-
- {message && {message} }
-
- {terminy.length &&
Stiahnuť ako iCal }
-
;
- },
-
- render() {
- return
-
- {this.renderContent()}
-
;
- }
-});
-
-
-export var SkuskyRegisterButton = React.createClass({
- propTypes: {
- termin: React.PropTypes.object.isRequired
- },
-
- getInitialState() {
- return {
- pressed: false
- };
- },
-
- handleClick() {
- var command = this.isSigninButton() ? 'prihlas_na_termin' : 'odhlas_z_terminu';
- var termin = this.props.termin;
-
- sendRpc(command, [termin.termin_key], (message) => {
- if (message) {
- this.setState({ pressed: false });
- alert(message);
- } else {
- RequestCache.invalidate('get_prihlasene_terminy');
- RequestCache.invalidate('get_vypisane_terminy');
- RequestCache.invalidate('get_prihlaseni_studenti');
- }
- });
-
- this.setState({ pressed: true });
- },
-
- isDisabled() {
- var termin = this.props.termin;
- return (this.isSigninButton() && termin.moznost_prihlasit !== 'A') || this.state.pressed;
- },
-
- isSigninButton() {
- var termin = this.props.termin;
- return !termin.datum_prihlasenia || termin.datum_odhlasenia;
- },
-
- render() {
- var termin = this.props.termin;
-
- if (termin.hodnotenie_terminu) {
- return null;
- }
-
- var today = new Date().toJSON().replace(/-/g, '').substring(0, 8);
- if (today > sortAs.date(termin.datum)) return null;
-
- var buttonClass = "btn btn-xs " + (this.isSigninButton() ? "btn-success" : "btn-danger") + (this.isDisabled() ? " appear-disabled" : "");
- var buttonText = this.state.pressed ? : this.isSigninButton() ? "Prihlásiť" : "Odhlásiť";
-
- return {buttonText} ;
- }
-});
-
-
-export var MojeSkuskyPage = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- render() {
- return
-
- ;
- }
-});
diff --git a/votrfront/js/PrehladStudiaPage.js b/votrfront/js/PrehladStudiaPage.js
deleted file mode 100644
index 3473c11..0000000
--- a/votrfront/js/PrehladStudiaPage.js
+++ /dev/null
@@ -1,158 +0,0 @@
-
-import { CacheRequester, Loading } from './ajax';
-import { PageLayout, PageTitle } from './layout';
-import { sortAs, sortTable } from './sorting';
-
-
-// TODO: Pridat kadejake sumarne informacie, aby to vyzeralo ako dashboard.
-// TODO: Ked to raz bude rychle, pouzit to ako "home page" pri prazdnom action.
-// TODO: Zvyraznit aktualne obdobia a pisat kolko casu zostava do dalsich.
-
-
-export var PrehladStudiumColumns = [
- ["Študijný program", 'sp_popis'],
- ["Rok štúdia", 'rok_studia', sortAs.number],
- ["Dĺžka v semestroch", 'sp_dlzka', sortAs.number],
- ["Začiatok štúdia", 'zaciatok', sortAs.date],
- ["Koniec štúdia", 'koniec', sortAs.date],
- ["Doplňujúce údaje", 'sp_doplnujuce_udaje']
-];
-PrehladStudiumColumns.defaultOrder = 'd4';
-
-
-export var PrehladZapisnyListColumns = [
- ["Akademický rok", 'akademicky_rok'],
- ["Študijný program", 'sp_popis'],
- ["Ročník", 'rocnik', sortAs.number],
- ["Dátum zápisu", 'datum_zapisu', sortAs.date]
-];
-PrehladZapisnyListColumns.defaultOrder = 'd0d3';
-
-
-export var PrehladStudiaPage = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- renderObdobie(label, rpcName, arg) {
- var cache = new CacheRequester();
- var result = cache.get(rpcName, arg);
- return
- {label}
-
- {result ?
- result.obdobie_od + " \u2013 " + result.obdobie_do :
- }
-
- ;
- },
-
- renderObdobia() {
- // Obdobia predsalen neukazujeme, lebo AIS ma vacsinou zle informacie
- // (skuskove je umelo predlzene kvoli moznosti zapisovat znamky, apod) a
- // nechceme byt matuci. Zapnut sa daju tymto schovanym query flagom.
- if (!this.props.query.reallyShowDates) {
- return null;
- }
-
- return
-
- {this.renderObdobie("Zimný semester", 'get_semester_obdobie', 'Z')}
- {this.renderObdobie("Zimné skúškové", 'get_skuskove_obdobie', 'Z')}
- {this.renderObdobie("Letný semester", 'get_semester_obdobie', 'L')}
- {this.renderObdobie("Letné skúškové", 'get_skuskove_obdobie', 'L')}
-
-
;
- },
-
- renderStudia() {
- var cache = new CacheRequester();
-
- var studia = cache.get('get_studia');
-
- if (!studia) {
- return ;
- }
-
- var [studia, header] = sortTable(
- studia, PrehladStudiumColumns, this.props.query, 'studiaSort');
-
- var message = studia.length ? null : "V AISe nemáte žiadne štúdiá.";
-
- return
- {header}
-
- {studia.map((studium) =>
-
- {studium.sp_popis} ({studium.sp_skratka})
- {studium.rok_studia}
- {studium.sp_dlzka}
- {studium.zaciatok}
- {studium.koniec}
- {studium.sp_doplnujuce_udaje.replace(/^\((.*)\)$/, '$1')}
-
- )}
-
- {message && {message} }
-
;
- },
-
- renderZapisneListy() {
- var cache = new CacheRequester();
-
- var studia = cache.get('get_studia');
-
- if (!studia) {
- return ;
- }
-
- var zapisneListy = [];
-
- if (studia) studia.forEach((studium) => {
- var mojeZapisneListy = cache.get('get_zapisne_listy', studium.studium_key);
- if (mojeZapisneListy) mojeZapisneListy.forEach((zapisnyList) => {
- zapisneListy.push(zapisnyList);
- });
- });
-
- var [zapisneListy, header] = sortTable(
- zapisneListy, PrehladZapisnyListColumns,
- this.props.query, 'zapisneListySort');
-
- var showTable = zapisneListy.length || cache.loadedAll;
-
- var message = zapisneListy.length ? null : "V AISe nemáte žiadne zápisné listy.";
-
- return
- {!cache.loadedAll && }
- {showTable &&
-
- {header}
-
- {zapisneListy.map((zapisnyList) =>
-
- {zapisnyList.akademicky_rok}
- {zapisnyList.sp_popis} ({zapisnyList.sp_skratka})
- {zapisnyList.rocnik}
- {zapisnyList.datum_zapisu}
-
- )}
-
- {message && {message} }
-
}
- ;
- },
-
- render() {
- return
-
- {this.renderObdobia()}
- Zoznam štúdií
- {this.renderStudia()}
- Zoznam zápisných listov
- {this.renderZapisneListy()}
- ;
- }
-});
diff --git a/votrfront/js/PriebezneHodnoteniaPage.js b/votrfront/js/PriebezneHodnoteniaPage.js
deleted file mode 100644
index 5b66718..0000000
--- a/votrfront/js/PriebezneHodnoteniaPage.js
+++ /dev/null
@@ -1,83 +0,0 @@
-
-import { ZapisnyListSelector } from './ZapisnyListSelector';
-import { CacheRequester, Loading } from './ajax';
-import { PageLayout, PageTitle } from './layout';
-import { Link } from './router';
-import { humanizeBoolean } from './humanizeAISData';
-
-
-export var PriebezneHodnoteniaPageContent = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- renderContent() {
- var cache = new CacheRequester();
- var {zapisnyListKey} = this.props.query;
- var [priebezneHodnotenia, message] = cache.get('get_priebezne_hodnotenia', zapisnyListKey) || [];
-
- if (!priebezneHodnotenia) {
- return ;
- }
-
- if (!message && !priebezneHodnotenia.length) {
- message = "Tento zápisný list nemá žiadne priebežné hodnotenia.";
- }
-
- return (
-
- {priebezneHodnotenia.map((priebHod) =>
-
-
- {priebHod.nazov}
-
-
-
-
- Popis
- Body
- Zaevidoval
- Započítavať
- Minimum
-
-
-
- {priebHod.zaznamy.map((zaznam) =>
-
- {zaznam.dovod}
- {zaznam.poc_bodov} / {zaznam.maximum}
- {zaznam.zaevidoval}
- {humanizeBoolean(zaznam.zapocitavat)}
- {zaznam.minimum}
-
- )}
-
-
-
- )}
- {message &&
{message} }
-
- );
- },
-
- render() {
- return
-
- {this.renderContent()}
-
;
- }
-});
-
-export var PriebezneHodnoteniaPage = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- render() {
- return
-
- ;
- }
-});
diff --git a/votrfront/js/RegisterOsobPage.js b/votrfront/js/RegisterOsobPage.js
deleted file mode 100644
index 96fa87e..0000000
--- a/votrfront/js/RegisterOsobPage.js
+++ /dev/null
@@ -1,210 +0,0 @@
-
-import { CacheRequester, Loading } from './ajax';
-import { currentAcademicYear } from './coursesStats';
-import { FormItem, PageLayout, PageTitle } from './layout';
-import { navigate } from './router';
-import { sortAs, sortTable } from './sorting';
-
-
-export var RegisterOsobColumns = [
- ["Plné meno", 'plne_meno', sortAs.personName],
- ["E-mail", 'email']
-];
-RegisterOsobColumns.defaultOrder = 'a0';
-
-export var RegisterOsobForm = React.createClass({
- getInitialState() {
- var query = this.props.query;
- return {
- meno: query.meno,
- priezvisko: query.priezvisko,
- absolventi: query.absolventi,
- studenti: query.studenti,
- zamestnanci: query.zamestnanci,
- akademickyRok: query.akademickyRok || currentAcademicYear(),
- fakulta: query.fakulta,
- skratkaSp: query.skratkaSp,
- uchadzaciRocnik: query.uchadzaciRocnik,
- prvyRocnik: query.prvyRocnik,
- druhyRocnik: query.druhyRocnik,
- tretiRocnik: query.tretiRocnik,
- stvrtyRocnik: query.stvrtyRocnik,
- piatyRocnik: query.piatyRocnik,
- siestyRocnik: query.siestyRocnik,
- siedmyRocnik: query.siedmyRocnik,
- osmyRocnik: query.osmyRocnik,
- absolventiRocnik: query.absolventiRocnik
- };
- },
-
- handleFieldChange(event) {
- this.setState({ [event.target.name]: event.target.value });
- },
-
- handleCheckBoxChange(event) {
- this.setState({ [event.target.name]: String(event.target.checked) });
- },
-
- handleSubmit(event) {
- event.preventDefault();
- navigate({ action: 'registerOsob', ...this.state });
- },
-
- renderTextInput(label, name, focus) {
- return
-
- ;
- },
-
- renderSelect(label, name, items, cache) {
- return
- {items ?
-
- {items.map((item) =>
- {item.title}
- )}
- : }
- ;
- },
-
- renderCheckbox(label, name) {
- return
-
- {label}
- ;
- },
-
- render() {
- var cache = new CacheRequester();
- var akademickeRoky = cache.get('get_register_osob_akademicky_rok_options');
- var fakulty = cache.get('get_register_osob_fakulty');
-
- return ;
- },
-});
-
-export var RegisterOsobResultTable = React.createClass({
- render() {
- var cache = new CacheRequester();
- var query = this.props.query;
-
- if(!query.akademickyRok ||
- !(query.meno ||
- query.priezvisko ||
- query.absolventi == "true" ||
- query.studenti == "true" ||
- query.zamestnanci == "true" ||
- query.fakulta ||
- query.skratkaSp ||
- query.uchadzaciRocnik == "true" ||
- query.prvyRocnik == "true" ||
- query.druhyRocnik == "true" ||
- query.tretiRocnik == "true" ||
- query.stvrtyRocnik == "true" ||
- query.piatyRocnik == "true" ||
- query.siestyRocnik == "true" ||
- query.siedmyRocnik == "true" ||
- query.osmyRocnik == "true" ||
- query.absolventiRocnik == "true")) {
- return null;
- }
-
- var response = cache.get('vyhladaj_osobu',
- query.meno,
- query.priezvisko,
- query.absolventi == "true",
- query.studenti == "true",
- query.zamestnanci == "true",
- query.akademickyRok,
- query.fakulta,
- query.skratkaSp,
- query.uchadzaciRocnik == "true",
- query.prvyRocnik == "true",
- query.druhyRocnik == "true",
- query.tretiRocnik == "true",
- query.stvrtyRocnik == "true",
- query.piatyRocnik == "true",
- query.siestyRocnik == "true",
- query.siedmyRocnik == "true",
- query.osmyRocnik == "true",
- query.absolventiRocnik == "true");
-
- if (!response) {
- return ;
- }
-
- var [osoby, message] = response;
-
- var [osoby, header] = sortTable(
- osoby, RegisterOsobColumns, this.props.query, 'osobySort');
-
- if (!message && !osoby.length) {
- message = "Podmienkam nevyhovuje žiadny záznam.";
- }
-
- return
-
Výsledky
-
- {header}
-
- {osoby.map((osoba, index) =>
-
- {osoba.plne_meno}
- {osoba.email &&
- {osoba.email} }
-
-
- )}
-
- {message && {message} }
-
-
;
- }
-});
-
-
-export var RegisterOsobPage = React.createClass({
- render() {
- return
-
-
-
- ;
- }
-});
diff --git a/votrfront/js/RegisterPredmetovPage.js b/votrfront/js/RegisterPredmetovPage.js
deleted file mode 100644
index a8450c9..0000000
--- a/votrfront/js/RegisterPredmetovPage.js
+++ /dev/null
@@ -1,163 +0,0 @@
-
-import { CacheRequester, Loading } from './ajax';
-import { currentAcademicYear } from './coursesStats';
-import { classForSemester, humanizeBoolean } from './humanizeAISData';
-import { FormItem, PageLayout, PageTitle } from './layout';
-import { Link, navigate } from './router';
-import { sortAs, sortTable } from './sorting';
-
-
-export var RegisterPredmetovColumns = [
- ["Názov predmetu", 'nazov'],
- ["Skratka predmetu", 'skratka'],
- ["Fakulta", 'fakulta'],
- [Sem. , 'semester'],
- ["Rozsah výučby", 'rozsah_vyucby'],
- ["Počet kreditov", 'kredit', sortAs.number],
- ["Konanie", 'konanie']
-];
-RegisterPredmetovColumns.defaultOrder = 'a0';
-
-export var RegisterPredmetovForm = React.createClass({
- getInitialState() {
- var query = this.props.query;
- return {
- fakulta: query.fakulta,
- stredisko: query.stredisko,
- semester: query.semester,
- stupen: query.stupen,
- studijnyProgramSkratka: query.studijnyProgramSkratka,
- skratkaPredmetu: query.skratkaPredmetu,
- nazovPredmetu: query.nazovPredmetu,
- akademickyRok: query.akademickyRok || currentAcademicYear()
- };
- },
-
- handleFieldChange(event) {
- this.setState({ [event.target.name]: event.target.value });
- },
-
- handleSubmit(event) {
- event.preventDefault();
- navigate({ action: 'registerPredmetov', ...this.state });
- },
-
- renderTextInput(label, name, focus) {
- return
-
- ;
- },
-
- renderSelect(label, name, items, cache) {
- return
- {items ?
-
- {items.map((item) =>
- {item.title}
- )}
- : }
- ;
- },
-
- render() {
- var cache = new CacheRequester();
- var fakulty = cache.get('get_register_predmetov_fakulta_options');
- var rocniky = cache.get('get_register_predmetov_akademicky_rok_options');
- var stupne = cache.get('get_register_predmetov_stupen_options');
- var semestre = cache.get('get_register_predmetov_semester_options');
-
- return ;
- }
-});
-
-export var RegisterPredmetovResultTable = React.createClass({
- render() {
- var cache = new CacheRequester();
- var query = this.props.query;
- if(!query.fakulta &&
- !query.stredisko &&
- !query.studijnyProgramSkratka &&
- !query.skratkaPredmetu &&
- !query.nazovPredmetu &&
- !query.semester &&
- !query.stupen) {
- return null;
- }
-
- if (!query.akademickyRok) {
- return null;
- }
-
- var response = cache.get('vyhladaj_predmety',
- query.akademickyRok,
- query.fakulta || null,
- query.stredisko || null,
- query.studijnyProgramSkratka || null,
- query.skratkaPredmetu || null,
- query.nazovPredmetu || null,
- query.semester || null,
- query.stupen || null);
-
- if (!response) {
- return
- }
-
- var [rows, message] = response;
-
- var [rows, header] = sortTable(
- rows, RegisterPredmetovColumns, this.props.query, 'predmetSort');
-
- if (!message && !rows.length) {
- message = "Podmienkam nevyhovuje žiadny záznam.";
- }
-
- return
-
Výsledky
-
- {header}
-
- {rows.map((predmet) =>
-
-
- {predmet.nazov}
-
- {predmet.skratka}
- {predmet.fakulta}
- {predmet.semester}
- {predmet.rozsah_vyucby}
- {predmet.kredit}
- {humanizeBoolean(predmet.konanie)}
-
- )}
-
- {message && {message} }
-
-
;
- }
-});
-
-
-export var RegisterPredmetovPage = React.createClass({
- render() {
- return
-
-
-
- ;
- }
-});
diff --git a/votrfront/js/StudiumSelector.js b/votrfront/js/StudiumSelector.js
deleted file mode 100644
index 5a0bc63..0000000
--- a/votrfront/js/StudiumSelector.js
+++ /dev/null
@@ -1,68 +0,0 @@
-
-import { CacheRequester, Loading } from './ajax';
-import { Link } from './router';
-import { sortAs } from './sorting';
-
-
-// TODO: Reduce code duplication with ZapisnyListSelector.
-
-
-export var StudiumSelector = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired,
- component: React.PropTypes.func.isRequired
- },
-
- getItems(cache) {
- var studia = cache.get('get_studia');
-
- var items = studia || [];
-
- return _.sortBy(items, (item) => sortAs.date(item.zaciatok)).reverse();
- },
-
- renderSelector(cache, items, query) {
- return
- Štúdium:
- {items.map((studium) => {
- var key = studium.studium_key;
- var active = key == query.studiumKey;
- return
-
- {studium.sp_skratka}
-
- ;
- })}
- {cache.loadedAll ? null :
-
-
- }
- ;
- },
-
- renderPage(cache, items, query) {
- if (query.studiumKey) {
- return ;
- }
- if (cache.loadedAll && items.length == 0) {
- return Žiadne štúdiá.
;
- }
- return null;
- },
-
- render() {
- var cache = new CacheRequester();
- var items = this.getItems(cache);
- var query = this.props.query;
-
- if (!query.studiumKey && cache.loadedAll && items.length) {
- var mostRecentItem = items[0];
- query = { ...query, studiumKey: mostRecentItem.studium_key };
- }
-
- return
- {this.renderSelector(cache, items, query)}
- {this.renderPage(cache, items, query)}
-
;
- }
-});
diff --git a/votrfront/js/ZapisPage.js b/votrfront/js/ZapisPage.js
deleted file mode 100644
index 4b5b2a5..0000000
--- a/votrfront/js/ZapisPage.js
+++ /dev/null
@@ -1,577 +0,0 @@
-
-import { ZapisnyListSelector } from './ZapisnyListSelector';
-import { CacheRequester, Loading, RequestCache, sendRpc } from './ajax';
-import { coursesStats } from './coursesStats';
-import { humanizeTypVyucby, plural } from './humanizeAISData';
-import { FormItem, PageLayout, PageTitle } from './layout';
-import { Link, navigate } from './router';
-import { sortAs, sortTable } from './sorting';
-
-
-export var ZapisZPlanuColumns = [
- ["Moje?", 'moje', null, true],
- [Typ , 'typ_vyucby'],
- ["Blok", null, (predmet) => parseInt(predmet.blok_index || 0) * 1000 + parseInt(predmet.v_bloku_index || 0)],
- ["Názov predmetu", 'nazov'],
- ["Skratka predmetu", 'skratka'],
- [Sem. , 'semester', null, true],
- ["Rozsah výučby", 'rozsah_vyucby'],
- ["Kredit", 'kredit', sortAs.number],
- ["Prihlásení", 'pocet_prihlasenych', sortAs.number],
- [Odp. ročník , 'odporucany_rocnik'],
- ["Jazyk", 'jazyk']
-];
-ZapisZPlanuColumns.defaultOrder = 'a1a2a9a3';
-
-
-export var ZapisZPonukyColumns = [
- ["Moje?", 'moje', null, true],
- [Typ , 'typ_vyucby'],
- ["Blok", 'blok_skratka'],
- ["Názov predmetu", 'nazov'],
- ["Skratka predmetu", 'skratka'],
- [Sem. , 'semester', null, true],
- ["Rozsah výučby", 'rozsah_vyucby'],
- ["Kredit", 'kredit', sortAs.number],
- ["Prihlásení", 'pocet_prihlasenych', sortAs.number],
- ["Jazyk", 'jazyk']
-];
-ZapisZPonukyColumns.defaultOrder = 'a3';
-
-
-export var ZapisVlastnostiColumns = [
- ["Skratka", 'skratka'],
- ["Názov", 'nazov'],
- ["Minimálny kredit", 'minimalny_kredit'],
- ["Poznámka", 'poznamka']
-];
-
-
-export var ZapisMenu = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- renderLink(content, href, active) {
- return {content};
- },
-
- render() {
- var {action, cast, zapisnyListKey} = this.props.query;
- return
-
-
Zápis predmetov
-
-
- {this.renderLink("Môj študijný plán",
- { action: 'zapisZPlanu', cast: 'SC', zapisnyListKey },
- action == 'zapisZPlanu' && cast != 'SS')}
- {this.renderLink("Predmety štátnej skúšky",
- { action: 'zapisZPlanu', cast: 'SS', zapisnyListKey },
- action == 'zapisZPlanu' && cast == 'SS')}
- {this.renderLink("Hľadať ďalšie predmety",
- { action: 'zapisZPonuky', zapisnyListKey },
- action == 'zapisZPonuky')}
-
-
-
-
{this.props.children}
-
;
- }
-});
-
-
-export var ZapisTableFooter = React.createClass({
- propTypes: {
- predmety: React.PropTypes.object.isRequired,
- moje: React.PropTypes.object.isRequired
- },
-
- render() {
- var bloky = {}, nazvy = {}, semestre = {};
- _.forEach(this.props.predmety, (predmet) => {
- semestre[predmet.semestre] = true;
- nazvy[predmet.blok_skratka] = predmet.blok_nazov;
- });
-
- _.forEach(_.sortBy(_.keys(nazvy)), (skratka) => bloky[skratka] = []);
- bloky[''] = [];
-
- _.forEach(this.props.predmety, (predmet) => {
- if (!this.props.moje[predmet.predmet_key]) return;
- if (predmet.blok_skratka) bloky[predmet.blok_skratka].push(predmet);
- bloky[''].push(predmet);
- });
-
- var jedinySemester = _.keys(semestre).length <= 1;
-
- return
- {_.map(bloky, (blok, skratka) => {
- var stats = coursesStats(blok);
- return
- {skratka ? "Súčet bloku" : "Dokopy"}
- {nazvy[skratka] ? {skratka} : skratka}
-
- {stats.spolu.count} {plural(stats.spolu.count, "predmet", "predmety", "predmetov")}
- {!jedinySemester && " ("+stats.zima.count+" v zime, "+stats.leto.count+" v lete)"}
-
-
- {stats.spolu.creditsCount}
- {!jedinySemester && " ("+stats.zima.creditsCount+"+"+stats.leto.creditsCount+")"}
-
-
- ;
- })}
- ;
- }
-});
-
-
-export var ZapisTable = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired,
- predmety: React.PropTypes.object,
- akademickyRok: React.PropTypes.string,
- message: React.PropTypes.node,
- columns: React.PropTypes.array.isRequired,
- showFooter: React.PropTypes.bool,
- odoberPredmety: React.PropTypes.func.isRequired,
- pridajPredmety: React.PropTypes.func.isRequired
- },
-
- getInitialState() {
- return { odoberanePredmety: {}, pridavanePredmety: {} };
- },
-
- handleChange(event) {
- var predmetKey = event.target.name;
- var predmet = this.props.predmety[predmetKey];
-
- delete this.state.odoberanePredmety[predmetKey];
- delete this.state.pridavanePredmety[predmetKey];
- if (predmet.moje && !event.target.checked) this.state.odoberanePredmety[predmetKey] = true;
- if (!predmet.moje && event.target.checked) this.state.pridavanePredmety[predmetKey] = true;
-
- this.forceUpdate();
- },
-
- handleSave(event) {
- event.preventDefault();
-
- if (this.state.saving) return;
-
- var predmety = this.props.predmety;
-
- var odoberanePredmety = [], pridavanePredmety = [];
- for (var predmet_key in predmety) {
- if (this.state.odoberanePredmety[predmet_key] && predmety[predmet_key].moje) {
- odoberanePredmety.push(predmety[predmet_key]);
- }
- if (this.state.pridavanePredmety[predmet_key] && !predmety[predmet_key].moje) {
- pridavanePredmety.push(predmety[predmet_key]);
- }
- }
-
- this.setState({ saving: true });
-
- var koniec = (odobral, pridal) => {
- if (odobral) {
- odoberanePredmety.forEach((predmet) => {
- RequestCache['pocet_prihlasenych_je_stary' + predmet.predmet_key] = true;
- });
- this.setState({ odoberanePredmety: {} });
- }
-
- if (pridal) {
- pridavanePredmety.forEach((predmet) => {
- RequestCache['pocet_prihlasenych_je_stary' + predmet.predmet_key] = true;
- });
- this.setState({ pridavanePredmety: {} });
- }
-
- // Aj ked skoncime neuspechom, je mozne, ze niektore predmety sa zapisali.
- RequestCache.invalidate('get_hodnotenia');
- RequestCache.invalidate('get_predmety');
- RequestCache.invalidate('get_prehlad_kreditov');
- RequestCache.invalidate('get_studenti_zapisani_na_predmet');
- RequestCache.invalidate('zapis_get_zapisane_predmety');
- };
-
- this.props.odoberPredmety(odoberanePredmety, (message) => {
- if (message) {
- this.setState({ saving: false });
- alert(message);
- koniec(false, false);
- } else {
- this.props.pridajPredmety(pridavanePredmety, (message) => {
- this.setState({ saving: false });
- if (message) {
- alert(message);
- koniec(true, false);
- } else {
- koniec(true, true);
- }
- });
- }
- });
- },
-
- render() {
- // Chceme, aby sa pre ZapisTable zachoval this.state aj vtedy, ked tabulku
- // nevidno, lebo sme prave zapisali predmety a obnovujeme zoznam predmetov.
- // Takze komponent ZapisTable sa bude renderovat vzdy, aby nikdy nezanikol
- // a neprisiel o state. Niekedy proste nedostane this.props.predmety.
- if (!this.props.predmety || !this.props.akademickyRok) {
- return ;
- }
-
- var {predmety, columns, query, message} = this.props;
-
- var classes = {}, checked = {};
- for (var predmet_key in predmety) {
- checked[predmet_key] = predmety[predmet_key].moje;
- if (this.state.odoberanePredmety[predmet_key] && predmety[predmet_key].moje) {
- classes[predmet_key] = 'danger';
- checked[predmet_key] = false;
- }
- if (this.state.pridavanePredmety[predmet_key] && !predmety[predmet_key].moje) {
- classes[predmet_key] = 'success';
- checked[predmet_key] = true;
- }
- }
-
- var saveButton =
-
- {this.state.saving ? : "Uložiť zmeny"}
-
-
;
-
- var [predmety, header] = sortTable(_.values(predmety), columns, query, 'predmetySort');
-
- return ;
- }
-});
-
-
-export var ZapisVlastnostiTable = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- render() {
- var cache = new CacheRequester();
- var {zapisnyListKey} = this.props.query;
-
- var [vlastnosti, message] = cache.get('zapis_get_vlastnosti_programu', zapisnyListKey) || [];
-
- if (!vlastnosti) {
- return ;
- }
-
- if (!message && !vlastnosti.length) {
- message = "Študijný plán nemá žiadne poznámky.";
- }
-
- var [vlastnosti, header] = sortTable(
- vlastnosti, ZapisVlastnostiColumns, this.props.query, 'vlastnostiSort');
-
- return
- {header}
-
- {vlastnosti.map((vlastnost, index) =>
-
- {vlastnost.skratka}
- {vlastnost.nazov}
- {vlastnost.minimalny_kredit}
- {vlastnost.poznamka}
-
- )}
-
- {message && {message} }
-
;
- }
-});
-
-
-export var ZapisZPlanuPageContent = React.createClass({
- getQuery() {
- var {zapisnyListKey, cast} = this.props.query;
- cast = (cast == 'SS' ? 'SS' : 'SC');
- return {zapisnyListKey, cast};
- },
-
- render() {
- var cache = new CacheRequester();
- var {zapisnyListKey, cast} = this.getQuery();
-
- var [zapisanePredmety, zapisaneMessage] = cache.get('zapis_get_zapisane_predmety', zapisnyListKey, cast) || [];
- var [ponukanePredmety, ponukaneMessage] = cache.get('zapis_plan_vyhladaj', zapisnyListKey, cast) || [];
- var akademickyRok = cache.get('zapisny_list_key_to_akademicky_rok', zapisnyListKey);
-
- var outerMessage, tableMessage, predmety;
-
- if (zapisaneMessage || ponukaneMessage) {
- outerMessage = {zapisaneMessage || ponukaneMessage}
;
- } else if (!cache.loadedAll) {
- outerMessage = ;
- } else {
- var vidnoZimne = false;
-
- predmety = {};
- ponukanePredmety.forEach((predmet) => {
- predmety[predmet.predmet_key] = { moje: false, ...predmet };
- if (predmet.semester == 'Z') vidnoZimne = true;
- });
- zapisanePredmety.forEach((predmet) => {
- var predmet_key = predmet.predmet_key;
- if (!predmety[predmet_key]) {
- if (predmet.semester == 'Z' && !vidnoZimne) return;
- predmety[predmet_key] = { moje: true, ...predmet };
- } else {
- for (var property in predmet) {
- if (predmet[property] !== null && predmet[property] !== undefined) {
- predmety[predmet_key][property] = predmet[property];
- }
- }
- predmety[predmet_key].moje = true;
- }
- });
-
- if (_.isEmpty(predmety)) {
- tableMessage = "Zoznam ponúkaných predmetov je prázdny.";
- }
- }
-
- return
- {outerMessage}
-
- Poznámky k študijnému plánu
-
- ;
- },
-
- pridajPredmety(predmety, callback) {
- if (!predmety.length) return callback(null);
-
- var {zapisnyListKey, cast} = this.getQuery();
- var dvojice = predmety.map((predmet) => [predmet.typ_vyucby, predmet.skratka]);
- sendRpc('zapis_plan_pridaj_predmety', [zapisnyListKey, cast, dvojice], callback);
- },
-
- odoberPredmety(predmety, callback) {
- if (!predmety.length) return callback(null);
-
- var {zapisnyListKey, cast} = this.getQuery();
- var kluce = predmety.map((predmet) => predmet.predmet_key);
- sendRpc('zapis_odstran_predmety', [zapisnyListKey, cast, kluce], callback);
- }
-});
-
-
-export var ZapisZPlanuPage = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- render() {
- return
-
- ;
- }
-});
-
-
-export var ZapisZPonukyForm = React.createClass({
- getInitialState() {
- var query = this.props.query;
- return {
- fakulta: query.fakulta,
- stredisko: query.stredisko,
- skratkaPredmetu: query.skratkaPredmetu,
- nazovPredmetu: query.nazovPredmetu
- };
- },
-
- handleFieldChange(event) {
- this.setState({ [event.target.name]: event.target.value });
- },
-
- handleSubmit(event) {
- event.preventDefault();
- var {zapisnyListKey} = this.props.query;
- navigate({ action: 'zapisZPonuky', zapisnyListKey, ...this.state });
- },
-
- renderTextInput(label, name, focus) {
- return
-
- ;
- },
-
- renderSelect(label, name, items, cache) {
- return
- {items ?
-
- {items.map((item) =>
- {item.title}
- )}
- : }
- ;
- },
-
- render() {
- var cache = new CacheRequester();
- var [fakulty, message] = cache.get('zapis_ponuka_options', this.props.query.zapisnyListKey) || [];
-
- if (!fakulty) {
- return ;
- }
-
- if (message) {
- return {message}
;
- }
-
- return ;
- }
-});
-
-
-export var ZapisZPonukyPageContent = React.createClass({
- render() {
- var cache = new CacheRequester();
- var query = this.props.query;
-
- var outerMessage, tableMessage, predmety, akademickyRok;
-
- if (query.fakulta ||
- query.stredisko ||
- query.skratkaPredmetu ||
- query.nazovPredmetu) {
- var [zapisanePredmety, zapisaneMessage] = cache.get('zapis_get_zapisane_predmety', query.zapisnyListKey, 'SC') || [];
- var [ponukanePredmety, ponukaneMessage] = cache.get('zapis_ponuka_vyhladaj', query.zapisnyListKey,
- query.fakulta || null,
- query.stredisko || null,
- query.skratkaPredmetu || null,
- query.nazovPredmetu || null) || [];
- akademickyRok = cache.get('zapisny_list_key_to_akademicky_rok', query.zapisnyListKey);
-
- if (zapisaneMessage) {
- outerMessage = {zapisaneMessage}
;
- } else if (!cache.loadedAll) {
- outerMessage = ;
- } else {
- var predmety = {};
- ponukanePredmety.forEach((predmet) => {
- predmety[predmet.predmet_key] = { moje: false, ...predmet };
- });
- zapisanePredmety.forEach((predmet) => {
- if (predmety[predmet.predmet_key]) {
- predmety[predmet.predmet_key].moje = true;
- }
- });
-
- tableMessage = ponukaneMessage;
- if (_.isEmpty(predmety) && !tableMessage) {
- tableMessage = "Podmienkam nevyhovuje žiadny záznam.";
- }
- }
- }
-
- return
-
- {outerMessage}
- {predmety && Výsledky }
-
- ;
- },
-
- pridajPredmety(predmety, callback) {
- if (!predmety.length) return callback(null);
-
- var query = this.props.query;
- var skratky = predmety.map((predmet) => predmet.skratka);
- sendRpc('zapis_ponuka_pridaj_predmety', [query.zapisnyListKey,
- query.fakulta || null,
- query.stredisko || null,
- query.skratkaPredmetu || null,
- query.nazovPredmetu || null,
- skratky], callback);
- },
-
- odoberPredmety(predmety, callback) {
- if (!predmety.length) return callback(null);
-
- var query = this.props.query;
- var kluce = predmety.map((predmet) => predmet.predmet_key);
- sendRpc('zapis_odstran_predmety', [query.zapisnyListKey, 'SC', kluce], callback);
- }
-});
-
-
-export var ZapisZPonukyPage = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- render() {
- return
-
- ;
- }
-});
diff --git a/votrfront/js/ZapisnyListSelector.js b/votrfront/js/ZapisnyListSelector.js
deleted file mode 100644
index 1f9c050..0000000
--- a/votrfront/js/ZapisnyListSelector.js
+++ /dev/null
@@ -1,70 +0,0 @@
-
-import { CacheRequester, Loading } from './ajax';
-import { Link } from './router';
-import { sortAs } from './sorting';
-
-
-export var ZapisnyListSelector = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired,
- component: React.PropTypes.func.isRequired
- },
-
- getItems(cache) {
- var studia = cache.get('get_studia');
-
- var items = [];
-
- if (studia) studia.forEach((studium) => {
- var zapisneListy = cache.get('get_zapisne_listy', studium.studium_key);
- if (zapisneListy) items.push(...zapisneListy);
- });
-
- return _.sortBy(items, (item) => sortAs.date(item.datum_zapisu)).reverse();
- },
-
- renderSelector(cache, items, query) {
- return
- Zápisný list:
- {items.map((zapisnyList) => {
- var key = zapisnyList.zapisny_list_key;
- var active = key == query.zapisnyListKey;
- return
-
- {zapisnyList.akademicky_rok} {zapisnyList.sp_skratka}
-
- ;
- })}
- {cache.loadedAll ? null :
-
-
- }
- ;
- },
-
- renderPage(cache, items, query) {
- if (query.zapisnyListKey) {
- return ;
- }
- if (cache.loadedAll && items.length == 0) {
- return Žiadne zápisné listy.
;
- }
- return null;
- },
-
- render() {
- var cache = new CacheRequester();
- var items = this.getItems(cache);
- var query = this.props.query;
-
- if (!query.zapisnyListKey && cache.loadedAll && items.length) {
- var mostRecentItem = items[0];
- query = { ...query, zapisnyListKey: mostRecentItem.zapisny_list_key };
- }
-
- return
- {this.renderSelector(cache, items, query)}
- {this.renderPage(cache, items, query)}
-
;
- }
-});
diff --git a/votrfront/js/ZoznamPrihlasenychNaTermin.js b/votrfront/js/ZoznamPrihlasenychNaTermin.js
deleted file mode 100644
index 41449dc..0000000
--- a/votrfront/js/ZoznamPrihlasenychNaTermin.js
+++ /dev/null
@@ -1,62 +0,0 @@
-
-import { CacheRequester, Loading } from './ajax';
-import { Modal } from './layout';
-import { sortAs, sortTable } from './sorting';
-
-
-export var ZoznamPrihlasenychNaTerminColumns = [
- ["Meno", 'plne_meno', sortAs.personName],
- ["Študijný program", 'sp_skratka'],
- ["Ročník", 'rocnik', sortAs.number],
- ["E-mail", 'email'],
- ["Dátum prihlásenia", 'datum_prihlasenia', sortAs.date]
-];
-
-
-export var ZoznamPrihlasenychNaTerminModal = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- renderContent() {
- var cache = new CacheRequester();
- var {modalTerminKey} = this.props.query;
-
- if (!modalTerminKey) return null;
- var studenti = cache.get('get_prihlaseni_studenti', modalTerminKey);
-
- if (!studenti) {
- return ;
- }
-
- var [studenti, header] = sortTable(
- studenti, ZoznamPrihlasenychNaTerminColumns,
- this.props.query, 'modalStudentiSort');
-
- var message = studenti.length ? null : "Na termín nie sú prihlásení žiadni študenti.";
-
- return
- {header}
-
- {studenti.map((student, index) =>
-
- {student.plne_meno}
- {student.sp_skratka}
- {student.rocnik}
- {student.email &&
- {student.email} }
-
- {student.datum_prihlasenia}
-
- )}
-
- {message && {message} }
-
;
- },
-
- render() {
- return
- {this.renderContent()}
- ;
- }
-});
diff --git a/votrfront/js/actions.js b/votrfront/js/actions.js
deleted file mode 100644
index c2f5836..0000000
--- a/votrfront/js/actions.js
+++ /dev/null
@@ -1,75 +0,0 @@
-
-import { AboutModal, IndexPage } from './About';
-import { DetailPredmetuModal } from './DetailPredmetu';
-import { ErrorModal } from './ErrorPage';
-import { LogViewer } from './LogViewer';
-import { MojeHodnoteniaPage } from './MojeHodnoteniaPage';
-import { PriebezneHodnoteniaPage } from './PriebezneHodnoteniaPage';
-import { MojePredmetyPage } from './MojePredmetyPage';
-import { MojeSkuskyPage } from './MojeSkuskyPage';
-import { PrehladStudiaPage } from './PrehladStudiaPage';
-import { RegisterOsobPage } from './RegisterOsobPage';
-import { RegisterPredmetovPage } from './RegisterPredmetovPage';
-import { ZapisZPlanuPage, ZapisZPonukyPage } from './ZapisPage';
-import { ZoznamPrihlasenychNaTerminModal } from './ZoznamPrihlasenychNaTermin';
-import { ModalBase, PageLayout } from './layout';
-import { navigate } from './router';
-import { AnketaPopup } from './AnketaPopup';
-
-
-export var NotFoundPage = React.createClass({
- render() {
- return
- Action not found!
- ;
- }
-});
-
-
-export var actions = {
- index: IndexPage,
- priebezneHodnotenia: PriebezneHodnoteniaPage,
- mojeHodnotenia: MojeHodnoteniaPage,
- mojePredmety: MojePredmetyPage,
- mojeSkusky: MojeSkuskyPage,
- prehladStudia: PrehladStudiaPage,
- registerOsob: RegisterOsobPage,
- registerPredmetov: RegisterPredmetovPage,
- zapisZPlanu: ZapisZPlanuPage,
- zapisZPonuky: ZapisZPonukyPage
-};
-
-
-export var modalActions = {
- about: AboutModal,
- detailPredmetu: DetailPredmetuModal,
- zoznamPrihlasenychNaTermin: ZoznamPrihlasenychNaTerminModal
-};
-
-
-export var App = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- handleClose() {
- if (Votr.ajaxError) return;
- navigate(_.omit(
- this.props.query, (value, key) => key.substring(0, 5) == 'modal'));
- },
-
- render() {
- var query = this.props.query;
- var action = query.action || 'index';
- var mainComponent = actions[action] || NotFoundPage;
- var modalComponent = Votr.ajaxError ? ErrorModal : modalActions[query.modal];
-
- var C = mainComponent;
- return ;
- }
-});
diff --git a/votrfront/js/ajax.js b/votrfront/js/ajax.js
deleted file mode 100644
index c58062d..0000000
--- a/votrfront/js/ajax.js
+++ /dev/null
@@ -1,143 +0,0 @@
-
-export function sendRpc(name, args, callback) {
- var HEADER_LENGTH = 10;
- var processed = 0;
- var result = undefined;
- var finished = false;
-
- function update() {
- if (finished) return;
- while (true) {
- var waiting = xhr.responseText.length - processed;
- if (waiting < HEADER_LENGTH) break;
- var header = xhr.responseText.substr(processed, HEADER_LENGTH);
- var length = parseInt(header, HEADER_LENGTH);
- if (waiting < HEADER_LENGTH + length) break;
- var payload = xhr.responseText.substr(processed + HEADER_LENGTH, length);
- var data = JSON.parse(payload);
- console.log('RECEIVED', data);
- if (data.log !== undefined) logs.push(data);
- if (data.result !== undefined) result = data.result;
- if (data.error !== undefined) return fail(data.error);
- processed += HEADER_LENGTH + length;
- }
- if (xhr.readyState == 4) {
- if (processed != xhr.responseText.length || result === undefined) {
- console.log('INCOMPLETE!');
- return fail("Network error: Incomplete response");
- }
- finished = true;
- if (callback) {
- callback(result);
- }
- }
- Votr.appRoot.forceUpdate();
- }
-
- function fail(e) {
- if (finished) return;
- finished = true;
- console.log("FAILED!", e);
- if (!Votr.ajaxError) {
- Votr.ajaxError = _.isString(e) ? e : "Network error";
- Votr.appRoot.forceUpdate();
- }
- }
-
- var xhr = new XMLHttpRequest();
- xhr.onload = update;
- xhr.onprogress = update;
- xhr.onerror = fail;
- xhr.open("POST", "rpc?name=" + name, true);
- xhr.setRequestHeader("Content-Type", "application/json");
- xhr.setRequestHeader("X-CSRF-Token", Votr.settings.csrf_token);
- xhr.send(JSON.stringify(args));
-}
-
-
-Votr.ajaxError = null;
-
-
-export var logs = [];
-
-
-export var RequestCache = {};
-
-RequestCache.pending = {};
-
-RequestCache.sendRequest = function (request) {
- var cacheKey = request.join('\0');
- if (RequestCache[cacheKey]) return;
- if (RequestCache.pending[cacheKey]) return;
- RequestCache.pending[cacheKey] = true;
- sendRpc(request[0], request.slice(1), function (result) {
- RequestCache[cacheKey] = result;
- });
-};
-
-RequestCache.invalidate = function (command) {
- for (var key in RequestCache) {
- if (key.split('\0')[0] === command) {
- delete RequestCache[key];
- }
- }
-
- for (var key in RequestCache.pending) {
- if (key.split('\0')[0] === command) {
- delete RequestCache.pending[key];
- }
- }
-}
-
-
-export function CacheRequester() {
- this.missing = [];
- this.loadedAll = true;
-};
-
-CacheRequester.prototype.get = function (...request) {
- var cacheKey = request.join('\0');
- if (RequestCache[cacheKey] !== undefined) {
- return RequestCache[cacheKey];
- } else {
- this.missing.push(request);
- this.loadedAll = false;
- return null;
- }
-};
-
-
-export var Loading = React.createClass({
- componentDidMount() {
- if (this.props.requests) this.props.requests.forEach((request) => {
- RequestCache.sendRequest(request);
- });
- },
-
- componentDidUpdate() {
- if (this.props.requests) this.props.requests.forEach((request) => {
- RequestCache.sendRequest(request);
- });
- },
-
- render() {
- return Načítavam... ;
- }
-});
-
-
-export function goPost(url) {
- $('', { method: 'POST', action: url, appendTo: 'body' }).submit();
-};
-
-export function goLogout() {
- goPost('logout');
-};
-
-export function goReset() {
- goPost('reset?destination=' + encodeURIComponent(location.search));
-};
-
-export function goResetHome() {
- goPost('reset?destination=');
-};
diff --git a/votrfront/js/coursesStats.js b/votrfront/js/coursesStats.js
deleted file mode 100644
index 8796277..0000000
--- a/votrfront/js/coursesStats.js
+++ /dev/null
@@ -1,71 +0,0 @@
-
-var ZNAMKY = {'A': 1, 'B': 1.5, 'C': 2, 'D': 2.5, 'E': 3, 'F': 4};
-
-export function coursesStats(hodnotenia) {
- var result = {};
-
- result.zima = {};
- result.zima.count = 0;
- result.zima.creditsCount = 0;
-
- result.leto = {};
- result.leto.count = 0;
- result.leto.creditsCount = 0;
-
- result.spolu = {};
- result.spolu.count = hodnotenia.length;
- result.spolu.creditsCount = 0;
-
- hodnotenia.forEach((row) => {
- var credits = parseInt(row.kredit);
- if (row.hodn_znamka && row.hodn_znamka[0] === 'F') {
- credits = 0;
- }
- result.spolu.creditsCount += credits;
- if (row.semester == 'Z') {
- result.zima.count += 1;
- result.zima.creditsCount += credits;
- }
- if (row.semester == 'L') {
- result.leto.count += 1;
- result.leto.creditsCount += credits;
- }
- });
-
- return result;
-};
-
-export function weightedStudyAverage(hodnotenia) {
- var weightedSum = 0;
- var creditsSum = 0;
-
- hodnotenia.forEach((row) => {
- var value = ZNAMKY[row.hodn_znamka[0]];
- if (value) {
- weightedSum += value * parseInt(row.kredit);
- creditsSum += parseInt(row.kredit);
- }
- });
-
- if (creditsSum == 0) return null;
- return weightedSum / creditsSum;
-};
-
-export function renderWeightedStudyAverage(hodnotenia) {
- var average = weightedStudyAverage(hodnotenia);
- if (average === null) return null;
- return {average.toFixed(2)}
-};
-
-export function currentAcademicYear() {
- var date = new Date();
-
- var year = date.getFullYear();
- var month = date.getMonth() + 1;
-
- if (month < 8) {
- return (year - 1) + '/' + year;
- } else {
- return year + '/' + (year + 1);
- }
-};
diff --git a/votrfront/js/humanizeAISData.js b/votrfront/js/humanizeAISData.js
deleted file mode 100644
index 3af7002..0000000
--- a/votrfront/js/humanizeAISData.js
+++ /dev/null
@@ -1,40 +0,0 @@
-
-function humanizeWith(table) {
- return function (value) {
- return table[value] || value;
- }
-}
-
-export var humanizeTypVyucby = humanizeWith({
- 'A': 'povinné (A)',
- 'B': 'povinne voliteľné (B)',
- 'C': 'výberové (C)'
-});
-
-export var humanizeTerminHodnotenia = humanizeWith({
- 'R - Riadny termín': 'riadny',
- '1 - Prvý opravný termín': 'prvý opravný',
- '2 - Druhý opravný termín': 'druhý opravný'
-});
-
-export var humanizeNazovPriemeru = humanizeWith({
- 'Sem ?': 'Semester',
- 'AkadR ?' : 'Akademický rok'
-});
-
-export var humanizeBoolean = humanizeWith({
- 'A': 'áno',
- 'N': 'nie'
-});
-
-export function classForSemester(semester) {
- if (semester == 'Z') return 'zima';
- if (semester == 'L') return 'leto';
- return undefined;
-};
-
-export function plural(count, one, few, many) {
- if (count == 1) return one;
- if (count >= 2 && count <= 4) return few;
- return many;
-};
diff --git a/votrfront/js/layout.js b/votrfront/js/layout.js
deleted file mode 100644
index 96b58cf..0000000
--- a/votrfront/js/layout.js
+++ /dev/null
@@ -1,210 +0,0 @@
-
-import { CacheRequester, Loading, goLogout, goReset, logs } from './ajax';
-import { FakeLink, Link } from './router';
-
-
-export var PageLayout = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- render() {
- return
-
-
-
-
-
-
-
- {this.props.children}
-
-
-
-
;
- }
-});
-
-
-export var PageNavbar = React.createClass({
- render() {
- return
-
-
- Votr
-
-
-
-
-
-
- O aplikácii
- Obnoviť
- Odhlásiť
-
-
-
-
;
- }
-});
-
-
-export var LogStatus = React.createClass({
- render() {
- var entry = _.last(logs);
- var message;
- if (!entry) {
- message = "\xA0"; // nbsp
- } else if (entry.log == 'http' && entry.message.match(/^Requesting/)) {
- message = "Čakám na AIS...";
- } else if (entry.log == 'rpc' && entry.message.match(/finished$/)) {
- message = "\xA0"; // nbsp
- } else {
- message = "Spracovávam dáta... (" + entry.message + ")";
- }
- return {message}
;
- }
-});
-
-
-export var PageTitle = React.createClass({
- componentDidMount() {
- document.title = this.refs.title.textContent;
- },
-
- componentDidUpdate() {
- document.title = this.refs.title.textContent;
- },
-
- render() {
- return {this.props.children} ;
- }
-});
-
-
-export var MainMenu = React.createClass({
- propTypes: {
- query: React.PropTypes.object.isRequired
- },
-
- renderMenuItem(content, href, moreActions) {
- var isActive = href.action == this.props.query.action || (moreActions && moreActions[this.props.query.action]);
- return
- {content}
- ;
- },
-
- renderDisabled(content) {
- return {content} ;
- },
-
- render() {
- var {studiumKey, zapisnyListKey} = this.props.query;
-
- var cache = new CacheRequester();
- var somStudent = cache.get('get_som_student');
-
- return
- Moje štúdium
- {somStudent === false && Nie ste študentom. }
- {somStudent && this.renderMenuItem("Moje predmety", { action: 'mojePredmety', zapisnyListKey })}
- {somStudent && this.renderMenuItem("Moje skúšky", { action: 'mojeSkusky', zapisnyListKey })}
- {somStudent && this.renderMenuItem("Moje hodnotenia", { action: 'mojeHodnotenia', studiumKey })}
- {somStudent && this.renderMenuItem("Priebežné hodnotenia", { action: 'priebezneHodnotenia', zapisnyListKey })}
- {/*somStudent && this.renderDisabled("Môj rozvrh")*/}
- {somStudent && this.renderMenuItem("Zápis predmetov", { action: 'zapisZPlanu', zapisnyListKey }, { zapisZPonuky: true })}
- {somStudent && this.renderMenuItem("Prehľad štúdia", { action: 'prehladStudia' })}
- {!cache.loadedAll && }
-
- Registre
- {this.renderMenuItem("Register osôb", { action: 'registerOsob' })}
- {this.renderMenuItem("Register predmetov", { action: 'registerPredmetov' })}
- {/*this.renderDisabled("Register miestností")*/}
- {/*this.renderDisabled("Register študijných programov")*/}
- ;
- }
-});
-
-
-export var FormItem = React.createClass({
- render() {
- if (this.props.label) {
- return
- {this.props.label}
- {this.props.children}
- ;
- } else {
- return
-
{this.props.children}
-
;
- }
- }
-});
-
-
-export var ModalBase = React.createClass({
- propTypes: {
- component: React.PropTypes.func,
- onClose: React.PropTypes.func.isRequired,
- query: React.PropTypes.object.isRequired
- },
-
- componentDidMount() {
- var $node = $(this.refs.modal);
- $node.modal();
- $node.on('hide.bs.modal', (e) => {
- if ($node.attr('data-show') == 'true') {
- e.preventDefault();
- this.props.onClose();
- }
- });
- },
-
- componentDidUpdate() {
- var $node = $(this.refs.modal);
- $node.modal($node.attr('data-show') == 'true' ? 'show' : 'hide');
- },
-
- render() {
- var C = this.props.component;
-
- return ;
- }
-});
-
-
-export var Modal = React.createClass({
- propTypes: {
- closeButton: React.PropTypes.bool.isRequired,
- title: React.PropTypes.node.isRequired,
- footer: React.PropTypes.node
- },
-
- getDefaultProps() {
- return {
- closeButton: true
- };
- },
-
- render() {
- return
-
- {this.props.closeButton &&
-
- ×
- Close
- }
-
{this.props.title}
-
-
- {this.props.children}
-
- {this.props.footer}
-
;
- }
-});
diff --git a/votrfront/js/libs/modal.js b/votrfront/js/libs/modal.js
new file mode 100644
index 0000000..f84142d
--- /dev/null
+++ b/votrfront/js/libs/modal.js
@@ -0,0 +1,339 @@
+/* ========================================================================
+ * Bootstrap: modal.js v3.3.7
+ * http://getbootstrap.com/javascript/#modals
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // MODAL CLASS DEFINITION
+ // ======================
+
+ var Modal = function (element, options) {
+ this.options = options
+ this.$body = $(document.body)
+ this.$element = $(element)
+ this.$dialog = this.$element.find('.modal-dialog')
+ this.$backdrop = null
+ this.isShown = null
+ this.originalBodyPad = null
+ this.scrollbarWidth = 0
+ this.ignoreBackdropClick = false
+
+ if (this.options.remote) {
+ this.$element
+ .find('.modal-content')
+ .load(this.options.remote, $.proxy(function () {
+ this.$element.trigger('loaded.bs.modal')
+ }, this))
+ }
+ }
+
+ Modal.VERSION = '3.3.7'
+
+ Modal.TRANSITION_DURATION = 300
+ Modal.BACKDROP_TRANSITION_DURATION = 150
+
+ Modal.DEFAULTS = {
+ backdrop: true,
+ keyboard: true,
+ show: true
+ }
+
+ Modal.prototype.toggle = function (_relatedTarget) {
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
+ }
+
+ Modal.prototype.show = function (_relatedTarget) {
+ var that = this
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+
+ this.$element.trigger(e)
+
+ if (this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = true
+
+ this.checkScrollbar()
+ this.setScrollbar()
+ this.$body.addClass('modal-open')
+
+ this.escape()
+ this.resize()
+
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+
+ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
+ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
+ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
+ })
+ })
+
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(that.$body) // don't move modals dom position
+ }
+
+ that.$element
+ .show()
+ .scrollTop(0)
+
+ that.adjustDialog()
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element.addClass('in')
+
+ that.enforceFocus()
+
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+
+ transition ?
+ that.$dialog // wait for modal to slide in
+ .one('bsTransitionEnd', function () {
+ that.$element.trigger('focus').trigger(e)
+ })
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ that.$element.trigger('focus').trigger(e)
+ })
+ }
+
+ Modal.prototype.hide = function (e) {
+ if (e) e.preventDefault()
+
+ e = $.Event('hide.bs.modal')
+
+ this.$element.trigger(e)
+
+ if (!this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = false
+
+ this.escape()
+ this.resize()
+
+ $(document).off('focusin.bs.modal')
+
+ this.$element
+ .removeClass('in')
+ .off('click.dismiss.bs.modal')
+ .off('mouseup.dismiss.bs.modal')
+
+ this.$dialog.off('mousedown.dismiss.bs.modal')
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$element
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ this.hideModal()
+ }
+
+ Modal.prototype.enforceFocus = function () {
+ $(document)
+ .off('focusin.bs.modal') // guard against infinite focus loop
+ .on('focusin.bs.modal', $.proxy(function (e) {
+ if (document !== e.target &&
+ this.$element[0] !== e.target &&
+ !this.$element.has(e.target).length) {
+ this.$element.trigger('focus')
+ }
+ }, this))
+ }
+
+ Modal.prototype.escape = function () {
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
+ e.which == 27 && this.hide()
+ }, this))
+ } else if (!this.isShown) {
+ this.$element.off('keydown.dismiss.bs.modal')
+ }
+ }
+
+ Modal.prototype.resize = function () {
+ if (this.isShown) {
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
+ } else {
+ $(window).off('resize.bs.modal')
+ }
+ }
+
+ Modal.prototype.hideModal = function () {
+ var that = this
+ this.$element.hide()
+ this.backdrop(function () {
+ that.$body.removeClass('modal-open')
+ that.resetAdjustments()
+ that.resetScrollbar()
+ that.$element.trigger('hidden.bs.modal')
+ })
+ }
+
+ Modal.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ Modal.prototype.backdrop = function (callback) {
+ var that = this
+ var animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $(document.createElement('div'))
+ .addClass('modal-backdrop ' + animate)
+ .appendTo(this.$body)
+
+ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
+ if (this.ignoreBackdropClick) {
+ this.ignoreBackdropClick = false
+ return
+ }
+ if (e.target !== e.currentTarget) return
+ this.options.backdrop == 'static'
+ ? this.$element[0].focus()
+ : this.hide()
+ }, this))
+
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+ this.$backdrop.addClass('in')
+
+ if (!callback) return
+
+ doAnimate ?
+ this.$backdrop
+ .one('bsTransitionEnd', callback)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
+
+ var callbackRemove = function () {
+ that.removeBackdrop()
+ callback && callback()
+ }
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$backdrop
+ .one('bsTransitionEnd', callbackRemove)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callbackRemove()
+
+ } else if (callback) {
+ callback()
+ }
+ }
+
+ // these following methods are used to handle overflowing modals
+
+ Modal.prototype.handleUpdate = function () {
+ this.adjustDialog()
+ }
+
+ Modal.prototype.adjustDialog = function () {
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
+
+ this.$element.css({
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
+ })
+ }
+
+ Modal.prototype.resetAdjustments = function () {
+ this.$element.css({
+ paddingLeft: '',
+ paddingRight: ''
+ })
+ }
+
+ Modal.prototype.checkScrollbar = function () {
+ var fullWindowWidth = window.innerWidth
+ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
+ var documentElementRect = document.documentElement.getBoundingClientRect()
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
+ }
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
+ this.scrollbarWidth = this.measureScrollbar()
+ }
+
+ Modal.prototype.setScrollbar = function () {
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
+ this.originalBodyPad = document.body.style.paddingRight || ''
+ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
+ }
+
+ Modal.prototype.resetScrollbar = function () {
+ this.$body.css('padding-right', this.originalBodyPad)
+ }
+
+ Modal.prototype.measureScrollbar = function () { // thx walsh
+ var scrollDiv = document.createElement('div')
+ scrollDiv.className = 'modal-scrollbar-measure'
+ this.$body.append(scrollDiv)
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+ this.$body[0].removeChild(scrollDiv)
+ return scrollbarWidth
+ }
+
+
+ // MODAL PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option, _relatedTarget) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.modal')
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option](_relatedTarget)
+ else if (options.show) data.show(_relatedTarget)
+ })
+ }
+
+ var old = $.fn.modal
+
+ $.fn.modal = Plugin
+ $.fn.modal.Constructor = Modal
+
+
+ // MODAL NO CONFLICT
+ // =================
+
+ $.fn.modal.noConflict = function () {
+ $.fn.modal = old
+ return this
+ }
+
+
+ // MODAL DATA-API
+ // ==============
+
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this)
+ var href = $this.attr('href')
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
+
+ if ($this.is('a')) e.preventDefault()
+
+ $target.one('show.bs.modal', function (showEvent) {
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
+ $target.one('hidden.bs.modal', function () {
+ $this.is(':visible') && $this.trigger('focus')
+ })
+ })
+ Plugin.call($target, option, this)
+ })
+
+}(jQuery);
diff --git a/votrfront/js/libs/transition.js b/votrfront/js/libs/transition.js
new file mode 100644
index 0000000..db76596
--- /dev/null
+++ b/votrfront/js/libs/transition.js
@@ -0,0 +1,59 @@
+/* ========================================================================
+ * Bootstrap: transition.js v3.3.7
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+ // ============================================================
+
+ function transitionEnd() {
+ var el = document.createElement('bootstrap')
+
+ var transEndEventNames = {
+ WebkitTransition : 'webkitTransitionEnd',
+ MozTransition : 'transitionend',
+ OTransition : 'oTransitionEnd otransitionend',
+ transition : 'transitionend'
+ }
+
+ for (var name in transEndEventNames) {
+ if (el.style[name] !== undefined) {
+ return { end: transEndEventNames[name] }
+ }
+ }
+
+ return false // explicit for ie8 ( ._.)
+ }
+
+ // http://blog.alexmaccaw.com/css-transitions
+ $.fn.emulateTransitionEnd = function (duration) {
+ var called = false
+ var $el = this
+ $(this).one('bsTransitionEnd', function () { called = true })
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+ setTimeout(callback, duration)
+ return this
+ }
+
+ $(function () {
+ $.support.transition = transitionEnd()
+
+ if (!$.support.transition) return
+
+ $.event.special.bsTransitionEnd = {
+ bindType: $.support.transition.end,
+ delegateType: $.support.transition.end,
+ handle: function (e) {
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
+ }
+ }
+ })
+
+}(jQuery);
diff --git a/votrfront/js/main.js b/votrfront/js/main.js
index 773950c..c588d5b 100644
--- a/votrfront/js/main.js
+++ b/votrfront/js/main.js
@@ -1,35 +1,48 @@
-
-import { ErrorPage } from './ErrorPage';
-import { LoginPage } from './LoginPage';
-import { App } from './actions';
-import { Root } from './router';
-
-
-(function () {
-
-if (!history.pushState) {
- return; // see prologue.js
-}
-
-if (typeof __webpack_require__ !== 'undefined') {
- Votr.webpackRequire = __webpack_require__;
-}
-
-var query = Votr.settings.destination;
-if (query !== undefined && (query == '' || query.substring(0, 1) == '?')) {
- try {
- history.replaceState(null, '', Votr.settings.url_root + query);
- } catch (e) {
- console.error(e);
+import React from 'react';
+import ReactDOM from 'react-dom';
+import $ from 'jquery';
+
+// TODO Remove these imports when Modals are implemented
+// in our source with some package
+import './libs/modal';
+import './libs/transition';
+
+import { ErrorPage } from './src/ErrorPage';
+import { LoginPage } from './src/LoginPage';
+import { App } from './src/actions';
+import { Root } from './src/router';
+
+// FIXME These are here just for their side effects, needs to be
+// incorporated into source and deleted
+import './src/prologue';
+import './src/ovce';
+
+(function() {
+ window.$ = window.jQuery = $;
+ if (!history.pushState) {
+ // see prologue.js
+ return;
}
-}
-
-var root =
- Votr.settings.servers ? :
- Votr.settings.error ? :
- ;
-Votr.appRoot = ReactDOM.render(root, document.getElementById('votr'));
+ //if (typeof __webpack_require__ !== 'undefined') {
+ // Votr.webpackRequire = __webpack_require__;
+ //}
+
+ const query = Votr.settings.destination;
+ if (query !== undefined && (query === '' || query.substring(0, 1) === '?')) {
+ try {
+ history.replaceState(null, '', Votr.settings.url_root + query);
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ let root = ;
+ if (Votr.settings.servers) {
+ root = ;
+ } else if (Votr.settings.error) {
+ root = ;
+ }
+ Votr.appRoot = ReactDOM.render(root, document.getElementById('votr'));
})();
diff --git a/votrfront/js/package.json b/votrfront/js/package.json
new file mode 100644
index 0000000..c1834d9
--- /dev/null
+++ b/votrfront/js/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "votrfront",
+ "version": "1.0.0",
+ "description": "Frontend for Comenius University Votr app",
+ "main": "main.js",
+ "dependencies": {
+ "file-saver": "^1.3.3",
+ "jquery": "^1.12.4",
+ "lodash": "^4.17.5",
+ "prop-types": "^15.6.1",
+ "react": "^16.2.0",
+ "react-dom": "^16.2.0"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.0.0-beta.40",
+ "@babel/plugin-proposal-class-properties": "^7.0.0-beta.40",
+ "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.40",
+ "@babel/preset-env": "^7.0.0-beta.40",
+ "@babel/preset-react": "^7.0.0-beta.40",
+ "babel-eslint": "^8.2.2",
+ "babel-loader": "8.0.0-beta.2",
+ "babel-plugin-lodash": "^3.3.2",
+ "bootstrap-sass": "^3.3",
+ "clean-webpack-plugin": "^0.1.18",
+ "eslint": "^4.18.1",
+ "eslint-plugin-babel": "^4.1.2",
+ "eslint-plugin-import": "^2.9.0",
+ "eslint-plugin-react": "^7.7.0",
+ "lodash-webpack-plugin": "^0.11.4",
+ "webpack": "^4.0.1",
+ "webpack-bundle-analyzer": "^2.11.1",
+ "webpack-cli": "^2.0.9",
+ "webpack-merge": "^4.1.2"
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "eslint": "eslint main.js src/",
+ "dev": "webpack -w --config webpack.dev.js",
+ "build": "NODE_ENV=production webpack --config webpack.prod.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/fmfi-svt/votr.git"
+ },
+ "author": "",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/fmfi-svt/votr/issues"
+ },
+ "homepage": "https://github.com/fmfi-svt/votr#readme"
+}
diff --git a/votrfront/js/sorting.js b/votrfront/js/sorting.js
deleted file mode 100644
index b1ad311..0000000
--- a/votrfront/js/sorting.js
+++ /dev/null
@@ -1,93 +0,0 @@
-
-import { navigate } from './router';
-
-
-export var sortAs = {};
-
-
-sortAs.personName = function (text) {
- var words = text.replace(/,/g, '').split(' ');
- words = _.filter(words, (word) => !word.match(/\.$/));
- words.unshift(words.pop()); // last name goes to the beginning
- return words.join(' ').toLowerCase();
- // TODO: consider using latinise (see fajr).
-};
-
-
-sortAs.number = function (text) {
- return +text.replace(/,/g, '.');
- // TODO: this won't be needed when fladgejt starts returning numbers
-};
-
-
-sortAs.date = function (date) {
- if (date.match(/^\d\d\.\d\d\.\d\d\d\d/)) {
- return date.substring(6, 10) + date.substring(3, 5) + date.substring(0, 2) + date.substring(10);
- }
- return date;
-};
-
-
-sortAs.interval = function (text) {
- var index = text.indexOf('do ');
- if (index == -1) return '';
- return sortAs.date(text.substring(index + 3));
-};
-
-
-export function sortTable(items, columns, query, queryKey) {
- var orderString = query[queryKey] || columns.defaultOrder;
- var order = orderString ? orderString.split(/(?=[ad])/) : [];
- var orderLength = order.length;
- var orderAsc = order.map((orderItem) => orderItem.substring(0, 1) == 'a');
- var orderColumns = order.map((orderItem) => columns[orderItem.substring(1)]);
-
- items = items.map((item, index) => {
- var criteria = [];
- for (var i = 0; i < orderLength; i++) {
- var [label, prop, process, preferDesc] = orderColumns[i];
- var value = prop ? item[prop] : item;
- if (process) value = process(value);
- if (!prop && !process) value = undefined;
- criteria.push(value);
- }
- return { item, index, criteria };
- });
-
- items.sort((a, b) => {
- for (var i = 0; i < orderLength; i++) {
- var ac = a.criteria[i], bc = b.criteria[i];
- if (ac === bc) continue;
- if (ac < bc) return orderAsc[i] ? -1 : 1;
- if (ac > bc) return orderAsc[i] ? 1 : -1;
- }
- return a.index - b.index;
- });
-
- items = items.map((a) => a.item);
-
- function handleClick(event) {
- var index = event.currentTarget.getAttribute('data-index');
- var [label, prop, process, preferDesc] = columns[index];
-
- var newOrder = _.without(order, 'a' + index, 'd' + index);
- newOrder.unshift((
- order[0] == 'a' + index ? 'd' :
- order[0] == 'd' + index ? 'a' :
- preferDesc ? 'd' : 'a') + index);
-
- navigate({ ...query, [queryKey]: newOrder.join('') });
- }
-
- var header =
- {columns.map(([label, prop, process, preferDesc], index) =>
-
- {label}
-
- )}
- ;
-
- return [items, header];
-};
diff --git a/votrfront/js/src/About.js b/votrfront/js/src/About.js
new file mode 100644
index 0000000..ad3b6de
--- /dev/null
+++ b/votrfront/js/src/About.js
@@ -0,0 +1,103 @@
+import React, { Component } from 'react';
+import { Modal, PageLayout } from './layout';
+
+export class AboutModal extends Component {
+ render() {
+ const github = 'https://github.com/fmfi-svt/votr';
+ return (
+
+
+ Len málokto sa vyzná v AISe. Kým sa študent dostane k tomu, čo
+ potrebuje, musí sa prebiť cez hŕbu okien a menu. A ani pravidelné
+ činnosti, ako zapisovanie sa na skúšky, nie sú výnimkou. Preto sme
+ vytvorili aplikáciu Votr. Vybrali sme tie najdôležitejšie informácie z
+ AISu a sprístupnili sme ich na jeden klik.
+
+
+ Cez Votr si študenti môžu zapísať skúšky, pozrieť hodnotenia,
+ skontrolovať počet kreditov a podobne. Votr používa tie isté dáta, ako
+ AIS, ale podáva ich prehľadnejším spôsobom.
+
+ Pomoc a technická podpora
+
+ Ak vám Votr nefunguje alebo máte akékoľvek otázky, nápady či
+ pripomienky, napíšte nám na
+ fmfi-svt@googlegroups.com a radi vám pomôžeme. Alebo ak chcete,
+ môžete zavolať na
+ hotline CePIT .
+
+
+ Cez Votr sa nedá robiť všetko to, čo v AISe — sústredí sa na
+ zjednodušenie tých najčastejších činností. Ak hľadáte záverečné práce,
+ štátne skúšky a ďalšie menej časté veci, musíte ísť cez AIS.
+
+ Autori projektu
+
+ Votr je projektom Študentského vývojového tímu z Fakulty matematiky,
+ fyziky a informatiky UK. Naprogramovali ho Tomáš Belan, Dušan Plavák
+ a ďalší spoluautori . Vývoj prebieha
+ verejne na stránke {github} . Ak sa
+ vám Votr páči a chceli by ste sa zapojiť, napíšte nám!
+
+ Meno projektu
+
+ Čo znamená meno "Votr"? Je to fonetický prepis anglického slova "water".
+ V tejto slovnej hračke začal už predchodca Votru, ktorý sa volal "FAJR"
+ (pretože "fajr" a "ais" sú protiklady). Keď sme sa neskôr rozhodli
+ prebudovať FAJR na novom základe, nazvali sme ho "Votr", lebo má ku AISu
+ bližšie a vie s ním plynule narábať. Aj mená interných súčastí Votru
+ pokračujú v tejto téme.
+
+
+ );
+ }
+}
+export class IndexPage extends Component {
+ render() {
+ // TODO: Use PageTitle, but show different h1.
+ return (
+
+ Vitajte
+
+ Votr je alternatívne rozhranie pre systém AIS2. Cez menu sa dostanete
+ k týmto informáciám:
+
+
+
+ Moje predmety — predmety, ktoré máte zapísané
+ v tomto alebo minulom akademickom roku, a získané hodnotenia
+
+
+ Moje skúšky — termíny skúšok, na ktoré ste
+ prihlásení resp. na ktoré sa môžete prihlásiť
+
+
+ Moje hodnotenia — hodnotenia predmetov a
+ získané študijné priemery za celé štúdium
+
+
+ Priebežné hodnotenia — priebežné hodnotenia
+ predmetov počas semestra
+
+
+ Zápis predmetov — pridávanie a odoberanie
+ predmetov zo súčasného zápisného listu
+
+
+ Prehľad štúdia — zoznam vašich štúdií a
+ zápisných listov
+
+
+ Register osôb — vyhľadávanie zamestnancov,
+ študentov a absolventov univerzity, e-mailové kontakty
+
+
+ Register predmetov — vyhľadávanie predmetov,
+ informácie o ich učiteľoch a zoznamy zapísaných študentov
+
+
+
+ );
+ }
+}
diff --git a/votrfront/js/src/AnketaPopup.js b/votrfront/js/src/AnketaPopup.js
new file mode 100644
index 0000000..1561f9a
--- /dev/null
+++ b/votrfront/js/src/AnketaPopup.js
@@ -0,0 +1,99 @@
+import React, { Component } from 'react';
+import { CacheRequester, Loading } from './ajax';
+
+const dropCookie = true; // false disables the Cookie, allowing you to style the banner
+const cookieDurationClose = 3;
+const cookieDurationVote = 60;
+const cookieName = 'anketaKolacik'; // Name of our cookie
+const cookieValue = 'on'; // Value of cookie
+const cookieHideDate = Date.parse('19 February 2018'); // Starting this day the cookie won't be visible
+
+const createCookie = (name, value, days) => {
+ let expires = '';
+ if (days) {
+ const date = new Date();
+ date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
+ const expires = '; expires=' + date.toGMTString();
+ }
+ if (dropCookie) {
+ document.cookie = name + '=' + value + expires + '; path=/';
+ }
+};
+
+const checkCookie = (name) => {
+ const nameEQ = name + '=';
+ const ca = document.cookie.split(';');
+ for (let i = 0; i < ca.length; i++) {
+ let c = ca[i];
+ while (c.charAt(0) === ' ') {
+ c = c.substring(1, c.length);
+ }
+ if (c.indexOf(nameEQ) === 0) {
+ return c.substring(nameEQ.length, c.length);
+ };
+ }
+ return null;
+};
+
+const eraseCookie = (name) => {
+ createCookie(name, '', -1);
+};
+
+export class AnketaPopup extends Component {
+
+ componentWillMount() {
+ const today = new Date();
+ const showPopup = (checkCookie(cookieName) !== cookieValue) && (cookieHideDate > today);
+
+ this.setState({ showPopup });
+ }
+
+ onClosePopup(action) {
+ if (action === 0) {
+ createCookie(cookieName, cookieValue, cookieDurationVote); // Create vote cookie
+ } else {
+ createCookie(cookieName, cookieValue, cookieDurationClose); // Create close cookie
+ }
+ this.setState({ showPopup: false });
+ }
+
+ render() {
+ if (!this.state.showPopup) return null;
+
+ const cache = new CacheRequester();
+ const studia = cache.get('get_studia');
+ if (!studia) return
;
+ if (!studia.some((s) => s.organizacna_jednotka === 'FMFI')) return null;
+
+ return (
+
+
+
+
+
+ Daj semestru ešte chvíľu
+
+
+
+
+
+ );
+ }
+}
diff --git a/votrfront/js/src/DetailPredmetu.js b/votrfront/js/src/DetailPredmetu.js
new file mode 100644
index 0000000..f7b1416
--- /dev/null
+++ b/votrfront/js/src/DetailPredmetu.js
@@ -0,0 +1,158 @@
+import React, { Component } from 'react';
+
+import { ZoznamPrihlasenychNaTerminColumns } from './ZoznamPrihlasenychNaTermin';
+import { CacheRequester, Loading } from './ajax';
+import { Modal } from './layout';
+import { sortAs, sortTable } from './sorting';
+
+export const DetailPredmetuUciteliaColumns = [
+ ['Meno', 'plne_meno', sortAs.personName],
+ ['Typ', 'typ'],
+];
+DetailPredmetuUciteliaColumns.defaultOrder = 'a0';
+
+export const DetailPredmetuStudentiColumns = ZoznamPrihlasenychNaTerminColumns.slice();
+DetailPredmetuStudentiColumns.defaultOrder = 'a0';
+
+export class DetailPredmetuModal extends Component {
+ getZapisaniStudenti = (cache, predmetKey, akademickyRok) => {
+ return cache.get('get_studenti_zapisani_na_predmet', predmetKey, akademickyRok);
+ }
+
+ renderInformacnyListPredmetu = () => {
+ const cache = new CacheRequester();
+ const { modalAkademickyRok, modalPredmetKey } = this.props.query;
+ const data = cache.get('get_informacny_list', modalPredmetKey, modalAkademickyRok);
+
+ if (!data) {
+ return ;
+ }
+
+ const url = 'data:application/pdf;base64,' + escape(data);
+ return Stiahnuť ;
+ }
+
+ renderUcitelia = () => {
+ const cache = new CacheRequester();
+ const { modalAkademickyRok, modalPredmetKey } = this.props.query;
+ const data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok);
+
+ if (!data) {
+ return ;
+ }
+
+ let [studenti, predmet] = data;
+
+ if (!predmet) {
+ return 'Dáta pre predmet neboli nájdené.';
+ }
+
+ let ucitelia = cache.get(
+ 'get_ucitelia_predmetu',
+ modalPredmetKey,
+ modalAkademickyRok,
+ predmet.semester,
+ predmet.fakulta
+ );
+
+ if (!ucitelia) {
+ return ;
+ }
+
+ let header;
+ [ucitelia, header] = sortTable(
+ ucitelia, DetailPredmetuUciteliaColumns, this.props.query, 'modalUciteliaSort');
+
+ const message = ucitelia.length ? null : 'Predmet nemá v AISe žiadnych učiteľov.';
+
+ return (
+
+ {header}
+
+ {ucitelia.map((ucitel, index) => (
+
+ {ucitel.plne_meno}
+ {ucitel.typ}
+
+ ))}
+
+ {message && {message} }
+
+ );
+ }
+
+ renderZapisaniStudenti = () => {
+ const cache = new CacheRequester();
+ const { modalAkademickyRok, modalPredmetKey } = this.props.query;
+
+ const data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok);
+
+ if (!data) {
+ return ;
+ }
+
+ let [studenti, predmet] = data;
+
+ if (!predmet) {
+ return 'Dáta pre predmet neboli nájdené.';
+ }
+
+ let header;
+ [studenti, header] = sortTable(
+ studenti, DetailPredmetuStudentiColumns, this.props.query, 'modalStudentiSort');
+
+ const message = studenti.length ? null : 'Predmet nemá v AISe žiadnych zapísaných študentov.';
+
+ return (
+
+ {header}
+
+ {studenti.map((student, index) => (
+
+ {student.plne_meno}
+ {student.sp_skratka}
+ {student.rocnik}
+ {student.email &&
+ {student.email} }
+
+ {student.datum_prihlasenia}
+
+ ))}
+
+ {message && {message} }
+
+ );
+ }
+
+ renderTitle = () => {
+ const cache = new CacheRequester();
+ const { modalAkademickyRok, modalPredmetKey } = this.props.query;
+
+ const data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok);
+
+ if (!data) {
+ return ;
+ }
+
+ const [studenti, predmet] = data;
+
+ if (!predmet) {
+ return 'Dáta nenájdené';
+ }
+
+ return predmet.nazov;
+ }
+
+ render() {
+ return (
+
+ Informačný list predmetu
+ {this.renderInformacnyListPredmetu()}
+ Učitelia
+ {this.renderUcitelia()}
+ Zapísaní študenti
+ {this.renderZapisaniStudenti()}
+
+ );
+ }
+}
diff --git a/votrfront/js/src/ErrorPage.js b/votrfront/js/src/ErrorPage.js
new file mode 100644
index 0000000..64cebb0
--- /dev/null
+++ b/votrfront/js/src/ErrorPage.js
@@ -0,0 +1,122 @@
+import React, { Component } from 'react';
+
+import { goLogout, goReset, goResetHome } from './ajax';
+import { Modal, ModalBase } from './layout';
+import { AnalyticsMixin, FakeLink } from './router';
+
+export class ErrorModal extends Component {
+ componentWillMount() {
+ this.setState({ open: false });
+ }
+
+ handleIgnore = () => {
+ Votr.ajaxError = null;
+ Votr.appRoot.forceUpdate();
+ }
+
+ handleDetails = () => {
+ this.setState({ open: true });
+ }
+
+ render() {
+ const error = Votr.settings.error || Votr.ajaxError;
+ const lines = error.trim('\n').split('\n');
+ const lastLine = lines[lines.length - 1];
+ const type = lastLine.split(':')[0];
+
+ let title = 'Chyba';
+ let description = 'Vyskytla sa chyba a vaša požiadavka nebola spracovaná.';
+ let contact = true;
+
+ if (type === 'aisikl.exceptions.LoggedOutError') {
+ title = 'Prihlásenie vypršalo';
+ description = 'Vaše prihlásenie vypršalo. Skúste znova.';
+ contact = false;
+ } else if (Votr.settings.error || type.match(/^requests\.exceptions\./)) {
+ title = 'Chyba pripojenia';
+ description = 'Votr sa nevie pripojiť na AIS.';
+ contact = false;
+ } else {
+ if (type === 'aisikl.exceptions.AISParseError') {
+ description = 'Votr nerozumie, čo spravil AIS. V novej verzii AISu sa asi niečo zmenilo.';
+ }
+ if (type === 'aisikl.exceptions.AISBehaviorError') {
+ if (lastLine.match(/args=\['(Nie je connection|Nastala SQL chyba)/)) {
+ description = 'AIS sa nevie pripojiť na svoju databázu.';
+ contact = false;
+ } else {
+ description = 'AIS spravil niečo nečakané a Votr si s tým nevie poradiť.';
+ }
+ }
+ }
+
+ // Some errors are caused by a malformed URL, so resetting won't help. If
+ // we haven't navigated since the last full reload (the user has probably
+ // reset just now), we redirect to the front page instead.
+ const goHome = !Votr.didNavigate && !Votr.settings.error && location.search.substring(1);
+
+ return (
+
+ {description}
+ {contact &&
+
+ Ak problém pretrváva, napíšte nám na
+ fmfi-svt@googlegroups.com .
+
+ }
+
+
+ {goHome ? (
+
+
+ Späť na začiatok
+
+
+ ) : (
+
+
+ Skúsiť znova
+
+
+ )}
+
+
+ Odhlásiť
+
+
+
+
+ {this.state.open
+ ? {error}
+ : (
+
+ Technické detaily: {lastLine}
{' '}
+ Viac detailov...
+
+ )
+ }
+ {!Votr.settings.error && this.state.open && (
+
+ Ignorovať chybu
+
+ )}
+
+ );
+ }
+}
+
+export class ErrorPage extends Component {
+
+ render() {
+ // TODO: ModalBase should probably use transferPropsTo() instead of requiring query.
+ return (
+ undefined}
+ />
+ );
+ }
+}
+
+ErrorPage.mixins = [AnalyticsMixin];
diff --git a/votrfront/js/src/LocalSettings.js b/votrfront/js/src/LocalSettings.js
new file mode 100644
index 0000000..86ba99f
--- /dev/null
+++ b/votrfront/js/src/LocalSettings.js
@@ -0,0 +1,9 @@
+export const LocalSettings = {
+ get(key) {
+ return localStorage.getItem(Votr.settings.instance_name + '_' + key);
+ },
+ set(key, value) {
+ localStorage.setItem(Votr.settings.instance_name + '_' + key, value);
+ Votr.appRoot.forceUpdate();
+ },
+};
diff --git a/votrfront/js/src/LogViewer.js b/votrfront/js/src/LogViewer.js
new file mode 100644
index 0000000..f4328da
--- /dev/null
+++ b/votrfront/js/src/LogViewer.js
@@ -0,0 +1,116 @@
+import React, { Component } from 'react';
+import $ from 'jquery';
+import { LocalSettings } from './LocalSettings';
+import { logs } from './ajax';
+
+export class LogViewerContent extends Component {
+ componentWillMount() {
+ this.setState({
+ http: true,
+ table: true,
+ });
+ }
+
+ componentDidUpdate() {
+ const div = this.refs.scroll;
+ const time = logs[logs.length - 1].time;
+ if (time !== this.lastTime) {
+ this.lastTime = time;
+ div.scrollTop = div.scrollHeight;
+ }
+ }
+
+ handleChange = (e) => {
+ const update = {};
+ update[e.target.name] = !e.target.checked;
+ this.setState(update);
+ }
+
+ render() {
+ // count the type of logs
+ const types = logs.reduce(
+ (counts, { log }) => {
+ counts[log] = counts[log] ? counts[log] + 1 : 1;
+ return counts;
+ },
+ {}
+ );
+
+ return (
+
+
+
+
+
+
+ {logs.map((entry, index) => !this.state[entry.log] &&
+
+ {(entry.time - logs[0].time).toFixed(3)}
+ {entry.log}
+ {entry.message}
+
+ )}
+
+
+
+
+ );
+ }
+}
+
+export class LogViewer extends Component {
+ toggle = () => {
+ LocalSettings.set(
+ 'logViewer',
+ LocalSettings.get('logViewer') === 'true' ? 'false' : 'true'
+ );
+ }
+
+ handleKeypress = (e) => {
+ // Ctrl + Alt + Shift + L
+ if (e.ctrlKey && e.altKey && e.shiftKey && e.which === 76) {
+ this.toggle();
+ e.preventDefault();
+ }
+ }
+
+ componentDidMount() {
+ $(window).on('keypress.logViewer', this.handleKeypress);
+ }
+
+ componentWillUnmount() {
+ $(window).off('keypress.logViewer');
+ }
+
+ render() {
+ if (LocalSettings.get('logViewer') !== 'true') {
+ return null;
+ }
+
+ return (
+
+ );
+ }
+}
diff --git a/votrfront/js/src/LoginPage.js b/votrfront/js/src/LoginPage.js
new file mode 100644
index 0000000..eb6fa63
--- /dev/null
+++ b/votrfront/js/src/LoginPage.js
@@ -0,0 +1,209 @@
+import React, { Component } from 'react';
+
+import { AboutModal } from './About';
+import { Modal, ModalBase } from './layout';
+import { AnalyticsMixin, FakeLink } from './router';
+
+const TYPE_NAMES = {
+ cosignproxy: 'Cosign (automatické)',
+ cosignpassword: 'Cosign (meno a heslo)',
+ cosigncookie: 'Cosign (manuálne cookie)',
+ plainpassword: 'Meno a heslo',
+ demo: 'Demo',
+};
+
+export class LoginForm extends Component {
+ componentWillMount() {
+ this.setState({
+ server: Votr.settings.server || 0,
+ type: Votr.settings.type,
+ });
+ }
+
+ handleServerChange = (event) => {
+ const server = event.target.value;
+ const newTypes = Votr.settings.servers[server].login_types;
+ const type = newTypes.indexOf(this.state.type) > -1 ? this.state.type : null;
+ this.setState({ server, type });
+ }
+
+ handleTypeChange = (event) => {
+ this.setState({ type: event.target.value });
+ }
+
+ render() {
+ const serverConfig = Votr.settings.servers[this.state.server];
+ const currentType = this.state.type || serverConfig.login_types[0];
+ let error;
+ if (Votr.settings.error) {
+ const errors = Votr.settings.error.trim('\n').split('\n');
+ error = errors[errors.length - 1];
+ }
+ return (
+
+ );
+ }
+}
+
+export class LoginErrorModal extends Component {
+ render() {
+ return (
+
+ {Votr.settings.error}
+
+ );
+ }
+}
+
+export class LoginPage extends Component {
+
+ componentWillMount() {
+ this.setState({ modal: null });
+ }
+
+ openAbout = () => {
+ this.setState({ modal: 'about' });
+ }
+
+ openError = () => {
+ this.setState({ modal: 'error' });
+ }
+
+ closeModal = () => {
+ this.setState({ modal: null });
+ }
+
+ render() {
+ const content = (
+
+
+
+
+ Votr ponúka študentom jednoduchší a pohodlnejší
+ spôsob, ako robiť najčastejšie činnosti zo systému AIS. Zapíšte sa na
+ skúšky, prezrite si vaše hodnotenia a skontrolujte si počet kreditov
+ bez zbytočného klikania.
+
+
+
+
+
+
+ );
+
+ const modals = { about: AboutModal, error: LoginErrorModal };
+ const modalComponent = modals[this.state.modal];
+
+ return (
+
+ {content}
+
+
+ );
+ }
+}
+
+LoginPage.mixins = [AnalyticsMixin];
diff --git a/votrfront/js/src/MojeHodnoteniaPage.js b/votrfront/js/src/MojeHodnoteniaPage.js
new file mode 100644
index 0000000..6ad1c80
--- /dev/null
+++ b/votrfront/js/src/MojeHodnoteniaPage.js
@@ -0,0 +1,193 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { MojePredmetyColumns } from './MojePredmetyPage';
+import { StudiumSelector } from './StudiumSelector';
+import { CacheRequester, Loading } from './ajax';
+import { coursesStats, renderWeightedStudyAverage } from './coursesStats';
+import {
+ classForSemester, humanizeNazovPriemeru, humanizeTerminHodnotenia, humanizeTypVyucby,
+ plural,
+} from './humanizeAISData';
+import { PageLayout, PageTitle } from './layout';
+import { Link } from './router';
+import { sortAs, sortTable } from './sorting';
+
+
+export const MojeHodnoteniaColumns = [
+ [
+ 'Akademický rok',
+ 'akademicky_rok',
+ ],
+].concat(MojePredmetyColumns);
+MojeHodnoteniaColumns.defaultOrder = 'a0d1a2';
+
+
+export const MojePriemeryColumns = [
+ ['Dátum výpočtu priemeru', 'datum_vypoctu', sortAs.date],
+ ['Názov priemeru', 'nazov'],
+ ['Akademický rok', 'akademicky_rok'],
+ ['Semester', 'semester', null, true],
+ ['Získaný kredit', 'ziskany_kredit', sortAs.number],
+ ['Celkový počet predmetov', 'predmetov', sortAs.number],
+ ['Počet neabsolvovaných predmetov', 'neabsolvovanych', sortAs.number],
+ ['Študijný priemer', 'studijny_priemer', sortAs.number],
+ ['Vážený priemer', 'vazeny_priemer', sortAs.number],
+];
+MojePriemeryColumns.defaultOrder = 'a0a2a1';
+
+export class MojeHodnoteniaPageContent extends Component {
+
+ renderHodnotenia = () => {
+ const cache = new CacheRequester();
+ const { studiumKey } = this.props.query;
+ let [hodnotenia, message] = cache.get('get_prehlad_kreditov', studiumKey) || [];
+
+ if (!hodnotenia) {
+ return ;
+ }
+
+ let header;
+ [hodnotenia, header] = sortTable(
+ hodnotenia, MojeHodnoteniaColumns, this.props.query, 'predmetySort');
+
+ const stats = coursesStats(hodnotenia);
+
+ return (
+
+ {header}
+
+ {hodnotenia.map((hodnotenie) => (
+
+ {hodnotenie.akademicky_rok}
+ {hodnotenie.semester}
+
+
+ {hodnotenie.nazov}
+
+
+ {hodnotenie.skratka}
+ {hodnotenie.kredit}
+ {humanizeTypVyucby(hodnotenie.typ_vyucby)}
+
+ {hodnotenie.hodn_znamka}
+ {hodnotenie.hodn_znamka ? ' - ' : null}
+ {hodnotenie.hodn_znamka_popis}
+
+ {hodnotenie.hodn_datum}
+ {humanizeTerminHodnotenia(hodnotenie.hodn_termin)}
+
+ ))}
+
+
+
+
+ Celkom {stats.spolu.count} {plural(stats.spolu.count, 'predmet', 'predmety', 'predmetov')}
+
+ {stats.spolu.creditsCount}
+
+ {renderWeightedStudyAverage(hodnotenia)}
+
+
+
+ {message && {message} }
+
+
+ );
+ }
+
+ renderPriemery = () => {
+ const cache = new CacheRequester();
+ const { studiumKey } = this.props.query;
+
+ let priemery, message;
+ const zapisneListy = cache.get('get_zapisne_listy', studiumKey);
+
+ if (zapisneListy && zapisneListy.length === 0) {
+ priemery = [];
+ } else if (zapisneListy) {
+ // Find the newest list
+ let zapisnyList = zapisneListy[0];
+
+ zapisneListy.forEach((list) => {
+ if (sortAs.date(list.datum_zapisu) > sortAs.date(zapisnyList.datum_zapisu)) {
+ zapisnyList = list;
+ }
+ });
+ const zapisnyListKey = zapisnyList.zapisny_list_key;
+ [priemery, message] = cache.get('get_priemery', zapisnyListKey) || [];
+ }
+
+ if (!priemery) {
+ return ;
+ }
+
+ let header;
+ [priemery, header] = sortTable(
+ priemery, MojePriemeryColumns, this.props.query, 'priemerySort');
+
+ if (!message && !priemery.length) {
+ message = 'V AISe zatiaľ nie sú vypočítané žiadne priemery.';
+ }
+
+ return (
+
+ {header}
+
+ {priemery.map((priemer, index) => (
+
+ {priemer.datum_vypoctu}
+ {humanizeNazovPriemeru(priemer.nazov)}
+ {priemer.akademicky_rok}
+ {priemer.semester}
+ {priemer.ziskany_kredit}
+ {priemer.predmetov}
+ {priemer.neabsolvovanych}
+ {priemer.studijny_priemer}
+ {priemer.vazeny_priemer}
+
+ ))}
+
+ {message && {message} }
+
+ );
+ }
+
+ render() {
+ return (
+
+
+ {this.renderHodnotenia()}
+
Moje priemery
+ {this.renderPriemery()}
+
+ );
+ }
+}
+
+MojeHodnoteniaPageContent.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class MojeHodnoteniaPage extends Component {
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+MojeHodnoteniaPage.propTypes = {
+ query: PropTypes.object.isRequired,
+};
diff --git a/votrfront/js/src/MojePredmetyPage.js b/votrfront/js/src/MojePredmetyPage.js
new file mode 100644
index 0000000..8dc0a6b
--- /dev/null
+++ b/votrfront/js/src/MojePredmetyPage.js
@@ -0,0 +1,121 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { ZapisnyListSelector } from './ZapisnyListSelector';
+import { CacheRequester, Loading } from './ajax';
+import { coursesStats, renderWeightedStudyAverage } from './coursesStats';
+import { classForSemester, humanizeTerminHodnotenia, humanizeTypVyucby, plural } from './humanizeAISData';
+import { PageLayout, PageTitle } from './layout';
+import { Link } from './router';
+import { sortAs, sortTable } from './sorting';
+
+
+export const MojePredmetyColumns = [
+ [Sem. , 'semester', null, true],
+ ['Názov predmetu', 'nazov'],
+ ['Skratka predmetu', 'skratka'],
+ ['Kredit', 'kredit', sortAs.number],
+ ['Typ výučby', 'typ_vyucby'],
+ ['Hodnotenie', 'hodn_znamka'],
+ ['Dátum hodnotenia', 'hodn_datum', sortAs.date],
+ ['Termín hodnotenia', 'hodn_termin'],
+];
+MojePredmetyColumns.defaultOrder = 'd0a1';
+
+export class MojePredmetyPageContent extends Component {
+
+ renderContent = () => {
+ const cache = new CacheRequester();
+ const { zapisnyListKey } = this.props.query;
+ let [hodnotenia, message] = cache.get('get_hodnotenia', zapisnyListKey) || [];
+
+ if (!hodnotenia) {
+ return ;
+ }
+
+ let header;
+ [hodnotenia, header] = sortTable(
+ hodnotenia, MojePredmetyColumns, this.props.query, 'predmetySort');
+
+ const stats = coursesStats(hodnotenia);
+
+ return (
+
+ {header}
+
+ {hodnotenia.map((hodnotenie) => (
+
+ {hodnotenie.semester}
+
+
+ {hodnotenie.nazov}
+
+
+ {hodnotenie.skratka}
+ {hodnotenie.kredit}
+ {humanizeTypVyucby(hodnotenie.typ_vyucby)}
+
+ {hodnotenie.hodn_znamka}
+ {hodnotenie.hodn_znamka ? ' - ' : null}
+ {hodnotenie.hodn_znamka_popis}
+
+ {hodnotenie.hodn_datum}
+ {humanizeTerminHodnotenia(hodnotenie.hodn_termin)}
+
+ ))}
+
+
+
+
+ Celkom {stats.spolu.count} {plural(stats.spolu.count, 'predmet', 'predmety', 'predmetov')}
+ {' ('}{stats.zima.count} v zime, {stats.leto.count} v lete)
+
+ {stats.spolu.creditsCount} ({stats.zima.creditsCount}+{stats.leto.creditsCount})
+
+ {renderWeightedStudyAverage(hodnotenia)}
+
+
+
+ {message && {message} }
+
+
+ );
+ }
+
+ render() {
+ return (
+
+
+ {this.renderContent()}
+
+ );
+ }
+}
+
+MojePredmetyPageContent.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class MojePredmetyPage extends Component {
+
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+MojePredmetyPage.propTypes = {
+ query: PropTypes.object.isRequired,
+};
diff --git a/votrfront/js/src/MojeSkuskyPage.js b/votrfront/js/src/MojeSkuskyPage.js
new file mode 100644
index 0000000..7a491b1
--- /dev/null
+++ b/votrfront/js/src/MojeSkuskyPage.js
@@ -0,0 +1,306 @@
+import React, { Component } from 'react';
+import FileSaver from 'file-saver';
+import PropTypes from 'prop-types';
+
+import { ZapisnyListSelector } from './ZapisnyListSelector';
+import { CacheRequester, Loading, RequestCache, sendRpc } from './ajax';
+import { PageLayout, PageTitle } from './layout';
+import { Link } from './router';
+import { sortAs, sortTable } from './sorting';
+
+
+// TODO: Oddelit Aktualne terminy hodnotenia vs Stare terminy hodnotenia
+
+export const MojeSkuskyColumns = [
+ ['Moje?', null, (termin) => !termin.datum_prihlasenia || termin.datum_odhlasenia ? 'N' : 'A'],
+ ['Predmet', 'nazov_predmetu'],
+ ['Dátum', 'datum', sortAs.date],
+ ['Čas', 'cas'],
+ ['Miestnosť', 'miestnost'],
+ ['Hodnotiaci', 'hodnotiaci', sortAs.personName],
+ ['Prihlásení', 'pocet_prihlasenych', sortAs.number],
+ ['Poznámka', 'poznamka'],
+ ['Prihlasovanie', 'prihlasovanie', sortAs.interval],
+ ['Odhlasovanie', 'odhlasovanie', sortAs.interval],
+ ['Známka', null, (termin) => termin.hodnotenie_terminu || termin.hodnotenie_predmetu],
+];
+
+const convertToICAL = (terminy) => {
+ // standard: https://tools.ietf.org/html/rfc5545
+ // verificator: http://severinghaus.org/projects/icv/
+
+ // header
+ const lines = [
+ 'BEGIN:VCALENDAR',
+ 'VERSION:2.0',
+ 'PRODID:-//svt.fmph.uniba.sk//NONSGML votr-2017//EN',
+ 'X-WR-CALNAME:Moje skúšky',
+ 'X-WR-CALDESC:Kalendár skúšok vyexportovaný z aplikácie Votr',
+ 'X-WR-TIMEZONE:Europe/Bratislava',
+ ];
+
+ const dtstamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+/, '');
+
+ // VEVENTs
+ for (let termin of terminy) {
+ if (!termin.datum_prihlasenia || termin.datum_odhlasenia) {
+ // nie je prihlaseny
+ continue;
+ }
+ lines.push('BEGIN:VEVENT');
+
+ lines.push('SUMMARY:' + termin.nazov_predmetu);
+
+ // unique identificator for each event (so we can identify copies of the same event)
+ const uid = termin.termin_key + '@votr.uniba.sk';
+ lines.push('UID:' + uid);
+
+ // DTSTAMP is when this VEVENT was created (exported), must be YYYYMMDDTHHMMSSZ
+ lines.push('DTSTAMP:' + dtstamp);
+
+ // DTSTART, DTEND
+ const [den, mesiac, rok] = termin.datum.split('.');
+ const [hodina, minuty] = termin.cas.split(':');
+ const dtstart = `${rok}${mesiac}${den}T${hodina}${minuty}00`;
+
+ // as for there is no info about duration, we'll set it for 4 hours
+ let hodinaKoniec = (parseInt(hodina, 10) + 4).toString();
+ // add leading zero
+ if (hodinaKoniec.length === 1) {
+ hodinaKoniec = '0' + hodinaKoniec;
+ }
+ const dtend = `${rok}${mesiac}${den}T${hodinaKoniec}${minuty}00`;
+ lines.push('DTSTART;TZID=Europe/Bratislava:' + dtstart);
+ lines.push('DTEND;TZID=Europe/Bratislava:' + dtend);
+
+ // LOCATION
+ if (termin.miestnost) {
+ lines.push('LOCATION:' + termin.miestnost);
+ }
+
+ // DESCRIPTION
+ //@TODO ake vsetky informacie chceme zobrazovat v popise eventu? (zatial su take, ako vo FAJR)
+ const desc = 'Prihlasovanie: ' + termin.prihlasovanie + '\n' +
+ 'Odhlasovanie: ' + termin.odhlasovanie + '\n' +
+ 'Poznámka: ' + termin.poznamka;
+ lines.push('DESCRIPTION:' + desc);
+
+ lines.push('END:VEVENT');
+ }
+
+ // footer
+ lines.push('END:VCALENDAR');
+
+ return lines.map((l) => l.replace(/\n/g, '\\n')).join('\r\n');
+};
+
+export class MojeSkuskyPageContent extends Component {
+
+ renderContent = () => {
+ const cache = new CacheRequester();
+ const { zapisnyListKey } = this.props.query;
+
+ const vidim = cache.get('get_vidim_terminy_hodnotenia', zapisnyListKey);
+
+ if (!cache.loadedAll) {
+ return ;
+ }
+
+ if (!vidim) {
+ return Skúšky pre tento zápisný list už nie sú k dispozícii.
;
+ }
+
+ const terminyPrihlasene = cache.get('get_prihlasene_terminy', zapisnyListKey);
+ const terminyVypisane = cache.get('get_vypisane_terminy', zapisnyListKey);
+
+ if (!terminyPrihlasene || !terminyVypisane) {
+ return ;
+ }
+
+ let terminy = {};
+ terminyVypisane.forEach((termin) => {terminy[termin.termin_key] = termin;});
+ terminyPrihlasene.forEach((termin) => {terminy[termin.termin_key] = termin;});
+ terminy = Object.keys(terminy).map((key) => terminy[key]);
+
+ let header;
+ [terminy, header] = sortTable(
+ terminy, MojeSkuskyColumns, this.props.query, 'skuskySort');
+
+ const message = terminy.length ? null : 'Zatiaľ nie sú vypísané žiadne termíny.';
+
+ const handleClickICal = () => {
+ const icalText = convertToICAL(terminyPrihlasene);
+ const blob = new Blob([icalText], { type: 'text/calendar;charset=utf-8' });
+ FileSaver.saveAs(blob, 'MojeTerminy.ics', true);
+ };
+
+ return (
+
+
+ {header}
+
+ {terminy.map((termin) => (
+
+ {!termin.datum_prihlasenia || termin.datum_odhlasenia
+ ? {'\u2718'}
+ : {'\u2714'}
+ }
+
+
+ {termin.nazov_predmetu}
+
+
+ {termin.datum}
+ {termin.cas}
+ {termin.miestnost}
+ {termin.hodnotiaci}
+
+
+ {termin.pocet_prihlasenych +
+ (termin.maximalne_prihlasenych ? '/' + termin.maximalne_prihlasenych : '')
+ }
+
+
+ {termin.poznamka}
+ {termin.prihlasovanie}
+ {termin.odhlasovanie}
+
+ {termin.hodnotenie_terminu
+ ? termin.hodnotenie_terminu
+ : (
+ termin.hodnotenie_predmetu
+ ? termin.hodnotenie_predmetu + ' (nepriradená k termínu)'
+ : null
+ )
+ }
+
+
+
+ ))}
+
+ {message && {message} }
+
+ {terminy.length &&
Stiahnuť ako iCal }
+
+ );
+ }
+
+ render() {
+ return (
+
+
+ {this.renderContent()}
+
+ );
+ }
+}
+
+MojeSkuskyPageContent.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class SkuskyRegisterButton extends Component {
+
+ componentWillMount() {
+ this.setState({ pressed: false });
+ }
+
+ handleClick = () => {
+ const command = this.isSigninButton() ? 'prihlas_na_termin' : 'odhlas_z_terminu';
+ const termin = this.props.termin;
+
+ sendRpc(command, [termin.termin_key], (message) => {
+ if (message) {
+ this.setState({ pressed: false });
+ alert(message);
+ } else {
+ RequestCache.invalidate('get_prihlasene_terminy');
+ RequestCache.invalidate('get_vypisane_terminy');
+ RequestCache.invalidate('get_prihlaseni_studenti');
+ }
+ });
+
+ this.setState({ pressed: true });
+ }
+
+ isDisabled = () => {
+ const termin = this.props.termin;
+ return (this.isSigninButton() && termin.moznost_prihlasit !== 'A') || this.state.pressed;
+ }
+
+ isSigninButton = () => {
+ const termin = this.props.termin;
+ return !termin.datum_prihlasenia || termin.datum_odhlasenia;
+ }
+
+ render() {
+ const termin = this.props.termin;
+
+ if (termin.hodnotenie_terminu) {
+ return null;
+ }
+
+ const today = new Date()
+ .toJSON()
+ .replace(/-/g, '')
+ .substring(0, 8);
+
+ if (today > sortAs.date(termin.datum)) {
+ return null;
+ }
+
+ const buttonClass = 'btn btn-xs '
+ + (this.isSigninButton() ? 'btn-success' : 'btn-danger')
+ + (this.isDisabled() ? ' appear-disabled' : '');
+ const buttonText = this.state.pressed
+ ?
+ : (
+ this.isSigninButton()
+ ? 'Prihlásiť'
+ : 'Odhlásiť'
+ );
+
+ return (
+
+ {buttonText}
+
+ );
+ }
+}
+
+SkuskyRegisterButton.propTypes = {
+ termin: PropTypes.object.isRequired,
+};
+
+export class MojeSkuskyPage extends Component {
+
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+MojeSkuskyPage.propTypes = {
+ query: PropTypes.object.isRequired,
+};
diff --git a/votrfront/js/src/PrehladStudiaPage.js b/votrfront/js/src/PrehladStudiaPage.js
new file mode 100644
index 0000000..c317f67
--- /dev/null
+++ b/votrfront/js/src/PrehladStudiaPage.js
@@ -0,0 +1,173 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { CacheRequester, Loading } from './ajax';
+import { PageLayout, PageTitle } from './layout';
+import { sortAs, sortTable } from './sorting';
+
+// TODO: Pridat kadejake sumarne informacie, aby to vyzeralo ako dashboard.
+// TODO: Ked to raz bude rychle, pouzit to ako "home page" pri prazdnom action.
+// TODO: Zvyraznit aktualne obdobia a pisat kolko casu zostava do dalsich.
+
+export const PrehladStudiumColumns = [
+ ['Študijný program', 'sp_popis'],
+ ['Rok štúdia', 'rok_studia', sortAs.number],
+ ['Dĺžka v semestroch', 'sp_dlzka', sortAs.number],
+ ['Začiatok štúdia', 'zaciatok', sortAs.date],
+ ['Koniec štúdia', 'koniec', sortAs.date],
+ ['Doplňujúce údaje', 'sp_doplnujuce_udaje'],
+];
+PrehladStudiumColumns.defaultOrder = 'd4';
+
+
+export const PrehladZapisnyListColumns = [
+ ['Akademický rok', 'akademicky_rok'],
+ ['Študijný program', 'sp_popis'],
+ ['Ročník', 'rocnik', sortAs.number],
+ ['Dátum zápisu', 'datum_zapisu', sortAs.date],
+];
+PrehladZapisnyListColumns.defaultOrder = 'd0d3';
+
+export class PrehladStudiaPage extends Component {
+
+ renderObdobie = (label, rpcName, arg) => {
+ const cache = new CacheRequester();
+ const result = cache.get(rpcName, arg);
+
+ return (
+
+ {label}
+
+ {result
+ ? result.obdobie_od + ' \u2013 ' + result.obdobie_do
+ :
+ }
+
+
+ );
+ }
+
+ renderObdobia = () => {
+ // Obdobia predsalen neukazujeme, lebo AIS ma vacsinou zle informacie
+ // (skuskove je umelo predlzene kvoli moznosti zapisovat znamky, apod) a
+ // nechceme byt matuci. Zapnut sa daju tymto schovanym query flagom.
+ if (!this.props.query.reallyShowDates) {
+ return null;
+ }
+
+ return (
+
+
+ {this.renderObdobie('Zimný semester', 'get_semester_obdobie', 'Z')}
+ {this.renderObdobie('Zimné skúškové', 'get_skuskove_obdobie', 'Z')}
+ {this.renderObdobie('Letný semester', 'get_semester_obdobie', 'L')}
+ {this.renderObdobie('Letné skúškové', 'get_skuskove_obdobie', 'L')}
+
+
+ );
+ }
+
+ renderStudia() {
+ const cache = new CacheRequester();
+ let studia = cache.get('get_studia');
+
+ if (!studia) {
+ return ;
+ }
+
+ let header;
+ [studia, header] = sortTable(
+ studia, PrehladStudiumColumns, this.props.query, 'studiaSort');
+
+ const message = studia.length ? null : 'V AISe nemáte žiadne štúdiá.';
+
+ return (
+
+ {header}
+
+ {studia.map((studium) => (
+
+ {studium.sp_popis} ({studium.sp_skratka})
+ {studium.rok_studia}
+ {studium.sp_dlzka}
+ {studium.zaciatok}
+ {studium.koniec}
+ {studium.sp_doplnujuce_udaje.replace(/^\((.*)\)$/, '$1')}
+
+ ))}
+
+ {message && {message} }
+
+ );
+ }
+
+ renderZapisneListy() {
+ const cache = new CacheRequester();
+ let studia = cache.get('get_studia');
+
+ if (!studia) {
+ return ;
+ }
+
+ let zapisneListy = [];
+
+ if (studia) {
+ studia.forEach((studium) => {
+ const mojeZapisneListy = cache.get('get_zapisne_listy', studium.studium_key);
+ if (mojeZapisneListy) {
+ mojeZapisneListy.forEach((zapisnyList) => {
+ zapisneListy.push(zapisnyList);
+ });
+ }
+ });
+ }
+
+ let header;
+ [zapisneListy, header] = sortTable(
+ zapisneListy, PrehladZapisnyListColumns, this.props.query, 'zapisneListySort'
+ );
+
+ const showTable = zapisneListy.length || cache.loadedAll;
+ const message = zapisneListy.length ? null : 'V AISe nemáte žiadne zápisné listy.';
+
+ return (
+
+ {!cache.loadedAll && }
+ {showTable &&
+
+ {header}
+
+ {zapisneListy.map((zapisnyList) => (
+
+ {zapisnyList.akademicky_rok}
+ {zapisnyList.sp_popis} ({zapisnyList.sp_skratka})
+ {zapisnyList.rocnik}
+ {zapisnyList.datum_zapisu}
+
+ ))}
+
+ {message && {message} }
+
}
+
+ );
+ }
+
+ render() {
+ return (
+
+
+ {this.renderObdobia()}
+ Zoznam štúdií
+ {this.renderStudia()}
+ Zoznam zápisných listov
+ {this.renderZapisneListy()}
+
+ );
+ }
+}
+
+PrehladStudiaPage.propTypes = {
+ query: PropTypes.object.isRequired,
+};
diff --git a/votrfront/js/src/PriebezneHodnoteniaPage.js b/votrfront/js/src/PriebezneHodnoteniaPage.js
new file mode 100644
index 0000000..a53164e
--- /dev/null
+++ b/votrfront/js/src/PriebezneHodnoteniaPage.js
@@ -0,0 +1,99 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { ZapisnyListSelector } from './ZapisnyListSelector';
+import { CacheRequester, Loading } from './ajax';
+import { PageLayout, PageTitle } from './layout';
+import { Link } from './router';
+import { humanizeBoolean } from './humanizeAISData';
+
+export class PriebezneHodnoteniaPageContent extends Component {
+
+ renderContent = () => {
+ const cache = new CacheRequester();
+ const { zapisnyListKey } = this.props.query;
+ let [priebezneHodnotenia, message] = cache.get('get_priebezne_hodnotenia', zapisnyListKey) || [];
+
+ if (!priebezneHodnotenia) {
+ return ;
+ }
+
+ if (!message && !priebezneHodnotenia.length) {
+ message = 'Tento zápisný list nemá žiadne priebežné hodnotenia.';
+ }
+
+ return (
+
+ {priebezneHodnotenia.map((priebHod, key) => (
+
+
+
+ {priebHod.nazov}
+
+
+
+
+
+ Popis
+ Body
+ Zaevidoval
+ Započítavať
+ Minimum
+
+
+
+ {priebHod.zaznamy.map((zaznam, key) => (
+
+ {zaznam.dovod}
+ {zaznam.poc_bodov} / {zaznam.maximum}
+ {zaznam.zaevidoval}
+ {humanizeBoolean(zaznam.zapocitavat)}
+ {zaznam.minimum}
+
+ ))}
+
+
+
+ ))}
+ {message &&
{message} }
+
+ );
+ }
+
+ render() {
+ return (
+
+
+ {this.renderContent()}
+
+ );
+ }
+}
+
+PriebezneHodnoteniaPageContent.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class PriebezneHodnoteniaPage extends Component {
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+PriebezneHodnoteniaPage.propTypes = {
+ query: PropTypes.object.isRequired,
+};
diff --git a/votrfront/js/src/RegisterOsobPage.js b/votrfront/js/src/RegisterOsobPage.js
new file mode 100644
index 0000000..2e07a6b
--- /dev/null
+++ b/votrfront/js/src/RegisterOsobPage.js
@@ -0,0 +1,239 @@
+import React, { Component } from 'react';
+import { CacheRequester, Loading } from './ajax';
+import { currentAcademicYear } from './coursesStats';
+import { FormItem, PageLayout, PageTitle } from './layout';
+import { navigate } from './router';
+import { sortAs, sortTable } from './sorting';
+
+
+export const RegisterOsobColumns = [
+ ['Plné meno', 'plne_meno', sortAs.personName],
+ ['E-mail', 'email'],
+];
+RegisterOsobColumns.defaultOrder = 'a0';
+
+export class RegisterOsobForm extends Component {
+ componentWillMount() {
+ const query = this.props.query;
+
+ this.setState({
+ meno: query.meno,
+ priezvisko: query.priezvisko,
+ absolventi: query.absolventi,
+ studenti: query.studenti,
+ zamestnanci: query.zamestnanci,
+ akademickyRok: query.akademickyRok || currentAcademicYear(),
+ fakulta: query.fakulta,
+ skratkaSp: query.skratkaSp,
+ uchadzaciRocnik: query.uchadzaciRocnik,
+ prvyRocnik: query.prvyRocnik,
+ druhyRocnik: query.druhyRocnik,
+ tretiRocnik: query.tretiRocnik,
+ stvrtyRocnik: query.stvrtyRocnik,
+ piatyRocnik: query.piatyRocnik,
+ siestyRocnik: query.siestyRocnik,
+ siedmyRocnik: query.siedmyRocnik,
+ osmyRocnik: query.osmyRocnik,
+ absolventiRocnik: query.absolventiRocnik,
+ });
+ }
+
+ handleFieldChange = (event) => {
+ this.setState({ [event.target.name]: event.target.value });
+ }
+
+ handleCheckBoxChange = (event) => {
+ this.setState({ [event.target.name]: String(event.target.checked) });
+ }
+
+ handleSubmit = (event) => {
+ event.preventDefault();
+ navigate({ action: 'registerOsob', ...this.state });
+ }
+
+ renderTextInput = (label, name, focus) => {
+ return (
+
+
+
+ );
+ }
+
+ renderSelect = (label, name, items, cache) => {
+ return (
+
+ {items ?
+
+ {items.map((item) =>
+ {item.title}
+ )}
+ : }
+
+ );
+ }
+
+ renderCheckbox = (label, name) => {
+ return (
+
+
+ {label}
+
+ );
+ }
+
+ render() {
+ const cache = new CacheRequester();
+ const akademickeRoky = cache.get('get_register_osob_akademicky_rok_options');
+ const fakulty = cache.get('get_register_osob_fakulty');
+
+ return (
+
+ );
+ }
+}
+
+export class RegisterOsobResultTable extends Component {
+ render() {
+ const cache = new CacheRequester();
+ const query = this.props.query;
+
+ if (!query.akademickyRok ||
+ !(query.meno ||
+ query.priezvisko ||
+ query.absolventi === 'true' ||
+ query.studenti === 'true' ||
+ query.zamestnanci === 'true' ||
+ query.fakulta ||
+ query.skratkaSp ||
+ query.uchadzaciRocnik === 'true' ||
+ query.prvyRocnik === 'true' ||
+ query.druhyRocnik === 'true' ||
+ query.tretiRocnik === 'true' ||
+ query.stvrtyRocnik === 'true' ||
+ query.piatyRocnik === 'true' ||
+ query.siestyRocnik === 'true' ||
+ query.siedmyRocnik === 'true' ||
+ query.osmyRocnik === 'true' ||
+ query.absolventiRocnik === 'true')) {
+ return null;
+ }
+
+ const response = cache.get('vyhladaj_osobu',
+ query.meno,
+ query.priezvisko,
+ query.absolventi === 'true',
+ query.studenti === 'true',
+ query.zamestnanci === 'true',
+ query.akademickyRok,
+ query.fakulta,
+ query.skratkaSp,
+ query.uchadzaciRocnik === 'true',
+ query.prvyRocnik === 'true',
+ query.druhyRocnik === 'true',
+ query.tretiRocnik === 'true',
+ query.stvrtyRocnik === 'true',
+ query.piatyRocnik === 'true',
+ query.siestyRocnik === 'true',
+ query.siedmyRocnik === 'true',
+ query.osmyRocnik === 'true',
+ query.absolventiRocnik === 'true'
+ );
+
+ if (!response) {
+ return ;
+ }
+
+ let [osoby, message] = response;
+ let header;
+ [osoby, header] = sortTable(
+ osoby, RegisterOsobColumns, this.props.query, 'osobySort');
+
+ if (!message && !osoby.length) {
+ message = 'Podmienkam nevyhovuje žiadny záznam.';
+ }
+
+ return (
+
+
Výsledky
+
+ {header}
+
+ {osoby.map((osoba, index) => (
+
+ {osoba.plne_meno}
+ {osoba.email &&
+ {osoba.email} }
+
+
+ ))}
+
+ {message && {message} }
+
+
+ );
+ }
+}
+
+export class RegisterOsobPage extends Component {
+ render() {
+ return (
+
+
+
+
+
+ );
+ }
+}
diff --git a/votrfront/js/src/RegisterPredmetovPage.js b/votrfront/js/src/RegisterPredmetovPage.js
new file mode 100644
index 0000000..4885720
--- /dev/null
+++ b/votrfront/js/src/RegisterPredmetovPage.js
@@ -0,0 +1,194 @@
+import React, { Component } from 'react';
+
+import { CacheRequester, Loading } from './ajax';
+import { currentAcademicYear } from './coursesStats';
+import { classForSemester, humanizeBoolean } from './humanizeAISData';
+import { FormItem, PageLayout, PageTitle } from './layout';
+import { Link, navigate } from './router';
+import { sortAs, sortTable } from './sorting';
+
+
+export const RegisterPredmetovColumns = [
+ ['Názov predmetu', 'nazov'],
+ ['Skratka predmetu', 'skratka'],
+ ['Fakulta', 'fakulta'],
+ [Sem. , 'semester'],
+ ['Rozsah výučby', 'rozsah_vyucby'],
+ ['Počet kreditov', 'kredit', sortAs.number],
+ ['Konanie', 'konanie'],
+];
+RegisterPredmetovColumns.defaultOrder = 'a0';
+
+export class RegisterPredmetovForm extends Component {
+ componentWillMount() {
+ const query = this.props.query;
+
+ this.setState({
+ fakulta: query.fakulta,
+ stredisko: query.stredisko,
+ semester: query.semester,
+ stupen: query.stupen,
+ studijnyProgramSkratka: query.studijnyProgramSkratka,
+ skratkaPredmetu: query.skratkaPredmetu,
+ nazovPredmetu: query.nazovPredmetu,
+ akademickyRok: query.akademickyRok || currentAcademicYear(),
+ });
+ }
+
+ handleFieldChange = (event) => {
+ this.setState({ [event.target.name]: event.target.value });
+ }
+
+ handleSubmit = (event) => {
+ event.preventDefault();
+ navigate({ action: 'registerPredmetov', ...this.state });
+ }
+
+ renderTextInput = (label, name, focus) => {
+ return (
+
+
+
+ );
+ }
+
+ renderSelect(label, name, items, cache) {
+ return (
+
+ {items ?
+
+ {items.map((item) =>
+ {item.title}
+ )}
+ : }
+
+ );
+ }
+
+ render() {
+ const cache = new CacheRequester();
+ const fakulty = cache.get('get_register_predmetov_fakulta_options');
+ const rocniky = cache.get('get_register_predmetov_akademicky_rok_options');
+ const stupne = cache.get('get_register_predmetov_stupen_options');
+ const semestre = cache.get('get_register_predmetov_semester_options');
+
+ return (
+
+ );
+ }
+}
+
+export class RegisterPredmetovResultTable extends Component {
+ render() {
+ const cache = new CacheRequester();
+ const query = this.props.query;
+ if (!query.fakulta &&
+ !query.stredisko &&
+ !query.studijnyProgramSkratka &&
+ !query.skratkaPredmetu &&
+ !query.nazovPredmetu &&
+ !query.semester &&
+ !query.stupen) {
+ return null;
+ }
+
+ if (!query.akademickyRok) {
+ return null;
+ }
+
+ const response = cache.get('vyhladaj_predmety',
+ query.akademickyRok,
+ query.fakulta || null,
+ query.stredisko || null,
+ query.studijnyProgramSkratka || null,
+ query.skratkaPredmetu || null,
+ query.nazovPredmetu || null,
+ query.semester || null,
+ query.stupen || null);
+
+ if (!response) {
+ return ;
+ }
+
+ let [rows, message] = response;
+ let header;
+ [rows, header] = sortTable(
+ rows, RegisterPredmetovColumns, this.props.query, 'predmetSort');
+
+ if (!message && !rows.length) {
+ message = 'Podmienkam nevyhovuje žiadny záznam.';
+ }
+
+ return (
+
+
Výsledky
+
+ {header}
+
+ {rows.map((predmet) => (
+
+
+
+ {predmet.nazov}
+
+
+ {predmet.skratka}
+ {predmet.fakulta}
+ {predmet.semester}
+ {predmet.rozsah_vyucby}
+ {predmet.kredit}
+ {humanizeBoolean(predmet.konanie)}
+
+ ))}
+
+ {message && {message} }
+
+
+ );
+ }
+}
+
+export class RegisterPredmetovPage extends Component {
+ render() {
+ return (
+
+
+
+
+
+ );
+ }
+}
diff --git a/votrfront/js/src/StudiumSelector.js b/votrfront/js/src/StudiumSelector.js
new file mode 100644
index 0000000..f5ac71d
--- /dev/null
+++ b/votrfront/js/src/StudiumSelector.js
@@ -0,0 +1,91 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { CacheRequester, Loading } from './ajax';
+import { Link } from './router';
+import { sortAs } from './sorting';
+
+
+// TODO: Reduce code duplication with ZapisnyListSelector.
+
+export class StudiumSelector extends Component {
+
+ getItems = (cache) => {
+ const studia = cache.get('get_studia');
+ const items = studia ? [...studia] : [];
+
+ return items.sort((a, b) => {
+ const d1 = sortAs.date(a.zaciatok);
+ const d2 = sortAs.date(b.zaciatok);
+
+ if (d1 < d2) {
+ return -1;
+ } else if (d1 > d2) {
+ return 1;
+ }
+ return 0;
+ }).reverse();
+ }
+
+ renderSelector = (cache, items, query) => {
+ return (
+
+ Štúdium:
+ {items.map((studium) => {
+ const key = studium.studium_key;
+ const active = key === query.studiumKey;
+ return (
+
+
+ {studium.sp_skratka}
+
+
+ );
+ })}
+ {cache.loadedAll
+ ? null
+ : (
+
+
+
+
+
+ )
+ }
+
+ );
+ }
+
+ renderPage = (cache, items, query) => {
+ if (query.studiumKey) {
+ return ;
+ }
+ if (cache.loadedAll && items.length === 0) {
+ return Žiadne štúdiá.
;
+ }
+ return null;
+ }
+
+ render() {
+ const cache = new CacheRequester();
+ const items = this.getItems(cache);
+ let query = this.props.query;
+
+ if (!query.studiumKey && cache.loadedAll && items.length) {
+ const mostRecentItem = items[0];
+ query = { ...query, studiumKey: mostRecentItem.studium_key };
+ }
+
+ return (
+
+ {this.renderSelector(cache, items, query)}
+ {this.renderPage(cache, items, query)}
+
+ );
+ }
+}
+
+StudiumSelector.propTypes = {
+ query: PropTypes.object.isRequired,
+ component: PropTypes.func.isRequired,
+};
diff --git a/votrfront/js/src/ZapisPage.js b/votrfront/js/src/ZapisPage.js
new file mode 100644
index 0000000..e3a107a
--- /dev/null
+++ b/votrfront/js/src/ZapisPage.js
@@ -0,0 +1,742 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { ZapisnyListSelector } from './ZapisnyListSelector';
+import { CacheRequester, Loading, RequestCache, sendRpc } from './ajax';
+import { coursesStats } from './coursesStats';
+import { humanizeTypVyucby, plural } from './humanizeAISData';
+import { FormItem, PageLayout, PageTitle } from './layout';
+import { Link, navigate } from './router';
+import { sortAs, sortTable } from './sorting';
+
+
+export const ZapisZPlanuColumns = [
+ ['Moje?', 'moje', null, true],
+ [Typ , 'typ_vyucby'],
+ [
+ 'Blok',
+ null,
+ (predmet) => (
+ parseInt(predmet.blok_index || 0, 10) * 1000
+ + parseInt(predmet.v_bloku_index || 0, 10)
+ ),
+ ],
+ ['Názov predmetu', 'nazov'],
+ ['Skratka predmetu', 'skratka'],
+ [Sem. , 'semester', null, true],
+ ['Rozsah výučby', 'rozsah_vyucby'],
+ ['Kredit', 'kredit', sortAs.number],
+ ['Prihlásení', 'pocet_prihlasenych', sortAs.number],
+ [Odp. ročník , 'odporucany_rocnik'],
+ ['Jazyk', 'jazyk'],
+];
+ZapisZPlanuColumns.defaultOrder = 'a1a2a9a3';
+
+
+export const ZapisZPonukyColumns = [
+ ['Moje?', 'moje', null, true],
+ [Typ , 'typ_vyucby'],
+ ['Blok', 'blok_skratka'],
+ ['Názov predmetu', 'nazov'],
+ ['Skratka predmetu', 'skratka'],
+ [Sem. , 'semester', null, true],
+ ['Rozsah výučby', 'rozsah_vyucby'],
+ ['Kredit', 'kredit', sortAs.number],
+ ['Prihlásení', 'pocet_prihlasenych', sortAs.number],
+ ['Jazyk', 'jazyk'],
+];
+ZapisZPonukyColumns.defaultOrder = 'a3';
+
+export const ZapisVlastnostiColumns = [
+ ['Skratka', 'skratka'],
+ ['Názov', 'nazov'],
+ ['Minimálny kredit', 'minimalny_kredit'],
+ ['Poznámka', 'poznamka'],
+];
+
+export class ZapisMenu extends Component {
+
+ renderLink = (content, href, active) => {
+ return (
+
+ {content}
+
+ );
+ }
+
+ render() {
+ const { action, cast, zapisnyListKey } = this.props.query;
+ return (
+
+
+
Zápis predmetov
+
+
+ {this.renderLink('Môj študijný plán',
+ { action: 'zapisZPlanu', cast: 'SC', zapisnyListKey },
+ action === 'zapisZPlanu' && cast !== 'SS')}
+ {this.renderLink('Predmety štátnej skúšky',
+ { action: 'zapisZPlanu', cast: 'SS', zapisnyListKey },
+ action === 'zapisZPlanu' && cast === 'SS')}
+ {this.renderLink('Hľadať ďalšie predmety',
+ { action: 'zapisZPonuky', zapisnyListKey },
+ action === 'zapisZPonuky')}
+
+
+
+
{this.props.children}
+
+ );
+ }
+}
+
+ZapisMenu.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class ZapisTableFooter extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = this.parseBloky(props);
+ }
+
+ parseBloky = (props) => {
+ const bloky = {}, nazvy = {}, semestre = {};
+ bloky[''] = [];
+
+ Object
+ .keys(props.predmety)
+ .forEach((predmetKey) => {
+ const predmet = props.predmety[predmetKey];
+ semestre[predmet.semestre] = true;
+ nazvy[predmet.blok_skratka] = predmet.blok_nazov;
+ });
+
+ Object
+ .keys(nazvy)
+ .sort()
+ .forEach((skratka) => {bloky[skratka] = [];});
+
+ Object
+ .keys(props.predmety)
+ .forEach((predmetKey) => {
+ const predmet = props.predmety[predmetKey];
+ if (!props.moje[predmet.predmet_key]) {
+ return;
+ }
+ if (predmet.blok_skratka) {
+ bloky[predmet.blok_skratka].push(predmet);
+ };
+ bloky[''].push(predmet);
+ });
+
+ const jedinySemester = Object.keys(semestre).length <= 1;
+
+ return { bloky, nazvy, semestre, jedinySemester };
+ }
+
+ componentWillReceiveProps(nextProps) {
+ this.setState(this.parseBloky(nextProps));
+ }
+
+ renderBlok = ({ blok, skratka }) => {
+ const stats = coursesStats(blok);
+ const { nazvy, jedinySemester } = this.state;
+
+ return (
+
+ {skratka ? 'Súčet bloku' : 'Dokopy'}
+
+ {nazvy[skratka]
+ ? {skratka}
+ : skratka
+ }
+
+
+ {stats.spolu.count} {plural(stats.spolu.count, 'predmet', 'predmety', 'predmetov')}
+ {!jedinySemester && ` (${stats.zima.count} v zime, ${stats.leto.count}) v lete)`}
+
+
+ {stats.spolu.creditsCount}
+ {!jedinySemester && ` (${stats.zima.creditsCount}+${stats.leto.creditsCount})`}
+
+
+
+ );
+ }
+
+ render() {
+ return (
+
+ {Object
+ .keys(this.state.bloky)
+ .map((skratka) => ({ skratka, blok: this.state.bloky[skratka] }))
+ .map(this.renderBlok)
+ }
+
+ );
+ }
+}
+
+ZapisTableFooter.propTypes = {
+ predmety: PropTypes.object.isRequired,
+ moje: PropTypes.object.isRequired,
+};
+
+export class ZapisTable extends Component {
+
+ componentWillMount() {
+ this.setState({
+ odoberanePredmety: {},
+ pridavanePredmety: {},
+ });
+ }
+
+ handleChange = (event) => {
+ const predmetKey = event.target.name;
+ const predmet = this.props.predmety[predmetKey];
+
+ delete this.state.odoberanePredmety[predmetKey];
+ delete this.state.pridavanePredmety[predmetKey];
+ if (predmet.moje && !event.target.checked) {
+ this.state.odoberanePredmety[predmetKey] = true;
+ }
+ if (!predmet.moje && event.target.checked) {
+ this.state.pridavanePredmety[predmetKey] = true;
+ }
+
+ this.forceUpdate();
+ }
+
+ handleSave = (event) => {
+ event.preventDefault();
+
+ if (this.state.saving) {
+ return;
+ }
+
+ const predmety = this.props.predmety;
+
+ const odoberanePredmety = [], pridavanePredmety = [];
+
+ Object.keys(predmety).forEach((predmetKey) => {
+ if (this.state.odoberanePredmety[predmetKey] && predmety[predmetKey].moje) {
+ odoberanePredmety.push(predmety[predmetKey]);
+ }
+ if (this.state.pridavanePredmety[predmetKey] && !predmety[predmetKey].moje) {
+ pridavanePredmety.push(predmety[predmetKey]);
+ }
+ });
+
+ this.setState({ saving: true });
+
+ const koniec = (odobral, pridal) => {
+ if (odobral) {
+ odoberanePredmety.forEach((predmet) => {
+ RequestCache['pocet_prihlasenych_je_stary' + predmet.predmet_key] = true;
+ });
+ this.setState({ odoberanePredmety: {} });
+ }
+
+ if (pridal) {
+ pridavanePredmety.forEach((predmet) => {
+ RequestCache['pocet_prihlasenych_je_stary' + predmet.predmet_key] = true;
+ });
+ this.setState({ pridavanePredmety: {} });
+ }
+
+ // Aj ked skoncime neuspechom, je mozne, ze niektore predmety sa zapisali.
+ RequestCache.invalidate('get_hodnotenia');
+ RequestCache.invalidate('get_predmety');
+ RequestCache.invalidate('get_prehlad_kreditov');
+ RequestCache.invalidate('get_studenti_zapisani_na_predmet');
+ RequestCache.invalidate('zapis_get_zapisane_predmety');
+ };
+
+ this.props.odoberPredmety(odoberanePredmety, (message) => {
+ if (message) {
+ this.setState({ saving: false });
+ alert(message);
+ koniec(false, false);
+ } else {
+ this.props.pridajPredmety(pridavanePredmety, (message) => {
+ this.setState({ saving: false });
+ if (message) {
+ alert(message);
+ koniec(true, false);
+ } else {
+ koniec(true, true);
+ }
+ });
+ }
+ });
+ }
+
+ render() {
+ // Chceme, aby sa pre ZapisTable zachoval this.state aj vtedy, ked tabulku
+ // nevidno, lebo sme prave zapisali predmety a obnovujeme zoznam predmetov.
+ // Takze komponent ZapisTable sa bude renderovat vzdy, aby nikdy nezanikol
+ // a neprisiel o state. Niekedy proste nedostane this.props.predmety.
+ if (!this.props.predmety || !this.props.akademickyRok) {
+ return ;
+ }
+
+ const { columns, query, message } = this.props;
+ let { predmety } = this.props;
+
+ const classes = {}, checked = {};
+
+ Object.keys(predmety).forEach((predmetKey) => {
+ checked[predmetKey] = predmety[predmetKey].moje;
+ if (this.state.odoberanePredmety[predmetKey] && predmety[predmetKey].moje) {
+ classes[predmetKey] = 'danger';
+ checked[predmetKey] = false;
+ }
+ if (this.state.pridavanePredmety[predmetKey] && !predmety[predmetKey].moje) {
+ classes[predmetKey] = 'success';
+ checked[predmetKey] = true;
+ }
+ });
+
+ const saveButton = (
+
+
+ {this.state.saving ? : 'Uložiť zmeny'}
+
+
+ );
+
+ let header;
+ [predmety, header] = sortTable(
+ Object.keys(predmety).map((key) => predmety[key]),
+ columns,
+ query,
+ 'predmetySort'
+ );
+
+ return (
+
+ );
+ }
+}
+
+ZapisTable.propTypes = {
+ query: PropTypes.object.isRequired,
+ predmety: PropTypes.object,
+ akademickyRok: PropTypes.string,
+ message: PropTypes.node,
+ columns: PropTypes.array.isRequired,
+ showFooter: PropTypes.bool,
+ odoberPredmety: PropTypes.func.isRequired,
+ pridajPredmety: PropTypes.func.isRequired,
+};
+
+export class ZapisVlastnostiTable extends Component {
+
+ render() {
+ const cache = new CacheRequester();
+ const { zapisnyListKey } = this.props.query;
+
+ let [vlastnosti, message] = cache.get('zapis_get_vlastnosti_programu', zapisnyListKey) || [];
+
+ if (!vlastnosti) {
+ return ;
+ }
+
+ if (!message && !vlastnosti.length) {
+ message = 'Študijný plán nemá žiadne poznámky.';
+ }
+
+ let header;
+ [vlastnosti, header] = sortTable(
+ vlastnosti, ZapisVlastnostiColumns, this.props.query, 'vlastnostiSort');
+
+ return (
+
+ {header}
+
+ {vlastnosti.map((vlastnost, index) => (
+
+ {vlastnost.skratka}
+ {vlastnost.nazov}
+ {vlastnost.minimalny_kredit}
+ {vlastnost.poznamka}
+
+ ))}
+
+ {message && {message} }
+
+ );
+ }
+}
+
+ZapisVlastnostiTable.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class ZapisZPlanuPageContent extends Component {
+ getQuery = () => {
+ let { zapisnyListKey, cast } = this.props.query;
+ cast = (cast === 'SS' ? 'SS' : 'SC');
+ return { zapisnyListKey, cast };
+ }
+
+ render() {
+ const cache = new CacheRequester();
+ const { zapisnyListKey, cast } = this.getQuery();
+
+ const [zapisanePredmety, zapisaneMessage] = cache.get(
+ 'zapis_get_zapisane_predmety', zapisnyListKey, cast
+ ) || [];
+ const [ponukanePredmety, ponukaneMessage] = cache.get(
+ 'zapis_plan_vyhladaj', zapisnyListKey, cast
+ ) || [];
+ const akademickyRok = cache.get('zapisny_list_key_to_akademicky_rok', zapisnyListKey);
+
+ let outerMessage, tableMessage, predmety = {};
+
+ if (zapisaneMessage || ponukaneMessage) {
+ outerMessage = {zapisaneMessage || ponukaneMessage}
;
+ } else if (!cache.loadedAll) {
+ outerMessage = ;
+ } else {
+ let vidnoZimne = false;
+
+ ponukanePredmety.forEach((predmet) => {
+ predmety[predmet.predmet_key] = { moje: false, ...predmet };
+ if (predmet.semester === 'Z') {
+ vidnoZimne = true;
+ }
+ });
+ zapisanePredmety.forEach((predmet) => {
+ const predmetKey = predmet.predmet_key;
+ if (!predmety[predmetKey]) {
+ if (predmet.semester === 'Z' && !vidnoZimne) {
+ return;
+ }
+ predmety[predmetKey] = { moje: true, ...predmet };
+ } else {
+ for (let property in predmet) {
+ if (predmet[property] !== null && predmet[property] !== undefined) {
+ predmety[predmetKey][property] = predmet[property];
+ }
+ }
+ predmety[predmetKey].moje = true;
+ }
+ });
+
+ if (Object.keys(predmety).length === 0) {
+ tableMessage = 'Zoznam ponúkaných predmetov je prázdny.';
+ }
+ }
+
+ return (
+
+ {outerMessage}
+
+ Poznámky k študijnému plánu
+
+
+ );
+ }
+
+ pridajPredmety = (predmety, callback) => {
+ if (!predmety.length) {
+ return callback(null);
+ }
+
+ const { zapisnyListKey, cast } = this.getQuery();
+ const dvojice = predmety.map((predmet) => [predmet.typ_vyucby, predmet.skratka]);
+ sendRpc('zapis_plan_pridaj_predmety', [zapisnyListKey, cast, dvojice], callback);
+ }
+
+ odoberPredmety = (predmety, callback) => {
+ if (!predmety.length) {
+ return callback(null);
+ }
+
+ const { zapisnyListKey, cast } = this.getQuery();
+ const kluce = predmety.map((predmet) => predmet.predmet_key);
+ sendRpc('zapis_odstran_predmety', [zapisnyListKey, cast, kluce], callback);
+ }
+}
+
+export class ZapisZPlanuPage extends Component {
+
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+ZapisZPlanuPage.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class ZapisZPonukyForm extends Component {
+ componentWillMount() {
+ const query = this.props.query;
+
+ this.setState({
+ fakulta: query.fakulta,
+ stredisko: query.stredisko,
+ skratkaPredmetu: query.skratkaPredmetu,
+ nazovPredmetu: query.nazovPredmetu,
+ });
+ }
+
+ handleFieldChange = (event) => {
+ this.setState({ [event.target.name]: event.target.value });
+ }
+
+ handleSubmit = (event) => {
+ event.preventDefault();
+ const { zapisnyListKey } = this.props.query;
+ navigate({ action: 'zapisZPonuky', zapisnyListKey, ...this.state });
+ }
+
+ renderTextInput = (label, name, focus) => {
+ return (
+
+
+
+ );
+ }
+
+ renderSelect = (label, name, items, cache) => {
+ return (
+
+ {items ?
+
+ {items.map((item) =>
+ {item.title}
+ )}
+ : }
+
+ );
+ }
+
+ render() {
+ const cache = new CacheRequester();
+ const [fakulty, message] = cache.get('zapis_ponuka_options', this.props.query.zapisnyListKey) || [];
+
+ if (!fakulty) {
+ return ;
+ }
+
+ if (message) {
+ return {message}
;
+ }
+
+ return (
+
+ );
+ }
+}
+
+export class ZapisZPonukyPageContent extends Component {
+
+ render() {
+ const cache = new CacheRequester();
+ const query = this.props.query;
+
+ let outerMessage, tableMessage, predmety, akademickyRok;
+
+ if (query.fakulta ||
+ query.stredisko ||
+ query.skratkaPredmetu ||
+ query.nazovPredmetu) {
+ const [zapisanePredmety, zapisaneMessage] = cache.get(
+ 'zapis_get_zapisane_predmety', query.zapisnyListKey, 'SC'
+ ) || [];
+ const [ponukanePredmety, ponukaneMessage] = cache.get('zapis_ponuka_vyhladaj', query.zapisnyListKey,
+ query.fakulta || null,
+ query.stredisko || null,
+ query.skratkaPredmetu || null,
+ query.nazovPredmetu || null) || [];
+ akademickyRok = cache.get('zapisny_list_key_to_akademicky_rok', query.zapisnyListKey);
+
+ if (zapisaneMessage) {
+ outerMessage = {zapisaneMessage}
;
+ } else if (!cache.loadedAll) {
+ outerMessage = ;
+ } else {
+ predmety = {};
+ ponukanePredmety.forEach((predmet) => {
+ predmety[predmet.predmet_key] = { moje: false, ...predmet };
+ });
+ zapisanePredmety.forEach((predmet) => {
+ if (predmety[predmet.predmet_key]) {
+ predmety[predmet.predmet_key].moje = true;
+ }
+ });
+
+ tableMessage = ponukaneMessage;
+ if (Object.keys(predmety) === 0 && !tableMessage) {
+ tableMessage = 'Podmienkam nevyhovuje žiadny záznam.';
+ }
+ }
+ }
+
+ return (
+
+
+ {outerMessage}
+ {predmety && Výsledky }
+
+
+ );
+ }
+
+ pridajPredmety = (predmety, callback) => {
+ if (!predmety.length) {
+ return callback(null);
+ }
+
+ const query = this.props.query;
+ const skratky = predmety.map((predmet) => predmet.skratka);
+ sendRpc('zapis_ponuka_pridaj_predmety', [query.zapisnyListKey,
+ query.fakulta || null,
+ query.stredisko || null,
+ query.skratkaPredmetu || null,
+ query.nazovPredmetu || null,
+ skratky], callback);
+ }
+
+ odoberPredmety(predmety, callback) {
+ if (!predmety.length) {
+ return callback(null);
+ }
+
+ const query = this.props.query;
+ const kluce = predmety.map((predmet) => predmet.predmet_key);
+ sendRpc('zapis_odstran_predmety', [query.zapisnyListKey, 'SC', kluce], callback);
+ }
+}
+
+export class ZapisZPonukyPage extends Component {
+
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+ZapisZPonukyPage.propTypes = {
+ query: PropTypes.object.isRequired,
+};
diff --git a/votrfront/js/src/ZapisnyListSelector.js b/votrfront/js/src/ZapisnyListSelector.js
new file mode 100644
index 0000000..75cd3bb
--- /dev/null
+++ b/votrfront/js/src/ZapisnyListSelector.js
@@ -0,0 +1,95 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { CacheRequester, Loading } from './ajax';
+import { Link } from './router';
+import { sortAs } from './sorting';
+
+export class ZapisnyListSelector extends Component {
+ getItems = (cache) => {
+ const studia = cache.get('get_studia');
+ const items = [];
+
+ if (studia) {
+ studia.forEach((studium) => {
+ const zapisneListy = cache.get('get_zapisne_listy', studium.studium_key);
+ if (zapisneListy) {
+ items.push(...zapisneListy);
+ }
+ });
+ }
+
+ return items.sort((a, b) => {
+ const d1 = sortAs.date(a.datum_zapisu);
+ const d2 = sortAs.date(b.datum_zapisu);
+
+ if (d1 < d2) {
+ return -1;
+ } else if (d1 > d2) {
+ return 1;
+ }
+ return 0;
+ }).reverse();
+ }
+
+ renderSelector = (cache, items, query) => {
+ return (
+
+
+
+ Zápisný list:
+
+
+ {items.map((zapisnyList) => {
+ const key = zapisnyList.zapisny_list_key;
+ const active = key === query.zapisnyListKey;
+ return (
+
+
+ {zapisnyList.akademicky_rok} {zapisnyList.sp_skratka}
+
+
+ );
+ })}
+ {cache.loadedAll ? null : (
+
+
+
+ )}
+
+ );
+ }
+
+ renderPage = (cache, items, query) => {
+ if (query.zapisnyListKey) {
+ return ;
+ }
+ if (cache.loadedAll && items.length === 0) {
+ return Žiadne zápisné listy.
;
+ }
+ return null;
+ }
+
+ render() {
+ const cache = new CacheRequester();
+ const items = this.getItems(cache);
+ let query = this.props.query;
+
+ if (!query.zapisnyListKey && cache.loadedAll && items.length) {
+ const mostRecentItem = items[0];
+ query = { ...query, zapisnyListKey: mostRecentItem.zapisny_list_key };
+ }
+
+ return (
+
+ {this.renderSelector(cache, items, query)}
+ {this.renderPage(cache, items, query)}
+
+ );
+ }
+}
+
+ZapisnyListSelector.propTypes = {
+ query: PropTypes.object.isRequired,
+ component: PropTypes.func.isRequired,
+};
diff --git a/votrfront/js/src/ZoznamPrihlasenychNaTermin.js b/votrfront/js/src/ZoznamPrihlasenychNaTermin.js
new file mode 100644
index 0000000..3c0c177
--- /dev/null
+++ b/votrfront/js/src/ZoznamPrihlasenychNaTermin.js
@@ -0,0 +1,70 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { CacheRequester, Loading } from './ajax';
+import { Modal } from './layout';
+import { sortAs, sortTable } from './sorting';
+
+export const ZoznamPrihlasenychNaTerminColumns = [
+ ['Meno', 'plne_meno', sortAs.personName],
+ ['Študijný program', 'sp_skratka'],
+ ['Ročník', 'rocnik', sortAs.number],
+ ['E-mail', 'email'],
+ ['Dátum prihlásenia', 'datum_prihlasenia', sortAs.date],
+];
+
+export class ZoznamPrihlasenychNaTerminModal extends Component {
+
+ renderContent = () => {
+ const cache = new CacheRequester();
+ const { modalTerminKey } = this.props.query;
+
+ if (!modalTerminKey) {
+ return null;
+ }
+ let studenti = cache.get('get_prihlaseni_studenti', modalTerminKey);
+
+ if (!studenti) {
+ return ;
+ }
+
+ let header;
+ [studenti, header] = sortTable(
+ studenti, ZoznamPrihlasenychNaTerminColumns,
+ this.props.query, 'modalStudentiSort');
+
+ const message = studenti.length ? null : 'Na termín nie sú prihlásení žiadni študenti.';
+
+ return (
+
+ {header}
+
+ {studenti.map((student, index) => (
+
+ {student.plne_meno}
+ {student.sp_skratka}
+ {student.rocnik}
+ {student.email &&
+ {student.email} }
+
+ {student.datum_prihlasenia}
+
+ ))}
+
+ {message && {message} }
+
+ );
+ }
+
+ render() {
+ return (
+
+ {this.renderContent()}
+
+ );
+ }
+}
+
+ZoznamPrihlasenychNaTerminModal.propTypes = {
+ query: PropTypes.object.isRequired,
+};
diff --git a/votrfront/js/src/actions.js b/votrfront/js/src/actions.js
new file mode 100644
index 0000000..012a7a2
--- /dev/null
+++ b/votrfront/js/src/actions.js
@@ -0,0 +1,94 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { AboutModal, IndexPage } from './About';
+import { DetailPredmetuModal } from './DetailPredmetu';
+import { ErrorModal } from './ErrorPage';
+import { LogViewer } from './LogViewer';
+import { MojeHodnoteniaPage } from './MojeHodnoteniaPage';
+import { PriebezneHodnoteniaPage } from './PriebezneHodnoteniaPage';
+import { MojePredmetyPage } from './MojePredmetyPage';
+import { MojeSkuskyPage } from './MojeSkuskyPage';
+import { PrehladStudiaPage } from './PrehladStudiaPage';
+import { RegisterOsobPage } from './RegisterOsobPage';
+import { RegisterPredmetovPage } from './RegisterPredmetovPage';
+import { ZapisZPlanuPage, ZapisZPonukyPage } from './ZapisPage';
+import { ZoznamPrihlasenychNaTerminModal } from './ZoznamPrihlasenychNaTermin';
+import { ModalBase, PageLayout } from './layout';
+import { navigate } from './router';
+import { AnketaPopup } from './AnketaPopup';
+
+export class NotFoundPage extends Component {
+ render() {
+ return (
+
+ Action not found!
+
+ );
+ }
+}
+
+export const actions = {
+ index: IndexPage,
+ priebezneHodnotenia: PriebezneHodnoteniaPage,
+ mojeHodnotenia: MojeHodnoteniaPage,
+ mojePredmety: MojePredmetyPage,
+ mojeSkusky: MojeSkuskyPage,
+ prehladStudia: PrehladStudiaPage,
+ registerOsob: RegisterOsobPage,
+ registerPredmetov: RegisterPredmetovPage,
+ zapisZPlanu: ZapisZPlanuPage,
+ zapisZPonuky: ZapisZPonukyPage,
+};
+
+export const modalActions = {
+ about: AboutModal,
+ detailPredmetu: DetailPredmetuModal,
+ zoznamPrihlasenychNaTermin: ZoznamPrihlasenychNaTerminModal,
+};
+
+export class App extends Component {
+
+ handleModalClose = () => {
+ if (Votr.ajaxError) return;
+ // remove ?modal=xxxx from querystring
+ const newQueryParams = Object
+ .keys(this.props.query)
+ .filter((key) => key.substring(0, 5) !== 'modal')
+ .reduce(
+ (newObj, key) => {
+ newObj[key] = this.props.query[key];
+ return newObj;
+ },
+ {}
+ );
+
+ navigate(newQueryParams);
+ }
+
+ render() {
+ const query = this.props.query;
+ const action = query.action || 'index';
+ const mainComponent = actions[action] || NotFoundPage;
+ const modalComponent = Votr.ajaxError ? ErrorModal : modalActions[query.modal];
+
+ const C = mainComponent;
+
+ return (
+
+ );
+ }
+}
+
+App.propTypes = {
+ query: PropTypes.object.isRequired,
+};
diff --git a/votrfront/js/src/ajax.js b/votrfront/js/src/ajax.js
new file mode 100644
index 0000000..eab18df
--- /dev/null
+++ b/votrfront/js/src/ajax.js
@@ -0,0 +1,165 @@
+import React, { Component } from 'react';
+import $ from 'jquery';
+
+const debug = function(...args) {
+ if (process.env.NODE_ENV !== 'production') {
+ // eslint-disable-next-line
+ console.log(...args);
+ }
+};
+
+export function sendRpc(name, args, callback) {
+ const HEADER_LENGTH = 10;
+ let processed = 0;
+ let result;
+ let finished = false;
+ const xhr = new XMLHttpRequest();
+
+ function update() {
+ if (finished) return;
+ while (true) {
+ const waiting = xhr.responseText.length - processed;
+ if (waiting < HEADER_LENGTH) {
+ break;
+ }
+ const header = xhr.responseText.substr(processed, HEADER_LENGTH);
+ const length = parseInt(header, HEADER_LENGTH);
+ if (waiting < HEADER_LENGTH + length) {
+ break;
+ }
+ const payload = xhr.responseText.substr(processed + HEADER_LENGTH, length);
+ const data = JSON.parse(payload);
+ debug('RECEIVED', data);
+ if (data.log !== undefined) {
+ logs.push(data);
+ }
+ if (data.result !== undefined) {
+ result = data.result;
+ }
+ if (data.error !== undefined) {
+ return fail(data.error);
+ }
+ processed += HEADER_LENGTH + length;
+ }
+ if (xhr.readyState === 4) {
+ if (processed !== xhr.responseText.length || result === undefined) {
+ debug('INCOMPLETE!');
+ return fail('Network error: Incomplete response');
+ }
+ finished = true;
+ if (callback) {
+ callback(result);
+ }
+ }
+ Votr.appRoot.forceUpdate();
+ }
+
+ function fail(e) {
+ if (finished) return;
+ finished = true;
+ debug('FAILED!', e);
+ if (!Votr.ajaxError) {
+ Votr.ajaxError = (typeof e === 'string' || e instanceof String) ? e : 'Network error';
+ Votr.appRoot.forceUpdate();
+ }
+ }
+
+ xhr.onload = update;
+ xhr.onprogress = update;
+ xhr.onerror = fail;
+ xhr.open('POST', 'rpc?name=' + name, true);
+ xhr.setRequestHeader('Content-Type', 'application/json');
+ xhr.setRequestHeader('X-CSRF-Token', Votr.settings.csrf_token);
+ xhr.send(JSON.stringify(args));
+}
+
+Votr.ajaxError = null;
+
+export const logs = [];
+
+export const RequestCache = {};
+
+RequestCache.pending = {};
+
+RequestCache.sendRequest = function(request) {
+ const cacheKey = request.join('\0');
+ if (RequestCache[cacheKey]) {
+ return;
+ }
+ if (RequestCache.pending[cacheKey]) {
+ return;
+ }
+ RequestCache.pending[cacheKey] = true;
+ sendRpc(request[0], request.slice(1), (result) => {
+ RequestCache[cacheKey] = result;
+ });
+};
+
+RequestCache.invalidate = function(command) {
+ for (let key in RequestCache) {
+ if (key.split('\0')[0] === command) {
+ delete RequestCache[key];
+ }
+ }
+
+ for (let key in RequestCache.pending) {
+ if (key.split('\0')[0] === command) {
+ delete RequestCache.pending[key];
+ }
+ }
+};
+
+export function CacheRequester() {
+ this.missing = [];
+ this.loadedAll = true;
+};
+
+CacheRequester.prototype.get = function(...request) {
+ const cacheKey = request.join('\0');
+ if (RequestCache[cacheKey] !== undefined) {
+ return RequestCache[cacheKey];
+ } else {
+ this.missing.push(request);
+ this.loadedAll = false;
+ return null;
+ }
+};
+
+export class Loading extends Component {
+ componentDidMount() {
+ if (this.props.requests) {
+ this.props.requests.forEach(
+ (request) => {RequestCache.sendRequest(request);}
+ );
+ }
+ }
+
+ componentDidUpdate() {
+ if (this.props.requests) {
+ this.props.requests.forEach(
+ (request) => {RequestCache.sendRequest(request);}
+ );
+ }
+ }
+
+ render() {
+ return Načítavam... ;
+ }
+}
+
+
+export const goPost = (url) => {
+ $('', { method: 'POST', action: url, appendTo: 'body' }).submit();
+};
+
+export const goLogout = () => {
+ goPost('logout');
+};
+
+export const goReset = () => {
+ goPost('reset?destination=' + encodeURIComponent(location.search));
+};
+
+export const goResetHome = () => {
+ goPost('reset?destination=');
+};
diff --git a/votrfront/js/src/coursesStats.js b/votrfront/js/src/coursesStats.js
new file mode 100644
index 0000000..3528ad1
--- /dev/null
+++ b/votrfront/js/src/coursesStats.js
@@ -0,0 +1,86 @@
+import React from 'react';
+
+const ZNAMKY = {
+ A: 1,
+ B: 1.5,
+ C: 2,
+ D: 2.5,
+ E: 3,
+ F: 4,
+};
+
+export const coursesStats = (hodnotenia) => {
+ const result = {};
+
+ result.zima = {};
+ result.zima.count = 0;
+ result.zima.creditsCount = 0;
+
+ result.leto = {};
+ result.leto.count = 0;
+ result.leto.creditsCount = 0;
+
+ result.spolu = {};
+ result.spolu.count = hodnotenia.length;
+ result.spolu.creditsCount = 0;
+
+ hodnotenia.forEach((row) => {
+ let credits = parseInt(row.kredit, 10);
+ if (row.hodn_znamka && row.hodn_znamka[0] === 'F') {
+ credits = 0;
+ }
+ result.spolu.creditsCount += credits;
+ if (row.semester === 'Z') {
+ result.zima.count += 1;
+ result.zima.creditsCount += credits;
+ }
+ if (row.semester === 'L') {
+ result.leto.count += 1;
+ result.leto.creditsCount += credits;
+ }
+ });
+
+ return result;
+};
+
+export const weightedStudyAverage = (hodnotenia) => {
+ let weightedSum = 0;
+ let creditsSum = 0;
+
+ hodnotenia.forEach((row) => {
+ const value = ZNAMKY[row.hodn_znamka[0]];
+ if (value) {
+ weightedSum += value * parseInt(row.kredit, 10);
+ creditsSum += parseInt(row.kredit, 10);
+ }
+ });
+
+ if (creditsSum === 0) {
+ return null;
+ }
+ return weightedSum / creditsSum;
+};
+
+export const renderWeightedStudyAverage = (hodnotenia) => {
+ const average = weightedStudyAverage(hodnotenia);
+ if (average === null) {
+ return null;
+ }
+ return (
+
+ {average.toFixed(2)}
+
+ );
+};
+
+export const currentAcademicYear = () => {
+ const date = new Date();
+ const year = date.getFullYear();
+ const month = date.getMonth() + 1;
+
+ if (month < 8) {
+ return (year - 1) + '/' + year;
+ } else {
+ return year + '/' + (year + 1);
+ }
+};
diff --git a/votrfront/js/src/humanizeAISData.js b/votrfront/js/src/humanizeAISData.js
new file mode 100644
index 0000000..91454ac
--- /dev/null
+++ b/votrfront/js/src/humanizeAISData.js
@@ -0,0 +1,47 @@
+const humanizeWith = (table) => {
+ return (value) => {
+ return table[value] || value;
+ };
+};
+
+export const humanizeTypVyucby = humanizeWith({
+ A: 'povinné (A)',
+ B: 'povinne voliteľné (B)',
+ C: 'výberové (C)',
+});
+
+export const humanizeTerminHodnotenia = humanizeWith({
+ 'R - Riadny termín': 'riadny',
+ '1 - Prvý opravný termín': 'prvý opravný',
+ '2 - Druhý opravný termín': 'druhý opravný',
+});
+
+export const humanizeNazovPriemeru = humanizeWith({
+ 'Sem ?': 'Semester',
+ 'AkadR ?': 'Akademický rok',
+});
+
+export const humanizeBoolean = humanizeWith({
+ A: 'áno',
+ N: 'nie',
+});
+
+export const classForSemester = (semester) => {
+ if (semester === 'Z') {
+ return 'zima';
+ }
+ if (semester === 'L') {
+ return 'leto';
+ }
+ return undefined;
+};
+
+export const plural = (count, one, few, many) => {
+ if (count === 1) {
+ return one;
+ }
+ if (count >= 2 && count <= 4) {
+ return few;
+ }
+ return many;
+};
diff --git a/votrfront/js/src/layout.js b/votrfront/js/src/layout.js
new file mode 100644
index 0000000..d3c99fd
--- /dev/null
+++ b/votrfront/js/src/layout.js
@@ -0,0 +1,243 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import $ from 'jquery';
+
+import { CacheRequester, Loading, goLogout, goReset, logs } from './ajax';
+import { FakeLink, Link } from './router';
+
+export class PageLayout extends Component {
+ render() {
+ return (
+
+
+
+
+
+
+
+
+ {this.props.children}
+
+
+
+
+ );
+ }
+}
+
+PageLayout.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class PageNavbar extends Component {
+ render() {
+ return (
+
+
+
+ Votr
+
+
+
+
+
+
+ O aplikácii
+ Obnoviť
+ Odhlásiť
+
+
+
+
+ );
+ }
+}
+
+export class LogStatus extends Component {
+ render() {
+ const entry = logs[logs.length - 1];
+ let message;
+ if (!entry) {
+ message = '\xA0'; // nbsp
+ } else if (entry.log === 'http' && entry.message.match(/^Requesting/)) {
+ message = 'Čakám na AIS...';
+ } else if (entry.log === 'rpc' && entry.message.match(/finished$/)) {
+ message = '\xA0'; // nbsp
+ } else {
+ message = `Spracovávam dáta... (${entry.message}")`;
+ }
+ return (
+
+ {message}
+
+ );
+ }
+}
+
+export class PageTitle extends Component {
+ componentDidMount() {
+ document.title = this.refs.title.textContent;
+ }
+
+ componentDidUpdate() {
+ document.title = this.refs.title.textContent;
+ }
+
+ render() {
+ return {this.props.children} ;
+ }
+}
+
+export class MainMenu extends Component {
+
+ renderMenuItem(content, href, moreActions) {
+ const isActive = href.action === this.props.query.action
+ || (moreActions && moreActions[this.props.query.action]);
+ return (
+
+ {content}
+
+ );
+ }
+
+ renderDisabled(content) {
+ return {content} ;
+ }
+
+ render() {
+ const { studiumKey, zapisnyListKey } = this.props.query;
+
+ const cache = new CacheRequester();
+ const somStudent = cache.get('get_som_student');
+
+ return (
+
+ Moje štúdium
+
+ {!somStudent && (Nie ste študentom. )}
+ {somStudent && this.renderMenuItem('Moje predmety', { action: 'mojePredmety', zapisnyListKey })}
+ {somStudent && this.renderMenuItem('Moje skúšky', { action: 'mojeSkusky', zapisnyListKey })}
+ {somStudent && this.renderMenuItem('Moje hodnotenia', { action: 'mojeHodnotenia', studiumKey })}
+ {somStudent && this.renderMenuItem(
+ 'Priebežné hodnotenia',
+ { action: 'priebezneHodnotenia', zapisnyListKey }
+ )}
+ {/*somStudent && this.renderDisabled('Môj rozvrh')*/}
+ {somStudent && this.renderMenuItem(
+ 'Zápis predmetov',
+ { action: 'zapisZPlanu', zapisnyListKey }, { zapisZPonuky: true }
+ )}
+ {somStudent && this.renderMenuItem('Prehľad štúdia', { action: 'prehladStudia' })}
+ {!cache.loadedAll && ( )}
+
+ Registre
+ {this.renderMenuItem('Register osôb', { action: 'registerOsob' })}
+ {this.renderMenuItem('Register predmetov', { action: 'registerPredmetov' })}
+ {/*this.renderDisabled('Register miestností')*/}
+ {/*this.renderDisabled('Register študijných programov')*/}
+
+ );
+ }
+};
+
+MainMenu.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export class FormItem extends Component {
+ render() {
+ if (this.props.label) {
+ return (
+
+ {this.props.label}
+ {this.props.children}
+
+ );
+ } else {
+ return (
+
+
{this.props.children}
+
+ );
+ }
+ }
+}
+
+export class ModalBase extends Component {
+
+ componentDidMount() {
+ const $node = $(this.refs.modal);
+ $node.modal();
+ $node.on('hide.bs.modal', (e) => {
+ if ($node.attr('data-show') === 'true') {
+ e.preventDefault();
+ this.props.onClose();
+ }
+ });
+ }
+
+ componentDidUpdate() {
+ const $node = $(this.refs.modal);
+ $node.modal($node.attr('data-show') === 'true' ? 'show' : 'hide');
+ }
+
+ render() {
+ const C = this.props.component;
+
+ return (
+
+ );
+ }
+}
+
+ModalBase.propTypes = {
+ component: PropTypes.func,
+ onClose: PropTypes.func.isRequired,
+ query: PropTypes.object.isRequired,
+};
+
+// TODO Refactor all modals to use something like react-bootstrap
+// so that the files in libs/ are not required
+
+export class Modal extends Component {
+
+ render() {
+ return (
+
+
+ {this.props.closeButton &&
+
+ ×
+ Close
+ }
+
{this.props.title}
+
+
+ {this.props.children}
+
+ {this.props.footer}
+
+ );
+ }
+}
+
+Modal.propTypes = {
+ closeButton: PropTypes.bool.isRequired,
+ title: PropTypes.node.isRequired,
+ footer: PropTypes.node,
+};
+
+Modal.defaultProps = {
+ closeButton: true,
+};
diff --git a/votrfront/js/src/ovce.js b/votrfront/js/src/ovce.js
new file mode 100644
index 0000000..84686a7
--- /dev/null
+++ b/votrfront/js/src/ovce.js
@@ -0,0 +1,89 @@
+import $ from 'jquery';
+
+const cookieDurationClose = 3;
+const cookieDurationVote = 60;
+const cookieName = 'ovcaKolacik';
+const cookieValue = 'on';
+// Starting this day the cookie won't be visible
+const cookieHideDate = Date.parse('6 Jul 2017');
+
+const createDiv = () => {
+ const bodytag = document.getElementsByTagName('body')[0];
+ const div = document.createElement('div');
+ div.setAttribute('id', 'cookie-ovca');
+ div.innerHTML = '';
+ div.innerHTML += 'Nebuď ovca!
';
+
+ // Adds the Cookie Law Banner just after the opening tag
+ bodytag.insertBefore(div, bodytag.firstChild);
+
+ // Adds a class tothe tag when the banner is visible
+ document.getElementsByTagName('body')[0].className += ' cookiebanner';
+};
+
+const createCookie = (name, value, days) => {
+ let expires = '';
+ if (days) {
+ const date = new Date();
+ date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
+ expires = '; expires=' + date.toGMTString();
+ }
+ document.cookie = name + '=' + value + expires + '; path=/';
+};
+
+const checkCookie = (name) => {
+ const nameEQ = name + '=';
+ const ca = document.cookie.split(';');
+ for (let i = 0; i < ca.length; i++) {
+ let c = ca[i];
+ while (c.charAt(0) === ' ') {
+ c = c.substring(1, c.length);
+ }
+ if (c.indexOf(nameEQ) === 0) {
+ return c.substring(nameEQ.length, c.length);
+ }
+ }
+ return null;
+};
+
+const eraseCookie = (name) => {
+ createCookie(name, '', -1);
+};
+
+const removeMe = (duration) => {
+ const element = document.getElementById('cookie-ovca');
+ element.parentNode.removeChild(element);
+ createCookie(window.cookieName, window.cookieValue, duration);
+};
+
+const isFromFMFI = (callback) => {
+ $.ajax({
+ type: 'POST',
+ url: '/rpc?name=get_studia',
+ data: [],
+ success: (msg) => {
+ if (msg.match(/"organizacna_jednotka": "FMFI"/) !== null) {
+ callback();
+ }
+ },
+ beforeSend: (req) => {
+ req.setRequestHeader('X-CSRF-Token', Votr.settings.csrf_token);
+ req.setRequestHeader('Content-Type', 'application/json');
+ },
+ });
+};
+
+const checkDOMChange = () => {
+ if ($('.main-menu li').size() >= 11) {
+ const today = new Date();
+ if ((checkCookie(window.cookieName) !== window.cookieValue) && (cookieHideDate > today)) {
+ isFromFMFI(createDiv);
+ }
+ } else {
+ setTimeout(checkDOMChange, 100);
+ }
+};
+
+$(document).ready(() => {
+ checkDOMChange();
+});
diff --git a/votrfront/js/prologue.js b/votrfront/js/src/prologue.js
similarity index 80%
rename from votrfront/js/prologue.js
rename to votrfront/js/src/prologue.js
index 15ef792..bb062d0 100644
--- a/votrfront/js/prologue.js
+++ b/votrfront/js/src/prologue.js
@@ -1,8 +1,7 @@
-
-Votr.setDebug = function (enabled) {
+Votr.setDebug = (enabled) => {
document.cookie = enabled ? 'votr_debug=true' : 'votr_debug=';
location.reload();
-}
+};
if (!history.pushState) {
document.getElementById('votr').innerHTML = `
@@ -10,7 +9,9 @@ if (!history.pushState) {
Votr
Votr ponúka študentom jednoduchší a pohodlnejší spôsob, ako robiť najčastejšie činnosti zo systému AIS.
Váš prehliadač je príliš starý a nedokáže robiť všetko to, čo Votr potrebuje.
- Prosím stiahnite si novší prehliadač. Nové prehliadače sú rýchlejšie, pohodlnejšie a navyše bezpečnejšie.
+
+ Prosím stiahnite si novší prehliadač. Nové prehliadače sú rýchlejšie, pohodlnejšie a navyše bezpečnejšie.
+
`;
- if (window.ga) ga('send', 'pageview');
+ if (window.ga) {
+ ga('send', 'pageview');
+ }
}
diff --git a/votrfront/js/router.js b/votrfront/js/src/router.js
similarity index 50%
rename from votrfront/js/router.js
rename to votrfront/js/src/router.js
index 858fa78..fcf17bd 100644
--- a/votrfront/js/router.js
+++ b/votrfront/js/src/router.js
@@ -1,55 +1,56 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import $ from 'jquery';
export function trackPageView() {
if (!window.ga) return;
- var current = location.protocol + '//' + location.hostname +
+ const current = location.protocol + '//' + location.hostname +
location.pathname + location.search;
- if (current == trackPageView.last) return;
+ if (current === trackPageView.last) return;
trackPageView.last = current;
ga('send', 'pageview', { location: current });
};
-export var AnalyticsMixin = {
+export const AnalyticsMixin = {
componentDidMount() {
trackPageView();
},
componentDidUpdate() {
trackPageView();
- }
+ },
};
-function parseQueryString(queryString) {
+const parseQueryString = (queryString) => {
if (!queryString) return {};
- var result = {};
- var pairs = queryString.split('&');
- for (var i = 0; i < pairs.length; i++) {
- var index = pairs[i].indexOf('=');
- if (index == -1) {
+ const result = {};
+ const pairs = queryString.split('&');
+ for (let i = 0; i < pairs.length; i++) {
+ let index = pairs[i].indexOf('=');
+ if (index === -1) {
index = pairs[i].length;
}
- var name = pairs[i].substring(0, index);
- var value = pairs[i].substring(index + 1);
+ const name = pairs[i].substring(0, index);
+ const value = pairs[i].substring(index + 1);
result[name] = decodeURIComponent(value.replace(/\+/g, ' '));
}
return result;
-}
-
+};
-export var Root = React.createClass({
- mixins: [AnalyticsMixin],
+export class Root extends Component {
- handlePopState() {
+ handlePopState = () => {
this.forceUpdate();
- },
+ }
componentDidMount() {
window.addEventListener('popstate', this.handlePopState, false);
- },
+ }
render() {
- var queryString = location.search.substring(1);
+ const queryString = location.search.substring(1);
if (queryString !== this.lastQueryString) {
this.query = parseQueryString(queryString);
this.lastQueryString = queryString;
@@ -57,59 +58,85 @@ export var Root = React.createClass({
return ;
}
-});
+}
+Root.mixins = [AnalyticsMixin];
-export function buildUrl(href) {
- if (_.isString(href)) return href;
- return '?' + $.param(_.omit(href, _.isUndefined), true);
+export const buildUrl = (href) => {
+ if (typeof href === 'string' || href instanceof String) {
+ return href;
+ }
+ // remove empty query paramaters
+ const newHref = Object.keys(href)
+ .filter((key) => key !== undefined)
+ .reduce(
+ (newObj, key) => {
+ newObj[key] = href[key];
+ return newObj;
+ },
+ {}
+ );
+
+ return '?' + $.param(newHref, true);
};
-
-export function navigate(href) {
+export const navigate = (href) => {
Votr.didNavigate = true;
history.pushState(null, '', Votr.settings.url_root + buildUrl(href));
Votr.appRoot.forceUpdate();
};
-
-export var Link = React.createClass({
- handleClick(event) {
+export class Link extends Component {
+ handleClick = (event) => {
// Chrome fires onclick on middle click. Firefox only fires it on document,
// see ,
// but React adds event listeners to document so we still see a click event.
- if (event.button != 0) return;
+ if (event.button !== 0) {
+ return;
+ }
event.preventDefault();
navigate(this.props.href);
- },
+ }
render() {
- return ;
+ return (
+
+ );
}
-});
+}
// Looks and acts like a link, but doesn't have a href and cannot be opened in
// a new tab when middle-clicked or ctrl-clicked.
-export var FakeLink = React.createClass({
- propTypes: {
- onClick: React.PropTypes.func.isRequired
- },
+export class FakeLink extends Component {
// Pressing Enter on emits a click event, and the HTML5 spec
// says elements with tabindex should do that too, but they don't.
// suggests using a keyup event:
- handleKeyUp(event) {
- if (event.which == 13) {
+ handleKeyUp = (event) => {
+ if (event.which === 13) {
event.preventDefault();
this.props.onClick(event);
}
- },
+ }
render() {
- return ;
+ return (
+
+ );
}
-});
+}
+
+FakeLink.propTypes = {
+ onClick: PropTypes.func.isRequired,
+};
diff --git a/votrfront/js/src/sorting.js b/votrfront/js/src/sorting.js
new file mode 100644
index 0000000..7ae933d
--- /dev/null
+++ b/votrfront/js/src/sorting.js
@@ -0,0 +1,115 @@
+import React from 'react';
+
+import { navigate } from './router';
+
+export const sortAs = {};
+
+sortAs.personName = (text) => {
+ let words = text.replace(/,/g, '').split(' ');
+ words = words.filter((word) => !word.match(/\.$/));
+ // last name goes to the beginning
+ words.unshift(words.pop());
+ return words.join(' ').toLowerCase();
+ // TODO: consider using latinise (see fajr).
+};
+
+
+sortAs.number = (text) => {
+ return +text.replace(/,/g, '.');
+ // TODO: this won't be needed when fladgejt starts returning numbers
+};
+
+
+sortAs.date = (date) => {
+ if (date.match(/^\d\d\.\d\d\.\d\d\d\d/)) {
+ return date.substring(6, 10) + date.substring(3, 5) + date.substring(0, 2) + date.substring(10);
+ }
+ return date;
+};
+
+
+sortAs.interval = (text) => {
+ const index = text.indexOf('do ');
+ if (index === -1) {
+ return '';
+ }
+ return sortAs.date(text.substring(index + 3));
+};
+
+export const sortTable = (items, columns, query, queryKey) => {
+ const orderString = query[queryKey] || columns.defaultOrder;
+ const order = orderString ? orderString.split(/(?=[ad])/) : [];
+ const orderLength = order.length;
+ const orderAsc = order.map((orderItem) => orderItem.substring(0, 1) === 'a');
+ const orderColumns = order.map((orderItem) => columns[orderItem.substring(1)]);
+
+ items = items.map((item, index) => {
+ const criteria = [];
+ for (let i = 0; i < orderLength; i++) {
+ const [label, prop, process, preferDesc] = orderColumns[i];
+ let value = prop ? item[prop] : item;
+ if (process) {
+ value = process(value);
+ }
+ if (!prop && !process) {
+ value = undefined;
+ }
+ criteria.push(value);
+ }
+ return { item, index, criteria };
+ });
+
+ items.sort((a, b) => {
+ for (let i = 0; i < orderLength; i++) {
+ const ac = a.criteria[i], bc = b.criteria[i];
+ if (ac === bc) {
+ continue;
+ }
+ if (ac < bc) {
+ return orderAsc[i] ? -1 : 1;
+ }
+ if (ac > bc) {
+ return orderAsc[i] ? 1 : -1;
+ }
+ }
+ return a.index - b.index;
+ });
+
+ items = items.map((a) => a.item);
+
+ const handleClick = (event) => {
+ const index = event.currentTarget.getAttribute('data-index');
+ const [label, prop, process, preferDesc] = columns[index];
+
+ const newOrder = order.filter(
+ (ord) => ord !== 'a' + index && ord !== 'd' + index
+ );
+ newOrder.unshift((
+ order[0] === 'a' + index ? 'd' :
+ order[0] === 'd' + index ? 'a' :
+ preferDesc ? 'd' : 'a'
+ ) + index);
+
+ navigate({ ...query, [queryKey]: newOrder.join('') });
+ };
+
+ const header = (
+
+ {columns.map(([label, prop, process, preferDesc], index) => (
+
+ {label}
+
+ ))}
+
+ );
+
+ return [items, header];
+};
diff --git a/votrfront/js/src/utils.js b/votrfront/js/src/utils.js
new file mode 100644
index 0000000..e69de29
diff --git a/votrfront/js/webpack.common.js b/votrfront/js/webpack.common.js
new file mode 100644
index 0000000..bf1ebc4
--- /dev/null
+++ b/votrfront/js/webpack.common.js
@@ -0,0 +1,38 @@
+const path = require('path');
+const webpack = require('webpack');
+const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
+const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
+
+module.exports = {
+ entry: {
+ app: './main.js',
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /(node_modules|bower_components)/,
+ use: {
+ loader: 'babel-loader',
+ },
+ },
+ ],
+ },
+ plugins: [
+ new LodashModuleReplacementPlugin({
+ shorthands: true,
+ }),
+ // remove the ProvidePlugin when libs/ folder is purged
+ new webpack.ProvidePlugin({
+ $: 'jquery',
+ jQuery: 'jquery',
+ }),
+ new BundleAnalyzerPlugin({
+ openAnalyzer: false,
+ }),
+ ],
+ output: {
+ filename: 'votr.bundle.js',
+ path: path.join(__dirname, '../static'),
+ },
+};
diff --git a/votrfront/js/webpack.dev.js b/votrfront/js/webpack.dev.js
new file mode 100644
index 0000000..e5909c3
--- /dev/null
+++ b/votrfront/js/webpack.dev.js
@@ -0,0 +1,7 @@
+const merge = require('webpack-merge');
+const common = require('./webpack.common.js');
+
+module.exports = merge(common, {
+ mode: 'development',
+ devtool: 'inline-source-map',
+});
diff --git a/votrfront/js/webpack.prod.js b/votrfront/js/webpack.prod.js
new file mode 100644
index 0000000..556b7cf
--- /dev/null
+++ b/votrfront/js/webpack.prod.js
@@ -0,0 +1,16 @@
+const webpack = require('webpack');
+const merge = require('webpack-merge');
+const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
+const common = require('./webpack.common.js');
+
+module.exports = merge(common, {
+ mode: 'production',
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env.NODE_ENV': JSON.stringify('production'),
+ }),
+ new webpack.optimize.OccurrenceOrderPlugin(),
+ new webpack.optimize.ModuleConcatenationPlugin(),
+ new UglifyJSPlugin(),
+ ],
+});
diff --git a/votrfront/js/yarn.lock b/votrfront/js/yarn.lock
new file mode 100644
index 0000000..c6aa951
--- /dev/null
+++ b/votrfront/js/yarn.lock
@@ -0,0 +1,6034 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/code-frame@7.0.0-beta.40", "@babel/code-frame@^7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz#37e2b0cf7c56026b4b21d3927cadf81adec32ac6"
+ dependencies:
+ "@babel/highlight" "7.0.0-beta.40"
+
+"@babel/core@^7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.40.tgz#455464dd81d499fd97d32b473f0331f74379a33f"
+ dependencies:
+ "@babel/code-frame" "7.0.0-beta.40"
+ "@babel/generator" "7.0.0-beta.40"
+ "@babel/helpers" "7.0.0-beta.40"
+ "@babel/template" "7.0.0-beta.40"
+ "@babel/traverse" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+ babylon "7.0.0-beta.40"
+ convert-source-map "^1.1.0"
+ debug "^3.0.1"
+ json5 "^0.5.0"
+ lodash "^4.2.0"
+ micromatch "^2.3.11"
+ resolve "^1.3.2"
+ source-map "^0.5.0"
+
+"@babel/generator@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.40.tgz#ab61f9556f4f71dbd1138949c795bb9a21e302ea"
+ dependencies:
+ "@babel/types" "7.0.0-beta.40"
+ jsesc "^2.5.1"
+ lodash "^4.2.0"
+ source-map "^0.5.0"
+ trim-right "^1.0.1"
+
+"@babel/helper-annotate-as-pure@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.40.tgz#095dd4c70b231eba17ebf61c3434e6f9d71bd574"
+ dependencies:
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.40.tgz#bec4240c95d8b646812c5d4ac536a5579dbcdd53"
+ dependencies:
+ "@babel/helper-explode-assignable-expression" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-builder-react-jsx@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0-beta.40.tgz#2a171b6c4939c6cd0bdc38cca261d1f3b32cedb1"
+ dependencies:
+ "@babel/types" "7.0.0-beta.40"
+ esutils "^2.0.0"
+
+"@babel/helper-call-delegate@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.40.tgz#5d5000d0bf76c68ee6866961e0b7eb6e9ed52438"
+ dependencies:
+ "@babel/helper-hoist-variables" "7.0.0-beta.40"
+ "@babel/traverse" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-define-map@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.40.tgz#ad64c548dd98e7746305852f113ed04dc74329c0"
+ dependencies:
+ "@babel/helper-function-name" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+ lodash "^4.2.0"
+
+"@babel/helper-explode-assignable-expression@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.40.tgz#0ef579288d894a987c60bf0577c074ad18cfa9dd"
+ dependencies:
+ "@babel/traverse" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-function-name@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz#9d033341ab16517f40d43a73f2d81fc431ccd7b6"
+ dependencies:
+ "@babel/helper-get-function-arity" "7.0.0-beta.40"
+ "@babel/template" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-get-function-arity@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz#ac0419cf067b0ec16453e1274f03878195791c6e"
+ dependencies:
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-hoist-variables@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.40.tgz#59d47fd133782d60db89af0d18083ad3c9f4801c"
+ dependencies:
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-module-imports@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.40.tgz#251cbb6404599282e8f7356a5b32c9381bef5d2d"
+ dependencies:
+ "@babel/types" "7.0.0-beta.40"
+ lodash "^4.2.0"
+
+"@babel/helper-module-transforms@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.40.tgz#e5240afd47bd98f6ae65874b9ae508533abfee76"
+ dependencies:
+ "@babel/helper-module-imports" "7.0.0-beta.40"
+ "@babel/helper-simple-access" "7.0.0-beta.40"
+ "@babel/template" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+ lodash "^4.2.0"
+
+"@babel/helper-optimise-call-expression@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.40.tgz#f0e7f70d455bff8ab6a248a84f0221098fa468ac"
+ dependencies:
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-regex@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-beta.40.tgz#b47018ecca8ff66bb390c34a95ff71bc01495833"
+ dependencies:
+ lodash "^4.2.0"
+
+"@babel/helper-remap-async-to-generator@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.40.tgz#33414d1cc160ebf0991ebc60afebe36b08feae05"
+ dependencies:
+ "@babel/helper-annotate-as-pure" "7.0.0-beta.40"
+ "@babel/helper-wrap-function" "7.0.0-beta.40"
+ "@babel/template" "7.0.0-beta.40"
+ "@babel/traverse" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-replace-supers@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.40.tgz#2ab0c9e7fa17d313745f1634ce6b7bccaa5dd5fe"
+ dependencies:
+ "@babel/helper-optimise-call-expression" "7.0.0-beta.40"
+ "@babel/template" "7.0.0-beta.40"
+ "@babel/traverse" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helper-simple-access@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.40.tgz#018f765090a3d25153778958969f235dc6ce5b57"
+ dependencies:
+ "@babel/template" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+ lodash "^4.2.0"
+
+"@babel/helper-wrap-function@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.40.tgz#4db4630cdaf4fd47fa2c45b5b7a9ecc33ff3f2be"
+ dependencies:
+ "@babel/helper-function-name" "7.0.0-beta.40"
+ "@babel/template" "7.0.0-beta.40"
+ "@babel/traverse" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/helpers@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.40.tgz#82f8e144f56b2896b1d624ca88ac4603023ececd"
+ dependencies:
+ "@babel/template" "7.0.0-beta.40"
+ "@babel/traverse" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+
+"@babel/highlight@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.40.tgz#b43d67d76bf46e1d10d227f68cddcd263786b255"
+ dependencies:
+ chalk "^2.0.0"
+ esutils "^2.0.2"
+ js-tokens "^3.0.0"
+
+"@babel/plugin-proposal-async-generator-functions@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.40.tgz#64f4aebc3fff33d2ae8f0a0870f0dfe2ff6815d6"
+ dependencies:
+ "@babel/helper-remap-async-to-generator" "7.0.0-beta.40"
+ "@babel/plugin-syntax-async-generators" "7.0.0-beta.40"
+
+"@babel/plugin-proposal-class-properties@^7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.40.tgz#ee0549729e9f44603efa17523b459ea3021458dc"
+ dependencies:
+ "@babel/helper-function-name" "7.0.0-beta.40"
+ "@babel/plugin-syntax-class-properties" "7.0.0-beta.40"
+
+"@babel/plugin-proposal-object-rest-spread@7.0.0-beta.40", "@babel/plugin-proposal-object-rest-spread@^7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.40.tgz#ce35d2240908e52706a612eb26d67db667cd700f"
+ dependencies:
+ "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.40"
+
+"@babel/plugin-proposal-optional-catch-binding@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0-beta.40.tgz#e76ddcb21880eea0225f1dcde20a5e97ca85fd39"
+ dependencies:
+ "@babel/plugin-syntax-optional-catch-binding" "7.0.0-beta.40"
+
+"@babel/plugin-proposal-unicode-property-regex@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0-beta.40.tgz#1fb2c29c8bd88d5fff82ec080dbe24e7126ec460"
+ dependencies:
+ "@babel/helper-regex" "7.0.0-beta.40"
+ regexpu-core "^4.1.3"
+
+"@babel/plugin-syntax-async-generators@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.40.tgz#6c45889569add3b3721cc9a481ae99906f240874"
+
+"@babel/plugin-syntax-class-properties@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.40.tgz#ff82c04c6d97cdb947dc64e3f3d4bc791e85a16f"
+
+"@babel/plugin-syntax-jsx@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.40.tgz#db44d52ff06f784be22f2659e694cc2cf97f99f9"
+
+"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.40.tgz#d5e04536062e4df685c203ae48bb19bfe2cf235c"
+
+"@babel/plugin-syntax-optional-catch-binding@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-beta.40.tgz#2e3de0919d05136bb658172ef9ba9ef7e84bce9e"
+
+"@babel/plugin-transform-arrow-functions@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.40.tgz#0842045b16835d6da0c334d0b09d575852f27962"
+
+"@babel/plugin-transform-async-to-generator@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-beta.40.tgz#9195e2473a435b9a9aabc0b64572e9d1ec1c57cb"
+ dependencies:
+ "@babel/helper-module-imports" "7.0.0-beta.40"
+ "@babel/helper-remap-async-to-generator" "7.0.0-beta.40"
+
+"@babel/plugin-transform-block-scoped-functions@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0-beta.40.tgz#491e61f860cabe69379233983fe7ca14f879e41f"
+
+"@babel/plugin-transform-block-scoping@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.40.tgz#23197ee6f696b7e5ace884f0dc5434df20d7dd97"
+ dependencies:
+ lodash "^4.2.0"
+
+"@babel/plugin-transform-classes@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.40.tgz#c7a752009df4bb0f77179027daa0783f9a036b0b"
+ dependencies:
+ "@babel/helper-annotate-as-pure" "7.0.0-beta.40"
+ "@babel/helper-define-map" "7.0.0-beta.40"
+ "@babel/helper-function-name" "7.0.0-beta.40"
+ "@babel/helper-optimise-call-expression" "7.0.0-beta.40"
+ "@babel/helper-replace-supers" "7.0.0-beta.40"
+ globals "^11.1.0"
+
+"@babel/plugin-transform-computed-properties@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.40.tgz#e4bd53455d9f96882cc8e9923895d71690f6969e"
+
+"@babel/plugin-transform-destructuring@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.40.tgz#503a4719eb9ed8c933b50d4ec3f106ed371852ee"
+
+"@babel/plugin-transform-dotall-regex@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0-beta.40.tgz#89b5ccff477624b97129f9a7e262a436437d7ae2"
+ dependencies:
+ "@babel/helper-regex" "7.0.0-beta.40"
+ regexpu-core "^4.1.3"
+
+"@babel/plugin-transform-duplicate-keys@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0-beta.40.tgz#91599be229d4409cf3c9bbd094fb04d354bd8068"
+
+"@babel/plugin-transform-exponentiation-operator@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.40.tgz#bf0bafdd5aad7061c25dba25e29e12329838baeb"
+ dependencies:
+ "@babel/helper-builder-binary-assignment-operator-visitor" "7.0.0-beta.40"
+
+"@babel/plugin-transform-for-of@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.40.tgz#67920d749bac4840ceeae9907d918dad33908244"
+
+"@babel/plugin-transform-function-name@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.40.tgz#37b5ca4f90fba207d359c0be3af5bfecdc737a3d"
+ dependencies:
+ "@babel/helper-function-name" "7.0.0-beta.40"
+
+"@babel/plugin-transform-literals@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.40.tgz#a6bf8808f97accf42a171b27a133802aa0650d3e"
+
+"@babel/plugin-transform-modules-amd@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0-beta.40.tgz#1882f1a02b16d261a332c87c035c9aeefd402683"
+ dependencies:
+ "@babel/helper-module-transforms" "7.0.0-beta.40"
+
+"@babel/plugin-transform-modules-commonjs@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.40.tgz#a85f8c311f498a94a45531cc4ed5ff98b338a70a"
+ dependencies:
+ "@babel/helper-module-transforms" "7.0.0-beta.40"
+ "@babel/helper-simple-access" "7.0.0-beta.40"
+
+"@babel/plugin-transform-modules-systemjs@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0-beta.40.tgz#808b372bdbe06a28bf7a3870d8e810bd7298227a"
+ dependencies:
+ "@babel/helper-hoist-variables" "7.0.0-beta.40"
+
+"@babel/plugin-transform-modules-umd@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0-beta.40.tgz#5bd4e395a2673e687ed592608ad2fd4883a5a119"
+ dependencies:
+ "@babel/helper-module-transforms" "7.0.0-beta.40"
+
+"@babel/plugin-transform-new-target@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0-beta.40.tgz#ee52bb87fbf325ac054811ec739b25fbce97809e"
+
+"@babel/plugin-transform-object-super@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0-beta.40.tgz#c64f9ba3587610d76c2edfdd8f507a59ea3ba63d"
+ dependencies:
+ "@babel/helper-replace-supers" "7.0.0-beta.40"
+
+"@babel/plugin-transform-parameters@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.40.tgz#efa366fab0dcbd0221b46aa2662c324b4b414d1d"
+ dependencies:
+ "@babel/helper-call-delegate" "7.0.0-beta.40"
+ "@babel/helper-get-function-arity" "7.0.0-beta.40"
+
+"@babel/plugin-transform-react-display-name@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0-beta.40.tgz#2e9aba5d74da8ecee00d6d4bf68c833955355e4c"
+
+"@babel/plugin-transform-react-jsx-self@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.0.0-beta.40.tgz#cbf0286ec9e52129840e16d1a173adb98e52fb97"
+ dependencies:
+ "@babel/plugin-syntax-jsx" "7.0.0-beta.40"
+
+"@babel/plugin-transform-react-jsx-source@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0-beta.40.tgz#7e62fe33f3e46c7f0d81d187d9c9aa348daa6488"
+ dependencies:
+ "@babel/plugin-syntax-jsx" "7.0.0-beta.40"
+
+"@babel/plugin-transform-react-jsx@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0-beta.40.tgz#93af0b0ef691cda86ab52d912b50f72eb538349d"
+ dependencies:
+ "@babel/helper-builder-react-jsx" "7.0.0-beta.40"
+ "@babel/plugin-syntax-jsx" "7.0.0-beta.40"
+
+"@babel/plugin-transform-regenerator@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.40.tgz#f8a89ce89a0fae8e9cdfc2f2768104811517374a"
+ dependencies:
+ regenerator-transform "^0.12.3"
+
+"@babel/plugin-transform-shorthand-properties@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.40.tgz#421835237b0fcab0e67c941726d95dfc543514f4"
+
+"@babel/plugin-transform-spread@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.40.tgz#881578938e5750137301750bef7fdd0e01be76be"
+
+"@babel/plugin-transform-sticky-regex@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0-beta.40.tgz#5b44b31f8539fc66af18962e55752b82298032ee"
+ dependencies:
+ "@babel/helper-regex" "7.0.0-beta.40"
+
+"@babel/plugin-transform-template-literals@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.40.tgz#5ef3377d1294aee39b913768a1f884806a45393b"
+ dependencies:
+ "@babel/helper-annotate-as-pure" "7.0.0-beta.40"
+
+"@babel/plugin-transform-typeof-symbol@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0-beta.40.tgz#67f0b8a5dd298b0aa5b347c3b6738c9c7baf1bcf"
+
+"@babel/plugin-transform-unicode-regex@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0-beta.40.tgz#a956187aad2965d7c095d64b1ae87eba10e0a2c6"
+ dependencies:
+ "@babel/helper-regex" "7.0.0-beta.40"
+ regexpu-core "^4.1.3"
+
+"@babel/preset-env@^7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.0.0-beta.40.tgz#713292f9e410f76b3f4301330756c89343c4b2e4"
+ dependencies:
+ "@babel/plugin-proposal-async-generator-functions" "7.0.0-beta.40"
+ "@babel/plugin-proposal-object-rest-spread" "7.0.0-beta.40"
+ "@babel/plugin-proposal-optional-catch-binding" "7.0.0-beta.40"
+ "@babel/plugin-proposal-unicode-property-regex" "7.0.0-beta.40"
+ "@babel/plugin-syntax-async-generators" "7.0.0-beta.40"
+ "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.40"
+ "@babel/plugin-syntax-optional-catch-binding" "7.0.0-beta.40"
+ "@babel/plugin-transform-arrow-functions" "7.0.0-beta.40"
+ "@babel/plugin-transform-async-to-generator" "7.0.0-beta.40"
+ "@babel/plugin-transform-block-scoped-functions" "7.0.0-beta.40"
+ "@babel/plugin-transform-block-scoping" "7.0.0-beta.40"
+ "@babel/plugin-transform-classes" "7.0.0-beta.40"
+ "@babel/plugin-transform-computed-properties" "7.0.0-beta.40"
+ "@babel/plugin-transform-destructuring" "7.0.0-beta.40"
+ "@babel/plugin-transform-dotall-regex" "7.0.0-beta.40"
+ "@babel/plugin-transform-duplicate-keys" "7.0.0-beta.40"
+ "@babel/plugin-transform-exponentiation-operator" "7.0.0-beta.40"
+ "@babel/plugin-transform-for-of" "7.0.0-beta.40"
+ "@babel/plugin-transform-function-name" "7.0.0-beta.40"
+ "@babel/plugin-transform-literals" "7.0.0-beta.40"
+ "@babel/plugin-transform-modules-amd" "7.0.0-beta.40"
+ "@babel/plugin-transform-modules-commonjs" "7.0.0-beta.40"
+ "@babel/plugin-transform-modules-systemjs" "7.0.0-beta.40"
+ "@babel/plugin-transform-modules-umd" "7.0.0-beta.40"
+ "@babel/plugin-transform-new-target" "7.0.0-beta.40"
+ "@babel/plugin-transform-object-super" "7.0.0-beta.40"
+ "@babel/plugin-transform-parameters" "7.0.0-beta.40"
+ "@babel/plugin-transform-regenerator" "7.0.0-beta.40"
+ "@babel/plugin-transform-shorthand-properties" "7.0.0-beta.40"
+ "@babel/plugin-transform-spread" "7.0.0-beta.40"
+ "@babel/plugin-transform-sticky-regex" "7.0.0-beta.40"
+ "@babel/plugin-transform-template-literals" "7.0.0-beta.40"
+ "@babel/plugin-transform-typeof-symbol" "7.0.0-beta.40"
+ "@babel/plugin-transform-unicode-regex" "7.0.0-beta.40"
+ browserslist "^3.0.0"
+ invariant "^2.2.2"
+ semver "^5.3.0"
+
+"@babel/preset-react@^7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0-beta.40.tgz#ccc8f916b694c8ea4b4ccbd1584f873caf199557"
+ dependencies:
+ "@babel/plugin-syntax-jsx" "7.0.0-beta.40"
+ "@babel/plugin-transform-react-display-name" "7.0.0-beta.40"
+ "@babel/plugin-transform-react-jsx" "7.0.0-beta.40"
+ "@babel/plugin-transform-react-jsx-self" "7.0.0-beta.40"
+ "@babel/plugin-transform-react-jsx-source" "7.0.0-beta.40"
+
+"@babel/template@7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.40.tgz#034988c6424eb5c3268fe6a608626de1f4410fc8"
+ dependencies:
+ "@babel/code-frame" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+ babylon "7.0.0-beta.40"
+ lodash "^4.2.0"
+
+"@babel/traverse@7.0.0-beta.40", "@babel/traverse@^7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.40.tgz#d140e449b2e093ef9fe1a2eecc28421ffb4e521e"
+ dependencies:
+ "@babel/code-frame" "7.0.0-beta.40"
+ "@babel/generator" "7.0.0-beta.40"
+ "@babel/helper-function-name" "7.0.0-beta.40"
+ "@babel/types" "7.0.0-beta.40"
+ babylon "7.0.0-beta.40"
+ debug "^3.0.1"
+ globals "^11.1.0"
+ invariant "^2.2.0"
+ lodash "^4.2.0"
+
+"@babel/types@7.0.0-beta.40", "@babel/types@^7.0.0-beta.40":
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.40.tgz#25c3d7aae14126abe05fcb098c65a66b6d6b8c14"
+ dependencies:
+ esutils "^2.0.2"
+ lodash "^4.2.0"
+ to-fast-properties "^2.0.0"
+
+abbrev@1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
+
+accepts@~1.3.4:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
+ dependencies:
+ mime-types "~2.1.18"
+ negotiator "0.6.1"
+
+acorn-dynamic-import@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278"
+ dependencies:
+ acorn "^5.0.0"
+
+acorn-jsx@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
+ dependencies:
+ acorn "^3.0.4"
+
+acorn@^3.0.4:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
+
+acorn@^5.0.0, acorn@^5.3.0, acorn@^5.4.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.0.tgz#1abb587fbf051f94e3de20e6b26ef910b1828298"
+
+ajv-keywords@^3.0.0, ajv-keywords@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be"
+
+ajv@^4.9.1:
+ version "4.11.8"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
+ dependencies:
+ co "^4.6.0"
+ json-stable-stringify "^1.0.1"
+
+ajv@^5.3.0:
+ version "5.5.2"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
+ dependencies:
+ co "^4.6.0"
+ fast-deep-equal "^1.0.0"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.3.0"
+
+ajv@^6.0.1, ajv@^6.1.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.2.0.tgz#afac295bbaa0152449e522742e4547c1ae9328d2"
+ dependencies:
+ fast-deep-equal "^1.0.0"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.3.0"
+
+ansi-escapes@^1.0.0, ansi-escapes@^1.1.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+
+ansi-escapes@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92"
+
+ansi-regex@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+
+ansi-regex@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
+
+ansi-styles@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+
+ansi-styles@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
+ dependencies:
+ color-convert "^1.9.0"
+
+ansi-styles@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
+
+anymatch@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
+ dependencies:
+ micromatch "^3.1.4"
+ normalize-path "^2.1.1"
+
+aproba@^1.0.3, aproba@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
+
+are-we-there-yet@~1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d"
+ dependencies:
+ delegates "^1.0.0"
+ readable-stream "^2.0.6"
+
+argparse@^1.0.7:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
+ dependencies:
+ sprintf-js "~1.0.2"
+
+argv@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab"
+
+arr-diff@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
+ dependencies:
+ arr-flatten "^1.0.1"
+
+arr-diff@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
+
+arr-flatten@^1.0.1, arr-flatten@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
+
+arr-union@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
+
+array-differ@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
+
+array-flatten@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
+
+array-includes@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d"
+ dependencies:
+ define-properties "^1.1.2"
+ es-abstract "^1.7.0"
+
+array-union@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+ dependencies:
+ array-uniq "^1.0.1"
+
+array-uniq@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+
+array-unique@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
+
+array-unique@^0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
+
+arrify@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+
+asap@~2.0.3:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+
+asn1.js@^4.0.0:
+ version "4.10.1"
+ resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
+ dependencies:
+ bn.js "^4.0.0"
+ inherits "^2.0.1"
+ minimalistic-assert "^1.0.0"
+
+asn1@~0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+
+assert-plus@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
+
+assert@^1.1.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91"
+ dependencies:
+ util "0.10.3"
+
+assign-symbols@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
+
+ast-types@0.10.1:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.1.tgz#f52fca9715579a14f841d67d7f8d25432ab6a3dd"
+
+ast-types@0.10.2:
+ version "0.10.2"
+ resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.2.tgz#aef76a04fde54634976fc94defaad1a67e2eadb0"
+
+async-each@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
+
+async-limiter@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
+
+async@^1.5.0:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
+
+async@^2.0.0:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
+ dependencies:
+ lodash "^4.14.0"
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+
+atob@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d"
+
+aws-sign2@~0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+
+aws4@^1.2.1:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+
+babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
+ dependencies:
+ chalk "^1.1.3"
+ esutils "^2.0.2"
+ js-tokens "^3.0.2"
+
+babel-core@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8"
+ dependencies:
+ babel-code-frame "^6.26.0"
+ babel-generator "^6.26.0"
+ babel-helpers "^6.24.1"
+ babel-messages "^6.23.0"
+ babel-register "^6.26.0"
+ babel-runtime "^6.26.0"
+ babel-template "^6.26.0"
+ babel-traverse "^6.26.0"
+ babel-types "^6.26.0"
+ babylon "^6.18.0"
+ convert-source-map "^1.5.0"
+ debug "^2.6.8"
+ json5 "^0.5.1"
+ lodash "^4.17.4"
+ minimatch "^3.0.4"
+ path-is-absolute "^1.0.1"
+ private "^0.1.7"
+ slash "^1.0.0"
+ source-map "^0.5.6"
+
+babel-eslint@^8.2.2:
+ version "8.2.2"
+ resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.2.tgz#1102273354c6f0b29b4ea28a65f97d122296b68b"
+ dependencies:
+ "@babel/code-frame" "^7.0.0-beta.40"
+ "@babel/traverse" "^7.0.0-beta.40"
+ "@babel/types" "^7.0.0-beta.40"
+ babylon "^7.0.0-beta.40"
+ eslint-scope "~3.7.1"
+ eslint-visitor-keys "^1.0.0"
+
+babel-generator@^6.26.0:
+ version "6.26.1"
+ resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90"
+ dependencies:
+ babel-messages "^6.23.0"
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ detect-indent "^4.0.0"
+ jsesc "^1.3.0"
+ lodash "^4.17.4"
+ source-map "^0.5.7"
+ trim-right "^1.0.1"
+
+babel-helper-bindify-decorators@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664"
+ dependencies:
+ babel-helper-explode-assignable-expression "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-helper-call-delegate@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d"
+ dependencies:
+ babel-helper-hoist-variables "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-helper-define-map@^6.24.1:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f"
+ dependencies:
+ babel-helper-function-name "^6.24.1"
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ lodash "^4.17.4"
+
+babel-helper-explode-assignable-expression@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-helper-explode-class@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb"
+ dependencies:
+ babel-helper-bindify-decorators "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-helper-function-name@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
+ dependencies:
+ babel-helper-get-function-arity "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-helper-get-function-arity@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-helper-hoist-variables@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-helper-module-imports@^7.0.0-beta.3:
+ version "7.0.0-beta.3"
+ resolved "https://registry.yarnpkg.com/babel-helper-module-imports/-/babel-helper-module-imports-7.0.0-beta.3.tgz#e15764e3af9c8e11810c09f78f498a2bdc71585a"
+ dependencies:
+ babel-types "7.0.0-beta.3"
+ lodash "^4.2.0"
+
+babel-helper-optimise-call-expression@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-helper-regex@^6.24.1:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72"
+ dependencies:
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ lodash "^4.17.4"
+
+babel-helper-remap-async-to-generator@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b"
+ dependencies:
+ babel-helper-function-name "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-helper-replace-supers@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a"
+ dependencies:
+ babel-helper-optimise-call-expression "^6.24.1"
+ babel-messages "^6.23.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-helpers@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-loader@8.0.0-beta.2:
+ version "8.0.0-beta.2"
+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.0-beta.2.tgz#4d5b67c964dc8c9cba866fd13d6b90df3acf8723"
+ dependencies:
+ find-cache-dir "^1.0.0"
+ loader-utils "^1.0.2"
+ mkdirp "^0.5.1"
+
+babel-messages@^6.23.0:
+ version "6.23.0"
+ resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-check-es2015-constants@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-lodash@^3.3.2:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.2.tgz#da3a5b49ba27447f54463f6c4fa81396ccdd463f"
+ dependencies:
+ babel-helper-module-imports "^7.0.0-beta.3"
+ babel-types "^6.26.0"
+ glob "^7.1.1"
+ lodash "^4.17.4"
+ require-package-name "^2.0.1"
+
+babel-plugin-syntax-async-functions@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
+
+babel-plugin-syntax-async-generators@^6.5.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a"
+
+babel-plugin-syntax-class-constructor-call@^6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416"
+
+babel-plugin-syntax-class-properties@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
+
+babel-plugin-syntax-decorators@^6.13.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b"
+
+babel-plugin-syntax-dynamic-import@^6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
+
+babel-plugin-syntax-exponentiation-operator@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
+
+babel-plugin-syntax-export-extensions@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721"
+
+babel-plugin-syntax-flow@^6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
+
+babel-plugin-syntax-object-rest-spread@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
+
+babel-plugin-syntax-trailing-function-commas@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
+
+babel-plugin-transform-async-generator-functions@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db"
+ dependencies:
+ babel-helper-remap-async-to-generator "^6.24.1"
+ babel-plugin-syntax-async-generators "^6.5.0"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-async-to-generator@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761"
+ dependencies:
+ babel-helper-remap-async-to-generator "^6.24.1"
+ babel-plugin-syntax-async-functions "^6.8.0"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-class-constructor-call@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9"
+ dependencies:
+ babel-plugin-syntax-class-constructor-call "^6.18.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-plugin-transform-class-properties@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac"
+ dependencies:
+ babel-helper-function-name "^6.24.1"
+ babel-plugin-syntax-class-properties "^6.8.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-plugin-transform-decorators@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d"
+ dependencies:
+ babel-helper-explode-class "^6.24.1"
+ babel-plugin-syntax-decorators "^6.13.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-arrow-functions@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-block-scoped-functions@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-block-scoping@^6.24.1:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f"
+ dependencies:
+ babel-runtime "^6.26.0"
+ babel-template "^6.26.0"
+ babel-traverse "^6.26.0"
+ babel-types "^6.26.0"
+ lodash "^4.17.4"
+
+babel-plugin-transform-es2015-classes@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db"
+ dependencies:
+ babel-helper-define-map "^6.24.1"
+ babel-helper-function-name "^6.24.1"
+ babel-helper-optimise-call-expression "^6.24.1"
+ babel-helper-replace-supers "^6.24.1"
+ babel-messages "^6.23.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-computed-properties@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-destructuring@^6.22.0:
+ version "6.23.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-duplicate-keys@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-for-of@^6.22.0:
+ version "6.23.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-function-name@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b"
+ dependencies:
+ babel-helper-function-name "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-literals@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-modules-amd@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154"
+ dependencies:
+ babel-plugin-transform-es2015-modules-commonjs "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a"
+ dependencies:
+ babel-plugin-transform-strict-mode "^6.24.1"
+ babel-runtime "^6.26.0"
+ babel-template "^6.26.0"
+ babel-types "^6.26.0"
+
+babel-plugin-transform-es2015-modules-systemjs@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23"
+ dependencies:
+ babel-helper-hoist-variables "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-modules-umd@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468"
+ dependencies:
+ babel-plugin-transform-es2015-modules-amd "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-object-super@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d"
+ dependencies:
+ babel-helper-replace-supers "^6.24.1"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-parameters@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b"
+ dependencies:
+ babel-helper-call-delegate "^6.24.1"
+ babel-helper-get-function-arity "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-shorthand-properties@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-spread@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-sticky-regex@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc"
+ dependencies:
+ babel-helper-regex "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-template-literals@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-typeof-symbol@^6.22.0:
+ version "6.23.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372"
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-unicode-regex@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9"
+ dependencies:
+ babel-helper-regex "^6.24.1"
+ babel-runtime "^6.22.0"
+ regexpu-core "^2.0.0"
+
+babel-plugin-transform-exponentiation-operator@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e"
+ dependencies:
+ babel-helper-builder-binary-assignment-operator-visitor "^6.24.1"
+ babel-plugin-syntax-exponentiation-operator "^6.8.0"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-export-extensions@^6.22.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653"
+ dependencies:
+ babel-plugin-syntax-export-extensions "^6.8.0"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-flow-strip-types@^6.8.0:
+ version "6.22.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
+ dependencies:
+ babel-plugin-syntax-flow "^6.18.0"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-object-rest-spread@^6.22.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06"
+ dependencies:
+ babel-plugin-syntax-object-rest-spread "^6.8.0"
+ babel-runtime "^6.26.0"
+
+babel-plugin-transform-regenerator@^6.24.1:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f"
+ dependencies:
+ regenerator-transform "^0.10.0"
+
+babel-plugin-transform-strict-mode@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-preset-es2015@^6.9.0:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
+ dependencies:
+ babel-plugin-check-es2015-constants "^6.22.0"
+ babel-plugin-transform-es2015-arrow-functions "^6.22.0"
+ babel-plugin-transform-es2015-block-scoped-functions "^6.22.0"
+ babel-plugin-transform-es2015-block-scoping "^6.24.1"
+ babel-plugin-transform-es2015-classes "^6.24.1"
+ babel-plugin-transform-es2015-computed-properties "^6.24.1"
+ babel-plugin-transform-es2015-destructuring "^6.22.0"
+ babel-plugin-transform-es2015-duplicate-keys "^6.24.1"
+ babel-plugin-transform-es2015-for-of "^6.22.0"
+ babel-plugin-transform-es2015-function-name "^6.24.1"
+ babel-plugin-transform-es2015-literals "^6.22.0"
+ babel-plugin-transform-es2015-modules-amd "^6.24.1"
+ babel-plugin-transform-es2015-modules-commonjs "^6.24.1"
+ babel-plugin-transform-es2015-modules-systemjs "^6.24.1"
+ babel-plugin-transform-es2015-modules-umd "^6.24.1"
+ babel-plugin-transform-es2015-object-super "^6.24.1"
+ babel-plugin-transform-es2015-parameters "^6.24.1"
+ babel-plugin-transform-es2015-shorthand-properties "^6.24.1"
+ babel-plugin-transform-es2015-spread "^6.22.0"
+ babel-plugin-transform-es2015-sticky-regex "^6.24.1"
+ babel-plugin-transform-es2015-template-literals "^6.22.0"
+ babel-plugin-transform-es2015-typeof-symbol "^6.22.0"
+ babel-plugin-transform-es2015-unicode-regex "^6.24.1"
+ babel-plugin-transform-regenerator "^6.24.1"
+
+babel-preset-stage-1@^6.5.0:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0"
+ dependencies:
+ babel-plugin-transform-class-constructor-call "^6.24.1"
+ babel-plugin-transform-export-extensions "^6.22.0"
+ babel-preset-stage-2 "^6.24.1"
+
+babel-preset-stage-2@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1"
+ dependencies:
+ babel-plugin-syntax-dynamic-import "^6.18.0"
+ babel-plugin-transform-class-properties "^6.24.1"
+ babel-plugin-transform-decorators "^6.24.1"
+ babel-preset-stage-3 "^6.24.1"
+
+babel-preset-stage-3@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395"
+ dependencies:
+ babel-plugin-syntax-trailing-function-commas "^6.22.0"
+ babel-plugin-transform-async-generator-functions "^6.24.1"
+ babel-plugin-transform-async-to-generator "^6.24.1"
+ babel-plugin-transform-exponentiation-operator "^6.24.1"
+ babel-plugin-transform-object-rest-spread "^6.22.0"
+
+babel-register@^6.26.0, babel-register@^6.9.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
+ dependencies:
+ babel-core "^6.26.0"
+ babel-runtime "^6.26.0"
+ core-js "^2.5.0"
+ home-or-tmp "^2.0.0"
+ lodash "^4.17.4"
+ mkdirp "^0.5.1"
+ source-map-support "^0.4.15"
+
+babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
+ dependencies:
+ core-js "^2.4.0"
+ regenerator-runtime "^0.11.0"
+
+babel-template@^6.24.1, babel-template@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
+ dependencies:
+ babel-runtime "^6.26.0"
+ babel-traverse "^6.26.0"
+ babel-types "^6.26.0"
+ babylon "^6.18.0"
+ lodash "^4.17.4"
+
+babel-traverse@^6.24.1, babel-traverse@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
+ dependencies:
+ babel-code-frame "^6.26.0"
+ babel-messages "^6.23.0"
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ babylon "^6.18.0"
+ debug "^2.6.8"
+ globals "^9.18.0"
+ invariant "^2.2.2"
+ lodash "^4.17.4"
+
+babel-types@7.0.0-beta.3:
+ version "7.0.0-beta.3"
+ resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.3.tgz#cd927ca70e0ae8ab05f4aab83778cfb3e6eb20b4"
+ dependencies:
+ esutils "^2.0.2"
+ lodash "^4.2.0"
+ to-fast-properties "^2.0.0"
+
+babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
+ dependencies:
+ babel-runtime "^6.26.0"
+ esutils "^2.0.2"
+ lodash "^4.17.4"
+ to-fast-properties "^1.0.3"
+
+babylon@7.0.0-beta.40, babylon@^7.0.0-beta.40:
+ version "7.0.0-beta.40"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.40.tgz#91fc8cd56d5eb98b28e6fde41045f2957779940a"
+
+babylon@^6.17.3, babylon@^6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
+
+balanced-match@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
+
+base64-js@^1.0.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.3.tgz#fb13668233d9614cf5fb4bce95a9ba4096cdf801"
+
+base@^0.11.1:
+ version "0.11.2"
+ resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
+ dependencies:
+ cache-base "^1.0.1"
+ class-utils "^0.3.5"
+ component-emitter "^1.2.1"
+ define-property "^1.0.0"
+ isobject "^3.0.1"
+ mixin-deep "^1.2.0"
+ pascalcase "^0.1.1"
+
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
+ dependencies:
+ tweetnacl "^0.14.3"
+
+bfj-node4@^5.2.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/bfj-node4/-/bfj-node4-5.2.1.tgz#3a6aa2730cf6911ba2afb836c2f88f015d718f3f"
+ dependencies:
+ bluebird "^3.5.1"
+ check-types "^7.3.0"
+ tryer "^1.0.0"
+
+big.js@^3.1.3:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
+
+binary-extensions@^1.0.0:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
+
+binaryextensions@2:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935"
+
+block-stream@*:
+ version "0.0.9"
+ resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
+ dependencies:
+ inherits "~2.0.0"
+
+bluebird@^3.5.1:
+ version "3.5.1"
+ resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
+
+bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
+ version "4.11.8"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
+
+body-parser@1.18.2:
+ version "1.18.2"
+ resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454"
+ dependencies:
+ bytes "3.0.0"
+ content-type "~1.0.4"
+ debug "2.6.9"
+ depd "~1.1.1"
+ http-errors "~1.6.2"
+ iconv-lite "0.4.19"
+ on-finished "~2.3.0"
+ qs "6.5.1"
+ raw-body "2.3.2"
+ type-is "~1.6.15"
+
+boom@2.x.x:
+ version "2.10.1"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
+ dependencies:
+ hoek "2.x.x"
+
+bootstrap-sass@^3.3:
+ version "3.3.7"
+ resolved "https://registry.yarnpkg.com/bootstrap-sass/-/bootstrap-sass-3.3.7.tgz#6596c7ab40f6637393323ab0bc80d064fc630498"
+
+brace-expansion@^1.1.7:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
+braces@^1.8.2:
+ version "1.8.5"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
+ dependencies:
+ expand-range "^1.8.1"
+ preserve "^0.2.0"
+ repeat-element "^1.1.2"
+
+braces@^2.3.0, braces@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb"
+ dependencies:
+ arr-flatten "^1.1.0"
+ array-unique "^0.3.2"
+ define-property "^1.0.0"
+ extend-shallow "^2.0.1"
+ fill-range "^4.0.0"
+ isobject "^3.0.1"
+ kind-of "^6.0.2"
+ repeat-element "^1.1.2"
+ snapdragon "^0.8.1"
+ snapdragon-node "^2.0.1"
+ split-string "^3.0.2"
+ to-regex "^3.0.1"
+
+brorand@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
+
+browserify-aes@^1.0.0, browserify-aes@^1.0.4:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f"
+ dependencies:
+ buffer-xor "^1.0.3"
+ cipher-base "^1.0.0"
+ create-hash "^1.1.0"
+ evp_bytestokey "^1.0.3"
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+browserify-cipher@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a"
+ dependencies:
+ browserify-aes "^1.0.4"
+ browserify-des "^1.0.0"
+ evp_bytestokey "^1.0.0"
+
+browserify-des@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd"
+ dependencies:
+ cipher-base "^1.0.1"
+ des.js "^1.0.0"
+ inherits "^2.0.1"
+
+browserify-rsa@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524"
+ dependencies:
+ bn.js "^4.1.0"
+ randombytes "^2.0.1"
+
+browserify-sign@^4.0.0:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298"
+ dependencies:
+ bn.js "^4.1.1"
+ browserify-rsa "^4.0.0"
+ create-hash "^1.1.0"
+ create-hmac "^1.1.2"
+ elliptic "^6.0.0"
+ inherits "^2.0.1"
+ parse-asn1 "^5.0.0"
+
+browserify-zlib@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
+ dependencies:
+ pako "~1.0.5"
+
+browserslist@^3.0.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.1.1.tgz#d380fc048bc3a33e60fb87dc135110ebaaa6320a"
+ dependencies:
+ caniuse-lite "^1.0.30000809"
+ electron-to-chromium "^1.3.33"
+
+buffer-xor@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
+
+buffer@^4.3.0:
+ version "4.9.1"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
+ dependencies:
+ base64-js "^1.0.2"
+ ieee754 "^1.1.4"
+ isarray "^1.0.0"
+
+builtin-modules@^1.0.0, builtin-modules@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
+
+builtin-status-codes@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
+
+bytes@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+
+cacache@^10.0.1:
+ version "10.0.4"
+ resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460"
+ dependencies:
+ bluebird "^3.5.1"
+ chownr "^1.0.1"
+ glob "^7.1.2"
+ graceful-fs "^4.1.11"
+ lru-cache "^4.1.1"
+ mississippi "^2.0.0"
+ mkdirp "^0.5.1"
+ move-concurrently "^1.0.1"
+ promise-inflight "^1.0.1"
+ rimraf "^2.6.2"
+ ssri "^5.2.4"
+ unique-filename "^1.1.0"
+ y18n "^4.0.0"
+
+cache-base@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
+ dependencies:
+ collection-visit "^1.0.0"
+ component-emitter "^1.2.1"
+ get-value "^2.0.6"
+ has-value "^1.0.0"
+ isobject "^3.0.1"
+ set-value "^2.0.0"
+ to-object-path "^0.3.0"
+ union-value "^1.0.0"
+ unset-value "^1.0.0"
+
+caller-path@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
+ dependencies:
+ callsites "^0.2.0"
+
+callsites@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
+
+camelcase@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
+
+caniuse-lite@^1.0.30000809:
+ version "1.0.30000810"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz#47585fffce0e9f3593a6feea4673b945424351d9"
+
+caseless@~0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+
+chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
+ dependencies:
+ ansi-styles "^3.2.0"
+ escape-string-regexp "^1.0.5"
+ supports-color "^5.2.0"
+
+chalk@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
+ dependencies:
+ ansi-styles "~1.0.0"
+ has-color "~0.1.0"
+ strip-ansi "~0.1.0"
+
+chardet@^0.4.0:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
+
+check-types@^7.3.0:
+ version "7.3.0"
+ resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.3.0.tgz#468f571a4435c24248f5fd0cb0e8d87c3c341e7d"
+
+chokidar@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7"
+ dependencies:
+ anymatch "^2.0.0"
+ async-each "^1.0.0"
+ braces "^2.3.0"
+ glob-parent "^3.1.0"
+ inherits "^2.0.1"
+ is-binary-path "^1.0.0"
+ is-glob "^4.0.0"
+ normalize-path "^2.1.1"
+ path-is-absolute "^1.0.0"
+ readdirp "^2.0.0"
+ upath "^1.0.0"
+ optionalDependencies:
+ fsevents "^1.0.0"
+
+chownr@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
+
+chrome-trace-event@^0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-0.1.2.tgz#90f36885d5345a50621332f0717b595883d5d982"
+
+cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+circular-json@^0.3.1:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
+
+class-utils@^0.3.5:
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
+ dependencies:
+ arr-union "^3.1.0"
+ define-property "^0.2.5"
+ isobject "^3.0.0"
+ static-extend "^0.1.1"
+
+clean-webpack-plugin@^0.1.18:
+ version "0.1.18"
+ resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.18.tgz#2e2173897c76646031bff047c14b9c22c80d8c4a"
+ dependencies:
+ rimraf "^2.6.1"
+
+cli-cursor@^1.0.1, cli-cursor@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
+ dependencies:
+ restore-cursor "^1.0.1"
+
+cli-cursor@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
+ dependencies:
+ restore-cursor "^2.0.0"
+
+cli-spinners@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
+
+cli-table@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
+ dependencies:
+ colors "1.0.3"
+
+cli-truncate@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
+ dependencies:
+ slice-ansi "0.0.4"
+ string-width "^1.0.1"
+
+cli-width@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
+
+cliui@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
+ dependencies:
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+ wrap-ansi "^2.0.0"
+
+clone-buffer@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
+
+clone-stats@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1"
+
+clone-stats@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680"
+
+clone@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f"
+
+clone@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb"
+
+cloneable-readable@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117"
+ dependencies:
+ inherits "^2.0.1"
+ process-nextick-args "^1.0.6"
+ through2 "^2.0.1"
+
+co@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+
+code-point-at@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+
+codecov@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.0.0.tgz#c273b8c4f12945723e8dc9d25803d89343e5f28e"
+ dependencies:
+ argv "0.0.2"
+ request "2.81.0"
+ urlgrey "0.4.4"
+
+collection-visit@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
+ dependencies:
+ map-visit "^1.0.0"
+ object-visit "^1.0.0"
+
+color-convert@^1.9.0:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
+ dependencies:
+ color-name "^1.1.1"
+
+color-name@^1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+
+colors@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
+
+colors@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
+
+combined-stream@^1.0.5, combined-stream@~1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
+ dependencies:
+ delayed-stream "~1.0.0"
+
+commander@^2.13.0:
+ version "2.14.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
+
+commander@~2.13.0:
+ version "2.13.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
+
+commondir@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+
+component-emitter@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.6.0:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.1.tgz#261b8f518301f1d834e36342b9fea095d2620a26"
+ dependencies:
+ inherits "^2.0.3"
+ readable-stream "^2.2.2"
+ typedarray "^0.0.6"
+
+console-browserify@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
+ dependencies:
+ date-now "^0.1.4"
+
+console-control-strings@^1.0.0, console-control-strings@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
+
+constants-browserify@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
+
+contains-path@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
+
+content-disposition@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
+
+content-type@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
+
+convert-source-map@^1.1.0, convert-source-map@^1.5.0:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
+
+cookie-signature@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
+
+cookie@0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
+
+copy-concurrently@^1.0.0:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
+ dependencies:
+ aproba "^1.1.1"
+ fs-write-stream-atomic "^1.0.8"
+ iferr "^0.1.5"
+ mkdirp "^0.5.1"
+ rimraf "^2.5.4"
+ run-queue "^1.0.0"
+
+copy-descriptor@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
+
+core-js@^1.0.0:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
+
+core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0:
+ version "2.5.3"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
+
+core-util-is@1.0.2, core-util-is@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+
+create-ecdh@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d"
+ dependencies:
+ bn.js "^4.1.0"
+ elliptic "^6.0.0"
+
+create-hash@^1.1.0, create-hash@^1.1.2:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd"
+ dependencies:
+ cipher-base "^1.0.1"
+ inherits "^2.0.1"
+ ripemd160 "^2.0.0"
+ sha.js "^2.4.0"
+
+create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06"
+ dependencies:
+ cipher-base "^1.0.3"
+ create-hash "^1.1.0"
+ inherits "^2.0.1"
+ ripemd160 "^2.0.0"
+ safe-buffer "^5.0.1"
+ sha.js "^2.4.8"
+
+cross-spawn@^5.0.1, cross-spawn@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
+ dependencies:
+ lru-cache "^4.0.1"
+ shebang-command "^1.2.0"
+ which "^1.2.9"
+
+cryptiles@2.x.x:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
+ dependencies:
+ boom "2.x.x"
+
+crypto-browserify@^3.11.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
+ dependencies:
+ browserify-cipher "^1.0.0"
+ browserify-sign "^4.0.0"
+ create-ecdh "^4.0.0"
+ create-hash "^1.1.0"
+ create-hmac "^1.1.0"
+ diffie-hellman "^5.0.0"
+ inherits "^2.0.1"
+ pbkdf2 "^3.0.3"
+ public-encrypt "^4.0.0"
+ randombytes "^2.0.0"
+ randomfill "^1.0.3"
+
+cyclist@~0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
+
+dargs@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/dargs/-/dargs-5.1.0.tgz#ec7ea50c78564cd36c9d5ec18f66329fade27829"
+
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ dependencies:
+ assert-plus "^1.0.0"
+
+date-fns@^1.27.2:
+ version "1.29.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
+
+date-now@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
+
+dateformat@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062"
+
+debug@2.6.9, debug@^2.0.0, debug@^2.1.0, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
+ version "2.6.9"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
+ dependencies:
+ ms "2.0.0"
+
+debug@^3.0.1, debug@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
+ dependencies:
+ ms "2.0.0"
+
+decamelize@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+
+decode-uri-component@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
+
+decompress-response@^3.2.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
+ dependencies:
+ mimic-response "^1.0.0"
+
+deep-extend@^0.4.0, deep-extend@~0.4.0:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
+
+deep-is@~0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
+
+define-properties@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
+ dependencies:
+ foreach "^2.0.5"
+ object-keys "^1.0.8"
+
+define-property@^0.2.5:
+ version "0.2.5"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
+ dependencies:
+ is-descriptor "^0.1.0"
+
+define-property@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6"
+ dependencies:
+ is-descriptor "^1.0.0"
+
+define-property@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d"
+ dependencies:
+ is-descriptor "^1.0.2"
+ isobject "^3.0.1"
+
+del@^2.0.2:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
+ dependencies:
+ globby "^5.0.0"
+ is-path-cwd "^1.0.0"
+ is-path-in-cwd "^1.0.0"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+ rimraf "^2.2.8"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+
+delegates@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
+
+depd@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
+
+depd@~1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
+
+des.js@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc"
+ dependencies:
+ inherits "^2.0.1"
+ minimalistic-assert "^1.0.0"
+
+destroy@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
+
+detect-conflict@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e"
+
+detect-indent@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
+ dependencies:
+ repeating "^2.0.0"
+
+detect-libc@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
+
+diff@^2.1.2:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99"
+
+diff@^3.3.0, diff@^3.3.1:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
+
+diffie-hellman@^5.0.0:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e"
+ dependencies:
+ bn.js "^4.1.0"
+ miller-rabin "^4.0.0"
+ randombytes "^2.0.0"
+
+doctrine@1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
+ dependencies:
+ esutils "^2.0.2"
+ isarray "^1.0.0"
+
+doctrine@^2.0.2, doctrine@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
+ dependencies:
+ esutils "^2.0.2"
+
+dom-walk@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
+
+domain-browser@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
+
+duplexer3@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
+
+duplexer@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
+
+duplexify@^3.4.2, duplexify@^3.5.3:
+ version "3.5.3"
+ resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e"
+ dependencies:
+ end-of-stream "^1.0.0"
+ inherits "^2.0.1"
+ readable-stream "^2.0.0"
+ stream-shift "^1.0.0"
+
+ecc-jsbn@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+ dependencies:
+ jsbn "~0.1.0"
+
+editions@^1.3.3:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b"
+
+ee-first@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
+
+ejs@^2.3.1, ejs@^2.5.7:
+ version "2.5.7"
+ resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a"
+
+electron-to-chromium@^1.3.33:
+ version "1.3.34"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz#d93498f40391bb0c16a603d8241b9951404157ed"
+
+elegant-spinner@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
+
+elliptic@^6.0.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
+ dependencies:
+ bn.js "^4.4.0"
+ brorand "^1.0.1"
+ hash.js "^1.0.0"
+ hmac-drbg "^1.0.0"
+ inherits "^2.0.1"
+ minimalistic-assert "^1.0.0"
+ minimalistic-crypto-utils "^1.0.0"
+
+emojis-list@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
+
+encodeurl@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
+
+encoding@^0.1.11:
+ version "0.1.12"
+ resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
+ dependencies:
+ iconv-lite "~0.4.13"
+
+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"
+ dependencies:
+ once "^1.4.0"
+
+enhanced-resolve@^3.4.1:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e"
+ dependencies:
+ graceful-fs "^4.1.2"
+ memory-fs "^0.4.0"
+ object-assign "^4.0.1"
+ tapable "^0.2.7"
+
+enhanced-resolve@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a"
+ dependencies:
+ graceful-fs "^4.1.2"
+ memory-fs "^0.4.0"
+ tapable "^1.0.0"
+
+errno@^0.1.3, errno@~0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
+ dependencies:
+ prr "~1.0.1"
+
+error-ex@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
+ dependencies:
+ is-arrayish "^0.2.1"
+
+error@^7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02"
+ dependencies:
+ string-template "~0.2.1"
+ xtend "~4.0.0"
+
+es-abstract@^1.7.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
+ dependencies:
+ es-to-primitive "^1.1.1"
+ function-bind "^1.1.1"
+ has "^1.0.1"
+ is-callable "^1.1.3"
+ is-regex "^1.0.4"
+
+es-to-primitive@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
+ dependencies:
+ is-callable "^1.1.1"
+ is-date-object "^1.0.1"
+ is-symbol "^1.0.1"
+
+escape-html@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
+
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+eslint-import-resolver-node@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a"
+ dependencies:
+ debug "^2.6.9"
+ resolve "^1.5.0"
+
+eslint-module-utils@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449"
+ dependencies:
+ debug "^2.6.8"
+ pkg-dir "^1.0.0"
+
+eslint-plugin-babel@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-4.1.2.tgz#79202a0e35757dd92780919b2336f1fa2fe53c1e"
+
+eslint-plugin-import@^2.9.0:
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.9.0.tgz#26002efbfca5989b7288ac047508bd24f217b169"
+ dependencies:
+ builtin-modules "^1.1.1"
+ contains-path "^0.1.0"
+ debug "^2.6.8"
+ doctrine "1.5.0"
+ eslint-import-resolver-node "^0.3.1"
+ eslint-module-utils "^2.1.1"
+ has "^1.0.1"
+ lodash "^4.17.4"
+ minimatch "^3.0.3"
+ read-pkg-up "^2.0.0"
+
+eslint-plugin-react@^7.7.0:
+ version "7.7.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz#f606c719dbd8a1a2b3d25c16299813878cca0160"
+ dependencies:
+ doctrine "^2.0.2"
+ has "^1.0.1"
+ jsx-ast-utils "^2.0.1"
+ prop-types "^15.6.0"
+
+eslint-scope@^3.7.1, eslint-scope@~3.7.1:
+ version "3.7.1"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
+ dependencies:
+ esrecurse "^4.1.0"
+ estraverse "^4.1.1"
+
+eslint-visitor-keys@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
+
+eslint@^4.18.1:
+ version "4.18.1"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.18.1.tgz#b9138440cb1e98b2f44a0d578c6ecf8eae6150b0"
+ dependencies:
+ ajv "^5.3.0"
+ babel-code-frame "^6.22.0"
+ chalk "^2.1.0"
+ concat-stream "^1.6.0"
+ cross-spawn "^5.1.0"
+ debug "^3.1.0"
+ doctrine "^2.1.0"
+ eslint-scope "^3.7.1"
+ eslint-visitor-keys "^1.0.0"
+ espree "^3.5.2"
+ esquery "^1.0.0"
+ esutils "^2.0.2"
+ file-entry-cache "^2.0.0"
+ functional-red-black-tree "^1.0.1"
+ glob "^7.1.2"
+ globals "^11.0.1"
+ ignore "^3.3.3"
+ imurmurhash "^0.1.4"
+ inquirer "^3.0.6"
+ is-resolvable "^1.0.0"
+ js-yaml "^3.9.1"
+ json-stable-stringify-without-jsonify "^1.0.1"
+ levn "^0.3.0"
+ lodash "^4.17.4"
+ minimatch "^3.0.2"
+ mkdirp "^0.5.1"
+ natural-compare "^1.4.0"
+ optionator "^0.8.2"
+ path-is-inside "^1.0.2"
+ pluralize "^7.0.0"
+ progress "^2.0.0"
+ require-uncached "^1.0.3"
+ semver "^5.3.0"
+ strip-ansi "^4.0.0"
+ strip-json-comments "~2.0.1"
+ table "^4.0.1"
+ text-table "~0.2.0"
+
+espree@^3.5.2:
+ version "3.5.3"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.3.tgz#931e0af64e7fbbed26b050a29daad1fc64799fa6"
+ dependencies:
+ acorn "^5.4.0"
+ acorn-jsx "^3.0.0"
+
+esprima@^4.0.0, esprima@~4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
+
+esquery@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa"
+ dependencies:
+ estraverse "^4.0.0"
+
+esrecurse@^4.1.0:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
+ dependencies:
+ estraverse "^4.1.0"
+
+estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
+
+esutils@^2.0.0, esutils@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+
+etag@~1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
+
+events@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
+
+evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
+ dependencies:
+ md5.js "^1.3.4"
+ safe-buffer "^5.1.1"
+
+execa@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
+ dependencies:
+ cross-spawn "^5.0.1"
+ get-stream "^3.0.0"
+ is-stream "^1.1.0"
+ npm-run-path "^2.0.0"
+ p-finally "^1.0.0"
+ signal-exit "^3.0.0"
+ strip-eof "^1.0.0"
+
+exit-hook@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
+
+expand-brackets@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
+ dependencies:
+ is-posix-bracket "^0.1.0"
+
+expand-brackets@^2.1.4:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
+ dependencies:
+ debug "^2.3.3"
+ define-property "^0.2.5"
+ extend-shallow "^2.0.1"
+ posix-character-classes "^0.1.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
+expand-range@^1.8.1:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
+ dependencies:
+ fill-range "^2.1.0"
+
+expand-tilde@^2.0.0, expand-tilde@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
+ dependencies:
+ homedir-polyfill "^1.0.1"
+
+express@^4.16.2:
+ version "4.16.2"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
+ dependencies:
+ accepts "~1.3.4"
+ array-flatten "1.1.1"
+ body-parser "1.18.2"
+ content-disposition "0.5.2"
+ content-type "~1.0.4"
+ cookie "0.3.1"
+ cookie-signature "1.0.6"
+ debug "2.6.9"
+ depd "~1.1.1"
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ finalhandler "1.1.0"
+ fresh "0.5.2"
+ merge-descriptors "1.0.1"
+ methods "~1.1.2"
+ on-finished "~2.3.0"
+ parseurl "~1.3.2"
+ path-to-regexp "0.1.7"
+ proxy-addr "~2.0.2"
+ qs "6.5.1"
+ range-parser "~1.2.0"
+ safe-buffer "5.1.1"
+ send "0.16.1"
+ serve-static "1.13.1"
+ setprototypeof "1.1.0"
+ statuses "~1.3.1"
+ type-is "~1.6.15"
+ utils-merge "1.0.1"
+ vary "~1.1.2"
+
+extend-shallow@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
+ dependencies:
+ is-extendable "^0.1.0"
+
+extend-shallow@^3.0.0, extend-shallow@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
+ dependencies:
+ assign-symbols "^1.0.0"
+ is-extendable "^1.0.1"
+
+extend@^3.0.0, extend@~3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+
+external-editor@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b"
+ dependencies:
+ extend "^3.0.0"
+ spawn-sync "^1.0.15"
+ tmp "^0.0.29"
+
+external-editor@^2.0.4:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48"
+ dependencies:
+ chardet "^0.4.0"
+ iconv-lite "^0.4.17"
+ tmp "^0.0.33"
+
+extglob@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
+ dependencies:
+ is-extglob "^1.0.0"
+
+extglob@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
+ dependencies:
+ array-unique "^0.3.2"
+ define-property "^1.0.0"
+ expand-brackets "^2.1.4"
+ extend-shallow "^2.0.1"
+ fragment-cache "^0.2.1"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
+extsprintf@1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+
+extsprintf@^1.2.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
+
+fast-deep-equal@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
+
+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"
+
+fast-levenshtein@~2.0.4:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+
+fbjs@^0.8.16:
+ version "0.8.16"
+ resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
+ dependencies:
+ core-js "^1.0.0"
+ isomorphic-fetch "^2.1.1"
+ loose-envify "^1.0.0"
+ object-assign "^4.1.0"
+ promise "^7.1.1"
+ setimmediate "^1.0.5"
+ ua-parser-js "^0.7.9"
+
+figures@^1.3.5, figures@^1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
+ dependencies:
+ escape-string-regexp "^1.0.5"
+ object-assign "^4.1.0"
+
+figures@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
+ dependencies:
+ escape-string-regexp "^1.0.5"
+
+file-entry-cache@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
+ dependencies:
+ flat-cache "^1.2.1"
+ object-assign "^4.0.1"
+
+file-saver@^1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-1.3.3.tgz#cdd4c44d3aa264eac2f68ec165bc791c34af1232"
+
+filename-regex@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
+
+filesize@^3.5.11:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.0.tgz#22d079615624bb6fd3c04026120628a41b3f4efa"
+
+fill-range@^2.1.0:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
+ dependencies:
+ is-number "^2.1.0"
+ isobject "^2.0.0"
+ randomatic "^1.1.3"
+ repeat-element "^1.1.2"
+ repeat-string "^1.5.2"
+
+fill-range@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
+ dependencies:
+ extend-shallow "^2.0.1"
+ is-number "^3.0.0"
+ repeat-string "^1.6.1"
+ to-regex-range "^2.1.0"
+
+finalhandler@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5"
+ dependencies:
+ debug "2.6.9"
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ on-finished "~2.3.0"
+ parseurl "~1.3.2"
+ statuses "~1.3.1"
+ unpipe "~1.0.0"
+
+find-cache-dir@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f"
+ dependencies:
+ commondir "^1.0.1"
+ make-dir "^1.0.0"
+ pkg-dir "^2.0.0"
+
+find-up@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
+ dependencies:
+ path-exists "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+find-up@^2.0.0, find-up@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
+ dependencies:
+ locate-path "^2.0.0"
+
+first-chunk-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70"
+ dependencies:
+ readable-stream "^2.0.2"
+
+flat-cache@^1.2.1:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
+ dependencies:
+ circular-json "^0.3.1"
+ del "^2.0.2"
+ graceful-fs "^4.1.2"
+ write "^0.2.1"
+
+flow-parser@^0.*:
+ version "0.66.0"
+ resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.66.0.tgz#be583fefb01192aa5164415d31a6241b35718983"
+
+flush-write-stream@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417"
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "^2.0.4"
+
+for-in@^1.0.1, for-in@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
+
+for-own@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce"
+ dependencies:
+ for-in "^1.0.1"
+
+foreach@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
+
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+
+form-data@~2.1.1:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.5"
+ mime-types "^2.1.12"
+
+forwarded@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
+
+fragment-cache@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
+ dependencies:
+ map-cache "^0.2.2"
+
+fresh@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
+
+from2@^2.1.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "^2.0.0"
+
+fs-write-stream-atomic@^1.0.8:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
+ dependencies:
+ graceful-fs "^4.1.2"
+ iferr "^0.1.5"
+ imurmurhash "^0.1.4"
+ readable-stream "1 || 2"
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+fsevents@^1.0.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8"
+ dependencies:
+ nan "^2.3.0"
+ node-pre-gyp "^0.6.39"
+
+fstream-ignore@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
+ dependencies:
+ fstream "^1.0.0"
+ inherits "2"
+ minimatch "^3.0.0"
+
+fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171"
+ dependencies:
+ graceful-fs "^4.1.2"
+ inherits "~2.0.0"
+ mkdirp ">=0.5 0"
+ rimraf "2"
+
+function-bind@^1.0.2, function-bind@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+
+functional-red-black-tree@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
+
+gauge@~2.7.3:
+ version "2.7.4"
+ resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
+ dependencies:
+ aproba "^1.0.3"
+ console-control-strings "^1.0.0"
+ has-unicode "^2.0.0"
+ object-assign "^4.1.0"
+ signal-exit "^3.0.0"
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+ wide-align "^1.1.0"
+
+get-caller-file@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5"
+
+get-stream@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
+
+get-value@^2.0.3, get-value@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
+
+getpass@^0.1.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+ dependencies:
+ assert-plus "^1.0.0"
+
+gh-got@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0"
+ dependencies:
+ got "^7.0.0"
+ is-plain-obj "^1.1.0"
+
+github-username@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417"
+ dependencies:
+ gh-got "^6.0.0"
+
+glob-all@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab"
+ dependencies:
+ glob "^7.0.5"
+ yargs "~1.2.6"
+
+glob-base@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
+ dependencies:
+ glob-parent "^2.0.0"
+ is-glob "^2.0.0"
+
+glob-parent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
+ dependencies:
+ is-glob "^2.0.0"
+
+glob-parent@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
+ dependencies:
+ is-glob "^3.1.0"
+ path-dirname "^1.0.0"
+
+glob@^6.0.1:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "2 || 3"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+global-modules@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
+ dependencies:
+ global-prefix "^1.0.1"
+ is-windows "^1.0.1"
+ resolve-dir "^1.0.0"
+
+global-prefix@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
+ dependencies:
+ expand-tilde "^2.0.2"
+ homedir-polyfill "^1.0.1"
+ ini "^1.3.4"
+ is-windows "^1.0.1"
+ which "^1.2.14"
+
+global@^4.3.2:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
+ dependencies:
+ min-document "^2.19.0"
+ process "~0.5.1"
+
+globals@^11.0.1, globals@^11.1.0:
+ version "11.3.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.3.0.tgz#e04fdb7b9796d8adac9c8f64c14837b2313378b0"
+
+globals@^9.18.0:
+ version "9.18.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
+
+globby@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8"
+ dependencies:
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ glob "^6.0.1"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+globby@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
+ dependencies:
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ glob "^7.0.3"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+globby@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
+ dependencies:
+ array-union "^1.0.1"
+ glob "^7.0.3"
+ object-assign "^4.0.1"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
+got@^7.0.0, got@^7.1.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
+ dependencies:
+ decompress-response "^3.2.0"
+ duplexer3 "^0.1.4"
+ get-stream "^3.0.0"
+ is-plain-obj "^1.1.0"
+ is-retry-allowed "^1.0.0"
+ is-stream "^1.0.0"
+ isurl "^1.0.0-alpha5"
+ lowercase-keys "^1.0.0"
+ p-cancelable "^0.3.0"
+ p-timeout "^1.1.1"
+ safe-buffer "^5.0.1"
+ timed-out "^4.0.0"
+ url-parse-lax "^1.0.0"
+ url-to-options "^1.0.1"
+
+graceful-fs@^4.1.11, graceful-fs@^4.1.2:
+ version "4.1.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+grouped-queue@^0.3.0, grouped-queue@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c"
+ dependencies:
+ lodash "^4.17.2"
+
+gzip-size@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c"
+ dependencies:
+ duplexer "^0.1.1"
+ pify "^3.0.0"
+
+har-schema@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+
+har-validator@~4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
+ dependencies:
+ ajv "^4.9.1"
+ har-schema "^1.0.5"
+
+has-ansi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+has-color@~0.1.0:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f"
+
+has-flag@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
+
+has-flag@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+
+has-symbol-support-x@^1.4.1:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
+
+has-to-string-tag-x@^1.2.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
+ dependencies:
+ has-symbol-support-x "^1.4.1"
+
+has-unicode@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
+
+has-value@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
+ dependencies:
+ get-value "^2.0.3"
+ has-values "^0.1.4"
+ isobject "^2.0.0"
+
+has-value@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177"
+ dependencies:
+ get-value "^2.0.6"
+ has-values "^1.0.0"
+ isobject "^3.0.0"
+
+has-values@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771"
+
+has-values@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f"
+ dependencies:
+ is-number "^3.0.0"
+ kind-of "^4.0.0"
+
+has@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
+ dependencies:
+ function-bind "^1.0.2"
+
+hash-base@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1"
+ dependencies:
+ inherits "^2.0.1"
+
+hash-base@^3.0.0:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918"
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+hash.js@^1.0.0, hash.js@^1.0.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846"
+ dependencies:
+ inherits "^2.0.3"
+ minimalistic-assert "^1.0.0"
+
+hawk@3.1.3, hawk@~3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
+ dependencies:
+ boom "2.x.x"
+ cryptiles "2.x.x"
+ hoek "2.x.x"
+ sntp "1.x.x"
+
+hmac-drbg@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
+ dependencies:
+ hash.js "^1.0.3"
+ minimalistic-assert "^1.0.0"
+ minimalistic-crypto-utils "^1.0.1"
+
+hoek@2.x.x:
+ version "2.16.3"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+
+home-or-tmp@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.1"
+
+homedir-polyfill@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc"
+ dependencies:
+ parse-passwd "^1.0.0"
+
+hosted-git-info@^2.1.4:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
+
+http-errors@1.6.2, http-errors@~1.6.2:
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
+ dependencies:
+ depd "1.1.1"
+ inherits "2.0.3"
+ setprototypeof "1.0.3"
+ statuses ">= 1.3.1 < 2"
+
+http-signature@~1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+ dependencies:
+ assert-plus "^0.2.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
+https-browserify@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
+
+iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13:
+ version "0.4.19"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
+
+ieee754@^1.1.4:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
+
+iferr@^0.1.5:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
+
+ignore@^3.3.3:
+ version "3.3.7"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021"
+
+imurmurhash@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+
+indent-string@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
+ dependencies:
+ repeating "^2.0.0"
+
+indent-string@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
+
+indexof@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+inherits@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+
+ini@^1.3.4, ini@~1.3.0:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
+
+inquirer@^1.0.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.2.3.tgz#4dec6f32f37ef7bb0b2ed3f1d1a5c3f545074918"
+ dependencies:
+ ansi-escapes "^1.1.0"
+ chalk "^1.0.0"
+ cli-cursor "^1.0.1"
+ cli-width "^2.0.0"
+ external-editor "^1.1.0"
+ figures "^1.3.5"
+ lodash "^4.3.0"
+ mute-stream "0.0.6"
+ pinkie-promise "^2.0.0"
+ run-async "^2.2.0"
+ rx "^4.1.0"
+ string-width "^1.0.1"
+ strip-ansi "^3.0.0"
+ through "^2.3.6"
+
+inquirer@^3.0.6, inquirer@^3.2.0, inquirer@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
+ dependencies:
+ ansi-escapes "^3.0.0"
+ chalk "^2.0.0"
+ cli-cursor "^2.1.0"
+ cli-width "^2.0.0"
+ external-editor "^2.0.4"
+ figures "^2.0.0"
+ lodash "^4.3.0"
+ mute-stream "0.0.7"
+ run-async "^2.2.0"
+ rx-lite "^4.0.8"
+ rx-lite-aggregates "^4.0.8"
+ string-width "^2.1.0"
+ strip-ansi "^4.0.0"
+ through "^2.3.6"
+
+interpret@^1.0.0, interpret@^1.0.4:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
+
+invariant@^2.2.0, invariant@^2.2.2:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688"
+ dependencies:
+ loose-envify "^1.0.0"
+
+invert-kv@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
+
+ipaddr.js@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b"
+
+is-accessor-descriptor@^0.1.6:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-accessor-descriptor@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656"
+ dependencies:
+ kind-of "^6.0.0"
+
+is-arrayish@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+
+is-binary-path@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
+ dependencies:
+ binary-extensions "^1.0.0"
+
+is-buffer@^1.1.5:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
+
+is-builtin-module@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
+ dependencies:
+ builtin-modules "^1.0.0"
+
+is-callable@^1.1.1, is-callable@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
+
+is-data-descriptor@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-data-descriptor@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7"
+ dependencies:
+ kind-of "^6.0.0"
+
+is-date-object@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
+
+is-descriptor@^0.1.0:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
+ dependencies:
+ is-accessor-descriptor "^0.1.6"
+ is-data-descriptor "^0.1.4"
+ kind-of "^5.0.0"
+
+is-descriptor@^1.0.0, is-descriptor@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec"
+ dependencies:
+ is-accessor-descriptor "^1.0.0"
+ is-data-descriptor "^1.0.0"
+ kind-of "^6.0.2"
+
+is-dotfile@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
+
+is-equal-shallow@^0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
+ dependencies:
+ is-primitive "^2.0.0"
+
+is-extendable@^0.1.0, is-extendable@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
+
+is-extendable@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4"
+ dependencies:
+ is-plain-object "^2.0.4"
+
+is-extglob@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
+
+is-extglob@^2.1.0, is-extglob@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+
+is-finite@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+ dependencies:
+ number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
+
+is-glob@^2.0.0, is-glob@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
+ dependencies:
+ is-extglob "^1.0.0"
+
+is-glob@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
+ dependencies:
+ is-extglob "^2.1.0"
+
+is-glob@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0"
+ dependencies:
+ is-extglob "^2.1.1"
+
+is-number@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-number@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
+ dependencies:
+ kind-of "^3.0.2"
+
+is-number@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
+
+is-object@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
+
+is-odd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24"
+ dependencies:
+ is-number "^4.0.0"
+
+is-path-cwd@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
+
+is-path-in-cwd@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc"
+ dependencies:
+ is-path-inside "^1.0.0"
+
+is-path-inside@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
+ dependencies:
+ path-is-inside "^1.0.1"
+
+is-plain-obj@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
+
+is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
+ dependencies:
+ isobject "^3.0.1"
+
+is-posix-bracket@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
+
+is-primitive@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
+
+is-promise@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
+
+is-regex@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
+ dependencies:
+ has "^1.0.1"
+
+is-resolvable@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
+
+is-retry-allowed@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
+
+is-scoped@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-scoped/-/is-scoped-1.0.0.tgz#449ca98299e713038256289ecb2b540dc437cb30"
+ dependencies:
+ scoped-regex "^1.0.0"
+
+is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+is-symbol@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
+
+is-typedarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+
+is-utf8@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
+
+is-windows@^1.0.1, is-windows@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
+
+isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+
+isobject@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
+ dependencies:
+ isarray "1.0.0"
+
+isobject@^3.0.0, isobject@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
+
+isomorphic-fetch@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+ dependencies:
+ node-fetch "^1.0.1"
+ whatwg-fetch ">=0.10.0"
+
+isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+
+istextorbinary@^2.1.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.2.1.tgz#a5231a08ef6dd22b268d0895084cf8d58b5bec53"
+ dependencies:
+ binaryextensions "2"
+ editions "^1.3.3"
+ textextensions "2"
+
+isurl@^1.0.0-alpha5:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
+ dependencies:
+ has-to-string-tag-x "^1.2.0"
+ is-object "^1.0.1"
+
+jquery@^1.12.4:
+ version "1.12.4"
+ resolved "https://registry.yarnpkg.com/jquery/-/jquery-1.12.4.tgz#01e1dfba290fe73deba77ceeacb0f9ba2fec9e0c"
+
+js-tokens@^3.0.0, js-tokens@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
+
+js-yaml@^3.9.1:
+ version "3.10.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^4.0.0"
+
+jsbn@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+
+jscodeshift@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.4.1.tgz#da91a1c2eccfa03a3387a21d39948e251ced444a"
+ dependencies:
+ async "^1.5.0"
+ babel-plugin-transform-flow-strip-types "^6.8.0"
+ babel-preset-es2015 "^6.9.0"
+ babel-preset-stage-1 "^6.5.0"
+ babel-register "^6.9.0"
+ babylon "^6.17.3"
+ colors "^1.1.2"
+ flow-parser "^0.*"
+ lodash "^4.13.1"
+ micromatch "^2.3.7"
+ node-dir "0.1.8"
+ nomnom "^1.8.1"
+ recast "^0.12.5"
+ temp "^0.8.1"
+ write-file-atomic "^1.2.0"
+
+jsesc@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
+
+jsesc@^2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe"
+
+jsesc@~0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
+
+json-schema-traverse@^0.3.0:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
+
+json-schema@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+
+json-stable-stringify-without-jsonify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
+
+json-stable-stringify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
+ dependencies:
+ jsonify "~0.0.0"
+
+json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+
+json5@^0.5.0, json5@^0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
+
+jsonify@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+jsprim@^1.2.2:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
+ dependencies:
+ assert-plus "1.0.0"
+ extsprintf "1.3.0"
+ json-schema "0.2.3"
+ verror "1.10.0"
+
+jsx-ast-utils@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f"
+ dependencies:
+ array-includes "^3.0.3"
+
+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
+ dependencies:
+ is-buffer "^1.1.5"
+
+kind-of@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
+ dependencies:
+ is-buffer "^1.1.5"
+
+kind-of@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
+
+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"
+
+lazy-cache@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264"
+ dependencies:
+ set-getter "^0.1.0"
+
+lcid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
+ dependencies:
+ invert-kv "^1.0.0"
+
+levn@^0.3.0, levn@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
+ dependencies:
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+
+listr-silent-renderer@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
+
+listr-update-renderer@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9"
+ dependencies:
+ chalk "^1.1.3"
+ cli-truncate "^0.2.1"
+ elegant-spinner "^1.0.1"
+ figures "^1.7.0"
+ indent-string "^3.0.0"
+ log-symbols "^1.0.2"
+ log-update "^1.0.2"
+ strip-ansi "^3.0.1"
+
+listr-verbose-renderer@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35"
+ dependencies:
+ chalk "^1.1.3"
+ cli-cursor "^1.0.2"
+ date-fns "^1.27.2"
+ figures "^1.7.0"
+
+listr@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a"
+ dependencies:
+ chalk "^1.1.3"
+ cli-truncate "^0.2.1"
+ figures "^1.7.0"
+ indent-string "^2.1.0"
+ is-promise "^2.1.0"
+ is-stream "^1.1.0"
+ listr-silent-renderer "^1.1.1"
+ listr-update-renderer "^0.2.0"
+ listr-verbose-renderer "^0.4.0"
+ log-symbols "^1.0.2"
+ log-update "^1.0.2"
+ ora "^0.2.3"
+ p-map "^1.1.1"
+ rxjs "^5.0.0-beta.11"
+ stream-to-observable "^0.1.0"
+ strip-ansi "^3.0.1"
+
+load-json-file@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^2.2.0"
+ pify "^2.0.0"
+ strip-bom "^3.0.0"
+
+loader-runner@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
+
+loader-utils@^1.0.2, loader-utils@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
+ dependencies:
+ big.js "^3.1.3"
+ emojis-list "^2.0.0"
+ json5 "^0.5.0"
+
+locate-path@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
+ dependencies:
+ p-locate "^2.0.0"
+ path-exists "^3.0.0"
+
+lodash-webpack-plugin@^0.11.4:
+ version "0.11.4"
+ resolved "https://registry.yarnpkg.com/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.4.tgz#6c3ecba3d4b8d24b53940b63542715c5ed3c4ac5"
+ dependencies:
+ lodash "^4.17.4"
+
+lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0:
+ version "4.17.5"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
+
+log-symbols@2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6"
+ dependencies:
+ chalk "^2.0.1"
+
+log-symbols@^1.0.1, log-symbols@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
+ dependencies:
+ chalk "^1.0.0"
+
+log-symbols@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
+ dependencies:
+ chalk "^2.0.1"
+
+log-update@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
+ dependencies:
+ ansi-escapes "^1.0.0"
+ cli-cursor "^1.0.2"
+
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
+ dependencies:
+ js-tokens "^3.0.0"
+
+lowercase-keys@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
+
+lru-cache@^4.0.1, lru-cache@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
+ dependencies:
+ pseudomap "^1.0.2"
+ yallist "^2.1.2"
+
+make-dir@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.2.0.tgz#6d6a49eead4aae296c53bbf3a1a008bd6c89469b"
+ dependencies:
+ pify "^3.0.0"
+
+map-cache@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
+
+map-visit@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
+ dependencies:
+ object-visit "^1.0.0"
+
+md5.js@^1.3.4:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
+ dependencies:
+ hash-base "^3.0.0"
+ inherits "^2.0.1"
+
+media-typer@0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
+
+mem-fs-editor@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz#dd0a6eaf2bb8a6b37740067aa549eb530105af9f"
+ dependencies:
+ commondir "^1.0.1"
+ deep-extend "^0.4.0"
+ ejs "^2.3.1"
+ glob "^7.0.3"
+ globby "^6.1.0"
+ mkdirp "^0.5.0"
+ multimatch "^2.0.0"
+ rimraf "^2.2.8"
+ through2 "^2.0.0"
+ vinyl "^2.0.1"
+
+mem-fs@^1.1.0:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc"
+ dependencies:
+ through2 "^2.0.0"
+ vinyl "^1.1.0"
+ vinyl-file "^2.0.0"
+
+mem@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
+ dependencies:
+ mimic-fn "^1.0.0"
+
+memory-fs@^0.4.0, memory-fs@~0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
+ dependencies:
+ errno "^0.1.3"
+ readable-stream "^2.0.1"
+
+merge-descriptors@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
+
+methods@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
+
+micromatch@^2.3.11, micromatch@^2.3.7:
+ version "2.3.11"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
+ dependencies:
+ arr-diff "^2.0.0"
+ array-unique "^0.2.1"
+ braces "^1.8.2"
+ expand-brackets "^0.1.4"
+ extglob "^0.3.1"
+ filename-regex "^2.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.1"
+ kind-of "^3.0.2"
+ normalize-path "^2.0.1"
+ object.omit "^2.0.0"
+ parse-glob "^3.0.4"
+ regex-cache "^0.4.2"
+
+micromatch@^3.1.4, micromatch@^3.1.8:
+ version "3.1.9"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.9.tgz#15dc93175ae39e52e93087847096effc73efcf89"
+ dependencies:
+ arr-diff "^4.0.0"
+ array-unique "^0.3.2"
+ braces "^2.3.1"
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
+ extglob "^2.0.4"
+ fragment-cache "^0.2.1"
+ kind-of "^6.0.2"
+ nanomatch "^1.2.9"
+ object.pick "^1.3.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
+miller-rabin@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
+ dependencies:
+ bn.js "^4.0.0"
+ brorand "^1.0.1"
+
+mime-db@~1.33.0:
+ version "1.33.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
+
+mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.7:
+ version "2.1.18"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
+ dependencies:
+ mime-db "~1.33.0"
+
+mime@1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
+
+mimic-fn@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
+
+mimic-response@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e"
+
+min-document@^2.19.0:
+ version "2.19.0"
+ resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
+ dependencies:
+ dom-walk "^0.1.0"
+
+minimalistic-assert@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
+
+minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
+
+"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+ 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"
+
+minimist@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de"
+
+minimist@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+mississippi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f"
+ dependencies:
+ concat-stream "^1.5.0"
+ duplexify "^3.4.2"
+ end-of-stream "^1.1.0"
+ flush-write-stream "^1.0.0"
+ from2 "^2.1.0"
+ parallel-transform "^1.1.0"
+ pump "^2.0.1"
+ pumpify "^1.3.3"
+ stream-each "^1.1.0"
+ through2 "^2.0.0"
+
+mixin-deep@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe"
+ dependencies:
+ for-in "^1.0.2"
+ is-extendable "^1.0.1"
+
+"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+ dependencies:
+ minimist "0.0.8"
+
+move-concurrently@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
+ dependencies:
+ aproba "^1.1.1"
+ copy-concurrently "^1.0.0"
+ fs-write-stream-atomic "^1.0.8"
+ mkdirp "^0.5.1"
+ rimraf "^2.5.4"
+ run-queue "^1.0.3"
+
+ms@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+
+multimatch@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
+ dependencies:
+ array-differ "^1.0.0"
+ array-union "^1.0.1"
+ arrify "^1.0.0"
+ minimatch "^3.0.0"
+
+mute-stream@0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db"
+
+mute-stream@0.0.7:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
+
+nan@^2.3.0:
+ version "2.9.2"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866"
+
+nanomatch@^1.2.9:
+ version "1.2.9"
+ resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2"
+ dependencies:
+ arr-diff "^4.0.0"
+ array-unique "^0.3.2"
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
+ fragment-cache "^0.2.1"
+ is-odd "^2.0.0"
+ is-windows "^1.0.2"
+ kind-of "^6.0.2"
+ object.pick "^1.3.0"
+ regex-not "^1.0.0"
+ snapdragon "^0.8.1"
+ to-regex "^3.0.1"
+
+natural-compare@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+
+negotiator@0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
+
+neo-async@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f"
+
+node-dir@0.1.8:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d"
+
+node-fetch@^1.0.1:
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
+ dependencies:
+ encoding "^0.1.11"
+ is-stream "^1.0.1"
+
+node-libs-browser@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df"
+ dependencies:
+ assert "^1.1.1"
+ browserify-zlib "^0.2.0"
+ buffer "^4.3.0"
+ console-browserify "^1.1.0"
+ constants-browserify "^1.0.0"
+ crypto-browserify "^3.11.0"
+ domain-browser "^1.1.1"
+ events "^1.0.0"
+ https-browserify "^1.0.0"
+ os-browserify "^0.3.0"
+ path-browserify "0.0.0"
+ process "^0.11.10"
+ punycode "^1.2.4"
+ querystring-es3 "^0.2.0"
+ readable-stream "^2.3.3"
+ stream-browserify "^2.0.1"
+ stream-http "^2.7.2"
+ string_decoder "^1.0.0"
+ timers-browserify "^2.0.4"
+ tty-browserify "0.0.0"
+ url "^0.11.0"
+ util "^0.10.3"
+ vm-browserify "0.0.4"
+
+node-pre-gyp@^0.6.39:
+ version "0.6.39"
+ resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649"
+ dependencies:
+ detect-libc "^1.0.2"
+ hawk "3.1.3"
+ mkdirp "^0.5.1"
+ nopt "^4.0.1"
+ npmlog "^4.0.2"
+ rc "^1.1.7"
+ request "2.81.0"
+ rimraf "^2.6.1"
+ semver "^5.3.0"
+ tar "^2.2.1"
+ tar-pack "^3.4.0"
+
+nomnom@^1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7"
+ dependencies:
+ chalk "~0.4.0"
+ underscore "~1.6.0"
+
+nopt@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
+ dependencies:
+ abbrev "1"
+ osenv "^0.1.4"
+
+normalize-package-data@^2.3.2:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
+ dependencies:
+ hosted-git-info "^2.1.4"
+ is-builtin-module "^1.0.0"
+ semver "2 || 3 || 4 || 5"
+ validate-npm-package-license "^3.0.1"
+
+normalize-path@^2.0.1, normalize-path@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
+ dependencies:
+ remove-trailing-separator "^1.0.1"
+
+npm-run-path@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
+ dependencies:
+ path-key "^2.0.0"
+
+npmlog@^4.0.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
+ dependencies:
+ are-we-there-yet "~1.1.2"
+ console-control-strings "~1.1.0"
+ gauge "~2.7.3"
+ set-blocking "~2.0.0"
+
+number-is-nan@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+
+oauth-sign@~0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+
+object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+object-copy@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
+ dependencies:
+ copy-descriptor "^0.1.0"
+ define-property "^0.2.5"
+ kind-of "^3.0.3"
+
+object-keys@^1.0.8:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
+
+object-visit@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb"
+ dependencies:
+ isobject "^3.0.0"
+
+object.omit@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
+ dependencies:
+ for-own "^0.1.4"
+ is-extendable "^0.1.1"
+
+object.pick@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
+ dependencies:
+ isobject "^3.0.1"
+
+on-finished@~2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
+ dependencies:
+ ee-first "1.1.1"
+
+once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ dependencies:
+ wrappy "1"
+
+onetime@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
+
+onetime@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
+ dependencies:
+ mimic-fn "^1.0.0"
+
+opener@^1.4.3:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
+
+optionator@^0.8.2:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
+ dependencies:
+ deep-is "~0.1.3"
+ fast-levenshtein "~2.0.4"
+ levn "~0.3.0"
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+ wordwrap "~1.0.0"
+
+ora@^0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
+ dependencies:
+ chalk "^1.1.1"
+ cli-cursor "^1.0.2"
+ cli-spinners "^0.1.2"
+ object-assign "^4.0.1"
+
+os-browserify@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
+
+os-homedir@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+
+os-locale@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2"
+ dependencies:
+ execa "^0.7.0"
+ lcid "^1.0.0"
+ mem "^1.1.0"
+
+os-shim@^0.1.2:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917"
+
+os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+
+osenv@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.0"
+
+p-cancelable@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
+
+p-each-series@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71"
+ dependencies:
+ p-reduce "^1.0.0"
+
+p-finally@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+
+p-lazy@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-lazy/-/p-lazy-1.0.0.tgz#ec53c802f2ee3ac28f166cc82d0b2b02de27a835"
+
+p-limit@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c"
+ dependencies:
+ p-try "^1.0.0"
+
+p-locate@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
+ dependencies:
+ p-limit "^1.1.0"
+
+p-map@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
+
+p-reduce@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa"
+
+p-timeout@^1.1.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
+ dependencies:
+ p-finally "^1.0.0"
+
+p-try@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
+
+pako@~1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
+
+parallel-transform@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06"
+ dependencies:
+ cyclist "~0.2.2"
+ inherits "^2.0.3"
+ readable-stream "^2.1.5"
+
+parse-asn1@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712"
+ dependencies:
+ asn1.js "^4.0.0"
+ browserify-aes "^1.0.0"
+ create-hash "^1.1.0"
+ evp_bytestokey "^1.0.0"
+ pbkdf2 "^3.0.3"
+
+parse-glob@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
+ dependencies:
+ glob-base "^0.3.0"
+ is-dotfile "^1.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.0"
+
+parse-json@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
+ dependencies:
+ error-ex "^1.2.0"
+
+parse-passwd@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
+
+parseurl@~1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
+
+pascalcase@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
+
+path-browserify@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"
+
+path-dirname@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
+
+path-exists@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
+ 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"
+
+path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-is-inside@^1.0.1, path-is-inside@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
+
+path-key@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
+
+path-parse@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+
+path-to-regexp@0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
+
+path-type@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
+ dependencies:
+ pify "^2.0.0"
+
+pbkdf2@^3.0.3:
+ version "3.0.14"
+ resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade"
+ dependencies:
+ create-hash "^1.1.2"
+ create-hmac "^1.1.4"
+ ripemd160 "^2.0.1"
+ safe-buffer "^5.0.1"
+ sha.js "^2.4.8"
+
+performance-now@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
+
+pify@^2.0.0, pify@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+
+pify@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
+
+pinkie-promise@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+ dependencies:
+ pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+
+pkg-dir@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
+ dependencies:
+ find-up "^1.0.0"
+
+pkg-dir@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
+ dependencies:
+ find-up "^2.1.0"
+
+pluralize@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
+
+posix-character-classes@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
+
+prelude-ls@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+
+prepend-http@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
+
+preserve@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+
+prettier@^1.5.3:
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75"
+
+pretty-bytes@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
+
+private@^0.1.6, private@^0.1.7, private@~0.1.5:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
+
+process-nextick-args@^1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+
+process-nextick-args@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
+
+process@^0.11.10:
+ version "0.11.10"
+ resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
+
+process@~0.5.1:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
+
+progress@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
+
+promise-inflight@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
+
+promise@^7.1.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ dependencies:
+ asap "~2.0.3"
+
+prop-types@^15.6.0, prop-types@^15.6.1:
+ version "15.6.1"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.3.1"
+ object-assign "^4.1.1"
+
+proxy-addr@~2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341"
+ dependencies:
+ forwarded "~0.1.2"
+ ipaddr.js "1.6.0"
+
+prr@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
+
+pseudomap@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
+
+public-encrypt@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6"
+ dependencies:
+ bn.js "^4.1.0"
+ browserify-rsa "^4.0.0"
+ create-hash "^1.1.0"
+ parse-asn1 "^5.0.0"
+ randombytes "^2.0.1"
+
+pump@^2.0.0, pump@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
+ dependencies:
+ end-of-stream "^1.1.0"
+ once "^1.3.1"
+
+pumpify@^1.3.3:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb"
+ dependencies:
+ duplexify "^3.5.3"
+ inherits "^2.0.3"
+ pump "^2.0.0"
+
+punycode@1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
+
+punycode@^1.2.4, punycode@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+
+qs@6.5.1:
+ version "6.5.1"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
+
+qs@~6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+
+querystring-es3@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
+
+querystring@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
+
+randomatic@^1.1.3:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c"
+ dependencies:
+ is-number "^3.0.0"
+ kind-of "^4.0.0"
+
+randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"
+ dependencies:
+ safe-buffer "^5.1.0"
+
+randomfill@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
+ dependencies:
+ randombytes "^2.0.5"
+ safe-buffer "^5.1.0"
+
+range-parser@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
+
+raw-body@2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
+ dependencies:
+ bytes "3.0.0"
+ http-errors "1.6.2"
+ iconv-lite "0.4.19"
+ unpipe "1.0.0"
+
+rc@^1.1.7:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.5.tgz#275cd687f6e3b36cc756baa26dfee80a790301fd"
+ dependencies:
+ deep-extend "~0.4.0"
+ ini "~1.3.0"
+ minimist "^1.2.0"
+ strip-json-comments "~2.0.1"
+
+react-dom@^16.2.0:
+ version "16.2.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+
+react@^16.2.0:
+ version "16.2.0"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+
+read-chunk@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655"
+ dependencies:
+ pify "^3.0.0"
+ safe-buffer "^5.1.1"
+
+read-pkg-up@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
+ dependencies:
+ find-up "^2.0.0"
+ read-pkg "^2.0.0"
+
+read-pkg@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
+ dependencies:
+ load-json-file "^2.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^2.0.0"
+
+"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.0.3"
+ util-deprecate "~1.0.1"
+
+readdirp@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
+ dependencies:
+ graceful-fs "^4.1.2"
+ minimatch "^3.0.2"
+ readable-stream "^2.0.2"
+ set-immediate-shim "^1.0.1"
+
+recast@^0.12.5:
+ version "0.12.9"
+ resolved "https://registry.yarnpkg.com/recast/-/recast-0.12.9.tgz#e8e52bdb9691af462ccbd7c15d5a5113647a15f1"
+ dependencies:
+ ast-types "0.10.1"
+ core-js "^2.4.1"
+ esprima "~4.0.0"
+ private "~0.1.5"
+ source-map "~0.6.1"
+
+recast@^0.13.0:
+ version "0.13.2"
+ resolved "https://registry.yarnpkg.com/recast/-/recast-0.13.2.tgz#919e7e856d5154f13284142ed1797753c6756137"
+ dependencies:
+ ast-types "0.10.2"
+ esprima "~4.0.0"
+ private "~0.1.5"
+ source-map "~0.6.1"
+
+rechoir@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
+ dependencies:
+ resolve "^1.1.6"
+
+regenerate-unicode-properties@^5.1.1:
+ version "5.1.3"
+ resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-5.1.3.tgz#54f5891543468f36f2274b67c6bc4c033c27b308"
+ dependencies:
+ regenerate "^1.3.3"
+
+regenerate@^1.2.1, regenerate@^1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f"
+
+regenerator-runtime@^0.11.0:
+ version "0.11.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
+
+regenerator-transform@^0.10.0:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"
+ dependencies:
+ babel-runtime "^6.18.0"
+ babel-types "^6.19.0"
+ private "^0.1.6"
+
+regenerator-transform@^0.12.3:
+ version "0.12.3"
+ resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.12.3.tgz#459adfb64f6a27164ab991b7873f45ab969eca8b"
+ dependencies:
+ private "^0.1.6"
+
+regex-cache@^0.4.2:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
+ dependencies:
+ is-equal-shallow "^0.1.3"
+
+regex-not@^1.0.0, regex-not@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
+ dependencies:
+ extend-shallow "^3.0.2"
+ safe-regex "^1.1.0"
+
+regexpu-core@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240"
+ dependencies:
+ regenerate "^1.2.1"
+ regjsgen "^0.2.0"
+ regjsparser "^0.1.4"
+
+regexpu-core@^4.1.3:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.1.3.tgz#fb81616dbbc2a917a7419b33f8379144f51eb8d0"
+ dependencies:
+ regenerate "^1.3.3"
+ regenerate-unicode-properties "^5.1.1"
+ regjsgen "^0.3.0"
+ regjsparser "^0.2.1"
+ unicode-match-property-ecmascript "^1.0.3"
+ unicode-match-property-value-ecmascript "^1.0.1"
+
+regjsgen@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
+
+regjsgen@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.3.0.tgz#0ee4a3e9276430cda25f1e789ea6c15b87b0cb43"
+
+regjsparser@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
+ dependencies:
+ jsesc "~0.5.0"
+
+regjsparser@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.2.1.tgz#c3787553faf04e775c302102ef346d995000ec1c"
+ dependencies:
+ jsesc "~0.5.0"
+
+remove-trailing-separator@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
+
+repeat-element@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
+
+repeat-string@^1.5.2, repeat-string@^1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+
+repeating@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
+ dependencies:
+ is-finite "^1.0.0"
+
+replace-ext@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924"
+
+replace-ext@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
+
+request@2.81.0:
+ version "2.81.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
+ dependencies:
+ aws-sign2 "~0.6.0"
+ aws4 "^1.2.1"
+ caseless "~0.12.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.0"
+ forever-agent "~0.6.1"
+ form-data "~2.1.1"
+ har-validator "~4.2.1"
+ hawk "~3.1.3"
+ http-signature "~1.1.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.7"
+ oauth-sign "~0.8.1"
+ performance-now "^0.2.0"
+ qs "~6.4.0"
+ safe-buffer "^5.0.1"
+ stringstream "~0.0.4"
+ tough-cookie "~2.3.0"
+ tunnel-agent "^0.6.0"
+ uuid "^3.0.0"
+
+require-directory@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+
+require-main-filename@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
+
+require-package-name@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"
+
+require-uncached@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
+ dependencies:
+ caller-path "^0.1.0"
+ resolve-from "^1.0.0"
+
+resolve-cwd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
+ dependencies:
+ resolve-from "^3.0.0"
+
+resolve-dir@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
+ dependencies:
+ expand-tilde "^2.0.0"
+ global-modules "^1.0.0"
+
+resolve-from@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
+
+resolve-from@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
+
+resolve-url@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
+
+resolve@^1.1.6, resolve@^1.3.2, resolve@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
+ dependencies:
+ path-parse "^1.0.5"
+
+restore-cursor@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
+ dependencies:
+ exit-hook "^1.0.0"
+ onetime "^1.0.0"
+
+restore-cursor@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
+ dependencies:
+ onetime "^2.0.0"
+ signal-exit "^3.0.2"
+
+ret@~0.1.10:
+ version "0.1.15"
+ resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
+
+rimraf@2, rimraf@^2.2.0, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
+ dependencies:
+ glob "^7.0.5"
+
+rimraf@~2.2.6:
+ version "2.2.8"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
+
+ripemd160@^2.0.0, ripemd160@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7"
+ dependencies:
+ hash-base "^2.0.0"
+ inherits "^2.0.1"
+
+run-async@^2.0.0, run-async@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
+ dependencies:
+ is-promise "^2.1.0"
+
+run-queue@^1.0.0, run-queue@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
+ dependencies:
+ aproba "^1.1.1"
+
+rx-lite-aggregates@^4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
+ dependencies:
+ rx-lite "*"
+
+rx-lite@*, rx-lite@^4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
+
+rx@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
+
+rxjs@^5.0.0-beta.11:
+ version "5.5.6"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.6.tgz#e31fb96d6fd2ff1fd84bcea8ae9c02d007179c02"
+ dependencies:
+ symbol-observable "1.0.1"
+
+safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
+
+safe-regex@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e"
+ dependencies:
+ ret "~0.1.10"
+
+schema-utils@^0.4.2:
+ version "0.4.5"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e"
+ dependencies:
+ ajv "^6.1.0"
+ ajv-keywords "^3.1.0"
+
+scoped-regex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8"
+
+"semver@2 || 3 || 4 || 5", semver@^5.3.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
+
+send@0.16.1:
+ version "0.16.1"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3"
+ dependencies:
+ debug "2.6.9"
+ depd "~1.1.1"
+ destroy "~1.0.4"
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ fresh "0.5.2"
+ http-errors "~1.6.2"
+ mime "1.4.1"
+ ms "2.0.0"
+ on-finished "~2.3.0"
+ range-parser "~1.2.0"
+ statuses "~1.3.1"
+
+serialize-javascript@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005"
+
+serve-static@1.13.1:
+ version "1.13.1"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719"
+ dependencies:
+ encodeurl "~1.0.1"
+ escape-html "~1.0.3"
+ parseurl "~1.3.2"
+ send "0.16.1"
+
+set-blocking@^2.0.0, set-blocking@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+
+set-getter@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
+ dependencies:
+ to-object-path "^0.3.0"
+
+set-immediate-shim@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
+
+set-value@^0.4.3:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1"
+ dependencies:
+ extend-shallow "^2.0.1"
+ is-extendable "^0.1.1"
+ is-plain-object "^2.0.1"
+ to-object-path "^0.3.0"
+
+set-value@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274"
+ dependencies:
+ extend-shallow "^2.0.1"
+ is-extendable "^0.1.1"
+ is-plain-object "^2.0.3"
+ split-string "^3.0.1"
+
+setimmediate@^1.0.4, setimmediate@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
+
+setprototypeof@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
+
+setprototypeof@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
+
+sha.js@^2.4.0, sha.js@^2.4.8:
+ version "2.4.10"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.10.tgz#b1fde5cd7d11a5626638a07c604ab909cfa31f9b"
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
+shebang-command@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
+ dependencies:
+ shebang-regex "^1.0.0"
+
+shebang-regex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+
+shelljs@^0.7.0:
+ version "0.7.8"
+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
+ dependencies:
+ glob "^7.0.0"
+ interpret "^1.0.0"
+ rechoir "^0.6.2"
+
+signal-exit@^3.0.0, signal-exit@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
+
+slash@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
+
+slice-ansi@0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
+
+slice-ansi@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
+ dependencies:
+ is-fullwidth-code-point "^2.0.0"
+
+slide@^1.1.5:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
+
+snapdragon-node@^2.0.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
+ dependencies:
+ define-property "^1.0.0"
+ isobject "^3.0.0"
+ snapdragon-util "^3.0.1"
+
+snapdragon-util@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2"
+ dependencies:
+ kind-of "^3.2.0"
+
+snapdragon@^0.8.1:
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.1.tgz#e12b5487faded3e3dea0ac91e9400bf75b401370"
+ dependencies:
+ base "^0.11.1"
+ debug "^2.2.0"
+ define-property "^0.2.5"
+ extend-shallow "^2.0.1"
+ map-cache "^0.2.2"
+ source-map "^0.5.6"
+ source-map-resolve "^0.5.0"
+ use "^2.0.0"
+
+sntp@1.x.x:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+ dependencies:
+ hoek "2.x.x"
+
+source-list-map@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
+
+source-map-resolve@^0.5.0:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a"
+ dependencies:
+ atob "^2.0.0"
+ 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.4.15:
+ version "0.4.18"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
+ dependencies:
+ source-map "^0.5.6"
+
+source-map-url@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
+
+source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+
+source-map@^0.6.1, source-map@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+
+spawn-sync@^1.0.15:
+ version "1.0.15"
+ resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476"
+ dependencies:
+ concat-stream "^1.4.7"
+ os-shim "^0.1.2"
+
+spdx-correct@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82"
+ dependencies:
+ spdx-expression-parse "^3.0.0"
+ spdx-license-ids "^3.0.0"
+
+spdx-exceptions@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9"
+
+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"
+ dependencies:
+ spdx-exceptions "^2.1.0"
+ spdx-license-ids "^3.0.0"
+
+spdx-license-ids@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87"
+
+split-string@^3.0.1, split-string@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
+ dependencies:
+ extend-shallow "^3.0.0"
+
+sprintf-js@~1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+
+sshpk@^1.7.0:
+ version "1.13.1"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ dashdash "^1.12.0"
+ getpass "^0.1.1"
+ optionalDependencies:
+ bcrypt-pbkdf "^1.0.0"
+ ecc-jsbn "~0.1.1"
+ jsbn "~0.1.0"
+ tweetnacl "~0.14.0"
+
+ssri@^5.2.4:
+ version "5.2.4"
+ resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.2.4.tgz#9985e14041e65fc397af96542be35724ac11da52"
+ dependencies:
+ safe-buffer "^5.1.1"
+
+static-extend@^0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
+ dependencies:
+ define-property "^0.2.5"
+ object-copy "^0.1.0"
+
+"statuses@>= 1.3.1 < 2":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
+
+statuses@~1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
+
+stream-browserify@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"
+ dependencies:
+ inherits "~2.0.1"
+ readable-stream "^2.0.2"
+
+stream-each@^1.1.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd"
+ dependencies:
+ end-of-stream "^1.1.0"
+ stream-shift "^1.0.0"
+
+stream-http@^2.7.2:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.0.tgz#fd86546dac9b1c91aff8fc5d287b98fafb41bc10"
+ dependencies:
+ builtin-status-codes "^3.0.0"
+ inherits "^2.0.1"
+ readable-stream "^2.3.3"
+ to-arraybuffer "^1.0.0"
+ xtend "^4.0.0"
+
+stream-shift@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
+
+stream-to-observable@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe"
+
+string-template@~0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
+
+string-width@^1.0.1, string-width@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+ dependencies:
+ code-point-at "^1.0.0"
+ is-fullwidth-code-point "^1.0.0"
+ strip-ansi "^3.0.0"
+
+string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
+ dependencies:
+ is-fullwidth-code-point "^2.0.0"
+ strip-ansi "^4.0.0"
+
+string_decoder@^1.0.0, string_decoder@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
+ dependencies:
+ safe-buffer "~5.1.0"
+
+stringstream@~0.0.4:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
+
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+strip-ansi@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
+ dependencies:
+ ansi-regex "^3.0.0"
+
+strip-ansi@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
+
+strip-bom-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
+ dependencies:
+ first-chunk-stream "^2.0.0"
+ strip-bom "^2.0.0"
+
+strip-bom@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
+ dependencies:
+ is-utf8 "^0.2.0"
+
+strip-bom@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+
+strip-eof@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
+
+strip-json-comments@~2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+
+supports-color@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+
+supports-color@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
+ dependencies:
+ has-flag "^2.0.0"
+
+supports-color@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a"
+ dependencies:
+ has-flag "^3.0.0"
+
+symbol-observable@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
+
+table@^4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"
+ dependencies:
+ ajv "^6.0.1"
+ ajv-keywords "^3.0.0"
+ chalk "^2.1.0"
+ lodash "^4.17.4"
+ slice-ansi "1.0.0"
+ string-width "^2.1.1"
+
+tapable@^0.2.7:
+ version "0.2.8"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
+
+tapable@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2"
+
+tar-pack@^3.4.0:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f"
+ dependencies:
+ debug "^2.2.0"
+ fstream "^1.0.10"
+ fstream-ignore "^1.0.5"
+ once "^1.3.3"
+ readable-stream "^2.1.4"
+ rimraf "^2.5.1"
+ tar "^2.2.1"
+ uid-number "^0.0.6"
+
+tar@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
+ dependencies:
+ block-stream "*"
+ fstream "^1.0.2"
+ inherits "2"
+
+temp@^0.8.1:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59"
+ dependencies:
+ os-tmpdir "^1.0.0"
+ rimraf "~2.2.6"
+
+text-table@^0.2.0, text-table@~0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
+
+textextensions@2:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.2.0.tgz#38ac676151285b658654581987a0ce1a4490d286"
+
+through2@^2.0.0, through2@^2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
+ dependencies:
+ readable-stream "^2.1.5"
+ xtend "~4.0.1"
+
+through@^2.3.6:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+
+timed-out@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
+
+timers-browserify@^2.0.4:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.6.tgz#241e76927d9ca05f4d959819022f5b3664b64bae"
+ dependencies:
+ setimmediate "^1.0.4"
+
+tmp@^0.0.29:
+ version "0.0.29"
+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0"
+ dependencies:
+ os-tmpdir "~1.0.1"
+
+tmp@^0.0.33:
+ version "0.0.33"
+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
+ dependencies:
+ os-tmpdir "~1.0.2"
+
+to-arraybuffer@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
+
+to-fast-properties@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
+
+to-fast-properties@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
+
+to-object-path@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
+ dependencies:
+ kind-of "^3.0.2"
+
+to-regex-range@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
+ dependencies:
+ is-number "^3.0.0"
+ repeat-string "^1.6.1"
+
+to-regex@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
+ dependencies:
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
+ regex-not "^1.0.2"
+ safe-regex "^1.1.0"
+
+tough-cookie@~2.3.0:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
+ dependencies:
+ punycode "^1.4.1"
+
+trim-right@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
+
+tryer@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7"
+
+tty-browserify@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
+
+tunnel-agent@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+ dependencies:
+ safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+
+type-check@~0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
+ dependencies:
+ prelude-ls "~1.1.2"
+
+type-is@~1.6.15:
+ version "1.6.16"
+ resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
+ dependencies:
+ media-typer "0.3.0"
+ mime-types "~2.1.18"
+
+typedarray@^0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+
+ua-parser-js@^0.7.9:
+ version "0.7.17"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
+
+uglify-es@^3.3.4:
+ version "3.3.9"
+ resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"
+ dependencies:
+ commander "~2.13.0"
+ source-map "~0.6.1"
+
+uglifyjs-webpack-plugin@^1.1.1, uglifyjs-webpack-plugin@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.2.tgz#e7516d4367afdb715c3847841eb46f94c45ca2b9"
+ dependencies:
+ cacache "^10.0.1"
+ find-cache-dir "^1.0.0"
+ schema-utils "^0.4.2"
+ serialize-javascript "^1.4.0"
+ source-map "^0.6.1"
+ uglify-es "^3.3.4"
+ webpack-sources "^1.1.0"
+ worker-farm "^1.5.2"
+
+uid-number@^0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
+
+underscore@~1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
+
+unicode-canonical-property-names-ecmascript@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.3.tgz#f6119f417467593c0086357c85546b6ad5abc583"
+
+unicode-match-property-ecmascript@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.3.tgz#db9b1cb4ffc67e0c5583780b1b59370e4cbe97b9"
+ dependencies:
+ unicode-canonical-property-names-ecmascript "^1.0.2"
+ unicode-property-aliases-ecmascript "^1.0.3"
+
+unicode-match-property-value-ecmascript@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.1.tgz#fea059120a016f403afd3bf586162b4db03e0604"
+
+unicode-property-aliases-ecmascript@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.3.tgz#ac3522583b9e630580f916635333e00c5ead690d"
+
+union-value@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"
+ dependencies:
+ arr-union "^3.1.0"
+ get-value "^2.0.6"
+ is-extendable "^0.1.1"
+ set-value "^0.4.3"
+
+unique-filename@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3"
+ dependencies:
+ unique-slug "^2.0.0"
+
+unique-slug@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab"
+ dependencies:
+ imurmurhash "^0.1.4"
+
+unpipe@1.0.0, unpipe@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
+
+unset-value@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"
+ dependencies:
+ has-value "^0.3.1"
+ isobject "^3.0.0"
+
+untildify@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0"
+ dependencies:
+ os-homedir "^1.0.0"
+
+untildify@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.2.tgz#7f1f302055b3fea0f3e81dc78eb36766cb65e3f1"
+
+upath@^1.0.0:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d"
+
+urix@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
+
+url-parse-lax@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
+ dependencies:
+ prepend-http "^1.0.1"
+
+url-to-options@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
+
+url@^0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
+ dependencies:
+ punycode "1.3.2"
+ querystring "0.2.0"
+
+urlgrey@0.4.4:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f"
+
+use@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8"
+ dependencies:
+ define-property "^0.2.5"
+ isobject "^3.0.0"
+ lazy-cache "^2.0.2"
+
+util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+
+util@0.10.3, util@^0.10.3:
+ version "0.10.3"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
+ dependencies:
+ inherits "2.0.1"
+
+utils-merge@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
+
+uuid@^3.0.0:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
+
+v8-compile-cache@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz#8d32e4f16974654657e676e0e467a348e89b0dc4"
+
+validate-npm-package-license@^3.0.1:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338"
+ dependencies:
+ spdx-correct "^3.0.0"
+ spdx-expression-parse "^3.0.0"
+
+vary@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
+
+verror@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
+ dependencies:
+ assert-plus "^1.0.0"
+ core-util-is "1.0.2"
+ extsprintf "^1.2.0"
+
+vinyl-file@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a"
+ dependencies:
+ graceful-fs "^4.1.2"
+ pify "^2.3.0"
+ pinkie-promise "^2.0.0"
+ strip-bom "^2.0.0"
+ strip-bom-stream "^2.0.0"
+ vinyl "^1.1.0"
+
+vinyl@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884"
+ dependencies:
+ clone "^1.0.0"
+ clone-stats "^0.0.1"
+ replace-ext "0.0.1"
+
+vinyl@^2.0.1:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c"
+ dependencies:
+ clone "^2.1.1"
+ clone-buffer "^1.0.0"
+ clone-stats "^1.0.0"
+ cloneable-readable "^1.0.0"
+ remove-trailing-separator "^1.0.1"
+ replace-ext "^1.0.0"
+
+vm-browserify@0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
+ dependencies:
+ indexof "0.0.1"
+
+watchpack@^1.4.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed"
+ dependencies:
+ chokidar "^2.0.2"
+ graceful-fs "^4.1.2"
+ neo-async "^2.5.0"
+
+webpack-addons@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/webpack-addons/-/webpack-addons-1.1.5.tgz#2b178dfe873fb6e75e40a819fa5c26e4a9bc837a"
+ dependencies:
+ jscodeshift "^0.4.0"
+
+webpack-bundle-analyzer@^2.11.1:
+ version "2.11.1"
+ resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.11.1.tgz#b9fbfb6a32c0a8c1c3237223e90890796b950ab9"
+ dependencies:
+ acorn "^5.3.0"
+ bfj-node4 "^5.2.0"
+ chalk "^2.3.0"
+ commander "^2.13.0"
+ ejs "^2.5.7"
+ express "^4.16.2"
+ filesize "^3.5.11"
+ gzip-size "^4.1.0"
+ lodash "^4.17.4"
+ mkdirp "^0.5.1"
+ opener "^1.4.3"
+ ws "^4.0.0"
+
+webpack-cli@^2.0.9:
+ version "2.0.9"
+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.0.9.tgz#0310fa04f4cad69714560cc0e4da5c7682eb4d9b"
+ dependencies:
+ chalk "^2.0.1"
+ codecov "^3.0.0"
+ cross-spawn "^5.1.0"
+ diff "^3.3.0"
+ enhanced-resolve "^3.4.1"
+ glob-all "^3.1.0"
+ global "^4.3.2"
+ global-modules "^1.0.0"
+ got "^7.1.0"
+ inquirer "^3.2.0"
+ interpret "^1.0.4"
+ jscodeshift "^0.4.0"
+ listr "^0.12.0"
+ loader-utils "^1.1.0"
+ lodash "^4.17.4"
+ log-symbols "2.1.0"
+ mkdirp "^0.5.1"
+ p-each-series "^1.0.0"
+ p-lazy "^1.0.0"
+ prettier "^1.5.3"
+ recast "^0.13.0"
+ resolve-cwd "^2.0.0"
+ supports-color "^4.4.0"
+ uglifyjs-webpack-plugin "^1.2.2"
+ v8-compile-cache "^1.1.0"
+ webpack-addons "^1.1.5"
+ webpack-fork-yeoman-generator "^1.1.1"
+ yargs "9.0.1"
+ yeoman-environment "^2.0.0"
+
+webpack-fork-yeoman-generator@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/webpack-fork-yeoman-generator/-/webpack-fork-yeoman-generator-1.1.1.tgz#c92b454aba7df9ea392669188aa0330964acf76f"
+ dependencies:
+ async "^2.0.0"
+ chalk "^1.0.0"
+ cli-table "^0.3.1"
+ cross-spawn "^5.0.1"
+ dargs "^5.1.0"
+ dateformat "^2.0.0"
+ debug "^2.1.0"
+ detect-conflict "^1.0.0"
+ error "^7.0.2"
+ find-up "^2.1.0"
+ github-username "^4.0.0"
+ istextorbinary "^2.1.0"
+ lodash "^4.11.1"
+ mem-fs-editor "^3.0.0"
+ minimist "^1.2.0"
+ mkdirp "^0.5.0"
+ pretty-bytes "^4.0.2"
+ read-chunk "^2.0.0"
+ read-pkg-up "^2.0.0"
+ rimraf "^2.2.0"
+ run-async "^2.0.0"
+ shelljs "^0.7.0"
+ text-table "^0.2.0"
+ through2 "^2.0.0"
+ yeoman-environment "^1.1.0"
+
+webpack-merge@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.2.tgz#5d372dddd3e1e5f8874f5bf5a8e929db09feb216"
+ dependencies:
+ lodash "^4.17.5"
+
+webpack-sources@^1.0.1, webpack-sources@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"
+ dependencies:
+ source-list-map "^2.0.0"
+ source-map "~0.6.1"
+
+webpack@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.0.1.tgz#768d708beeca4c5f77f6c2d38a240fb6ff50ba5d"
+ dependencies:
+ acorn "^5.0.0"
+ acorn-dynamic-import "^3.0.0"
+ ajv "^6.1.0"
+ ajv-keywords "^3.1.0"
+ chrome-trace-event "^0.1.1"
+ enhanced-resolve "^4.0.0"
+ eslint-scope "^3.7.1"
+ loader-runner "^2.3.0"
+ loader-utils "^1.1.0"
+ memory-fs "~0.4.1"
+ micromatch "^3.1.8"
+ mkdirp "~0.5.0"
+ neo-async "^2.5.0"
+ node-libs-browser "^2.0.0"
+ schema-utils "^0.4.2"
+ tapable "^1.0.0"
+ uglifyjs-webpack-plugin "^1.1.1"
+ watchpack "^1.4.0"
+ webpack-sources "^1.0.1"
+
+whatwg-fetch@>=0.10.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
+
+which-module@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
+
+which@^1.2.14, which@^1.2.9:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
+ dependencies:
+ isexe "^2.0.0"
+
+wide-align@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710"
+ dependencies:
+ string-width "^1.0.2"
+
+wordwrap@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+
+worker-farm@^1.5.2:
+ version "1.5.4"
+ resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.4.tgz#4debbe46b40edefcc717ebde74a90b1ae1e909a1"
+ dependencies:
+ errno "~0.1.7"
+ xtend "~4.0.1"
+
+wrap-ansi@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
+ dependencies:
+ string-width "^1.0.1"
+ strip-ansi "^3.0.1"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+write-file-atomic@^1.2.0:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
+ dependencies:
+ graceful-fs "^4.1.11"
+ imurmurhash "^0.1.4"
+ slide "^1.1.5"
+
+write@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
+ dependencies:
+ mkdirp "^0.5.1"
+
+ws@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289"
+ dependencies:
+ async-limiter "~1.0.0"
+ safe-buffer "~5.1.0"
+
+xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
+
+y18n@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
+
+y18n@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
+
+yallist@^2.1.2:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
+
+yargs-parser@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9"
+ dependencies:
+ camelcase "^4.1.0"
+
+yargs@9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c"
+ dependencies:
+ camelcase "^4.1.0"
+ cliui "^3.2.0"
+ decamelize "^1.1.1"
+ get-caller-file "^1.0.1"
+ os-locale "^2.0.0"
+ read-pkg-up "^2.0.0"
+ require-directory "^2.1.1"
+ require-main-filename "^1.0.1"
+ set-blocking "^2.0.0"
+ string-width "^2.0.0"
+ which-module "^2.0.0"
+ y18n "^3.2.1"
+ yargs-parser "^7.0.0"
+
+yargs@~1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.2.6.tgz#9c7b4a82fd5d595b2bf17ab6dcc43135432fe34b"
+ dependencies:
+ minimist "^0.1.0"
+
+yeoman-environment@^1.1.0:
+ version "1.6.6"
+ resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-1.6.6.tgz#cd85fa67d156060e440d7807d7ef7cf0d2d1d671"
+ dependencies:
+ chalk "^1.0.0"
+ debug "^2.0.0"
+ diff "^2.1.2"
+ escape-string-regexp "^1.0.2"
+ globby "^4.0.0"
+ grouped-queue "^0.3.0"
+ inquirer "^1.0.2"
+ lodash "^4.11.1"
+ log-symbols "^1.0.1"
+ mem-fs "^1.1.0"
+ text-table "^0.2.0"
+ untildify "^2.0.0"
+
+yeoman-environment@^2.0.0:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.0.5.tgz#84f22bafa84088971fe99ea85f654a3a3dd2b693"
+ dependencies:
+ chalk "^2.1.0"
+ debug "^3.1.0"
+ diff "^3.3.1"
+ escape-string-regexp "^1.0.2"
+ globby "^6.1.0"
+ grouped-queue "^0.3.3"
+ inquirer "^3.3.0"
+ is-scoped "^1.0.0"
+ lodash "^4.17.4"
+ log-symbols "^2.1.0"
+ mem-fs "^1.1.0"
+ text-table "^0.2.0"
+ untildify "^3.0.2"
diff --git a/votrfront/serve.py b/votrfront/serve.py
index cc430bc..75ad531 100644
--- a/votrfront/serve.py
+++ b/votrfront/serve.py
@@ -1,7 +1,6 @@
import os
from werkzeug.serving import run_simple
-from .watchstatic import watch_in_background
def serve(app, *args):
@@ -17,8 +16,6 @@ def serve(app, *args):
os.makedirs(app.var_path('oldlogs'), exist_ok=True)
os.makedirs(app.var_path('sessions'), exist_ok=True)
- if os.getenv('WERKZEUG_RUN_MAIN'):
- watch_in_background()
app.wrap_static()
run_simple('127.0.0.1', int(os.getenv('PORT') or 5000), app,
diff --git a/votrfront/watchstatic.py b/votrfront/watchstatic.py
deleted file mode 100644
index 9cc8e02..0000000
--- a/votrfront/watchstatic.py
+++ /dev/null
@@ -1,67 +0,0 @@
-
-import os
-import subprocess
-import sys
-import threading
-import time
-
-
-votrfront_path = os.path.dirname(__file__) or '.'
-watch_paths = ['buildstatic.sh', 'js', 'css']
-watch_extensions = ['.sh', '.js', '.scss']
-
-
-def build():
- command = ['./buildstatic.sh']
- if hasattr(sys, 'real_prefix'):
- command.append('--env=' + sys.prefix)
- returncode = subprocess.call(command, cwd=votrfront_path)
- print(' * buildstatic.sh failed' if returncode else
- ' * buildstatic.sh ended successfully', file=sys.stderr)
-
-
-def walk(root):
- if os.path.isfile(root):
- yield root
- if os.path.isdir(root):
- for dirpath, dirnames, filenames in os.walk(root):
- for filename in filenames:
- yield os.path.join(dirpath, filename)
-
-
-def watch(interval=1):
- last_build = time.time()
- build()
-
- while True:
- modified_files = []
-
- for root in watch_paths:
- for filename in walk(os.path.join(votrfront_path, root)):
- if os.path.splitext(filename)[1] not in watch_extensions:
- continue
- try:
- mtime = os.stat(filename).st_mtime
- if mtime > last_build:
- modified_files.append(filename)
- except OSError:
- continue
-
- if modified_files:
- print(' * Detected change in {}, rebuilding static'.format(
- repr(modified_files)[1:-1]), file=sys.stderr)
- last_build = time.time()
- build()
-
- time.sleep(interval)
-
-
-def watch_in_background():
- t = threading.Thread(target=watch)
- t.daemon = True
- t.start()
- return t
-
-
-if __name__ == '__main__':
- watch()
diff --git a/votrfront/webpack.config.js b/votrfront/webpack.config.js
deleted file mode 100644
index f610fe0..0000000
--- a/votrfront/webpack.config.js
+++ /dev/null
@@ -1,79 +0,0 @@
-
-var webpack = require("webpack");
-var ConcatSource = require("webpack/lib/ConcatSource");
-
-
-function VotrDevelPlugin(moduleVariablePrefix, outputPath) {
- this.moduleVariablePrefix = moduleVariablePrefix;
- this.outputPath = outputPath;
-}
-
-VotrDevelPlugin.prototype.apply = function (compiler) {
- var self = this;
- compiler.plugin('compilation', function (compilation) {
- compilation.moduleTemplate.plugin('package', function (moduleSource, module) {
- // Ugly hack to remove the newlines added by FunctionModuleTemplatePlugin.
- if (moduleSource instanceof ConcatSource && moduleSource.children[0].constructor === String) {
- moduleSource.children[0] = moduleSource.children[0].replace(/\n*$/, '');
- }
-
- // Uglier hack to move the whole source code to a separate file.
- var id = self.moduleVariablePrefix + module.id;
- var req = module.readableIdentifier(this.requestShortener);
- var devFilename = self.outputPath + req.replace(/\.\w+$/, '').replace(/^\.\//, '').replace(/\W/g, '_') + '.js';
-
- compilation.assets[devFilename] = new ConcatSource(id, ' = ', moduleSource);
- return id;
- });
- });
-};
-
-
-function makeConfig() {
- return {
- context: __dirname + '/js',
- entry: './main',
- output: {
- path: __dirname + '/static',
- sourceMapFilename: '[file].' + Date.now() + '.map', // it seems Chrome caches source maps even if "Disable cache" is enabled
- },
- plugins: [],
- module: {
- loaders: [
- {
- test: /\.js$/,
- exclude: /node_modules/,
- loader: 'babel',
- query: {
- cacheDirectory: __dirname + '/static/cache',
- loose: ['es6.destructuring', 'es6.properties.computed', 'es6.spread'],
- },
- },
- ],
- },
- records: __dirname + '/static/records',
- };
-};
-
-
-var prodConfig = makeConfig();
-prodConfig.output.filename = 'votr.min.js';
-prodConfig.plugins.push(new webpack.optimize.UglifyJsPlugin());
-prodConfig.plugins.push(new webpack.optimize.OccurenceOrderPlugin());
-prodConfig.devtool = 'source-map';
-
-
-var devConfig = makeConfig();
-devConfig.output.filename = 'votr.dev.js';
-devConfig.plugins.push(new VotrDevelPlugin('_votr_module_', 'dev/'));
-devConfig.module.loaders[0].query.retainLines = true;
-
-
-var prologueConfig = makeConfig();
-prologueConfig.entry = './prologue';
-prologueConfig.output.filename = 'prologue.js';
-prologueConfig.plugins.push(new webpack.optimize.UglifyJsPlugin());
-prologueConfig.plugins.push(new webpack.optimize.OccurenceOrderPlugin());
-
-
-module.exports = [prodConfig, devConfig, prologueConfig];