diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f1cc3ad --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.lesshintrc b/.lesshintrc new file mode 100644 index 0000000..0347cb1 --- /dev/null +++ b/.lesshintrc @@ -0,0 +1,6 @@ +{ + "fileExtensions": [".less", ".css"], + "idSelector": false, + "importantRule": false, + "zeroUnit": false +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 8465204..852164e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,34 @@ +## 0.5.7 + +* [Updates webpack configuration.](https://github.com/material-foundation/material-remixer-js/commit/fffca3cf29960defe0b280cbe60f37308dc1aaf5) +* [Adds variable `constraintType` and updates `dataType`.](https://github.com/material-foundation/material-remixer-js/commit/b4be6daf176cf0f36a6fa9e32e94edbd6703d70a) +* [Renames possibleValues to limitedToValues.](https://github.com/material-foundation/material-remixer-js/commit/c795fd8533f4ae5f85a1b1b857a70dfc59e6890f) +* [Adds variable `controlType` property.](https://github.com/material-foundation/material-remixer-js/commit/83e326d8fbb947abfd59f5421b2ac0d43713659c) +* [Adds clone tests and updates `dataType` tests for variables.](https://github.com/material-foundation/material-remixer-js/commit/8949d8d33d25f41ad45c70c7e1b8289ebe7664fa) +* [Converts colors to rgba during serialization.](https://github.com/material-foundation/material-remixer-js/commit/40f673f5057776681e0fdee1db903cf789b6de2d) + +## 0.5.6 + +* [Adds editorconfig file.](https://github.com/material-foundation/material-remixer-js/commit/6925701f3a7c05cc2b0ac174331a1fd1d8539dd7) +* [Adds tests for UI control classes.](https://github.com/material-foundation/material-remixer-js/commit/45b343608515871053382dfa6d0a8876d82374a5) + +## 0.5.5 + +* [Renames to material-remxer-js.](https://github.com/material-foundation/material-remixer-js/commit/6bcebcdbc2bed6b8a8bac62a32f4d6f2fe8f9d93) +* Adds codecov. + +## 0.5.4 + +* [Adds `lesshint` CSS/LESS linter.](https://github.com/material-foundation/material-remixer-js/commit/c86ffdec4f8a3796abd94b18d095e4f00b874cea) + +## 0.5.3 + +* [Updates per tslint core rules.](https://github.com/material-foundation/material-remixer-js/commit/94e39ac7ae54d9d2549281558cf5160861b7386b) +* [Adds additional tests for `Remixer` and `LocalStorage`](https://github.com/material-foundation/material-remixer-js/commit/3925ac91914cf1ea85c34f4aa2fd284c71c9aac3). + ## 0.5.2 -Replaces gulp with NPM scripts. +* [Replaces gulp with NPM scripts.](https://github.com/material-foundation/material-remixer-js/commit/e3f97595016236cb24a60071ad8d41819590b52a) ## 0.5.1 diff --git a/README.md b/README.md index d58e4aa..cb34156 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -![remixer](https://cdn.rawgit.com/material-foundation/material-remixer/master/docs/assets/lockup_remixer_icon_horizontal_dark_small.svg) +![remixer](https://cdn.rawgit.com/material-foundation/material-remixer-js/develop/docs/assets/lockup_remixer_for_web.svg) -[![Build Status](https://travis-ci.org/material-foundation/material-remixer-web.svg?branch=develop)](https://travis-ci.org/material-foundation/material-remixer-web) [![codecov](https://codecov.io/gh/material-foundation/material-remixer-web/branch/develop/graph/badge.svg)](https://codecov.io/gh/material-foundation/material-remixer-web) [![npm version](https://badge.fury.io/js/material-remixer.svg)](https://badge.fury.io/js/material-remixer) +[![Build Status](https://travis-ci.org/material-foundation/material-remixer-js.svg?branch=develop)](https://travis-ci.org/material-foundation/material-remixer-js) [![codecov](https://codecov.io/gh/material-foundation/material-remixer-js/branch/develop/graph/badge.svg)](https://codecov.io/gh/material-foundation/material-remixer-js) [![npm version](https://badge.fury.io/js/material-remixer.svg)](https://badge.fury.io/js/material-remixer) Remixer helps teams use and refine design specs by providing an abstraction for these values that is accessible and configurable from both inside and outside the app itself. @@ -64,8 +64,8 @@ Yes, the [material-foundation](https://github.com/material-foundation) organizat ## Contributing -We gladly welcome contributions! If you have found a bug, have questions, or wish to contribute, please follow our [Contributing Guidelines](https://github.com/material-foundation/material-remixer-web/blob/develop/CONTRIBUTING.md). +We gladly welcome contributions! If you have found a bug, have questions, or wish to contribute, please follow our [Contributing Guidelines](https://github.com/material-foundation/material-remixer-js/blob/develop/CONTRIBUTING.md). ## License -© Google, 2016. Licensed under an [Apache-2](https://github.com/material-foundation/material-remixer-web/blob/develop/LICENSE) license. +© Google, 2016. Licensed under an [Apache-2](https://github.com/material-foundation/material-remixer-js/blob/develop/LICENSE) license. diff --git a/docs/assets/lockup_remixer_for_web.svg b/docs/assets/lockup_remixer_for_web.svg new file mode 100644 index 0000000..c161abe --- /dev/null +++ b/docs/assets/lockup_remixer_for_web.svg @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/index.html b/examples/index.html index c96286e..19c038c 100644 --- a/examples/index.html +++ b/examples/index.html @@ -26,7 +26,7 @@ - + diff --git a/examples/package.json b/examples/package.json index 78c7084..4fbb657 100644 --- a/examples/package.json +++ b/examples/package.json @@ -5,10 +5,11 @@ "author": "The Material Remixer Authors (see AUTHORS)", "license": "Apache-2.0", "scripts": { - "start": "$( yarn bin )/http-server -o" + "start": "webpack-dev-server --open" }, "devDependencies": { - "http-server": "^0.9.0" + "webpack": "^2.2.0-rc.3", + "webpack-dev-server": "^2.2.0-rc.0" }, "dependencies": { "material-design-lite": "^1.2.1", diff --git a/examples/styles.css b/examples/styles.css index 6f3e5bb..33f5606 100644 --- a/examples/styles.css +++ b/examples/styles.css @@ -14,10 +14,12 @@ * under the License. */ -.page-content { padding: 40px; } +.page-content { + padding: 40px; +} #box { - width: 200px; - height: 200px; - background-color: lightGray; + background-color: lightGray; + height: 200px; + width: 200px; } diff --git a/examples/webpack.config.js b/examples/webpack.config.js new file mode 100644 index 0000000..4ec457b --- /dev/null +++ b/examples/webpack.config.js @@ -0,0 +1,33 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +'use strict'; + +module.exports = { + entry: { + remixer: './node_modules/material-remixer/dist/remixer.js', + overlay: './node_modules/material-remixer/dist/overlay.js', + }, + output: { + publicPath: '/assets/', + filename: '[name].js', + libraryTarget: 'umd', + umdNamedDefine: true + }, + performance: { + hints: false + }, +}; diff --git a/examples/yarn.lock b/examples/yarn.lock index 3bb0c7f..3e1132e 100644 --- a/examples/yarn.lock +++ b/examples/yarn.lock @@ -1,33 +1,330 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 + + +abbrev@1: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + +accepts@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" + dependencies: + mime-types "~2.1.11" + negotiator "0.6.1" + +ansi-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +aproba@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" + +are-we-there-yet@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + asap@~2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" -async@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.0.tgz#ac3613b1da9bed1b47510bb4651b8931e47146c7" +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" -colors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +batch@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.3.tgz#3f3414f380321743bfc1042f9a83ff1d5824d464" + +bcrypt-pbkdf@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz#3ca76b85241c7170bf7d9703e7b9aa74630040d4" + dependencies: + tweetnacl "^0.14.3" + +binary-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +bytes@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.3.0.tgz#d5b680a165b6201739acb611542aabc2d8ceb070" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chokidar@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +compressible@~2.0.8: + version "2.0.9" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.9.tgz#6daab4e2b599c2770dd9e21e7a891b1c5a755425" + dependencies: + mime-db ">= 1.24.0 < 2" + +compression@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.6.2.tgz#cceb121ecc9d09c52d7ad0c3350ea93ddd402bc3" + dependencies: + accepts "~1.3.3" + bytes "2.3.0" + compressible "~2.0.8" + debug "~2.2.0" + on-headers "~1.0.1" + vary "~1.1.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +connect-history-api-fallback@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz#e51d17f8f0ef0db90a64fdb47de3051556e9f169" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +content-disposition@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.1.tgz#87476c6a67c8daa87e32e87616df883ba7fb071b" + +content-type@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" -corser@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87" +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -ecstatic@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-1.4.1.tgz#32cb7b6fa2e290d58668674d115e8f0c3d567d6a" +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +debug@^2.2.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" + dependencies: + ms "0.7.2" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" dependencies: - he "^0.5.0" - mime "^1.2.11" - minimist "^1.1.0" - url-join "^1.0.0" + ms "0.7.1" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-extend@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +encodeurl@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" encoding@^0.1.11: version "0.1.12" @@ -35,53 +332,501 @@ encoding@^0.1.11: dependencies: iconv-lite "~0.4.13" +errno@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + dependencies: + prr "~0.0.0" + +error-ex@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.0.tgz#e67b43f3e82c96ea3a584ffee0b9fc3325d802d9" + dependencies: + is-arrayish "^0.2.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +etag@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" + eventemitter3@1.x.x: version "1.2.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" +eventsource@~0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" + dependencies: + original ">=0.0.5" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +express@^4.13.3: + version "4.14.0" + resolved "https://registry.yarnpkg.com/express/-/express-4.14.0.tgz#c1ee3f42cdc891fb3dc650a8922d51ec847d0d66" + dependencies: + accepts "~1.3.3" + array-flatten "1.1.1" + content-disposition "0.5.1" + content-type "~1.0.2" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "~2.2.0" + depd "~1.1.0" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.7.0" + finalhandler "0.5.0" + fresh "0.3.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.1" + path-to-regexp "0.1.7" + proxy-addr "~1.1.2" + qs "6.2.0" + range-parser "~1.2.0" + send "0.14.1" + serve-static "~1.11.1" + type-is "~1.6.13" + utils-merge "1.0.0" + vary "~1.1.0" + +extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.0.tgz#d9ccf0e789e7db725d74bc4877d23aa42972ac50" + dependencies: + websocket-driver ">=0.5.1" + fbjs@^0.8.1, fbjs@^0.8.4: - version "0.8.6" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.6.tgz#7eb67d6986b2d5007a9b6e92e0e7cb6f75cad290" + version "0.8.8" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.8.tgz#02f1b6e0ea0d46c24e0b51a2d24df069563a5ad6" dependencies: core-js "^1.0.0" isomorphic-fetch "^2.1.1" loose-envify "^1.0.0" object-assign "^4.1.0" promise "^7.1.1" + setimmediate "^1.0.5" ua-parser-js "^0.7.9" -he@^0.5.0: +filename-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +finalhandler@0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.0.tgz#e9508abece9b6dba871a6942a1d7911b91911ac7" + dependencies: + debug "~2.2.0" + escape-html "~1.0.3" + on-finished "~2.3.0" + statuses "~1.3.0" + unpipe "~1.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +for-in@^0.1.5: + version "0.1.6" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8" + +for-own@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072" + dependencies: + for-in "^0.1.5" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +forwarded@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" + +fresh@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.0.15" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.15.tgz#fa63f590f3c2ad91275e4972a6cea545fb0aae44" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +gauge@~2.7.1: + version "2.7.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.2.tgz#15cecc31b02d05345a5d6b0e171cdb3ad2307774" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + supports-color "^0.2.0" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +getpass@^0.1.1: + version "0.1.6" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@^7.0.5: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +handle-thing@^1.2.4: + version "1.2.5" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" -http-proxy@^1.8.1: - version "1.16.0" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.0.tgz#f9b52305e9f864811835277e4a486051b5d4a523" +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +hosted-git-info@^2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +http-deceiver@^1.2.4: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + +http-errors@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" + dependencies: + inherits "2.0.3" + setprototypeof "1.0.2" + statuses ">= 1.3.1 < 2" + +http-proxy-middleware@~0.17.1: + version "0.17.3" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.3.tgz#940382147149b856084f5534752d5b5a8168cd1d" + dependencies: + http-proxy "^1.16.2" + is-glob "^3.1.0" + lodash "^4.17.2" + micromatch "^2.3.11" + +http-proxy@^1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" dependencies: eventemitter3 "1.x.x" requires-port "1.x.x" -http-server@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.9.0.tgz#8f1b06bdc733618d4dc42831c7ba1aff4e06001a" +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" dependencies: - colors "1.0.3" - corser "~2.0.0" - ecstatic "^1.4.0" - http-proxy "^1.8.1" - opener "~1.4.0" - optimist "0.6.x" - portfinder "0.4.x" - union "~0.4.3" + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" iconv-lite@~0.4.13: version "0.4.15" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +ipaddr.js@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.1.1.tgz#c791d95f52b29c1247d5df80ada39b8a73647230" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.0.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-dotfile@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-my-json-valid@^2.12.4: + version "2.15.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^2.0.2, is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + is-stream@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + isomorphic-fetch@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" @@ -89,10 +834,74 @@ isomorphic-fetch@^2.1.1: node-fetch "^1.0.1" whatwg-fetch ">=0.10.0" +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + js-tokens@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5" +jsbn@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json3@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" + dependencies: + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +kind-of@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" + dependencies: + is-buffer "^1.0.2" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +lodash@^4.17.2: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + loose-envify@^1.0.0, loose-envify@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.0.tgz#6b26248c42f6d4fa4b0d8542f78edfcde35642a8" @@ -100,39 +909,108 @@ loose-envify@^1.0.0, loose-envify@^1.1.0: js-tokens "^2.0.0" material-design-lite@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/material-design-lite/-/material-design-lite-1.2.1.tgz#09e5caab2575af8ee21b2630bff175c5a822c662" + version "1.3.0" + resolved "https://registry.yarnpkg.com/material-design-lite/-/material-design-lite-1.3.0.tgz#d004ce3fee99a1eeb74a78b8a325134a5f1171d3" material-remixer@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/material-remixer/-/material-remixer-0.5.1.tgz#c3a5c22fcaee293eafb95c363de314fc09f44fdd" + version "0.5.6" + resolved "https://registry.yarnpkg.com/material-remixer/-/material-remixer-0.5.6.tgz#f8172540921008476147e553d4c2fb9ca083455c" dependencies: material-design-lite "^1.2.1" react "^15.4.0" react-dom "^15.4.0" -mime@^1.2.11: +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +"mime-db@>= 1.24.0 < 2", mime-db@~1.25.0: + version "1.25.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.25.0.tgz#c18dbd7c73a5dbf6f44a024dc0d165a1e7b1c392" + +mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.7: + version "2.1.13" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.13.tgz#e07aaa9c6c6b9a7ca3012c69003ad25a39e92a88" + dependencies: + mime-db "~1.25.0" + +mime@1.3.4, mime@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" -minimist@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" +minimalistic-assert@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" +minimatch@^3.0.0, minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -mkdirp@0.5.x: +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +nan@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.0.tgz#aa8f1e34531d807e9e27755b234b4a6ec0c152a8" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + node-fetch@^1.0.1: version "1.6.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" @@ -140,37 +1018,229 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" -object-assign@^4.1.0: +node-pre-gyp@^0.6.29: + version "0.6.32" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.32.tgz#fc452b376e7319b3d255f5f34853ef6fd8fe1fd5" + dependencies: + mkdirp "~0.5.1" + nopt "~3.0.6" + npmlog "^4.0.1" + rc "~1.1.6" + request "^2.79.0" + rimraf "~2.5.4" + semver "~5.3.0" + tar "~2.2.1" + tar-pack "~3.3.0" + +nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2: + version "2.3.5" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" + +npmlog@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" -opener@~1.4.0: - version "1.4.2" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.2.tgz#b32582080042af8680c389a499175b4c54fff523" +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" -optimist@0.6.x: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" +obuf@^1.0.0, obuf@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.1.tgz#104124b6c602c6796881a042541d36db43a5264e" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" + ee-first "1.1.1" -portfinder@0.4.x: - version "0.4.0" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-0.4.0.tgz#a3ffadffafe4fb98e0601a85eda27c27ce84ca1e" +on-headers@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + +once@^1.3.0, once@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + +opn@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +original@>=0.0.5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b" + dependencies: + url-parse "1.0.x" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parseurl@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" dependencies: - async "0.9.0" + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +portfinder@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.10.tgz#7a4de9d98553c315da6f1e1ed05138eeb2d16bb8" + dependencies: + async "^1.5.2" + debug "^2.2.0" mkdirp "0.5.x" +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + promise@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" dependencies: asap "~2.0.3" -qs@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" +proxy-addr@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.2.tgz#b4cc5f22610d9535824c123aef9d3cf73c40ba37" + dependencies: + forwarded "~0.1.0" + ipaddr.js "1.1.1" + +prr@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b" + +qs@~6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442" + +querystringify@0.0.x: + version "0.0.4" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" + +randomatic@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + dependencies: + is-number "^2.0.2" + kind-of "^3.0.2" + +range-parser@^1.0.3, range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +rc@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.6.tgz#43651b76b6ae53b5c802f1151fa3fc3b059969c9" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~1.0.4" react-dom@^15.4.0: version "15.4.1" @@ -188,29 +1258,501 @@ react@^15.4.0: loose-envify "^1.1.0" object-assign "^4.1.0" -requires-port@1.x.x: +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.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" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +regex-cache@^0.4.2: + version "0.4.3" + resolved "http://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +request@^2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +requires-port@1.0.x, requires-port@1.x.x: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" +rimraf@2, rimraf@~2.5.1, rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + +"semver@2 || 3 || 4 || 5", semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +send@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.14.1.tgz#a954984325392f51532a7760760e459598c89f7a" + dependencies: + debug "~2.2.0" + depd "~1.1.0" + destroy "~1.0.4" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.7.0" + fresh "0.3.0" + http-errors "~1.5.0" + mime "1.3.4" + ms "0.7.1" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.3.0" + +serve-index@^1.7.2: + version "1.8.0" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.8.0.tgz#7c5d96c13fb131101f93c1c5774f8516a1e78d3b" + dependencies: + accepts "~1.3.3" + batch "0.5.3" + debug "~2.2.0" + escape-html "~1.0.3" + http-errors "~1.5.0" + mime-types "~2.1.11" + parseurl "~1.3.1" + +serve-static@~1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.1.tgz#d6cce7693505f733c759de57befc1af76c0f0805" + dependencies: + encodeurl "~1.0.1" + escape-html "~1.0.3" + parseurl "~1.3.1" + send "0.14.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +setprototypeof@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sockjs-client@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.1.tgz#284843e9a9784d7c474b1571b3240fca9dda4bb0" + dependencies: + debug "^2.2.0" + eventsource "~0.1.6" + faye-websocket "~0.11.0" + inherits "^2.0.1" + json3 "^3.3.2" + url-parse "^1.1.1" + +sockjs@0.3.18: + version "0.3.18" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.18.tgz#d9b289316ca7df77595ef299e075f0f937eb4207" + dependencies: + faye-websocket "^0.10.0" + uuid "^2.0.2" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +spdy-transport@^2.0.15: + version "2.0.18" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.0.18.tgz#43fc9c56be2cccc12bb3e2754aa971154e836ea6" + dependencies: + debug "^2.2.0" + hpack.js "^2.1.6" + obuf "^1.1.0" + readable-stream "^2.0.1" + wbuf "^1.4.0" + +spdy@^3.4.1: + version "3.4.4" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.4.tgz#e0406407ca90ff01b553eb013505442649f5a819" + dependencies: + debug "^2.2.0" + handle-thing "^1.2.4" + http-deceiver "^1.2.4" + select-hose "^2.0.0" + spdy-transport "^2.0.15" + +sshpk@^1.7.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.1.tgz#30e1a5d329244974a1af61511339d595af6638b0" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +"statuses@>= 1.3.1 < 2", statuses@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-json-comments@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + +supports-color@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + +tar-pack@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" + dependencies: + debug "~2.2.0" + fstream "~1.0.10" + fstream-ignore "~1.0.5" + once "~1.3.3" + readable-stream "~2.1.4" + rimraf "~2.5.1" + tar "~2.2.1" + uid-number "~0.0.6" + +tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-is@~1.6.13: + version "1.6.14" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.13" + ua-parser-js@^0.7.9: version "0.7.12" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" -union@~0.4.3: - version "0.4.6" - resolved "https://registry.yarnpkg.com/union/-/union-0.4.6.tgz#198fbdaeba254e788b0efcb630bc11f24a2959e0" +uid-number@~0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +url-parse@1.0.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" + dependencies: + querystringify "0.0.x" + requires-port "1.0.x" + +url-parse@^1.1.1: + version "1.1.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.1.7.tgz#025cff999653a459ab34232147d89514cc87d74a" + dependencies: + querystringify "0.0.x" + requires-port "1.0.x" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + +uuid@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" dependencies: - qs "~2.3.3" + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" -url-join@^1.0.0: +vary@~1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +wbuf@^1.1.0, wbuf@^1.4.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.2.tgz#d697b99f1f59512df2751be42769c1580b5801fe" + dependencies: + minimalistic-assert "^1.0.0" + +webpack-dev-middleware@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.9.0.tgz#a1c67a3dfd8a5c5d62740aa0babe61758b4c84aa" + dependencies: + memory-fs "~0.4.1" + mime "^1.3.4" + path-is-absolute "^1.0.0" + range-parser "^1.0.3" + +webpack-dev-server@^2.2.0-rc.0: + version "2.2.0-rc.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.2.0-rc.0.tgz#ea8a11e211d9524b8999945fe5645481a51fdf46" + dependencies: + chokidar "^1.6.0" + compression "^1.5.2" + connect-history-api-fallback "^1.3.0" + express "^4.13.3" + http-proxy-middleware "~0.17.1" + opn "4.0.2" + portfinder "^1.0.9" + serve-index "^1.7.2" + sockjs "0.3.18" + sockjs-client "1.1.1" + spdy "^3.4.1" + strip-ansi "^3.0.0" + supports-color "^3.1.1" + webpack-dev-middleware "^1.9.0" + yargs "^6.0.0" + +websocket-driver@>=0.5.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + dependencies: + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7" whatwg-fetch@>=0.10.0: version "2.0.1" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.1.tgz#078b9461bbe91cea73cbce8bb122a05f9e92b772" -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" +yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + dependencies: + camelcase "^3.0.0" + +yargs@^6.0.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" diff --git a/karma.conf.js b/karma.conf.js index 77cd150..5d69e39 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -13,7 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ - + const webpackConfig = require('./webpack.config.js'); module.exports = function(config) { @@ -28,19 +28,18 @@ module.exports = function(config) { }, }, coverageReporter: { + dir: 'coverage', reporters: [{ + type: 'text' + }, { type: 'lcov' }] }, files: [ - 'src/**/__tests__/**', - ], - exclude: [ - '**/*.map', + 'src/**/__tests__/*.ts?(x)', ], preprocessors: { - './src/**/*.ts': ['webpack', 'coverage'], - './src/**/*.js': ['webpack', 'coverage'], + 'src/**/*.ts?(x)': ['webpack'], }, webpack: { devtool: webpackConfig.devtool, diff --git a/package.json b/package.json index 5fedc06..ea50960 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "material-remixer", - "version": "0.5.2", + "version": "0.5.7", "description": "A set of libraries and protocols to allow the sharing of design values and live refinement of apps during the development process.", "homepage": "https://github.com/material-foundation/material-remixer", "author": "The Material Remixer Authors (see AUTHORS)", @@ -11,10 +11,10 @@ ], "repository": { "type": "git", - "url": "https://github.com/material-foundation/material-remixer-web.git" + "url": "https://github.com/material-foundation/material-remixer-js.git" }, "bugs": { - "url": "https://github.com/material-foundation/material-remixer-web/issues/" + "url": "https://github.com/material-foundation/material-remixer-js/issues/" }, "scripts": { "build:dev": "mkdirp build && cross-env RMX_ENV=development webpack --progress --colors", @@ -24,8 +24,8 @@ "clean": "del-cli build/** dist/**", "dev": "npm run clean && npm run build && cross-env RMX_ENV=development webpack-dev-server", "dist": "npm run clean && npm run build && copyFiles -f build/*.* dist", - "install": "cd examples && npm install", "lint:ts": "tslint --fix --force 'src/**/*.ts?(x)'", + "lint:css": "lesshint src/ui/styles/*.less examples/*.css", "lint": "npm-run-all --parallel lint:*", "test": "karma start" }, @@ -33,9 +33,11 @@ "@types/chai": "^3.4.34", "@types/mocha": "^2.2.33", "@types/react": "^0.14.50", + "@types/react-addons-test-utils": "^0.14.15", "@types/react-dom": "^0.14.19", "@types/sinon": "^1.16.32", "@types/sinon-chai": "^2.7.27", + "@types/tinycolor2": "^1.1.0", "chai": "^3.5.0", "codecov.io": "^0.1.6", "copyfiles": "^1.0.0", @@ -43,6 +45,7 @@ "css-loader": "^0.26.0", "del-cli": "^0.2.0", "html-loader": "^0.4.4", + "istanbul-instrumenter-loader": "^1.1.0", "karma": "^1.3.0", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^2.0.0", @@ -54,9 +57,11 @@ "karma-webpack": "^1.8.0", "less": "^2.7.1", "less-loader": "^2.2.3", + "lesshint": "^2.3.0", "mkdirp": "^0.5.1", "mocha": "^3.1.2", "npm-run-all": "^3.1.2", + "react-addons-test-utils": "^15.4.1", "sinon": "^2.0.0-pre.4", "sinon-chai": "^2.8.0", "source-map-loader": "^0.1.5", @@ -64,12 +69,13 @@ "ts-loader": "^1.2.2", "tslint": "^4.0.2", "typescript": "^2.0.10", - "webpack": "^2.1.0-beta.27", - "webpack-dev-server": "^2.1.0-beta.12" + "webpack": "^2.2.0-rc.3", + "webpack-dev-server": "^2.2.0-rc.0" }, "dependencies": { "material-design-lite": "^1.2.1", "react": "^15.4.0", - "react-dom": "^15.4.0" + "react-dom": "^15.4.0", + "tinycolor2": "^1.4.1" } } diff --git a/src/core/Remixer.ts b/src/core/Remixer.ts index e5207d2..3d7a56e 100644 --- a/src/core/Remixer.ts +++ b/src/core/Remixer.ts @@ -14,16 +14,17 @@ * under the License. */ -import "../ui/styles/iframe.less"; import { BooleanVariable } from "./variables/BooleanVariable"; import { ColorVariable } from "./variables/ColorVariable"; -import { KeyCode, KeyEvent, CSS } from "../lib/Constants"; +import { CSS, KeyCode, KeyEvent } from "../lib/Constants"; import { LocalStorage } from "../lib/LocalStorage"; import { Messaging } from "../lib/Messaging"; import { NumberVariable } from "./variables/NumberVariable"; -import { RangeVariable } from "./variables/RangeVariable"; +import { IRangeVariableParams, RangeVariable } from "./variables/RangeVariable"; +import { IVariableCallback, IVariableKeyMap, Variable } from "./variables/Variable"; import { StringVariable } from "./variables/StringVariable"; -import { Variable, VariableCallback, VariableKeyMap } from "./variables/Variable"; + +import "../ui/styles/iframe.less"; /** * A declaration used for the webpack `html-loader` module to load string @@ -53,7 +54,12 @@ class Remixer { * @return {Remixer} The attached instance of Remixer. */ static get attachedInstance(): Remixer { - return window.parent["remixer"]._sharedInstance as Remixer; + let parentRemixer = window.parent["remixer"]; + if (parentRemixer) { + return parentRemixer._sharedInstance as Remixer; + } + // Simply return shared remixer instance if no parent. + return this._sharedInstance; } private _frameElement: HTMLFrameElement; @@ -120,13 +126,17 @@ class Remixer { /** * Adds a boolean Variable to array of Variables with optional callback. - * @param {string} key The key of the Variable. - * @param {boolean} defaultValue The initial default value of the variable. - * @param {VariableCallback} callback The callback method to be invoked - * when the Variable is updated. + * @param {string} key The key of the Variable. + * @param {boolean} defaultValue The initial default value of the variable. + * @param {IVariableCallback} callback The callback method to be invoked + * when the Variable is updated. * @return {BooleanVariable} */ - static addBooleanVariable(key: string, defaultValue: boolean, callback?: VariableCallback): BooleanVariable { + static addBooleanVariable( + key: string, + defaultValue: boolean, + callback?: IVariableCallback, + ): BooleanVariable { let variable = new BooleanVariable(key, defaultValue, callback); this.addVariable(variable); return variable; @@ -139,11 +149,18 @@ class Remixer { * @param {number} minValue The allowed minimum value of the variable. * @param {number} maxValue The allowed maximum value of the variable. * @param {number} increment The amount to increment the value. - * @param {VariableCallback} callback The callback method to be invoked + * @param {IVariableCallback} callback The callback method to be invoked * when the Variable is updated. * @return {RangeVariable} */ - static addRangeVariable(key: string, defaultValue: number, minValue: number, maxValue: number, increment: number, callback?: VariableCallback): RangeVariable { + static addRangeVariable( + key: string, + defaultValue: number, + minValue: number, + maxValue: number, + increment: number, + callback?: IVariableCallback, + ): RangeVariable { let variable = new RangeVariable(key, defaultValue, minValue, maxValue, increment, callback); this.addVariable(variable); return variable; @@ -151,45 +168,60 @@ class Remixer { /** * Adds a string Variable to array of variables with optional callback - * @param {string} key The key of the Variable. - * @param {string} defaultValue The initial default value of the variable. - * @param {Array} possibleValues The optional array of available items for the variable. - * @param {VariableCallback} callback The callback method to be invoked - * when the Variable is updated. + * @param {string} key The key of the Variable. + * @param {string} defaultValue The initial default value of the variable. + * @param {string[]} limitedToValues The optional array of allowed values. + * @param {IVariableCallback} callback The callback method to be invoked + * when the Variable is updated. * @return {StringVariable} */ - static addStringVariable(key: string, defaultValue: string, possibleValues?: Array, callback?: VariableCallback): StringVariable { - let variable = new StringVariable(key, defaultValue, possibleValues, callback); + static addStringVariable( + key: string, + defaultValue: string, + limitedToValues?: string[], + callback?: IVariableCallback, + ): StringVariable { + let variable = new StringVariable(key, defaultValue, limitedToValues, callback); this.addVariable(variable); return variable; } /** * Adds a number variable to array of variables with optional callback. - * @param {string} key The key of the Variable. - * @param {number} defaultValue The initial default value of the variable. - * @param {Array} possibleValues The optional array of available items for the variable. - * @param {VariableCallback} callback The callback method to be invoked - * when the Variable is updated. + * @param {string} key The key of the Variable. + * @param {number} defaultValue The initial default value of the variable. + * @param {number[]} limitedToValues The optional array of allowed values. + * @param {IVariableCallback} callback The callback method to be invoked + * when the Variable is updated. * @return {NumberVariable} */ - static addNumberVariable(key: string, defaultValue: number, possibleValues?: Array, callback?: VariableCallback): NumberVariable { - let variable = new NumberVariable(key, defaultValue, possibleValues, callback); + static addNumberVariable( + key: string, + defaultValue: number, + limitedToValues?: number[], + callback?: IVariableCallback, + ): NumberVariable { + let variable = new NumberVariable(key, defaultValue, limitedToValues, callback); this.addVariable(variable); return variable; } /** * Adds a color variable to array of variables with optional callback. - * @param {string} key The key of the Variable. - * @param {string} defaultValue The initial default value of the variable. - * @param {Array} possibleValues The optional array of available items for the variable. - * @param {VariableCallback} callback The callback method to be invoked - * when the Variable is updated. + * @param {string} key The key of the Variable. + * @param {string} defaultValue The initial default value of the variable. + * @param {string[]} limitedToValues The optional array of allowed values. + * @param {IVariableCallback} callback The callback method to be invoked + * when the Variable is updated. * @return {ColorVariable} */ - static addColorVariable(key: string, defaultValue: string, possibleValues?: Array, callback?: VariableCallback): ColorVariable { - let variable = new ColorVariable(key, defaultValue, possibleValues, callback); + static addColorVariable( + key: string, + defaultValue: string, + limitedToValues?: string[], + callback?: IVariableCallback, + ): ColorVariable { + let variable = new ColorVariable(key, defaultValue, limitedToValues, callback); this.addVariable(variable); return variable; } @@ -221,28 +253,28 @@ class Remixer { } } - private _variables: VariableKeyMap = {}; + private _variables: IVariableKeyMap = {}; /** * Returns the Variable-Key mapping from the Remixer shared instance. - * @return {VariableKeyMap} + * @return {IVariableKeyMap} */ - get variables(): VariableKeyMap { + get variables(): IVariableKeyMap { return this._variables; } /** * Returns an array of Variables from the Remixer shared instance. - * @return {Array} Array of Variables. + * @return {Variable[]} Array of Variables. */ - get variablesArray(): Array { - return Object.keys(this._variables).map(key => this._variables[key]); + get variablesArray(): Variable[] { + return Object.keys(this._variables).map((key) => this._variables[key]); } /** * Returns an Variable for a given key from the Remixer shared instance. * @static - * @return {Array} Array of Variables. + * @return {Variable[]} Array of Variables. */ static getVariable(key: string): Variable { return this._sharedInstance._variables[key]; diff --git a/src/core/__tests__/BooleanVariable_test.ts b/src/core/__tests__/BooleanVariable_test.ts index 4f93ee9..94cb64a 100644 --- a/src/core/__tests__/BooleanVariable_test.ts +++ b/src/core/__tests__/BooleanVariable_test.ts @@ -4,8 +4,8 @@ import * as sinonChai from "sinon-chai"; import { remixer } from "../Remixer"; import { BooleanVariable } from "../variables/BooleanVariable"; +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; import { Variable } from "../variables/Variable"; -import { VariableType } from "../../lib/Constants"; const expect = chai.expect; chai.use(sinonChai); @@ -27,7 +27,15 @@ describe("BooleanVariable", () => { }); it("have the correct datatype", () => { - expect(variable.dataType).to.equal(VariableType.BOOLEAN); + expect(variable.dataType).to.equal(DataType.BOOLEAN); + }); + + it("have the correct contraintType", () => { + expect(variable.constraintType).to.equal(ConstraintType.NONE); + }); + + it("have the correct controlType", () => { + expect(variable.controlType).to.equal(ControlType.SWITCH); }); it("have the correct title", () => { @@ -46,4 +54,9 @@ describe("BooleanVariable", () => { expect(callbackSpy).to.have.been.calledOnce.and.calledWith(variable); expect(updatedVariable.selectedValue).to.equal(newValue); }); + + it("should clone properly", () => { + let clone = variable.clone(); + expect(JSON.stringify(clone)).to.equal(JSON.stringify(variable)); + }); }); diff --git a/src/core/__tests__/ColorVariable_test.ts b/src/core/__tests__/ColorVariable_test.ts index a01fd6a..e274e8c 100644 --- a/src/core/__tests__/ColorVariable_test.ts +++ b/src/core/__tests__/ColorVariable_test.ts @@ -4,8 +4,8 @@ import * as sinonChai from "sinon-chai"; import { remixer } from "../Remixer"; import { ColorVariable } from "../variables/ColorVariable"; +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; import { Variable } from "../variables/Variable"; -import { VariableType } from "../../lib/Constants"; const expect = chai.expect; chai.use(sinonChai); @@ -14,13 +14,18 @@ describe("ColorVariable", () => { const key: string = "test variable"; const sanitizedKey: string = "test_variable"; const defaultValue: string = "#4285F4"; - const possibleValues: Array = ["#4285F4", "#0F9D58", "#DB4437"]; + const limitedToValues: string[] = ["#4285F4", "#0F9D58", "#DB4437"]; let callbackSpy: sinon.SinonSpy; let variable: ColorVariable; beforeEach(() => { callbackSpy = sinon.spy(); - variable = remixer.addColorVariable(key, defaultValue, possibleValues, callbackSpy); + variable = remixer.addColorVariable( + key, + defaultValue, + limitedToValues, + callbackSpy, + ); }); it("should create a new variable", () => { @@ -28,7 +33,27 @@ describe("ColorVariable", () => { }); it("have the correct datatype", () => { - expect(variable.dataType).to.equal(VariableType.COLOR); + expect(variable.dataType).to.equal(DataType.COLOR); + }); + + it("have the correct contraintType", () => { + expect(variable.constraintType).to.equal(ConstraintType.LIST); + + variable.limitedToValues = []; + expect(variable.constraintType).to.equal(ConstraintType.NONE); + }); + + it("have the correct controlType", () => { + expect(variable.controlType).to.equal(ControlType.COLOR_LIST); + }); + + it("should have correct controlType based on number of allowed values", () => { + // List control. + expect(variable.controlType).to.equal(ControlType.COLOR_LIST); + + // Input control. + let var1 = remixer.addColorVariable("test_key", "#4285F4"); + expect(var1.controlType).to.equal(ControlType.COLOR_INPUT); }); it("have the correct title", () => { @@ -39,8 +64,8 @@ describe("ColorVariable", () => { expect(variable.key).to.equal(sanitizedKey); }); - it("have the correct possible values", () => { - expect(variable.possibleValues).to.equal(possibleValues); + it("have the correct allowed values", () => { + expect(variable.limitedToValues).to.equal(limitedToValues); }); it("should trigger callback when selected value of variable changes", () => { @@ -51,4 +76,9 @@ describe("ColorVariable", () => { expect(callbackSpy).to.have.been.calledOnce.and.calledWith(variable); expect(updatedVariable.selectedValue).to.equal(newValue); }); + + it("should clone properly", () => { + let clone = variable.clone(); + expect(JSON.stringify(clone)).to.equal(JSON.stringify(variable)); + }); }); diff --git a/src/core/__tests__/NumberVariable_test.ts b/src/core/__tests__/NumberVariable_test.ts index 52f5bec..235691e 100644 --- a/src/core/__tests__/NumberVariable_test.ts +++ b/src/core/__tests__/NumberVariable_test.ts @@ -3,9 +3,9 @@ import * as sinon from "sinon"; import * as sinonChai from "sinon-chai"; import { remixer } from "../Remixer"; +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; import { NumberVariable } from "../variables/NumberVariable"; import { Variable } from "../variables/Variable"; -import { VariableType } from "../../lib/Constants"; const expect = chai.expect; chai.use(sinonChai); @@ -14,13 +14,18 @@ describe("NumberVariable", () => { const key: string = "test variable"; const sanitizedKey: string = "test_variable"; const defaultValue: number = 20; - const possibleValues: Array = [10, 20, 30, 40]; + const limitedToValues: number[] = [10, 20, 30, 40]; let callbackSpy: sinon.SinonSpy; let variable: NumberVariable; beforeEach(() => { callbackSpy = sinon.spy(); - variable = remixer.addNumberVariable(key, defaultValue, possibleValues, callbackSpy); + variable = remixer.addNumberVariable( + key, + defaultValue, + limitedToValues, + callbackSpy, + ); }); it("should create a new variable", () => { @@ -28,7 +33,27 @@ describe("NumberVariable", () => { }); it("have the correct datatype", () => { - expect(variable.dataType).to.equal(VariableType.NUMBER); + expect(variable.dataType).to.equal(DataType.NUMBER); + }); + + it("have the correct contraintType", () => { + expect(variable.constraintType).to.equal(ConstraintType.LIST); + + variable.limitedToValues = []; + expect(variable.constraintType).to.equal(ConstraintType.NONE); + }); + + it("should have correct controlType based on number of allowed values", () => { + // List control. + expect(variable.controlType).to.equal(ControlType.TEXT_LIST); + + // Segmented control. + let var1 = remixer.addNumberVariable("test_key1", 1, [1, 2]); + expect(var1.controlType).to.equal(ControlType.SEGMENTED); + + // Text input control. + let var2 = remixer.addNumberVariable("test_key2", 1); + expect(var2.controlType).to.equal(ControlType.TEXT_INPUT); }); it("have the correct title", () => { @@ -39,8 +64,8 @@ describe("NumberVariable", () => { expect(variable.key).to.equal(sanitizedKey); }); - it("have the correct possible values", () => { - expect(variable.possibleValues).to.equal(possibleValues); + it("have the correct allowed values", () => { + expect(variable.limitedToValues).to.equal(limitedToValues); }); it("should trigger callback when selected value of variable changes", () => { @@ -51,4 +76,9 @@ describe("NumberVariable", () => { expect(callbackSpy).to.have.been.calledOnce.and.calledWith(variable); expect(updatedVariable.selectedValue).to.equal(newValue); }); + + it("should clone properly", () => { + let clone = variable.clone(); + expect(JSON.stringify(clone)).to.equal(JSON.stringify(variable)); + }); }); diff --git a/src/core/__tests__/RangeVariable_test.ts b/src/core/__tests__/RangeVariable_test.ts index 807f359..9aca2b3 100644 --- a/src/core/__tests__/RangeVariable_test.ts +++ b/src/core/__tests__/RangeVariable_test.ts @@ -3,9 +3,9 @@ import * as sinon from "sinon"; import * as sinonChai from "sinon-chai"; import { remixer } from "../Remixer"; +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; import { RangeVariable } from "../variables/RangeVariable"; import { Variable } from "../variables/Variable"; -import { VariableType } from "../../lib/Constants"; const expect = chai.expect; chai.use(sinonChai); @@ -22,7 +22,14 @@ describe("RangeVariable", () => { beforeEach(() => { callbackSpy = sinon.spy(); - variable = remixer.addRangeVariable(key, defaultValue, minValue, maxValue, increment, callbackSpy); + variable = remixer.addRangeVariable( + key, + defaultValue, + minValue, + maxValue, + increment, + callbackSpy, + ); }); it("should create a new variable", () => { @@ -30,7 +37,15 @@ describe("RangeVariable", () => { }); it("have the correct datatype", () => { - expect(variable.dataType).to.equal(VariableType.RANGE); + expect(variable.dataType).to.equal(DataType.NUMBER); + }); + + it("have the correct contraintType", () => { + expect(variable.constraintType).to.equal(ConstraintType.RANGE); + }); + + it("have the correct controlType", () => { + expect(variable.controlType).to.equal(ControlType.SLIDER); }); it("have the correct title", () => { @@ -55,4 +70,9 @@ describe("RangeVariable", () => { expect(callbackSpy).to.have.been.calledOnce.and.calledWith(variable); expect(updatedVariable.selectedValue).to.equal(newValue); }); + + it("should clone properly", () => { + let clone = variable.clone(); + expect(JSON.stringify(clone)).to.equal(JSON.stringify(variable)); + }); }); diff --git a/src/core/__tests__/Remixer_test.ts b/src/core/__tests__/Remixer_test.ts new file mode 100644 index 0000000..b78f745 --- /dev/null +++ b/src/core/__tests__/Remixer_test.ts @@ -0,0 +1,48 @@ +import * as chai from "chai"; +import * as sinon from "sinon"; +import * as sinonChai from "sinon-chai"; + +import { remixer } from "../Remixer"; +import { DataType } from "../../lib/Constants"; + +const expect = chai.expect; +chai.use(sinonChai); + +describe("Remixer", () => { + + beforeEach(() => { + localStorage.clear(); + remixer.addBooleanVariable("key1", true); + remixer.addStringVariable("key2", "testString"); + remixer.addNumberVariable("key3", 40); + }); + + it("should create an iframe after start", () => { + expect(remixer.frameElement).to.not.exist; + remixer.start(); + expect(remixer.frameElement).to.exist; + }); + + it("have the correct number of variables in array", () => { + let variablesArray = remixer.attachedInstance.variablesArray; + expect(variablesArray).to.have.length(3); + }); + + it("should retrieve variables from map", () => { + let variablesMap = remixer.attachedInstance.variables; + expect(variablesMap).to.have.all.keys("key1", "key2", "key3"); + }); + + it("should retrieve correct variable from map by key", () => { + let stringVariable = remixer.getVariable("key2"); + expect(stringVariable.dataType).to.equal(DataType.STRING); + }); + + it("should update selected value of variable", () => { + let numberVariable = remixer.getVariable("key3"); + expect(numberVariable.selectedValue).to.equal(40); + + remixer.updateVariable(numberVariable, 50); + expect(numberVariable.selectedValue).to.equal(50); + }); +}); diff --git a/src/core/__tests__/StringVariable_test.ts b/src/core/__tests__/StringVariable_test.ts index 671b541..eab0c13 100644 --- a/src/core/__tests__/StringVariable_test.ts +++ b/src/core/__tests__/StringVariable_test.ts @@ -3,9 +3,9 @@ import * as sinon from "sinon"; import * as sinonChai from "sinon-chai"; import { remixer } from "../Remixer"; +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; import { StringVariable } from "../variables/StringVariable"; import { Variable } from "../variables/Variable"; -import { VariableType } from "../../lib/Constants"; const expect = chai.expect; chai.use(sinonChai); @@ -14,13 +14,18 @@ describe("StringVariable", () => { const key: string = "test variable"; const sanitizedKey: string = "test_variable"; const defaultValue: string = "B"; - const possibleValues: Array = ["A", "B", "C", "D"]; + const limitedToValues: string[] = ["A", "B", "C", "D"]; let callbackSpy: sinon.SinonSpy; let variable: StringVariable; beforeEach(() => { callbackSpy = sinon.spy(); - variable = remixer.addStringVariable(key, defaultValue, possibleValues, callbackSpy); + variable = remixer.addStringVariable( + key, + defaultValue, + limitedToValues, + callbackSpy, + ); }); it("should create a new variable", () => { @@ -28,7 +33,27 @@ describe("StringVariable", () => { }); it("have the correct datatype", () => { - expect(variable.dataType).to.equal(VariableType.STRING); + expect(variable.dataType).to.equal(DataType.STRING); + }); + + it("have the correct contraintType", () => { + expect(variable.constraintType).to.equal(ConstraintType.LIST); + + variable.limitedToValues = []; + expect(variable.constraintType).to.equal(ConstraintType.NONE); + }); + + it("should have correct controlType based on number of allowed values", () => { + // List control. + expect(variable.controlType).to.equal(ControlType.TEXT_LIST); + + // Segmented control. + let var1 = remixer.addStringVariable("test_key1", "a", ["a", "b"]); + expect(var1.controlType).to.equal(ControlType.SEGMENTED); + + // Text input control. + let var2 = remixer.addStringVariable("test_key2", "a"); + expect(var2.controlType).to.equal(ControlType.TEXT_INPUT); }); it("have the correct title", () => { @@ -39,8 +64,8 @@ describe("StringVariable", () => { expect(variable.key).to.equal(sanitizedKey); }); - it("have the correct possible values", () => { - expect(variable.possibleValues).to.equal(possibleValues); + it("have the correct allowed values", () => { + expect(variable.limitedToValues).to.equal(limitedToValues); }); it("should trigger callback when selected value of variable changes", () => { @@ -51,4 +76,9 @@ describe("StringVariable", () => { expect(callbackSpy).to.have.been.calledOnce.and.calledWith(variable); expect(updatedVariable.selectedValue).to.equal(newValue); }); + + it("should clone properly", () => { + let clone = variable.clone(); + expect(JSON.stringify(clone)).to.equal(JSON.stringify(variable)); + }); }); diff --git a/src/core/variables/BooleanVariable.ts b/src/core/variables/BooleanVariable.ts index a370046..2b1d909 100644 --- a/src/core/variables/BooleanVariable.ts +++ b/src/core/variables/BooleanVariable.ts @@ -14,16 +14,16 @@ * under the License. */ -import { SerializableData } from "../../lib/LocalStorage"; -import { Variable, VariableParams, VariableCallback } from "./Variable"; -import { VariableType } from "../../lib/Constants"; +import { ControlType, DataType } from "../../lib/Constants"; +import { ISerializableData } from "../../lib/LocalStorage"; +import { IVariableCallback, IVariableParams, Variable } from "./Variable"; /** * Interface for a class that represents a type of Variable for boolean values. * @interface - * @extends VariableParams + * @extends IVariableParams */ -interface BooleanVariableParams extends VariableParams { +interface IBooleanVariableParams extends IVariableParams { defaultValue: boolean; selectedValue: boolean; } @@ -32,20 +32,25 @@ interface BooleanVariableParams extends VariableParams { * A class representing a type of Variable for boolean values. * @class * @extends Variable - * @implements {BooleanVariableParams} + * @implements {IBooleanVariableParams} */ -export class BooleanVariable extends Variable implements BooleanVariableParams { +export class BooleanVariable extends Variable implements IBooleanVariableParams { /** * Creates an instance of a BooleanVariable. * @constructor - * @param {string} key A unique key for the Variable. - * @param {boolean} defaultValue The default value. - * @param {VariableCallback} callback The callback to invoke when updated. + * @param {string} key A unique key for the Variable. + * @param {boolean} defaultValue The default value. + * @param {IVariableCallback} callback The callback to invoke when updated. * @return {BooleanVariable} */ - constructor(key: string, defaultValue: boolean, callback?: VariableCallback) { - super(key, VariableType.BOOLEAN, defaultValue, callback); + constructor( + key: string, + defaultValue: boolean, + callback?: IVariableCallback, + ) { + super(key, DataType.BOOLEAN, defaultValue, callback); + this.controlType = ControlType.SWITCH; } /** @@ -62,9 +67,9 @@ export class BooleanVariable extends Variable implements BooleanVariableParams { /** * Returns a serialized representation of this object. * @override - * @return {SerializableData} The serialized data. + * @return {ISerializableData} The serialized data. */ - serialize(): SerializableData { + serialize(): ISerializableData { let data = super.serialize(); data.defaultValue = this.defaultValue; data.selectedValue = this.selectedValue; @@ -74,10 +79,10 @@ export class BooleanVariable extends Variable implements BooleanVariableParams { /** * Returns a new initialized BooleanVariable from serialized data. * @override - * @param {SerializableData} data The serialized data. - * @return {BooleanVariable} A new initialized BooleanVariable. + * @param {ISerializableData} data The serialized data. + * @return {BooleanVariable} A new initialized BooleanVariable. */ - static deserialize(data: SerializableData): BooleanVariable { + static deserialize(data: ISerializableData): BooleanVariable { return new BooleanVariable(data.key, data.selectedValue); } } diff --git a/src/core/variables/ColorVariable.ts b/src/core/variables/ColorVariable.ts index 127dc61..f3c2c8d 100644 --- a/src/core/variables/ColorVariable.ts +++ b/src/core/variables/ColorVariable.ts @@ -14,41 +14,60 @@ * under the License. */ -import { SerializableData } from "../../lib/LocalStorage"; -import { Variable, VariableListParams, VariableCallback } from "./Variable"; -import { VariableType } from "../../lib/Constants"; +import * as TinyColor from "tinycolor2"; + +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; +import { ISerializableData } from "../../lib/LocalStorage"; +import { IVariableCallback, IVariableListParams, Variable } from "./Variable"; /** * Interface for a class that represents a type of Variable for color values. * @interface - * @extends VariableListParams + * @extends IVariableListParams */ -interface ColorVariableParams extends VariableListParams { +interface IColorVariableParams extends IVariableListParams { defaultValue: string; selectedValue: string; - possibleValues?: Array; + limitedToValues?: string[]; } /** * A class representing a type of Variable for color values. * @class * @extends Variable - * @implements {ColorVariableParams} + * @implements {IColorVariableParams} */ -export class ColorVariable extends Variable implements ColorVariableParams { +export class ColorVariable extends Variable implements IColorVariableParams { /** * Creates an instance of a ColorVariable. * @constructor - * @param {string} key A unique key for the Variable. - * @param {string} defaultValue The default value. - * @param {Array} possibleValues The array of possible values. - * @param {VariableCallback} callback The callback to invoke when updated. + * @param {string} key A unique key for the Variable. + * @param {string} defaultValue The default value. + * @param {string[]} limitedToValues The array of allowed values. + * @param {IVariableCallback} callback The callback to invoke when updated. * @return {ColorVariable} */ - constructor(key: string, defaultValue: string, possibleValues?: Array, callback?: VariableCallback) { - super(key, VariableType.COLOR, defaultValue, callback); - this.possibleValues = possibleValues; + constructor( + key: string, + defaultValue: string, + limitedToValues?: string[], + callback?: IVariableCallback, + ) { + super(key, DataType.COLOR, defaultValue, callback); + this.limitedToValues = limitedToValues ? limitedToValues : []; + this.controlType = (this.limitedToValues.length > 0) ? + ControlType.COLOR_LIST : ControlType.COLOR_INPUT; + } + + /** + * The data constraint type for this Variable. + * @type {string} + * @readonly + */ + get constraintType(): string { + return this.limitedToValues.length > 0 ? + ConstraintType.LIST : ConstraintType.NONE; } /** @@ -59,7 +78,7 @@ export class ColorVariable extends Variable implements ColorVariableParams { let cloned = new ColorVariable( this.key, this.defaultValue, - this.possibleValues + this.limitedToValues, ); cloned.title = this.title; cloned._callbacks = this._callbacks.slice(); @@ -67,31 +86,37 @@ export class ColorVariable extends Variable implements ColorVariableParams { } /** - * The array of possible values for this Variable. + * The array of allowed values for this Variable. * @override - * @type {Array} + * @type {string[]} */ - possibleValues?: Array; + limitedToValues?: string[]; /** * Returns a serialized representation of this object. * @override - * @return {SerializableData} The serialized data. + * @return {ISerializableData} The serialized data. */ - serialize(): SerializableData { + serialize(): ISerializableData { let data = super.serialize(); - data.selectedValue = this.selectedValue; - data.possibleValues = this.possibleValues; + data.selectedValue = TinyColor(this.selectedValue).toRgb(); + data.limitedToValues = this.limitedToValues.map((value: any) => { + return TinyColor(value).toRgb(); + }); return data; } /** * Returns a new initialized ColorVariable from serialized data. * @override - * @param {SerializableData} data The serialized data. - * @return {ColorVariable} A new initialized ColorVariable. + * @param {ISerializableData} data The serialized data. + * @return {ColorVariable} A new initialized ColorVariable. */ - static deserialize(data: SerializableData): Variable { - return new ColorVariable(data.key, data.selectedValue, data.possibleValues); + static deserialize(data: ISerializableData): Variable { + let selectedValue = TinyColor(data.selectedValue).toHexString(); + let limitedToValues = data.limitedToValues.map((color: string) => { + return TinyColor(color).toHexString(); + }); + return new ColorVariable(data.key, selectedValue, limitedToValues); } } diff --git a/src/core/variables/NumberVariable.ts b/src/core/variables/NumberVariable.ts index f43ccf4..c98ff5b 100644 --- a/src/core/variables/NumberVariable.ts +++ b/src/core/variables/NumberVariable.ts @@ -14,41 +14,63 @@ * under the License. */ -import { SerializableData } from "../../lib/LocalStorage"; -import { Variable, VariableListParams, VariableCallback } from "./Variable"; -import { VariableType } from "../../lib/Constants"; +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; +import { ISerializableData } from "../../lib/LocalStorage"; +import { IVariableCallback, IVariableListParams, Variable } from "./Variable"; /** * Interface for a class that represents a type of Variable for number values. * @interface - * @extends VariableListParams + * @extends IVariableListParams */ -interface NumberVariableParams extends VariableListParams { +interface INumberVariableParams extends IVariableListParams { defaultValue: number; selectedValue: number; - possibleValues?: Array; + limitedToValues?: number[]; } /** * A class representing a type of Variable for number values. * @class * @extends Variable - * @implements {NumberVariableParams} + * @implements {INumberVariableParams} */ -export class NumberVariable extends Variable implements NumberVariableParams { +export class NumberVariable extends Variable implements INumberVariableParams { /** * Creates an instance of a ColorVariable. * @constructor - * @param {string} key A unique key for the Variable. - * @param {number} defaultValue The default value. - * @param {Array} possibleValues The array of possible values. - * @param {VariableCallback} callback The callback to invoke when updated. - * @return {[NumberVariable]} + * @param {string} key A unique key for the Variable. + * @param {number} defaultValue The default value. + * @param {number[]} limitedToValues The array of allowed values. + * @param {IVariableCallback} callback The callback to invoke when updated. + * @return {NumberVariable} */ - constructor(key: string, defaultValue: number, possibleValues?: Array, callback?: VariableCallback) { - super(key, VariableType.NUMBER, defaultValue, callback); - this.possibleValues = possibleValues; + constructor( + key: string, + defaultValue: number, + limitedToValues?: number[], + callback?: IVariableCallback, + ) { + super(key, DataType.NUMBER, defaultValue, callback); + this.limitedToValues = limitedToValues ? limitedToValues : []; + if (this.limitedToValues.length === 0) { + this.controlType = ControlType.TEXT_INPUT; + } else if (this.limitedToValues.length <= 2) { + this.controlType = ControlType.SEGMENTED; + } else { + this.controlType = ControlType.TEXT_LIST; + } + } + + /** + * The data constraint type for this Variable. + * @type {string} + * @readonly + */ + get constraintType(): string { + return this.limitedToValues.length > 0 ? + ConstraintType.LIST : ConstraintType.NONE; } /** @@ -59,7 +81,7 @@ export class NumberVariable extends Variable implements NumberVariableParams { let cloned = new NumberVariable( this.key, this.defaultValue, - this.possibleValues + this.limitedToValues, ); cloned.title = this.title; cloned._callbacks = this._callbacks.slice(); @@ -67,31 +89,35 @@ export class NumberVariable extends Variable implements NumberVariableParams { } /** - * The array of possible values for this Variable. + * The array of allowed values for this Variable. * @override - * @type {Array} + * @type {number[]} */ - possibleValues?: Array; + limitedToValues?: number[]; /** * Returns a serialized representation of this object. * @override - * @return {SerializableData} The serialized data. + * @return {ISerializableData} The serialized data. */ - serialize(): SerializableData { + serialize(): ISerializableData { let data = super.serialize(); data.selectedValue = this.selectedValue; - data.possibleValues = this.possibleValues; + data.limitedToValues = this.limitedToValues; return data; } /** * Returns a new initialized NumberVariable from serialized data. * @override - * @param {SerializableData} data The serialized data. - * @return {NumberVariable} A new initialized NumberVariable. + * @param {ISerializableData} data The serialized data. + * @return {NumberVariable} A new initialized NumberVariable. */ - static deserialize(data: SerializableData): Variable { - return new NumberVariable(data.key, data.selectedValue, data.possibleValues); + static deserialize(data: ISerializableData): Variable { + return new NumberVariable( + data.key, + data.selectedValue, + data.limitedToValues, + ); } } diff --git a/src/core/variables/RangeVariable.ts b/src/core/variables/RangeVariable.ts index ed2d40b..49d8625 100644 --- a/src/core/variables/RangeVariable.ts +++ b/src/core/variables/RangeVariable.ts @@ -14,46 +14,65 @@ * under the License. */ -import { SerializableData } from "../../lib/LocalStorage"; -import { Variable, VariableParams, VariableCallback } from "./Variable"; -import { VariableType } from "../../lib/Constants"; +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; +import { ISerializableData } from "../../lib/LocalStorage"; +import { IVariableCallback, IVariableParams, Variable } from "./Variable"; /** - * Interface for a class that represents a type of Variable for a range of values. + * Interface for a class that represents a type of Variable for a range + * of values. * @interface - * @extends VariableParams + * @extends IVariableParams */ -interface RangeVariableParams extends VariableParams { +export interface IRangeVariableParams extends IVariableParams { defaultValue: number; selectedValue: number; minValue: number; maxValue: number; increment: number; + callback?: IVariableCallback; } /** * A class representing a type of Variable for a range of values. * @class * @extends Variable - * @implements {RangeVariableParams} + * @implements {IRangeVariableParams} */ -export class RangeVariable extends Variable implements RangeVariableParams { +export class RangeVariable extends Variable implements IRangeVariableParams { /** * Creates an instance of a RangeVariable. * @constructor - * @param {string} key A unique key for the Variable. - * @param {number} defaultValue The default value. - * @param {number} minValue The minimum value allowed. - * @param {number} maxValue The maximum value allowed. - * @param {VariableCallback} callback The callback to invoke when updated. + * @param {string} key A unique key for the Variable. + * @param {number} defaultValue The default value. + * @param {number} minValue The minimum value allowed. + * @param {number} maxValue The maximum value allowed. + * @param {IVariableCallback} callback The callback to invoke when updated. * @return {RangeVariable} */ - constructor(key: string, defaultValue: number, minValue: number, maxValue: number, increment: number, callback?: VariableCallback) { - super(key, VariableType.RANGE, defaultValue, callback); + constructor( + key: string, + defaultValue: number, + minValue: number, + maxValue: number, + increment: number, + callback?: IVariableCallback, + ) { + super(key, DataType.NUMBER, defaultValue, callback); this.minValue = minValue; this.maxValue = maxValue; this.increment = increment; + this.controlType = ControlType.SLIDER; + } + + /** + * The data constraint type for this Variable. + * @type {string} + * @readonly + */ + get constraintType(): string { + return ConstraintType.RANGE; } /** @@ -66,7 +85,7 @@ export class RangeVariable extends Variable implements RangeVariableParams { this.defaultValue, this.minValue, this.maxValue, - this.increment + this.increment, ); cloned.title = this.title; cloned._callbacks = this._callbacks.slice(); @@ -97,9 +116,9 @@ export class RangeVariable extends Variable implements RangeVariableParams { /** * Returns a serialized representation of this object. * @override - * @return {SerializableData} The serialized data. + * @return {ISerializableData} The serialized data. */ - serialize(): SerializableData { + serialize(): ISerializableData { let data = super.serialize(); data.selectedValue = this.selectedValue.toString(); data.minValue = this.minValue; @@ -111,14 +130,20 @@ export class RangeVariable extends Variable implements RangeVariableParams { /** * Returns a new initialized RangeVariable from serialized data. * @override - * @param {SerializableData} data The serialized data. - * @return {RangeVariable} A new initialized RangeVariable. + * @param {ISerializableData} data The serialized data. + * @return {RangeVariable} A new initialized RangeVariable. */ - static deserialize(data: SerializableData): Variable { + static deserialize(data: ISerializableData): Variable { let selectedValue: number = parseFloat(data.selectedValue); let minValue: number = data.minValue; let maxValue: number = data.maxValue; let increment: number = data.increment; - return new RangeVariable(data.key, selectedValue, minValue, maxValue, increment); + return new RangeVariable( + data.key, + selectedValue, + minValue, + maxValue, + increment, + ); } } diff --git a/src/core/variables/StringVariable.ts b/src/core/variables/StringVariable.ts index 06f9208..a64adb1 100644 --- a/src/core/variables/StringVariable.ts +++ b/src/core/variables/StringVariable.ts @@ -14,41 +14,63 @@ * under the License. */ -import { SerializableData } from "../../lib/LocalStorage"; -import { Variable, VariableListParams, VariableCallback } from "./Variable"; -import { VariableType } from "../../lib/Constants"; +import { ConstraintType, ControlType, DataType } from "../../lib/Constants"; +import { ISerializableData } from "../../lib/LocalStorage"; +import { IVariableCallback, IVariableListParams, Variable } from "./Variable"; /** * Interface for a class that represents a type of Variable for string values. * @interface - * @extends VariableListParams + * @extends IVariableListParams */ -interface StringVariableParams extends VariableListParams { +interface IStringVariableParams extends IVariableListParams { defaultValue: string; selectedValue: string; - possibleValues?: Array; + limitedToValues?: string[]; } /** * A class representing a type of Variable for string values. * @class * @extends Variable - * @implements {StringVariableParams} + * @implements {IStringVariableParams} */ -export class StringVariable extends Variable implements StringVariableParams { +export class StringVariable extends Variable implements IStringVariableParams { /** * Creates an instance of a StringVariable. * @constructor - * @param {string} key [A unique key for the Variable. - * @param {string} defaultValue The default value. - * @param {Array} possibleValues The array of possible values. - * @param {VariableCallback} callback The callback to invoke when updated. + * @param {string} key [A unique key for the Variable. + * @param {string} defaultValue The default value. + * @param {string[]} limitedToValues The array of allowed values. + * @param {IVariableCallback} callback The callback to invoke when updated. * @return {StringVariable} */ - constructor(key: string, defaultValue: string, possibleValues?: Array, callback?: VariableCallback) { - super(key, VariableType.STRING, defaultValue, callback); - this.possibleValues = possibleValues; + constructor( + key: string, + defaultValue: string, + limitedToValues?: string[], + callback?: IVariableCallback, + ) { + super(key, DataType.STRING, defaultValue, callback); + this.limitedToValues = limitedToValues ? limitedToValues : []; + if (this.limitedToValues.length === 0) { + this.controlType = ControlType.TEXT_INPUT; + } else if (this.limitedToValues.length <= 2) { + this.controlType = ControlType.SEGMENTED; + } else { + this.controlType = ControlType.TEXT_LIST; + } + } + + /** + * The data constraint type for this Variable. + * @type {string} + * @readonly + */ + get constraintType(): string { + return this.limitedToValues.length > 0 ? + ConstraintType.LIST : ConstraintType.NONE; } /** @@ -59,7 +81,7 @@ export class StringVariable extends Variable implements StringVariableParams { let cloned = new StringVariable( this.key, this.defaultValue, - this.possibleValues + this.limitedToValues, ); cloned.title = this.title; cloned._callbacks = this._callbacks.slice(); @@ -67,31 +89,35 @@ export class StringVariable extends Variable implements StringVariableParams { } /** - * The array of possible values for this Variable. + * The array of allowed values for this Variable. * @override - * @type {Array} + * @type {string[]} */ - possibleValues?: Array; + limitedToValues?: string[]; /** * Returns a serialized representation of this object. * @override - * @return {SerializableData} The serialized data. + * @return {ISerializableData} The serialized data. */ - serialize(): SerializableData { + serialize(): ISerializableData { let data = super.serialize(); data.selectedValue = this.selectedValue; - data.possibleValues = this.possibleValues; + data.limitedToValues = this.limitedToValues; return data; } /** * Returns a new initialized StringVariable from serialized data. * @override - * @param {SerializableData} data The serialized data. - * @return {StringVariable} A new initialized StringVariable. + * @param {ISerializableData} data The serialized data. + * @return {StringVariable} A new initialized StringVariable. */ - static deserialize(data: SerializableData): StringVariable { - return new StringVariable(data.key, data.selectedValue, data.possibleValues); + static deserialize(data: ISerializableData): StringVariable { + return new StringVariable( + data.key, + data.selectedValue, + data.limitedToValues, + ); } } diff --git a/src/core/variables/Variable.ts b/src/core/variables/Variable.ts index f668ad3..9a12b3c 100644 --- a/src/core/variables/Variable.ts +++ b/src/core/variables/Variable.ts @@ -14,29 +14,33 @@ * under the License. */ -import { SerializableData } from "../../lib/LocalStorage"; import { remixer } from "../Remixer"; +import { ConstraintType } from "../../lib/Constants"; +import { ISerializableData } from "../../lib/LocalStorage"; /** * Interface for a class that represents a type a Variable. * @interface */ -export interface VariableParams { +export interface IVariableParams { key: string; title: string; + constraintType: string; + controlType: string; dataType: string; defaultValue: any; selectedValue: any; - callbacks?: Array; + callbacks?: IVariableCallback[]; } /** - * Interface for a class that represents a type a Variable with possible values. + * Interface for a class that represents a type of Variable that can only be + * set to predefined values. * @interface - * @extends VariableParams + * @extends IVariableParams */ -export interface VariableListParams extends VariableParams { - possibleValues?: Array; +export interface IVariableListParams extends IVariableParams { + limitedToValues?: any[]; } /** @@ -44,7 +48,7 @@ export interface VariableListParams extends VariableParams { * @interface * @extends Function */ -export interface VariableCallback extends Function { +export interface IVariableCallback extends Function { variable?: Variable; } @@ -52,26 +56,31 @@ export interface VariableCallback extends Function { * Interface that maps a Variable to its key. * @interface */ -export interface VariableKeyMap { +export interface IVariableKeyMap { [key: string]: Variable; } /** * A class representing a type a Variable. * @class - * @implements {VariableParams} + * @implements {IVariableParams} */ -export class Variable implements VariableParams { +export class Variable implements IVariableParams { /** * Creates an instance of a Variable. - * @param {string} key A unique key for the Variable. - * @param {string} dataType The data type of this Variable. - * @param {any} defaultValue The default value. - * @param {VariableCallback} callback The callback to invoke when updated. + * @param {string} key A unique key for the Variable. + * @param {string} dataType The data type of this Variable. + * @param {any} defaultValue The default value. + * @param {IVariableCallback} callback The callback to invoke when updated. * @return {Variable} */ - constructor(key: string, dataType: string, defaultValue: any, callback?: VariableCallback) { + constructor( + key: string, + dataType: string, + defaultValue: any, + callback?: IVariableCallback, + ) { this.key = this.sanitizeKey(key); this.title = key; this.dataType = dataType; @@ -88,12 +97,32 @@ export class Variable implements VariableParams { * @return {Variable} Returns the cloned variable. */ clone() { - let cloned = new Variable(this.key, this.defaultValue, null); + let cloned = new Variable( + this.key, + this.dataType, + this.defaultValue, + null, + ); cloned.title = this.title; cloned._callbacks = this._callbacks.slice(); return cloned; } + /** + * The data constraint type for this Variable. + * @type {string} + * @readonly + */ + get constraintType(): string { + return ConstraintType.NONE; + } + + /** + * The rendered control type for this Variable. + * @type {string} + */ + controlType: string; + /** * The data type represented by this Variable. * @type {string} @@ -145,21 +174,21 @@ export class Variable implements VariableParams { } } - protected _callbacks: Array = new Array(); + protected _callbacks: IVariableCallback[] = new Array(); /** * The callback method to be invoked when the Variable is updated. - * @return {Array} The array of callback methods. + * @return {IVariableCallback[]} The array of callback methods. */ - get callbacks(): Array { + get callbacks(): IVariableCallback[] { return this._callbacks; } /** * Adds a callback to array of callbacks. - * @param {VariableCallback} callback The callback to add. + * @param {IVariableCallback} callback The callback to add. */ - addCallback(callback: VariableCallback): any { + addCallback(callback: IVariableCallback): any { this._callbacks.push(callback); } @@ -174,9 +203,9 @@ export class Variable implements VariableParams { /** * First adds a callback to array, and then immediatly executes that callback. - * @param {VariableCallback} callback The callback to add and execute. + * @param {IVariableCallback} callback The callback to add and execute. */ - addAndExecuteCallback(callback: VariableCallback): void { + addAndExecuteCallback(callback: IVariableCallback): void { this._callbacks.push(callback); callback(this); } @@ -197,11 +226,13 @@ export class Variable implements VariableParams { /** * Returns a serialized representation of this object. - * @return {SerializableData} The serialized data. + * @return {ISerializableData} The serialized data. */ - serialize(): SerializableData { - let data = {}; + serialize(): ISerializableData { + let data = {}; data.key = this.key; + data.constraintType = this.constraintType; + data.controlType = this.controlType; data.dataType = this.dataType; data.title = this.title; return data; @@ -210,10 +241,10 @@ export class Variable implements VariableParams { /** * Subclass should override this method and return a new instance of thei * Variable class from serialized data. - * @param {SerializableData} data The serialized data. - * @return {Variable} A new initialized Variable subclass. + * @param {ISerializableData} data The serialized data. + * @return {Variable} A new initialized Variable subclass. */ - static deserialize(data: SerializableData): Variable { + static deserialize(data: ISerializableData): Variable { return null; } diff --git a/src/lib/Constants.ts b/src/lib/Constants.ts index dda0254..826665b 100644 --- a/src/lib/Constants.ts +++ b/src/lib/Constants.ts @@ -16,26 +16,45 @@ /** Keycode constants. */ export const KeyCode = { - ESC: 27 + ESC: 27, }; /** Key event constants. */ export const KeyEvent = { - DOWN: "keydown" + DOWN: "keydown", }; /** Storage keys constants. */ export const StorageKey = { - REMIXER: "__remixer__" + REMIXER: "__remixer__", }; -/** Variable types constants. */ -export const VariableType = { - BOOLEAN: "boolean", - COLOR: "color", - NUMBER: "number", - RANGE: "range", - STRING: "string", +/** Variable data constraints. */ +export const ConstraintType = { + NONE: "__ConstraintTypeNone__", + LIST: "__ConstraintTypeList__", + RANGE: "__ConstraintTypeRange__", +}; + +/** Rendered variable control types. */ +export const ControlType = { + BUTTON: "__ControlTypeButton__", + COLOR_INPUT: "__ControlTypeColorInput__", + COLOR_LIST: "__ControlTypeColorList__", + SEGMENTED: "__ControlTypeSegmented__", + SLIDER: "__ControlTypeSlider__", + STEPPER: "__ControlTypeStepper__", + SWITCH: "__ControlTypeSwitch__", + TEXT_INPUT: "__ControlTypeTextInput__", + TEXT_LIST: "__ControlTypeTextList__", +}; + +/** Variable data types. */ +export const DataType = { + BOOLEAN: "__DataTypeBoolean__", + COLOR: "__DataTypeColor__", + NUMBER: "__DataTypeNumber__", + STRING: "__DataTypeString__", }; /** CSS class and id constants. */ @@ -46,20 +65,18 @@ export const CSS = { MDL_SECONDARY: "mdl-list__item-secondary-content", MDL_TWO_LINE: "mdl-list__item--two-line", - // iFrame ID must be unique within a client page. - RMX_OVERLAY_FRAME: "__remixer-overlay-frame__", - - RMX_OVERLAY_WRAPPER: "rmx-overlay-wrapper", - RMX_VISIBLE: "rmx-visible", - RMX_SELECTED_VALUE: "rmx-selected-value", RMX_COLOR_SWATCH: "rmx-color-swatch", RMX_COLOR_SWATCH_ITEM: "rmx-color-swatch-item", RMX_DROPDOWN: "rmx-dropdown", + RMX_OVERLAY_FRAME: "__remixer-overlay-frame__", + RMX_OVERLAY_WRAPPER: "rmx-overlay-wrapper", RMX_RADIO_LIST: "rmx-radio-list", RMX_RADIO_LIST_ITEM: "rmx-radio-list-item", + RMX_SELECTED_VALUE: "rmx-selected-value", RMX_SLIDER: "rmx-slider", - RMX_SLIDER_MIN: "rmx-slider-min-value", RMX_SLIDER_MAX: "rmx-slider-max-value", + RMX_SLIDER_MIN: "rmx-slider-min-value", RMX_SWITCH: "rmx-switch", RMX_TEXTFIELD: "rmx-textfield", + RMX_VISIBLE: "rmx-visible", }; diff --git a/src/lib/LocalStorage.ts b/src/lib/LocalStorage.ts index 85b6de1..696cefb 100644 --- a/src/lib/LocalStorage.ts +++ b/src/lib/LocalStorage.ts @@ -14,12 +14,11 @@ * under the License. */ -import { remixer } from "../core/Remixer"; import { BooleanVariable } from "../core/variables/BooleanVariable"; import { ColorVariable } from "../core/variables/ColorVariable"; +import { ConstraintType, DataType, StorageKey } from "../lib/Constants"; import { NumberVariable } from "../core/variables/NumberVariable"; import { RangeVariable } from "../core/variables/RangeVariable"; -import { StorageKey, VariableType } from "../lib/Constants"; import { StringVariable } from "../core/variables/StringVariable"; import { Variable } from "../core/variables/Variable"; @@ -27,13 +26,15 @@ import { Variable } from "../core/variables/Variable"; * Interface for a class that represents serialized data. * @interface */ -export interface SerializableData { +export interface ISerializableData { key: string; + constraintType: string; + controlType: string; dataType: string; title: string; defaultValue: any; selectedValue: any; - possibleValues?: Array; + limitedToValues?: any[]; minValue?: number; maxValue?: number; increment?: number; @@ -43,8 +44,8 @@ export interface SerializableData { * Interface that maps a serialized data to a global "remixer" key. * @interface */ -interface SerializableDataMap { - [remixer: string]: SerializableData; +interface ISerializableDataMap { + [remixer: string]: ISerializableData; } /** @@ -61,7 +62,7 @@ export class LocalStorage { */ static getVariable(key: string): Variable { let remixerData = this.getRawData(); - let variableData = remixerData[key] as SerializableData; + let variableData = remixerData[key] as ISerializableData; if (variableData) { return this.deserialize(variableData); } @@ -83,20 +84,21 @@ export class LocalStorage { * Returns an initialized Variable based on the data type. * @private * @static - * @param {SerializableData} data The serialized data. + * @param {ISerializableData} data The serialized data. * @return {Variable} */ - private static deserialize(data: SerializableData): Variable { + private static deserialize(data: ISerializableData): Variable { switch (data.dataType) { - case VariableType.BOOLEAN: + case DataType.BOOLEAN: return BooleanVariable.deserialize(data); - case VariableType.COLOR: + case DataType.COLOR: return ColorVariable.deserialize(data); - case VariableType.NUMBER: + case DataType.NUMBER: + if (data.constraintType === ConstraintType.RANGE) { + return RangeVariable.deserialize(data); + } return NumberVariable.deserialize(data); - case VariableType.RANGE: - return RangeVariable.deserialize(data); - case VariableType.STRING: + case DataType.STRING: return StringVariable.deserialize(data); default: return null; @@ -107,10 +109,10 @@ export class LocalStorage { * Retrieves the raw JSON data from local storage. * @private * @static - * @return {SerializableDataMap} The json data from local storage. + * @return {ISerializableDataMap} The json data from local storage. */ - private static getRawData(): SerializableDataMap { - let data: SerializableDataMap = JSON.parse(localStorage.getItem(StorageKey.REMIXER)); + private static getRawData(): ISerializableDataMap { + let data: ISerializableDataMap = JSON.parse(localStorage.getItem(StorageKey.REMIXER)); return data || {}; } @@ -118,9 +120,9 @@ export class LocalStorage { * Saves the raw JSON data to local storage. * @private * @static - * @param {SerializableDataMap} data The serialized data to save. + * @param {ISerializableDataMap} data The serialized data to save. */ - private static saveRawData(data: SerializableDataMap): void { + private static saveRawData(data: ISerializableDataMap): void { localStorage.setItem(StorageKey.REMIXER, JSON.stringify(data)); } } diff --git a/src/lib/Messaging.ts b/src/lib/Messaging.ts index 7201668..56c8b0d 100644 --- a/src/lib/Messaging.ts +++ b/src/lib/Messaging.ts @@ -21,7 +21,7 @@ import { CSS } from "../lib/Constants"; * @enum */ enum MessagingType { - ToggleVisibility + ToggleVisibility, } /** diff --git a/src/lib/__tests__/LocalStorage_test.ts b/src/lib/__tests__/LocalStorage_test.ts new file mode 100644 index 0000000..4556158 --- /dev/null +++ b/src/lib/__tests__/LocalStorage_test.ts @@ -0,0 +1,37 @@ +import * as chai from "chai"; +import * as sinon from "sinon"; +import * as sinonChai from "sinon-chai"; + +import { remixer } from "../../core/Remixer"; +import { ConstraintType, ControlType, DataType } from "../Constants"; +import { LocalStorage } from "../LocalStorage"; + +const expect = chai.expect; +chai.use(sinonChai); + +describe("LocalStorage", () => { + + function addVariables() { + remixer.addBooleanVariable("test_key1", true); + remixer.addStringVariable("test_key2", "testString"); + remixer.addNumberVariable("test_key3", 40); + } + + it("should call saveVariable method", () => { + let callbackSpy = sinon.spy(LocalStorage, "saveVariable"); + localStorage.clear(); + addVariables(); + + expect(callbackSpy).to.have.been.calledThrice; + }); + + it("should retrieve correct variable from storage", () => { + addVariables(); + let stringVariable = LocalStorage.getVariable("test_key2"); + + expect(stringVariable.dataType).to.equal(DataType.STRING); + expect(stringVariable.constraintType).to.equal(ConstraintType.NONE); + expect(stringVariable.controlType).to.equal(ControlType.TEXT_INPUT); + expect(stringVariable.selectedValue).to.equal("testString"); + }); +}); diff --git a/src/ui/OverlayController.tsx b/src/ui/OverlayController.tsx index 4557eb2..d5c8ce0 100644 --- a/src/ui/OverlayController.tsx +++ b/src/ui/OverlayController.tsx @@ -15,7 +15,8 @@ */ import * as React from "react"; -import { KeyCode, KeyEvent, CSS } from "../lib/Constants"; + +import { CSS, KeyCode, KeyEvent } from "../lib/Constants"; import { Messaging } from "../lib/Messaging"; import { OverlayVariables } from "./OverlayVariables"; import { Variable } from "../core/variables/Variable"; @@ -24,9 +25,9 @@ import { Variable } from "../core/variables/Variable"; * Interface for the properties assigned to the OverlayController component. * @interface */ -interface ControllerProps { +interface IControllerProps { wrapperElement: HTMLElement; - variables: Array; + variables: Variable[]; updateVariable(variable: Variable, selectedValue: any): void; } @@ -36,7 +37,7 @@ interface ControllerProps { * @class * @extends React.Component */ -export class OverlayController extends React.Component { +export class OverlayController extends React.Component { /** @override */ componentDidMount() { diff --git a/src/ui/OverlayVariables.tsx b/src/ui/OverlayVariables.tsx index 5c0c17f..f76a4d0 100644 --- a/src/ui/OverlayVariables.tsx +++ b/src/ui/OverlayVariables.tsx @@ -15,10 +15,11 @@ */ import * as React from "react"; + +import { CSS, ControlType } from "../lib/Constants"; import { ColorSwatchControl } from "./controls/ColorSwatchControl"; -import { ControlUpdateProps } from "./controls/controlProps"; -import { CSS, VariableType } from "../lib/Constants"; import { DropdownControl } from "./controls/DropdownControl"; +import { IControlUpdateProps } from "./controls/controlProps"; import { RadioListControl } from "./controls/RadioListControl"; import { SliderControl } from "./controls/SliderControl"; import { StringVariable } from "../core/variables/StringVariable"; @@ -29,10 +30,10 @@ import { Variable } from "../core/variables/Variable"; /** * Interface for a React class that requires an array of Variables. * @interface - * @extends ControlUpdateProps + * @extends IControlUpdateProps */ -export interface OverlayVariableProps extends ControlUpdateProps { - variables: Array; +export interface IOverlayVariableProps extends IControlUpdateProps { + variables: Variable[]; } /** @@ -41,51 +42,52 @@ export interface OverlayVariableProps extends ControlUpdateProps { * @class * @extends React.Component */ -export class OverlayVariables extends React.Component { - - /** - * Returns a control as determined by the variable `dataType` property. - * @param {Variable} variable The variable to provide the control for. - * @return {any} A control component. - */ - controlForVariable(variable: Variable): any { - switch (variable.dataType) { - case VariableType.BOOLEAN: - return SwitchControl; - case VariableType.RANGE: - return SliderControl; - case VariableType.STRING: - const { possibleValues } = variable as StringVariable; - if (!possibleValues) { - return TextFieldControl; - } else if (possibleValues.length === 2) { - return RadioListControl; - } else { - return DropdownControl; - } - case VariableType.NUMBER: - return TextFieldControl; - case VariableType.COLOR: - return ColorSwatchControl; - } - return null; - } +export class OverlayVariables extends React.Component { /** @override */ render() { return (
- {this.props.variables.map(variable => { + {this.props.variables.map((variable) => { const Control = this.controlForVariable(variable); - return ( - - ); + if (Control) { + return ( + + ); + } })}
); } + + /** + * Returns a control as determined by the variable `dataType` property. + * @private + * @param {Variable} variable The variable to provide the control for. + * @return {any} A control component. + */ + private controlForVariable(variable: Variable): any { + // TODO(cjcox): Provide support for controls: + // BUTTON, COLOR_INPUT, STEPPER + switch (variable.controlType) { + case ControlType.COLOR_LIST: + return ColorSwatchControl; + case ControlType.SEGMENTED: + return RadioListControl; + case ControlType.SLIDER: + return SliderControl; + case ControlType.SWITCH: + return SwitchControl; + case ControlType.TEXT_INPUT: + return TextFieldControl; + case ControlType.TEXT_LIST: + return DropdownControl; + default: + return null; + } + } } diff --git a/src/ui/__tests__/ColorSwatchControl_test.tsx b/src/ui/__tests__/ColorSwatchControl_test.tsx new file mode 100644 index 0000000..39a9ff4 --- /dev/null +++ b/src/ui/__tests__/ColorSwatchControl_test.tsx @@ -0,0 +1,48 @@ +import * as React from "react"; +import * as TestUtils from "react-addons-test-utils"; +import * as chai from "chai"; + +import { remixer } from "../../core/Remixer"; +import { ColorSwatchControl } from "../controls/ColorSwatchControl"; +import { CSS } from "../../lib/Constants"; +import { Variable } from "../../core/variables/Variable"; + +const expect = chai.expect; + +describe("ColorSwatchControl", () => { + const key: string = "test_variable"; + const defaultValue: string = "#4285F4"; + const limitedToValues: string[] = ["#4285F4", "#0F9D58", "#DB4437"]; + let variable: Variable; + + beforeEach(() => { + variable = remixer.addColorVariable(key, defaultValue, limitedToValues); + this.component = TestUtils.renderIntoDocument( + + ); + }); + + it("should render with proper class name", () => { + let control = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.RMX_COLOR_SWATCH + ); + + expect(TestUtils.isDOMComponent(control)).to.be.true; + }); + + it("have correct number of children with proper data values", () => { + let list = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.MDL_SECONDARY + ); + + expect(list.children.length).to.equal(3); + + for (let i = 0; i < list.children.length; i++) { + let element = list.children[i] as HTMLElement; + expect(element.dataset["value"]).to.equal(limitedToValues[i]); + } + }); +}); diff --git a/src/ui/__tests__/DropdownControl_test.tsx b/src/ui/__tests__/DropdownControl_test.tsx new file mode 100644 index 0000000..64352d5 --- /dev/null +++ b/src/ui/__tests__/DropdownControl_test.tsx @@ -0,0 +1,48 @@ +import * as React from "react"; +import * as TestUtils from "react-addons-test-utils"; +import * as chai from "chai"; + +import { remixer } from "../../core/Remixer"; +import { CSS } from "../../lib/Constants"; +import { DropdownControl } from "../controls/DropdownControl"; +import { Variable } from "../../core/variables/Variable"; + +const expect = chai.expect; + +describe("DropdownControl", () => { + const key: string = "test_variable"; + const defaultValue: string = "a"; + const limitedToValues: string[] = ["a", "b", "c"]; + let variable: Variable; + + beforeEach(() => { + variable = remixer.addStringVariable(key, defaultValue, limitedToValues); + this.component = TestUtils.renderIntoDocument( + + ); + }); + + it("should render with proper class name", () => { + let control = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.RMX_DROPDOWN + ); + + expect(TestUtils.isDOMComponent(control)).to.be.true; + }); + + it("have correct number of children with proper data values", () => { + let list = TestUtils.findRenderedDOMComponentWithTag( + this.component, "ul" + ); + + expect(list.children.length).to.equal(3); + + for (let i = 0; i < list.children.length; i++) { + let element = list.children[i] as HTMLElement; + expect(element.dataset["value"]).to.equal(limitedToValues[i]); + } + }); +}); diff --git a/src/ui/__tests__/RadioListControl_test.tsx b/src/ui/__tests__/RadioListControl_test.tsx new file mode 100644 index 0000000..1600c9c --- /dev/null +++ b/src/ui/__tests__/RadioListControl_test.tsx @@ -0,0 +1,51 @@ +import * as React from "react"; +import * as TestUtils from "react-addons-test-utils"; +import * as chai from "chai"; + +import { remixer } from "../../core/Remixer"; +import { CSS } from "../../lib/Constants"; +import { RadioListControl } from "../controls/RadioListControl"; +import { Variable } from "../../core/variables/Variable"; + +const expect = chai.expect; + +describe("RadioListControl", () => { + const key: string = "test_variable"; + const defaultValue: string = "a"; + const limitedToValues: string[] = ["a", "b"]; + let variable: Variable; + + beforeEach(() => { + variable = remixer.addStringVariable(key, defaultValue, limitedToValues); + this.component = TestUtils.renderIntoDocument( + + ); + }); + + it("should render with proper class name", () => { + let control = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.RMX_RADIO_LIST + ); + + expect(TestUtils.isDOMComponent(control)).to.be.true; + }); + + it("have correct number of children with proper data values", () => { + let list = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.MDL_SECONDARY + ); + + expect(list.children.length).to.equal(2); + + let elements = TestUtils.scryRenderedDOMComponentsWithClass( + this.component, "mdl-radio__button" + ) as HTMLInputElement[]; + + for (let i = 0; i < elements.length; i++) { + expect(elements[i].value).to.equal(limitedToValues[i]); + } + }); +}); diff --git a/src/ui/__tests__/SliderControl_test.tsx b/src/ui/__tests__/SliderControl_test.tsx new file mode 100644 index 0000000..70a6e57 --- /dev/null +++ b/src/ui/__tests__/SliderControl_test.tsx @@ -0,0 +1,64 @@ +import * as React from "react"; +import * as TestUtils from "react-addons-test-utils"; +import * as chai from "chai"; + +import { remixer } from "../../core/Remixer"; +import { CSS } from "../../lib/Constants"; +import { RangeVariable } from "../../core/variables/RangeVariable"; +import { SliderControl } from "../controls/SliderControl"; + +const expect = chai.expect; + +describe("SliderControl", () => { + const key: string = "test_variable"; + const defaultValue: number = 0.5; + const minValue: number = 0; + const maxValue: number = 1; + const increment: number = 0.1; + let variable: RangeVariable; + + beforeEach(() => { + variable = remixer.addRangeVariable(key, defaultValue, minValue, maxValue, increment); + this.component = TestUtils.renderIntoDocument( + + ); + }); + + it("should render with proper class name", () => { + let control = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.RMX_SLIDER + ); + + expect(TestUtils.isDOMComponent(control)).to.be.true; + }); + + it("have correct min label", () => { + let label = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.RMX_SLIDER_MIN + ); + + expect(Number(label.textContent)).to.equal(minValue); + }); + + it("have correct max label", () => { + let label = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.RMX_SLIDER_MAX + ); + + expect(Number(label.textContent)).to.equal(maxValue); + }); + + it("have correct slider input value and attributes", () => { + let slider = TestUtils.findRenderedDOMComponentWithClass( + this.component, "mdl-slider" + ) as HTMLInputElement; + + expect(Number(slider.min)).to.equal(minValue); + expect(Number(slider.max)).to.equal(maxValue); + expect(Number(slider.step)).to.equal(increment); + expect(Number(slider.value)).to.equal(defaultValue); + }); +}); diff --git a/src/ui/__tests__/SwitchControl_test.tsx b/src/ui/__tests__/SwitchControl_test.tsx new file mode 100644 index 0000000..3ee71d9 --- /dev/null +++ b/src/ui/__tests__/SwitchControl_test.tsx @@ -0,0 +1,42 @@ +import * as React from "react"; +import * as TestUtils from "react-addons-test-utils"; +import * as chai from "chai"; + +import { remixer } from "../../core/Remixer"; +import { CSS } from "../../lib/Constants"; +import { SwitchControl } from "../controls/SwitchControl"; +import { Variable } from "../../core/variables/Variable"; + +const expect = chai.expect; + +describe("SwitchControl", () => { + const key: string = "test_variable"; + const defaultValue: boolean = true; + let variable: Variable; + + beforeEach(() => { + variable = remixer.addBooleanVariable(key, defaultValue,); + this.component = TestUtils.renderIntoDocument( + + ); + }); + + it("should render with proper class name", () => { + let control = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.RMX_SWITCH + ); + + expect(TestUtils.isDOMComponent(control)).to.be.true; + }); + + it("have correct switch checked value", () => { + let control = TestUtils.findRenderedDOMComponentWithClass( + this.component, "mdl-switch__input" + ) as HTMLInputElement; + + expect(control.checked).to.equal(defaultValue); + }); +}); diff --git a/src/ui/__tests__/TextFieldControl_test.tsx b/src/ui/__tests__/TextFieldControl_test.tsx new file mode 100644 index 0000000..06040bb --- /dev/null +++ b/src/ui/__tests__/TextFieldControl_test.tsx @@ -0,0 +1,43 @@ +import * as React from "react"; +import * as TestUtils from "react-addons-test-utils"; +import * as chai from "chai"; + +import { remixer } from "../../core/Remixer"; +import { CSS } from "../../lib/Constants"; +import { TextFieldControl } from "../controls/TextFieldControl"; +import { Variable } from "../../core/variables/Variable"; + +const expect = chai.expect; + +describe("TextFieldControl", () => { + const key: string = "test_variable"; + const defaultValue: string = "test string value"; + let variable: Variable; + + beforeEach(() => { + variable = remixer.addStringVariable(key, defaultValue); + variable.selectedValue = defaultValue; + this.component = TestUtils.renderIntoDocument( + + ); + }); + + it("should render with proper class name", () => { + let control = TestUtils.findRenderedDOMComponentWithClass( + this.component, CSS.RMX_TEXTFIELD + ); + + expect(TestUtils.isDOMComponent(control)).to.be.true; + }); + + it("have correct innertext checked value", () => { + let textField = TestUtils.findRenderedDOMComponentWithClass( + this.component, "mdl-textfield__input" + ) as HTMLInputElement; + + expect(textField.value).to.equal(defaultValue); + }); +}); diff --git a/src/ui/controls/ColorSwatchControl.tsx b/src/ui/controls/ColorSwatchControl.tsx index 2b704f9..03183de 100644 --- a/src/ui/controls/ColorSwatchControl.tsx +++ b/src/ui/controls/ColorSwatchControl.tsx @@ -15,27 +15,29 @@ */ import * as React from "react"; -import { ColorControlProps } from "./controlProps"; -import { CSS, VariableType } from "../../lib/Constants"; +import * as TinyColor from "tinycolor2"; + +import { CSS } from "../../lib/Constants"; +import { IColorControlProps } from "./controlProps"; /** * A color swatch picker control consisting of a single color swatch for each - * possible value. + * allowed value. * @class * @extends React.Component */ -export class ColorSwatchControl extends React.Component { +export class ColorSwatchControl extends React.Component { /** Handles the update event for this control. */ onClick = (event: React.FormEvent): void => { this.props.updateVariable( this.props.variable, - (event.target as HTMLElement).dataset["value"] + (event.target as HTMLElement).dataset["value"], ); } /** @override */ - shouldComponentUpdate(nextProps: ColorControlProps) { + shouldComponentUpdate(nextProps: IColorControlProps) { return nextProps.variable !== this.props.variable; } @@ -43,20 +45,25 @@ export class ColorSwatchControl extends React.Component render() { const { title, - possibleValues, - selectedValue + limitedToValues, + selectedValue, } = this.props.variable; return (
{title} - {selectedValue} + + {TinyColor(selectedValue).toString()} + - {possibleValues.map((value: string) => ( + {limitedToValues.map((value: string) => ( ))} @@ -71,7 +78,7 @@ export class ColorSwatchControl extends React.Component * Interface containing properties for a single color swatch. * @interface */ -interface ColorSwatchProps { +interface IColorSwatchProps { color: string; isSelected: boolean; onClick: any; @@ -79,14 +86,18 @@ interface ColorSwatchProps { /** * Returns a single color swatch displayed within the `ColorSwatchControl`. - * @param {ColorSwatchProps} props The color swatch properties. + * @param {IColorSwatchProps} props The color swatch properties. */ -function ColorSwatch(props: ColorSwatchProps) { +function ColorSwatch(props: IColorSwatchProps) { const { color, isSelected, onClick, } = props; + // Determine a readable color to prevent a white checkmark on a light + // color swatch. + let readableCheckColors = [TinyColor("white"), TinyColor("gray")]; + let checkColor = TinyColor.mostReadable(TinyColor(color), readableCheckColors); return (
- {isSelected ? check : ""} + { + isSelected ? check : "" + }
); } diff --git a/src/ui/controls/DropdownControl.tsx b/src/ui/controls/DropdownControl.tsx index 4bce1af..03cfd53 100644 --- a/src/ui/controls/DropdownControl.tsx +++ b/src/ui/controls/DropdownControl.tsx @@ -15,26 +15,27 @@ */ import * as React from "react"; + import { CSS } from "../../lib/Constants"; -import { StringControlProps } from "./controlProps"; +import { IStringControlProps } from "./controlProps"; /** * A dropdown control. * @class * @extends React.Component */ -export class DropdownControl extends React.Component { +export class DropdownControl extends React.Component { /** Handles the update event for this control. */ onClick = (event: React.FormEvent): void => { this.props.updateVariable( this.props.variable, - (event.target as HTMLElement).dataset["value"] + (event.target as HTMLElement).dataset["value"], ); } /** @override */ - shouldComponentUpdate(nextProps: StringControlProps) { + shouldComponentUpdate(nextProps: IStringControlProps) { return nextProps.variable !== this.props.variable; } @@ -43,8 +44,8 @@ export class DropdownControl extends React.Component { const { title, key, - possibleValues, - selectedValue + limitedToValues, + selectedValue, } = this.props.variable; const id = `${CSS.RMX_DROPDOWN}-${key}`; @@ -61,7 +62,7 @@ export class DropdownControl extends React.Component { className="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" htmlFor={id} > - {possibleValues.map((value: string) => ( + {limitedToValues.map((value: string) => (
  • {value} diff --git a/src/ui/controls/RadioListControl.tsx b/src/ui/controls/RadioListControl.tsx index d875218..5636e82 100644 --- a/src/ui/controls/RadioListControl.tsx +++ b/src/ui/controls/RadioListControl.tsx @@ -15,26 +15,27 @@ */ import * as React from "react"; -import { CSS, VariableType } from "../../lib/Constants"; -import { StringControlProps } from "./controlProps"; + +import { CSS } from "../../lib/Constants"; +import { IStringControlProps } from "./controlProps"; /** * A radio list control. * @class * @extends React.Component */ -export class RadioListControl extends React.Component { +export class RadioListControl extends React.Component { /** Handles the update event for this control. */ onChange = (event: React.FormEvent): void => { this.props.updateVariable( this.props.variable, - (event.target as HTMLInputElement).value + (event.target as HTMLInputElement).value, ); } /** @override */ - shouldComponentUpdate(nextProps: StringControlProps) { + shouldComponentUpdate(nextProps: IStringControlProps) { return nextProps.variable !== this.props.variable; } @@ -43,8 +44,8 @@ export class RadioListControl extends React.Component const { title, key, - possibleValues, - selectedValue + limitedToValues, + selectedValue, } = this.props.variable; const id = `${CSS.RMX_RADIO_LIST_ITEM}-${key}`; @@ -52,7 +53,7 @@ export class RadioListControl extends React.Component
    {title} - {possibleValues.map((value: string, i: number) => ( + {limitedToValues.map((value: string, i: number) => (