From deca6697e064152643b89afb61d9ce1ce9cef634 Mon Sep 17 00:00:00 2001 From: Sasha Koss Date: Wed, 12 Dec 2018 10:29:09 +0530 Subject: [PATCH] Add lightFormat function and optimize toDate --- config/karma.js | 49 +- package.json | 1 + src/_lib/addLeadingZeros/index.js | 8 + .../_lib => _lib/format}/formatters/index.js | 385 ++++++------ src/_lib/format/lightFormatters/index.js | 115 ++++ .../format}/longFormatters/index.js | 30 +- src/format/index.js | 4 +- src/lightFormat/index.js | 134 +++++ src/lightFormat/test.js | 154 +++++ src/toDate/index.js | 447 ++++---------- src/toDate/test.js | 335 ++++++----- yarn.lock | 564 +++++++++++++++++- 12 files changed, 1506 insertions(+), 720 deletions(-) create mode 100644 src/_lib/addLeadingZeros/index.js rename src/{format/_lib => _lib/format}/formatters/index.js (64%) create mode 100644 src/_lib/format/lightFormatters/index.js rename src/{format/_lib => _lib/format}/longFormatters/index.js (51%) create mode 100644 src/lightFormat/index.js create mode 100644 src/lightFormat/test.js diff --git a/config/karma.js b/config/karma.js index 1e496c2f8b..8f2e862c0c 100644 --- a/config/karma.js +++ b/config/karma.js @@ -1,11 +1,11 @@ process.env.PHANTOMJS_BIN = 'node_modules/.bin/phantomjs' process.env.NODE_ENV = 'test' -var webpackConfig = require('./webpack') -var countReporter = require('./_lib/countReporter') -var benchmarkJSONReporter = require('./_lib/benchmarkJSONReporter') +const webpackConfig = require('./webpack') +const countReporter = require('./_lib/countReporter') +const benchmarkJSONReporter = require('./_lib/benchmarkJSONReporter') -var sauceLabsLaunchers = { +const sauceLabsLaunchers = { // TODO: See if Safari became more reliable safari: { base: 'SauceLabs', @@ -83,13 +83,13 @@ var sauceLabsLaunchers = { } } -var localLaunchers = { +const localLaunchers = { LocalChrome: { base: 'Chrome' } } -var travisLaunchers = { +const travisLaunchers = { ChromeTravis: { base: 'ChromeHeadless', // NOTE: We need to launch Chrome with --no-sandbox. @@ -98,7 +98,7 @@ var travisLaunchers = { } } -function config (config) { +function config(config) { config.set({ frameworks: getFrameworksConfig(), files: getFilesConfig(), @@ -119,10 +119,10 @@ function config (config) { // so waiting time must be insanely high. browserNoActivityTimeout: process.env.TEST_CROSS_BROWSER ? 60 * 60 * 1000 /* 1 hour */ - : 10 * 1000, /* 10 sec */ + : 10 * 1000 /* 10 sec */, captureTimeout: process.env.TEST_CROSS_BROWSER ? 120 * 1000 /* 2 min */ - : 60 * 1000, /* 1 min */ + : 60 * 1000 /* 1 min */, sauceLabs: { startConnect: false, @@ -146,17 +146,21 @@ function config (config) { 'karma-webpack', 'karma-benchmark', 'karma-benchmark-reporter', - {'reporter:count': ['type', countReporter]}, - {'reporter:benchmark-json': ['type', benchmarkJSONReporter]} + { 'reporter:count': ['type', countReporter] }, + { 'reporter:benchmark-json': ['type', benchmarkJSONReporter] } ], - customLaunchers: process.env.TEST_CROSS_BROWSER ? sauceLabsLaunchers : process.env.TRAVIS ? travisLaunchers : localLaunchers, + customLaunchers: process.env.TEST_CROSS_BROWSER + ? sauceLabsLaunchers + : process.env.TRAVIS + ? travisLaunchers + : localLaunchers, browsers: getBrowsersConfig(), reporters: getReportersConfig() }) } -function getFrameworksConfig () { +function getFrameworksConfig() { if (process.env.TEST_BENCHMARK) { return ['benchmark'] } else { @@ -164,30 +168,27 @@ function getFrameworksConfig () { } } -function getFilesConfig () { +function getFilesConfig() { if (process.env.USE_STATIC_TESTS) { return ['../tmp/tests.js'] } else if (process.env.TEST_BENCHMARK) { - return [ - '../node_modules/moment/moment.js', - '../benchmark.js' - ] + return ['../node_modules/moment/moment.js', '../benchmark.js'] } else { return ['../test.js'] } } -function getPreprocessorsConfig () { +function getPreprocessorsConfig() { if (process.env.USE_STATIC_TESTS) { - return {'../tmp/tests.js': ['sourcemap']} + return { '../tmp/tests.js': ['sourcemap'] } } else if (process.env.TEST_BENCHMARK) { - return {'../benchmark.js': ['webpack', 'sourcemap']} + return { '../benchmark.js': ['webpack', 'sourcemap'] } } else { - return {'../test.js': ['webpack', 'sourcemap']} + return { '../test.js': ['webpack', 'sourcemap'] } } } -function getBrowsersConfig () { +function getBrowsersConfig() { if (process.env.TEST_CROSS_BROWSER) { return Object.keys(sauceLabsLaunchers) } else if (process.env.TEST_BENCHMARK) { @@ -199,7 +200,7 @@ function getBrowsersConfig () { } } -function getReportersConfig () { +function getReportersConfig() { if (process.env.TEST_CROSS_BROWSER) { return ['dots', 'saucelabs', 'count'] } else if (process.env.TEST_BENCHMARK) { diff --git a/package.json b/package.json index f6d633a9bf..346d100085 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "power-assert": "^1.3.1", "prettier": "^1.14.3", "sinon": "^1.17.3", + "size-limit": "^0.21.0", "snazzy": "^7.0.0", "systemjs": "^0.19.39", "systemjs-plugin-babel": "0.0.17", diff --git a/src/_lib/addLeadingZeros/index.js b/src/_lib/addLeadingZeros/index.js new file mode 100644 index 0000000000..62f812bc22 --- /dev/null +++ b/src/_lib/addLeadingZeros/index.js @@ -0,0 +1,8 @@ +export default function addLeadingZeros(number, targetLength) { + var sign = number < 0 ? '-' : '' + var output = Math.abs(number).toString() + while (output.length < targetLength) { + output = '0' + output + } + return sign + output +} diff --git a/src/format/_lib/formatters/index.js b/src/_lib/format/formatters/index.js similarity index 64% rename from src/format/_lib/formatters/index.js rename to src/_lib/format/formatters/index.js index af4cbdf553..a719537ee5 100644 --- a/src/format/_lib/formatters/index.js +++ b/src/_lib/format/formatters/index.js @@ -1,8 +1,10 @@ +import lightFormatters from '../lightFormatters/index.js' import getUTCDayOfYear from '../../../_lib/getUTCDayOfYear/index.js' import getUTCISOWeek from '../../../_lib/getUTCISOWeek/index.js' import getUTCISOWeekYear from '../../../_lib/getUTCISOWeekYear/index.js' import getUTCWeek from '../../../_lib/getUTCWeek/index.js' import getUTCWeekYear from '../../../_lib/getUTCWeekYear/index.js' +import addLeadingZeros from '../../addLeadingZeros/index.js' var dayPeriodEnum = { am: 'am', @@ -63,58 +65,41 @@ var dayPeriodEnum = { var formatters = { // Era - G: function (date, token, localize) { + G: function(date, token, localize) { var era = date.getUTCFullYear() > 0 ? 1 : 0 switch (token) { // AD, BC case 'G': case 'GG': case 'GGG': - return localize.era(era, {width: 'abbreviated'}) + return localize.era(era, { width: 'abbreviated' }) // A, B case 'GGGGG': - return localize.era(era, {width: 'narrow'}) + return localize.era(era, { width: 'narrow' }) // Anno Domini, Before Christ case 'GGGG': default: - return localize.era(era, {width: 'wide'}) + return localize.era(era, { width: 'wide' }) } }, // Year - y: function (date, token, localize, options) { - // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens - // | Year | y | yy | yyy | yyyy | yyyyy | - // |----------|-------|----|-------|-------|-------| - // | AD 1 | 1 | 01 | 001 | 0001 | 00001 | - // | AD 12 | 12 | 12 | 012 | 0012 | 00012 | - // | AD 123 | 123 | 23 | 123 | 0123 | 00123 | - // | AD 1234 | 1234 | 34 | 1234 | 1234 | 01234 | - // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 | - - var signedYear = date.getUTCFullYear() - - // Returns 1 for 1 BC (which is year 0 in JavaScript) - var year = signedYear > 0 ? signedYear : 1 - signedYear - - // Two digit year - if (token === 'yy') { - var twoDigitYear = year % 100 - return addLeadingZeros(twoDigitYear, 2) - } - + y: function(date, token, localize) { // Ordinal number if (token === 'yo') { - return localize.ordinalNumber(year, {unit: 'year'}) + var signedYear = date.getUTCFullYear() + // Returns 1 for 1 BC (which is year 0 in JavaScript) + var year = signedYear > 0 ? signedYear : 1 - signedYear + return localize.ordinalNumber(year, { unit: 'year' }) } - // Padding - return addLeadingZeros(year, token.length) + return lightFormatters.y(date, token) }, // Local week-numbering year - Y: function (date, token, localize, options) { + Y: function(date, token, localize, options) { var signedWeekYear = getUTCWeekYear(date, options) + // Returns 1 for 1 BC (which is year 0 in JavaScript) var weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear // Two digit year @@ -125,7 +110,7 @@ var formatters = { // Ordinal number if (token === 'Yo') { - return localize.ordinalNumber(weekYear, {unit: 'year'}) + return localize.ordinalNumber(weekYear, { unit: 'year' }) } // Padding @@ -133,7 +118,7 @@ var formatters = { }, // ISO week-numbering year - R: function (date, token, localize, options) { + R: function(date, token, _localize, options) { var isoWeekYear = getUTCISOWeekYear(date, options) // Padding @@ -149,13 +134,13 @@ var formatters = { // | BC 2 | 2 | -1 | // Also `yy` always returns the last two digits of a year, // while `uu` pads single digit years to 2 characters and returns other years unchanged. - u: function (date, token, localize, options) { + u: function(date, token) { var year = date.getUTCFullYear() return addLeadingZeros(year, token.length) }, // Quarter - Q: function (date, token, localize, options) { + Q: function(date, token, localize) { var quarter = Math.ceil((date.getUTCMonth() + 1) / 3) switch (token) { // 1, 2, 3, 4 @@ -166,22 +151,31 @@ var formatters = { return addLeadingZeros(quarter, 2) // 1st, 2nd, 3rd, 4th case 'Qo': - return localize.ordinalNumber(quarter, {unit: 'quarter'}) + return localize.ordinalNumber(quarter, { unit: 'quarter' }) // Q1, Q2, Q3, Q4 case 'QQQ': - return localize.quarter(quarter, {width: 'abbreviated', context: 'formatting'}) + return localize.quarter(quarter, { + width: 'abbreviated', + context: 'formatting' + }) // 1, 2, 3, 4 (narrow quarter; could be not numerical) case 'QQQQQ': - return localize.quarter(quarter, {width: 'narrow', context: 'formatting'}) + return localize.quarter(quarter, { + width: 'narrow', + context: 'formatting' + }) // 1st quarter, 2nd quarter, ... case 'QQQQ': default: - return localize.quarter(quarter, {width: 'wide', context: 'formatting'}) + return localize.quarter(quarter, { + width: 'wide', + context: 'formatting' + }) } }, // Stand-alone quarter - q: function (date, token, localize, options) { + q: function(date, token, localize) { var quarter = Math.ceil((date.getUTCMonth() + 1) / 3) switch (token) { // 1, 2, 3, 4 @@ -192,48 +186,57 @@ var formatters = { return addLeadingZeros(quarter, 2) // 1st, 2nd, 3rd, 4th case 'qo': - return localize.ordinalNumber(quarter, {unit: 'quarter'}) + return localize.ordinalNumber(quarter, { unit: 'quarter' }) // Q1, Q2, Q3, Q4 case 'qqq': - return localize.quarter(quarter, {width: 'abbreviated', context: 'standalone'}) + return localize.quarter(quarter, { + width: 'abbreviated', + context: 'standalone' + }) // 1, 2, 3, 4 (narrow quarter; could be not numerical) case 'qqqqq': - return localize.quarter(quarter, {width: 'narrow', context: 'standalone'}) + return localize.quarter(quarter, { + width: 'narrow', + context: 'standalone' + }) // 1st quarter, 2nd quarter, ... case 'qqqq': default: - return localize.quarter(quarter, {width: 'wide', context: 'standalone'}) + return localize.quarter(quarter, { + width: 'wide', + context: 'standalone' + }) } }, // Month - M: function (date, token, localize, options) { + M: function(date, token, localize) { var month = date.getUTCMonth() switch (token) { - // 1, 2, ..., 12 case 'M': - return String(month + 1) - // 01, 02, ..., 12 case 'MM': - return addLeadingZeros(month + 1, 2) + return lightFormatters.M(date, token) // 1st, 2nd, ..., 12th case 'Mo': - return localize.ordinalNumber(month + 1, {unit: 'month'}) + return localize.ordinalNumber(month + 1, { unit: 'month' }) // Jan, Feb, ..., Dec case 'MMM': - return localize.month(month, {width: 'abbreviated', context: 'formatting'}) + return localize.month(month, { + width: 'abbreviated', + context: 'formatting' + }) // J, F, ..., D case 'MMMMM': - return localize.month(month, {width: 'narrow', context: 'formatting'}) + return localize.month(month, { width: 'narrow', context: 'formatting' }) // January, February, ..., December case 'MMMM': default: - return localize.month(month, {width: 'wide', context: 'formatting'}) + return localize.month(month, { width: 'wide', context: 'formatting' }) } }, // Stand-alone month - L: function (date, token, localize, options) { + L: function(date, token, localize, options) { var month = date.getUTCMonth() switch (token) { // 1, 2, ..., 12 @@ -244,90 +247,100 @@ var formatters = { return addLeadingZeros(month + 1, 2) // 1st, 2nd, ..., 12th case 'Lo': - return localize.ordinalNumber(month + 1, {unit: 'month'}) + return localize.ordinalNumber(month + 1, { unit: 'month' }) // Jan, Feb, ..., Dec case 'LLL': - return localize.month(month, {width: 'abbreviated', context: 'standalone'}) + return localize.month(month, { + width: 'abbreviated', + context: 'standalone' + }) // J, F, ..., D case 'LLLLL': - return localize.month(month, {width: 'narrow', context: 'standalone'}) + return localize.month(month, { width: 'narrow', context: 'standalone' }) // January, February, ..., December case 'LLLL': default: - return localize.month(month, {width: 'wide', context: 'standalone'}) + return localize.month(month, { width: 'wide', context: 'standalone' }) } }, // Local week of year - w: function (date, token, localize, options) { + w: function(date, token, localize, options) { var week = getUTCWeek(date, options) if (token === 'wo') { - return localize.ordinalNumber(week, {unit: 'week'}) + return localize.ordinalNumber(week, { unit: 'week' }) } return addLeadingZeros(week, token.length) }, // ISO week of year - I: function (date, token, localize, options) { + I: function(date, token, localize, options) { var isoWeek = getUTCISOWeek(date, options) if (token === 'Io') { - return localize.ordinalNumber(isoWeek, {unit: 'week'}) + return localize.ordinalNumber(isoWeek, { unit: 'week' }) } return addLeadingZeros(isoWeek, token.length) }, // Day of the month - d: function (date, token, localize, options) { - var dayOfMonth = date.getUTCDate() - + d: function(date, token, localize) { if (token === 'do') { - return localize.ordinalNumber(dayOfMonth, {unit: 'date'}) + return localize.ordinalNumber(date.getUTCDate(), { unit: 'date' }) } - return addLeadingZeros(dayOfMonth, token.length) + return lightFormatters.d(date, token) }, // Day of year - D: function (date, token, localize, options) { + D: function(date, token, localize, options) { var dayOfYear = getUTCDayOfYear(date, options) if (token === 'Do') { - return localize.ordinalNumber(dayOfYear, {unit: 'dayOfYear'}) + return localize.ordinalNumber(dayOfYear, { unit: 'dayOfYear' }) } return addLeadingZeros(dayOfYear, token.length) }, // Day of week - E: function (date, token, localize, options) { + E: function(date, token, localize, options) { var dayOfWeek = date.getUTCDay() switch (token) { // Tue case 'E': case 'EE': case 'EEE': - return localize.day(dayOfWeek, {width: 'abbreviated', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'abbreviated', + context: 'formatting' + }) // T case 'EEEEE': - return localize.day(dayOfWeek, {width: 'narrow', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'narrow', + context: 'formatting' + }) // Tu case 'EEEEEE': - return localize.day(dayOfWeek, {width: 'short', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'short', + context: 'formatting' + }) // Tuesday case 'EEEE': default: - return localize.day(dayOfWeek, {width: 'wide', context: 'formatting'}) + return localize.day(dayOfWeek, { width: 'wide', context: 'formatting' }) } }, // Local day of week - e: function (date, token, localize, options) { + e: function(date, token, localize, options) { var dayOfWeek = date.getUTCDay() - var localDayOfWeek = ((dayOfWeek - options.weekStartsOn + 8) % 7) || 7 + var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7 switch (token) { // Numerical value (Nth day of week with current locale or weekStartsOn) case 'e': @@ -337,26 +350,35 @@ var formatters = { return addLeadingZeros(localDayOfWeek, 2) // 1st, 2nd, ..., 7th case 'eo': - return localize.ordinalNumber(localDayOfWeek, {unit: 'day'}) + return localize.ordinalNumber(localDayOfWeek, { unit: 'day' }) case 'eee': - return localize.day(dayOfWeek, {width: 'abbreviated', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'abbreviated', + context: 'formatting' + }) // T case 'eeeee': - return localize.day(dayOfWeek, {width: 'narrow', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'narrow', + context: 'formatting' + }) // Tu case 'eeeeee': - return localize.day(dayOfWeek, {width: 'short', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'short', + context: 'formatting' + }) // Tuesday case 'eeee': default: - return localize.day(dayOfWeek, {width: 'wide', context: 'formatting'}) + return localize.day(dayOfWeek, { width: 'wide', context: 'formatting' }) } }, // Stand-alone local day of week - c: function (date, token, localize, options) { + c: function(date, token, localize, options) { var dayOfWeek = date.getUTCDay() - var localDayOfWeek = ((dayOfWeek - options.weekStartsOn + 8) % 7) || 7 + var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7 switch (token) { // Numerical value (same as in `e`) case 'c': @@ -366,24 +388,33 @@ var formatters = { return addLeadingZeros(localDayOfWeek, token.length) // 1st, 2nd, ..., 7th case 'co': - return localize.ordinalNumber(localDayOfWeek, {unit: 'day'}) + return localize.ordinalNumber(localDayOfWeek, { unit: 'day' }) case 'ccc': - return localize.day(dayOfWeek, {width: 'abbreviated', context: 'standalone'}) + return localize.day(dayOfWeek, { + width: 'abbreviated', + context: 'standalone' + }) // T case 'ccccc': - return localize.day(dayOfWeek, {width: 'narrow', context: 'standalone'}) + return localize.day(dayOfWeek, { + width: 'narrow', + context: 'standalone' + }) // Tu case 'cccccc': - return localize.day(dayOfWeek, {width: 'short', context: 'standalone'}) + return localize.day(dayOfWeek, { + width: 'short', + context: 'standalone' + }) // Tuesday case 'cccc': default: - return localize.day(dayOfWeek, {width: 'wide', context: 'standalone'}) + return localize.day(dayOfWeek, { width: 'wide', context: 'standalone' }) } }, // ISO day of week - i: function (date, token, localize, options) { + i: function(date, token, localize, options) { var dayOfWeek = date.getUTCDay() var isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek switch (token) { @@ -395,43 +426,61 @@ var formatters = { return addLeadingZeros(isoDayOfWeek, token.length) // 2nd case 'io': - return localize.ordinalNumber(isoDayOfWeek, {unit: 'day'}) + return localize.ordinalNumber(isoDayOfWeek, { unit: 'day' }) // Tue case 'iii': - return localize.day(dayOfWeek, {width: 'abbreviated', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'abbreviated', + context: 'formatting' + }) // T case 'iiiii': - return localize.day(dayOfWeek, {width: 'narrow', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'narrow', + context: 'formatting' + }) // Tu case 'iiiiii': - return localize.day(dayOfWeek, {width: 'short', context: 'formatting'}) + return localize.day(dayOfWeek, { + width: 'short', + context: 'formatting' + }) // Tuesday case 'iiii': default: - return localize.day(dayOfWeek, {width: 'wide', context: 'formatting'}) + return localize.day(dayOfWeek, { width: 'wide', context: 'formatting' }) } }, // AM or PM - a: function (date, token, localize) { + a: function(date, token, localize) { var hours = date.getUTCHours() - var dayPeriodEnumValue = (hours / 12) >= 1 ? 'pm' : 'am' + var dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am' switch (token) { case 'a': case 'aa': case 'aaa': - return localize.dayPeriod(dayPeriodEnumValue, {width: 'abbreviated', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'abbreviated', + context: 'formatting' + }) case 'aaaaa': - return localize.dayPeriod(dayPeriodEnumValue, {width: 'narrow', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'narrow', + context: 'formatting' + }) case 'aaaa': default: - return localize.dayPeriod(dayPeriodEnumValue, {width: 'wide', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'wide', + context: 'formatting' + }) } }, // AM, PM, midnight, noon - b: function (date, token, localize) { + b: function(date, token, localize) { var hours = date.getUTCHours() var dayPeriodEnumValue if (hours === 12) { @@ -439,24 +488,33 @@ var formatters = { } else if (hours === 0) { dayPeriodEnumValue = dayPeriodEnum.midnight } else { - dayPeriodEnumValue = (hours / 12) >= 1 ? 'pm' : 'am' + dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am' } switch (token) { case 'b': case 'bb': case 'bbb': - return localize.dayPeriod(dayPeriodEnumValue, {width: 'abbreviated', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'abbreviated', + context: 'formatting' + }) case 'bbbbb': - return localize.dayPeriod(dayPeriodEnumValue, {width: 'narrow', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'narrow', + context: 'formatting' + }) case 'bbbb': default: - return localize.dayPeriod(dayPeriodEnumValue, {width: 'wide', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'wide', + context: 'formatting' + }) } }, // in the morning, in the afternoon, in the evening, at night - B: function (date, token, localize) { + B: function(date, token, localize) { var hours = date.getUTCHours() var dayPeriodEnumValue if (hours >= 17) { @@ -473,99 +531,97 @@ var formatters = { case 'B': case 'BB': case 'BBB': - return localize.dayPeriod(dayPeriodEnumValue, {width: 'abbreviated', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'abbreviated', + context: 'formatting' + }) case 'BBBBB': - return localize.dayPeriod(dayPeriodEnumValue, {width: 'narrow', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'narrow', + context: 'formatting' + }) case 'BBBB': default: - return localize.dayPeriod(dayPeriodEnumValue, {width: 'wide', context: 'formatting'}) + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'wide', + context: 'formatting' + }) } }, // Hour [1-12] - h: function (date, token, localize, options) { - var hours = date.getUTCHours() % 12 - - if (hours === 0) { - hours = 12 - } - + h: function(date, token, localize) { if (token === 'ho') { - return localize.ordinalNumber(hours, {unit: 'hour'}) + var hours = date.getUTCHours() % 12 + if (hours === 0) hours = 12 + return localize.ordinalNumber(hours, { unit: 'hour' }) } - return addLeadingZeros(hours, token.length) + return lightFormatters.h(date, token) }, // Hour [0-23] - H: function (date, token, localize, options) { - var hours = date.getUTCHours() - + H: function(date, token, localize) { if (token === 'Ho') { - return localize.ordinalNumber(hours, {unit: 'hour'}) + return localize.ordinalNumber(date.getUTCHours(), { unit: 'hour' }) } - return addLeadingZeros(hours, token.length) + return lightFormatters.H(date, token) }, // Hour [0-11] - K: function (date, token, localize, options) { + K: function(date, token, localize) { var hours = date.getUTCHours() % 12 if (token === 'Ko') { - return localize.ordinalNumber(hours, {unit: 'hour'}) + return localize.ordinalNumber(hours, { unit: 'hour' }) } return addLeadingZeros(hours, token.length) }, // Hour [1-24] - k: function (date, token, localize, options) { + k: function(date, token, localize) { var hours = date.getUTCHours() - - if (hours === 0) { - hours = 24 - } + if (hours === 0) hours = 24 if (token === 'ko') { - return localize.ordinalNumber(hours, {unit: 'hour'}) + return localize.ordinalNumber(hours, { unit: 'hour' }) } return addLeadingZeros(hours, token.length) }, // Minute - m: function (date, token, localize, options) { - var minutes = date.getUTCMinutes() - + m: function(date, token, localize) { if (token === 'mo') { - return localize.ordinalNumber(minutes, {unit: 'minute'}) + return localize.ordinalNumber(date.getUTCMinutes(), { unit: 'minute' }) } - return addLeadingZeros(minutes, token.length) + return lightFormatters.m(date, token) }, // Second - s: function (date, token, localize, options) { - var seconds = date.getUTCSeconds() - + s: function(date, token, localize) { if (token === 'so') { - return localize.ordinalNumber(seconds, {unit: 'second'}) + return localize.ordinalNumber(date.getUTCSeconds(), { unit: 'second' }) } - return addLeadingZeros(seconds, token.length) + return lightFormatters.s(date, token) }, // Fraction of second - S: function (date, token, localize, options) { + S: function(date, token, localize, options) { var numberOfDigits = token.length var milliseconds = date.getUTCMilliseconds() - var fractionalSeconds = Math.floor(milliseconds * Math.pow(10, numberOfDigits - 3)) + var fractionalSeconds = Math.floor( + milliseconds * Math.pow(10, numberOfDigits - 3) + ) return addLeadingZeros(fractionalSeconds, numberOfDigits) }, // Timezone (ISO-8601. If offset is 0, output is always `'Z'`) - X: function (date, token, localize, options) { + X: function(date, token, _localize, options) { var originalDate = options._originalDate || date var timezoneOffset = originalDate.getTimezoneOffset() @@ -596,7 +652,7 @@ var formatters = { }, // Timezone (ISO-8601. If offset is 0, output is `'+00:00'` or equivalent) - x: function (date, token, localize, options) { + x: function(date, token, _localize, options) { var originalDate = options._originalDate || date var timezoneOffset = originalDate.getTimezoneOffset() @@ -623,7 +679,7 @@ var formatters = { }, // Timezone (GMT) - O: function (date, token, localize, options) { + O: function(date, token, localize, options) { var originalDate = options._originalDate || date var timezoneOffset = originalDate.getTimezoneOffset() @@ -641,7 +697,7 @@ var formatters = { }, // Timezone (specific non-location) - z: function (date, token, localize, options) { + z: function(date, token, localize, options) { var originalDate = options._originalDate || date var timezoneOffset = originalDate.getTimezoneOffset() @@ -659,39 +715,33 @@ var formatters = { }, // Seconds timestamp - t: function (date, token, localize, options) { + t: function(date, token, localize, options) { var originalDate = options._originalDate || date var timestamp = Math.floor(originalDate.getTime() / 1000) return addLeadingZeros(timestamp, token.length) }, // Milliseconds timestamp - T: function (date, token, localize, options) { + T: function(date, token, localize, options) { var originalDate = options._originalDate || date var timestamp = originalDate.getTime() return addLeadingZeros(timestamp, token.length) } } -function addLeadingZeros (number, targetLength) { - var sign = number < 0 ? '-' : '' - var output = Math.abs(number).toString() - while (output.length < targetLength) { - output = '0' + output - } - return sign + output -} - -function formatTimezone (offset, dirtyDelimiter) { - var delimiter = dirtyDelimiter || '' +function formatTimezoneShort(offset, dirtyDelimiter) { var sign = offset > 0 ? '-' : '+' var absOffset = Math.abs(offset) - var hours = addLeadingZeros(Math.floor(absOffset / 60), 2) - var minutes = addLeadingZeros(absOffset % 60, 2) - return sign + hours + delimiter + minutes + var hours = Math.floor(absOffset / 60) + var minutes = absOffset % 60 + if (minutes === 0) { + return sign + String(hours) + } + var delimiter = dirtyDelimiter || '' + return sign + String(hours) + delimiter + addLeadingZeros(minutes, 2) } -function formatTimezoneWithOptionalMinutes (offset, dirtyDelimiter) { +function formatTimezoneWithOptionalMinutes(offset, dirtyDelimiter) { if (offset % 60 === 0) { var sign = offset > 0 ? '-' : '+' return sign + addLeadingZeros(Math.abs(offset) / 60, 2) @@ -699,16 +749,13 @@ function formatTimezoneWithOptionalMinutes (offset, dirtyDelimiter) { return formatTimezone(offset, dirtyDelimiter) } -function formatTimezoneShort (offset, dirtyDelimiter) { +function formatTimezone(offset, dirtyDelimiter) { + var delimiter = dirtyDelimiter || '' var sign = offset > 0 ? '-' : '+' var absOffset = Math.abs(offset) - var hours = Math.floor(absOffset / 60) - var minutes = absOffset % 60 - if (minutes === 0) { - return sign + String(hours) - } - var delimiter = dirtyDelimiter || '' - return sign + String(hours) + delimiter + addLeadingZeros(minutes, 2) + var hours = addLeadingZeros(Math.floor(absOffset / 60), 2) + var minutes = addLeadingZeros(absOffset % 60, 2) + return sign + hours + delimiter + minutes } export default formatters diff --git a/src/_lib/format/lightFormatters/index.js b/src/_lib/format/lightFormatters/index.js new file mode 100644 index 0000000000..b04494ed92 --- /dev/null +++ b/src/_lib/format/lightFormatters/index.js @@ -0,0 +1,115 @@ +import addLeadingZeros from '../../addLeadingZeros/index.js' + +/* + * | | Unit | | Unit | + * |-----|--------------------------------|-----|--------------------------------| + * | a | AM, PM | A* | Milliseconds in day | + * | c | Stand-alone local day of week | C* | Localized hour w/ day period | + * | d | Day of month | D | Day of year | + * | e | Local day of week | E | Day of week | + * | f | | F* | Day of week in month | + * | g* | Modified Julian day | G | Era | + * | h | Hour [1-12] | H | Hour [0-23] | + * | i! | ISO day of week | I! | ISO week of year | + * | j* | Localized hour w/ day period | J* | Localized hour w/o day period | + * | k | Hour [1-24] | K | Hour [0-11] | + * | l* | (deprecated) | L | Stand-alone month | + * | m | Minute | M | Month | + * | n | | N | | + * | o! | Ordinal number modifier | O | Timezone (GMT) | + * | p! | Long localized time | P! | Long localized date | + * | q | Stand-alone quarter | Q | Quarter | + * | r* | Related Gregorian year | R! | ISO week-numbering year | + * | s | Second | S | Fraction of second | + * | t! | Seconds timestamp | T! | Milliseconds timestamp | + * | u | Extended year | U* | Cyclic year | + * | v* | Timezone (generic non-locat.) | V* | Timezone (location) | + * | w | Local week of year | W* | Week of month | + * | x | Timezone (ISO-8601 w/o Z) | X | Timezone (ISO-8601) | + * | y | Year (abs) | Y | Local week-numbering year | + * | z | Timezone (specific non-locat.) | Z* | Timezone (aliases) | + * + * Letters marked by * are not implemented but reserved by Unicode standard. + * + * Letters marked by ! are non-standard, but implemented by date-fns: + * - `o` modifies the previous token to turn it into an ordinal (see `format` docs) + * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days, + * i.e. 7 for Sunday, 1 for Monday, etc. + * - `I` is ISO week of year, as opposed to `w` which is local week of year. + * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year. + * `R` is supposed to be used in conjunction with `I` and `i` + * for universal ISO week-numbering date, whereas + * `Y` is supposed to be used in conjunction with `w` and `e` + * for week-numbering date specific to the locale. + * - `P` is long localized date format + * - `p` is long localized time format + */ + +var formatters = { + // Year + y: function(date, token) { + // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens + // | Year | y | yy | yyy | yyyy | yyyyy | + // |----------|-------|----|-------|-------|-------| + // | AD 1 | 1 | 01 | 001 | 0001 | 00001 | + // | AD 12 | 12 | 12 | 012 | 0012 | 00012 | + // | AD 123 | 123 | 23 | 123 | 0123 | 00123 | + // | AD 1234 | 1234 | 34 | 1234 | 1234 | 01234 | + // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 | + + var signedYear = date.getUTCFullYear() + // Returns 1 for 1 BC (which is year 0 in JavaScript) + var year = signedYear > 0 ? signedYear : 1 - signedYear + return addLeadingZeros(token === 'yy' ? year % 100 : year, token.length) + }, + + // Month + M: function(date, token) { + var month = date.getUTCMonth() + return token === 'M' ? String(month + 1) : addLeadingZeros(month + 1, 2) + }, + + // Day of the month + d: function(date, token) { + return addLeadingZeros(date.getUTCDate(), token.length) + }, + + // AM or PM + a: function(date, token) { + var dayPeriodEnumValue = date.getUTCHours() / 12 >= 1 ? 'pm' : 'am' + + switch (token) { + case 'a': + case 'aa': + case 'aaa': + return dayPeriodEnumValue.toUpperCase() + case 'aaaaa': + return dayPeriodEnumValue[0] + case 'aaaa': + default: + return dayPeriodEnumValue === 'am' ? 'a.m.' : 'p.m.' + } + }, + + // Hour [1-12] + h: function(date, token) { + return addLeadingZeros(date.getUTCHours() % 12 || 12, token.length) + }, + + // Hour [0-23] + H: function(date, token) { + return addLeadingZeros(date.getUTCHours(), token.length) + }, + + // Minute + m: function(date, token) { + return addLeadingZeros(date.getUTCMinutes(), token.length) + }, + + // Second + s: function(date, token) { + return addLeadingZeros(date.getUTCSeconds(), token.length) + } +} + +export default formatters diff --git a/src/format/_lib/longFormatters/index.js b/src/_lib/format/longFormatters/index.js similarity index 51% rename from src/format/_lib/longFormatters/index.js rename to src/_lib/format/longFormatters/index.js index 45c4d6f58f..0a830982cc 100644 --- a/src/format/_lib/longFormatters/index.js +++ b/src/_lib/format/longFormatters/index.js @@ -1,32 +1,32 @@ -function dateLongFormatter (pattern, formatLong, options) { +function dateLongFormatter(pattern, formatLong, options) { switch (pattern) { case 'P': - return formatLong.date({width: 'short'}) + return formatLong.date({ width: 'short' }) case 'PP': - return formatLong.date({width: 'medium'}) + return formatLong.date({ width: 'medium' }) case 'PPP': - return formatLong.date({width: 'long'}) + return formatLong.date({ width: 'long' }) case 'PPPP': default: - return formatLong.date({width: 'full'}) + return formatLong.date({ width: 'full' }) } } -function timeLongFormatter (pattern, formatLong, options) { +function timeLongFormatter(pattern, formatLong, options) { switch (pattern) { case 'p': - return formatLong.time({width: 'short'}) + return formatLong.time({ width: 'short' }) case 'pp': - return formatLong.time({width: 'medium'}) + return formatLong.time({ width: 'medium' }) case 'ppp': - return formatLong.time({width: 'long'}) + return formatLong.time({ width: 'long' }) case 'pppp': default: - return formatLong.time({width: 'full'}) + return formatLong.time({ width: 'full' }) } } -function dateTimeLongFormatter (pattern, formatLong, options) { +function dateTimeLongFormatter(pattern, formatLong, options) { var matchResult = pattern.match(/(P+)(p+)?/) var datePattern = matchResult[1] var timePattern = matchResult[2] @@ -39,17 +39,17 @@ function dateTimeLongFormatter (pattern, formatLong, options) { switch (datePattern) { case 'P': - dateTimeFormat = formatLong.dateTime({width: 'short'}) + dateTimeFormat = formatLong.dateTime({ width: 'short' }) break case 'PP': - dateTimeFormat = formatLong.dateTime({width: 'medium'}) + dateTimeFormat = formatLong.dateTime({ width: 'medium' }) break case 'PPP': - dateTimeFormat = formatLong.dateTime({width: 'long'}) + dateTimeFormat = formatLong.dateTime({ width: 'long' }) break case 'PPPP': default: - dateTimeFormat = formatLong.dateTime({width: 'full'}) + dateTimeFormat = formatLong.dateTime({ width: 'full' }) break } diff --git a/src/format/index.js b/src/format/index.js index b6e28bbc9c..0a0b4aa902 100644 --- a/src/format/index.js +++ b/src/format/index.js @@ -3,8 +3,8 @@ import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMillisec import toDate from '../toDate/index.js' import isValid from '../isValid/index.js' import defaultLocale from '../locale/en-US/index.js' -import formatters from './_lib/formatters/index.js' -import longFormatters from './_lib/longFormatters/index.js' +import formatters from '../_lib/format/formatters/index.js' +import longFormatters from '../_lib/format/longFormatters/index.js' import subMilliseconds from '../subMilliseconds/index.js' import { isProtectedToken, diff --git a/src/lightFormat/index.js b/src/lightFormat/index.js new file mode 100644 index 0000000000..cc63c0f4d2 --- /dev/null +++ b/src/lightFormat/index.js @@ -0,0 +1,134 @@ +import toDate from '../toDate/index.js' +import formatters from '../_lib/format/lightFormatters/index.js' +import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js' +import isValid from '../isValid/index.js' +import subMilliseconds from '../subMilliseconds/index.js' + +// This RegExp consists of three parts separated by `|`: +// - (\w)\1* matches any sequences of the same letter +// - '' matches two quote characters in a row +// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('), +// except a single quote symbol, which ends the sequence. +// Two quote characters do not end the sequence. +// If there is no matching single quote +// then the sequence will continue until the end of the string. +// - . matches any single character unmatched by previous parts of the RegExps +var formattingTokensRegExp = /(\w)\1*|''|'(''|[^'])+('|$)|./g + +var escapedStringRegExp = /^'(.*?)'?$/ +var doubleQuoteRegExp = /''/g + +/** + * @name lightFormat + * @category Common Helpers + * @summary Format the date. + * + * @description + * Return the formatted date string in the given format. Unlike `format`, + * `lightFormat` doesn't use locales and outputs date using the most popular tokens. + * + * > ⚠️ Please note that the `lightFormat` tokens differ from Moment.js and other libraries. + * > See: https://git.io/fxCyr + * + * The characters wrapped between two single quotes characters (') are escaped. + * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote. + * (see the last example) + * + * Format of the string is based on Unicode Technical Standard #35: + * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table + * with a few additions (see note 7 below the table). + * + * Accepted patterns: + * | Unit | Pattern | Result examples | + * |---------------------------------|---------|-----------------------------------| + * | AM, PM | a..aaa | AM, PM | + * | | aaaa | a.m., p.m. | + * | | aaaaa | a, p | + * | Calendar year | y | 44, 1, 1900, 2017 | + * | | yy | 44, 01, 00, 17 | + * | | yyy | 044, 001, 000, 017 | + * | | yyyy | 0044, 0001, 1900, 2017 | + * | Month (formatting) | M | 1, 2, ..., 12 | + * | | MM | 01, 02, ..., 12 | + * | Day of month | d | 1, 2, ..., 31 | + * | | dd | 01, 02, ..., 31 | + * | Hour [1-12] | h | 1, 2, ..., 11, 12 | + * | | hh | 01, 02, ..., 11, 12 | + * | Hour [0-23] | H | 0, 1, 2, ..., 23 | + * | | HH | 00, 01, 02, ..., 23 | + * | Minute | m | 0, 1, ..., 59 | + * | | mm | 00, 01, ..., 59 | + * | Second | s | 0, 1, ..., 59 | + * | | ss | 00, 01, ..., 59 | + * | Timezone (ISO-8601 w/ Z) | X | -08, +0530, Z | + * | | XX | -0800, +0530, Z | + * | | XXX | -08:00, +05:30, Z | + * | | XXXX | -0800, +0530, Z, +123456 | + * | | XXXXX | -08:00, +05:30, Z, +12:34:56 | + * | Timezone (ISO-8601 w/o Z) | x | -08, +0530, +00 | + * | | xx | -0800, +0530, +0000 | + * | | xxx | -08:00, +05:30, +00:00 | + * | | xxxx | -0800, +0530, +0000, +123456 | + * | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | + * + * @param {Date|String|Number} date - the original date + * @param {String} format - the string of tokens + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {String} the formatted date string + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * var result = format(new Date(2014, 1, 11), 'yyyy-MM-dd') + * //=> '1987-02-11' + */ +export default function lightFormat(dirtyDate, dirtyFormatStr, options) { + if (arguments.length < 2) { + throw new TypeError( + '2 arguments required, but only ' + arguments.length + ' present' + ) + } + + var formatStr = String(dirtyFormatStr) + + var originalDate = toDate(dirtyDate, options) + + if (!isValid(originalDate, options)) { + return 'Invalid Date' + } + + // Convert the date in system timezone to the same date in UTC+00:00 timezone. + // This ensures that when UTC functions will be implemented, locales will be compatible with them. + // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376 + var timezoneOffset = getTimezoneOffsetInMilliseconds(originalDate) + var utcDate = subMilliseconds(originalDate, timezoneOffset, options) + + var result = formatStr + .match(formattingTokensRegExp) + .map(function(substring) { + // Replace two single quote characters with one single quote character + if (substring === "''") { + return "'" + } + + var firstCharacter = substring[0] + if (firstCharacter === "'") { + return cleanEscapedString(substring) + } + + var formatter = formatters[firstCharacter] + if (formatter) { + return formatter(utcDate, substring, null, {}) + } + + return substring + }) + .join('') + + return result +} + +function cleanEscapedString(input) { + return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, "'") +} diff --git a/src/lightFormat/test.js b/src/lightFormat/test.js new file mode 100644 index 0000000000..8cb9bfbe2b --- /dev/null +++ b/src/lightFormat/test.js @@ -0,0 +1,154 @@ +// @flow +/* eslint-env mocha */ + +import assert from 'power-assert' +import lightFormat from '.' + +describe('lightFormat', () => { + const date = new Date(1986, 3 /* Apr */, 4, 10, 32, 55, 123) + + var offset = date.getTimezoneOffset() + var absoluteOffset = Math.abs(offset) + var hours = Math.floor(absoluteOffset / 60) + var hoursLeadingZero = hours < 10 ? '0' : '' + var minutes = absoluteOffset % 60 + var minutesLeadingZero = minutes < 10 ? '0' : '' + var sign = offset > 0 ? '-' : '+' + + var timezone = + sign + hoursLeadingZero + hours + ':' + minutesLeadingZero + minutes + var timezoneShort = timezone.replace(':', '') + var timezoneWithOptionalMinutesShort = + minutes === 0 ? sign + hoursLeadingZero + hours : timezoneShort + + var timezoneWithZ = offset === 0 ? 'Z' : timezone + var timezoneWithZShort = offset === 0 ? 'Z' : timezoneShort + var timezoneWithOptionalMinutesAndZShort = + offset === 0 ? 'Z' : timezoneWithOptionalMinutesShort + + it('accepts a string', () => { + var date = new Date(1987, 1, 11).toISOString() + assert(lightFormat(date, 'yyyy-MM-dd') === '1987-02-11') + }) + + it('accepts a timestamp', () => { + var date = new Date(2014, 3, 4).getTime() + assert(lightFormat(date, 'yyyy-MM-dd') === '2014-04-04') + }) + + it('escapes characters between the single quote characters', () => { + var result = lightFormat(date, "'yyyy-'MM-dd'D yyyy-'MM-dd'") + assert(result === 'yyyy-04-04D yyyy-04-04') + }) + + it('two single quote characters are transformed into a "real" single quote', () => { + var date = new Date(2014, 3, 4, 5) + assert(lightFormat(date, "''h 'o''clock'''") === "'5 o'clock'") + }) + + describe('year', () => { + describe('regular year', () => { + it('works as expected', () => { + var result = lightFormat(date, 'y yy yyy yyyy yyyyy') + assert(result === '1986 86 1986 1986 01986') + }) + + it('1 BC formats as 1', () => { + var date = new Date(0, 0 /* Jan */, 1) + date.setFullYear(0) + var result = lightFormat(date, 'y') + assert(result === '1') + }) + + it('2 BC formats as 2', () => { + var date = new Date(0, 0 /* Jan */, 1) + date.setFullYear(-1) + var result = lightFormat(date, 'y') + assert(result === '2') + }) + }) + }) + + describe('month', () => { + it('formatting month', () => { + var result = lightFormat(date, 'M MM') + assert(result === '4 04') + }) + }) + + describe('day', () => { + it('date', () => { + var result = lightFormat(date, 'd dd') + assert(result === '4 04') + }) + }) + + describe('hour', () => { + it('hour [1-12]', () => { + var result = lightFormat( + new Date(2018, 0 /* Jan */, 1, 0, 0, 0, 0), + 'h hh' + ) + assert(result === '12 12') + }) + + it('hour [0-23]', () => { + var result = lightFormat( + new Date(2018, 0 /* Jan */, 1, 0, 0, 0, 0), + 'H HH' + ) + assert(result === '0 00') + }) + + describe('AM, PM', () => { + it('works as expected', () => { + var result = lightFormat( + new Date(2018, 0 /* Jan */, 1, 0, 0, 0, 0), + 'a aa aaa aaaa aaaaa' + ) + assert(result === 'AM AM AM a.m. a') + }) + + it('12 PM', () => { + var date = new Date(1986, 3 /* Apr */, 4, 12, 0, 0, 900) + assert(lightFormat(date, 'h H a') === '12 12 PM') + }) + + it('12 AM', () => { + var date = new Date(1986, 3 /* Apr */, 6, 0, 0, 0, 900) + assert(lightFormat(date, 'h H a') === '12 0 AM') + }) + }) + }) + + it('minute', () => { + var result = lightFormat(date, 'm mm') + assert(result === '32 32') + }) + + describe('second', () => { + it('second', () => { + var result = lightFormat(date, 's ss') + assert(result === '55 55') + }) + }) + + it("returns String('Invalid Date') if the date isn't valid", () => { + assert(lightFormat(new Date(NaN), 'MMMM d, yyyy') === 'Invalid Date') + }) + + it('implicitly converts `formatString`', () => { + // eslint-disable-next-line no-new-wrappers + var formatString = new String('yyyy-MM-dd') + + var date = new Date(2014, 3, 4) + + // $ExpectedMistake + assert(lightFormat(date, formatString) === '2014-04-04') + }) + + it('throws TypeError exception if passed less than 2 arguments', () => { + assert.throws(lightFormat.bind(null), TypeError) + assert.throws(lightFormat.bind(null, 1), TypeError) + }) +}) diff --git a/src/toDate/index.js b/src/toDate/index.js index 0947e13356..001105eff9 100644 --- a/src/toDate/index.js +++ b/src/toDate/index.js @@ -7,41 +7,14 @@ var DEFAULT_ADDITIONAL_DIGITS = 2 var patterns = { dateTimeDelimiter: /[T ]/, - plainTime: /:/, timeZoneDelimiter: /[Z ]/i, - - // year tokens - YY: /^(\d{2})$/, - YYY: [ - /^([+-]\d{2})$/, // 0 additional digits - /^([+-]\d{3})$/, // 1 additional digit - /^([+-]\d{4})$/ // 2 additional digits - ], - YYYY: /^(\d{4})/, - YYYYY: [ - /^([+-]\d{4})/, // 0 additional digits - /^([+-]\d{5})/, // 1 additional digit - /^([+-]\d{6})/ // 2 additional digits - ], - - // date tokens - MM: /^-(\d{2})$/, - DDD: /^-?(\d{3})$/, - MMDD: /^-?(\d{2})-?(\d{2})$/, - Www: /^-?W(\d{2})$/, - WwwD: /^-?W(\d{2})-?(\d{1})$/, - - HH: /^(\d{2}([.,]\d*)?)$/, - HHMM: /^(\d{2}):?(\d{2}([.,]\d*)?)$/, - HHMMSS: /^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/, - - // timezone tokens - timezone: /([Z+-].*)$/, - timezoneZ: /^(Z)$/, - timezoneHH: /^([+-])(\d{2})$/, - timezoneHHMM: /^([+-])(\d{2}):?(\d{2})$/ + timezone: /([Z+-].*)$/ } +var dateRegex = /^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/ +var timeRegex = /^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/ +var timezoneRegex = /^([+-])(\d{2})(?::?(\d{2}))?$/ + /** * @name toDate * @category Common Helpers @@ -115,10 +88,6 @@ export default function toDate(argument, dirtyOptions) { ) } - if (argument === null) { - return new Date(NaN) - } - var options = dirtyOptions || {} var additionalDigits = @@ -156,56 +125,46 @@ export default function toDate(argument, dirtyOptions) { } var dateStrings = splitDateString(argument) - var parseYearResult = parseYear(dateStrings.date, additionalDigits) - var year = parseYearResult.year - var restDateString = parseYearResult.restDateString - - var date = parseDate(restDateString, year) + var date = parseDate(parseYearResult.restDateString, parseYearResult.year) - if (isNaN(date)) { + if (isNaN(date) || !date) { return new Date(NaN) } - if (date) { - var timestamp = date.getTime() - var time = 0 - var offset + var timestamp = date.getTime() + var time = 0 + var offset - if (dateStrings.time) { - time = parseTime(dateStrings.time) - - if (isNaN(time)) { - return new Date(NaN) - } + if (dateStrings.time) { + time = parseTime(dateStrings.time) + if (isNaN(time)) { + return new Date(NaN) } + } - if (dateStrings.timezone) { - offset = parseTimezone(dateStrings.timezone) - if (isNaN(offset)) { - return new Date(NaN) - } - } else { - var fullTime = timestamp + time - var fullTimeDate = new Date(fullTime) - - offset = getTimezoneOffsetInMilliseconds(fullTimeDate) - - // Adjust time when it's coming from DST - var fullTimeDateNextDay = new Date(fullTime) - fullTimeDateNextDay.setDate(fullTimeDate.getDate() + 1) - var offsetDiff = - getTimezoneOffsetInMilliseconds(fullTimeDateNextDay) - - getTimezoneOffsetInMilliseconds(fullTimeDate) - if (offsetDiff > 0) { - offset += offsetDiff - } + if (dateStrings.timezone) { + offset = parseTimezone(dateStrings.timezone) + if (isNaN(offset)) { + return new Date(NaN) } - - return new Date(timestamp + time + offset) } else { - return new Date(NaN) + var fullTime = timestamp + time + var fullTimeDate = new Date(fullTime) + + offset = getTimezoneOffsetInMilliseconds(fullTimeDate) + + // Adjust time when it's coming from DST + var fullTimeDateNextDay = new Date(fullTime) + fullTimeDateNextDay.setDate(fullTimeDate.getDate() + 1) + var offsetDiff = + getTimezoneOffsetInMilliseconds(fullTimeDateNextDay) - offset + if (offsetDiff > 0) { + offset += offsetDiff + } } + + return new Date(timestamp + time + offset) } function splitDateString(dateString) { @@ -213,7 +172,7 @@ function splitDateString(dateString) { var array = dateString.split(patterns.dateTimeDelimiter) var timeString - if (patterns.plainTime.test(array[0])) { + if (/:/.test(array[0])) { dateStrings.date = null timeString = array[0] } else { @@ -239,314 +198,152 @@ function splitDateString(dateString) { } function parseYear(dateString, additionalDigits) { - var patternYYY = patterns.YYY[additionalDigits] - var patternYYYYY = patterns.YYYYY[additionalDigits] - - var token - - // YYYY or ±YYYYY - token = patterns.YYYY.exec(dateString) || patternYYYYY.exec(dateString) - if (token) { - var yearString = token[1] - return { - year: parseInt(yearString, 10), - restDateString: dateString.slice(yearString.length) - } - } + var regex = new RegExp( + '^(?:(\\d{4}|[+-]\\d{' + + (4 + additionalDigits) + + '})|(\\d{2}|[+-]\\d{' + + (2 + additionalDigits) + + '})$)' + ) + + var captures = dateString.match(regex) + // Invalid ISO-formatted year + if (!captures) return { year: null } - // YY or ±YYY - token = patterns.YY.exec(dateString) || patternYYY.exec(dateString) - if (token) { - var centuryString = token[1] - return { - year: parseInt(centuryString, 10) * 100, - restDateString: dateString.slice(centuryString.length) - } - } + var year = captures[1] && parseInt(captures[1]) + var century = captures[2] && parseInt(captures[2]) - // Invalid ISO-formatted year return { - year: null + year: century == null ? year : century * 100, + restDateString: dateString.slice((captures[1] || captures[2]).length) } } function parseDate(dateString, year) { // Invalid ISO-formatted year - if (year === null) { - return null - } - - var token - var date - var month - var week + if (year === null) return null - // YYYY - if (dateString.length === 0) { - date = new Date(0) - date.setUTCFullYear(year) - return date - } + var captures = dateString.match(dateRegex) + // Invalid ISO-formatted string + if (!captures) return null - // YYYY-MM - token = patterns.MM.exec(dateString) - if (token) { - date = new Date(0) - month = parseInt(token[1], 10) - 1 + var isWeekDate = !!captures[4] + var dayOfYear = parseDateUnit(captures[1]) + var month = parseDateUnit(captures[2]) - 1 + var day = parseDateUnit(captures[3]) + var week = parseDateUnit(captures[4]) - 1 + var dayOfWeek = parseDateUnit(captures[5]) - 1 - if (!validateDate(year, month)) { - return new Date(NaN) - } - - date.setUTCFullYear(year, month) - return date - } - - // YYYY-DDD or YYYYDDD - token = patterns.DDD.exec(dateString) - if (token) { - date = new Date(0) - var dayOfYear = parseInt(token[1], 10) - - if (!validateDayOfYearDate(year, dayOfYear)) { + if (isWeekDate) { + if (!validateWeekDate(year, week, dayOfWeek)) { return new Date(NaN) } - - date.setUTCFullYear(year, 0, dayOfYear) - return date - } - - // YYYY-MM-DD or YYYYMMDD - token = patterns.MMDD.exec(dateString) - if (token) { - date = new Date(0) - month = parseInt(token[1], 10) - 1 - var day = parseInt(token[2], 10) - - if (!validateDate(year, month, day)) { + return dayOfISOWeekYear(year, week, dayOfWeek) + } else { + var date = new Date(0) + if ( + !validateDate(year, month, day) || + !validateDayOfYearDate(year, dayOfYear) + ) { return new Date(NaN) } - - date.setUTCFullYear(year, month, day) + date.setUTCFullYear(year, month, Math.max(dayOfYear, day)) return date } +} - // YYYY-Www or YYYYWww - token = patterns.Www.exec(dateString) - if (token) { - week = parseInt(token[1], 10) - 1 - - if (!validateWeekDate(year, week)) { - return new Date(NaN) - } - - return dayOfISOWeekYear(year, week) - } - - // YYYY-Www-D or YYYYWwwD - token = patterns.WwwD.exec(dateString) - if (token) { - week = parseInt(token[1], 10) - 1 - var dayOfWeek = parseInt(token[2], 10) - 1 - - if (!validateWeekDate(year, week, dayOfWeek)) { - return new Date(NaN) - } - - return dayOfISOWeekYear(year, week, dayOfWeek) - } - - // Invalid ISO-formatted date - return null +function parseDateUnit(value) { + return value ? parseInt(value) : 1 } function parseTime(timeString) { - var token - var hours - var minutes + var captures = timeString.match(timeRegex) + if (!captures) return null // Invalid ISO-formatted time - // hh - token = patterns.HH.exec(timeString) - if (token) { - hours = parseFloat(token[1].replace(',', '.')) + var hours = parseTimeUnit(captures[1]) + var minutes = parseTimeUnit(captures[2]) + var seconds = parseTimeUnit(captures[3]) - if (!validateTime(hours)) { - return NaN - } - - return (hours % 24) * MILLISECONDS_IN_HOUR + if (!validateTime(hours, minutes, seconds)) { + return NaN } - // hh:mm or hhmm - token = patterns.HHMM.exec(timeString) - if (token) { - hours = parseInt(token[1], 10) - minutes = parseFloat(token[2].replace(',', '.')) - - if (!validateTime(hours, minutes)) { - return NaN - } - - return ( - (hours % 24) * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE - ) - } - - // hh:mm:ss or hhmmss - token = patterns.HHMMSS.exec(timeString) - if (token) { - hours = parseInt(token[1], 10) - minutes = parseInt(token[2], 10) - var seconds = parseFloat(token[3].replace(',', '.')) - - if (!validateTime(hours, minutes, seconds)) { - return NaN - } - - return ( - (hours % 24) * MILLISECONDS_IN_HOUR + - minutes * MILLISECONDS_IN_MINUTE + - seconds * 1000 - ) - } + return ( + (hours % 24) * MILLISECONDS_IN_HOUR + + minutes * MILLISECONDS_IN_MINUTE + + seconds * 1000 + ) +} - // Invalid ISO-formatted time - return null +function parseTimeUnit(value) { + return (value && parseFloat(value.replace(',', '.'))) || 0 } function parseTimezone(timezoneString) { - var token - var absoluteOffset - - // Z - token = patterns.timezoneZ.exec(timezoneString) - if (token) { - return 0 - } - - var hours - - // ±hh - token = patterns.timezoneHH.exec(timezoneString) - if (token) { - hours = parseInt(token[2], 10) - - if (!validateTimezone(hours)) { - return NaN - } - - absoluteOffset = hours * MILLISECONDS_IN_HOUR - return token[1] === '+' ? -absoluteOffset : absoluteOffset - } + if (timezoneString === 'Z') return 0 - // ±hh:mm or ±hhmm - token = patterns.timezoneHHMM.exec(timezoneString) - if (token) { - hours = parseInt(token[2], 10) - var minutes = parseInt(token[3], 10) + var captures = timezoneString.match(timezoneRegex) + if (!captures) return 0 - if (!validateTimezone(hours, minutes)) { - return NaN - } + var sign = captures[1] === '+' ? -1 : 1 + var hours = parseInt(captures[2]) + var minutes = (captures[3] && parseInt(captures[3])) || 0 - absoluteOffset = - hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE - return token[1] === '+' ? -absoluteOffset : absoluteOffset + if (!validateTimezone(hours, minutes)) { + return NaN } - return 0 + return ( + sign * (hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE) + ) } function dayOfISOWeekYear(isoWeekYear, week, day) { - week = week || 0 - day = day || 0 var date = new Date(0) date.setUTCFullYear(isoWeekYear, 0, 4) var fourthOfJanuaryDay = date.getUTCDay() || 7 - var diff = week * 7 + day + 1 - fourthOfJanuaryDay + var diff = (week || 0) * 7 + (day || 0) + 1 - fourthOfJanuaryDay date.setUTCDate(date.getUTCDate() + diff) return date } // Validation functions -var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -var DAYS_IN_MONTH_LEAP_YEAR = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] +// February is null to handle the leap year (using ||) +var daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] function isLeapYearIndex(year) { - return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0) + return year % 400 === 0 || (year % 4 === 0 && year % 100) } function validateDate(year, month, date) { - if (month < 0 || month > 11) { - return false - } - - if (date != null) { - if (date < 1) { - return false - } - - var isLeapYear = isLeapYearIndex(year) - if (isLeapYear && date > DAYS_IN_MONTH_LEAP_YEAR[month]) { - return false - } - if (!isLeapYear && date > DAYS_IN_MONTH[month]) { - return false - } - } - - return true + return !( + month < 0 || + month > 11 || + date < 1 || + date > (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28)) + ) } function validateDayOfYearDate(year, dayOfYear) { - if (dayOfYear < 1) { - return false - } - - var isLeapYear = isLeapYearIndex(year) - if (isLeapYear && dayOfYear > 366) { - return false - } - if (!isLeapYear && dayOfYear > 365) { - return false - } - - return true + return !(dayOfYear < 1 || dayOfYear > (isLeapYearIndex(year) ? 366 : 365)) } -function validateWeekDate(year, week, day) { - if (week < 0 || week > 52) { - return false - } - - if (day != null && (day < 0 || day > 6)) { - return false - } - - return true +function validateWeekDate(_year, week, day) { + return !(week < 0 || week > 52 || day < 0 || day > 6) } function validateTime(hours, minutes, seconds) { - if (hours != null && (hours < 0 || hours >= 25)) { - return false - } - - if (minutes != null && (minutes < 0 || minutes >= 60)) { - return false - } - - if (seconds != null && (seconds < 0 || seconds >= 60)) { - return false - } - - return true + return !( + seconds < 0 || + seconds >= 60 || + minutes < 0 || + minutes >= 60 || + hours < 0 || + hours >= 25 + ) } -function validateTimezone(hours, minutes) { - if (minutes != null && (minutes < 0 || minutes > 59)) { - return false - } - - return true +function validateTimezone(_hours, minutes) { + return !(minutes < 0 || minutes > 59) } diff --git a/src/toDate/test.js b/src/toDate/test.js index 533d15fc27..888cd0d449 100644 --- a/src/toDate/test.js +++ b/src/toDate/test.js @@ -4,420 +4,425 @@ import assert from 'power-assert' import toDate from '.' -describe('toDate', function () { - describe('date argument', function () { - it('returns a clone of the given date', function () { - var date = new Date(2016, 0, 1) - var dateClone = toDate(date) +describe('toDate', () => { + describe('date argument', () => { + it('returns a clone of the given date', () => { + const date = new Date(2016, 0, 1) + const dateClone = toDate(date) dateClone.setFullYear(2015) assert.deepEqual(date, new Date(2016, 0, 1)) }) }) - describe('timestamp argument', function () { - it('creates a date from the timestamp', function () { - var timestamp = new Date(2016, 0, 1, 23, 30, 45, 123).getTime() - var result = toDate(timestamp) + describe('timestamp argument', () => { + it('creates a date from the timestamp', () => { + const timestamp = new Date(2016, 0, 1, 23, 30, 45, 123).getTime() + const result = toDate(timestamp) assert.deepEqual(result, new Date(2016, 0, 1, 23, 30, 45, 123)) }) }) - describe('string argument', function () { - describe('centuries', function () { - it('parses YY', function () { - var result = toDate('20') + describe('string argument', () => { + describe('centuries', () => { + it('parses YY', () => { + const result = toDate('20') assert.deepEqual(result, new Date(2000, 0 /* Jan */, 1)) }) }) - describe('years', function () { - it('parses YYYY', function () { - var result = toDate('2014') + describe('years', () => { + it('parses YYYY', () => { + const result = toDate('2014') assert.deepEqual(result, new Date(2014, 0 /* Jan */, 1)) }) }) - describe('months', function () { - it('parses YYYY-MM', function () { - var result = toDate('2014-02') + describe('months', () => { + it('parses YYYY-MM', () => { + const result = toDate('2014-02') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 1)) }) }) - describe('weeks', function () { - it('parses YYYY-Www', function () { - var result = toDate('2014-W02') + describe('weeks', () => { + it('parses YYYY-Www', () => { + const result = toDate('2014-W02') assert.deepEqual(result, new Date(2014, 0 /* Jan */, 6)) }) - it('parses YYYYWww', function () { - var result = toDate('2014W02') + it('parses YYYYWww', () => { + const result = toDate('2014W02') assert.deepEqual(result, new Date(2014, 0 /* Jan */, 6)) }) }) - describe('calendar dates', function () { - it('parses YYYY-MM-DD', function () { - var result = toDate('2014-02-11') + describe('calendar dates', () => { + it('parses YYYY-MM-DD', () => { + const result = toDate('2014-02-11') assert.deepEqual(result, new Date(2014, 1, /* Feb */ 11)) }) - it('parses YYYYMMDD', function () { - var result = toDate('20140211') + it('parses YYYYMMDD', () => { + const result = toDate('20140211') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11)) }) }) - describe('week dates', function () { - it('parses YYYY-Www-D', function () { - var result = toDate('2014-W02-7') + describe('week dates', () => { + it('parses YYYY-Www-D', () => { + const result = toDate('2014-W02-7') assert.deepEqual(result, new Date(2014, 0 /* Jan */, 12)) }) - it('parses YYYYWwwD', function () { - var result = toDate('2014W027') + it('parses YYYYWwwD', () => { + const result = toDate('2014W027') assert.deepEqual(result, new Date(2014, 0 /* Jan */, 12)) }) - it('correctly handles years in which 4 January is Sunday', function () { - var result = toDate('2009-W01-1') + it('correctly handles years in which 4 January is Sunday', () => { + const result = toDate('2009-W01-1') assert.deepEqual(result, new Date(2008, 11 /* Dec */, 29)) }) }) - describe('ordinal dates', function () { - it('parses YYYY-DDD', function () { - var result = toDate('2014-026') + describe('ordinal dates', () => { + it('parses YYYY-DDD', () => { + const result = toDate('2014-026') assert.deepEqual(result, new Date(2014, 0 /* Jan */, 26)) }) - it('parses YYYYDDD', function () { - var result = toDate('2014026') + it('parses YYYYDDD', () => { + const result = toDate('2014026') assert.deepEqual(result, new Date(2014, 0 /* Jan */, 26)) }) }) - describe('date and time combined', function () { - it('parses YYYY-MM-DDThh:mm', function () { - var result = toDate('2014-02-11T11:30') + describe('date and time combined', () => { + it('parses YYYY-MM-DDThh:mm', () => { + const result = toDate('2014-02-11T11:30') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30)) }) - it('parses YYYY-MM-DDThhmm', function () { - var result = toDate('2014-02-11T1130') + it('parses YYYY-MM-DDThhmm', () => { + const result = toDate('2014-02-11T1130') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30)) }) - it('parses 24:00 as midnight', function () { - var result = toDate('2014-02-11T2400') + it('parses 24:00 as midnight', () => { + const result = toDate('2014-02-11T2400') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 0, 0)) }) }) - describe('extended century representation', function () { - it('parses century 101 BC - 2 BC', function () { - var result = toDate('-0001') - var date = new Date(-100, 0 /* Jan */, 1) + describe('extended century representation', () => { + it('parses century 101 BC - 2 BC', () => { + const result = toDate('-0001') + const date = new Date(-100, 0 /* Jan */, 1) date.setFullYear(-100) assert.deepEqual(result, date) }) - it('parses century 1 BC - 99 AD', function () { - var result = toDate('00') - var date = new Date(0, 0 /* Jan */, 1) + it('parses century 1 BC - 99 AD', () => { + const result = toDate('00') + const date = new Date(0, 0 /* Jan */, 1) date.setFullYear(0) assert.deepEqual(result, date) }) - it('parses centuries after 9999 AD', function () { - var result = toDate('+0123') + it('parses centuries after 9999 AD', () => { + const result = toDate('+0123') assert.deepEqual(result, new Date(12300, 0 /* Jan */, 1)) }) - it('allows to specify the number of additional digits', function () { - var result = toDate('-20', {additionalDigits: 0}) - var date = new Date(-2000, 0 /* Jan */, 1) + it('allows to specify the number of additional digits', () => { + const result = toDate('-20', { additionalDigits: 0 }) + const date = new Date(-2000, 0 /* Jan */, 1) date.setFullYear(-2000) assert.deepEqual(result, date) }) }) - describe('extended year representation', function () { - it('correctly parses years from 1 AD to 99 AD', function () { - var result = toDate('0095-07-02') - var date = new Date(0, 6 /* Jul */, 2) + describe('extended year representation', () => { + it('correctly parses years from 1 AD to 99 AD', () => { + const result = toDate('0095-07-02') + const date = new Date(0, 6 /* Jul */, 2) date.setFullYear(95) assert.deepEqual(result, date) }) - it('parses years after 9999 AD', function () { - var result = toDate('+012345-07-02') + it('parses years after 9999 AD', () => { + const result = toDate('+012345-07-02') assert.deepEqual(result, new Date(12345, 6 /* Jul */, 2)) }) - it('allows to specify the number of additional digits', function () { - var result = toDate('+12340702', {additionalDigits: 0}) + it('allows to specify the number of additional digits', () => { + const result = toDate('+12340702', { additionalDigits: 0 }) assert.deepEqual(result, new Date(1234, 6 /* Jul */, 2)) }) - it('parses year 1 BC', function () { - var result = toDate('0000-07-02') - var date = new Date(0, 6 /* Jul */, 2) + it('parses year 1 BC', () => { + const result = toDate('0000-07-02') + const date = new Date(0, 6 /* Jul */, 2) date.setFullYear(0) assert.deepEqual(result, date) }) - it('parses years less than 1 BC', function () { - var result = toDate('-000001-07-02') - var date = new Date(0, 6 /* Jul */, 2) + it('parses years less than 1 BC', () => { + const result = toDate('-000001-07-02') + const date = new Date(0, 6 /* Jul */, 2) date.setFullYear(-1) assert.deepEqual(result, date) }) }) - describe('float time', function () { - it('parses float hours', function () { - var result = toDate('2014-02-11T11.5') + describe('float time', () => { + it('parses float hours', () => { + const result = toDate('2014-02-11T11.5') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30)) }) - it('parses float minutes', function () { - var result = toDate('2014-02-11T11:30.5') + it('parses float minutes', () => { + const result = toDate('2014-02-11T11:30.5') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30, 30)) }) - it('parses float seconds', function () { - var result = toDate('2014-02-11T11:30:30.768') - assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30, 30, 768)) + it('parses float seconds', () => { + const result = toDate('2014-02-11T11:30:30.768') + assert.deepEqual( + result, + new Date(2014, 1 /* Feb */, 11, 11, 30, 30, 768) + ) }) - it('parses , as decimal mark', function () { - var result = toDate('2014-02-11T11,5') + it('parses , as decimal mark', () => { + const result = toDate('2014-02-11T11,5') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30)) }) }) - describe('timezones', function () { - context('when the date and the time are specified', function () { - it('parses Z', function () { - var result = toDate('2014-10-25T06:46:20Z') + describe('timezones', () => { + context('when the date and the time are specified', () => { + it('parses Z', () => { + const result = toDate('2014-10-25T06:46:20Z') assert.deepEqual(result, new Date('2014-10-25T13:46:20+07:00')) }) - it('parses ±hh:mm', function () { - var result = toDate('2014-10-25T13:46:20+07:00') + it('parses ±hh:mm', () => { + const result = toDate('2014-10-25T13:46:20+07:00') assert.deepEqual(result, new Date('2014-10-25T13:46:20+07:00')) }) - it('parses ±hhmm', function () { - var result = toDate('2014-10-25T03:46:20-0300') + it('parses ±hhmm', () => { + const result = toDate('2014-10-25T03:46:20-0300') assert.deepEqual(result, new Date('2014-10-25T13:46:20+07:00')) }) - it('parses ±hh', function () { - var result = toDate('2014-10-25T13:46:20+07') + it('parses ±hh', () => { + const result = toDate('2014-10-25T13:46:20+07') assert.deepEqual(result, new Date('2014-10-25T13:46:20+07:00')) }) }) - context('when the year and the month are specified', function () { - it('sets timezone correctly on yyyy-MMZ format', function () { - var result = toDate('2012-01Z') + context('when the year and the month are specified', () => { + it('sets timezone correctly on yyyy-MMZ format', () => { + const result = toDate('2012-01Z') assert.deepEqual(result, new Date('2012-01-01T00:00:00+00:00')) }) }) }) - describe('failure', function () { - it('returns `Invalid Date` if the string is not an ISO formatted date', function () { - var result = toDate(new Date(2014, 8 /* Sep */, 1, 11).toString()) + describe('failure', () => { + it('returns `Invalid Date` if the string is not an ISO formatted date', () => { + const result = toDate(new Date(2014, 8 /* Sep */, 1, 11).toString()) assert(result instanceof Date) assert(isNaN(result)) }) }) }) - describe('validation', function () { - describe('months', function () { - it('returns `Invalid Date` for invalid month', function () { - var result = toDate('2014-00') + describe('validation', () => { + describe('months', () => { + it('returns `Invalid Date` for invalid month', () => { + const result = toDate('2014-00') assert(result instanceof Date) assert(isNaN(result)) }) }) - describe('weeks', function () { - it('returns `Invalid Date` for invalid week', function () { - var result = toDate('2014-W00') + describe('weeks', () => { + it('returns `Invalid Date` for invalid week', () => { + const result = toDate('2014-W00') assert(result instanceof Date) assert(isNaN(result)) }) - it('returns `Invalid Date` for 54th week', function () { - var result = toDate('2014-W54') + it('returns `Invalid Date` for 54th week', () => { + const result = toDate('2014-W54') assert(result instanceof Date) assert(isNaN(result)) }) }) - describe('calendar dates', function () { - it('returns `Invalid Date` for invalid day of the month', function () { - var result = toDate('2012-02-30') + describe('calendar dates', () => { + it('returns `Invalid Date` for invalid day of the month', () => { + const result = toDate('2012-02-30') assert(result instanceof Date) assert(isNaN(result)) }) - it('returns `Invalid Date` for 29th of February of non-leap year', function () { - var result = toDate('2014-02-29') + it('returns `Invalid Date` for 29th of February of non-leap year', () => { + const result = toDate('2014-02-29') assert(result instanceof Date) assert(isNaN(result)) }) - it('parses 29th of February of leap year', function () { - var result = toDate('2012-02-29') + it('parses 29th of February of leap year', () => { + const result = toDate('2012-02-29') assert.deepEqual(result, new Date(2012, 1, /* Feb */ 29)) }) }) - describe('week dates', function () { - it('returns `Invalid Date` for invalid day of the week', function () { - var result = toDate('2014-W02-0') + describe('week dates', () => { + it('returns `Invalid Date` for invalid day of the week', () => { + const result = toDate('2014-W02-0') assert(result instanceof Date) assert(isNaN(result)) }) }) - describe('ordinal dates', function () { - it('returns `Invalid Date` for invalid day of the year', function () { - var result = toDate('2012-000') + describe('ordinal dates', () => { + it('returns `Invalid Date` for invalid day of the year', () => { + const result = toDate('2012-000') assert(result instanceof Date) assert(isNaN(result)) }) - it('returns `Invalid Date` for 366th day of non-leap year', function () { - var result = toDate('2014-366') + it('returns `Invalid Date` for 366th day of non-leap year', () => { + const result = toDate('2014-366') assert(result instanceof Date) assert(isNaN(result)) }) - it('parses 366th day of leap year', function () { - var result = toDate('2012-366') + it('parses 366th day of leap year', () => { + const result = toDate('2012-366') assert.deepEqual(result, new Date(2012, 11, /* Dec */ 31)) }) }) - describe('time', function () { - it('parses 24:00 as midnight', function () { - var result = toDate('2014-02-11T24:00') + describe('time', () => { + it('parses 24:00 as midnight', () => { + const result = toDate('2014-02-11T24:00') assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 0, 0)) }) - it('returns `Invalid Date` for invalid hours', function () { - var result = toDate('2014-02-11T25') + it('returns `Invalid Date` for invalid hours', () => { + const result = toDate('2014-02-11T25') assert(result instanceof Date) assert(isNaN(result)) }) - it('returns `Invalid Date` for invalid minutes', function () { - var result = toDate('2014-02-11T21:60') + it('returns `Invalid Date` for invalid minutes', () => { + const result = toDate('2014-02-11T21:60') assert(result instanceof Date) assert(isNaN(result)) }) - it('returns `Invalid Date` for invalid seconds', function () { - var result = toDate('2014-02-11T21:59:60') + it('returns `Invalid Date` for invalid seconds', () => { + const result = toDate('2014-02-11T21:59:60') assert(result instanceof Date) assert(isNaN(result)) }) }) - describe('timezones', function () { - it('returns `Invalid Date` for invalid timezone minutes', function () { - var result = toDate('2014-02-11T21:35:45+04:60') + describe('timezones', () => { + it('returns `Invalid Date` for invalid timezone minutes', () => { + const result = toDate('2014-02-11T21:35:45+04:60') assert(result instanceof Date) assert(isNaN(result)) }) }) }) - describe('invalid argument', function () { - it('returns Invalid Date if argument is non-date string', function () { - var result = toDate('abc') + describe('invalid argument', () => { + it('returns Invalid Date if argument is non-date string', () => { + const result = toDate('abc') assert(result instanceof Date) assert(isNaN(result)) }) - it('returns Invalid Date if argument is NaN', function () { - var result = toDate(NaN) + it('returns Invalid Date if argument is NaN', () => { + const result = toDate(NaN) assert(result instanceof Date) assert(isNaN(result)) }) - it('returns Invalid Date if argument is Invalid Date', function () { - var result = toDate(new Date(NaN)) + it('returns Invalid Date if argument is Invalid Date', () => { + const result = toDate(new Date(NaN)) assert(result instanceof Date) assert(isNaN(result)) }) - it('returns Invalid Date if argument is null', function () { + it('returns Invalid Date if argument is null', () => { // $ExpectedMistake - var result = toDate(null) + const result = toDate(null) assert(result instanceof Date) assert(isNaN(result)) }) - it('returns Invalid Date if argument is undefined', function () { + it('returns Invalid Date if argument is undefined', () => { // $ExpectedMistake - var result = toDate(undefined) + const result = toDate(undefined) assert(result instanceof Date) assert(isNaN(result)) }) - it('returns Invalid Date if argument is false', function () { + it('returns Invalid Date if argument is false', () => { // $ExpectedMistake - var result = toDate(false) + const result = toDate(false) assert(result instanceof Date) assert(isNaN(result)) }) - it('returns Invalid Date if argument is true', function () { + it('returns Invalid Date if argument is true', () => { // $ExpectedMistake - var result = toDate(true) + const result = toDate(true) assert(result instanceof Date) assert(isNaN(result)) }) }) - describe('argument conversion', function () { - it('implicitly converts instance of Number into a number', function () { + describe('argument conversion', () => { + it('implicitly converts instance of Number into a number', () => { // eslint-disable-next-line no-new-wrappers - var timestamp = new Number(new Date(2016, 0, 1, 23, 30, 45, 123).getTime()) + const timestamp = new Number( + new Date(2016, 0, 1, 23, 30, 45, 123).getTime() + ) // $ExpectedMistake - var result = toDate(timestamp) + const result = toDate(timestamp) assert.deepEqual(result, new Date(2016, 0, 1, 23, 30, 45, 123)) }) - it('implicitly converts instance of String into a string', function () { + it('implicitly converts instance of String into a string', () => { // eslint-disable-next-line no-new-wrappers - var dateString = new String('2014-02-11') + const dateString = new String('2014-02-11') // $ExpectedMistake - var result = toDate(dateString) + const result = toDate(dateString) assert.deepEqual(result, new Date(2014, 1, /* Feb */ 11)) }) - it('implicitly converts options', function () { + it('implicitly converts options', () => { // $ExpectedMistake - var result = toDate('+12340702', {additionalDigits: '0'}) + const result = toDate('+12340702', { additionalDigits: '0' }) assert.deepEqual(result, new Date(1234, 6 /* Jul */, 2)) }) - it('throws `RangeError` if `options.additionalDigits` is not convertable to 0, 1, 2 or undefined`', function () { + it('throws `RangeError` if `options.additionalDigits` is not convertable to 0, 1, 2 or undefined`', () => { // $ExpectedMistake - var block = toDate.bind(null, '+12340702', {additionalDigits: 3}) + const block = toDate.bind(null, '+12340702', { additionalDigits: 3 }) assert.throws(block, RangeError) }) }) - it('throws TypeError exception if passed less than 1 argument', function () { + it('throws TypeError exception if passed less than 1 argument', () => { assert.throws(toDate.bind(null), TypeError) }) }) diff --git a/yarn.lock b/yarn.lock index 6dcefb4472..360d13b74d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -76,6 +76,19 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + "@webassemblyjs/ast@1.7.11": version "1.7.11" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" @@ -239,7 +252,7 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= -accepts@~1.3.4: +accepts@~1.3.4, accepts@~1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= @@ -288,7 +301,7 @@ acorn@^5.0.0, acorn@^5.3.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" integrity sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ== -acorn@^5.6.2: +acorn@^5.6.2, acorn@^5.7.3: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== @@ -522,11 +535,28 @@ array-find-index@^1.0.1: resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + array-slice@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + 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" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" @@ -542,7 +572,7 @@ arraybuffer.slice@~0.0.7: resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== -arrify@^1.0.0: +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= @@ -673,6 +703,15 @@ babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.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" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + babel-core@^6.22.0, babel-core@^6.22.1: version "6.22.1" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.22.1.tgz#9c5fd658ba1772d28d721f6d25d968fc7ae21648" @@ -1239,6 +1278,16 @@ better-assert@~1.0.0: dependencies: callsite "1.0.0" +bfj@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.1.tgz#05a3b7784fbd72cfa3c22e56002ef99336516c48" + integrity sha512-+GUNvzHR4nRyGybQc2WpNJL4MJazMuvf92ueIyA0bIkPRwhhQu3IfZQ2PSoVPpCBJfmoSdOxu5rnotfFLlvYRQ== + dependencies: + bluebird "^3.5.1" + check-types "^7.3.0" + hoopy "^0.1.2" + tryer "^1.0.0" + big.js@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" @@ -1284,7 +1333,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== -body-parser@^1.16.1: +body-parser@1.18.3, body-parser@^1.16.1: version "1.18.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= @@ -1520,12 +1569,12 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -bytes@3.0.0: +bytes@3.0.0, bytes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= -cacache@^11.0.2: +cacache@^11.0.2, cacache@^11.2.0: version "11.3.1" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f" integrity sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA== @@ -1579,11 +1628,30 @@ call-matcher@^1.0.0: espurify "^1.6.0" estraverse "^4.0.0" +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + call-signature@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" integrity sha1-qEq8glpV70yysCi9dOIFpluaSZY= +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + callsite@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" @@ -1658,6 +1726,11 @@ chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +check-types@^7.3.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4" + integrity sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg== + chokidar@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" @@ -1711,6 +1784,11 @@ ci-info@^1.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2" integrity sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg== +ci-job-number@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ci-job-number/-/ci-job-number-0.3.0.tgz#34bdd114b0dece1960287bd40a57051041a2a800" + integrity sha1-NL3RFLDezhlgKHvUClcFEEGiqAA= + 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" @@ -1874,6 +1952,11 @@ commander@^2.14.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== +commander@^2.18.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + commander@~2.17.1: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" @@ -1914,6 +1997,18 @@ compress-commons@^1.2.0: normalize-path "^2.0.0" readable-stream "^2.0.0" +compression-webpack-plugin@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-2.0.0.tgz#46476350c1eb27f783dccc79ac2f709baa2cffbc" + integrity sha512-bDgd7oTUZC8EkRx8j0sjyCfeiO+e5sFcfgaFcjVhfQf5lLya7oY2BczxcJ7IUuVjz5m6fy8IECFmVFew3xLk8Q== + dependencies: + cacache "^11.2.0" + find-cache-dir "^2.0.0" + neo-async "^2.5.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + webpack-sources "^1.0.1" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -1970,6 +2065,11 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -1980,6 +2080,11 @@ convert-source-map@^1.1.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.3.0.tgz#e9f3e9c6e2728efc2676696a70eb382f73106a67" integrity sha1-6fPpxuJyjvwmdmlqcOs4L3MQamc= +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" @@ -2031,6 +2136,16 @@ cosmiconfig@^5.0.2: js-yaml "^3.9.0" parse-json "^4.0.0" +cosmiconfig@^5.0.6: + version "5.0.7" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" + integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + crc32-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" @@ -2128,6 +2243,38 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +css-loader@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-1.0.1.tgz#6885bb5233b35ec47b006057da01cc640b6b79fe" + integrity sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw== + dependencies: + babel-code-frame "^6.26.0" + css-selector-tokenizer "^0.7.0" + icss-utils "^2.1.0" + loader-utils "^1.0.2" + lodash "^4.17.11" + postcss "^6.0.23" + postcss-modules-extract-imports "^1.2.0" + postcss-modules-local-by-default "^1.2.0" + postcss-modules-scope "^1.1.0" + postcss-modules-values "^1.3.0" + postcss-value-parser "^3.3.0" + source-list-map "^2.0.0" + +css-selector-tokenizer@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d" + integrity sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA== + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + +cssesc@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" + integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q= + cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.2" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" @@ -2302,6 +2449,11 @@ des.js@^1.0.0: 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" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" @@ -2343,6 +2495,14 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + dmd@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/dmd/-/dmd-3.0.3.tgz#3c91f7ba895d379a21c187386d2427e52909a070" @@ -2438,6 +2598,11 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +ejs@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" + integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== + elegant-spinner@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" @@ -2477,7 +2642,7 @@ empower@^1.1.0: core-js "^2.0.0" empower-core "^0.6.1" -encodeurl@~1.0.1: +encodeurl@~1.0.1, encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= @@ -2703,6 +2868,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + eventemitter3@1.x.x: version "1.2.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" @@ -2808,6 +2978,42 @@ expect@^22.4.0: jest-message-util "^22.4.3" jest-regex-util "^22.4.3" +express@^4.16.3: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.3" + 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.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + 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.4" + qs "6.5.2" + range-parser "~1.2.0" + safe-buffer "5.1.2" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + 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" @@ -2879,6 +3085,18 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-glob@^2.0.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.4.tgz#e54f4b66d378040e0e4d6a68ec36bbc5b04363c0" + integrity sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + 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" @@ -2889,6 +3107,11 @@ fast-levenshtein@~2.0.4: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastparse@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + faye-websocket@0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.9.3.tgz#482a505b0df0ae626b969866d3bd740cdb962e83" @@ -2923,6 +3146,14 @@ figures@^1.7.0: escape-string-regexp "^1.0.5" object-assign "^4.1.0" +file-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-2.0.0.tgz#39749c82f020b9e85901dcff98e8004e6401cfde" + integrity sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ== + dependencies: + loader-utils "^1.0.2" + schema-utils "^1.0.0" + file-set@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/file-set/-/file-set-1.1.1.tgz#d3ec70c080ec8f18f204ba1de106780c9056926b" @@ -2936,6 +3167,11 @@ filename-regex@^2.0.0: resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" integrity sha1-mW4+gEebmLmJfxWopYs9CE6SZ3U= +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + fill-range@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" @@ -2970,6 +3206,19 @@ finalhandler@1.1.0: statuses "~1.3.1" unpipe "~1.0.0" +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + 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" @@ -3099,6 +3348,11 @@ formatio@1.1.1: dependencies: samsam "~1.1" +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -3106,6 +3360,11 @@ fragment-cache@^0.2.1: 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" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + from2@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -3313,6 +3572,11 @@ glob-promise@^2.0.0: resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-2.0.0.tgz#7a0f42660f42d0964f62ffec37fd41ecb64f5eb5" integrity sha1-eg9CZg9C0JZPYv/sN/1B7LZPXrU= +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + glob@7.0.5: version "7.0.5" resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" @@ -3364,6 +3628,19 @@ globals@^9.0.0: resolved "https://registry.yarnpkg.com/globals/-/globals-9.14.0.tgz#8859936af0038741263053b39d0e76ca241e4034" integrity sha1-iFmTavADh0EmMFOznQ52yiQeQDQ= +globby@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" + integrity sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw== + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -3394,6 +3671,14 @@ gzip-size@^3.0.0: dependencies: duplexer "^0.1.1" +gzip-size@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80" + integrity sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA== + dependencies: + duplexer "^0.1.1" + pify "^3.0.0" + handlebars@3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-3.0.3.tgz#0e09651a2f0fb3c949160583710d551f92e6d2ad" @@ -3568,6 +3853,11 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" +hoopy@^0.1.2: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + hosted-git-info@^2.1.4: version "2.2.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.2.0.tgz#7a0d097863d886c0fabbdcd37bf1758d8becf8a5" @@ -3580,7 +3870,7 @@ html-encoding-sniffer@^1.0.2: dependencies: whatwg-encoding "^1.0.1" -http-errors@1.6.3, http-errors@~1.6.3: +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" resolved "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= @@ -3668,6 +3958,18 @@ iconv-lite@~0.4.13: resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" integrity sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es= +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +icss-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962" + integrity sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI= + dependencies: + postcss "^6.0.1" + ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" @@ -3685,6 +3987,19 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + import-local@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" @@ -3755,6 +4070,11 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= + 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" @@ -4250,6 +4570,11 @@ js-tokens@^3.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" integrity sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc= +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + js-yaml@^3.9.0: version "3.11.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" @@ -4878,7 +5203,7 @@ lodash@4.17.4, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.17.4, lodash@^4.2.0, lod resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= -lodash@^4.16.6, lodash@^4.17.10, lodash@^4.8.0: +lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.8.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -5023,7 +5348,7 @@ mem@^4.0.0: mimic-fn "^1.0.0" p-is-promise "^1.1.0" -memory-fs@^0.4.0, memory-fs@~0.4.1: +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= @@ -5047,6 +5372,21 @@ meow@^3.3.0: redent "^1.0.0" trim-newlines "^1.0.0" +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge2@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" + integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + micromatch@^2.1.5, micromatch@^2.3.11: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -5066,7 +5406,7 @@ micromatch@^2.1.5, micromatch@^2.3.11: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.1.4, micromatch@^3.1.8: +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -5129,6 +5469,11 @@ mime-types@~2.1.18: dependencies: mime-db "~1.36.0" +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + mime@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" @@ -5613,6 +5958,11 @@ onetime@^1.0.0: resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -5865,6 +6215,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +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" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -5975,6 +6330,51 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +postcss-modules-extract-imports@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz#dc87e34148ec7eab5f791f7cd5849833375b741a" + integrity sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw== + dependencies: + postcss "^6.0.1" + +postcss-modules-local-by-default@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" + integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-scope@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" + integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-values@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" + integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA= + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^6.0.1" + +postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss@^6.0.1, postcss@^6.0.23: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + power-assert-context-formatter@^1.0.7: version "1.1.1" resolved "https://registry.yarnpkg.com/power-assert-context-formatter/-/power-assert-context-formatter-1.1.1.tgz#edba352d3ed8a603114d667265acce60d689ccdf" @@ -6132,6 +6532,14 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= +proxy-addr@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" + prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" @@ -6262,7 +6670,7 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -range-parser@^1.0.3, range-parser@^1.2.0: +range-parser@^1.0.3, range-parser@^1.2.0, range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= @@ -6305,6 +6713,14 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -6451,6 +6867,15 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpu-core@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" + integrity sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" @@ -6721,16 +7146,16 @@ rxjs@^5.4.2: dependencies: symbol-observable "1.0.1" +safe-buffer@5.1.2, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-buffer@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" integrity sha1-0mPKVGls2KMGtcplUekt5XkY++c= -safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - 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" @@ -6818,11 +7243,40 @@ semver@~5.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + serialize-javascript@^1.4.0: version "1.5.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + 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" @@ -6903,6 +7357,28 @@ sinon@^1.17.3: samsam "1.1.2" util ">=0.10.3 <1" +size-limit@^0.21.0: + version "0.21.0" + resolved "https://registry.yarnpkg.com/size-limit/-/size-limit-0.21.0.tgz#aba65baea7026665dc3f633b17b95b1f43258292" + integrity sha512-HsRrag+Uqj6kpE4byCfFXXBRh+qvyq8fegMUC7mMwwkncyDp+ZL4H8j2eQD2ajXsaJHpFuT+PLNtxuY3CXiLug== + dependencies: + bytes "^3.0.0" + chalk "^2.4.1" + ci-job-number "^0.3.0" + compression-webpack-plugin "^2.0.0" + cosmiconfig "^5.0.6" + css-loader "^1.0.1" + escape-string-regexp "^1.0.5" + file-loader "^2.0.0" + globby "^8.0.1" + gzip-size "^5.0.0" + memory-fs "^0.4.1" + read-pkg-up "^4.0.0" + style-loader "^0.23.1" + webpack "^4.23.1" + webpack-bundle-analyzer "^3.0.3" + yargs "^12.0.2" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -7182,6 +7658,11 @@ statuses@~1.3.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -7365,6 +7846,14 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +style-loader@^0.23.1: + version "0.23.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925" + integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg== + dependencies: + loader-utils "^1.1.0" + schema-utils "^1.0.0" + supports-color@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" @@ -7396,7 +7885,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^5.5.0: +supports-color@^5.4.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -7685,6 +8174,11 @@ trim-newlines@^1.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= +tryer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -7926,6 +8420,11 @@ vargs@0.1.0: resolved "https://registry.yarnpkg.com/vargs/-/vargs-0.1.0.tgz#6b6184da6520cc3204ce1b407cac26d92609ebff" integrity sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8= +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + verror@1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" @@ -7989,6 +8488,24 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webpack-bundle-analyzer@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.3.tgz#dbc7fff8f52058b6714a20fddf309d0790e3e0a0" + integrity sha512-naLWiRfmtH4UJgtUktRTLw6FdoZJ2RvCR9ePbwM9aRMsS/KjFerkPZG9epEvXRAw5d5oPdrs9+3p+afNjxW8Xw== + dependencies: + acorn "^5.7.3" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.10" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + webpack-cli@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.2.tgz#17d7e01b77f89f884a2bbf9db545f0f6a648e746" @@ -8023,7 +8540,7 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-sources@^1.1.0, webpack-sources@^1.3.0: +webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== @@ -8031,7 +8548,7 @@ webpack-sources@^1.1.0, webpack-sources@^1.3.0: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@4: +webpack@4, webpack@^4.23.1: version "4.27.1" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.27.1.tgz#5f2e2db446d2266376fa15d7d2277a1a9c2e12bb" integrity sha512-WArHiLvHrlfyRM8i7f+2SFbr/XbQ0bXqTkPF8JpHOzub5482Y3wx7rEO8stuLGOKOgZJcqcisLhD7LrM/+fVMw== @@ -8178,6 +8695,13 @@ ws@^4.0.0: async-limiter "~1.0.0" safe-buffer "~5.1.0" +ws@^6.0.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" + integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== + dependencies: + async-limiter "~1.0.0" + ws@~3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"