diff --git a/.gitignore b/.gitignore index 44b79e4..2c5975d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +dist lib diff --git a/img/2d/corner01.png b/img/2d/corner01.png new file mode 100644 index 0000000..659ddb7 Binary files /dev/null and b/img/2d/corner01.png differ diff --git a/img/2d/corner02.png b/img/2d/corner02.png new file mode 100644 index 0000000..ed49079 Binary files /dev/null and b/img/2d/corner02.png differ diff --git a/img/2d/corner03.png b/img/2d/corner03.png new file mode 100644 index 0000000..d81214d Binary files /dev/null and b/img/2d/corner03.png differ diff --git a/img/2d/corner04.png b/img/2d/corner04.png new file mode 100644 index 0000000..62a7ac7 Binary files /dev/null and b/img/2d/corner04.png differ diff --git a/img/2d/dotLine01.png b/img/2d/dotLine01.png new file mode 100644 index 0000000..dfa6694 Binary files /dev/null and b/img/2d/dotLine01.png differ diff --git a/img/2d/dotLine02.png b/img/2d/dotLine02.png new file mode 100644 index 0000000..954263f Binary files /dev/null and b/img/2d/dotLine02.png differ diff --git a/img/2d/pivitPoint.png b/img/2d/pivitPoint.png new file mode 100644 index 0000000..ae3a928 Binary files /dev/null and b/img/2d/pivitPoint.png differ diff --git a/img/2d/rotateHandle.png b/img/2d/rotateHandle.png new file mode 100644 index 0000000..2019bfe Binary files /dev/null and b/img/2d/rotateHandle.png differ diff --git a/img/3d/heightHandle.png b/img/3d/heightHandle.png new file mode 100644 index 0000000..ca18099 Binary files /dev/null and b/img/3d/heightHandle.png differ diff --git a/img/3d/moveHandle.png b/img/3d/moveHandle.png new file mode 100644 index 0000000..de337e0 Binary files /dev/null and b/img/3d/moveHandle.png differ diff --git a/img/3d/rotateHandle.png b/img/3d/rotateHandle.png new file mode 100644 index 0000000..5e23689 Binary files /dev/null and b/img/3d/rotateHandle.png differ diff --git a/img/3d/sculptHandle.png b/img/3d/sculptHandle.png new file mode 100644 index 0000000..1801caa Binary files /dev/null and b/img/3d/sculptHandle.png differ diff --git a/img/apple-touch-icon-144x144-precomposed.png b/img/apple-touch-icon-144x144-precomposed.png new file mode 100644 index 0000000..e3c478b Binary files /dev/null and b/img/apple-touch-icon-144x144-precomposed.png differ diff --git a/img/authenticate/bg.jpg b/img/authenticate/bg.jpg new file mode 100644 index 0000000..69d0241 Binary files /dev/null and b/img/authenticate/bg.jpg differ diff --git a/img/bannerBg.png b/img/bannerBg.png new file mode 100644 index 0000000..e1e36b4 Binary files /dev/null and b/img/bannerBg.png differ diff --git a/img/btnCross.png b/img/btnCross.png new file mode 100644 index 0000000..ade2255 Binary files /dev/null and b/img/btnCross.png differ diff --git a/img/btnDrawGrid.png b/img/btnDrawGrid.png new file mode 100644 index 0000000..382573e Binary files /dev/null and b/img/btnDrawGrid.png differ diff --git a/img/btnDrawPencil.png b/img/btnDrawPencil.png new file mode 100644 index 0000000..f524883 Binary files /dev/null and b/img/btnDrawPencil.png differ diff --git a/img/btnDrawSmooth.png b/img/btnDrawSmooth.png new file mode 100644 index 0000000..6905f63 Binary files /dev/null and b/img/btnDrawSmooth.png differ diff --git a/img/btnExport.png b/img/btnExport.png new file mode 100644 index 0000000..1422edb Binary files /dev/null and b/img/btnExport.png differ diff --git a/img/btnPlus.png b/img/btnPlus.png new file mode 100644 index 0000000..8225861 Binary files /dev/null and b/img/btnPlus.png differ diff --git a/img/cheatsheet.jpg b/img/cheatsheet.jpg new file mode 100644 index 0000000..f900eab Binary files /dev/null and b/img/cheatsheet.jpg differ diff --git a/img/contextmenu/btnAlignBottom.png b/img/contextmenu/btnAlignBottom.png new file mode 100644 index 0000000..dbfed8f Binary files /dev/null and b/img/contextmenu/btnAlignBottom.png differ diff --git a/img/contextmenu/btnAlignHorizontal.png b/img/contextmenu/btnAlignHorizontal.png new file mode 100644 index 0000000..5629e23 Binary files /dev/null and b/img/contextmenu/btnAlignHorizontal.png differ diff --git a/img/contextmenu/btnAlignLeft.png b/img/contextmenu/btnAlignLeft.png new file mode 100644 index 0000000..57cb26f Binary files /dev/null and b/img/contextmenu/btnAlignLeft.png differ diff --git a/img/contextmenu/btnAlignRight.png b/img/contextmenu/btnAlignRight.png new file mode 100644 index 0000000..8a3c3b5 Binary files /dev/null and b/img/contextmenu/btnAlignRight.png differ diff --git a/img/contextmenu/btnAlignTop.png b/img/contextmenu/btnAlignTop.png new file mode 100644 index 0000000..2eb0f77 Binary files /dev/null and b/img/contextmenu/btnAlignTop.png differ diff --git a/img/contextmenu/btnAlignVertical.png b/img/contextmenu/btnAlignVertical.png new file mode 100644 index 0000000..2a8b76e Binary files /dev/null and b/img/contextmenu/btnAlignVertical.png differ diff --git a/img/contextmenu/btnColor.svg b/img/contextmenu/btnColor.svg new file mode 100644 index 0000000..f08685e --- /dev/null +++ b/img/contextmenu/btnColor.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/img/contextmenu/btnColorOption.svg b/img/contextmenu/btnColorOption.svg new file mode 100644 index 0000000..793d42a --- /dev/null +++ b/img/contextmenu/btnColorOption.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/img/contextmenu/btnCutOut.png b/img/contextmenu/btnCutOut.png new file mode 100644 index 0000000..a8d3aeb Binary files /dev/null and b/img/contextmenu/btnCutOut.png differ diff --git a/img/contextmenu/btnDelete.png b/img/contextmenu/btnDelete.png new file mode 100644 index 0000000..8985d00 Binary files /dev/null and b/img/contextmenu/btnDelete.png differ diff --git a/img/contextmenu/btnDuplicate.png b/img/contextmenu/btnDuplicate.png new file mode 100644 index 0000000..ec92242 Binary files /dev/null and b/img/contextmenu/btnDuplicate.png differ diff --git a/img/contextmenu/btnGroup.png b/img/contextmenu/btnGroup.png new file mode 100644 index 0000000..fb5ac18 Binary files /dev/null and b/img/contextmenu/btnGroup.png differ diff --git a/img/contextmenu/btnMore.png b/img/contextmenu/btnMore.png new file mode 100644 index 0000000..cef8c39 Binary files /dev/null and b/img/contextmenu/btnMore.png differ diff --git a/img/contextmenu/btnOutline1.png b/img/contextmenu/btnOutline1.png new file mode 100644 index 0000000..48bdb98 Binary files /dev/null and b/img/contextmenu/btnOutline1.png differ diff --git a/img/contextmenu/btnOutline2.png b/img/contextmenu/btnOutline2.png new file mode 100644 index 0000000..54f9f04 Binary files /dev/null and b/img/contextmenu/btnOutline2.png differ diff --git a/img/contextmenu/btnOutline3.png b/img/contextmenu/btnOutline3.png new file mode 100644 index 0000000..6c29904 Binary files /dev/null and b/img/contextmenu/btnOutline3.png differ diff --git a/img/contextmenu/btnRedo.png b/img/contextmenu/btnRedo.png new file mode 100644 index 0000000..8f61e97 Binary files /dev/null and b/img/contextmenu/btnRedo.png differ diff --git a/img/contextmenu/btnShapeFill.png b/img/contextmenu/btnShapeFill.png new file mode 100644 index 0000000..60fd7ff Binary files /dev/null and b/img/contextmenu/btnShapeFill.png differ diff --git a/img/contextmenu/btnShapeOutline.png b/img/contextmenu/btnShapeOutline.png new file mode 100644 index 0000000..f55e3f9 Binary files /dev/null and b/img/contextmenu/btnShapeOutline.png differ diff --git a/img/contextmenu/btnUndo.png b/img/contextmenu/btnUndo.png new file mode 100644 index 0000000..0d73fc8 Binary files /dev/null and b/img/contextmenu/btnUndo.png differ diff --git a/img/contextmenu/btnUngroup.png b/img/contextmenu/btnUngroup.png new file mode 100644 index 0000000..31b309e Binary files /dev/null and b/img/contextmenu/btnUngroup.png differ diff --git a/img/contextmenu/colors/btnColor_01.png b/img/contextmenu/colors/btnColor_01.png new file mode 100644 index 0000000..f585eef Binary files /dev/null and b/img/contextmenu/colors/btnColor_01.png differ diff --git a/img/contextmenu/colors/btnColor_02.png b/img/contextmenu/colors/btnColor_02.png new file mode 100644 index 0000000..184bade Binary files /dev/null and b/img/contextmenu/colors/btnColor_02.png differ diff --git a/img/contextmenu/colors/btnColor_03.png b/img/contextmenu/colors/btnColor_03.png new file mode 100644 index 0000000..a9b27a4 Binary files /dev/null and b/img/contextmenu/colors/btnColor_03.png differ diff --git a/img/contextmenu/colors/btnColor_04.png b/img/contextmenu/colors/btnColor_04.png new file mode 100644 index 0000000..884d899 Binary files /dev/null and b/img/contextmenu/colors/btnColor_04.png differ diff --git a/img/contextmenu/colors/btnColor_05.png b/img/contextmenu/colors/btnColor_05.png new file mode 100644 index 0000000..b5d0751 Binary files /dev/null and b/img/contextmenu/colors/btnColor_05.png differ diff --git a/img/contextmenu/colors/btnColor_06.png b/img/contextmenu/colors/btnColor_06.png new file mode 100644 index 0000000..4a475d3 Binary files /dev/null and b/img/contextmenu/colors/btnColor_06.png differ diff --git a/img/contextmenu/colors/btnColor_07.png b/img/contextmenu/colors/btnColor_07.png new file mode 100644 index 0000000..158591b Binary files /dev/null and b/img/contextmenu/colors/btnColor_07.png differ diff --git a/img/contextmenu/colors/btnColor_08.png b/img/contextmenu/colors/btnColor_08.png new file mode 100644 index 0000000..b8f3950 Binary files /dev/null and b/img/contextmenu/colors/btnColor_08.png differ diff --git a/img/contextmenu/colors/btnColor_09.png b/img/contextmenu/colors/btnColor_09.png new file mode 100644 index 0000000..d77f31b Binary files /dev/null and b/img/contextmenu/colors/btnColor_09.png differ diff --git a/img/contextmenu/colors/btnColor_10.png b/img/contextmenu/colors/btnColor_10.png new file mode 100644 index 0000000..8c784ff Binary files /dev/null and b/img/contextmenu/colors/btnColor_10.png differ diff --git a/img/contextmenu/colors/btnColor_11.png b/img/contextmenu/colors/btnColor_11.png new file mode 100644 index 0000000..353d1dc Binary files /dev/null and b/img/contextmenu/colors/btnColor_11.png differ diff --git a/img/contextmenu/colors/btnColor_12.png b/img/contextmenu/colors/btnColor_12.png new file mode 100644 index 0000000..0873721 Binary files /dev/null and b/img/contextmenu/colors/btnColor_12.png differ diff --git a/img/corner/btnExport.png b/img/corner/btnExport.png new file mode 100644 index 0000000..8ae0166 Binary files /dev/null and b/img/corner/btnExport.png differ diff --git a/img/corner/btnHamburger.png b/img/corner/btnHamburger.png new file mode 100644 index 0000000..140380d Binary files /dev/null and b/img/corner/btnHamburger.png differ diff --git a/img/dashboard/add_doodle.png b/img/dashboard/add_doodle.png new file mode 100644 index 0000000..7fa46d8 Binary files /dev/null and b/img/dashboard/add_doodle.png differ diff --git a/img/dashboard/logo.png b/img/dashboard/logo.png new file mode 100644 index 0000000..128b70b Binary files /dev/null and b/img/dashboard/logo.png differ diff --git a/img/dashboard/menuopen.png b/img/dashboard/menuopen.png new file mode 100644 index 0000000..5c776e3 Binary files /dev/null and b/img/dashboard/menuopen.png differ diff --git a/img/design-files/btnColor.psd b/img/design-files/btnColor.psd new file mode 100644 index 0000000..2775e19 Binary files /dev/null and b/img/design-files/btnColor.psd differ diff --git a/img/doodle3d-sign.png b/img/doodle3d-sign.png new file mode 100644 index 0000000..9369536 Binary files /dev/null and b/img/doodle3d-sign.png differ diff --git a/img/export/btn3DHubs.png b/img/export/btn3DHubs.png new file mode 100644 index 0000000..7b4f8c8 Binary files /dev/null and b/img/export/btn3DHubs.png differ diff --git a/img/export/btnEmailSTL.png b/img/export/btnEmailSTL.png new file mode 100644 index 0000000..a06854f Binary files /dev/null and b/img/export/btnEmailSTL.png differ diff --git a/img/export/btnFacebook.png b/img/export/btnFacebook.png new file mode 100644 index 0000000..f2fc115 Binary files /dev/null and b/img/export/btnFacebook.png differ diff --git a/img/export/btnFormide.png b/img/export/btnFormide.png new file mode 100644 index 0000000..678edeb Binary files /dev/null and b/img/export/btnFormide.png differ diff --git a/img/export/btnMaterialise.png b/img/export/btnMaterialise.png new file mode 100644 index 0000000..e3a664b Binary files /dev/null and b/img/export/btnMaterialise.png differ diff --git a/img/export/btnMyMiniFactory.png b/img/export/btnMyMiniFactory.png new file mode 100644 index 0000000..55dce0e Binary files /dev/null and b/img/export/btnMyMiniFactory.png differ diff --git a/img/export/btnPrintWiFi.png b/img/export/btnPrintWiFi.png new file mode 100644 index 0000000..07b0fa7 Binary files /dev/null and b/img/export/btnPrintWiFi.png differ diff --git a/img/export/btnSaveSTL.png b/img/export/btnSaveSTL.png new file mode 100644 index 0000000..9c5ab7e Binary files /dev/null and b/img/export/btnSaveSTL.png differ diff --git a/img/export/btnShapeways.png b/img/export/btnShapeways.png new file mode 100644 index 0000000..2cb8a40 Binary files /dev/null and b/img/export/btnShapeways.png differ diff --git a/img/export/btnShare.png b/img/export/btnShare.png new file mode 100644 index 0000000..a98722f Binary files /dev/null and b/img/export/btnShare.png differ diff --git a/img/export/btnSketchFab.png b/img/export/btnSketchFab.png new file mode 100644 index 0000000..5d5675a Binary files /dev/null and b/img/export/btnSketchFab.png differ diff --git a/img/export/btnThingiverse.png b/img/export/btnThingiverse.png new file mode 100644 index 0000000..58abec6 Binary files /dev/null and b/img/export/btnThingiverse.png differ diff --git a/img/export/btnTwitter.png b/img/export/btnTwitter.png new file mode 100644 index 0000000..5632ed9 Binary files /dev/null and b/img/export/btnTwitter.png differ diff --git a/img/export/btnYouMagine.png b/img/export/btnYouMagine.png new file mode 100644 index 0000000..128e584 Binary files /dev/null and b/img/export/btnYouMagine.png differ diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 0000000..6a13769 Binary files /dev/null and b/img/logo.png differ diff --git a/img/mainmenu/btnRedo.png b/img/mainmenu/btnRedo.png new file mode 100644 index 0000000..7921f58 Binary files /dev/null and b/img/mainmenu/btnRedo.png differ diff --git a/img/mainmenu/btnTopExport.png b/img/mainmenu/btnTopExport.png new file mode 100644 index 0000000..3c29c65 Binary files /dev/null and b/img/mainmenu/btnTopExport.png differ diff --git a/img/mainmenu/btnTopNew.png b/img/mainmenu/btnTopNew.png new file mode 100644 index 0000000..b386121 Binary files /dev/null and b/img/mainmenu/btnTopNew.png differ diff --git a/img/mainmenu/btnTopOpen.png b/img/mainmenu/btnTopOpen.png new file mode 100644 index 0000000..a09fbec Binary files /dev/null and b/img/mainmenu/btnTopOpen.png differ diff --git a/img/mainmenu/btnTopSave.png b/img/mainmenu/btnTopSave.png new file mode 100644 index 0000000..e9a9864 Binary files /dev/null and b/img/mainmenu/btnTopSave.png differ diff --git a/img/mainmenu/btnTopSettings.png b/img/mainmenu/btnTopSettings.png new file mode 100644 index 0000000..82b8015 Binary files /dev/null and b/img/mainmenu/btnTopSettings.png differ diff --git a/img/mainmenu/btnTopUndo.png b/img/mainmenu/btnTopUndo.png new file mode 100644 index 0000000..83d3c10 Binary files /dev/null and b/img/mainmenu/btnTopUndo.png differ diff --git a/img/mainmenu/btnUndo.png b/img/mainmenu/btnUndo.png new file mode 100644 index 0000000..025a5aa Binary files /dev/null and b/img/mainmenu/btnUndo.png differ diff --git a/img/menu/chat.png b/img/menu/chat.png new file mode 100644 index 0000000..593861e Binary files /dev/null and b/img/menu/chat.png differ diff --git a/img/menu/draw_a_doodle.png b/img/menu/draw_a_doodle.png new file mode 100644 index 0000000..d9b4f5d Binary files /dev/null and b/img/menu/draw_a_doodle.png differ diff --git a/img/menu/export.png b/img/menu/export.png new file mode 100644 index 0000000..dac05eb Binary files /dev/null and b/img/menu/export.png differ diff --git a/img/menu/feedback.png b/img/menu/feedback.png new file mode 100644 index 0000000..f3fa1f9 Binary files /dev/null and b/img/menu/feedback.png differ diff --git a/img/menu/help.png b/img/menu/help.png new file mode 100644 index 0000000..aa79433 Binary files /dev/null and b/img/menu/help.png differ diff --git a/img/menu/home.png b/img/menu/home.png new file mode 100644 index 0000000..19d9260 Binary files /dev/null and b/img/menu/home.png differ diff --git a/img/menu/import.png b/img/menu/import.png new file mode 100644 index 0000000..c923962 Binary files /dev/null and b/img/menu/import.png differ diff --git a/img/menu/new.png b/img/menu/new.png new file mode 100644 index 0000000..227236f Binary files /dev/null and b/img/menu/new.png differ diff --git a/img/menu/open.png b/img/menu/open.png new file mode 100644 index 0000000..3836859 Binary files /dev/null and b/img/menu/open.png differ diff --git a/img/menu/save.png b/img/menu/save.png new file mode 100644 index 0000000..ea3b257 Binary files /dev/null and b/img/menu/save.png differ diff --git a/img/menu/settings.png b/img/menu/settings.png new file mode 100644 index 0000000..ebe0d68 Binary files /dev/null and b/img/menu/settings.png differ diff --git a/img/menu/terms.png b/img/menu/terms.png new file mode 100644 index 0000000..250af78 Binary files /dev/null and b/img/menu/terms.png differ diff --git a/img/oauth/logo-google.png b/img/oauth/logo-google.png new file mode 100644 index 0000000..57cbf0e Binary files /dev/null and b/img/oauth/logo-google.png differ diff --git a/img/payment/corner_free_plan.png b/img/payment/corner_free_plan.png new file mode 100644 index 0000000..9ab9881 Binary files /dev/null and b/img/payment/corner_free_plan.png differ diff --git a/img/payment/corner_full_plan.png b/img/payment/corner_full_plan.png new file mode 100644 index 0000000..d20df1a Binary files /dev/null and b/img/payment/corner_full_plan.png differ diff --git a/img/placeholder.png b/img/placeholder.png new file mode 100644 index 0000000..5e0bd2b Binary files /dev/null and b/img/placeholder.png differ diff --git a/img/platform.png b/img/platform.png new file mode 100644 index 0000000..b6e8079 Binary files /dev/null and b/img/platform.png differ diff --git a/img/toolbar2d/btnBrush.png b/img/toolbar2d/btnBrush.png new file mode 100644 index 0000000..7dc2d98 Binary files /dev/null and b/img/toolbar2d/btnBrush.png differ diff --git a/img/toolbar2d/btnBrushSelect.png b/img/toolbar2d/btnBrushSelect.png new file mode 100644 index 0000000..c1061b4 Binary files /dev/null and b/img/toolbar2d/btnBrushSelect.png differ diff --git a/img/toolbar2d/btnBucket.png b/img/toolbar2d/btnBucket.png new file mode 100644 index 0000000..af7ab91 Binary files /dev/null and b/img/toolbar2d/btnBucket.png differ diff --git a/img/toolbar2d/btnBucketSelect.png b/img/toolbar2d/btnBucketSelect.png new file mode 100644 index 0000000..442dabd Binary files /dev/null and b/img/toolbar2d/btnBucketSelect.png differ diff --git a/img/toolbar2d/btnDraw.png b/img/toolbar2d/btnDraw.png new file mode 100644 index 0000000..e63b7f5 Binary files /dev/null and b/img/toolbar2d/btnDraw.png differ diff --git a/img/toolbar2d/btnDrawSelect.png b/img/toolbar2d/btnDrawSelect.png new file mode 100644 index 0000000..8d9a764 Binary files /dev/null and b/img/toolbar2d/btnDrawSelect.png differ diff --git a/img/toolbar2d/btnEraser.png b/img/toolbar2d/btnEraser.png new file mode 100644 index 0000000..86f25e7 Binary files /dev/null and b/img/toolbar2d/btnEraser.png differ diff --git a/img/toolbar2d/btnEraserSelect.png b/img/toolbar2d/btnEraserSelect.png new file mode 100644 index 0000000..8b14af5 Binary files /dev/null and b/img/toolbar2d/btnEraserSelect.png differ diff --git a/img/toolbar2d/btnPhoto.png b/img/toolbar2d/btnPhoto.png new file mode 100644 index 0000000..0092368 Binary files /dev/null and b/img/toolbar2d/btnPhoto.png differ diff --git a/img/toolbar2d/btnPhotoSelect.png b/img/toolbar2d/btnPhotoSelect.png new file mode 100644 index 0000000..85a5235 Binary files /dev/null and b/img/toolbar2d/btnPhotoSelect.png differ diff --git a/img/toolbar2d/btnPolygon.png b/img/toolbar2d/btnPolygon.png new file mode 100644 index 0000000..95179cf Binary files /dev/null and b/img/toolbar2d/btnPolygon.png differ diff --git a/img/toolbar2d/btnPolygonSelect.png b/img/toolbar2d/btnPolygonSelect.png new file mode 100644 index 0000000..fc5a561 Binary files /dev/null and b/img/toolbar2d/btnPolygonSelect.png differ diff --git a/img/toolbar2d/btnSelect.png b/img/toolbar2d/btnSelect.png new file mode 100644 index 0000000..07ddfac Binary files /dev/null and b/img/toolbar2d/btnSelect.png differ diff --git a/img/toolbar2d/btnSelectSelect.png b/img/toolbar2d/btnSelectSelect.png new file mode 100644 index 0000000..31b9da6 Binary files /dev/null and b/img/toolbar2d/btnSelectSelect.png differ diff --git a/img/toolbar2d/btnShapeMenuMini.png b/img/toolbar2d/btnShapeMenuMini.png new file mode 100644 index 0000000..494409e Binary files /dev/null and b/img/toolbar2d/btnShapeMenuMini.png differ diff --git a/img/toolbar2d/btnText.png b/img/toolbar2d/btnText.png new file mode 100644 index 0000000..a996038 Binary files /dev/null and b/img/toolbar2d/btnText.png differ diff --git a/img/toolbar2d/btnTextSelect.png b/img/toolbar2d/btnTextSelect.png new file mode 100644 index 0000000..db6733d Binary files /dev/null and b/img/toolbar2d/btnTextSelect.png differ diff --git a/img/toolbar2d/shapeMenuBackground.png b/img/toolbar2d/shapeMenuBackground.png new file mode 100644 index 0000000..32528ec Binary files /dev/null and b/img/toolbar2d/shapeMenuBackground.png differ diff --git a/img/toolbar2d/shapes/btnShapeCircle.png b/img/toolbar2d/shapes/btnShapeCircle.png new file mode 100644 index 0000000..5f97ee2 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeCircle.png differ diff --git a/img/toolbar2d/shapes/btnShapeCircleSegment.png b/img/toolbar2d/shapes/btnShapeCircleSegment.png new file mode 100644 index 0000000..3aec1b6 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeCircleSegment.png differ diff --git a/img/toolbar2d/shapes/btnShapeCircleSegmentSelect.png b/img/toolbar2d/shapes/btnShapeCircleSegmentSelect.png new file mode 100644 index 0000000..9385b44 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeCircleSegmentSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeCircleSelect.png b/img/toolbar2d/shapes/btnShapeCircleSelect.png new file mode 100644 index 0000000..b43a9c3 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeCircleSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeHeart.png b/img/toolbar2d/shapes/btnShapeHeart.png new file mode 100644 index 0000000..58dacf8 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeHeart.png differ diff --git a/img/toolbar2d/shapes/btnShapeHeartSelect.png b/img/toolbar2d/shapes/btnShapeHeartSelect.png new file mode 100644 index 0000000..742922b Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeHeartSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeHex.png b/img/toolbar2d/shapes/btnShapeHex.png new file mode 100644 index 0000000..df76810 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeHex.png differ diff --git a/img/toolbar2d/shapes/btnShapeHexSelect.png b/img/toolbar2d/shapes/btnShapeHexSelect.png new file mode 100644 index 0000000..80a5948 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeHexSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeLine.png b/img/toolbar2d/shapes/btnShapeLine.png new file mode 100644 index 0000000..5b286ad Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeLine.png differ diff --git a/img/toolbar2d/shapes/btnShapeLineSelect.png b/img/toolbar2d/shapes/btnShapeLineSelect.png new file mode 100644 index 0000000..80c7989 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeLineSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeRect.png b/img/toolbar2d/shapes/btnShapeRect.png new file mode 100644 index 0000000..ccc017e Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeRect.png differ diff --git a/img/toolbar2d/shapes/btnShapeRectSelect.png b/img/toolbar2d/shapes/btnShapeRectSelect.png new file mode 100644 index 0000000..5c8dba0 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeRectSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeRightTriangle.png b/img/toolbar2d/shapes/btnShapeRightTriangle.png new file mode 100644 index 0000000..28d859d Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeRightTriangle.png differ diff --git a/img/toolbar2d/shapes/btnShapeRightTriangleSelect.png b/img/toolbar2d/shapes/btnShapeRightTriangleSelect.png new file mode 100644 index 0000000..29b36a1 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeRightTriangleSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeRoundRect.png b/img/toolbar2d/shapes/btnShapeRoundRect.png new file mode 100644 index 0000000..2decdf4 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeRoundRect.png differ diff --git a/img/toolbar2d/shapes/btnShapeRoundRectSelect.png b/img/toolbar2d/shapes/btnShapeRoundRectSelect.png new file mode 100644 index 0000000..485086d Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeRoundRectSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeSkewedRect.png b/img/toolbar2d/shapes/btnShapeSkewedRect.png new file mode 100644 index 0000000..e60ee97 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeSkewedRect.png differ diff --git a/img/toolbar2d/shapes/btnShapeSkewedRectSelect.png b/img/toolbar2d/shapes/btnShapeSkewedRectSelect.png new file mode 100644 index 0000000..cd0a429 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeSkewedRectSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeStar.png b/img/toolbar2d/shapes/btnShapeStar.png new file mode 100644 index 0000000..bedb42d Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeStar.png differ diff --git a/img/toolbar2d/shapes/btnShapeStarSelect.png b/img/toolbar2d/shapes/btnShapeStarSelect.png new file mode 100644 index 0000000..df1ee88 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeStarSelect.png differ diff --git a/img/toolbar2d/shapes/btnShapeTriangle.png b/img/toolbar2d/shapes/btnShapeTriangle.png new file mode 100644 index 0000000..8e462b5 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeTriangle.png differ diff --git a/img/toolbar2d/shapes/btnShapeTriangleSelect.png b/img/toolbar2d/shapes/btnShapeTriangleSelect.png new file mode 100644 index 0000000..c2a2559 Binary files /dev/null and b/img/toolbar2d/shapes/btnShapeTriangleSelect.png differ diff --git a/img/toolbar2d/toolbar2d.png b/img/toolbar2d/toolbar2d.png new file mode 100644 index 0000000..cd97627 Binary files /dev/null and b/img/toolbar2d/toolbar2d.png differ diff --git a/img/toolbar3d/btnCut.png b/img/toolbar3d/btnCut.png new file mode 100644 index 0000000..23c816f Binary files /dev/null and b/img/toolbar3d/btnCut.png differ diff --git a/img/toolbar3d/btnCutSelect.png b/img/toolbar3d/btnCutSelect.png new file mode 100644 index 0000000..cd2889e Binary files /dev/null and b/img/toolbar3d/btnCutSelect.png differ diff --git a/img/toolbar3d/btnExtrude.png b/img/toolbar3d/btnExtrude.png new file mode 100644 index 0000000..b742848 Binary files /dev/null and b/img/toolbar3d/btnExtrude.png differ diff --git a/img/toolbar3d/btnExtrudeSelect.png b/img/toolbar3d/btnExtrudeSelect.png new file mode 100644 index 0000000..11ffc67 Binary files /dev/null and b/img/toolbar3d/btnExtrudeSelect.png differ diff --git a/img/toolbar3d/btnSculpt.png b/img/toolbar3d/btnSculpt.png new file mode 100644 index 0000000..8bdbe9a Binary files /dev/null and b/img/toolbar3d/btnSculpt.png differ diff --git a/img/toolbar3d/btnSculptSelect.png b/img/toolbar3d/btnSculptSelect.png new file mode 100644 index 0000000..1aa67db Binary files /dev/null and b/img/toolbar3d/btnSculptSelect.png differ diff --git a/img/toolbar3d/btnStamp.png b/img/toolbar3d/btnStamp.png new file mode 100644 index 0000000..5c7d201 Binary files /dev/null and b/img/toolbar3d/btnStamp.png differ diff --git a/img/toolbar3d/btnStampSelect.png b/img/toolbar3d/btnStampSelect.png new file mode 100644 index 0000000..e4d3406 Binary files /dev/null and b/img/toolbar3d/btnStampSelect.png differ diff --git a/img/toolbar3d/btnTwist.png b/img/toolbar3d/btnTwist.png new file mode 100644 index 0000000..b72cfd4 Binary files /dev/null and b/img/toolbar3d/btnTwist.png differ diff --git a/img/toolbar3d/btnTwistSelect.png b/img/toolbar3d/btnTwistSelect.png new file mode 100644 index 0000000..adcb2dc Binary files /dev/null and b/img/toolbar3d/btnTwistSelect.png differ diff --git a/img/toolbar3d/toolbar3d.png b/img/toolbar3d/toolbar3d.png new file mode 100644 index 0000000..17b58fa Binary files /dev/null and b/img/toolbar3d/toolbar3d.png differ diff --git a/img/trace.jpg b/img/trace.jpg new file mode 100644 index 0000000..36a7362 Binary files /dev/null and b/img/trace.jpg differ diff --git a/img/vline.png b/img/vline.png new file mode 100644 index 0000000..f16b72e Binary files /dev/null and b/img/vline.png differ diff --git a/index.js b/index.js new file mode 100644 index 0000000..3f1ae3a --- /dev/null +++ b/index.js @@ -0,0 +1,40 @@ +// import polyfill +import 'babel-polyfill'; + +// inject tap event plugin +import injectTapEventPlugin from 'react-tap-event-plugin'; +injectTapEventPlugin(); + +// create store +import { createStore, combineReducers, compose, applyMiddleware } from 'redux'; +import thunkMiddleware from 'redux-thunk'; +import promiseMiddleware from 'redux-promise-middleware'; +import { createLogger } from 'redux-logger'; +const reducer = combineReducers({ sketcher: sketcherReducer }); +const enhancer = compose(applyMiddleware(thunkMiddleware, promiseMiddleware(), createLogger({ collapsed: true }))); +const store = createStore(reducer, enhancer); + +// prepare html (SHOULDN'T BE DONE LIKE THIS) +document.body.style.margin = 0; +document.body.style.padding = 0; +document.body.style.height = '100%'; +document.documentElement.style.height = '100%'; +document.documentElement.style.overflow = 'hidden'; +document.getElementById('app').style.height = '100%'; + +// render dom +import React from 'react'; +import { Provider } from 'react-redux'; +import { render } from 'react-dom'; +import App from './src/components/App.js'; +import InlineIconsLoader from './src/components/InlineIconsLoader.js'; +import sketcherReducer from './src/reducer/index.js'; + +render(( + + + + + + +), document.getElementById('app')); diff --git a/package-lock.json b/package-lock.json index 72dbc2c..4f9ea0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,14 @@ "resolved": "https://registry.npmjs.org/@doodle3d/clipper-lib/-/clipper-lib-6.4.2-b.tgz", "integrity": "sha512-glELSijsD9b+/0d9iOdasBwqH3s+xPxD59tJ7aXkBx7klugygGOMXn7PB05AdhVyA1OYMj7GUCegaQa7nvLtmQ==" }, + "@doodle3d/fill-path": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@doodle3d/fill-path/-/fill-path-1.0.7.tgz", + "integrity": "sha512-4sdgWQ28JgRsmnyy1OnuKHE+DZ8kDGpluGqFmMASh2/6dlyjp2/oXnNEgNefG4/xiEitV8AtzEij9Bijh6yNRw==", + "requires": { + "@doodle3d/clipper-js": "1.0.7" + } + }, "@doodle3d/potrace-js": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@doodle3d/potrace-js/-/potrace-js-0.0.6.tgz", @@ -60,6 +68,15 @@ } } }, + "@doodle3d/touch-events": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@doodle3d/touch-events/-/touch-events-0.0.7.tgz", + "integrity": "sha512-EpL8IEGKKy2gqFFlxA4n84IeAyPTrEzle0jwmRv+mmVBzwGr6xDl5Ga5vJIrg2WcYs4Xc7qWbiKSHEXvEpDLlg==", + "requires": { + "eventdispatcher.js": "0.0.2", + "pepjs": "0.4.3" + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -73,6 +90,39 @@ "xtend": "4.0.1" } }, + "accepts": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", + "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "dev": true, + "requires": { + "mime-types": "2.1.17", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", @@ -87,11 +137,34 @@ "json-stable-stringify": "1.0.1" } }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, "ansi": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -107,7 +180,6 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, - "optional": true, "requires": { "micromatch": "2.3.11", "normalize-path": "2.1.1" @@ -122,6 +194,15 @@ "readable-stream": "2.3.3" } }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, "argsarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", @@ -132,7 +213,6 @@ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, - "optional": true, "requires": { "arr-flatten": "1.1.0" } @@ -141,8 +221,29 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", + "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", + "dev": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", "dev": true, - "optional": true + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.9.0" + } }, "array-index": { "version": "1.0.0", @@ -153,12 +254,26 @@ "es6-symbol": "3.1.1" } }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true, - "optional": true + "dev": true }, "asap": { "version": "2.0.6", @@ -170,6 +285,26 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" }, + "asn1.js": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, "assert-plus": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", @@ -184,8 +319,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true, - "optional": true + "dev": true }, "asynckit": { "version": "0.4.0", @@ -287,6 +421,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true, "requires": { "babel-runtime": "6.26.0", "babel-traverse": "6.26.0", @@ -350,6 +485,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true, "requires": { "babel-helper-bindify-decorators": "6.24.1", "babel-runtime": "6.26.0", @@ -478,6 +614,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/babel-plugin-inline-import/-/babel-plugin-inline-import-2.0.6.tgz", "integrity": "sha1-ijwXlWG1A79K8xnzytQ15reyhjw=", + "dev": true, "requires": { "require-resolve": "0.0.2" } @@ -486,6 +623,7 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/babel-plugin-ramda/-/babel-plugin-ramda-1.4.3.tgz", "integrity": "sha1-JltUqS8p9e1WGAuVxJnRriqKJac=", + "dev": true, "requires": { "ramda": "0.21.0" } @@ -498,32 +636,38 @@ "babel-plugin-syntax-async-generators": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", - "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=" + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true }, "babel-plugin-syntax-class-constructor-call": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", - "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=" + "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=", + "dev": true }, "babel-plugin-syntax-class-properties": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=" + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true }, "babel-plugin-syntax-decorators": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", - "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=" + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true }, "babel-plugin-syntax-do-expressions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", - "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=" + "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=", + "dev": true }, "babel-plugin-syntax-dynamic-import": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", - "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=" + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true }, "babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", @@ -533,7 +677,8 @@ "babel-plugin-syntax-export-extensions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", - "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=" + "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", + "dev": true }, "babel-plugin-syntax-flow": { "version": "6.18.0", @@ -544,7 +689,8 @@ "babel-plugin-syntax-function-bind": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", - "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=" + "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=", + "dev": true }, "babel-plugin-syntax-jsx": { "version": "6.18.0", @@ -555,7 +701,8 @@ "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true }, "babel-plugin-syntax-trailing-function-commas": { "version": "6.22.0", @@ -566,6 +713,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true, "requires": { "babel-helper-remap-async-to-generator": "6.24.1", "babel-plugin-syntax-async-generators": "6.13.0", @@ -586,6 +734,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=", + "dev": true, "requires": { "babel-plugin-syntax-class-constructor-call": "6.18.0", "babel-runtime": "6.26.0", @@ -596,6 +745,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, "requires": { "babel-helper-function-name": "6.24.1", "babel-plugin-syntax-class-properties": "6.13.0", @@ -607,6 +757,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true, "requires": { "babel-helper-explode-class": "6.24.1", "babel-plugin-syntax-decorators": "6.13.0", @@ -619,6 +770,7 @@ "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=", + "dev": true, "requires": { "babel-plugin-syntax-do-expressions": "6.13.0", "babel-runtime": "6.26.0" @@ -850,6 +1002,7 @@ "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", + "dev": true, "requires": { "babel-plugin-syntax-export-extensions": "6.13.0", "babel-runtime": "6.26.0" @@ -869,6 +1022,7 @@ "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=", + "dev": true, "requires": { "babel-plugin-syntax-function-bind": "6.13.0", "babel-runtime": "6.26.0" @@ -878,6 +1032,7 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, "requires": { "babel-plugin-syntax-object-rest-spread": "6.13.0", "babel-runtime": "6.26.0" @@ -931,6 +1086,15 @@ "regenerator-transform": "0.10.1" } }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, "babel-plugin-transform-strict-mode": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", @@ -944,7 +1108,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "dev": true, "requires": { "babel-runtime": "6.26.0", "core-js": "2.5.1", @@ -954,8 +1117,7 @@ "regenerator-runtime": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" } } }, @@ -991,7 +1153,7 @@ "babel-plugin-transform-es2015-unicode-regex": "6.24.1", "babel-plugin-transform-exponentiation-operator": "6.24.1", "babel-plugin-transform-regenerator": "6.26.0", - "browserslist": "2.5.1", + "browserslist": "2.9.0", "invariant": "2.2.2", "semver": "5.4.1" } @@ -1055,6 +1217,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=", + "dev": true, "requires": { "babel-plugin-transform-do-expressions": "6.22.0", "babel-plugin-transform-function-bind": "6.22.0", @@ -1065,6 +1228,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", + "dev": true, "requires": { "babel-plugin-transform-class-constructor-call": "6.24.1", "babel-plugin-transform-export-extensions": "6.22.0", @@ -1075,6 +1239,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, "requires": { "babel-plugin-syntax-dynamic-import": "6.18.0", "babel-plugin-transform-class-properties": "6.24.1", @@ -1086,6 +1251,7 @@ "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, "requires": { "babel-plugin-syntax-trailing-function-commas": "6.22.0", "babel-plugin-transform-async-generator-functions": "6.24.1", @@ -1196,6 +1362,18 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", @@ -1219,8 +1397,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", - "dev": true, - "optional": true + "dev": true }, "bindings": { "version": "1.2.1", @@ -1263,6 +1440,64 @@ "inherits": "2.0.3" } }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.1", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.15" + }, + "dependencies": { + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "2.1.1", + "deep-equal": "1.0.1", + "dns-equal": "1.0.0", + "dns-txt": "2.0.2", + "multicast-dns": "6.1.1", + "multicast-dns-service-types": "1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, "boom": { "version": "2.10.1", "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", @@ -1271,6 +1506,11 @@ "hoek": "2.16.3" } }, + "bowser": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.8.1.tgz", + "integrity": "sha512-NMPaR8ILtdLSWzxQtEs16XbxMcY8ohWGQ5V+TZSJS3fNUt/PBAGkF6YWO9B/4qWE23bK3o0moQKq8UyFEosYkA==" + }, "brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", @@ -1285,7 +1525,6 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, - "optional": true, "requires": { "expand-range": "1.8.2", "preserve": "0.2.0", @@ -1297,15 +1536,110 @@ "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.1.tgz", "integrity": "sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg==" }, - "browserslist": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.1.tgz", - "integrity": "sha512-jAvM2ku7YDJ+leAq3bFH1DE0Ylw+F+EQDq4GkqZfgPEqpWYw9ofQH85uKSB9r3Tv7XDbfqVtE+sdvKJW7IlPJA==", + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "dev": true, "requires": { - "caniuse-lite": "1.0.30000749", + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "requires": { + "browserify-aes": "1.1.1", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.5" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "0.2.9" + }, + "dependencies": { + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + } + } + }, + "browserslist": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.9.0.tgz", + "integrity": "sha512-vJEBcDTANoDhSHL46NeOEW5hvQw7It9uCqzeFPQhpawXfnOwnpvW5C97vn1eGJ7iCkSg8wWU0nYObE7d/N95Iw==", + "requires": { + "caniuse-lite": "1.0.30000764", "electron-to-chromium": "1.3.27" } }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "1.2.1", + "ieee754": "1.1.8", + "isarray": "1.0.0" + } + }, "buffer-from": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.1.tgz", @@ -1314,21 +1648,95 @@ "is-array-buffer-x": "1.7.0" } }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, "cached-constructors-x": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cached-constructors-x/-/cached-constructors-x-1.0.0.tgz", "integrity": "sha512-JVP0oilYlPgBTD8bkQ+of7hSIJRtydCCJiMtzdRMXVQ98gdj0NyrJTZzbu5wtlO26Ev/1HXRTtbBNsVlLJ3+3A==" }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "2.3.2", + "upper-case": "1.1.3" + } + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, "caniuse-lite": { - "version": "1.0.30000749", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000749.tgz", - "integrity": "sha1-L/OChlrq2MyjXaz7qwT1jv+kwBw=" + "version": "1.0.30000764", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000764.tgz", + "integrity": "sha1-l+p0cvnT5pHu3jTyGYPPwhmseEI=" }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -1346,7 +1754,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, - "optional": true, "requires": { "anymatch": "1.3.2", "async-each": "1.0.1", @@ -1364,6 +1771,42 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "classnames": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", + "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=", + "dev": true + }, + "clean-css": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz", + "integrity": "sha1-Nc7ornaHpJuYA09w3gDE7dOCYwE=", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, "clone-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", @@ -1374,6 +1817,12 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, "combined-stream": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", @@ -1394,17 +1843,86 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "compressible": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz", + "integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=", + "dev": true, + "requires": { + "mime-db": "1.30.0" + } + }, + "compression": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz", + "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=", + "dev": true, + "requires": { + "accepts": "1.3.4", + "bytes": "3.0.0", + "compressible": "2.0.12", + "debug": "2.6.9", + "on-headers": "1.0.1", + "safe-buffer": "5.1.1", + "vary": "1.1.2" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, "convert-source-map": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", "dev": true }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, "core-js": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", @@ -1415,6 +1933,42 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.9" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, "create-react-class": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz", @@ -1425,6 +1979,17 @@ "object-assign": "4.1.1" } }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, "cryptiles": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", @@ -1433,6 +1998,37 @@ "boom": "2.10.1" } }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.5", + "randomfill": "1.0.3" + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "1.0.0", + "css-what": "2.1.0", + "domutils": "1.5.1", + "nth-check": "1.0.1" + } + }, "css-vendor": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", @@ -1441,6 +2037,21 @@ "is-in-browser": "1.1.3" } }, + "css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, "d": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", @@ -1464,6 +2075,12 @@ } } }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1472,6 +2089,18 @@ "ms": "2.0.0" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-diff": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", + "integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=", + "dev": true + }, "deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", @@ -1490,6 +2119,38 @@ "abstract-leveldown": "2.6.3" } }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "6.1.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "p-map": "1.2.0", + "pify": "3.0.0", + "rimraf": "2.6.2" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1500,6 +2161,28 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -1509,6 +2192,114 @@ "repeating": "2.0.1" } }, + "detect-node": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz", + "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.5" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.2.2.tgz", + "integrity": "sha512-kN+DjfGF7dJGUL7nWRktL9Z18t1rWP3aQlyZdY8XlpvU3Nc6GeFTQApftcjtWKxAZfiggZSGrCEoszNgvnpwDg==", + "dev": true, + "requires": { + "ip": "1.1.5", + "safe-buffer": "5.1.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "1.1.1" + } + }, + "dom-converter": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", + "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", + "dev": true, + "requires": { + "utila": "0.3.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", + "dev": true + } + } + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", + "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" + } + }, "double-ended-queue": { "version": "2.1.0-0", "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", @@ -1554,16 +2345,43 @@ "jsbn": "0.1.1" } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, "electron-to-chromium": { "version": "1.3.27", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz", "integrity": "sha1-eOy4o5kGYYe7N07t412ccFZagD0=" }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", + "dev": true + }, "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", @@ -1588,6 +2406,24 @@ "write-stream": "0.4.3" } }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.8" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + }, "errno": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", @@ -1603,6 +2439,39 @@ } } }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz", + "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", + "dev": true, + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, "es5-ext": { "version": "0.10.35", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.35.tgz", @@ -1637,11 +2506,60 @@ } } }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.35" + } + } + } + }, "es6-promise": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=" }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.35" + } + } + } + }, "es6-symbol": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", @@ -1693,16 +2611,85 @@ } } }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.35" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + } + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", @@ -1722,6 +2709,57 @@ } } }, + "eventdispatcher.js": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/eventdispatcher.js/-/eventdispatcher.js-0.0.2.tgz", + "integrity": "sha1-wntZzkEEa2iUEu3M/UzYr8ZM2DU=" + }, + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "eventsource": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", + "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", + "dev": true, + "requires": { + "original": "1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, "execspawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/execspawn/-/execspawn-1.0.1.tgz", @@ -1735,7 +2773,6 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, - "optional": true, "requires": { "is-posix-bracket": "0.1.1" } @@ -1745,7 +2782,6 @@ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, - "optional": true, "requires": { "fill-range": "2.2.3" } @@ -1755,6 +2791,58 @@ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.0.tgz", "integrity": "sha512-kkjwkMqj0h4w/sb32ERCDxCQkREMCAgS39DscDnSwDsbxnwwM1BTZySdC3Bn1lhY7vL08n9GoO/fVTynjDgRyQ==" }, + "express": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "dev": true, + "requires": { + "accepts": "1.3.4", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.1", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.0", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.2", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", + "statuses": "1.3.1", + "type-is": "1.6.15", + "utils-merge": "1.0.1", + "vary": "1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + } + } + }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", @@ -1765,7 +2853,6 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, - "optional": true, "requires": { "is-extglob": "1.0.0" } @@ -1775,11 +2862,32 @@ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, "fast-future": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=" }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": "0.7.0" + } + }, "fbjs": { "version": "0.8.16", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", @@ -1801,19 +2909,27 @@ } } }, + "file-loader": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.5.tgz", + "integrity": "sha512-RzGHDatcVNpGISTvCpfUfOGpYuSR7HSsSg87ki+wF6rw1Hm0RALPTiAdsxAq1UwLf0RRhbe22/eHK6nhXspiOQ==", + "dev": true, + "requires": { + "loader-utils": "1.1.0", + "schema-utils": "0.3.0" + } + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true, - "optional": true + "dev": true }, "fill-range": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, - "optional": true, "requires": { "is-number": "2.1.0", "isobject": "2.1.0", @@ -1822,6 +2938,21 @@ "repeat-string": "1.6.1" } }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + } + }, "find-cache-dir": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", @@ -1852,19 +2983,23 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "optional": true + "dev": true }, "for-own": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, - "optional": true, "requires": { "for-in": "1.0.2" } }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1880,6 +3015,18 @@ "mime-types": "2.1.17" } }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, "fs-readdir-recursive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz", @@ -2914,6 +4061,12 @@ "rimraf": "2.6.2" } }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "gauge": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", @@ -2926,6 +4079,24 @@ "lodash.padstart": "4.6.1" } }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -2994,7 +4165,6 @@ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, - "optional": true, "requires": { "glob-parent": "2.0.0", "is-glob": "2.0.1" @@ -3014,11 +4184,30 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, + "handle-thing": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", + "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", + "dev": true + }, "har-schema": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", @@ -3033,6 +4222,15 @@ "har-schema": "1.0.5" } }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -3041,6 +4239,12 @@ "ansi-regex": "2.1.1" } }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, "has-own-property-x": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/has-own-property-x/-/has-own-property-x-3.2.0.tgz", @@ -3069,6 +4273,25 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, "hawk": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", @@ -3080,6 +4303,23 @@ "sntp": "1.0.9" } }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, "hoek": { "version": "2.16.3", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", @@ -3100,6 +4340,216 @@ "os-tmpdir": "1.0.2" } }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "obuf": "1.1.1", + "readable-stream": "2.3.3", + "wbuf": "1.7.2" + } + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true + }, + "html-minifier": { + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.6.tgz", + "integrity": "sha512-88FjtKrlak2XjczhxrBomgzV4jmGzM3UnHRBScRkJcmcRum0kb+IwhVAETJ8AVp7j0p3xugjSaw9L+RmI5/QOA==", + "dev": true, + "requires": { + "camel-case": "3.0.0", + "clean-css": "4.1.9", + "commander": "2.11.0", + "he": "1.1.1", + "ncname": "1.0.0", + "param-case": "2.1.1", + "relateurl": "0.2.7", + "uglify-js": "3.1.9" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "uglify-js": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.9.tgz", + "integrity": "sha512-ari2E89bD7f+fMU173NgF12JBcOhgoxeyuCs97h5K58IBENrnG9eVj2lFadrOPdqf0KifsxVmUQfzA2cHNxCZQ==", + "dev": true, + "requires": { + "commander": "2.11.0", + "source-map": "0.6.1" + } + } + } + }, + "html-webpack-plugin": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz", + "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "html-minifier": "3.5.6", + "loader-utils": "0.2.17", + "lodash": "4.17.4", + "pretty-error": "2.1.1", + "toposort": "1.0.6" + }, + "dependencies": { + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1", + "object-assign": "4.1.1" + } + } + } + }, + "html-webpack-template": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/html-webpack-template/-/html-webpack-template-6.0.2.tgz", + "integrity": "sha512-ekYCkU5t41wOu4kgGWvojVrREHap1qvZ8cbuy8ogH7EmscY4B0ElOEGQFFKpvig4GhhlVCK4mWaIik3dgz92SQ==", + "dev": true + }, + "htmlparser2": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", + "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.1.0", + "domutils": "1.1.6", + "readable-stream": "1.0.34" + }, + "dependencies": { + "domutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", + "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", + "dev": true, + "requires": { + "domelementtype": "1.3.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.3.1" + }, + "dependencies": { + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } + } + }, + "http-parser-js": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", + "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=", + "dev": true + }, + "http-proxy": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", + "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "dev": true, + "requires": { + "eventemitter3": "1.2.0", + "requires-port": "1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", + "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", + "dev": true, + "requires": { + "http-proxy": "1.16.2", + "is-glob": "3.1.0", + "lodash": "4.17.4", + "micromatch": "2.3.11" + }, + "dependencies": { + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, "http-signature": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", @@ -3110,6 +4560,12 @@ "sshpk": "1.13.1" } }, + "https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "dev": true + }, "hyperquest": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-1.2.0.tgz", @@ -3156,11 +4612,47 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, "immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, + "import-local": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-0.1.1.tgz", + "integrity": "sha1-sReVcqrNwRxqkQCftDDbyrX2aKg=", + "dev": true, + "requires": { + "pkg-dir": "2.0.0", + "resolve-cwd": "2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "2.1.0" + } + } + } + }, "imports-loader": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.7.1.tgz", @@ -3170,6 +4662,21 @@ "source-map": "0.5.7" } }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, "infinity-x": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/infinity-x/-/infinity-x-1.0.0.tgz", @@ -3194,6 +4701,21 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" }, + "internal-ip": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", + "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=", + "dev": true, + "requires": { + "meow": "3.7.0" + } + }, + "interpret": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", + "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", + "dev": true + }, "invariant": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", @@ -3202,6 +4724,24 @@ "loose-envify": "1.3.1" } }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ipaddr.js": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=", + "dev": true + }, "is-array-buffer-x": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/is-array-buffer-x/-/is-array-buffer-x-1.7.0.tgz", @@ -3214,12 +4754,17 @@ "to-string-tag-x": "1.4.2" } }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, - "optional": true, "requires": { "binary-extensions": "1.10.0" } @@ -3230,6 +4775,21 @@ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", "dev": true }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", @@ -3239,15 +4799,13 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true, - "optional": true + "dev": true }, "is-equal-shallow": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, - "optional": true, "requires": { "is-primitive": "2.0.0" } @@ -3256,8 +4814,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "optional": true + "dev": true }, "is-extglob": { "version": "1.0.0", @@ -3291,6 +4848,15 @@ "is-nan-x": "1.0.1" } }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, "is-function": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", @@ -3356,7 +4922,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, - "optional": true, "requires": { "kind-of": "3.2.2" } @@ -3370,19 +4935,28 @@ "is-primitive": "2.0.0" } }, - "is-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", - "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, "requires": { - "symbol-observable": "0.2.4" - }, - "dependencies": { - "symbol-observable": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", - "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=" - } + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" } }, "is-plain-object": { @@ -3404,8 +4978,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true, - "optional": true + "dev": true }, "is-primitive": { "version": "2.0.0", @@ -3417,6 +4990,15 @@ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "1.0.1" + } + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -3437,6 +5019,18 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -3452,7 +5046,6 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, - "optional": true, "requires": { "isarray": "1.0.0" } @@ -3476,6 +5069,16 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -3488,11 +5091,23 @@ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", @@ -3506,6 +5121,12 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -3545,105 +5166,6 @@ } } }, - "jss": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/jss/-/jss-9.3.1.tgz", - "integrity": "sha512-YBW2fS3IQxJoDVVVOTornlMwKg0x09LjkqSeySPmnKstYOIH1liXy74MFxEM2B7e0KN8CitYsSV0l/oMaSD1Zg==", - "requires": { - "is-in-browser": "1.1.3", - "symbol-observable": "1.0.4", - "warning": "3.0.0" - } - }, - "jss-camel-case": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.0.0.tgz", - "integrity": "sha512-XAYa7JpGkLdlLgEfuzSQSVONRzSVvv4Tvyv5H8hLmJuHeFHTWwVrJrW1Cg/buED3izXKwTU2KBGpeXjIR5Eaew==" - }, - "jss-compose": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz", - "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==", - "requires": { - "warning": "3.0.0" - } - }, - "jss-default-unit": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.0.tgz", - "integrity": "sha512-tzYgFePQL0neV3Z/oZlbv7XT9Oj2wd3DMjtRYtLGeExSz/SMyVyMhnVtuX01dWUAvA94RhkddvotpdpNDj2Y8g==", - "requires": { - "is-observable": "0.2.0" - } - }, - "jss-expand": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.0.0.tgz", - "integrity": "sha512-ndsp+OnIeIc5XIHRFZlLeKNZZW25xqgohhMAyBSUZNZDuUAI9pdod3psHGRaQzyNrU3aMupyBvHnIglBHHgNTg==", - "requires": { - "is-observable": "0.2.0" - } - }, - "jss-extend": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.0.1.tgz", - "integrity": "sha512-PgJRg6zkILmgiA4Ye6P33rTjHAVDx+/dN3syT2JE6EhylfmOYs/2d+MsMxXH+Fkh9wjlvNUiinlu7Mljl+TuXA==", - "requires": { - "is-observable": "0.2.0", - "warning": "3.0.0" - } - }, - "jss-global": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz", - "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q==" - }, - "jss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz", - "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==", - "requires": { - "warning": "3.0.0" - } - }, - "jss-preset-default": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.0.1.tgz", - "integrity": "sha512-ZBj1ifZAPDn8iiC9PuB1jDCm/I0Bn53UNL9NHBgOY6AyMorDPgEb3IRjt6H+OHKwnEuCHw8tC/e3/q4I4DgTIw==", - "requires": { - "jss-camel-case": "6.0.0", - "jss-compose": "5.0.0", - "jss-default-unit": "8.0.0", - "jss-expand": "5.0.0", - "jss-extend": "6.0.1", - "jss-global": "3.0.0", - "jss-nested": "6.0.1", - "jss-props-sort": "6.0.0", - "jss-template": "1.0.0", - "jss-vendor-prefixer": "7.0.0" - } - }, - "jss-props-sort": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz", - "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g==" - }, - "jss-template": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.0.tgz", - "integrity": "sha512-NFAgcAp8V2fUxffWGGQ5zAolJq3neAvNjmWIwSmy9M6bmXTK9rnTu0fBlAcUh0ALC94B596/2TRphdkE5WRECQ==", - "requires": { - "warning": "3.0.0" - } - }, - "jss-vendor-prefixer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz", - "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==", - "requires": { - "css-vendor": "0.3.8" - } - }, "jszip": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.4.tgz", @@ -3681,6 +5203,12 @@ } } }, + "killable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz", + "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=", + "dev": true + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -3690,6 +5218,21 @@ "is-buffer": "1.1.5" } }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, "level-codec": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.0.tgz", @@ -3798,6 +5341,24 @@ "immediate": "3.0.6" } }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, "loader-utils": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", @@ -3808,6 +5369,24 @@ "json5": "0.5.1" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", @@ -3838,6 +5417,18 @@ "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" }, + "loglevel": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.0.tgz", + "integrity": "sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ=", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -3846,6 +5437,32 @@ "js-tokens": "3.0.2" } }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, "lru-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", @@ -3859,6 +5476,12 @@ "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.0.tgz", "integrity": "sha1-tlul/LNJopkkyOMz98alVi8uSEI=" }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, "math-clamp-x": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/math-clamp-x/-/math-clamp-x-1.2.0.tgz", @@ -3881,6 +5504,43 @@ "resolved": "https://registry.npmjs.org/max-safe-integer/-/max-safe-integer-1.0.1.tgz", "integrity": "sha1-84BgvixWPYwC5tSK85Ei/YO29BA=" }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, "memoizee": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.3.10.tgz", @@ -3895,12 +5555,113 @@ "timers-ext": "0.1.2" } }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "0.1.4", + "readable-stream": "2.3.3" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, - "optional": true, "requires": { "arr-diff": "2.0.0", "array-unique": "0.2.1", @@ -3917,6 +5678,22 @@ "regex-cache": "0.4.4" } }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, "mime-db": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", @@ -3930,6 +5707,24 @@ "mime-db": "1.30.0" } }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -3956,6 +5751,22 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multicast-dns": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.1.1.tgz", + "integrity": "sha1-bn3oalcIcqsXBYrepxYLvsqBTd4=", + "dev": true, + "requires": { + "dns-packet": "1.2.2", + "thunky": "0.1.0" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, "nan": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz", @@ -3968,11 +5779,35 @@ "resolved": "https://registry.npmjs.org/nan-x/-/nan-x-1.0.0.tgz", "integrity": "sha512-yw4Fhe2/UTzanQ4f0yHWkRnfTuHZFAi4GZDjXS4G+qv5BqXTqPJBbSxpa7MyyW9v4Y4ZySZQik1vcbNkhdnIOg==" }, + "ncname": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz", + "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", + "dev": true, + "requires": { + "xml-char-classes": "1.0.0" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, "next-tick": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz", "integrity": "sha1-ddpKkn7liH45BliABltzNkE7MQ0=" }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "1.1.4" + } + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -3982,6 +5817,12 @@ "is-stream": "1.1.0" } }, + "node-forge": { + "version": "0.6.33", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.33.tgz", + "integrity": "sha1-RjgRh59XPUUVWtap9D3ClujoXrw=", + "dev": true + }, "node-gyp": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", @@ -4009,6 +5850,45 @@ } } }, + "node-libs-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", + "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", + "dev": true, + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.1.4", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "domain-browser": "1.1.7", + "events": "1.1.1", + "https-browserify": "0.0.1", + "os-browserify": "0.2.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.3", + "stream-browserify": "2.0.1", + "stream-http": "2.7.2", + "string_decoder": "0.10.31", + "timers-browserify": "2.0.4", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, "node-ninja": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/node-ninja/-/node-ninja-1.0.2.tgz", @@ -4043,6 +5923,18 @@ "abbrev": "1.1.1" } }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -4062,6 +5954,15 @@ "white-space-x": "3.0.0" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, "npmlog": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", @@ -4072,6 +5973,15 @@ "gauge": "1.2.7" } }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "dev": true, + "requires": { + "boolbase": "1.0.0" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -4105,17 +6015,43 @@ "to-property-key-x": "2.0.2" } }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, - "optional": true, "requires": { "for-own": "0.1.5", "is-extendable": "0.1.1" } }, + "obuf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz", + "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4124,11 +6060,58 @@ "wrappy": "1.0.2" } }, + "opn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", + "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", + "dev": true, + "requires": { + "is-wsl": "1.1.0" + } + }, + "original": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz", + "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=", + "dev": true, + "requires": { + "url-parse": "1.0.5" + }, + "dependencies": { + "url-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz", + "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=", + "dev": true, + "requires": { + "querystringify": "0.0.4", + "requires-port": "1.0.0" + } + } + } + }, + "os-browserify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", + "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "dev": true + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -4154,17 +6137,65 @@ "object-assign": "4.1.1" } }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, "pako": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "requires": { + "no-case": "2.3.2" + } + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "requires": { + "asn1.js": "4.9.2", + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" + } + }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, - "optional": true, "requires": { "glob-base": "0.3.0", "is-dotfile": "1.0.3", @@ -4183,6 +6214,21 @@ "trim-left-x": "3.0.0" } }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, "path-array": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-array/-/path-array-1.0.1.tgz", @@ -4191,6 +6237,12 @@ "array-index": "1.0.0" } }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -4203,18 +6255,70 @@ "path-extra": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/path-extra/-/path-extra-1.0.3.tgz", - "integrity": "sha1-fBEhiablDVlXkOetIDfkTkEMEWY=" + "integrity": "sha1-fBEhiablDVlXkOetIDfkTkEMEWY=", + "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "pepjs": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/pepjs/-/pepjs-0.4.3.tgz", + "integrity": "sha1-FggOlwqud5kTdWwtrviOqnSG30E=" + }, "performance-now": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", @@ -4239,6 +6343,17 @@ "find-up": "1.1.2" } }, + "portfinder": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", + "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=", + "dev": true, + "requires": { + "async": "1.5.2", + "debug": "2.6.9", + "mkdirp": "0.5.1" + } + }, "pouchdb": { "version": "6.3.4", "resolved": "https://registry.npmjs.org/pouchdb/-/pouchdb-6.3.4.tgz", @@ -4337,14 +6452,29 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", "dev": true, - "optional": true + "requires": { + "renderkid": "2.0.1", + "utila": "0.4.0" + } }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", @@ -4382,11 +6512,40 @@ "resolved": "https://registry.npmjs.org/proptypes/-/proptypes-1.1.0.tgz", "integrity": "sha1-eLOCilqmuxMIk54N48YETf1L0jk=" }, + "proxy-addr": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "dev": true, + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.5.2" + } + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.5" + } + }, "pump": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz", @@ -4406,6 +6565,24 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=" }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz", + "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=", + "dev": true + }, "raf": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz", @@ -4431,7 +6608,6 @@ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, - "optional": true, "requires": { "is-number": "3.0.0", "kind-of": "4.0.0" @@ -4442,7 +6618,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, - "optional": true, "requires": { "kind-of": "3.2.2" }, @@ -4452,7 +6627,6 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, - "optional": true, "requires": { "is-buffer": "1.1.5" } @@ -4464,17 +6638,54 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, - "optional": true, "requires": { "is-buffer": "1.1.5" } } } }, + "randombytes": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "dev": true, + "requires": { + "randombytes": "2.0.5", + "safe-buffer": "5.1.1" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + } + }, "raw-loader": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", - "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=" + "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", + "dev": true }, "rc": { "version": "1.2.2", @@ -4514,16 +6725,117 @@ "object-assign": "4.1.1" } }, - "react-jss": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.0.0.tgz", - "integrity": "sha512-vVzOLePx1gjdR/V4nZr0tsCLKCKfKfPdJAnQVDU9BSVh+vlva36/gZNdb1p5BrnX4gvZ9cqLHF0urzkaTX1xzg==", + "react-dom": { + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.1.1.tgz", + "integrity": "sha512-q06jiwST8SEPAMIEkAsu7BgynEZtqF87VrTc70XsW7nxVhWEu2Y4MF5UfxxHQO/mNtQHQWP0YcFxmwm9oMrMaQ==", + "dev": true, "requires": { - "hoist-non-react-statics": "2.3.1", - "jss": "9.3.1", - "jss-preset-default": "4.0.1", + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + }, + "react-jss": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-7.2.0.tgz", + "integrity": "sha512-vgnNFImsjfchBloCt0BCe7MeiNEiGtTm/MGA0RVFjU/ccTt+YAlfFhSlGJ+KOC3qQ9Sl5mkl07JatGfjW2CTQQ==", + "requires": { + "hoist-non-react-statics": "1.2.0", + "jss": "8.1.0", + "jss-preset-default": "3.0.0", "prop-types": "15.6.0", "theming": "1.2.1" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", + "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=" + }, + "jss": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-8.1.0.tgz", + "integrity": "sha512-NZ4CNAoPaPlM2rqHxPG5uGQbQEFZ9n1PITn0+wGIdAk2ZtA/F6el0SphLHf8So1Sx6N34hnVFFIuc32/hdsEzw==", + "requires": { + "is-in-browser": "1.1.3", + "warning": "3.0.0" + } + }, + "jss-camel-case": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-5.0.0.tgz", + "integrity": "sha512-vz11ip5EIlGuevtlUo9xIgiuD+it4Ebbb0+Y4o0A4oA8eOWY4aY7ihi/L7WvkQ54xnGOjUvLZ6nm2VYch2ufYg==" + }, + "jss-compose": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-4.0.0.tgz", + "integrity": "sha512-VnsEziD2Lwrfwp10wx39FNybRLW5+RX/E2qQAXPAMbS+nHc0Jf2dC6ZiCfn5FaBGrpzLfIZ9MalTJDx4CQoMAQ==", + "requires": { + "warning": "3.0.0" + } + }, + "jss-default-unit": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-7.0.0.tgz", + "integrity": "sha512-U1Oi1h45vFRuISr+g1DQ3Oua7CkNKNs47fTdiT/lHkuBMc6BBDUbPv9IbPPhk9gsEaX45Iy9TX8CAuaHLPCfEA==" + }, + "jss-expand": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-4.0.1.tgz", + "integrity": "sha512-LRIMXXChAOgnhwSqYLJg8MS6dI98bf/sg52pAg04pbjOAtjfzyS0JTnQAiyk3PxqR3nKFR/Yv44ahpIpkdcxVA==" + }, + "jss-extend": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-5.0.0.tgz", + "integrity": "sha512-fUp+9KipbdmzSfTxNHoT3mrFnE7fYn7EyHg3LTUexfpWrwj5Afkwb3iCfYV7GYCpg9OKDsqc18atwjHvSPWWKg==", + "requires": { + "warning": "3.0.0" + } + }, + "jss-global": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-2.0.0.tgz", + "integrity": "sha512-/FSOMp4lF/vg47T/w8kKvL9tu7ka9am8N4izS63W81Qlay9hAq6xe9RxrPxygLpnn4KEb8LNbkKRoUv4SJfQsQ==" + }, + "jss-nested": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-5.0.0.tgz", + "integrity": "sha512-9Molau+XVpSc6QEco3EC5yXmzeGMc5ZVII8+qy6jD6bvu6Y9mpfGoJ00LalR/n7xr/LC7Cxgs44UQQlLzumMBg==", + "requires": { + "warning": "3.0.0" + } + }, + "jss-preset-default": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-3.0.0.tgz", + "integrity": "sha512-5wRsHsV89XjnQlUVN5jQfo6gcfcirDJmsMJL52HmWoQlV9SA+jhUtt1w3LjcJHe4e3tX4u/To/x3Btmhi+LZtQ==", + "requires": { + "jss-camel-case": "5.0.0", + "jss-compose": "4.0.0", + "jss-default-unit": "7.0.0", + "jss-expand": "4.0.1", + "jss-extend": "5.0.0", + "jss-global": "2.0.0", + "jss-nested": "5.0.0", + "jss-props-sort": "5.0.0", + "jss-vendor-prefixer": "6.0.0" + } + }, + "jss-props-sort": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-5.0.0.tgz", + "integrity": "sha512-xtoVE7BlcPaMN/dzypHPYJn+QiphLPB1skypAOp9zLkOozPbR/x0JVAFdZnd7zqmmjvg+Ma/txjSg0HN/eZsGA==" + }, + "jss-vendor-prefixer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-6.0.0.tgz", + "integrity": "sha512-leqW7B2QLXYsUNR3jsUZP3CkuOYcWXyfF8TSJc4XNxhVCNH7ztK5dcnF8nLoMnxT0w/ajloeJKcch2ty/viCAA==", + "requires": { + "css-vendor": "0.3.8" + } + } } }, "react-notification-system": { @@ -4566,6 +6878,63 @@ "prop-types": "15.6.0" } }, + "react-router-redux": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-4.0.8.tgz", + "integrity": "sha1-InQDWWtRUeGCN32rg1tdRfD4BU4=", + "dev": true + }, + "react-svg-inline": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/react-svg-inline/-/react-svg-inline-2.0.1.tgz", + "integrity": "sha512-9YVqJ80g1gPWAvD9CS/z4cKPD45ZSMjjzwxFAmQJiMEoAo1Ajhz92WirXag3ftltDN5lPNkVWx/KOnEWB/PaMQ==", + "dev": true, + "requires": { + "classnames": "2.2.5", + "prop-types": "15.6.0" + } + }, + "react-tap-event-plugin": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-tap-event-plugin/-/react-tap-event-plugin-3.0.2.tgz", + "integrity": "sha1-KANxZ3uIHDE3bgAnoLhtLG3gOe4=", + "dev": true, + "requires": { + "fbjs": "0.8.16" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + } + } + }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -4585,7 +6954,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "dev": true, - "optional": true, "requires": { "graceful-fs": "4.1.11", "minimatch": "3.0.4", @@ -4593,6 +6961,28 @@ "set-immediate-shim": "1.0.1" } }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "redux": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", + "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", + "dev": true, + "requires": { + "lodash": "4.17.4", + "lodash-es": "4.17.4", + "loose-envify": "1.3.1", + "symbol-observable": "1.0.4" + } + }, "redux-form": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/redux-form/-/redux-form-7.1.2.tgz", @@ -4608,6 +6998,27 @@ "prop-types": "15.6.0" } }, + "redux-logger": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz", + "integrity": "sha1-91VZZvMJjzyIYExEnPC69XeCdL8=", + "dev": true, + "requires": { + "deep-diff": "0.3.8" + } + }, + "redux-promise-middleware": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/redux-promise-middleware/-/redux-promise-middleware-4.4.2.tgz", + "integrity": "sha512-PdBYebU+pstX2/CIrHiSD0meFetsFI0P/LrtsQLfhLPxU7zJASnMdO9KSrv1fHRh0fftYMtg8HfYiyVePBcDFg==", + "dev": true + }, + "redux-thunk": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.2.0.tgz", + "integrity": "sha1-5hWhbha0ehmlFXZhM9Hj6Zt4UuU=", + "dev": true + }, "redux-undo": { "version": "1.0.0-beta9-9-7", "resolved": "https://registry.npmjs.org/redux-undo/-/redux-undo-1.0.0-beta9-9-7.tgz", @@ -4638,7 +7049,6 @@ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, - "optional": true, "requires": { "is-equal-shallow": "0.1.3" } @@ -4673,12 +7083,39 @@ } } }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, + "renderkid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", + "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", + "dev": true, + "requires": { + "css-select": "1.2.0", + "dom-converter": "0.1.4", + "htmlparser2": "3.3.0", + "strip-ansi": "3.0.1", + "utila": "0.3.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", + "dev": true + } + } + }, "repeat-element": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", @@ -4689,8 +7126,7 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "optional": true + "dev": true }, "repeating": { "version": "2.0.1", @@ -4747,6 +7183,18 @@ "to-string-x": "1.4.2" } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, "require-object-coercible-x": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/require-object-coercible-x/-/require-object-coercible-x-1.4.1.tgz", @@ -4759,15 +7207,46 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/require-resolve/-/require-resolve-0.0.2.tgz", "integrity": "sha1-urQQqxruLz9Vt5MXRR3TQodk5vM=", + "dev": true, "requires": { "x-path": "0.0.2" } }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, "reselect": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "0.1.4" + } + }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -4776,33 +7255,171 @@ "glob": "7.1.2" } }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "dev": true, + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "requires": { + "ajv": "5.3.0" + }, + "dependencies": { + "ajv": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", + "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selfsigned": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.1.tgz", + "integrity": "sha1-v4y3uDJWxFUeMTR8YxF3jbme7FI=", + "dev": true, + "requires": { + "node-forge": "0.6.33" + } + }, "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" }, + "send": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "1.1.1", + "destroy": "1.0.4", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "1.0.3", + "http-errors": "1.6.2", + "mime-types": "2.1.17", + "parseurl": "1.3.2" + } + }, + "serve-static": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "dev": true, + "requires": { + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "optional": true + "dev": true }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "sha.js": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shortid": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.8.tgz", "integrity": "sha1-AzsRfWoul1gE9vCWnb59PQs1UTE=" }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, "simple-get": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz", @@ -4832,6 +7449,55 @@ "hoek": "2.16.3" } }, + "sockjs": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz", + "integrity": "sha1-2bKJMWyn33dZXvKZ4HXw+TfrQgc=", + "dev": true, + "requires": { + "faye-websocket": "0.10.0", + "uuid": "2.0.3" + }, + "dependencies": { + "uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + } + } + }, + "sockjs-client": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz", + "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=", + "dev": true, + "requires": { + "debug": "2.6.9", + "eventsource": "0.1.6", + "faye-websocket": "0.11.1", + "inherits": "2.0.3", + "json3": "3.3.2", + "url-parse": "1.2.0" + }, + "dependencies": { + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "dev": true, + "requires": { + "websocket-driver": "0.7.0" + } + } + } + }, + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4851,6 +7517,62 @@ "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.0.tgz", "integrity": "sha1-NyIifFTi+vJLHcbZM8wUTm9xv+8=" }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "spdy": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", + "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", + "dev": true, + "requires": { + "debug": "2.6.9", + "handle-thing": "1.2.5", + "http-deceiver": "1.2.7", + "safe-buffer": "5.1.1", + "select-hose": "2.0.0", + "spdy-transport": "2.0.20" + } + }, + "spdy-transport": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz", + "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=", + "dev": true, + "requires": { + "debug": "2.6.9", + "detect-node": "2.0.3", + "hpack.js": "2.1.6", + "obuf": "1.1.1", + "readable-stream": "2.3.3", + "safe-buffer": "5.1.1", + "wbuf": "1.7.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", @@ -4873,6 +7595,35 @@ } } }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", @@ -4881,6 +7632,39 @@ "safe-buffer": "5.1.1" } }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", @@ -4894,6 +7678,27 @@ "ansi-regex": "2.1.1" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -4907,7 +7712,14 @@ "symbol-observable": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", - "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" + "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=", + "dev": true + }, + "tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", + "dev": true }, "tar": { "version": "2.2.1", @@ -4971,6 +7783,27 @@ "xtend": "4.0.1" } }, + "thunky": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=", + "dev": true + }, + "time-stamp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz", + "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz", + "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==", + "dev": true, + "requires": { + "setimmediate": "1.0.5" + } + }, "timers-ext": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz", @@ -4987,6 +7820,12 @@ } } }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, "to-boolean-x": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-boolean-x/-/to-boolean-x-1.0.1.tgz", @@ -5081,6 +7920,12 @@ "is-symbol": "1.0.1" } }, + "toposort": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz", + "integrity": "sha1-wxdI5V0hDv/AD9zcfW5o19e7nOw=", + "dev": true + }, "tough-cookie": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", @@ -5099,6 +7944,12 @@ "white-space-x": "3.0.0" } }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", @@ -5124,6 +7975,12 @@ "trim-right-x": "3.0.0" } }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, "tunnel-agent": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", @@ -5135,16 +7992,117 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "optional": true }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.17" + } + }, "ua-parser-js": { "version": "0.7.17", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-js": "2.8.29", + "webpack-sources": "1.0.2" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, "unzip-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=" }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz", + "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==", + "dev": true, + "requires": { + "querystringify": "1.0.0", + "requires-port": "1.0.0" + }, + "dependencies": { + "querystringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", + "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=", + "dev": true + } + } + }, "url-template": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", @@ -5156,6 +8114,23 @@ "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", "dev": true }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5166,6 +8141,18 @@ "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=" }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, "uuid": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", @@ -5185,11 +8172,27 @@ "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=" }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, "validate.io-undefined": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/validate.io-undefined/-/validate.io-undefined-1.0.3.tgz", "integrity": "sha1-fif8uzFbhB54JDQxiXZxkp4gt/Q=" }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -5207,6 +8210,15 @@ } } }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, "vuvuzela": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz", @@ -5220,6 +8232,328 @@ "loose-envify": "1.3.1" } }, + "watchpack": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "dev": true, + "requires": { + "async": "2.6.0", + "chokidar": "1.7.0", + "graceful-fs": "4.1.11" + }, + "dependencies": { + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + } + } + }, + "wbuf": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz", + "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=", + "dev": true, + "requires": { + "minimalistic-assert": "1.0.0" + } + }, + "webpack": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.8.1.tgz", + "integrity": "sha512-5ZXLWWsMqHKFr5y0N3Eo5IIisxeEeRAajNq4mELb/WELOR7srdbQk2N5XiyNy2A/AgvlR3AmeBCZJW8lHrolbw==", + "dev": true, + "requires": { + "acorn": "5.2.1", + "acorn-dynamic-import": "2.0.2", + "ajv": "5.3.0", + "ajv-keywords": "2.1.1", + "async": "2.6.0", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.0.4", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.0.0", + "source-map": "0.5.7", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.4.0", + "webpack-sources": "1.0.2", + "yargs": "8.0.2" + }, + "dependencies": { + "ajv": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", + "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "webpack-dev-middleware": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz", + "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=", + "dev": true, + "requires": { + "memory-fs": "0.4.1", + "mime": "1.4.1", + "path-is-absolute": "1.0.1", + "range-parser": "1.2.0", + "time-stamp": "2.0.0" + } + }, + "webpack-dev-server": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.4.tgz", + "integrity": "sha512-thrqC0EQEoSjXeYgP6pUXcUCZ+LNrKsDPn+mItLnn5VyyNZOJKd06hUP5vqkYwL8nWWXsii0loSF9NHNccT6ow==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "array-includes": "3.0.3", + "bonjour": "3.5.0", + "chokidar": "1.7.0", + "compression": "1.7.1", + "connect-history-api-fallback": "1.5.0", + "debug": "3.1.0", + "del": "3.0.0", + "express": "4.16.2", + "html-entities": "1.2.1", + "http-proxy-middleware": "0.17.4", + "import-local": "0.1.1", + "internal-ip": "1.2.0", + "ip": "1.1.5", + "killable": "1.0.0", + "loglevel": "1.6.0", + "opn": "5.1.0", + "portfinder": "1.0.13", + "selfsigned": "1.10.1", + "serve-index": "1.9.1", + "sockjs": "0.3.18", + "sockjs-client": "1.1.4", + "spdy": "3.4.7", + "strip-ansi": "3.0.1", + "supports-color": "4.5.0", + "webpack-dev-middleware": "1.12.0", + "yargs": "6.6.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "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.1" + } + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + } + } + } + }, + "webpack-sources": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.2.tgz", + "integrity": "sha512-Y7UddMCv6dGjy81nBv6nuQeFFIt5aalHm7uyDsAsW86nZwfOVPGRr3XMjEQLaT+WKo8rlzhC9qtbJvYKLtAwaw==", + "dev": true, + "requires": { + "source-list-map": "2.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "dev": true, + "requires": { + "http-parser-js": "0.4.9", + "websocket-extensions": "0.1.3" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true + }, "whatwg-fetch": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", @@ -5233,11 +8567,62 @@ "isexe": "2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "white-space-x": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/white-space-x/-/white-space-x-3.0.0.tgz", "integrity": "sha512-nMPVXGMdi/jQepXKryxqzEh/vCwdOYY/u6NZy40glMHvZfEr7/+vQKnDhEq4rZ1nniOFq9GWohQYB30uW/5Olg==" }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "worker-loader": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.1.0.tgz", + "integrity": "sha512-W91q8Wi1JxbzFQZuLJlFK4x8UuWjKgeOX9IMMyng007K0UkP6I8lOejckoCWY61QmnJq2x9qZ/Viru+uF8g6nA==", + "dev": true, + "requires": { + "loader-utils": "1.1.0", + "schema-utils": "0.3.0" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -5262,14 +8647,113 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/x-path/-/x-path-0.0.2.tgz", "integrity": "sha1-KU0Ha7l6dwbMBwu7Km/YxU32exI=", + "dev": true, "requires": { "path-extra": "1.0.3" } }, + "xml-char-classes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz", + "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=", + "dev": true + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + }, + "yml-loader": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/yml-loader/-/yml-loader-2.1.0.tgz", + "integrity": "sha512-mo42d5FQWlXxpyTEpYywPu1LzK3F69pPPCOB8WKgJi8s+aqaogQP7XnXTjSobbKzzlZ/wXm7kg9CkP4x4ZnVMw==", + "dev": true, + "requires": { + "js-yaml": "3.10.0", + "loader-utils": "1.1.0" + } } } } diff --git a/package.json b/package.json index 8a40ca7..fa99aad 100755 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "module": "module", "esnext": "src", "scripts": { + "start": "webpack-dev-server -w", "prepare": "npm run build", "build": "npm run build:main && npm run build:module ", "build:main": "BABEL_ENV=main babel src -s -d lib", @@ -14,14 +15,14 @@ "dependencies": { "@doodle3d/cal": "0.0.8", "@doodle3d/clipper-js": "^1.0.7", + "@doodle3d/fill-path": "^1.0.7", "@doodle3d/potrace-js": "0.0.6", "@doodle3d/threejs-export-obj": "0.0.4", "@doodle3d/threejs-export-stl": "0.0.3", - "babel-plugin-inline-import": "^2.0.6", - "babel-plugin-ramda": "^1.4.3", - "babel-plugin-transform-regenerator": "^6.26.0", - "babel-preset-stage-0": "^6.24.1", + "@doodle3d/touch-events": "0.0.7", + "babel-polyfill": "^6.26.0", "bezier-js": "^2.2.3", + "bowser": "^1.8.1", "fit-curve": "^0.1.6", "imports-loader": "^0.7.1", "memoizee": "^0.3.9", @@ -29,16 +30,14 @@ "proptypes": "^1.1.0", "raf": "^3.4.0", "ramda": "^0.21.0", - "raw-loader": "^0.5.1", "react": "^16.0.0", "react-addons-update": "^15.6.2", - "react-jss": "^8.0.0", + "react-jss": "^7.0.2", "react-notification-system-redux": "^1.2.0", "react-redux": "^5.0.6", "react-resize-detector": "^1.1.0", "redux-form": "^7.1.2", "redux-undo": "^1.0.0-beta9-9-7", - "regenerator-runtime": "^0.11.0", "reselect": "^3.0.1", "semver": "^5.4.1", "shortid": "^2.2.8", @@ -47,17 +46,38 @@ "valid-url": "^1.0.9" }, "devDependencies": { - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-preset-env": "^1.6.1", - "babel-preset-react": "^6.24.1", + "redux-logger": "^3.0.6", + "raw-loader": "^0.5.1", + "react-svg-inline": "^2.0.1", + "react-router-redux": "^4.0.8", + "redux-promise-middleware": "^4.4.2", + "redux-thunk": "^2.2.0", + "redux": "^3.7.2", + "file-loader": "^1.1.5", + "webpack-dev-server": "^2.9.4", + "babel-plugin-transform-runtime": "^6.23.0", + "html-webpack-plugin": "^2.30.1", + "html-webpack-template": "^6.0.2", + "react-dom": "^16.1.1", + "webpack": "^3.8.1", + "worker-loader": "^1.1.0", + "yml-loader": "^2.1.0", "babel-cli": "6.24.1", "babel-core": "6.24.1", "babel-loader": "7.0.0", "babel-plugin-add-module-exports": "0.2.1", - "babel-preset-es2015": "6.24.1" + "babel-plugin-inline-import": "^2.0.6", + "babel-plugin-ramda": "^1.4.3", + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.26.0", + "babel-plugin-transform-regenerator": "^6.26.0", + "babel-preset-env": "^1.6.1", + "babel-preset-es2015": "6.24.1", + "babel-preset-react": "^6.24.1", + "babel-preset-stage-0": "^6.24.1", + "react-tap-event-plugin": "^3.0.2" }, "repository": { "type": "git", diff --git a/src/components/App.js b/src/components/App.js index 23d2e2c..0a2930e 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -7,12 +7,15 @@ import Logo from './Logo.js'; import D2Panel from './D2Panel.js'; import D3Panel from './D3Panel.js'; import SketcherToolbars from './SketcherToolbars.js'; -import vlineImageURL from 'img/vline.png'; -import btnUndoImageURL from 'img/mainmenu/btnUndo.png'; -import btnRedoImageURL from 'img/mainmenu/btnRedo.png'; +import Button from './Button.js'; +import vlineImageURL from '../../img/vline.png'; +import btnUndoImageURL from '../../img/mainmenu/btnUndo.png'; +import btnRedoImageURL from '../../img/mainmenu/btnRedo.png'; const styles = { container: { + position: 'relative', + userSelect: 'none', display: 'flex', flexDirection: 'column', alignItems: 'stretch', @@ -61,7 +64,6 @@ class App extends React.Component { render() { const { classes, undo, redo } = this.props; - return (
@@ -70,11 +72,11 @@ class App extends React.Component {
-
-
-
+
+
); } diff --git a/src/components/Button.js b/src/components/Button.js new file mode 100644 index 0000000..dc6f74a --- /dev/null +++ b/src/components/Button.js @@ -0,0 +1,48 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:button'); + +export default class Button extends React.Component { + static propTypes = { + onSelect: PropTypes.func, + value: PropTypes.string, + selected: PropTypes.bool, + disabled: PropTypes.bool, + id: PropTypes.string, + className: PropTypes.string, + children: PropTypes.node, + svg: PropTypes.string, + stopPropagation: PropTypes.bool + }; + static defaultProps = { + disabled: false, + stopPropagation: false + }; + onClick = (event) => { + const { onSelect, value, disabled, stopPropagation } = this.props; + if (disabled) return; + if (onSelect) onSelect({ ...event, value }); + // we might want to stop the propagation of events to prevent + // other things to respond to this click, like submenu's closing themselves + if (stopPropagation) { + event.nativeEvent.stopImmediatePropagation(); + } + }; + render() { + const { id, selected, disabled, className, children, svg } = this.props; + let combinedClassName = 'button'; + if (selected) combinedClassName += ' selected'; + if (disabled) combinedClassName += ' disabled'; + if (className) combinedClassName += ` ${className}`; + + return ( +
+ {svg && + + } + {children} +
+ ); + } +} diff --git a/src/components/D2Panel.js b/src/components/D2Panel.js index 2d4ba61..9353f2c 100644 --- a/src/components/D2Panel.js +++ b/src/components/D2Panel.js @@ -5,20 +5,21 @@ import { connect } from 'react-redux'; import * as CAL from 'cal'; import * as toolNames from '../constants/d2Tools'; import { CANVAS_SIZE } from '../constants/d2Constants'; -import createRAFOnce from 'src/js/utils/rafOnce.js'; -import Grid from 'src/js/design/Grid.js'; -import BaseTool from 'src/js/design/tools/BaseTool.js'; -import TransformTool from 'src/js/design/tools/TransformTool.js'; -import EraserTool from 'src/js/design/tools/EraserTool.js'; -import BrushTool from 'src/js/design/tools/BrushTool.js'; -import PolygonTool from 'src/js/design/tools/PolygonTool.js'; -import CircleTool from 'src/js/design/tools/CircleTool.js'; -import TextTool from 'src/js/design/tools/TextTool.js'; -import BucketTool from 'src/js/design/tools/BucketTool.js'; -import PhotoGuideTool from 'src/js/design/tools/PhotoGuideTool.js'; +import createRAFOnce from '../utils/rafOnce.js'; +import Grid from '../d2/Grid.js'; +import BaseTool from '../d2/tools/BaseTool.js'; +import TransformTool from '../d2/tools/TransformTool.js'; +import EraserTool from '../d2/tools/EraserTool.js'; +import BrushTool from '../d2/tools/BrushTool.js'; +import PolygonTool from '../d2/tools/PolygonTool.js'; +import CircleTool from '../d2/tools/CircleTool.js'; +import TextTool from '../d2/tools/TextTool.js'; +import BucketTool from '../d2/tools/BucketTool.js'; +import PhotoGuideTool from '../d2/tools/PhotoGuideTool.js'; import { PIXEL_RATIO } from '../constants/general'; -import ShapesManager from 'src/js/design/ShapesManager.js'; -import EventGroup from 'src/js/design/EventGroup.js'; +import ShapesManager from '../d2/ShapesManager.js'; +import EventGroup from '../d2/EventGroup.js'; +import ReactResizeDetector from 'react-resize-detector'; // import createDebug from 'debug'; // const debug = createDebug('d3d:d2'); @@ -48,7 +49,7 @@ const styles = { alignItems: 'stretch', overflow: 'hidden' }, - canvas: { + canvasContainer: { flexGrow: 1, margin: '0px', overflow: 'hidden', @@ -91,23 +92,17 @@ class D2Panel extends React.Component { this.shapesManager = new ShapesManager(this.objectContainerActive, this.objectContainerInactive); - window.addEventListener('resize', this.resizeHandler); - this.DOM = null; } componentDidMount() { - const { canvasContainer, activeScene, inactiveScene } = this.refs; - console.log('canvasContainer: ', canvasContainer); + const { canvasContainer } = this.refs; this.container = canvasContainer; - this.sceneActive.setCanvas(activeScene); - this.sceneInactive.setCanvas(inactiveScene); - this.resizeHandler(); - } + this.container.appendChild(this.sceneInactive.image); + this.container.appendChild(this.sceneActive.image); - componentWillUnmount() { - window.removeEventListener('resize', this.resizeHandler); + this.sceneActive.onClick = (event) => event.stopPropagation(); } updateTool(newState) { @@ -178,8 +173,7 @@ class D2Panel extends React.Component { this.state = newState; } - resizeHandler = () => { - const { offsetWidth: width, offsetHeight: height } = this.container; + resizeHandler = (width, height) => { this.sceneActive.setSize(width, height, PIXEL_RATIO); this.sceneInactive.setSize(width, height, PIXEL_RATIO); @@ -210,11 +204,6 @@ class D2Panel extends React.Component { } }; - stopPropagation(event) { - // stop propagation to prefent popup to close immidiatly - event.stopPropagation(); - } - render() { // debug('this.props.state: ', this.props.state); const { state, classes } = this.props; @@ -222,10 +211,8 @@ class D2Panel extends React.Component { this.renderCanvas(); return (
-
- - -
+ +
); } diff --git a/src/components/D3Panel.js b/src/components/D3Panel.js index 746c640..17df2d5 100644 --- a/src/components/D3Panel.js +++ b/src/components/D3Panel.js @@ -6,20 +6,21 @@ import injectSheet from 'react-jss'; import { CANVAS_SIZE } from '../constants/d2Constants'; import ShapesManager from '../d3/ShapesManager'; import { getSelectedObjectsSelector, getBoundingBox } from '../utils/selectionUtils'; -import createRAFOnce from 'src/js/utils/rafOnce.js'; +import createRAFOnce from '../utils/rafOnce.js'; import { hasExtensionsFor } from '../utils/WebGLSupport.js'; import { PIXEL_RATIO } from '../constants/general.js'; import * as toolsNames from '../constants/d3Tools.js'; -import { EventScene, EventObject3D } from 'src/js/preview/EventScene.js'; -import HeightTransformer from 'src/js/preview/transformers/HeightTransformer.js'; -import TwistTransformer from 'src/js/preview/transformers/TwistTransformer.js'; -import SculptTransformer from 'src/js/preview/transformers/SculptTransformer.js'; -import StampTransformer from 'src/js/preview/transformers/StampTransformer.js'; -import SelectionBox from 'src/js/preview/SelectionBox.js'; +import { EventScene, EventObject3D } from '../d3/EventScene.js'; +import HeightTransformer from '../d3/transformers/HeightTransformer.js'; +import TwistTransformer from '../d3/transformers/TwistTransformer.js'; +import SculptTransformer from '../d3/transformers/SculptTransformer.js'; +import StampTransformer from '../d3/transformers/StampTransformer.js'; +import SelectionBox from '../d3/SelectionBox.js'; import ToonShaderRenderChain from '../d3/ToonShaderRenderChain'; import RenderChain from '../d3/RenderChain'; -import BaseTransformer from 'src/js/preview/transformers/BaseTransformer.js'; -import Camera from 'src/js/preview/Camera.js'; +import BaseTransformer from '../d3/transformers/BaseTransformer.js'; +import Camera from '../d3/Camera.js'; +import ReactResizeDetector from 'react-resize-detector'; // import createDebug from 'debug'; // const debug = createDebug('d3d:d3'); @@ -45,7 +46,7 @@ const styles = { alignItems: 'stretch', overflow: 'hidden' }, - canvas: { + canvasContainer: { flexGrow: 1, margin: '0px', overflow: 'hidden', @@ -79,21 +80,17 @@ class D3Panel extends React.Component { this.renderChain = new RenderChain(this.renderer, this.scene, this.camera); } - window.addEventListener('resize', this.resizeHandler); - this.DOM = null; } componentDidMount() { this.container = this.refs.canvasContainer; - this.resizeHandler(); this.container.appendChild(this.renderer.domElement); this.renderScene(); // immidiatly render because when THREE.JS inits, a black screen is generated } componentWillUnmount() { - window.removeEventListener('resize', this.resizeHandler); this.scene.setCanvas(null); } @@ -224,9 +221,7 @@ class D3Panel extends React.Component { this.state = newState; } - resizeHandler = () => { - const { offsetWidth: width, offsetHeight: height } = this.container; - + resizeHandler = (width, height) => { // set renderer size this.renderChain.setSize(width, height, PIXEL_RATIO); @@ -244,7 +239,8 @@ class D3Panel extends React.Component { this.renderScene(); return (
-
+ +
); } diff --git a/src/components/DoodlePreview.js b/src/components/DoodlePreview.js index b6a1eba..fd188e0 100644 --- a/src/components/DoodlePreview.js +++ b/src/components/DoodlePreview.js @@ -62,7 +62,7 @@ class DoodlePreview extends React.Component { if (this.editorControls) this.editorControls.dispose(); } - onResize = (width, height) => { + resizeHandler = (width, height) => { requestAnimationFrame(() => { const { setSize, render } = this.state; const { pixelRatio } = this.props; @@ -75,7 +75,7 @@ class DoodlePreview extends React.Component { return (
- +
); diff --git a/src/components/InlineIconsLoader.js b/src/components/InlineIconsLoader.js new file mode 100644 index 0000000..d4a6a19 --- /dev/null +++ b/src/components/InlineIconsLoader.js @@ -0,0 +1,19 @@ +import React from 'react'; +import InlineSVG from 'react-svg-inline'; +import btnColorOption from '../../img/contextmenu/btnColorOption.svg'; +import btnColor from '../../img/contextmenu/btnColor.svg'; +import injectSheet from 'react-jss'; + +const styles = { + container: { + display: 'none' + } +}; + +const InlineIconsLoader = ({ classes }) => ( +
+ + +
+); +export default injectSheet(styles)(InlineIconsLoader); diff --git a/src/components/Logo.js b/src/components/Logo.js index 71e87d9..5083c2d 100644 --- a/src/components/Logo.js +++ b/src/components/Logo.js @@ -1,5 +1,5 @@ import React from 'react'; -import doodleSignImageURL from 'img/doodle3d-sign.png'; +import doodleSignImageURL from '../../img/doodle3d-sign.png'; import injectSheet from 'react-jss'; const styles = { diff --git a/src/components/Menu.js b/src/components/Menu.js new file mode 100644 index 0000000..0b08362 --- /dev/null +++ b/src/components/Menu.js @@ -0,0 +1,44 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import initialMenuStructure from '../constants/menu.js'; +import { connect } from 'react-redux'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:menu'); + +class Menu extends React.Component { + static propTypes = { + onSelect: PropTypes.func, + onOpen: PropTypes.func, + onClose: PropTypes.func, + selectedValue: PropTypes.string, + value: PropTypes.string, + className: PropTypes.string, + children: PropTypes.node, + stateMenu: PropTypes.object + }; + onSelect = (event) => { + const { onSelect, value } = this.props; + // add menu value when it's not already defined by a submenu + const { menuValue = value } = event; + if (onSelect) onSelect({ ...event, menuValue }); + }; + render() { + const { className = '', id, selectedValue, onOpen, onClose, value, children, stateMenu } = this.props; + return ( +
    + {React.Children.map(children, (child) => { + return React.cloneElement(child, { + onSelect: this.onSelect, + onOpen, + onClose, + selected: (child.props.value === selectedValue) + }); + })} +
+ ); + } +} + +export default connect(state => ({ + stateMenu: state.sketcher.present.menus +}))(Menu); diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js new file mode 100644 index 0000000..2619567 --- /dev/null +++ b/src/components/MenuItem.js @@ -0,0 +1,28 @@ +import React from 'react'; +import Button from './Button.js'; +import injectSheet from 'react-jss'; + +const styles = { + container: { + display: 'block' + } +}; + +const MenuItem = ({ id, value, selected, disabled, onSelect, children, className, svg, classes }) => { + return ( +
  • + +
  • + ); +}; +export default injectSheet(styles)(MenuItem); diff --git a/src/components/SketcherToolbars.js b/src/components/SketcherToolbars.js index 8a44de1..21584a9 100644 --- a/src/components/SketcherToolbars.js +++ b/src/components/SketcherToolbars.js @@ -2,12 +2,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as actions from '../actions/index.js'; import { connect } from 'react-redux'; -import * as contextTools from '../constants/contextTools'; -import * as d2Tools from '../constants/d2Tools'; +import Menu from '../components/Menu.js'; +import SubMenu from '../components/SubMenu.js'; +import MenuItem from '../components/MenuItem.js'; +import * as contextTools from '../constants/contextTools.js'; +import * as d2Tools from '../constants/d2Tools.js'; import { createSelector } from 'reselect'; -import Menu from 'src/js/components/Menu.js'; -import SubMenu from 'src/js/components/SubMenu.js'; -import MenuItem from 'src/js/components/MenuItem.js'; // import createDebug from 'debug'; // const debug = createDebug('d3d:sketchertoolbars'); @@ -197,4 +197,612 @@ const getMenus = createSelector([ context: filterMenus(numSelectedObjects, allObjectsAreFilled, activeTool, nestChildren(menus, menus[CONTEXT])) })); +const style = document.createElement('style'); +style.innerHTML = ` +.centerer { /* centers child */ + position: absolute; + left: 0; + bottom: 0; + right: 0; + top: 0; + display: flex; + justify-content: center; + align-items: center; + pointer-events: none; /* enable clicking through object */ +} +.centerer * { + pointer-events: visible; /* enable clicking in children */ +} +.button { + cursor: pointer; +} +#toolbar3d-container { + position: absolute; + right: 0; + bottom: 0; + width: 50%; +} +#toolbar3d { + background-image: url('../img/toolbar3d/toolbar3d.png'); + background-size: 493px auto; + background-repeat: no-repeat; + background-position: center -4px; + height: 77px; + + width: 493px; +} + +#toolbar3d>.menuitem>.button, +#toolbar3d>.submenu>.button { + /* positioning buttons with padding to increase hit area */ + padding: 10px 52px 0 52px; +} + +/* 3D toolbar tools */ +#toolbar3d #height-tool { + background-image: url('../img/toolbar3d/btnExtrude.png'); + background-size: 21px auto; + width: 21px; + height: 42px; +} +#toolbar3d #sculpt-tool { + background-image: url('../img/toolbar3d/btnSculpt.png'); + background-size: 39px auto; + width: 39px; + height: 42px; +} +#toolbar3d #twist-tool { + background-image: url('../img/toolbar3d/btnTwist.png'); + background-size: 40px auto; + width: 40px; + height: 42px; +} +#toolbar3d #cut-tool { + background-image: url('../img/toolbar3d/btnCut.png'); + background-size: 43px auto; + width: 43px; + height: 41px; +} +#toolbar3d #stamp-tool { + background-image: url('../img/toolbar3d/btnStamp.png'); + background-size: 43px auto; + width: 40px; + height: 42px; +} + +/* 3D toolbar tools SELECTED */ +#toolbar3d #height-tool.selected { + background-image: url('../img/toolbar3d/btnExtrudeSelect.png'); +} +#toolbar3d #sculpt-tool.selected { + background-image: url('../img/toolbar3d/btnSculptSelect.png'); +} +#toolbar3d #twist-tool.selected { + background-image: url('../img/toolbar3d/btnTwistSelect.png'); +} +#toolbar3d #cut-tool.selected { + background-image: url('../img/toolbar3d/btnCutSelect.png'); +} +#toolbar3d #stamp-tool.selected { + background-image: url('../img/toolbar3d/btnStampSelect.png'); +} + +@media (max-width: 900px) { + #toolbar3d { + background-image: none; + background-color: white; + height: 60px; + } + + #toolbar3d>.menuitem>.button, + #toolbar3d>.submenu>.button { + padding: 10px 25px 0 25px; + } +} + +@media (max-width: 720px) { + #toolbar3d>.menuitem>.button, + #toolbar3d>.submenu>.button { + padding: 10px 25px 0 25px; + } +} +@media (max-width: 620px) { + #toolbar3d>.menuitem>.button, + #toolbar3d>.submenu>.button { + padding: 10px 10px 0 10px; + } +} +#context { + background: #fff; + border: 4px solid #000; + border-radius: 1rem; +} +#context .submenu { + position: relative; +} +#context .menu { + z-index: 1; + position: absolute; + top: 50px; + /* Using transform to center submenu + Needed because some browser don't support flex-box's changed behaivior: + https://developers.google.com/web/updates/2016/06/absolute-positioned-children + Can't use the bottom toolbar's positioning system + because this submenu needs to be in line with the flex direction */ + left: 50%; + transform: translateX(-50%); +} +#context .button { + padding: 0.5rem 0.5rem 0.5rem 0.5rem; + + background-repeat: no-repeat; + background-position: center; +} +#context #duplicate-tool { + background-image: url('../img/contextmenu/btnDuplicate.png'); + background-size: 33px auto; + height: 41px; +} +#context #delete-tool { + background-image: url('../img/contextmenu/btnDelete.png'); + background-size: 33px auto; + height: 41px; +} +#context #union-tool { + background-image: url('../img/contextmenu/btnGroup.png'); + background-size: 33px auto; + height: 41px; + width: 30px; +} +#context #intersect-tool { + background-image: url('../img/contextmenu/btnCutOut.png'); + background-size: 33px auto; + height: 41px; + width: 30px; +} +#union-tool-menu, #intersect-tool-menu { + background-image: url('../img/contextmenu/btnMore.png'); + background-size: 33px auto; + height: 41px; + width: 30px; +} +#brush-size-small, #brush-size-small-menu, +#eraser-size-small, #eraser-size-small-menu { + background-image: url('../img/contextmenu/btnOutline1.png'); + background-size: 33px auto; + width: 33px; + height: 41px; +} +#brush-size-medium, #brush-size-medium-menu, +#eraser-size-medium, #eraser-size-medium-menu { + background-image: url('../img/contextmenu/btnOutline2.png'); + background-size: 33px auto; + width: 33px; + height: 41px; +} +#brush-size-large, #brush-size-large-menu, +#eraser-size-large, #eraser-size-large-menu { + background-image: url('../img/contextmenu/btnOutline3.png'); + background-size: 33px auto; + width: 33px; + height: 41px; +} +#fill-toggle-fill, #fill-toggle-fill-menu { + background-image: url('../img/contextmenu/btnShapeFill.png'); + background-size: 33px auto; + width: 33px; + height: 41px; +} +#fill-toggle-outline, #fill-toggle-outline-menu { + background-image: url('../img/contextmenu/btnShapeOutline.png'); + background-size: 33px auto; + width: 33px; + height: 41px; +} +#align-right-menu, #align-horizontal-menu, #align-left-menu, +#align-top-menu, #align-vertical-menu, #align-bottom-menu { + background-image: url('../img/contextmenu/btnAlignHorizontal.png'); + background-size: 40px auto; + width: 40px; + height: 40px; +} +#align-left { + background-image: url('../img/contextmenu/btnAlignLeft.png'); + background-size: 40px auto; + width: 40px; + height: 40px; +} +#align-horizontal { + background-image: url('../img/contextmenu/btnAlignHorizontal.png'); + background-size: 40px auto; + width: 40px; + height: 40px; +} +#align-right { + background-image: url('../img/contextmenu/btnAlignRight.png'); + background-size: 40px auto; + width: 40px; + height: 40px; +} +#align-top { + background-image: url('../img/contextmenu/btnAlignTop.png'); + background-size: 40px auto; + width: 40px; + height: 40px; +} +#align-vertical { + background-image: url('../img/contextmenu/btnAlignVertical.png'); + background-size: 40px auto; + width: 40px; + height: 40px; +} +#align-bottom { + background-image: url('../img/contextmenu/btnAlignBottom.png'); + background-size: 40px auto; + width: 40px; + height: 40px; +} +#color-picker-tool .button { + margin: 0.5rem 0.5rem 0.5rem 0.5rem; + padding: 0; + width: 33px; + height: 41px; + overflow: hidden; +} + +#color-picker-tool .menu .button { + width: 30px; + height: 30px; +} + +#color-picker-tool .menu { + width: 185px; + flex-wrap: wrap; +} + +#align-tool .menu { + width: 170px; + flex-wrap: wrap; +} + +#color-light-blue, #color-light-blue-menu { + fill: #c8e4f7; +} +#color-light-green, #color-light-green-menu { + fill: #cbe6c0; +} +#color-light-pink, #color-light-pink-menu { + fill: #f8c4d8; +} +#color-light-yellow, #color-light-yellow-menu { + fill: #f5f5c0; +} +#color-blue, #color-blue-menu { + fill: #92c8ef; +} +#color-green, #color-green-menu { + fill: #99cc81; +} +#color-pink, #color-pink-menu { + fill: #f28bb1; +} +#color-yellow, #color-yellow-menu { + fill: #ebea7f; +} +#color-dark-blue, #color-dark-blue-menu { + fill: #50a8e4; +} +#color-dark-green, #color-dark-green-menu { + fill: #5aae31; +} +#color-dark-pink, #color-dark-pink-menu { + fill: #e94481; +} +#color-dark-yellow, #color-dark-yellow-menu { + fill: #dfde24; +} +/* menu's */ +.menu { + list-style: none; + margin: 0; + padding: 0; + border: none; +} + +.menu .menuitem { + display: block; +} + +.menu .submenu { + display: flex; + /* put menu above button */ + flex-direction: column-reverse; + /* center menu above button */ + align-items: center; + /* overriding width making the submenu's menu doesn't take up space */ + width: 64px; +} + +.menu .submenu .menu { + background-color: #fff; + border: 4px solid #000; + border-radius: 1rem; + display: none; + margin: 0 0 -0.5rem 0; +} +.menu .submenu.open .menu { + display: flex; +} +.menu .submenu .button { + padding: 0.2rem 0.6rem 0.4rem 0.6rem; +} +/* Toolbars */ +.toolbar .button { + background-repeat: no-repeat; + background-position: center; +} +.toolbar .button.disabled { + opacity: 0.5; + cursor: auto; +} + +#sketcher-toolbars .toolbar { + max-width: 100%; + margin-left: auto; + margin-right: auto; + + display: flex; + justify-content: center; + align-items: flex-end; +} +@media (max-width: 930px) { + .menu .submenu { + width: 54px; + } +} +@media (max-width: 790px) { + .menu .submenu { + width: 40px; + } +} +/* 2D toolbar */ +#toolbar2d-container { + position: absolute; + left: 0; + bottom: 0; + width: 50%; +} + +#toolbar2d { + background-image: url('../img/toolbar2d/toolbar2d.png'); + background-size: 493px auto; + background-repeat: no-repeat; + background-position: center; + height: 77px; + width: 493px; +} + +#toolbar2d>.menuitem>.button, +#toolbar2d>.submenu>.button { + /* positioning buttons with padding to increase hit area */ + padding: 25px 15px 0 15px; +} + +#toolbar2d #shape-tools .menu{ + width: 160px; + flex-wrap: wrap; +} +#toolbar2d #bucket-tools .menu{ + width: 220px; + flex-wrap: wrap; +} +/*#toolbar2d #pen-tools { + align-items: flex-start; +}*/ +#toolbar2d #pen-tools .menu { + margin: 0 0 -0.7rem 0; +} + +/* 2D toolbar tools */ +#toolbar2d #transform-tool { + background-image: url('../img/toolbar2d/btnSelect.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #freehand-tool-menu, #toolbar2d #freehand-tool { + background-image: url('../img/toolbar2d/btnDraw.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #polygon-tool-menu, #toolbar2d #polygon-tool { + background-image: url('../img/toolbar2d/btnPolygon.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #brush-tool-menu, #toolbar2d #brush-tool { + background-image: url('../img/toolbar2d/btnBrush.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #eraser-tool { + background-image: url('../img/toolbar2d/btnEraser.png'); + background-size: 45px auto; + width: 44px; + height: 45px; +} +#toolbar2d #text-tool { + background-image: url('../img/toolbar2d/btnText.png'); + background-size: 35px auto; + width: 37px; + height: 35px; +} +#toolbar2d #photo-guide-tool { + background-size: 45px auto; + width: 50px; + height: 34px; + background-image: url('../img/toolbar2d/btnPhoto.png'); +} +/* 2D toolbar shape submenu tools */ +#toolbar2d #star-tool-menu, #toolbar2d #star-tool { + background-image: url('../img/toolbar2d/shapes/btnShapeStar.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #circle-tool-menu, #toolbar2d #circle-tool { + background-image: url('../img/toolbar2d/shapes/btnShapeCircle.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #poly-point-tool-menu, #toolbar2d #poly-point-tool { + background-image: url('../img/toolbar2d/shapes/btnShapeHex.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #heart-tool-menu, #toolbar2d #heart-tool { + background-image: url('../img/toolbar2d/shapes/btnShapeHeart.png'); + background-size: 42px auto; + width: 42px; + height: 41px; +} +#toolbar2d #circle-segment-tool-menu, #toolbar2d #circle-segment-tool { + background-image: url('../img/toolbar2d/shapes/btnShapeCircleSegment.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #rect-tool-menu, #toolbar2d #rect-tool { + background-image: url('../img/toolbar2d/shapes/btnShapeRect.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #triangle-tool-menu, #toolbar2d #triangle-tool { + background-image: url('../img/toolbar2d/shapes/btnShapeTriangle.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} +#toolbar2d #bucket-tool-menu, #toolbar2d #bucket-tool { + background-image: url('../img/toolbar2d/btnBucket.png'); + background-size: 34px auto; + width: 34px; + height: 41px; +} + +/* 2D toolbar tools SELECTED */ +#toolbar2d #transform-tool.selected { + background-image: url('../img/toolbar2d/btnSelectSelect.png'); +} +#toolbar2d #freehand-tool-menu.selected, #toolbar2d #freehand-tool.selected { + background-image: url('../img/toolbar2d/btnDrawSelect.png'); +} +#toolbar2d #polygon-tool-menu.selected, #toolbar2d #polygon-tool.selected { + background-image: url('../img/toolbar2d/btnPolygonSelect.png'); +} +#toolbar2d #brush-tool-menu.selected, #toolbar2d #brush-tool.selected { + background-image: url('../img/toolbar2d/btnBrushSelect.png'); +} +#toolbar2d #eraser-tool.selected { + background-image: url('../img/toolbar2d/btnEraserSelect.png'); +} +#toolbar2d #text-tool.selected { + background-image: url('../img/toolbar2d/btnTextSelect.png'); +} +#toolbar2d #photo-guide-tool.selected { + background-image: url('../img/toolbar2d/btnPhotoSelect.png'); +} +/* 2D toolbar shape submenu tools SELECTED */ +#toolbar2d #star-tool-menu.selected, #toolbar2d #star-tool.selected { + background-image: url('../img/toolbar2d/shapes/btnShapeStarSelect.png'); +} +#toolbar2d #circle-tool-menu.selected, #toolbar2d #circle-tool.selected { + background-image: url('../img/toolbar2d/shapes/btnShapeCircleSelect.png'); +} +#toolbar2d #circle-segment-tool-menu.selected, #toolbar2d #circle-segment-tool.selected { + background-image: url('../img/toolbar2d/shapes/btnShapeCircleSegmentSelect.png'); +} +#toolbar2d #rect-tool-menu.selected, #toolbar2d #rect-tool.selected { + background-image: url('../img/toolbar2d/shapes/btnShapeRectSelect.png'); +} +#toolbar2d #triangle-tool-menu.selected, #toolbar2d #triangle-tool.selected { + background-image: url('../img/toolbar2d/shapes/btnShapeTriangleSelect.png'); +} +#toolbar2d #poly-point-tool-menu.selected, #toolbar2d #poly-point-tool.selected { + background-image: url('../img/toolbar2d/shapes/btnShapeHexSelect.png'); +} +#toolbar2d #heart-tool-menu.selected, #toolbar2d #heart-tool.selected { + background-image: url('../img/toolbar2d/shapes/btnShapeHeartSelect.png'); +} +#toolbar2d #bucket-tool-menu.selected, #toolbar2d #bucket-tool.selected { + background-image: url('../img/toolbar2d/btnBucketSelect.png'); +} + +@media (max-width: 930px) { + #toolbar2d>.menuitem>.button, + #toolbar2d>.submenu>.button { + padding: 25px 10px 0 10px; + } +} +@media (max-width: 900px) { + #toolbar2d { + background-image: none; + background-color: white; + height: 60px; + } + + #toolbar2d>.menuitem>.button, + #toolbar2d>.submenu>.button { + padding: 25px 0px 0 0px; + } +} + +/*#submenu-shape { + display: none; + position: absolute; + bottom: 55px; + width: 181px; + height: 200px; + padding-left: 18px; + padding-top: 25px; + /*border: 1px solid red;*/ + /*background-color: white; + background-image: url('../img/toolbar2d/shapeMenuBackground.png'); + background-repeat: no-repeat; + background-position: center; + background-size: 181px auto;*/ +/*}*/ + +/*#submenu-shape div { + display: inline-block; +} + +#submenu-shape img { + width: 45px; + height: 45px; +} + +#btnShapeMenuMini { + position: absolute; + margin-left: -310px; + display: inline-block; +} + +#btnShapeMenuMini img { + width: 67px; + height: 33px; +} + +#submenu-shape #skewed-rect-tool { + display: none; +}*/ +`; +document.body.append(style); + export default connect(getMenus)(SketcherToolbars); diff --git a/src/components/SubMenu.js b/src/components/SubMenu.js new file mode 100644 index 0000000..5d4cfdf --- /dev/null +++ b/src/components/SubMenu.js @@ -0,0 +1,91 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Button from './Button.js'; +import Menu from './Menu.js'; +import bowser from 'bowser'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:ui:submenu'); + +export default class SubMenu extends React.Component { + static propTypes = { + onSelect: PropTypes.func, + onOpen: PropTypes.func, + onClose: PropTypes.func, + selected: PropTypes.bool, + open: PropTypes.bool, + selectedValue: PropTypes.string, + id: PropTypes.string, + value: PropTypes.string, + svg: PropTypes.string, + children: PropTypes.node, + selectOnOpen: PropTypes.bool, + toggleBehavior: PropTypes.bool + }; + componentWillMount = () => { + // Listeners to close the submenu when anywhere else is clicked + document.addEventListener('click', this.onDocumentClick); + // NOTE for some reason I couldn't pick up a background click from our 2D/3D panel. + document.addEventListener('touchstart', this.onDocumentTouch); + }; + componentWillUnmount = () => { + document.removeEventListener('click', this.onDocumentClick); + document.removeEventListener('touchstart', this.onDocumentTouch); + }; + onSelect = (event) => { + const { onSelect, onOpen, selectOnOpen, toggleBehavior, children } = this.props; + + let { value } = event; + if (toggleBehavior) { + const index = (children.findIndex(({ key }) => key === value) + 1) % children.length; + value = children[index].key; + } + if (onSelect && selectOnOpen) onSelect({ value }); + + // add menu value when it's not already defined by a submenu + const { menuValue = this.props.value } = event; + if (onOpen && !toggleBehavior) onOpen({ menuValue }); + }; + onSubSelect = (event) => { + const { onSelect, onClose, value } = this.props; + if (onSelect) onSelect(event); + if (onClose) onClose({ menuValue: value }); + }; + onDocumentTouch = (event) => { + document.removeEventListener('click', this.onDocumentClick); + this.onDocumentClick(event); + }; + onDocumentClick = (event) => { + const { open, onClose, value } = this.props; + if (open && onClose) { + // was click on this submenu? + const onSubmenu = this.refs.li.contains(event.target); + // debug(`onDocumentClick ${event.type} ${onSubmenu ? 'onSubmenu' : ''}`); + if (!onSubmenu) onClose({ menuValue: value }); + } + }; + render() { + const { id, value, selected, open, selectedValue, children, svg, toggleBehavior } = this.props; + + let className = 'submenu'; + if (open) className += ' open'; + return ( +
  • +
  • + ); + } +} diff --git a/src/d2/EraserPointer.js b/src/d2/EraserPointer.js new file mode 100644 index 0000000..57a1fd8 --- /dev/null +++ b/src/d2/EraserPointer.js @@ -0,0 +1,56 @@ +import { Vector } from 'cal'; +import transposeEvents from '../utils/transposeEvents.js'; +import { PIXEL_RATIO } from '../constants/general.js'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:design:EraserPointer'); + +export default class EraserPointer { + constructor() { + this.visible = true; + this.active = true; + this.depth = 20000; + + this.radius = 0; + this.mousePosition = new Vector(); + this.erasing = false; + this.showMouse = false; + } + onEvent = transposeEvents; + dragStart({ position }) { + this.erasing = true; + this.mousePosition.copy(position); + if (this.onChanged) this.onChanged(); + } + dragEnd() { + this.erasing = false; + if (this.onChanged) this.onChanged(); + } + pointerMove(event) { + this.showMouse = event.pointerType === 'mouse'; + if (this.erasing || this.showMouse) { + this.mousePosition.set(event.clientX, event.clientY); + if (this.onChanged) this.onChanged(); + } + } + pointerOut() { + this.showMouse = false; + if (this.onChanged) this.onChanged(); + } + draw(context) { + if (!this.erasing && !this.showMouse) return; + + const x = this.mousePosition.x * PIXEL_RATIO; + const y = this.mousePosition.y * PIXEL_RATIO; + const radius = this.radius * PIXEL_RATIO; + const color = '#72bcd4'; + const alpha = this.erasing ? 1.0 : 0.25; + const lineWidth = 2.0 * PIXEL_RATIO; + + context.strokeStyle = color; + context.globalAlpha = alpha; + context.lineWidth = lineWidth; + context.beginPath(); + context.arc(x, y, radius, 0, Math.PI * 2.0); + context.stroke(); + } +} diff --git a/src/d2/EventGroup.js b/src/d2/EventGroup.js new file mode 100644 index 0000000..7779e08 --- /dev/null +++ b/src/d2/EventGroup.js @@ -0,0 +1,101 @@ +import { Group, Utils } from 'cal'; +import createListener from 'touch-events'; +import bowser from 'bowser'; +import { convertEvent, isMouseEvent } from '../utils/pointerUtils.js'; + +const events = [ + 'wheel', 'tap', + 'dragstart', 'drag', 'dragend', + 'seconddragstart', 'seconddrag', 'seconddragend', + 'multitouchstart', 'multitouch', 'multitouchend', + 'pointerdown', 'pointermove', 'pointerup', 'pointerout', 'pointerover', 'pointerleave', 'pointercancel' +]; + +export default class EventGroup extends Group { + _addEventsListeners() { + // need to add timeout because this.convert event is not defined for some reason + setTimeout(() => { + for (let i = 0; i < events.length; i ++) { + const eventType = events[i]; + this._eventDispatcher.addEventListener(eventType, this.convertEvent); + } + this.image.addEventListener('contextmenu', this.contextMenu); + }); + } + _removeEventListeners() { + for (let i = 0; i < events.length; i ++) { + const eventType = events[i]; + this._eventDispatcher.removeEventListener(eventType, this.convertEvent); + } + this.image.removeEventListener('contextmenu', this.contextMenu); + } + contextMenu(event) { + event.preventDefault(); + } + convertEvent = (event) => { + if (bowser.ios && isMouseEvent(event)) return; + + switch (event.type) { + case 'pointerdown': + case 'pointermove': + case 'pointerup': + case 'pointerover': + case 'pointerout': + case 'pointerleave': + case 'pointercancel': + this.onEvent(event); + break; + + case 'wheel': + case 'tap': + case 'dragstart': + case 'drag': + case 'dragend': + case 'seconddragstart': + case 'seconddrag': + case 'seconddragend': + case 'multitouchstart': + case 'multitouch': + case 'multitouchend': { + const gestureEvent = { type: event.type }; + + const _convertEvent = convertEvent.bind(null, this.image); + + if (event.event) gestureEvent.position = _convertEvent(event.event); + if (event.events) gestureEvent.positions = event.events.map(_convertEvent); + if (event.preEvents) gestureEvent.preDrags = event.preEvents.map(_convertEvent); + if (event.event && event.event.deltaY !== undefined) gestureEvent.wheelDelta = event.event.deltaY; + + this.onEvent(gestureEvent); + } + + default: + break; + } + }; + onEvent(event) { + const objects = Utils.cloneArray(this.objects); + + for (let i = objects.length - 1; i >= 0; i --) { + const object = objects[i]; + if (object.active && object.onEvent !== undefined) { + if (object.onEvent(event, this)) break; + } + } + } + setCanvas(canvas) { + if (this.useCanvas && this.image instanceof Node) { + this._removeEventListeners(); + } + + super.setCanvas(canvas); + + this._eventDispatcher = createListener(canvas); + + if (this.useCanvas) { + this._addEventsListeners(); + } + + return this; + } +} diff --git a/src/d2/Grid.js b/src/d2/Grid.js new file mode 100644 index 0000000..6fb7f9d --- /dev/null +++ b/src/d2/Grid.js @@ -0,0 +1,59 @@ +import { Color, Vector } from 'cal'; +import { CANVAS_SIZE, GRID_SIZE } from '../constants/d2Constants'; +import { PIXEL_RATIO } from '../constants/general.js'; + +export default class Grid { + constructor(color = new Color(0xeeeeee), widthCenter = 2, widthNormal = 1) { + this.active = false; + this.visible = true; + this.depth = -10000; + + this.color = color; + this.widthCenter = widthCenter; + this.widthNormal = widthNormal; + } + + draw(context, matrix) { + context.save(); + context.lineCap = 'butt'; + context.lineJoin = 'bevel'; + context.globalAlpha = 1; + context.strokeStyle = this.color.setStroke(context); + + context.beginPath(); + + for (let x = -CANVAS_SIZE; x <= CANVAS_SIZE; x += GRID_SIZE) { + const startLineA = new Vector(x, -CANVAS_SIZE).applyMatrix(matrix); + const endLineA = new Vector(x, CANVAS_SIZE).applyMatrix(matrix); + + const startLineB = new Vector(-CANVAS_SIZE, x).applyMatrix(matrix); + const endLineB = new Vector(CANVAS_SIZE, x).applyMatrix(matrix); + + context.moveTo(startLineA.x, startLineA.y); + context.lineTo(endLineA.x, endLineA.y); + + context.moveTo(startLineB.x, startLineB.y); + context.lineTo(endLineB.x, endLineB.y); + } + context.lineWidth = this.widthNormal * this.parent.sx * PIXEL_RATIO; + context.stroke(); + + const startLineVertical = new Vector(0, -CANVAS_SIZE).applyMatrix(matrix); + const endLineVertical = new Vector(0, CANVAS_SIZE).applyMatrix(matrix); + + const startLineHorizontal = new Vector(-CANVAS_SIZE, 0).applyMatrix(matrix); + const endLineHorizontal = new Vector(CANVAS_SIZE, 0).applyMatrix(matrix); + + context.beginPath(); + + context.moveTo(startLineVertical.x, startLineVertical.y); + context.lineTo(endLineVertical.x, endLineVertical.y); + + context.moveTo(startLineHorizontal.x, startLineHorizontal.y); + context.lineTo(endLineHorizontal.x, endLineHorizontal.y); + + context.lineWidth = this.widthCenter * this.parent.sx * PIXEL_RATIO; + + context.stroke(); + } +} diff --git a/src/d2/ShapesManager.js b/src/d2/ShapesManager.js new file mode 100644 index 0000000..dfd100e --- /dev/null +++ b/src/d2/ShapesManager.js @@ -0,0 +1,127 @@ +import { shapeDataToShape } from '../shape/shapeDataUtils.js'; +// import R from 'ramda'; + +export default class ShapesManager { + constructor(objectContainerActive, objectContainerInactive) { + this.objectContainerActive = objectContainerActive; + this.objectContainerInactive = objectContainerInactive; + + this._shapes = {}; + this._activeObjectUIDs = []; + this._inactiveObjectUIDs = []; + } + // activeShapes is an array with object id's that are active + update(state) { + const needRender = { active: false, inactive: false }; + + const selectedObjects = state.selection.objects.map(({ id }) => id); + // determine if shape is "active", meaning it will be updated frequently + const activeShapes = Object.keys(state.objectsById) + .filter(id => state.d2.activeShape === id || selectedObjects.indexOf(id) !== -1); + + const { objectsById } = state; + + if ( + this._objectsById === objectsById && + true && + state.activeSpace === this._activeSpace + ) { + return needRender; + } + + // object ids that are in the current space + const spaceObjectIds = state.spaces[state.activeSpace].objectIds; + + // remove shapes + if (this._objectsById !== undefined) { + for (const id in this._objectsById) { + if (spaceObjectIds.indexOf(id) === -1) { + this._handleShapeRemove(id, needRender); + } + } + } + + const newActiveObjectUIDs = []; + const newInactiveObjectUIDs = []; + + for (const UID of spaceObjectIds) { + const active = activeShapes.indexOf(UID) !== -1; + if (active) { + newActiveObjectUIDs.push(UID); + } else { + newInactiveObjectUIDs.push(UID); + } + + const shapeData = objectsById[UID]; + const shape = this._shapes[shapeData.UID] || this._createShape(shapeData); + + // Put shapes into the right container; active or inactive + if (!active && this._activeObjectUIDs.indexOf(UID) !== -1) { + this.objectContainerActive.remove(shape); + needRender.active = true; + } else if (active && this._inactiveObjectUIDs.indexOf(UID) !== -1) { + this.objectContainerInactive.remove(shape); + needRender.inactive = true; + } + + if (!active && this._inactiveObjectUIDs.indexOf(UID) === -1) { + this.objectContainerInactive.add(shape); + needRender.inactive = true; + } else if (active && this._activeObjectUIDs.indexOf(UID) === -1) { + this.objectContainerActive.add(shape); + needRender.active = true; + } + + // update shape properties + if (!this._objectsById || !this._objectsById[UID]) continue; + + const update = shape.update(shapeData); + if (update) { + if (active) needRender.active = true; + else needRender.inactive = true; + } + } + + this._activeObjectUIDs = newActiveObjectUIDs; + this._inactiveObjectUIDs = newInactiveObjectUIDs; + + this._objectsById = objectsById; + this._activeShapes = activeShapes; + this._activeSpace = state.activeSpace; + return needRender; + } + + updateTransparent(selectedUIDs) { + for (const UID in this._shapes) { + const shape = this._shapes[UID]; + const selected = selectedUIDs.indexOf(UID) !== -1; + const opaque = selected || selectedUIDs.length === 0; + + shape.setOpaque(opaque); + } + } + + _handleShapeRemove(UID, needRender) { + const shape = this._shapes[UID]; + delete this._shapes[UID]; + + // check which container + const active = this._activeObjectUIDs.indexOf(UID) !== -1; + + if (active) { + this.objectContainerActive.remove(shape); + needRender.active = true; + } else { + this.objectContainerInactive.remove(shape); + needRender.inactive = true; + } + } + + _createShape(shapeData) { + const shape = shapeDataToShape(shapeData); + + this._shapes[shapeData.UID] = shape; + + return shape; + } +} diff --git a/src/d2/TolerancePointer.js b/src/d2/TolerancePointer.js new file mode 100644 index 0000000..637bceb --- /dev/null +++ b/src/d2/TolerancePointer.js @@ -0,0 +1,31 @@ +import { Vector } from 'cal'; +import { PIXEL_RATIO } from '../constants/general.js'; + +export default class TolerancePointer { + constructor() { + this.visible = false; + this.active = true; + this.depth = 0; + + this.start = new Vector(); + this.position = new Vector(); + } + update(trace) { + this.start.copy(trace.start); + this.position.copy(trace.position); + } + draw(context) { + context.strokeStyle = '#000000'; + context.lineWidth = 2.0 * PIXEL_RATIO; + + const start = this.start.scale(PIXEL_RATIO); + const position = this.position.scale(PIXEL_RATIO); + + context.beginPath(); + context.arc(start.x, start.y, 20.0 * PIXEL_RATIO, 0, Math.PI * 2.0, true); + + context.moveTo(start.x, start.y); + context.lineTo(position.x, position.y); + context.stroke(); + } +} diff --git a/src/d2/texts.js b/src/d2/texts.js new file mode 100644 index 0000000..e30fb82 --- /dev/null +++ b/src/d2/texts.js @@ -0,0 +1,13 @@ +import { Text, Color } from 'cal'; + +export const dimensionsText = new Text({ + size: 16, + family: 'monospace', + fill: true, + fillColor: new Color(0x000000), + stroke: true, + strokeWidth: 2, + strokeColor: new Color(0xffffff), + align: 'center', + baseline: 'alphabetic' +}); diff --git a/src/d2/tools/BaseTool.js b/src/d2/tools/BaseTool.js new file mode 100644 index 0000000..66d2530 --- /dev/null +++ b/src/d2/tools/BaseTool.js @@ -0,0 +1,198 @@ +import EventGroup from '../EventGroup.js'; +import * as actions from '../../actions/index.js'; +import transposeEvents from '../../utils/transposeEvents.js'; +import ClipperShape from 'clipper-js'; +import { applyMatrixOnShape } from '../../utils/vectorUtils'; +import { getPointsBounds } from '../../shape/shapeDataUtils'; +import { shapeToPoints } from '../../shape/shapeToPoints'; +import { LINE_COLLISION_MARGIN } from '../../constants/d2Constants'; +import { LINE_WIDTH } from '../../constants/d2Constants'; +import { PIXEL_RATIO } from '../../constants/general'; +import { Matrix } from 'cal'; + +const HIT_ORDER = { + RECT: 0, + TRIANGLE: 0, + STAR: 0, + CIRCLE: 0, + CIRCLE_SEGMENT: 0, + BRUSH: 1, + COMPOUND_PATH: 1, + TEXT: 1, + FREE_HAND: 0, + IMAGE_GUIDE: 2, + POLYGON: 0, + POLY_POINTS: 0, + HEART: 0, + EXPORT_SHAPE: 0 +}; + +export default class BaseTool extends EventGroup { + constructor(dispatch, sceneSpaceContainer, renderRequest) { + super(); + this.active = true; + this.visible = true; + this.depth = 1001; + this.enableHitDetection = false; + + this.dispatch = dispatch; + this.sceneSpaceContainer = sceneSpaceContainer; + this.renderRequest = renderRequest; + } + + dragStart({ position, preDrags, intersections }) { + this._dispatch(actions.d2DragStart, position, preDrags, intersections); + } + drag({ position, previousPosition }) { + this._dispatch(actions.d2Drag, position, previousPosition); + } + dragEnd({ position }) { + this._dispatch(actions.d2DragEnd, position); + } + secondDragStart({ position, preDrags, intersections }) { + this._dispatch(actions.d2SecondDragStart, position, preDrags, intersections); + } + secondDrag({ position, previousPosition }) { + this._dispatch(actions.d2SecondDrag, position, previousPosition); + } + secondDragEnd({ position }) { + this._dispatch(actions.d2DragEnd, position); + } + tap({ position, intersections }) { + this._dispatch(actions.d2Tap, position, intersections); + } + wheel({ position, wheelDelta }) { + this._dispatch(actions.d2MouseWheel, position, wheelDelta); + } + multitouchStart({ positions, preDrags }) { + this._dispatch(actions.d2MultitouchStart, positions, preDrags); + } + multitouch({ positions, previousPositions }) { + this._dispatch(actions.d2Multitouch, positions, previousPositions); + } + multitouchEnd({ positions }) { + this._dispatch(actions.d2MultitouchEnd, positions); + } + + onEvent(event) { + switch (event.type) { + case 'dragstart': + this._previousPosition = event.position; + break; + + case 'drag': + event.previousPosition = this._previousPosition; + this._previousPosition = event.position; + break; + + case 'seconddragstart': + this._previousSecondPosition = event.position; + break; + + case 'seconddrag': + event.previousPosition = this._previousSecondPosition; + this._previousSecondPosition = event.position; + break; + + case 'multitouchstart': + this._previousMultitouchPositions = event.positions; + break; + + case 'multitouch': + event.previousPositions = this._previousMultitouchPositions; + this._previousMultitouchPositions = event.positions; + break; + + default: + break; + } + + event.intersections = []; + if (this.enableHitDetection) { + if (event.type === 'tap' || event.type === 'dragstart' || event.type === 'seconddragstart') { + event.intersections = this.findHit(event.position); + } + } + + transposeEvents.call(this, event); + super.onEvent(event); + } + + findHit(position) { + if (!this.enableHitDetection) return []; + + const pixelRatioNormalizer = new Matrix(); + pixelRatioNormalizer.scale = 1 / PIXEL_RATIO; + + const matrix = this.parent.getScreenMatrix().multiplyMatrix(pixelRatioNormalizer); + + const shapeDatas = this.space.objectIds.map(id => this.objectsById[id]); + const margin = LINE_COLLISION_MARGIN + this.parent.parent.sx * LINE_WIDTH; + + const objects = shapeDatas + .filter(shapeData => { + const shapeMatrix = shapeData.transform.multiplyMatrix(matrix); + + const isHit = shapeToPoints(shapeData) + .some(({ points, holes }) => { + const shape = applyMatrixOnShape([points, ...holes], shapeMatrix); + const clipperShape = new ClipperShape(shape, shapeData.fill, true, true); + + if (shapeData.fill) { + return clipperShape + .fixOrientation() + .pointInShape(position, true, true); + } else { + return clipperShape + .offset(margin, { joinType: 'jtSquare', endType: 'etOpenButt' }) + .seperateShapes() + .some(_clipperShape => _clipperShape.pointInShape(position, true, true)); + } + }); + + return isHit; + }) + .sort((shapeDataA, shapeDataB) => { + const hitOrderA = HIT_ORDER[shapeDataA.type]; + const hitOrderB = HIT_ORDER[shapeDataB.type]; + + if (hitOrderA === hitOrderB) { + const { min: minA, max: maxA } = getPointsBounds(shapeToPoints(shapeDataA), shapeDataA.transform); + const sizeA = (maxA.x - minA.x) * (maxA.y - minA.y); + const { min: minB, max: maxB } = getPointsBounds(shapeToPoints(shapeDataB), shapeDataB.transform); + const sizeB = (maxB.x - minB.x) * (maxB.y - minB.y); + + return sizeA - sizeB; + } else { + return hitOrderA - hitOrderB; + } + }) + .map(({ UID }) => UID); + + return objects; + } + + _dispatch(action, ...args) { + // TODO could be optimized + + const pixelRatioNormalizer = new Matrix(); + pixelRatioNormalizer.scale = 1 / PIXEL_RATIO; + + const screenMatrixContainer = this.sceneSpaceContainer + .getScreenMatrix() + .multiplyMatrix(pixelRatioNormalizer); + + const screenMatrixZoom = this + .getScreenMatrix() + .multiplyMatrix(pixelRatioNormalizer); + + this.dispatch(action(...args, screenMatrixContainer, screenMatrixZoom)); + } + + update(newState) { + // Needed for hit detection: + this.objectsById = newState.objectsById; + this.space = newState.spaces[newState.activeSpace]; + } + destroy() {} +} diff --git a/src/d2/tools/BrushTool.js b/src/d2/tools/BrushTool.js new file mode 100644 index 0000000..9cbfe72 --- /dev/null +++ b/src/d2/tools/BrushTool.js @@ -0,0 +1,51 @@ +import BaseTool from './BaseTool.js'; +import { Vector } from 'cal'; +import { PIXEL_RATIO } from '../../constants/general.js'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:2d:tool:eraser'); +export default class BrushTool extends BaseTool { + constructor(dispatch, sceneSpaceContainer, renderRequest) { + super(dispatch, sceneSpaceContainer, renderRequest); + + this.mousePosition = new Vector(); + this.radius = null; + this.showMouse = false; + } + pointerMove(event) { + this.showMouse = event.pointerType === 'mouse'; + if (this.showMouse) { + this.mousePosition.set(event.clientX, event.clientY); + this.renderRequest(); + } + } + pointerOut() { + this.showMouse = false; + this.renderRequest(); + } + update(state) { + const eraserState = state.d2.brush; + if (this.radius !== eraserState.size) { + this.radius = eraserState.size; + return true; + } + return false; + } + draw(context) { + if (!this.showMouse) return; + + const x = this.mousePosition.x * PIXEL_RATIO; + const y = this.mousePosition.y * PIXEL_RATIO; + // not really happy with this.parent.sx * this.parent.parent.sx; + const radius = this.radius * PIXEL_RATIO * this.parent.sx * this.parent.parent.sx; + const color = '#72bcd4'; + const alpha = this.erasing ? 1.0 : 0.25; + const lineWidth = 2.0 * PIXEL_RATIO; + + context.strokeStyle = color; + context.globalAlpha = alpha; + context.lineWidth = lineWidth; + context.beginPath(); + context.arc(x, y, radius, 0, Math.PI * 2.0); + context.stroke(); + } +} diff --git a/src/d2/tools/BucketTool.js b/src/d2/tools/BucketTool.js new file mode 100644 index 0000000..75a8a99 --- /dev/null +++ b/src/d2/tools/BucketTool.js @@ -0,0 +1,8 @@ +import BaseTool from './BaseTool.js'; + +export default class BucketTool extends BaseTool { + constructor(dispatch, sceneSpaceContainer) { + super(dispatch, sceneSpaceContainer); + this.enableHitDetection = true; + } +} diff --git a/src/d2/tools/CircleTool.js b/src/d2/tools/CircleTool.js new file mode 100644 index 0000000..423d451 --- /dev/null +++ b/src/d2/tools/CircleTool.js @@ -0,0 +1,51 @@ +import { Vector } from 'cal'; +import BaseTool from './BaseTool.js'; +import * as humanReadable from '../../utils/humanReadable.js'; +import { dimensionsText } from '../texts.js'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:2d:tool:circle'); + +export default class PolygonTool extends BaseTool { + constructor(dispatch, sceneSpaceContainer, renderRequest) { + super(dispatch, sceneSpaceContainer, renderRequest); + + this.drawRuler = false; + this.rulerLength = 0; + this.rulerPosition = new Vector(); + } + update(state) { + const activeShape = state.d2.activeShape && state.objectsById[state.d2.activeShape]; + if (activeShape) { + this.drawRuler = true; + + this.rulerPosition.copy(new Vector().applyMatrix(activeShape.transform)); + this.rulerLength = activeShape.circle.radius; + + return true; + } else if (this.drawRuler) { + this.drawRuler = false; + + return true; + } + return false; + } + draw(context, matrix) { + if (this.drawRuler) { + context.beginPath(); + + const rulerStart = this.rulerPosition.applyMatrix(matrix); + const rulerEnd = this.rulerPosition.add(new Vector(this.rulerLength, 0)).applyMatrix(matrix); + + context.moveTo(rulerStart.x, rulerStart.y); + context.lineTo(rulerEnd.x, rulerEnd.y); + + context.lineWidth = 2; + context.strokeStyle = '#333'; + context.stroke(); + + const rulerPosition = rulerStart.add(rulerEnd).scale(0.5).add(new Vector(0, -5)); + const text = humanReadable.distance(this.rulerLength); + dimensionsText.drawText(context, text, rulerPosition.x, rulerPosition.y); + } + } +} diff --git a/src/d2/tools/EraserTool.js b/src/d2/tools/EraserTool.js new file mode 100644 index 0000000..a08f03e --- /dev/null +++ b/src/d2/tools/EraserTool.js @@ -0,0 +1,23 @@ +import BaseTool from './BaseTool.js'; +import EraserPointer from '../EraserPointer.js'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:2d:tool:eraser'); +export default class EraseTool extends BaseTool { + constructor(dispatch, sceneSpaceContainer, renderRequest) { + super(dispatch, sceneSpaceContainer, renderRequest); + + this.pointer = new EraserPointer(); + this.pointer.onChanged = renderRequest; + this.add(this.pointer); + } + update(state) { + const eraserState = state.d2.eraser; + if (!this._state || this._state !== eraserState) { + this.pointer.radius = eraserState.size; + + this._state = eraserState; + return true; + } + return false; + } +} diff --git a/src/d2/tools/PhotoGuideTool.js b/src/d2/tools/PhotoGuideTool.js new file mode 100644 index 0000000..c31f8c3 --- /dev/null +++ b/src/d2/tools/PhotoGuideTool.js @@ -0,0 +1,109 @@ +import BaseTool from './BaseTool.js'; +import * as CAL from 'cal'; +import TolerancePointer from '../TolerancePointer.js'; +import * as actions from '../../actions/index.js'; +import { calculateTolerance } from '../../utils/traceUtils'; +import { MAX_TRACE_TOLERANCE } from '../../constants/d2Constants'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:tool:photoguide'); + +export default class PhotoGuideTool extends BaseTool { + constructor(dispatch, sceneSpaceContainer, renderRequest) { + super(dispatch, sceneSpaceContainer, renderRequest); + this.enableHitDetection = true; + + this.preview = new CAL.Surface(); + this.preview.visible = false; + + this.maxToleranceView = new CAL.Surface(); + this.maxToleranceView.visible = false; + + this.tolerancePointer = new TolerancePointer(); + + this.start = new CAL.Vector(); + + this.add(this.maxToleranceView, this.preview, this.tolerancePointer); + } + + dragStart(event) { + this.start.copy(event.position); + this.intersectionId = event.intersections.find(id => this.state.objectsById[id].type === 'IMAGE_GUIDE'); + super.dragStart(event); + } + + drag(event) { + if (this.intersectionId) { + this._dispatch(actions.traceDrag, event.position, this.start, this.intersectionId); + } + super.drag(event); + } + + dragEnd(event) { + this._dispatch(actions.traceDragEnd); + super.dragEnd(event); + } + + tap(event) { + this._dispatch(actions.traceTap, event.position, event.intersections); + super.tap(event); + } + + update(newState) { + let needRender = false; + if (newState === this.state) return needRender; + super.update(newState); + + this.tolerancePointer.visible = newState.d2.trace.active; + + if (!this.state || (this.state && newState.d2.trace !== this.state.d2.trace)) { + const { trace } = newState.d2; + + needRender = true; + + const maxTolerance = calculateTolerance(trace.start, trace.position) > MAX_TRACE_TOLERANCE; + + this.preview.visible = trace.active && !maxTolerance; + this.maxToleranceView.visible = trace.active && maxTolerance; + const UID = newState.d2.activeShape || (this.state ? this.state.d2.activeShape : null); + if (UID && trace.active) { + const shapeData = newState.objectsById[UID]; + const { width, height } = shapeData.imageData; + + if (this.preview.image.width !== width || this.preview.image.height !== height) { + this.preview.centerX = width / 2; + this.preview.centerY = height / 2; + this.preview.setSize(width, height); + } + + this.preview.copyMatrix(shapeData.transform); + + if (this.maxToleranceView.image.width !== width || this.maxToleranceView.image.height !== height) { + this.maxToleranceView.centerX = width / 2; + this.maxToleranceView.centerY = height / 2; + this.maxToleranceView.setSize(width, height); + + this.maxToleranceView.context.fillStyle = 'rgba(255, 0, 0, 0.5)'; + this.maxToleranceView.context.fillRect(0, 0, width, height); + } + + this.maxToleranceView.copyMatrix(shapeData.transform); + + this.tolerancePointer.update(trace); + + if (trace.floodFillData !== this.state.d2.trace.floodFillData) { + const imageData = this.preview.context.createImageData(this.preview.width, this.preview.height); + + // Color red trace line based on edges in flood data from state + for (let i = 0; i < trace.floodFillData.edge.length; i ++) { + const index = trace.floodFillData.edge[i] * 4; + imageData.data[index] = 255; + imageData.data[index + 3] = 255; + } + this.preview.context.putImageData(imageData, 0, 0); + } + } + } + this.state = newState; + return needRender; + } +} diff --git a/src/d2/tools/PolygonTool.js b/src/d2/tools/PolygonTool.js new file mode 100644 index 0000000..ce66b1e --- /dev/null +++ b/src/d2/tools/PolygonTool.js @@ -0,0 +1,81 @@ +import BaseTool from './BaseTool.js'; +import { Vector, Utils } from 'cal'; +import * as humanReadable from '../../utils/humanReadable.js'; +import { dimensionsText } from '../texts.js'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:2d:tool:polygon'); + +export default class PolygonTool extends BaseTool { + constructor(dispatch, sceneSpaceContainer, renderRequest) { + super(dispatch, sceneSpaceContainer, renderRequest); + + this.drawRuler = false; + + this.rulerLength = 0; + this.rulerAngle = 0; + this.rulerPosition = new Vector(); + + // this.anglePosition = new Vector(); + // this.angleDegrees = 0; + } + update(state) { + const activeShape = state.d2.activeShape && state.objectsById[state.d2.activeShape]; + if (activeShape) { + this.drawRuler = true; + + const pointA = activeShape.points[activeShape.points.length - 2]; + const pointB = activeShape.points[activeShape.points.length - 1]; + + this.rulerPosition.copy(pointA.add(pointB).scale(0.5)); + this.rulerLength = pointA.distanceTo(pointB); + this.rulerAngle = pointB + .subtract(pointA) + .scale(Utils.MathExtended.sign(pointB.subtract(pointA).x) || 1) + .angle(); + + // this.anglePosition.copy(pointA); + // this.angleDegrees = (pointB.subtract(pointA).angle() + (Math.PI * 2.0)) % (Math.PI * 2.0); + + return true; + } else if (this.drawRuler) { + this.drawRuler = false; + return true; + } + + return false; + } + draw(context, matrix) { + if (this.drawRuler) { + context.save(); + + const rulerPosition = this.rulerPosition.applyMatrix(matrix); + context.translate(rulerPosition.x, rulerPosition.y); + context.rotate(this.rulerAngle); + + const text = humanReadable.distance(this.rulerLength); + dimensionsText.drawText(context, text, 0, -5); + + context.restore(); + + context.beginPath(); + + // const anglePosition = this.anglePosition.applyMatrix(matrix); + // context.arc(anglePosition.x, anglePosition.y, 20, 0, this.angleDegrees, this.angleDegrees > Math.PI); + // + // context.strokeStyle = 'black'; + // context.lineWidth = 1; + // context.stroke(); + // + // const angleTextPos = new Vector(28, 0) + // .rotate((this.angleDegrees < Math.PI ? this.angleDegrees : this.angleDegrees - Math.PI * 2.0) / 2) + // .add(anglePosition); + // context.textAlign = 'start'; + // context.textBaseline = 'middle'; + // context.fillStyle = '#000'; + // context.font = '10px Arial'; + // + // const angleDegrees = this.angleDegrees < Math.PI ? this.angleDegrees : Math.PI * 2 - this.angleDegrees; + // dimensionsText.drawText(context, humanReadable.degrees(angleDegrees), angleTextPos.x, angleTextPos.y); + } + } +} diff --git a/src/d2/tools/TextTool.js b/src/d2/tools/TextTool.js new file mode 100644 index 0000000..438f19d --- /dev/null +++ b/src/d2/tools/TextTool.js @@ -0,0 +1,19 @@ +import BaseTool from './BaseTool.js'; +import * as actions from '../../actions/index.js'; + +export default class TextTool extends BaseTool { + constructor(dispatch, sceneSpaceContainer, renderRequest) { + super(dispatch, sceneSpaceContainer, renderRequest); + this.enableHitDetection = true; + } + tap({ position, intersections }) { + const textId = intersections.find(id => this.state.objectsById[id].type === 'TEXT'); + + this._dispatch(actions.d2textInit, position, textId); + } + update(state) { + if (state === this.state) return; + super.update(state); + this.state = state; + } +} diff --git a/src/d2/tools/TransformTool.js b/src/d2/tools/TransformTool.js new file mode 100644 index 0000000..04836d8 --- /dev/null +++ b/src/d2/tools/TransformTool.js @@ -0,0 +1,337 @@ +import { Vector, Matrix, Image } from 'cal'; +import { SELECTION_VIEW_MIN_AXIS_SCALE, SELECTION_VIEW_MIN_SCALE } from '../../constants/d2Constants'; +import dottedLineUrl from '../../../img/2d/dotLine01.png'; +import rotateHandleUrl from '../../../img/2d/rotateHandle.png'; +import corner01Url from '../../../img/2d/corner01.png'; +import corner02Url from '../../../img/2d/corner02.png'; +import corner03Url from '../../../img/2d/corner03.png'; +import corner04Url from '../../../img/2d/corner04.png'; +import { PIXEL_RATIO } from '../../constants/general'; +import { getSelectedObjectsSelector, getBoundingBox } from '../../utils/selectionUtils'; +import * as actions from '../../actions/index.js'; +import BaseTool from './BaseTool.js'; +import * as humanReadable from '../../utils/humanReadable.js'; +import { dimensionsText } from '../texts.js'; +import { isNegative } from '../../utils/matrixUtils'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:2d:selection'); + +const dottedLine = new Image(dottedLineUrl, 0, 14).load(() => URL.revokeObjectURL(dottedLineUrl)); +const rotateHandle = new Image(rotateHandleUrl, 27, 30).load(() => URL.revokeObjectURL(rotateHandleUrl)); +const cornerImages = [ + new Image(corner01Url, 35, 35).load(() => URL.revokeObjectURL(corner01Url)), + new Image(corner02Url, 35, 35).load(() => URL.revokeObjectURL(corner02Url)), + new Image(corner03Url, 35, 35).load(() => URL.revokeObjectURL(corner03Url)), + new Image(corner04Url, 35, 35).load(() => URL.revokeObjectURL(corner04Url)) +]; + +export default class TransformTool extends BaseTool { + constructor(dispatch, sceneSpaceContainer) { + super(dispatch, sceneSpaceContainer); + + this.active = true; + this.visible = true; + + this.transform = new Matrix(); + this.position = new Vector(); + + this.enableHitDetection = true; + } + + _findHit(position) { + if (this.numObjects === 0) return 'dragselect'; + + const thresholdDistance = 20.0 * PIXEL_RATIO; + const pixelRatioNormalizer = new Matrix(); + pixelRatioNormalizer.scale = 1 / PIXEL_RATIO; + const screenMatrixZoom = this.parent.getScreenMatrix().multiplyMatrix(pixelRatioNormalizer); + + const { + rotatePos, corners, cornerNames, sides, sideNames, points + } = getHandlePositions(this.boundingBox, this.transform, screenMatrixZoom); + + if (rotatePos.distanceTo(position) < thresholdDistance) return 'rotate'; + + for (let i = 0; i < corners.length; i ++) { + const point = corners[i]; + if (point.distanceTo(position) < thresholdDistance) return cornerNames[i]; + } + + for (let i = 0; i < sides.length; i ++) { + const point = sides[i]; + if (point.distanceTo(position) < thresholdDistance) return sideNames[i]; + } + + // if point is inside bounding box => translate + if (pointInsideConvexPolygon(points, position)) return 'translate'; + + // if position is outside any select handle => dragselect + return 'dragselect'; + } + + dragStart(event) { + const { position, intersections } = event; + let handle = this._findHit(position, intersections); + + if (!handle) { + super.dragStart(event); + return; + } + + if (handle === 'dragselect') { + const [uid] = intersections; + if (uid !== undefined) { + this.dispatch(actions.deselectAll()); + this.dispatch(actions.select(uid)); + handle = 'translate'; + } + } + + this._dispatch(actions.transformStart, handle, position); + + this.position.copy(position); + } + + drag(event) { + if (!this._active) { + super.drag(event); + return; + } + + const { position } = event; + const delta = position.subtract(this.position); + this.position.copy(position); + + this._dispatch(actions.transform, delta, position); + } + + dragEnd(event) { + if (!this._active) { + super.dragEnd(event); + return; + } + + this._dispatch(actions.transformEnd); + } + + multitouchStart(event) { + if (this.numObjects === 0) { + super.multitouchStart(event); + return; + } + + const screenMatrixZoom = this.parent.getScreenMatrix(); + const { points } = getHandlePositions(this.boundingBox, this.transform, screenMatrixZoom); + if (!event.positions.some(position => pointInsideConvexPolygon(points, position))) { + super.multitouchStart(event); + return; + } + + this._dispatch(actions.multitouchTransformStart); + } + + multitouch(event) { + if (!this._active) { + super.multitouch(event); + return; + } + + const { positions, previousPositions } = event; + this._dispatch(actions.multitouchTransform, positions, previousPositions); + } + + multitouchEnd(event) { + if (!this._active) { + super.dragEnd(event); + return; + } + + this._dispatch(actions.multitouchTransformEnd); + } + + tap(event) { + const { intersections } = event; + if (intersections.length === 0) { + this.dispatch(actions.deselectAll()); + } else { + const [id] = intersections; + this.dispatch(actions.toggleSelect(id)); + } + + super.tap(event); + } + + update(state) { + super.update(state); + + let needRender = false; + if (state === this._state) return needRender; + + this._active = state.d2.transform.active; + + const { selection, objectsById, d2: transform } = state; + + if (!this._state || selection !== this._state.selection) { + const selectedShapeDatas = getSelectedObjectsSelector(selection.objects, objectsById); + const boundingBox = getBoundingBox(selectedShapeDatas, selection.transform); + + this.numObjects = selection.objects.length; + this.transform = selection.transform; + this.boundingBox = boundingBox; + + needRender = true; + } + + if (!this._state || transform !== this._state.d2.transform) needRender = true; + + this._state = state; + return needRender; + } + + draw(context, matrix) { + if (this.numObjects !== 0) { + context.globalAlpha = 1.0; + const scale = 0.5 * PIXEL_RATIO; + + const { + rotatePos, corners, sides, points, width, height, widthPosition, heightPosition + } = getHandlePositions(this.boundingBox, this.transform, matrix); + const { rotation } = this.transform; + + const rotateAngle = isNegative(this.transform) ? Math.PI + rotation : rotation; + rotateHandle.drawAngleScale(context, 0, rotatePos.x, rotatePos.y, rotateAngle, scale, scale); + + for (let i = 0; i < points.length; i ++) { + const pointA = points[i]; + const pointB = points[(i + 1) % points.length]; + + const angle = pointB.subtract(pointA).angle(); + + const sx = pointA.distanceTo(pointB) * 2 / PIXEL_RATIO; + const sy = dottedLine.height; + + dottedLine.drawCropAngleScale(context, 0, pointA.x, pointA.y, sx, sy, angle, scale, scale); + } + + for (let i = 0; i < corners.length; i ++) { + const image = cornerImages[i]; + const point = corners[i]; + + image.drawAngleScale(context, 0, point.x, point.y, rotation, scale, scale); + } + + for (let i = 0; i < sides.length; i ++) { + const image = cornerImages[i]; + const point = sides[i]; + + image.drawAngleScale(context, 0, point.x, point.y, rotation, scale, scale); + } + + const textWidth = humanReadable.distance(width); + dimensionsText.drawText(context, textWidth, widthPosition.x, widthPosition.y); + const textHeight = humanReadable.distance(height); + dimensionsText.drawText(context, textHeight, heightPosition.x, heightPosition.y); + } + + if (this._state && this._state.d2.transform.handle === 'dragselect') { + let { start, end } = this._state.d2.transform.dragSelect; + start = start.scale(PIXEL_RATIO); + end = end.scale(PIXEL_RATIO); + + const width = end.x - start.x; + const height = end.y - start.y; + + context.strokeStyle = '#72bcd4'; + context.lineWidth = 1.0 * PIXEL_RATIO; + context.strokeRect(start.x, start.y, width, height); + } + } +} + +const CORNERS = ['lefttop', 'leftbottom', 'rightbottom', 'righttop']; +const SIDES = ['left', 'bottom', 'right', 'top']; + +function getHandlePositions(boundingBox, transform, screenMatrixZoom) { + const matrix = transform.multiplyMatrix(screenMatrixZoom); + const { min, max } = boundingBox; + + const points = [ + new Vector(min.x, min.z), + new Vector(min.x, max.z), + new Vector(max.x, max.z), + new Vector(max.x, min.z) + ].map(point => point.applyMatrix(matrix)); + if (isNegative(transform)) points.reverse(); + + const distanceVertical = points[0].distanceTo(points[1]); + const distanceHorizontal = points[1].distanceTo(points[2]); + + const minAxisScale = PIXEL_RATIO * SELECTION_VIEW_MIN_AXIS_SCALE; + const minViewScale = PIXEL_RATIO * SELECTION_VIEW_MIN_SCALE; + + const drawScaleY = distanceVertical > minAxisScale; + const drawScaleX = distanceHorizontal > minAxisScale; + const drawMinScale = distanceVertical < minViewScale && distanceHorizontal < minViewScale; + + const corners = []; + const cornerNames = []; + for (let i = 0; i < points.length; i ++) { + if (drawMinScale && i !== 2) continue; + + const point = points[i]; + corners.push(point); + + const cornerIndex = isNegative(transform) ? (3 - i) : i; + cornerNames.push(`scale-${CORNERS[cornerIndex]}`); + } + + const sides = []; + const sideNames = []; + for (let i = 0; i < points.length; i ++) { + const pointA = points[i]; + + const isHorizontal = (i + 1) % 2 === 0; + const isVertical = i % 2 === 0; + if (!(drawScaleX && isHorizontal) && !(drawScaleY && isVertical)) continue; + + const pointB = points[(i + 1) % points.length]; + sides.push(pointA.add(pointB).scale(0.5)); + + const cornerIndex = isNegative(transform) ? (6 - i) % 4 : i; + sideNames.push(`scale-${SIDES[cornerIndex]}`); + } + + const center = points[0].add(points[3]).scale(0.5); + const normal = points[3].subtract(points[0]).normal().normalize(); + + const rotatePos = center.add(normal.scale(30 * PIXEL_RATIO)); + + const width = (max.x - min.x) * Math.abs(transform.sx); + const height = (max.z - min.z) * Math.abs(transform.sy); + + const widthPosition = calculateCenterLineOffset(points[1], points[2], -25, -20); + const heightPosition = calculateCenterLineOffset(points[2], points[3], -25, -20); + + return { + rotatePos, corners, cornerNames, sides, sideNames, points, width, height, widthPosition, heightPosition + }; +} + +function calculateCenterLineOffset(a, b, minOffset, additionalOffset) { + const normal = b.subtract(a).normal().normalize(); + const offset = minOffset + Math.abs(normal.dot(new Vector(1, 0))) * additionalOffset; + return a.add(b).scale(0.5).add(normal.scale(offset)); +} + +function pointInsideConvexPolygon(boundingBoxPoints, point) { + for (let i = 1; i <= boundingBoxPoints.length; i ++) { + const pointA = boundingBoxPoints[i - 1]; + const pointB = boundingBoxPoints[i % boundingBoxPoints.length]; + + const normal = pointB.subtract(pointA).normal().normalize(); + + if (point.subtract(pointA).dot(normal) < 0) return false; + } + + return true; +} diff --git a/src/d3/Camera.js b/src/d3/Camera.js new file mode 100644 index 0000000..4f9fa34 --- /dev/null +++ b/src/d3/Camera.js @@ -0,0 +1,9 @@ +import * as THREE from 'three'; + +export default class Camera extends THREE.PerspectiveCamera { + matrixAutoUpdate = false; + + update({ object }) { + this.matrix.copy(object.matrix); + } +} diff --git a/src/d3/EventScene.js b/src/d3/EventScene.js new file mode 100644 index 0000000..9f5414c --- /dev/null +++ b/src/d3/EventScene.js @@ -0,0 +1,78 @@ +import * as THREE from 'three'; +import { Utils } from 'cal'; +import createListener from 'touch-events'; +import bowser from 'bowser'; +import { convertEvent, isMouseEvent } from '../utils/pointerUtils.js'; + +const events = ['wheel', 'tap', 'dragstart', 'drag', 'dragend', 'seconddragstart', 'seconddrag', + 'seconddragend', 'multitouchstart', 'multitouch', 'multitouchend']; + +export class EventScene extends THREE.Scene { + constructor(domElement) { + super(); + + if (domElement) this.setCanvas(domElement); + } + _addEventsListeners() { + for (let i = 0; i < events.length; i ++) { + const eventType = events[i]; + this._eventDispatcher.addEventListener(eventType, this.convertEvent); + } + this._domElement.addEventListener('contextmenu', this.contextMenu); + } + _removeEventListeners() { + for (let i = 0; i < events.length; i ++) { + const eventType = events[i]; + this._eventDispatcher.removeEventListener(eventType, this.convertEvent); + } + this._domElement.removeEventListener('contextmenu', this.contextMenu); + } + contextMenu(event) { + event.preventDefault(); + } + convertEvent = (event) => { + // Prevent delayed click events bubbling through closing menus on iOS #1026 + if (bowser.ios && isMouseEvent(event)) return; + + const gestureEvent = { type: event.type }; + + const _convertEvent = convertEvent.bind(null, this._domElement); + + if (event.event) gestureEvent.position = _convertEvent(event.event); + if (event.events) gestureEvent.positions = event.events.map(_convertEvent); + if (event.preEvents) gestureEvent.preDrags = event.preEvents.map(_convertEvent); + if (event.event && event.event.deltaY !== undefined) gestureEvent.wheelDelta = event.event.deltaY; + + this.onEvent(gestureEvent); + }; + onEvent(event) { + const objects = Utils.cloneArray(this.children); + + for (let i = objects.length - 1; i >= 0; i --) { + const object = objects[i]; + if (object.onEvent && object.onEvent(event, this)) break; + } + } + setCanvas(domElement) { + if (this._eventDispatcher) this._removeEventListeners(); + + this._domElement = domElement; + if (domElement) { + this._eventDispatcher = createListener(domElement); + this._addEventsListeners(); + } + + return this; + } +} + +export class EventObject3D extends THREE.Object3D { + onEvent(event) { + const objects = Utils.cloneArray(this.children); + + for (let i = objects.length - 1; i >= 0; i --) { + const object = objects[i]; + if (object.onEvent && object.onEvent(event, this)) break; + } + } +} diff --git a/src/d3/SelectionBox.js b/src/d3/SelectionBox.js new file mode 100644 index 0000000..422153b --- /dev/null +++ b/src/d3/SelectionBox.js @@ -0,0 +1,67 @@ +import * as THREE from 'three'; +import { Vector } from 'cal'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:preview:selectionBox'); + + +export default class SelectionBox extends THREE.Object3D { + matrixAutoUpdate = false; + + constructor() { + super(); + + this._box = new THREE.BoxHelper(); + + this._box.material.color.setHex(0x72bcd4); + this._box.name = 'bounding-box'; + + const material = new THREE.MeshBasicMaterial(); + const geometry = new THREE.BoxGeometry(1, 1, 1); + + const matrix = new THREE.Matrix4(); + matrix.setPosition(new THREE.Vector3(0.5, 0.5, 0.5)); + geometry.applyMatrix(matrix); + + const mesh = new THREE.Mesh(geometry, material); + + this._box.update(mesh); + + this.add(this._box); + } + updateBoundingBox(boundingBox) { + if (this._boundingBox === boundingBox) { + return; + } + this._boundingBox = boundingBox; + + this.update(); + } + + updateTransform(transform) { + if (this._transform === transform) { + return; + } + + this._transform = transform; + + this.update(); + } + + update() { + if (!this.visible || this._transform === undefined || this._boundingBox === undefined) { + return; + } + + let min = new Vector(this._boundingBox.min.x, this._boundingBox.min.z); + min = min.applyMatrix(this._transform); + + this._box.rotation.y = -this._transform.rotation; + this._box.position.x = min.x; + this._box.position.z = min.y; + this._box.scale.x = (this._boundingBox.max.x - this._boundingBox.min.x) * this._transform.sx; + this._box.scale.z = (this._boundingBox.max.z - this._boundingBox.min.z) * this._transform.sy; + + this._box.scale.y = this._boundingBox.max.y - this._boundingBox.min.y; + this._box.position.y = this._boundingBox.min.y; + } +} diff --git a/src/d3/transformers/BaseTransformer.js b/src/d3/transformers/BaseTransformer.js new file mode 100644 index 0000000..c63b8b6 --- /dev/null +++ b/src/d3/transformers/BaseTransformer.js @@ -0,0 +1,143 @@ +import * as THREE from 'three'; +import * as actions from '../../actions/index.js'; +import { EventObject3D } from '../EventScene.js'; +import transposeEvents from '../../utils/transposeEvents.js'; +import ShapeMesh from '../ShapeMesh.js'; +import { SpriteHandle } from '../../utils/threeUtils.js'; + +const RAY_CASTER = new THREE.Raycaster(); +const MOUSE = new THREE.Vector2(); + +export default class BaseTransformer extends EventObject3D { + constructor(dispatch, scene, camera, DOMNode, renderRequest) { + super(); + + // enable hit detection by default because it is needed for toggling selection + this.enableHitDetection = true; + + this.dispatch = dispatch; + this.scene = scene; + this.camera = camera; + this.DOMNode = DOMNode; + this.renderRequest = renderRequest; + } + dragStart({ position, preDrags, intersections }) { + this.dispatch(actions.d3DragStart(position, preDrags, intersections)); + } + drag({ position, previousPosition }) { + this.dispatch(actions.d3Drag(position, previousPosition)); + } + dragEnd({ position }) { + this.dispatch(actions.d3DragEnd(position)); + } + secondDragStart({ position, preDrags, intersections }) { + this.dispatch(actions.d3SecondDragStart(position, preDrags, intersections)); + } + secondDrag({ position, previousPosition }) { + this.dispatch(actions.d3SecondDrag(position, previousPosition)); + } + secondDragEnd({ position }) { + this.dispatch(actions.d3DragEnd(position)); + } + tap({ position, intersections }) { + // perhaps better to do this in a more general location + // but currently this is the only place we have access to intersections + this.select(intersections); + + this.dispatch(actions.d3Tap(position, intersections)); + } + wheel({ position, wheelDelta }) { + this.dispatch(actions.d3MouseWheel(position, wheelDelta)); + } + multitouchStart({ positions, preDrags }) { + this.dispatch(actions.d3MultitouchStart(positions, preDrags)); + } + multitouch({ positions, previousPositions }) { + this.dispatch(actions.d3Multitouch(positions, previousPositions)); + } + multitouchEnd({ positions }) { + this.dispatch(actions.d3MultitouchEnd(positions)); + } + select(intersections) { + const mesh = intersections.find(({ object }) => object instanceof ShapeMesh); + const bed = intersections.find(({ object }) => object.name === 'bed-plane'); + + if (mesh) { + this.dispatch(actions.toggleSelect(mesh.object.name)); + } else { + if (bed) { + this.dispatch(actions.bedSelect()); + } + this.dispatch(actions.deselectAll()); + } + } + onEvent(event) { + switch (event.type) { + case 'dragstart': + this._previousPosition = event.position; + break; + + case 'drag': + event.previousPosition = this._previousPosition; + this._previousPosition = event.position; + break; + + case 'seconddragstart': + this._previousSecondPosition = event.position; + break; + + case 'seconddrag': + event.previousPosition = this._previousSecondPosition; + this._previousSecondPosition = event.position; + break; + + case 'multitouchstart': + this._previousMultitouchPositions = event.positions; + break; + + case 'multitouch': + event.previousPositions = this._previousMultitouchPositions; + this._previousMultitouchPositions = event.positions; + break; + + default: + break; + } + + event.intersections = []; + if (this.enableHitDetection) { + if (event.type === 'tap' || event.type === 'dragstart' || event.type === 'seconddragstart') { + event.intersections = this.findHit(event.position); + } + } + + transposeEvents.call(this, event); + super.onEvent(event); + } + getRayCaster({ x, y }) { + MOUSE.setX((x / this.DOMNode.offsetWidth) * 2 - 1); + MOUSE.setY(-(y / this.DOMNode.offsetHeight) * 2 + 1); + + RAY_CASTER.setFromCamera(MOUSE, this.camera); + + return RAY_CASTER; + } + findHit(mouse) { + if (!this.enableHitDetection || this.scene.children.length === 0) return []; + + const rayCaster = this.getRayCaster(mouse); + const intersections = rayCaster.intersectObjects(this.scene.children, true); + + return intersections; + } + updateSpriteScale() { + for (const sprite of this.children) { + if (!(sprite instanceof SpriteHandle) || !sprite.material.map) continue; + + const scale = sprite.position.distanceTo(this.camera.getWorldPosition()) / 2000.0; + const { width, height } = sprite.material.map.image; + sprite.scale.set(width * scale, height * scale, 0); // TODO only if changed + } + } + destroy() {} +} diff --git a/src/d3/transformers/HeightTransformer.js b/src/d3/transformers/HeightTransformer.js new file mode 100644 index 0000000..55031ce --- /dev/null +++ b/src/d3/transformers/HeightTransformer.js @@ -0,0 +1,176 @@ +import { Vector } from 'cal'; +import * as THREE from 'three'; +import heightHandleURL from '../../../img/3d/heightHandle.png'; +import pivitHandleURL from '../../../img/3d/sculptHandle.png'; +import * as d3Tools from '../../constants/d3Tools'; +import { SHAPE_TYPE_PROPERTIES } from '../../constants/shapeTypeProperties'; +import { createTextureFromURL, SpriteHandle, CanvasPlane } from '../../utils/threeUtils.js'; +import BaseTransformer from './BaseTransformer.js'; +import { getSelectedObjectsSelector, getBoundingBox } from '../../utils/selectionUtils'; +import * as actions from '../../actions/index.js'; +import { dimensionsText } from '../../d2/texts.js'; +import * as humanReadable from '../../utils/humanReadable.js'; + +// import createDebug from 'debug'; +// const debug = createDebug('d3d:transformer:height'); + +const HEIGHT_HANDLE_OFFSET = 15; +const HEIGHT_HANDLE_SCALE = 0.166; + +const heightHandleTexture = createTextureFromURL(heightHandleURL); +const pivitHandleTexture = createTextureFromURL(pivitHandleURL); + +const HEIGHT_LABEL_HEIGHT = 128; +const HEIGHT_LABEL_WIDTH = 32; +const HEIGHT_LABEL_FONT = dimensionsText.clone(); +HEIGHT_LABEL_FONT.size = 30; + +export default class HeightTransformer extends BaseTransformer { + constructor(dispatch, scene, camera, domElement) { + super(dispatch, scene, camera, domElement); + + this.name = 'height-transformer'; + this.enableHitDetection = true; + + this._active = false; + } + + dragStart(event) { + const handle = this.includesHandle(event.intersections); + if (handle) { + this.dispatch(actions.heightStart(handle)); + } else { + super.dragStart(event); + } + } + + drag(event) { + if (this._active) { + const delta = event.position.subtract(event.previousPosition); + this.dispatch(actions.height(delta)); + } else { + super.drag(event); + } + } + + dragEnd(event) { + if (this._active) { + this.dispatch(actions.heightEnd()); + } else { + super.dragEnd(event); + } + } + + update(state) { + this.visible = state.selection.objects.length > 0; + + // TODO: create general selector for this in a reducer + const objectsById = state.objectsById; + const selectedShapeDatas = getSelectedObjectsSelector(state.selection.objects, objectsById); + const boundingBox = getBoundingBox(selectedShapeDatas, state.selection.transform); + + let editableObjects = false; + for (const shapeData of selectedShapeDatas) { + if (SHAPE_TYPE_PROPERTIES[shapeData.type].tools[d3Tools.HEIGHT]) { + editableObjects = true; + break; + } + } + + this._active = state.d3.height.active; + + this.visible = editableObjects; + + if (!this.visible) return; + if (!this._handleTop) { + this.createHandle(); + } + let { max, min, center } = boundingBox; + + center = center.applyMatrix(state.selection.transform); + + this._handleTop.position.set(center.x, max.y + HEIGHT_HANDLE_OFFSET, center.y); + this._handleBottom.position.set(center.x, min.y - HEIGHT_HANDLE_OFFSET, center.y); + this._handleTranslate.position.set(center.x, (min.y + max.y) / 2, center.y); + + if (this._active !== this._heightLabel.visible) { + if (!this._heightLabel.visible) { + const inverseWorld = new THREE.Matrix4().getInverse(this.matrixWorld); + const normalMatrix = new THREE.Matrix3().getNormalMatrix(inverseWorld); + + const objectDirection = new THREE.Vector3(0, 1, 0).applyMatrix3(normalMatrix); + + const cameraDirection = new THREE.Vector3() + .set(0, 0, -1) + .applyEuler(state.d3.camera.object.rotation) + .applyMatrix3(normalMatrix); + + const sculptDirection = new THREE.Vector3() + .crossVectors(cameraDirection, objectDirection) + .setY(0) + .normalize(); + + const maxSize = new Vector(max.x, max.z).applyMatrix(state.selection.transform); + const sideDistance = maxSize.subtract(center).length(); + + const base = new THREE.Vector2(sculptDirection.x, sculptDirection.z) + .multiplyScalar(sideDistance) + .add(center); + + const position = new THREE.Vector3(base.x, 0, base.y); + this._heightLabel.position.copy(position); + this._heightLabel.rotation.y = -new THREE.Vector2(sculptDirection.x, sculptDirection.z).angle(); + } + + this._heightLabel.visible = this._active; + } + + if (this._active) { + this._heightLabel.position.y = (min.y + max.y) / 2; + + this._heightLabel.draw((context, width, height) => { + context.clearRect(0, 0, width, height); + + // context.fillStyle = 'rgba(0, 0, 0, 0.5)'; + // context.fillRect(0, 0, width, height); + + context.save(); + context.translate(5, Math.round(height / 2)); + context.rotate(Math.PI * 0.5); + HEIGHT_LABEL_FONT.drawText(context, humanReadable.distance(max.y - min.y), 0, 0); + context.restore(); + }); + + const scale = this._heightLabel.position.distanceTo(this.camera.getWorldPosition()) / 1000.0; + this._heightLabel.scale.set(scale, scale, scale); + } + + this.updateSpriteScale(); + } + createHandle() { + this._handleTop = new SpriteHandle(heightHandleTexture, HEIGHT_HANDLE_SCALE); + this._handleTop.name = 'height-transformer-handle-top'; + this.add(this._handleTop); + + this._handleBottom = new SpriteHandle(heightHandleTexture, HEIGHT_HANDLE_SCALE); + this._handleBottom.name = 'height-transformer-handle-bottom'; + this.add(this._handleBottom); + + this._handleTranslate = new SpriteHandle(pivitHandleTexture, HEIGHT_HANDLE_SCALE); + this._handleTranslate.name = 'height-transformer-handle-translate'; + this.add(this._handleTranslate); + + this._heightLabel = new CanvasPlane(HEIGHT_LABEL_WIDTH, HEIGHT_LABEL_HEIGHT); + this._heightLabel.visible = false; + this.add(this._heightLabel); + } + includesHandle(intersections) { + if (!this._handleTop) return ''; + const objects = intersections.map(({ object }) => object); + + if (objects.indexOf(this._handleTop) !== -1) return 'top'; + if (objects.indexOf(this._handleBottom) !== -1) return 'bottom'; + if (objects.indexOf(this._handleTranslate) !== -1) return 'translate'; + return ''; + } +} diff --git a/src/d3/transformers/SculptTransformer.js b/src/d3/transformers/SculptTransformer.js new file mode 100644 index 0000000..c345b98 --- /dev/null +++ b/src/d3/transformers/SculptTransformer.js @@ -0,0 +1,263 @@ +import * as THREE from 'three'; +import { Vector } from 'cal'; +import { SHAPE_TYPE_PROPERTIES } from '../../constants/shapeTypeProperties.js'; +import * as d3Tools from '../../constants/d3Tools'; +import handleURL from '../../../img/3d/sculptHandle.png'; +import { createTextureFromURL, SpriteHandle } from '../../utils/threeUtils.js'; +import BaseTransformer from './BaseTransformer.js'; +import { getSelectedObjectsSelector, getBoundingBox } from '../../utils/selectionUtils.js'; +import * as actions from '../../actions/index.js'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:transformer:sculpt'); + +const ARROW_HELPER = false; + +const HANDLE_SCALE = 0.125; +const LINE_HIT_DISTANCE = 5.0; +const lineMaterial = new THREE.LineBasicMaterial({ + color: 0x72bcd4 +}); + +const ARROW_HELPER_OBJECT_DIR = new THREE.ArrowHelper(new THREE.Vector3(), new THREE.Vector3(), 50, 0xff0000); +const ARROW_HELPER_CAMERA_DIR = new THREE.ArrowHelper(new THREE.Vector3(), new THREE.Vector3(), 50, 0x00ff00); +const ARROW_HELPER_SCULPT_DIR = new THREE.ArrowHelper(new THREE.Vector3(), new THREE.Vector3(), 50, 0x0000ff); +const ARROW_HELPER_MOUSE_DIR = new THREE.ArrowHelper(new THREE.Vector3(), new THREE.Vector3(), 50, 0xffff00); +ARROW_HELPER_MOUSE_DIR.visible = false; + +const handleTexture = createTextureFromURL(handleURL); + +export default class SculptTransformer extends BaseTransformer { + _handles = []; + constructor(dispatch, scene, camera, domElement) { + super(dispatch, scene, camera, domElement); + + this.name = 'sculpt-transformer'; + + this.center = new THREE.Vector2(); + this.cameraRotation = new THREE.Vector3(); + this.sideDistance = 0; + + this.enableHitDetection = true; + } + + tap(event) { + const handle = this.includedHandle(event.intersections); + if (handle) { + this.dispatch(actions.removeSculptHandle(handle.heightIndex)); + return; + } + + const hitLine = this.findHitLine(event); + if (hitLine) { + // add sculpt handle, do not store as active + this.dispatch(actions.addSculptHandle(hitLine, false)); + return; + } + + super.tap(event); + } + + dragStart(event) { + const handle = this.includedHandle(event.intersections); + if (handle) { + this.dispatch(actions.sculptStart(handle.heightIndex, true)); + return; + } + + const hitLine = this.findHitLine(event); + if (hitLine) { + // add sculpt handle, store as active + this.dispatch(actions.addSculptHandle(hitLine, true)); + return; + } + + super.dragStart(event); + } + + drag(event) { + if (this.sculpt && this.sculpt.activeHandle !== null) { + const { normalMatrix, origin, sculptDirection } = this.calculateSculptDirection(); + + const mouseDelta = event.position.subtract(event.previousPosition); + const mouseDirection = new THREE.Vector3() + .set(mouseDelta.x, -mouseDelta.y, 0) + .applyMatrix3(new THREE.Matrix3().getNormalMatrix(this._camera.object.matrix)) + .applyMatrix3(normalMatrix) + .normalize(); + + ARROW_HELPER_MOUSE_DIR.position.copy(origin); + ARROW_HELPER_MOUSE_DIR.setDirection(mouseDirection); + + const delta = mouseDirection.dot(sculptDirection) * mouseDelta.length(); + + this.dispatch(actions.sculpt(delta)); + } else { + super.drag(event); + } + } + + dragEnd(event) { + if (this.sculpt && this.sculpt.activeHandle !== null) { + ARROW_HELPER_MOUSE_DIR.visible = false; + this.dispatch(actions.sculptEnd()); + return; + } + super.dragEnd(event); + } + + update(state) { + this.sculpt = state.d3.sculpt; + + this.visible = state.selection.objects.length > 0; + + // TODO: create general selector for this in a reducer + const objectsById = state.objectsById; + const selectedShapeDatas = getSelectedObjectsSelector(state.selection.objects, objectsById); + const boundingBox = getBoundingBox(selectedShapeDatas, state.selection.transform); + + const editableObjects = selectedShapeDatas.some(shapeData => { + return SHAPE_TYPE_PROPERTIES[shapeData.type].tools[d3Tools.SCULPT]; + }); + + this.visible = editableObjects; + if (!editableObjects) return; + + let { min, max, center } = boundingBox; + center = center.applyMatrix(state.selection.transform); + const maxSize = new Vector(max.x, max.z).applyMatrix(state.selection.transform); + this.sideDistance = maxSize.subtract(center).length(); + this.center.copy(center); + this.maxHeight = max.y; + this.minHeight = min.y; + + if (!this._state || state.d3.camera !== this._state.d3.camera) this._camera = state.d3.camera; + + this.createUI(this.sculpt.handles.length); + this.updateHandlePosition(); + + this.updateSpriteScale(); + + this._state = state; + } + removeHandles() { + const children = [...this.children]; + for (let i = 0; i < children.length; i ++) { + const mesh = children[i]; + if (mesh.geometry) mesh.geometry.dispose(); + this.remove(mesh); + } + } + createUI(numItems) { + if (this.numItems === numItems) return; + this.removeHandles(); + + if (ARROW_HELPER) { + this.add( + ARROW_HELPER_OBJECT_DIR, + ARROW_HELPER_SCULPT_DIR, + ARROW_HELPER_CAMERA_DIR, + ARROW_HELPER_MOUSE_DIR + ); + } + + this._handles = []; + const lineGeometry = new THREE.Geometry(); + for (let heightIndex = 0; heightIndex < numItems; heightIndex ++) { + const handle = this.createHandle(heightIndex); + this.add(handle); + this._handles.push(handle); + lineGeometry.vertices.push(new THREE.Vector3(0, 0, 0)); + } + this.line = new THREE.Line(lineGeometry, lineMaterial); + this.add(this.line); + this.numItems = numItems; + } + createHandle(index) { + const handle = new SpriteHandle(handleTexture, HANDLE_SCALE); + handle.name = `sculpt-transformer-handle-${index}`; + handle.heightIndex = index; + return handle; + } + calculateSculptDirection() { + const inverseWorld = new THREE.Matrix4().getInverse(this.matrixWorld); + const normalMatrix = new THREE.Matrix3().getNormalMatrix(inverseWorld); + + const origin = new THREE.Vector3(this.center.x, this.minHeight, this.center.y); + + const objectDirection = new THREE.Vector3(0, 1, 0).applyMatrix3(normalMatrix); + + const cameraDirection = new THREE.Vector3() + .set(0, 0, -1) + .applyEuler(this._camera.object.rotation) + .applyMatrix3(normalMatrix); + + const sculptDirection = new THREE.Vector3() + .crossVectors(cameraDirection, objectDirection) + .setY(0) + .normalize(); + + return { origin, objectDirection, cameraDirection, sculptDirection, normalMatrix }; + } + updateHandlePosition() { + const { origin, objectDirection, cameraDirection, sculptDirection } = this.calculateSculptDirection(); + + ARROW_HELPER_OBJECT_DIR.position.copy(origin); + ARROW_HELPER_OBJECT_DIR.setDirection(objectDirection); + ARROW_HELPER_CAMERA_DIR.position.copy(origin); + ARROW_HELPER_CAMERA_DIR.setDirection(cameraDirection); + ARROW_HELPER_SCULPT_DIR.position.copy(origin); + ARROW_HELPER_SCULPT_DIR.setDirection(sculptDirection); + + for (let i = 0; i < this.sculpt.handles.length; i ++) { + const handle = this._handles[i]; + + const { scale, pos: y } = this.sculpt.handles[i]; + + const base = new THREE.Vector2(sculptDirection.x, sculptDirection.z) + .multiplyScalar(this.sideDistance * scale) + .add(this.center); + + const position = new THREE.Vector3(base.x, y, base.y); + handle.position.copy(position); + + this.line.geometry.vertices[i].copy(position); + } + if (this.line) { + this.line.geometry.verticesNeedUpdate = true; + } + } + // checks for handles in objects and returns the first found + includedHandle(intersections) { + if (this._handles.length === 0) return null; + for (const i in intersections) { + const object = intersections[i].object; + const handleIndex = this._handles.indexOf(object); + if (handleIndex !== -1) { + return this._handles[handleIndex]; + } + } + return null; + } + + // Check if event was close enough to line, + // if it was returns y position + // otherwise returns null + findHitLine(event) { + if (!this.line) return null; + + const { ray } = this.getRayCaster(event.position); + + for (let i = 1; i < this.line.geometry.vertices.length; i ++) { + const v0 = this.line.geometry.vertices[i - 1]; + const v1 = this.line.geometry.vertices[i]; + + const pointOnSegment = new THREE.Vector3(); + const distance = Math.sqrt(ray.distanceSqToSegment(v0, v1, pointOnSegment, null)); + + if (distance < LINE_HIT_DISTANCE) { + return pointOnSegment.y; + } + } + return null; + } +} diff --git a/src/d3/transformers/StampTransformer.js b/src/d3/transformers/StampTransformer.js new file mode 100644 index 0000000..ada8e8a --- /dev/null +++ b/src/d3/transformers/StampTransformer.js @@ -0,0 +1,52 @@ +import { CANVAS_SIZE } from '../../constants/d2Constants'; +import ShapeMesh from '../ShapeMesh.js'; +import * as THREE from 'three'; +import BaseTransformer from './BaseTransformer.js'; +import * as actions from '../../actions/index.js'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:transformer:sculpt'); + +const CANVAS_WIDTH = CANVAS_SIZE; +const CANVAS_HEIGHT = CANVAS_SIZE; + +export default class SculptTransformer extends BaseTransformer { + constructor(dispatch, scene, camera, domElement) { + super(dispatch, scene, camera, domElement); + + this.name = 'stamp-transformer'; + this.enableHitDetection = true; + + const geometry = new THREE.Geometry(); + geometry.vertices.push( + new THREE.Vector3(-CANVAS_WIDTH, 0, -CANVAS_HEIGHT), + new THREE.Vector3(CANVAS_WIDTH, 0, -CANVAS_HEIGHT), + new THREE.Vector3(CANVAS_WIDTH, 0, CANVAS_HEIGHT), + new THREE.Vector3(-CANVAS_WIDTH, 0, CANVAS_HEIGHT), + new THREE.Vector3(-CANVAS_WIDTH, 0, -CANVAS_HEIGHT) + ); + geometry.computeLineDistances(); + const lineMaterial = new THREE.LineDashedMaterial({ + color: 0x000000, + dashSize: 10, + gapSize: 10, + linewidth: 1 + }); + this.dottedLine = new THREE.Line(geometry, lineMaterial); + this.add(this.dottedLine); + + this.hasSelection = false; + } + + update(state) { + this.hasSelection = state.selection.objects.length > 0; + } + + tap(event) { + const intersection = event.intersections.find(({ object }) => object instanceof ShapeMesh); + if (this.hasSelection && intersection) { + this.dispatch(actions.stamp(intersection)); + } else { + super.tap(event); + } + } +} diff --git a/src/d3/transformers/TwistTransformer.js b/src/d3/transformers/TwistTransformer.js new file mode 100644 index 0000000..128dde9 --- /dev/null +++ b/src/d3/transformers/TwistTransformer.js @@ -0,0 +1,86 @@ +import { SHAPE_TYPE_PROPERTIES } from '../../constants/shapeTypeProperties'; +import * as d3Tools from '../../constants/d3Tools'; +import rotateHandleURL from '../../../img/3d/rotateHandle.png'; +import { createTextureFromURL, SpriteHandle } from '../../utils/threeUtils.js'; +import BaseTransformer from './BaseTransformer.js'; +import { getSelectedObjectsSelector, getBoundingBox } from '../../utils/selectionUtils'; +import * as actions from '../../actions/index.js'; +// import createDebug from 'debug'; +// const debug = createDebug('d3d:transformer:twist'); + +const HANDLE_SCALE = 0.166; +const HANDLE_OFFSET = 15; +const handleTexture = createTextureFromURL(rotateHandleURL); + +export default class TwistTransformer extends BaseTransformer { + constructor(dispatch, scene, camera, domElement) { + super(dispatch, scene, camera, domElement); + + this.name = 'twist-transformer'; + this.createHandle(); + + this._active = false; + this.enableHitDetection = true; + } + dragStart(event) { + if (this.includesHandle(event.intersections)) { + this.dispatch(actions.twistStart()); + } else { + super.dragStart(event); + } + } + drag(event) { + if (this._active) { + const delta = event.position.subtract(event.previousPosition); + this._handle.material.rotation -= delta; + + this.dispatch(actions.twist(delta)); + } else { + super.drag(event); + } + } + dragEnd(event) { + if (this._active) { + this.dispatch(actions.twistEnd()); + } else { + super.dragEnd(event); + } + } + update(state) { + this.visible = state.selection.objects.length > 0; + + // TODO: create general selector for this in a reducer + const objectsById = state.objectsById; + const selectedShapeDatas = getSelectedObjectsSelector(state.selection.objects, objectsById); + const boundingBox = getBoundingBox(selectedShapeDatas, state.selection.transform); + + let editableObjects = false; + for (const shapeData of selectedShapeDatas) { + if (SHAPE_TYPE_PROPERTIES[shapeData.type].tools[d3Tools.TWIST]) { + editableObjects = true; + break; + } + } + + this._active = state.d3.twist.active; + + this.visible = editableObjects; + if (!editableObjects) return; + + let { max, center } = boundingBox; + center = center.applyMatrix(state.selection.transform); + this._handle.position.set(center.x, max.y + HANDLE_OFFSET, center.y); + this._handle.material.rotation = -state.d3.twist.rotation; + + this.updateSpriteScale(); + } + createHandle() { + this._handle = new SpriteHandle(handleTexture, HANDLE_SCALE); + this._handle.name = 'twist-transformer-handle'; + this.add(this._handle); + } + includesHandle(intersections) { + const objects = intersections.map(({ object }) => object); + return (objects.indexOf(this._handle) !== -1); + } +} diff --git a/src/reducer/d2/toolReducer.js b/src/reducer/d2/toolReducer.js index e596986..37735b6 100644 --- a/src/reducer/d2/toolReducer.js +++ b/src/reducer/d2/toolReducer.js @@ -46,23 +46,6 @@ export default function toolReducer(state, action) { state = updateTool(state, tools.TRANSFORM); } - switch (action.type) { - case actions.D2_DRAG_START: - state = update(state, { - d2: { dragging: { $set: true } } - }); - break; - - case actions.D2_DRAG_END: - state = update(state, { - d2: { dragging: { $set: false } } - }); - break; - - default: - break; - } - const tool = state.d2.tool; const reducer = reducers[tool]; if (reducer) { diff --git a/src/reducer/d3/toolReducer.js b/src/reducer/d3/toolReducer.js index 960985e..0ee8d76 100644 --- a/src/reducer/d3/toolReducer.js +++ b/src/reducer/d3/toolReducer.js @@ -24,23 +24,6 @@ export default function toolReducer(state, action) { d3: { camera: { $set: cameraReducer(state.d3.camera, action) } } }); - switch (action.type) { - case actions.D3_DRAG_START: - state = update(state, { - d3: { dragging: { $set: true } } - }); - break; - - case actions.D3_DRAG_END: - state = update(state, { - d3: { dragging: { $set: false } } - }); - break; - - default: - break; - } - if (action.type === actions.D3_CHANGE_TOOL && action.tool !== state.d3.tool) { state = update(state, { d3: { tool: { $set: action.tool } } diff --git a/src/reducer/index.js b/src/reducer/index.js index 953c490..e797671 100644 --- a/src/reducer/index.js +++ b/src/reducer/index.js @@ -73,8 +73,7 @@ const initialState = { toolbar: { open: [] }, - canvasMatrix: new Matrix(), - dragging: false + canvasMatrix: new Matrix() }, d3: { height: { @@ -93,8 +92,7 @@ const initialState = { toolbar: { open: [] }, - camera: defaultCamera, - dragging: false + camera: defaultCamera }, menus: menusReducer(undefined, {}) }; diff --git a/src/utils/humanReadable.js b/src/utils/humanReadable.js new file mode 100644 index 0000000..44bac62 --- /dev/null +++ b/src/utils/humanReadable.js @@ -0,0 +1,16 @@ +export const price = (number) => number.toLocaleString(navigator.language, { + style: 'currency', + currency: 'EUR' +}); +export const percentage = (percent) => percent.toLocaleString(navigator.language, { + style: 'percent', + maximumFractionDigits: 0 +}); +export const distance = (dist) => `${(dist).toLocaleString(navigator.language, { + style: 'decimal', + maximumFractionDigits: 0 +})}mm`; +export const degrees = (rad) => `${(rad * 360 / (Math.PI * 2)).toLocaleString(navigator.language, { + style: 'decimal', + maximumFractionDigits: 0 +})}°`; diff --git a/src/utils/pointerUtils.js b/src/utils/pointerUtils.js new file mode 100644 index 0000000..f414281 --- /dev/null +++ b/src/utils/pointerUtils.js @@ -0,0 +1,11 @@ +import { Vector } from 'cal'; + +export function convertEvent(DOMNode, event) { + const { left, top } = DOMNode.getBoundingClientRect(); + return new Vector(event.clientX - left, event.clientY - top); +} + +export function isMouseEvent(event) { + // Multitouch events can be ignored because they cannot be triggered by a mouse + return event.event && event.event.pointerType === 'mouse'; +} diff --git a/src/utils/rafOnce.js b/src/utils/rafOnce.js new file mode 100644 index 0000000..664dd50 --- /dev/null +++ b/src/utils/rafOnce.js @@ -0,0 +1,16 @@ + +// Utility to make it easy for one instance to create only one +// animation request. +import raf from 'raf'; +export default function createRAFOnce() { + let rafID; + return function rafOnce(notify) { + if (rafID) { + return; + } + rafID = raf(() => { + rafID = null; + notify(); + }); + }; +} diff --git a/src/utils/threeUtils.js b/src/utils/threeUtils.js new file mode 100644 index 0000000..86d5e90 --- /dev/null +++ b/src/utils/threeUtils.js @@ -0,0 +1,109 @@ +import * as THREE from 'three'; +import { loadImage } from './imageUtils.js' +import createDebug from 'debug'; +const debug = createDebug('d3d:threeUtils'); + +export function createTextureFromURL(url, useRGBAFormat = true) { + const texture = new THREE.Texture(); + + loadImage(url).then(image => { + URL.revokeObjectURL(url); + texture.format = useRGBAFormat ? THREE.RGBAFormat : THREE.RGBFormat; + texture.image = image; + texture.needsUpdate = true; + }).catch(() => { + URL.revokeObjectURL(url); + throw new Error(`Unable to load image: '${url}'`); + }); + + return texture; +} + +export function createTextureFromBlob(blob) { + const texture = new THREE.Texture(); + + const url = URL.createObjectURL(blob); + loadImage(url).then(image => { + URL.revokeObjectURL(url); + + texture.format = (blob.type === 'image/jpeg' || blob.type === 'image/jpg') ? + THREE.RGBFormat : + THREE.RGBAFormat; + texture.image = image; + texture.needsUpdate = true; + }).catch(() => { + URL.revokeObjectURL(url); + + throw new Error(`Unable to load image: '${url}'`); + }); + + return texture; +} + +export class SpriteHandle extends THREE.Sprite { + constructor(texture, scale) { + if (!texture.image) { + debug('Error: Texture not loaded'); + super(); + return; + } + const spriteMaterial = new THREE.SpriteMaterial({ + color: 0xffffff, + fog: true, + depthTest: false, + map: texture + }); + super(spriteMaterial); + const { width, height } = texture.image; + this.scale.set(width * scale, height * scale, 1); + } +} + +export class CanvasPlane extends THREE.Mesh { + constructor(width = 100, height = 100) { + const planeGeometry = new THREE.PlaneBufferGeometry(0, 0, 1, 1); + + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + const texture = new THREE.Texture(canvas); + const material = new THREE.MeshBasicMaterial({ + map: texture, + side: THREE.DoubleSide + }); + + super(planeGeometry, material); + + this._width = width; + this._height = height; + + this._canvas = canvas; + this._context = context; + this._texture = texture; + + this.updateSize(width, height); + } + updateSize(width, height) { + this._width = width; + this._height = height; + + this._canvas.width = Math.round(width); + this._canvas.height = Math.round(height); + + const positions = this.geometry.getAttribute('position'); + const halfWidth = width / 2; + const halfHeight = height / 2; + positions.array[0] = -halfWidth; + positions.array[1] = halfHeight; + positions.array[3] = halfWidth; + positions.array[4] = halfHeight; + positions.array[6] = -halfWidth; + positions.array[7] = -halfHeight; + positions.array[9] = halfWidth; + positions.array[10] = -halfHeight; + positions.needsUpdate = true; + } + draw(draw) { + draw(this._context, this._width, this._height); + this._texture.needsUpdate = true; + } +} diff --git a/src/utils/traceUtils.js b/src/utils/traceUtils.js index 5d839f6..db75fc0 100644 --- a/src/utils/traceUtils.js +++ b/src/utils/traceUtils.js @@ -1,6 +1,6 @@ import { applyMatrixOnPath, pathToVectorPath } from './vectorUtils.js'; import { Matrix } from 'cal'; -import TraceWorker from 'workers/worker.js'; +import TraceWorker from '../../workers/trace.worker.js'; import { getPixel } from './colorUtils.js'; import memoize from 'memoizee'; diff --git a/src/utils/transposeEvents.js b/src/utils/transposeEvents.js new file mode 100644 index 0000000..23851fd --- /dev/null +++ b/src/utils/transposeEvents.js @@ -0,0 +1,66 @@ +export default function transposeEvents(event) { + let eventHandler; + + switch (event.type) { + case 'dragstart': + eventHandler = this.dragStart; + break; + case 'drag': + eventHandler = this.drag; + break; + case 'dragend': + eventHandler = this.dragEnd; + break; + case 'seconddragstart': + eventHandler = this.secondDragStart; + break; + case 'seconddrag': + eventHandler = this.secondDrag; + break; + case 'seconddragend': + eventHandler = this.secondDragEnd; + break; + case 'tap': + eventHandler = this.tap; + break; + case 'wheel': + eventHandler = this.wheel; + break; + case 'multitouchstart': + eventHandler = this.multitouchStart; + break; + case 'multitouch': + eventHandler = this.multitouch; + break; + case 'multitouchend': + eventHandler = this.multitouchEnd; + break; + case 'pointerdown': + eventHandler = this.pointerDown; + break; + case 'pointermove': + eventHandler = this.pointerMove; + break; + case 'pointerup': + eventHandler = this.pointerUp; + break; + case 'pointerover': + eventHandler = this.pointerOver; + break; + case 'pointerout': + eventHandler = this.pointerOut; + break; + case 'pointerleave': + eventHandler = this.pointerLeave; + break; + case 'pointercancel': + eventHandler = this.pointerCancel; + break; + default: + break; + } + + if (eventHandler) { + eventHandler.call(this, event); + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..f6fa4f9 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,81 @@ +const path = require('path'); +// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +const HTMLWebpackPlugin = require('html-webpack-plugin'); + +const babelLoader = { + loader: 'babel-loader', + options: { + presets: [ + require('babel-preset-env'), + require('babel-preset-react') + ], + plugins: [ + require('babel-plugin-transform-object-rest-spread'), + require('babel-plugin-transform-class-properties'), + require('babel-plugin-transform-runtime') + ], + babelrc: false + } +}; + +module.exports = { + entry: './index.js', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist') + }, + resolve: { + alias: { + 'doodle3d-slicer': path.resolve(__dirname, '../src/index.js'), + 'clipper-lib': '@doodle3d/clipper-lib', + 'clipper-js': '@doodle3d/clipper-js', + 'cal': '@doodle3d/cal', + 'touch-events': '@doodle3d/touch-events', + 'potrace-js': '@doodle3d/potrace-js', + 'fill-path': '@doodle3d/fill-path', + } + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: babelLoader + }, { // make THREE global available to three.js examples + test: /three\/examples\/.+\.js/, + use: 'imports-loader?THREE=three' + }, { + test: /\.yml$/, + use: 'yml-loader' + }, { + test: /\.worker.js$/, + use: ['worker-loader', babelLoader] + }, { + test: /\.(png|jpg|gif)$/, + use: { + loader: 'file-loader', + options: { + name: '[path][name].[ext]' + } + } + }, { + test: /\.svg$/, + use: { + loader: 'raw-loader' + } + } + ] + }, + plugins: [ + new HTMLWebpackPlugin({ + title: 'Doodle3D Slicer - Simple example', + template: require('html-webpack-template'), + inject: false, + appMountId: 'app' + }), + ], + devtool: "source-map", + devServer: { + contentBase: 'dist' + } +}; diff --git a/workers/trace.worker.js b/workers/trace.worker.js new file mode 100644 index 0000000..a782765 --- /dev/null +++ b/workers/trace.worker.js @@ -0,0 +1,85 @@ +import 'babel-polyfill'; +import * as POTRACE from 'potrace-js'; +import { POTRACE_OPTIONS } from '../src/constants/d2Constants.js'; + +self.addEventListener('message', (event) => { + switch (event.data.msg) { + case 'FLOOD_FILL': + const { imageData, start, tolerance } = event.data; + + self.postMessage({ + msg: 'FLOOD_FILL', + status: 'OK', + traceData: floodFill(imageData, start, tolerance) + }); + break; + + case 'TRACE': + const { fill, width, height } = event.data; + + const bitmap = new POTRACE.Bitmap(width, height); + for (let i = 0; i < fill.length; i ++) { + const index = fill[i]; + bitmap.data[index] = 1; + } + + self.postMessage({ + msg: 'TRACE', + status: 'OK', + paths: POTRACE.getPaths(POTRACE.traceBitmap(bitmap, POTRACE_OPTIONS)) + }); + break; + + default: + break; + } +}); + +function floodFill(imageData, start, tolerance) { + const { width, height } = imageData; + + const compairIndex = start.y * width + start.x; + const stack = [compairIndex]; + const done = { [compairIndex]: true }; + + const edge = []; + const fill = []; + + while (stack.length > 0) { + const index = stack.pop(); + + const value = imageData.data[index]; + const pass = value < tolerance; + + if (!pass) { + edge.push(index); + continue; + } + + fill.push(index); + + const left = index % width !== 0; + const right = index % width !== width - 1; + const top = Math.floor(index / width) !== 0; + const bottom = Math.floor(index / width) !== height - 1; + + const neighbours = []; + if (left) neighbours.push(index - 1); + if (right) neighbours.push(index + 1); + if (top) neighbours.push(index - width); + if (bottom) neighbours.push(index + width); + + if (neighbours.length !== 4) edge.push(index); + + for (let i = 0; i < neighbours.length; i ++) { + const neighbourIndex = neighbours[i]; + + if (!done[neighbourIndex]) { + stack.push(neighbourIndex); + } + done[neighbourIndex] = true; + } + } + + return { edge, fill }; +}