diff --git a/httpdocs/theme/react/assets/css/product-browse.css b/httpdocs/theme/react/assets/css/product-browse.css
index 694606067..98d812274 100644
--- a/httpdocs/theme/react/assets/css/product-browse.css
+++ b/httpdocs/theme/react/assets/css/product-browse.css
@@ -1 +1 @@
-#product-browse{position:relative}#product-browse #product-tag-filter-container{position:absolute;right:0px;top:10px}#product-browse #product-tag-filter-container .product-tag-group-dropdown{width:135px;margin-right:5px;float:left}#product-browse #product-tag-filter-container .product-tag-group-dropdown select{width:100%}#product-browse-container #product-browse-item-list{padding:25px 0;float:left;margin-right:-7px;margin-left:-7px;min-width:100%}#product-browse-container #product-browse-item-list.on-mobile{margin:0}#product-browse-container #product-browse-item-list .product-browse-item-row{width:100%;float:left}#product-browse-container #product-browse-item-list .product-browse-item-row.favorites-row{padding:10px 0;font-size:12px;border-top:1px solid #ccc}#product-browse-container #product-browse-item-list .product-browse-item-row.favorites-row:first-of-type{border-top:0}#product-browse-container #product-browse-item-list .product-browse-item{float:left;margin-bottom:30px;position:relative;padding:0 7px}#product-browse-container #product-browse-item-list .product-browse-item>a{display:block;width:100%;height:auto;text-decoration:none}#product-browse-container #product-browse-item-list .product-browse-item>a:hover{text-decoration:none !important}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars{display:block;width:83px !important;float:left;background-image:url('../img/rating_stars.png');background-position:0px 0px;height:25px !important}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-5{background-position:0 -22px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-10{background-position:0 -44px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-15{background-position:0 -66px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-20{background-position:0 -88px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-25{background-position:0 -110px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-30{background-position:0 -132px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-35{background-position:0 -154px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-40{background-position:0 -176px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-45{background-position:0 -198px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-50{background-position:0 -220px}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-image{width:100%;overflow:hidden;box-shadow:1px 1px 2px rgba(0,0,0,0.5);position:relative}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-image .product-browse-item-preview-music-player{position:absolute;top:0;left:0}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-image img{width:100%}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info{font-size:14px;font-weight:bold;overflow:hidden}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info h2{font-size:20px;font-weight:bold;margin-bottom:3px;white-space:nowrap;overflow:hidden;display:block;text-overflow:ellipsis;font-size:18px;min-height:22px;margin-top:8px;margin-bottom:4px}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info span{width:50%;float:left;display:block;font-weight:normal;color:black;font-size:1.2rem}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info span b{color:black;font-weight:normal}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info span+span{text-align:right}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-music-item-info{font-size:14px;padding:5px;float:left;margin-bottom:5px;width:100%}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-music-item-info h2{font-size:16px;font-weight:bold;margin-bottom:3px;white-space:nowrap;overflow:hidden;display:block;text-overflow:ellipsis;margin:5px 0;width:100%}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-music-item-info span{width:100%;float:left;white-space:nowrap;overflow:hidden;display:block;text-overflow:ellipsis;margin:2px 0}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter{margin-top:3px;font-size:12px;font-weight:400;margin-bottom:5px}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter .hearts-container .glyphicon{width:auto;font-size:15px;color:#c1c1c1;font-weight:normal;margin-right:5px;margin-top:0px}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter .hearts-container .glyphicon.glyphicon-heart{display:none}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter .hearts-container:hover .glyphicon{display:none}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter .hearts-container:hover .glyphicon-heart{display:block ;color:red}#product-browse-container #product-browse-item-list .product-browse-item .info-container{width:100%;float:left}#product-browse-container #product-browse-item-list .product-browse-item .wrapper{width:100%;position:relative}#product-browse-container #product-browse-item-list .product-browse-item.phone-pictures .product-browse-image{border-radius:5px 5px 5px 5px}#product-browse-container #product-browse-item-list .product-browse-item.phone-pictures h2,#product-browse-container #product-browse-item-list .product-browse-item.phone-pictures span{font-size:13px;line-height:14px;font-weight:400}#product-browse-container #product-browse-item-list .product-browse-item.comics .product-browse-item-info h2{font-size:13px;line-height:14px;font-weight:400}#product-browse-container #product-browse-item-list .product-browse-item.comics .product-browse-item-info .score-container{margin-top:-10px}#product-browse-container #product-browse-item-list .product-browse-item.music *,#product-browse-container #product-browse-item-list .product-browse-item.music-test *{user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper{position:absolute;top:0;left:0;width:100%;height:40px;z-index:10}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control{float:left;background:rgba(0,0,0,0.5);height:40px;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span{display:block;padding:5px;float:left}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span svg,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span svg{font-size:28px;color:white;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span svg:hover,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span svg:hover{color:#31c27c}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span:first-child,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span:first-child,#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span:last-child,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span:last-child{display:none}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .track-number-display,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .track-number-display{opacity:0;float:right;background:rgba(0,0,0,0.5);height:40px;padding:5px;color:white;font-size:12px;line-height:30px;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .music-player-audio-control span:first-child,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .music-player-audio-control span:first-child,#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .music-player-audio-control span:last-child,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .music-player-audio-control span:last-child{display:block;padding:5px 0}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .track-number-display,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .track-number-display{opacity:1}#product-browse-container #product-browse-item-list .product-browse-item.music-test{height:150px}#product-browse-container #product-browse-item-list .product-browse-item.music-test .wrapper a.product-browse-item-wrapper{display:none}#product-browse-container #product-browse-item-list .product-browse-item.favorites{margin-bottom:0}#product-browse-container #product-browse-item-list .product-browse-item.favorites:first-of-type{border-top:0}#product-browse-container #product-browse-item-list .product-browse-item.favorites span.index{width:8.33333333%;display:block;float:left;text-align:center}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper{width:91.6666667%;display:block;float:left}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-image{width:15%;overflow:hidden;float:left}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-image img{max-width:100%;height:auto}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info{width:85%;float:left;padding-left:15px}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .info-container{width:75%;float:left}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .info-container span{width:auto;margin-right:10px}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .score-container{float:left;width:25%}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .score-container .rating{width:50%;margin-bottom:10px}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .score-container .rating .rating-text{margin-bottom:5px}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper{overflow:hidden;box-shadow:1px 1px 2px rgba(0,0,0,0.5);position:relative}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper .product-browse-image{box-shadow:none}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper .product-browse-item-info{padding:5px;height:100px}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper .product-browse-item-info>span{width:100%}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper .likes-counter{margin-top:3px;font-size:12px;font-weight:400;margin-bottom:5px;position:absolute;left:5px;bottom:5px;width:100%}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player{width:100%;position:absolute;top:44px;left:0;z-index:10}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player button{padding:0;background-color:transparent;border:0;outline:none !important}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player{top:-44px;position:absolute;width:100%;left:0}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .track-counter{padding:5px;height:40px;background-color:rgba(0,0,0,0.5)}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls{float:left;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls span{cursor:pointer}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls svg{font-size:28px;color:white;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out;vertical-align:middle}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls svg:hover{color:#31c27c}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .track-counter{float:right;color:white;line-height:30px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls{width:100%;height:100px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls .play-icon,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls .pause-icon{font-size:60px;top:20px;position:absolute;left:50%;margin-left:-30px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls .prev-icon{font-size:50px;position:absolute;top:25px;left:0}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls .next-icon{font-size:50px;position:absolute;top:25px;right:0}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .track-counter{position:absolute;left:50%;bottom:0;height:27px;background:0;margin-left:-25px;padding:0;width:50px;text-align:center}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .music-player-counter{position:absolute;top:-44px;background-color:rgba(0,0,0,0.7);right:0;display:block;z-index:100000;height:44px;color:white;line-height:35px;padding:5px;display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel{position:absolute;height:44px;width:38px;overflow:hidden;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .play-mode-title{display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content{padding:5px;height:100%;position:relative;display:block}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .img-content,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .audio-title,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .progress-bar-content{display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content{padding:0px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group{padding:0;margin:0}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.prev-audio,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.next-audio,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.audio-lists-btn,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.play-sounds{display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.play-btn.play{margin-right:5px;margin-top:3px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.loading{margin-top:2px;margin-left:42px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile{height:auto;position:absolute;top:-44px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-header,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-singer,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-switch,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-cover,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-progress,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-operation{display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-toggle{padding:0;display:flex;justify-content:center}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-toggle .play-btn{padding:0 20px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .group.prev-audio,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .group.next-audio{display:none;padding-top:6px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.show-controls .music-player-counter{display:block}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.show-controls .react-jinke-music-player-main .music-player-panel{width:110px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.show-controls .group.prev-audio,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.show-controls .group.next-audio{display:block !important}#product-browse-container #product-browse-pagination{text-align:center;clear:both}#product-browse-container #product-browse-pagination ul{display:table;margin:10px auto;padding:0;list-style-type:none}#product-browse-container #product-browse-pagination ul li{float:left}#product-browse-container #product-browse-pagination ul li a,#product-browse-container #product-browse-pagination ul li span.no-link{display:block;padding:5px 4px;cursor:pointer}
\ No newline at end of file
+#product-browse{position:relative}#product-browse #product-tag-filter-container{position:absolute;right:0px;top:10px}#product-browse #product-tag-filter-container .product-tag-group-dropdown{width:135px;margin-right:5px;float:left}#product-browse #product-tag-filter-container .product-tag-group-dropdown select{width:100%}#product-browse-container #product-browse-item-list{padding:25px 0;float:left;margin-right:-7px;margin-left:-7px;min-width:100%}#product-browse-container #product-browse-item-list.on-mobile{margin:0}#product-browse-container #product-browse-item-list .product-browse-item-row{width:100%;float:left}#product-browse-container #product-browse-item-list .product-browse-item-row.favorites-row{padding:10px 0;font-size:12px;border-top:1px solid #ccc}#product-browse-container #product-browse-item-list .product-browse-item-row.favorites-row:first-of-type{border-top:0}#product-browse-container #product-browse-item-list .product-browse-item-row.skills-row{margin:0 -22px}@media only screen and (max-width:768px){#product-browse-container #product-browse-item-list .product-browse-item-row.skills-row{margin:0}}#product-browse-container #product-browse-item-list .product-browse-item{float:left;margin-bottom:30px;position:relative;padding:0 7px}#product-browse-container #product-browse-item-list .product-browse-item>a{display:block;width:100%;height:auto;text-decoration:none}#product-browse-container #product-browse-item-list .product-browse-item>a:hover{text-decoration:none !important}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars{display:block;width:83px !important;float:left;background-image:url('../img/rating_stars.png');background-position:0px 0px;height:25px !important}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-5{background-position:0 -22px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-10{background-position:0 -44px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-15{background-position:0 -66px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-20{background-position:0 -88px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-25{background-position:0 -110px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-30{background-position:0 -132px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-35{background-position:0 -154px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-40{background-position:0 -176px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-45{background-position:0 -198px}#product-browse-container #product-browse-item-list .product-browse-item .product-score-stars.stars-50{background-position:0 -220px}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-image{width:100%;overflow:hidden;box-shadow:1px 1px 2px rgba(0,0,0,0.5);position:relative}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-image .product-browse-item-preview-music-player{position:absolute;top:0;left:0}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-image img{width:100%}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info{font-size:14px;font-weight:bold;overflow:hidden}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info h2{font-size:20px;font-weight:bold;margin-bottom:3px;white-space:nowrap;overflow:hidden;display:block;text-overflow:ellipsis;font-size:18px;min-height:22px;margin-top:8px;margin-bottom:4px}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info span{width:50%;float:left;display:block;font-weight:normal;color:black;font-size:1.2rem}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info span b{color:black;font-weight:normal}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-item-info span+span{text-align:right}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-music-item-info{font-size:14px;padding:5px;float:left;margin-bottom:5px;width:100%}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-music-item-info h2{font-size:16px;font-weight:bold;margin-bottom:3px;white-space:nowrap;overflow:hidden;display:block;text-overflow:ellipsis;margin:5px 0;width:100%}#product-browse-container #product-browse-item-list .product-browse-item .product-browse-music-item-info span{width:100%;float:left;white-space:nowrap;overflow:hidden;display:block;text-overflow:ellipsis;margin:2px 0}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter{margin-top:3px;font-size:12px;font-weight:400;margin-bottom:5px}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter .hearts-container .glyphicon{width:auto;font-size:15px;color:#c1c1c1;font-weight:normal;margin-right:5px;margin-top:0px}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter .hearts-container .glyphicon.glyphicon-heart{display:none}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter .hearts-container:hover .glyphicon{display:none}#product-browse-container #product-browse-item-list .product-browse-item .likes-counter .hearts-container:hover .glyphicon-heart{display:block ;color:red}#product-browse-container #product-browse-item-list .product-browse-item .info-container{width:100%;float:left}#product-browse-container #product-browse-item-list .product-browse-item .wrapper{width:100%;position:relative}#product-browse-container #product-browse-item-list .product-browse-item.phone-pictures .product-browse-image{border-radius:5px 5px 5px 5px}#product-browse-container #product-browse-item-list .product-browse-item.phone-pictures h2,#product-browse-container #product-browse-item-list .product-browse-item.phone-pictures span{font-size:13px;line-height:14px;font-weight:400}#product-browse-container #product-browse-item-list .product-browse-item.comics .product-browse-item-info h2{font-size:13px;line-height:14px;font-weight:400}#product-browse-container #product-browse-item-list .product-browse-item.comics .product-browse-item-info .score-container{margin-top:-10px}#product-browse-container #product-browse-item-list .product-browse-item.music *,#product-browse-container #product-browse-item-list .product-browse-item.music-test *{user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper{position:absolute;top:0;left:0;width:100%;height:40px;z-index:10}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control{float:left;background:rgba(0,0,0,0.5);height:40px;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span{display:block;padding:5px;float:left}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span svg,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span svg{font-size:28px;color:white;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span svg:hover,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span svg:hover{color:#31c27c}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span:first-child,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span:first-child,#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span:last-child,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .music-player-audio-control span:last-child{display:none}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar .track-number-display,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar .track-number-display{opacity:0;float:right;background:rgba(0,0,0,0.5);height:40px;padding:5px;color:white;font-size:12px;line-height:30px;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .music-player-audio-control span:first-child,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .music-player-audio-control span:first-child,#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .music-player-audio-control span:last-child,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .music-player-audio-control span:last-child{display:block;padding:5px 0}#product-browse-container #product-browse-item-list .product-browse-item.music .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .track-number-display,#product-browse-container #product-browse-item-list .product-browse-item.music-test .product-browse-music-player-wrapper .music-player-controls-bar.is-playing .track-number-display{opacity:1}#product-browse-container #product-browse-item-list .product-browse-item.music-test{height:150px}#product-browse-container #product-browse-item-list .product-browse-item.music-test .wrapper a.product-browse-item-wrapper{display:none}#product-browse-container #product-browse-item-list .product-browse-item.favorites{margin-bottom:0}#product-browse-container #product-browse-item-list .product-browse-item.favorites:first-of-type{border-top:0}#product-browse-container #product-browse-item-list .product-browse-item.favorites span.index{width:8.33333333%;display:block;float:left;text-align:center}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper{width:91.6666667%;display:block;float:left}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-image{width:15%;overflow:hidden;float:left}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-image img{max-width:100%;height:auto}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info{width:85%;float:left;padding-left:15px}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .info-container{width:75%;float:left}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .info-container span{width:auto;margin-right:10px}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .score-container{float:left;width:25%}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .score-container .rating{width:50%;margin-bottom:10px}#product-browse-container #product-browse-item-list .product-browse-item.favorites .product-browse-item-wrapper .product-browse-item-info .score-container .rating .rating-text{margin-bottom:5px}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper{overflow:hidden;box-shadow:1px 1px 2px rgba(0,0,0,0.5);position:relative}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper .product-browse-image{box-shadow:none}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper .product-browse-item-info{padding:5px;height:100px}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper .product-browse-item-info>span{width:100%}#product-browse-container #product-browse-item-list .product-browse-item.books .wrapper .likes-counter{margin-top:3px;font-size:12px;font-weight:400;margin-bottom:5px;position:absolute;left:5px;bottom:5px;width:100%}#product-browse-container #product-browse-item-list .product-browse-item.skills{box-shadow:none !important;padding:0 30px}#product-browse-container #product-browse-item-list .product-browse-item.skills .wrapper{width:100%;position:relative;padding:15px;box-shadow:0 0 1px rgba(0,0,0,0.5);-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item.skills .wrapper:hover,#product-browse-container #product-browse-item-list .product-browse-item.skills .wrapper:active{box-shadow:1px 1px 2px rgba(0,0,0,0.5)}#product-browse-container #product-browse-item-list .product-browse-item.skills .wrapper .product-browse-image{box-shadow:none !important}#product-browse-container #product-browse-item-list .product-browse-item.skills .wrapper .product-browse-item-info h2{color:#787878}#product-browse-container #product-browse-item-list .product-browse-item.skills .wrapper .product-browse-item-info span{width:100%;float:left;font-weight:normal;color:black;font-size:1.2rem !important;text-align:left !important;margin-top:8px;height:14px;overflow:hidden;display:block}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player{width:100%;position:absolute;top:44px;left:0;z-index:10}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player button{padding:0;background-color:transparent;border:0;outline:none !important}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player{top:-44px;position:absolute;width:100%;left:0}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .track-counter{padding:5px;height:40px;background-color:rgba(0,0,0,0.5)}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls{float:left;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls span{cursor:pointer}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls svg{font-size:28px;color:white;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out;vertical-align:middle}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .audio-player-controls svg:hover{color:#31c27c}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .player .track-counter{float:right;color:white;line-height:30px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls{width:100%;height:100px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls .play-icon,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls .pause-icon{font-size:60px;top:20px;position:absolute;left:50%;margin-left:-30px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls .prev-icon{font-size:50px;position:absolute;top:25px;left:0}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .audio-player-controls .next-icon{font-size:50px;position:absolute;top:25px;right:0}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.mobile .player .player-interface .track-counter{position:absolute;left:50%;bottom:0;height:27px;background:0;margin-left:-25px;padding:0;width:50px;text-align:center}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .music-player-counter{position:absolute;top:-44px;background-color:rgba(0,0,0,0.7);right:0;display:block;z-index:100000;height:44px;color:white;line-height:35px;padding:5px;display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel{position:absolute;height:44px;width:38px;overflow:hidden;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .play-mode-title{display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content{padding:5px;height:100%;position:relative;display:block}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .img-content,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .audio-title,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .progress-bar-content{display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content{padding:0px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group{padding:0;margin:0}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.prev-audio,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.next-audio,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.audio-lists-btn,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.play-sounds{display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.play-btn.play{margin-right:5px;margin-top:3px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-main .music-player-panel .panel-content .player-content .group.loading{margin-top:2px;margin-left:42px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile{height:auto;position:absolute;top:-44px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-header,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-singer,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-switch,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-cover,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-progress,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-operation{display:none}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-toggle{padding:0;display:flex;justify-content:center}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .react-jinke-music-player-mobile-toggle .play-btn{padding:0 20px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .group.prev-audio,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player .react-jinke-music-player-mobile .group.next-audio{display:none;padding-top:6px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.show-controls .music-player-counter{display:block}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.show-controls .react-jinke-music-player-main .music-player-panel{width:110px}#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.show-controls .group.prev-audio,#product-browse-container #product-browse-item-list .product-browse-item-preview-music-player.show-controls .group.next-audio{display:block !important}#product-browse-container #product-browse-pagination{text-align:center;clear:both}#product-browse-container #product-browse-pagination ul{display:table;margin:10px auto;padding:0;list-style-type:none}#product-browse-container #product-browse-pagination ul li{float:left}#product-browse-container #product-browse-pagination ul li a,#product-browse-container #product-browse-pagination ul li span.no-link{display:block;padding:5px 4px;cursor:pointer}
\ No newline at end of file
diff --git a/httpdocs/theme/react/assets/less/product-browse.less b/httpdocs/theme/react/assets/less/product-browse.less
index cfe6de41d..35df5653e 100644
--- a/httpdocs/theme/react/assets/less/product-browse.less
+++ b/httpdocs/theme/react/assets/less/product-browse.less
@@ -1,695 +1,743 @@
// out: ../css/product-browse.css, sourcemap: true, compress: true
@import "elements.less";
#product-browse {
position: relative;
#product-tag-filter-container {
position: absolute;
right: 0px;
top: 10px;
.product-tag-group-dropdown {
width: 135px;
margin-right: 5px;
float: left;
select {
width:100%;
}
}
}
}
#product-browse-container {
#product-browse-item-list {
padding: 25px 0;
float: left;
margin-right: -7px;
margin-left: -7px;
min-width: 100%;
&.on-mobile {
margin: 0;
}
.product-browse-item-row {
width: 100%;
float: left;
&.favorites-row {
padding: 10px 0;
font-size: 12px;
border-top: 1px solid #ccc;
&:first-of-type {
border-top: 0;
}
}
+
+ &.skills-row {
+ margin: 0 -22px;
+ @media only screen and (max-width: 768px) {
+ margin: 0;
+ }
+ }
}
.product-browse-item {
float:left;
margin-bottom:30px;
position: relative;
padding: 0 7px;
> a {
display: block;
width:100%;
height:auto;
text-decoration: none;
&:hover {
text-decoration: none !important;
}
}
.product-score-stars {
display: block;
width:83px !important;
float: left;
background-image: url('../img/rating_stars.png');
background-position: 0px 0px;
height: 25px !important;
&.stars-5 {
background-position: 0px -22px;
}
&.stars-10 {
background-position: 0px -44px;
}
&.stars-15 {
background-position: 0px -66px;
}
&.stars-20 {
background-position: 0px -88px;
}
&.stars-25 {
background-position: 0px -110px;
}
&.stars-30 {
background-position: 0px -132px;
}
&.stars-35 {
background-position: 0px -154px;
}
&.stars-40 {
background-position: 0px -176px;
}
&.stars-45 {
background-position: 0px -198px;
}
&.stars-50 {
background-position: 0px -220px;
}
}
.product-browse-image {
width: 100%;
overflow: hidden;
box-shadow: 1px 1px 2px rgba(0,0,0,0.5);
position: relative;
.product-browse-item-preview-music-player {
position: absolute;
top:0;
left:0;
}
img {
width: 100%;
}
}
.product-browse-item-info {
font-size:14px;
font-weight: bold;
overflow: hidden;
h2 {
font-size: 20px;
font-weight: bold;
margin-bottom: 3px;
white-space: nowrap;
overflow: hidden;
display: block;
text-overflow: ellipsis;
font-size: 18px;
min-height: 22px;
margin-top: 8px;
margin-bottom: 4px;
}
span {
width: 50%;
float: left;
display: block;
font-weight: normal;
color: black;
font-size: 1.2rem;
b {
color:black;
font-weight: normal;
}
}
span + span {
text-align: right;
}
}
.product-browse-music-item-info {
font-size: 14px;
padding: 5px;
float: left;
margin-bottom: 5px;
width:100%;
h2 {
font-size: 16px;
font-weight: bold;
margin-bottom: 3px;
white-space: nowrap;
overflow: hidden;
display: block;
text-overflow: ellipsis;
margin: 5px 0;
width:100%;
}
span {
width: 100%;
float: left;
white-space: nowrap;
overflow: hidden;
display: block;
text-overflow: ellipsis;
margin: 2px 0;
}
}
.likes-counter {
margin-top: 3px;
font-size: 12px;
font-weight: 400;
margin-bottom: 5px;
.hearts-container {
.glyphicon {
width: auto;
font-size: 15px;
color: #c1c1c1;
font-weight: normal;
margin-right: 5px;
margin-top: 0px;
&.glyphicon-heart {
display: none;
}
}
&:hover {
.glyphicon {
display: none;
}
.glyphicon-heart {
display: block ;
color:red;
}
}
}
}
.info-container {
width:100%;
float:left;
}
.wrapper {
width:100%;
position: relative;
}
&.phone-pictures {
.product-browse-image {
border-radius: 5px 5px 5px 5px;
}
h2, span {
font-size: 13px;
line-height: 14px;
font-weight: 400;
}
}
&.comics {
.product-browse-item-info {
h2 {
font-size: 13px;
line-height: 14px;
font-weight: 400;
}
.score-container {
margin-top: -10px;
}
}
}
&.music, &.music-test {
* {
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.product-browse-music-player-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 40px;
z-index: 10;
.music-player-controls-bar {
.music-player-audio-control {
float: left;
background: rgba(0,0,0,0.5);
height: 40px;
.transition();
span {
display: block;
padding: 5px;
float: left;
svg {
font-size: 28px;
color: white;
.transition();
&:hover {
color:#31c27c;
}
}
&:first-child, &:last-child {
display: none;
}
}
}
.track-number-display {
opacity: 0;
float: right;
background: rgba(0,0,0,0.5);
height: 40px;
padding: 5px;
color: white;
font-size: 12px;
line-height: 30px;
.transition()
}
&.is-playing {
.music-player-audio-control {
span {
&:first-child, &:last-child {
display: block;
padding: 5px 0;
}
}
}
.track-number-display {
opacity: 1;
}
}
}
}
}
&.music-test {
height: 150px;
.wrapper {
a.product-browse-item-wrapper {
display: none;
}
}
}
&.favorites {
margin-bottom: 0;
&:first-of-type {
border-top: 0;
}
span.index {
width: 8.33333333%;
display: block;
float: left;
text-align: center;
}
.product-browse-item-wrapper {
width: 91.6666667%;
display: block;
float: left;
.product-browse-image {
width:15%;
overflow: hidden;
float: left;
img {
max-width: 100%;
height: auto;
}
}
.product-browse-item-info {
width: 85%;
float: left;
padding-left:15px;
.info-container {
width: 75%;
float: left;
span {
width: auto;
margin-right:10px;
}
}
.score-container {
float: left;
width:25%;
.rating {
width:50%;
margin-bottom: 10px;
.rating-text {
margin-bottom: 5px;
}
}
}
}
}
}
&.books {
.wrapper {
overflow: hidden;
box-shadow: 1px 1px 2px rgba(0,0,0,0.5);
position: relative;
.product-browse-image {
box-shadow: none;
}
.product-browse-item-info {
padding: 5px;
height: 100px;
> span {
width: 100%;
}
}
.likes-counter {
margin-top: 3px;
font-size: 12px;
font-weight: 400;
margin-bottom: 5px;
position: absolute;
left: 5px;
bottom: 5px;
width: 100%;
}
}
}
+
+ &.skills {
+ box-shadow: none !important;
+ padding: 0 30px;
+
+ .wrapper {
+ width: 100%;
+ position: relative;
+ padding: 15px;
+ box-shadow: 0px 0px 1px rgba(0,0,0,0.5);
+ .transition();
+
+ &:hover, &:active {
+ box-shadow: 1px 1px 2px rgba(0,0,0,0.5);
+ }
+
+ .product-browse-image {
+ box-shadow: none !important;
+ }
+ .product-browse-item-info {
+
+ h2 {
+ color: #787878;
+ }
+
+ span {
+ width: 100%;
+ float: left;
+ display: block;
+ font-weight: normal;
+ color: black;
+ font-size: 1.2rem !important;
+ text-align: left !important;
+ margin-top: 8px;
+ height: 14px;
+ overflow: hidden;
+ display: block;
+ }
+ }
+ }
+ }
}
.product-browse-item-preview-music-player {
width:100%;
position: absolute;
top: 44px;
left: 0;
z-index: 10;
button {
padding: 0;
background-color: transparent;
border: 0;
outline: none !important;
}
.player {
top: -44px;
position: absolute;
width:100%;
left: 0;
.audio-player-controls, .track-counter {
padding: 5px;
height: 40px;
background-color: rgba(0,0,0,0.5);
}
.audio-player-controls {
float: left;
.transition();
span {
cursor: pointer;
}
svg {
font-size: 28px;
color:white;
.transition();
vertical-align: middle;
&:hover {
color: #31c27c;
}
}
}
.track-counter {
float: right;
color: white;
line-height: 30px;
}
}
&.mobile {
.player {
.player-interface {
.audio-player-controls {
width:100%;
height:100px;
.play-icon,
.pause-icon {
font-size: 60px;
top: 20px;
position: absolute;
left: 50%;
margin-left: -30px;
}
.prev-icon {
font-size: 50px;
position: absolute;
top: 25px;
left: 0;
}
.next-icon {
font-size: 50px;
position: absolute;
top: 25px;
right: 0;
}
}
.track-counter {
position: absolute;
left: 50%;
bottom: 0;
height: 27px;
background: 0;
margin-left: -25px;
padding: 0;
width: 50px;
text-align: center;
}
}
}
}
.music-player-counter {
position: absolute;
top: -44px;
background-color: rgba(0, 0, 0, 0.7);
right: 0;
display: block;
z-index: 100000;
height: 44px;
color: white;
line-height: 35px;
padding: 5px;
display: none;
}
.react-jinke-music-player-main .music-player-panel {
position: absolute;
height: 44px;
width: 38px;
overflow: hidden;
.transition();
.play-mode-title {
display: none;
}
.panel-content {
padding:5px;
height: 100%;
position: relative;
display: block;
.img-content,
.audio-title,
.progress-bar-content {
display: none;
}
.player-content {
padding:0px;
.group {
padding:0;
margin:0;
&.prev-audio,
&.next-audio,
&.audio-lists-btn,
&.play-sounds {
display: none;
}
&.play-btn.play {
margin-right:5px;
margin-top: 3px;
}
&.loading {
margin-top: 2px;
margin-left: 42px;
}
}
}
}
}
.react-jinke-music-player-mobile {
height: auto;
position: absolute;
top: -44px;
.react-jinke-music-player-mobile-header,
.react-jinke-music-player-mobile-singer,
.react-jinke-music-player-mobile-switch,
.react-jinke-music-player-mobile-cover,
.react-jinke-music-player-mobile-progress,
.react-jinke-music-player-mobile-operation {
display: none;
}
.react-jinke-music-player-mobile-toggle {
padding: 0;
display: flex;
justify-content: center;
.play-btn {
padding:0 20px;
}
}
.group.prev-audio,
.group.next-audio {
display: none;
padding-top: 6px;
}
}
&.show-controls {
.music-player-counter {
display: block;
}
.react-jinke-music-player-main .music-player-panel {
width:110px;
}
.group {
&.prev-audio,
&.next-audio {
display: block !important;
}
}
}
}
}
#product-browse-pagination {
text-align: center;
clear: both;
ul {
display: table;
margin: 10px auto;
padding: 0;
list-style-type: none;
li {
float: left;
a, span.no-link {
display: block;
padding: 5px 4px;
cursor: pointer;
}
}
}
}
}
\ No newline at end of file
diff --git a/httpdocs/theme/react/product-browse/app/product-browse-helpers.js b/httpdocs/theme/react/product-browse/app/product-browse-helpers.js
index 3b834fde9..5faebf734 100644
--- a/httpdocs/theme/react/product-browse/app/product-browse-helpers.js
+++ b/httpdocs/theme/react/product-browse/app/product-browse-helpers.js
@@ -1,115 +1,118 @@
export function getNumberOfItemsPerRow(browseListType,isMobile,containerWidth){
let itemsPerRow;
- if (isMobile) itemsPerRow = 2;
+ if (isMobile){
+ if (browseListType === "skills") itemsPerRow = 1;
+ else itemsPerRow = 2;
+ }
else {
if (browseListType === "music" || browseListType === "music-test") itemsPerRow = getAdujustItemsPerRow(7,containerWidth,160 + 14)
else if (browseListType === "books") itemsPerRow = getAdujustItemsPerRow(6,containerWidth,180 + 14)
else if (browseListType === "apps") itemsPerRow = getAdujustItemsPerRow(7,containerWidth,160 + 14)
else if (browseListType === "comics") itemsPerRow = getAdujustItemsPerRow(7,containerWidth,160 + 14)
else if (browseListType === "phone-pictures") itemsPerRow = getAdujustItemsPerRow(5,containerWidth,210)
else if (browseListType === "favorites" ) itemsPerRow = getAdujustItemsPerRow(1,containerWidth,containerWidth - 1);
else itemsPerRow = getAdujustItemsPerRow(3,containerWidth,250 + 14)
}
return itemsPerRow;
}
function getAdujustItemsPerRow(itemsPerRow,containerWidth,minWidth){
if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;
else {
itemsPerRow = itemsPerRow - 1;
if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;
else {
itemsPerRow = itemsPerRow - 1;
if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;
else {
itemsPerRow = itemsPerRow - 1;
if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;
else {
itemsPerRow = itemsPerRow - 1;
if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;
else {
itemsPerRow = itemsPerRow - 1;
if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;
}
}
}
}
}
}
export function chunkArray(myArray, chunk_size){
var index = 0;
var arrayLength = myArray.length;
var tempArray = [];
for (index = 0; index < arrayLength; index += chunk_size) {
const myChunk = myArray.slice(index, index+chunk_size);
// Do something if you want with the group
tempArray.push(myChunk);
}
return tempArray;
}
export function getItemWidth(browseListType,containerWidth,itemsInRow){
let itemWidth;
if (browseListType === "music" || browseListType === "music-test") itemWidth = 160 + 14;
else if (browseListType === "apps") itemWidth = 160 + 14;
else if (browseListType === "comics") itemWidth = 160 + 14;
else if (browseListType === "books") itemWidth = 180 + 14;
else itemWidth = containerWidth / itemsInRow;
return itemWidth;
}
export function getImageHeight(browseListType,itemWidth){
let itemHeightDivider, imgHeight;
itemWidth = itemWidth - 14;
if (browseListType === "music" || browseListType === "music-test"){
imgHeight = 155;
}
else if (browseListType === "apps"){
imgHeight = 155;
}
else if (browseListType === "phone-pictures"){
itemHeightDivider = .5;
imgHeight = itemWidth / itemHeightDivider;
}
else if (browseListType === "comics"){
imgHeight = 220;
}
else if (browseListType === "books"){
imgHeight = 220;
}
else if (browseListType === "favorites"){
imgHeight = 167;
}
else {
itemHeightDivider = 1.85;
imgHeight = itemWidth / itemHeightDivider;
}
return imgHeight;
}
export function getImageUrl(p,itemWidth,imgHeight){
let imgUrl = "";
if (p.image_small && p.image_small.indexOf('https://') > -1 || p.image_small && p.image_small.indexOf('http://') > -1 ) imgUrl = p.image_small;
else {
imgUrl = json_server_images;
imgUrl += "/cache/400x400/img/" + p.image_small;
}
return imgUrl;
}
export function ConvertObjectToArray(object,key){
let newArray = [];
for (var i in object){
const newObject = {
tag:object[i],
id:i
}
newArray.push(newObject);
}
return newArray;
}
\ No newline at end of file
diff --git a/httpdocs/theme/react/product-browse/app/product-browse-item.js b/httpdocs/theme/react/product-browse/app/product-browse-item.js
index 47c3eac4d..ef30cf088 100644
--- a/httpdocs/theme/react/product-browse/app/product-browse-item.js
+++ b/httpdocs/theme/react/product-browse/app/product-browse-item.js
@@ -1,721 +1,733 @@
import React, { useState, useEffect, useRef } from "react";
import { Context } from './context-provider.js';
import { isMobile } from 'react-device-detect';
import { getImageUrl } from './product-browse-helpers';
export function ProductBrowseItem(props){
const p = props.product;
const [ productFilesFetched, setProductFilesFetched ] = useState(false);
const [ productFiles, setProductFiles ] = useState();
const [ imgUrl, setImgUrl ] = useState(getImageUrl(p,props.itemWidth,props.imgHeight));
React.useEffect(() => {
if (browseListType === "music" && productFilesFetched === false ||browseListType === "music-test" && productFilesFetched === false) onMusicProductLoad()
},[])
function onMusicProductLoad(){
setProductFilesFetched(true);
const ajaxUrl = window.location.origin + "/p/"+p.project_id+"/loadfilesjson";
$.ajax({
url: ajaxUrl
}).done(function(res) {
let newProductFiles = [];
res.forEach(function(f,index){
if ( f.type.split('/')[0] === "audio" || f.type.split('/')[1] === "ogg"){
let nf = f;
nf.musicSrc = f.url.replace(/%2F/g,'/').replace(/%3A/g,':');
nf.cover = imgUrl;
newProductFiles.push(nf);
}
});
setProductFiles(newProductFiles);
});
}
function onImageLoadError(){
const ajaxUrl = window.location.origin + "/p/"+p.project_id+"/loadfilesjson";
$.ajax({
url: ajaxUrl
}).done(function(res) {
let newImgUrl;
res.forEach(function(f,index){
if ( f.type.split('/')[0] === "image"){
newImgUrl = f.url.replace(/%2F/g,'/').replace(/%3A/g,':');
}
});
if (!newImgUrl){
newImgUrl = "https://cn.opendesktop.";
newImgUrl += window.location.host.endsWith('org') === true || window.location.host.endsWith('com') === true ? "org" : "cc";
newImgUrl += "/cache/" + Math.ceil(props.itemWidth * 2) + "x" + Math.ceil(props.imgHeight * 2) + "/img/default.png";
}
setImgUrl(newImgUrl);
});
}
const productBrowseItemLikesDislpay = (
({p.count_follower}) Likes
)
let itemInfoDisplay,
musicItemInfoDisplay,
musicPlayerDisplay,
showIndex,
itemInfoHeight;
if (browseListType === "picture") {
itemInfoDisplay = (
{p.title}
{p.cat_title}
by {p.username}
)
} else if (browseListType === "apps") {
itemInfoDisplay = (
{p.title}
{p.cat_title}
by {p.username}
)
}
else if (browseListType === "phone-pictures"){
itemInfoDisplay = (
{p.title}
)
}
else if (browseListType === "comics"){
itemInfoDisplay = (
{p.title}
{productBrowseItemLikesDislpay}
)
}
else if (browseListType === "books"){
itemInfoDisplay = (
{p.title}
{p.username}
{productBrowseItemLikesDislpay}
)
}
else if (browseListType === "music" || browseListType === "music-test"){
musicItemInfoDisplay = (
{p.title}
{productBrowseItemLikesDislpay}
{p.cat_title}
by {p.username}
);
if (productFiles && productFiles.length > 0){
musicPlayerDisplay = (
)
}
}
else if (browseListType === "videos"){
itemInfoDisplay = (
{p.title}
{productBrowseItemLikesDislpay}
{p.cat_title}
by {p.username}
)
- }
+ }
+
+ else if (browseListType === "skills") {
+ console.log(p);
+ itemInfoDisplay = (
+
+
{p.title}
+ by {p.username}
+ {p.description}
+
+ )
+ }
+
else if (browseListType === "favorites"){
itemInfoHeight = props.imgHeight;
showIndex = true;
itemInfoDisplay = (
{p.title}
{p.cat_title}
by {p.username}
Score {p.laplace_score / 10}%
{p.created_at}
)
}
let indexDisplay;
if (showIndex === true){
indexDisplay = (
{props.rowIndex + 1}
)
}
let itemLink = json_serverUrl;
itemLink = is_show_real_domain_as_url === 1 ? "/" : "/s/" + json_store_name + "/";
itemLink += p.type_id === "3" ? "c" : "p";
itemLink += "/" + p.project_id;
return (
)
}
/*function ProductBrowseItemPreviewMusicPlayerTwo(props){
const {productBrowseState, productBrowseDispatch} = React.useContext(Context);
const [ productFiles, setProductFiles ] = useState(props.productFiles)
const [ showAudioControls, setShowAudioControls ] = useState(false);
const [ playIndex, setPlayIndex ] = useState(0);
let initialPLayedAudioArray = [];
if (productFiles){
productFiles.forEach(function(i,index){
const pa = {
...i,
played:0,
stopped:0
}
initialPLayedAudioArray.push(pa);
})
}
const [ playedAudioArray, setPlayedAudioArray ] = useState(initialPLayedAudioArray);
const [ isPlaying, setIsPlaying ] = useState(false);
const [ isPaused, setIsPaused ] = useState(false);
React.useEffect(() => {
if (productBrowseState.current === props.projectId){
if (productBrowseState.isPlaying === true){
playTrack();
} else {
pauseTrack()
}
} else {
if (isPlaying === true){
pauseTrack();
}
}
},[productBrowseState.current,productBrowseState.isPlaying])
function onPlayClick(pIndex){
productBrowseDispatch({type:'SET_CURRENT_ITEM',itemId:props.projectId,pIndex:pIndex});
}
function onPauseClick(){
productBrowseDispatch({type:'PAUSE'});
}
function playTrack(){
console.log('play track');
const playerElement = document.getElementById("product-browse-music-player-"+props.projectId).getElementsByTagName('audio');
let currentSrc;
if (isPaused === false) {
currentSrc = productFiles[productBrowseState.currentPlayIndex].musicSrc;
playerElement[0].src = currentSrc;
}
console.log('current src');
console.log(currentSrc);
playerElement[0].play();
setShowAudioControls(true);
setIsPlaying(true);
setIsPaused(false);
onReportAudioPlay(currentSrc);
}
function pauseTrack(){
console.log('pause track');
const playerElement = document.getElementById("product-browse-music-player-"+props.projectId).getElementsByTagName('audio');
playerElement[0].pause();
setShowAudioControls(false);
setIsPlaying(false);
setIsPaused(true);
onReportAudioStop(productFiles[playIndex].musicSrc)
}
function onPrevTrackPlayClick(){
let prevTrackIndex;
if (playIndex === 0){
prevTrackIndex = productFiles.length - 1;
} else {
prevTrackIndex = playIndex - 1;
}
setPlayIndex(prevTrackIndex);
onPlayClick(prevTrackIndex);
}
function onNextTrackPlayClick(){
let nextTrackIndex;
if (playIndex + 1 === productFiles.length){
nextTrackIndex = 0;
} else {
nextTrackIndex = playIndex + 1;
}
setPlayIndex(nextTrackIndex);
onPlayClick(nextTrackIndex);
}
function onReportAudioPlay(src){
const audioItem = playedAudioArray.find((i => i.musicSrc === src));
const audioItemIndex = playedAudioArray.findIndex((i => i.musicSrc === src));
const newAudioItem = {
...audioItem,
played:audioItem.played + 1
}
const newPLayedAudioArray = [
...playedAudioArray.slice(0,audioItemIndex),
newAudioItem,
...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
];
setPlayedAudioArray(newPLayedAudioArray);
if (playedAudioArray[audioItemIndex].played === 0){
const audioStartUrl = "https://" + window.location.hostname + "/p/" + props.projectId + "/" + 'startmediaviewajax?collection_id='+audioItem.collection_id+'&file_id='+audioItem.id+'&type_id=2';
$.ajax({url: audioStartUrl}).done(function(res) {
console.log(res);
const newAudioItem = {
...audioItem,
mediaViewId:res.MediaViewId,
played:audioItem.played + 1
}
const newPLayedAudioArray = [
...playedAudioArray.slice(0,audioItemIndex),
newAudioItem,
...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
];
// console.log('new played audio array - ');
// console.log(newPLayedAudioArray);
setPlayedAudioArray(newPLayedAudioArray);
});
}
}
function onReportAudioStop(src){
const audioItem = playedAudioArray.find((i => i.musicSrc === src));
const audioItemIndex = playedAudioArray.findIndex((i => i.musicSrc === src));
const newAudioItem = {
...audioItem,
stopped:audioItem.stopped + 1
}
const newPLayedAudioArray = [
...playedAudioArray.slice(0,audioItemIndex),
newAudioItem,
...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
];
setPlayedAudioArray(newPLayedAudioArray);
if (playedAudioArray[audioItemIndex].stopped === 0){
const audioStopUrl = "https://" + window.location.hostname + "/p/" + props.projectId + "/" + "stopmediaviewajax?media_view_id=" + playedAudioArray[audioItemIndex].mediaViewId;
$.ajax({url: audioStopUrl}).done(function(res) {
console.log(res);
});
}
}
let musicPlayerDisplay;
if (productFiles) {
const playButtonElement = (
)
const pauseButtonElement = (
)
const prevButtonElement = (
)
const nextButtonElement = (
)
let prevDisplay, nextDisplay;
if (productFiles.length > 1 && showAudioControls){
prevDisplay = onPrevTrackPlayClick()}>{prevButtonElement}
nextDisplay = onNextTrackPlayClick()}>{nextButtonElement}
}
let playButtonDisplay;
if (isPlaying === true) playButtonDisplay = onPauseClick()}>{pauseButtonElement}
else playButtonDisplay = onPlayClick(playIndex)}>{playButtonElement}
let trackCounterDisplay;
if (showAudioControls === true){
trackCounterDisplay = (
{playIndex + 1}/{productFiles.length}
)
}
musicPlayerDisplay = (
{prevDisplay}
{playButtonDisplay}
{nextDisplay}
{trackCounterDisplay}
)
}
let showControlsCssClass = "";
if (showAudioControls === true) showControlsCssClass = " show-controls"
let isMobileCssClass = "";
if (isMobile === true) isMobileCssClass = " mobile";
return (
{musicPlayerDisplay}
)
}*/
function MusicPlayerWrapper(props){
return (
)
}
function MusicPlayer(props){
/* COMPONENT */
const { productBrowseState, productBrowseDispatch } = React.useContext(Context);
const [ playIndex, setPlayIndex ] = useState(0);
const prevIndex = usePrevious(playIndex);
const [ isPlaying, setIsPlaying ] = useState();
const [ isPaused, setIsPaused ] = useState();
let initialPLayedAudioArray = []
props.items.forEach(function(i,index){
let pl = 0;
if (index === 0) pl = -1;
const pa = {
...i,
played:0,
stopped:0
}
initialPLayedAudioArray.push(pa);
})
const [ playedAudioArray, setPlayedAudioArray ] = useState(initialPLayedAudioArray);
const initialIsMobileValue = props.containerWidth < 600 ? true : false;
const [ isMobile, setIsMobile ] = useState(initialIsMobileValue);
useEffect(() => {
const playerElement = document.getElementById("music-player-container-"+props.product.project_id).getElementsByTagName('audio');
const currentSrc = props.items[playIndex].musicSrc;
playerElement[0].src = currentSrc;
playerElement[0].volume = 0.5;
},[])
useEffect(() => {
if (isPlaying) playAudio(true);
if (isPaused){
if (prevIndex === playIndex) playAudio();
else playAudio(true);
}
if (isPlaying === true) onReportAudioStop(props.items[prevIndex].musicSrc,playIndex)
},[playIndex])
React.useEffect(() => {
if (productBrowseState.current === props.product.project_id){
if (productBrowseState.isPlaying === true) playAudio(true);
else pauseAudio();
} else {
if (isPlaying === true) pauseAudio();
}
},[productBrowseState.current,productBrowseState.isPlaying])
// audio player
function onPlayClick(){ productBrowseDispatch({type:'SET_CURRENT_ITEM',itemId:props.product.project_id,pIndex:playIndex}); }
function playAudio(reload,newPlayIndex){
const playerElement = document.getElementById("music-player-container-"+props.product.project_id).getElementsByTagName('audio');
let pi = newPlayIndex ? newPlayIndex : playIndex;
const currentSrc = props.items[pi].musicSrc;
if (isPaused === false || playerElement[0].currentTime && playerElement[0].currentTime === 0 || reload === true) playerElement[0].src = currentSrc;
playerElement[0].play();
setIsPlaying(true);
setIsPaused(false);
onReportAudioPlay(currentSrc,newPlayIndex);
}
function onPauseClick(){ productBrowseDispatch({type:'PAUSE'}); }
function pauseAudio(){
const playerElement = document.getElementById("music-player-container-"+props.product.project_id).getElementsByTagName('audio');
playerElement[0].pause();
setIsPlaying(false);
setIsPaused(true);
onReportAudioStop(props.items[playIndex].musicSrc)
}
function onPrevTrackPlayClick(){
let prevTrackIndex;
if (playIndex === 0){
prevTrackIndex = props.items.length - 1;
} else {
prevTrackIndex = playIndex - 1;
}
setPlayIndex(prevTrackIndex);
}
function onNextTrackPlayClick(){
let nextTrackIndex;
if (playIndex + 1 === props.items.length){
nextTrackIndex = 0;
} else {
nextTrackIndex = playIndex + 1;
}
setPlayIndex(nextTrackIndex);
}
function onReportAudioPlay(musicSrc,newPlayIndex){
const audioItem = playedAudioArray.find((i => i.musicSrc === musicSrc));
const audioItemIndex = newPlayIndex ? newPlayIndex : playedAudioArray.findIndex((i => i.musicSrc === musicSrc));
const newAudioItem = {
...audioItem,
played:audioItem.played + 1
}
const newPLayedAudioArray = [
...playedAudioArray.slice(0,audioItemIndex),
newAudioItem,
...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
];
if (playedAudioArray[audioItemIndex].played === 0){
const audioStartUrl = "https://" + window.location.hostname + "/p/" + props.product.project_id + '/startmediaviewajax?collection_id='+audioItem.collection_id+'&file_id='+audioItem.id+'&type_id=2';
$.ajax({url: audioStartUrl}).done(function(res) {
const newAudioItem = {
...audioItem,
mediaViewId:res.MediaViewId,
played:audioItem.played + 1
}
const newPLayedAudioArray = [
...playedAudioArray.slice(0,audioItemIndex),
newAudioItem,
...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
];
setPlayedAudioArray(newPLayedAudioArray);
});
} else {
setPlayedAudioArray(newPLayedAudioArray);
}
}
function onReportAudioStop(musicSrc){
const audioItem = playedAudioArray.find((i => i.musicSrc === musicSrc));
const audioItemIndex = playedAudioArray.findIndex((i => i.musicSrc === musicSrc));
const newAudioItem = {
...audioItem,
stopped:audioItem.stopped + 1
}
const newPLayedAudioArray = [
...playedAudioArray.slice(0,audioItemIndex),
newAudioItem,
...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)
];
if (playedAudioArray[audioItemIndex].stopped === 0){
const audioStopUrl = "https://" + window.location.hostname + "/p/" + props.product.project_id + "/stopmediaviewajax?media_view_id=" + playedAudioArray[audioItemIndex].mediaViewId;
$.ajax({url: audioStopUrl}).done(function(res) {
setPlayedAudioArray(newPLayedAudioArray);
});
} else {
setPlayedAudioArray(newPLayedAudioArray);
}
}
/* RENDER */
return (
onPlayClick(reload)}
onPauseClick={onPauseClick}
onPrevTrackPlayClick={onPrevTrackPlayClick}
onNextTrackPlayClick={onNextTrackPlayClick}
items={props.items}
/>
)
}
// Hook
function usePrevious(value) {
// The ref object is a generic container whose current property is mutable ...
// ... and can hold any value, similar to an instance property on a class
const ref = useRef();
// Store current value in ref
useEffect(() => {
ref.current = value;
}, [value]); // Only re-run if value changes
// Return previous value (happens before update in useEffect above)
return ref.current;
}
function MusicPlayerControlPanel(props){
/* DISPLAY */
// audio controls display
const playButtonElement = (
)
const pauseButtonElement = (
)
const prevButtonElement = (
)
const nextButtonElement = (
)
let playButtonDisplay;
if (props.isPlaying === true){
if (props.isMobile === true) playButtonDisplay = props.onPauseClick()}>{pauseButtonElement}
else playButtonDisplay = props.onPauseClick()}>{pauseButtonElement}
} else {
if (props.isMobile === true) playButtonDisplay = props.onPlayClick()}>{playButtonElement}
else playButtonDisplay = props.onPlayClick()}>{playButtonElement}
}
let audioControlsDisplay;
if (props.isMobile === true){
audioControlsDisplay = (
props.onPrevTrackPlayClick()}>{prevButtonElement}
{playButtonDisplay}
props.onNextTrackPlayClick()}>{nextButtonElement}
)
} else {
audioControlsDisplay = (
props.onPrevTrackPlayClick()}>{prevButtonElement}
{playButtonDisplay}
props.onNextTrackPlayClick()}>{nextButtonElement}
)
}
/* RENDER */
// music player css class
let musicPlayerControlBarCssClass = "music-player-controls-bar ";
if (props.isPlaying) musicPlayerControlBarCssClass += "is-playing";
return (
{audioControlsDisplay}
{parseInt(props.playIndex + 1) + " / " + props.items.length}
)
}
export default ProductBrowseItem;
\ No newline at end of file
diff --git a/httpdocs/theme/react/product-browse/app/product-browse.js b/httpdocs/theme/react/product-browse/app/product-browse.js
index d5dffdd58..acecf0e2a 100644
--- a/httpdocs/theme/react/product-browse/app/product-browse.js
+++ b/httpdocs/theme/react/product-browse/app/product-browse.js
@@ -1,244 +1,245 @@
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import {isMobile} from 'react-device-detect';
import StoreContextProvider,{Context} from './context-provider.js';
import {ProductBrowseItem} from './product-browse-item';
import {getNumberOfItemsPerRow, getImageHeight, chunkArray, getItemWidth, ConvertObjectToArray} from './product-browse-helpers';
function ProductBrowse(){
-
+ console.log('browse list type:');
+ console.log(browseListType);
return (
)
}
function ProductBrowseFilterContainer(){
let filtersBaseUrl = json_serverUrl;
filtersBaseUrl += json_store_name === "ALL" ? "/" : "/s/" + json_store_name + "/";
filtersBaseUrl += "browse/";
if (typeof filters.category === 'number') filtersBaseUrl += "cat/" + filters.category + "/";
return (
)
}
function ProductTagGroupFilterContainer(){
const [ tagGroups, setTagGroups ] = useState([]);
const [ tagGroupIds, setTagGroupIds ] = useState([]);
const [ selectedTags, setSelectedTags ] = useState([]);
React.useState(() => {
renderTagGroups();
},[])
function renderTagGroups(){
for ( var i in tag_group_filter){
const newTagGroupIds = tagGroupIds;
newTagGroupIds.push(i);
setTagGroupIds(newTagGroupIds);
const tagGroup = tag_group_filter[i];
for (var ii in tagGroup){
if (ii === "selected_tag"){
const newSelectedTags = selectedTags;
newSelectedTags.push(tagGroup[ii]);
setSelectedTags(newSelectedTags);
} else {
const newArray = ConvertObjectToArray(tagGroup[ii],ii);
let newTagGroupsArray = tagGroups;
newTagGroupsArray.push(newArray);
setTagGroups(newTagGroupsArray);
}
}
}
}
let tagGroupsDropdownDisplay;
if (tagGroups.length > 0){
tagGroupsDropdownDisplay = tagGroups.map((tagGroup,index) => (
));
}
return (
{tagGroupsDropdownDisplay}
)
}
function TagGroupDropDownMenu(props){
function onSelectTag(e){
const serverUrl = json_serverUrl.split('://')[1];
const ajaxUrl = "https://"+ serverUrl + "/explore/savetaggroupfilter?group_id="+props.tagGroupId+"&tag_id="+e.target.value;
$.ajax({url: ajaxUrl}).done(function(res) {
window.location.reload();
});
}
const tagsDisplay = props.tagGroup.map((tag,index) => (
{tag.tag}
));
return (
onSelectTag(e)}>
{tagsDisplay}
)
}
function ProductBrowseItemList(props){
if (window.location.search === "?index=7") {
window.browseListType === "favorites";
browseListType = "favorites";
}
const [ containerWidth, setContainerWidth ] = useState($('#product-browse-container').width() + 14);
const [ itemsInRow, setItemsInRow ] = useState(getNumberOfItemsPerRow(browseListType,isMobile,containerWidth));
const [ itemWidth, setItemWidth ] = useState(getItemWidth(browseListType,containerWidth,itemsInRow));
const [ imgHeight, setImgHeight ] = useState(getImageHeight(browseListType,itemWidth));
React.useEffect(() => {
window.addEventListener("resize", function(event){ updateDimensions() });
window.addEventListener("orientationchange", function(event){ updateDimensions() });
},[])
function updateDimensions(){
const newContainerWidth = $('#product-browse-container').width() + 14;
setContainerWidth(newContainerWidth);
const newItemsInRow = getNumberOfItemsPerRow(browseListType,isMobile,newContainerWidth);
setItemsInRow(newItemsInRow);
const newItemWidth = getItemWidth(browseListType,newContainerWidth,newItemsInRow)
setItemWidth(newItemWidth);
const newImgHeight = getImageHeight(browseListType,newItemWidth);
setImgHeight(newImgHeight);
}
let productsRowsDisplay;
if (itemsInRow){
productsRowsDisplay = chunkArray(products,itemsInRow).map((ac,index) => (
))
}
return (
)
}
function ProductBrowseItemsRow(props){
const productsDisplay = props.products.map((p,index) => (
));
return (
{productsDisplay}
)
}
function ProductBrowsePagination(){
const [ totalItems, setTotalItems ] = useState(pagination.totalcount);
const [ itemsPerPage, setItemsPerPage ] = useState(50);
const [ currentPage, setCurrentPage ] = useState(pagination.page);
const [ totalPages, setTotalPages ] = useState(Math.ceil(totalItems / itemsPerPage));
const minPage = currentPage - 5 > 0 ? currentPage - 5 : 0;
const maxPage = minPage + 10 < totalPages ? minPage + 10 : totalPages;
let paginationArray = [];
for (var i = minPage; i < maxPage; i++){ paginationArray.push(i + 1); }
let pageLinkBase = json_serverUrl;
pageLinkBase += is_show_real_domain_as_url === 1 ? "/" : "/s/" + json_store_name + "/";
pageLinkBase += "browse/page/";
let pageLinkSuffix = "/"
if (typeof filters.category === 'number') pageLinkSuffix += "cat/" + filters.category + "/";
pageLinkSuffix += "ord/" + filters.order + "/";
let previousButtonDisplay;
if (currentPage > 1) previousButtonDisplay = Previous
let nextButtonDisplay;
if (currentPage < totalPages) nextButtonDisplay = Next
const paginationDisplay = paginationArray.map((p,index) => {
let pageLinkDisplay;
if (currentPage === p) pageLinkDisplay = {p}
else pageLinkDisplay = {p}
return (
{pageLinkDisplay}
)
});
return (
)
}
const rootElement = document.getElementById("product-browse-container");
ReactDOM.render( , rootElement);
\ No newline at end of file
diff --git a/httpdocs/theme/react/product-browse/product-browse.js b/httpdocs/theme/react/product-browse/product-browse.js
index 4e44e0213..033cc9953 100644
--- a/httpdocs/theme/react/product-browse/product-browse.js
+++ b/httpdocs/theme/react/product-browse/product-browse.js
@@ -1,303 +1,303 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./app/product-browse.js");
/******/ })
/************************************************************************/
/******/ ({
/***/ "./app/context-provider.js":
/*!*********************************!*\
!*** ./app/context-provider.js ***!
\*********************************/
/*! exports provided: Context, default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Context\", function() { return Context; });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _product_browse_reducer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./product-browse-reducer */ \"./app/product-browse-reducer.js\");\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\nvar Context = react__WEBPACK_IMPORTED_MODULE_0___default.a.createContext();\nvar Provider = Context.Provider;\n\nvar StoreContextProvider = function StoreContextProvider(props) {\n var _React$useReducer = react__WEBPACK_IMPORTED_MODULE_0___default.a.useReducer(_product_browse_reducer__WEBPACK_IMPORTED_MODULE_1__[\"default\"], _product_browse_reducer__WEBPACK_IMPORTED_MODULE_1__[\"productBrowseReducerInitialState\"]),\n _React$useReducer2 = _slicedToArray(_React$useReducer, 2),\n productBrowseState = _React$useReducer2[0],\n productBrowseDispatch = _React$useReducer2[1];\n\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Provider, _extends({}, props, {\n value: {\n productBrowseState: productBrowseState,\n productBrowseDispatch: productBrowseDispatch\n }\n }));\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (StoreContextProvider);\n\n//# sourceURL=webpack:///./app/context-provider.js?");
/***/ }),
/***/ "./app/product-browse-helpers.js":
/*!***************************************!*\
!*** ./app/product-browse-helpers.js ***!
\***************************************/
/*! exports provided: getNumberOfItemsPerRow, chunkArray, getItemWidth, getImageHeight, getImageUrl, ConvertObjectToArray */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getNumberOfItemsPerRow\", function() { return getNumberOfItemsPerRow; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"chunkArray\", function() { return chunkArray; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getItemWidth\", function() { return getItemWidth; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getImageHeight\", function() { return getImageHeight; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getImageUrl\", function() { return getImageUrl; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"ConvertObjectToArray\", function() { return ConvertObjectToArray; });\nfunction getNumberOfItemsPerRow(browseListType, isMobile, containerWidth) {\n var itemsPerRow;\n if (isMobile) itemsPerRow = 2;else {\n if (browseListType === \"music\" || browseListType === \"music-test\") itemsPerRow = getAdujustItemsPerRow(7, containerWidth, 160 + 14);else if (browseListType === \"books\") itemsPerRow = getAdujustItemsPerRow(6, containerWidth, 180 + 14);else if (browseListType === \"apps\") itemsPerRow = getAdujustItemsPerRow(7, containerWidth, 160 + 14);else if (browseListType === \"comics\") itemsPerRow = getAdujustItemsPerRow(7, containerWidth, 160 + 14);else if (browseListType === \"phone-pictures\") itemsPerRow = getAdujustItemsPerRow(5, containerWidth, 210);else if (browseListType === \"favorites\") itemsPerRow = getAdujustItemsPerRow(1, containerWidth, containerWidth - 1);else itemsPerRow = getAdujustItemsPerRow(3, containerWidth, 250 + 14);\n }\n return itemsPerRow;\n}\n\nfunction getAdujustItemsPerRow(itemsPerRow, containerWidth, minWidth) {\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;\n }\n }\n }\n }\n }\n}\n\nfunction chunkArray(myArray, chunk_size) {\n var index = 0;\n var arrayLength = myArray.length;\n var tempArray = [];\n\n for (index = 0; index < arrayLength; index += chunk_size) {\n var myChunk = myArray.slice(index, index + chunk_size); // Do something if you want with the group\n\n tempArray.push(myChunk);\n }\n\n return tempArray;\n}\nfunction getItemWidth(browseListType, containerWidth, itemsInRow) {\n var itemWidth;\n if (browseListType === \"music\" || browseListType === \"music-test\") itemWidth = 160 + 14;else if (browseListType === \"apps\") itemWidth = 160 + 14;else if (browseListType === \"comics\") itemWidth = 160 + 14;else if (browseListType === \"books\") itemWidth = 180 + 14;else itemWidth = containerWidth / itemsInRow;\n return itemWidth;\n}\nfunction getImageHeight(browseListType, itemWidth) {\n var itemHeightDivider, imgHeight;\n itemWidth = itemWidth - 14;\n\n if (browseListType === \"music\" || browseListType === \"music-test\") {\n imgHeight = 155;\n } else if (browseListType === \"apps\") {\n imgHeight = 155;\n } else if (browseListType === \"phone-pictures\") {\n itemHeightDivider = .5;\n imgHeight = itemWidth / itemHeightDivider;\n } else if (browseListType === \"comics\") {\n imgHeight = 220;\n } else if (browseListType === \"books\") {\n imgHeight = 220;\n } else if (browseListType === \"favorites\") {\n imgHeight = 167;\n } else {\n itemHeightDivider = 1.85;\n imgHeight = itemWidth / itemHeightDivider;\n }\n\n return imgHeight;\n}\nfunction getImageUrl(p, itemWidth, imgHeight) {\n var imgUrl = \"\";\n if (p.image_small && p.image_small.indexOf('https://') > -1 || p.image_small && p.image_small.indexOf('http://') > -1) imgUrl = p.image_small;else {\n imgUrl = json_server_images;\n imgUrl += \"/cache/400x400/img/\" + p.image_small;\n }\n return imgUrl;\n}\nfunction ConvertObjectToArray(object, key) {\n var newArray = [];\n\n for (var i in object) {\n var newObject = {\n tag: object[i],\n id: i\n };\n newArray.push(newObject);\n }\n\n return newArray;\n}\n\n//# sourceURL=webpack:///./app/product-browse-helpers.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getNumberOfItemsPerRow\", function() { return getNumberOfItemsPerRow; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"chunkArray\", function() { return chunkArray; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getItemWidth\", function() { return getItemWidth; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getImageHeight\", function() { return getImageHeight; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"getImageUrl\", function() { return getImageUrl; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"ConvertObjectToArray\", function() { return ConvertObjectToArray; });\nfunction getNumberOfItemsPerRow(browseListType, isMobile, containerWidth) {\n var itemsPerRow;\n\n if (isMobile) {\n if (browseListType === \"skills\") itemsPerRow = 1;else itemsPerRow = 2;\n } else {\n if (browseListType === \"music\" || browseListType === \"music-test\") itemsPerRow = getAdujustItemsPerRow(7, containerWidth, 160 + 14);else if (browseListType === \"books\") itemsPerRow = getAdujustItemsPerRow(6, containerWidth, 180 + 14);else if (browseListType === \"apps\") itemsPerRow = getAdujustItemsPerRow(7, containerWidth, 160 + 14);else if (browseListType === \"comics\") itemsPerRow = getAdujustItemsPerRow(7, containerWidth, 160 + 14);else if (browseListType === \"phone-pictures\") itemsPerRow = getAdujustItemsPerRow(5, containerWidth, 210);else if (browseListType === \"favorites\") itemsPerRow = getAdujustItemsPerRow(1, containerWidth, containerWidth - 1);else itemsPerRow = getAdujustItemsPerRow(3, containerWidth, 250 + 14);\n }\n\n return itemsPerRow;\n}\n\nfunction getAdujustItemsPerRow(itemsPerRow, containerWidth, minWidth) {\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;else {\n itemsPerRow = itemsPerRow - 1;\n if (containerWidth / itemsPerRow > minWidth) return itemsPerRow;\n }\n }\n }\n }\n }\n}\n\nfunction chunkArray(myArray, chunk_size) {\n var index = 0;\n var arrayLength = myArray.length;\n var tempArray = [];\n\n for (index = 0; index < arrayLength; index += chunk_size) {\n var myChunk = myArray.slice(index, index + chunk_size); // Do something if you want with the group\n\n tempArray.push(myChunk);\n }\n\n return tempArray;\n}\nfunction getItemWidth(browseListType, containerWidth, itemsInRow) {\n var itemWidth;\n if (browseListType === \"music\" || browseListType === \"music-test\") itemWidth = 160 + 14;else if (browseListType === \"apps\") itemWidth = 160 + 14;else if (browseListType === \"comics\") itemWidth = 160 + 14;else if (browseListType === \"books\") itemWidth = 180 + 14;else itemWidth = containerWidth / itemsInRow;\n return itemWidth;\n}\nfunction getImageHeight(browseListType, itemWidth) {\n var itemHeightDivider, imgHeight;\n itemWidth = itemWidth - 14;\n\n if (browseListType === \"music\" || browseListType === \"music-test\") {\n imgHeight = 155;\n } else if (browseListType === \"apps\") {\n imgHeight = 155;\n } else if (browseListType === \"phone-pictures\") {\n itemHeightDivider = .5;\n imgHeight = itemWidth / itemHeightDivider;\n } else if (browseListType === \"comics\") {\n imgHeight = 220;\n } else if (browseListType === \"books\") {\n imgHeight = 220;\n } else if (browseListType === \"favorites\") {\n imgHeight = 167;\n } else {\n itemHeightDivider = 1.85;\n imgHeight = itemWidth / itemHeightDivider;\n }\n\n return imgHeight;\n}\nfunction getImageUrl(p, itemWidth, imgHeight) {\n var imgUrl = \"\";\n if (p.image_small && p.image_small.indexOf('https://') > -1 || p.image_small && p.image_small.indexOf('http://') > -1) imgUrl = p.image_small;else {\n imgUrl = json_server_images;\n imgUrl += \"/cache/400x400/img/\" + p.image_small;\n }\n return imgUrl;\n}\nfunction ConvertObjectToArray(object, key) {\n var newArray = [];\n\n for (var i in object) {\n var newObject = {\n tag: object[i],\n id: i\n };\n newArray.push(newObject);\n }\n\n return newArray;\n}\n\n//# sourceURL=webpack:///./app/product-browse-helpers.js?");
/***/ }),
/***/ "./app/product-browse-item.js":
/*!************************************!*\
!*** ./app/product-browse-item.js ***!
\************************************/
/*! exports provided: ProductBrowseItem, default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"ProductBrowseItem\", function() { return ProductBrowseItem; });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _context_provider_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./context-provider.js */ \"./app/context-provider.js\");\n/* harmony import */ var react_device_detect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-device-detect */ \"./node_modules/react-device-detect/dist/index.js\");\n/* harmony import */ var react_device_detect__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_device_detect__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _product_browse_helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./product-browse-helpers */ \"./app/product-browse-helpers.js\");\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\nfunction ProductBrowseItem(props) {\n var p = props.product;\n\n var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(false),\n _useState2 = _slicedToArray(_useState, 2),\n productFilesFetched = _useState2[0],\n setProductFilesFetched = _useState2[1];\n\n var _useState3 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(),\n _useState4 = _slicedToArray(_useState3, 2),\n productFiles = _useState4[0],\n setProductFiles = _useState4[1];\n\n var _useState5 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_3__[\"getImageUrl\"])(p, props.itemWidth, props.imgHeight)),\n _useState6 = _slicedToArray(_useState5, 2),\n imgUrl = _useState6[0],\n setImgUrl = _useState6[1];\n\n react__WEBPACK_IMPORTED_MODULE_0___default.a.useEffect(function () {\n if (browseListType === \"music\" && productFilesFetched === false || browseListType === \"music-test\" && productFilesFetched === false) onMusicProductLoad();\n }, []);\n\n function onMusicProductLoad() {\n setProductFilesFetched(true);\n var ajaxUrl = window.location.origin + \"/p/\" + p.project_id + \"/loadfilesjson\";\n $.ajax({\n url: ajaxUrl\n }).done(function (res) {\n var newProductFiles = [];\n res.forEach(function (f, index) {\n if (f.type.split('/')[0] === \"audio\" || f.type.split('/')[1] === \"ogg\") {\n var nf = f;\n nf.musicSrc = f.url.replace(/%2F/g, '/').replace(/%3A/g, ':');\n nf.cover = imgUrl;\n newProductFiles.push(nf);\n }\n });\n setProductFiles(newProductFiles);\n });\n }\n\n function onImageLoadError() {\n var ajaxUrl = window.location.origin + \"/p/\" + p.project_id + \"/loadfilesjson\";\n $.ajax({\n url: ajaxUrl\n }).done(function (res) {\n var newImgUrl;\n res.forEach(function (f, index) {\n if (f.type.split('/')[0] === \"image\") {\n newImgUrl = f.url.replace(/%2F/g, '/').replace(/%3A/g, ':');\n }\n });\n\n if (!newImgUrl) {\n newImgUrl = \"https://cn.opendesktop.\";\n newImgUrl += window.location.host.endsWith('org') === true || window.location.host.endsWith('com') === true ? \"org\" : \"cc\";\n newImgUrl += \"/cache/\" + Math.ceil(props.itemWidth * 2) + \"x\" + Math.ceil(props.imgHeight * 2) + \"/img/default.png\";\n }\n\n setImgUrl(newImgUrl);\n });\n }\n\n var productBrowseItemLikesDislpay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"likes-counter\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"hearts-container\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"glyphicon glyphicon-heart\"\n }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"glyphicon glyphicon-heart-empty\"\n })), \"(\", p.count_follower, \") Likes\");\n var itemInfoDisplay, musicItemInfoDisplay, musicPlayerDisplay, showIndex, itemInfoHeight;\n\n if (browseListType === \"picture\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username)));\n } else if (browseListType === \"apps\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username)));\n } else if (browseListType === \"phone-pictures\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title));\n } else if (browseListType === \"comics\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), productBrowseItemLikesDislpay);\n } else if (browseListType === \"books\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.username), productBrowseItemLikesDislpay);\n } else if (browseListType === \"music\" || browseListType === \"music-test\") {\n musicItemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-music-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), productBrowseItemLikesDislpay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username)));\n\n if (productFiles && productFiles.length > 0) {\n musicPlayerDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(MusicPlayerWrapper, {\n product: p,\n items: productFiles\n });\n }\n } else if (browseListType === \"videos\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), productBrowseItemLikesDislpay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"info-container\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username))));\n } else if (browseListType === \"favorites\") {\n itemInfoHeight = props.imgHeight;\n showIndex = true;\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"info-container\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"score-container\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"explore-product-plings\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"rating\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"rating-text\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"small\", {\n className: \"center-block text-center\"\n }, \"Score \", p.laplace_score / 10, \"%\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"progress\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"progress-bar\",\n style: {\n \"backgroundColor\": \"#c8c8c8\",\n \"width\": p.laplace_score / 10 + \"%\"\n }\n }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"progress-bar\",\n style: {\n \"backgroundColor\": \"#eeeeee\",\n \"opacity\": \"0.5\",\n \"width\": 100 - p.laplace_score / 10 + \"%\"\n }\n }))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"collected\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.created_at)))));\n }\n\n var indexDisplay;\n\n if (showIndex === true) {\n indexDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"index\"\n }, props.rowIndex + 1);\n }\n\n var itemLink = json_serverUrl;\n itemLink = is_show_real_domain_as_url === 1 ? \"/\" : \"/s/\" + json_store_name + \"/\";\n itemLink += p.type_id === \"3\" ? \"c\" : \"p\";\n itemLink += \"/\" + p.project_id;\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item \" + browseListType,\n id: \"product-\" + p.project_id,\n style: {\n \"width\": props.itemWidth\n }\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"wrapper\"\n }, indexDisplay, musicPlayerDisplay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: itemLink,\n className: \"product-browse-item-wrapper\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-image\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"img\", {\n src: imgUrl,\n height: props.imgHeight,\n onError: onImageLoadError\n }), musicItemInfoDisplay), itemInfoDisplay)));\n}\n/*function ProductBrowseItemPreviewMusicPlayerTwo(props){\r\n\r\n const {productBrowseState, productBrowseDispatch} = React.useContext(Context);\r\n\r\n const [ productFiles, setProductFiles ] = useState(props.productFiles)\r\n\r\n const [ showAudioControls, setShowAudioControls ] = useState(false);\r\n const [ playIndex, setPlayIndex ] = useState(0);\r\n let initialPLayedAudioArray = [];\r\n if (productFiles){\r\n productFiles.forEach(function(i,index){\r\n const pa = {\r\n ...i,\r\n played:0,\r\n stopped:0\r\n }\r\n initialPLayedAudioArray.push(pa);\r\n })\r\n }\r\n const [ playedAudioArray, setPlayedAudioArray ] = useState(initialPLayedAudioArray);\r\n const [ isPlaying, setIsPlaying ] = useState(false);\r\n const [ isPaused, setIsPaused ] = useState(false);\r\n\r\n React.useEffect(() => {\r\n if (productBrowseState.current === props.projectId){\r\n if (productBrowseState.isPlaying === true){\r\n playTrack();\r\n } else {\r\n pauseTrack()\r\n }\r\n } else {\r\n if (isPlaying === true){\r\n pauseTrack();\r\n }\r\n }\r\n },[productBrowseState.current,productBrowseState.isPlaying])\r\n\r\n function onPlayClick(pIndex){\r\n productBrowseDispatch({type:'SET_CURRENT_ITEM',itemId:props.projectId,pIndex:pIndex});\r\n }\r\n\r\n function onPauseClick(){\r\n productBrowseDispatch({type:'PAUSE'});\r\n }\r\n\r\n function playTrack(){\r\n console.log('play track');\r\n const playerElement = document.getElementById(\"product-browse-music-player-\"+props.projectId).getElementsByTagName('audio');\r\n let currentSrc;\r\n if (isPaused === false) {\r\n currentSrc = productFiles[productBrowseState.currentPlayIndex].musicSrc;\r\n playerElement[0].src = currentSrc;\r\n }\r\n console.log('current src');\r\n console.log(currentSrc);\r\n playerElement[0].play();\r\n setShowAudioControls(true);\r\n setIsPlaying(true);\r\n setIsPaused(false);\r\n onReportAudioPlay(currentSrc);\r\n }\r\n\r\n function pauseTrack(){\r\n console.log('pause track');\r\n const playerElement = document.getElementById(\"product-browse-music-player-\"+props.projectId).getElementsByTagName('audio');\r\n playerElement[0].pause();\r\n setShowAudioControls(false);\r\n setIsPlaying(false);\r\n setIsPaused(true);\r\n onReportAudioStop(productFiles[playIndex].musicSrc)\r\n }\r\n\r\n function onPrevTrackPlayClick(){\r\n let prevTrackIndex;\r\n if (playIndex === 0){\r\n prevTrackIndex = productFiles.length - 1;\r\n } else {\r\n prevTrackIndex = playIndex - 1;\r\n }\r\n setPlayIndex(prevTrackIndex);\r\n onPlayClick(prevTrackIndex);\r\n }\r\n\r\n function onNextTrackPlayClick(){\r\n let nextTrackIndex;\r\n if (playIndex + 1 === productFiles.length){\r\n nextTrackIndex = 0;\r\n } else {\r\n nextTrackIndex = playIndex + 1;\r\n }\r\n setPlayIndex(nextTrackIndex);\r\n onPlayClick(nextTrackIndex);\r\n }\r\n\r\n function onReportAudioPlay(src){\r\n const audioItem = playedAudioArray.find((i => i.musicSrc === src));\r\n const audioItemIndex = playedAudioArray.findIndex((i => i.musicSrc === src));\r\n const newAudioItem = {\r\n ...audioItem,\r\n played:audioItem.played + 1\r\n }\r\n const newPLayedAudioArray = [\r\n ...playedAudioArray.slice(0,audioItemIndex),\r\n newAudioItem,\r\n ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)\r\n ];\r\n setPlayedAudioArray(newPLayedAudioArray);\r\n\r\n if (playedAudioArray[audioItemIndex].played === 0){\r\n \r\n const audioStartUrl = \"https://\" + window.location.hostname + \"/p/\" + props.projectId + \"/\" + 'startmediaviewajax?collection_id='+audioItem.collection_id+'&file_id='+audioItem.id+'&type_id=2';\r\n\r\n $.ajax({url: audioStartUrl}).done(function(res) { \r\n console.log(res);\r\n const newAudioItem = {\r\n ...audioItem,\r\n mediaViewId:res.MediaViewId,\r\n played:audioItem.played + 1\r\n }\r\n const newPLayedAudioArray = [\r\n ...playedAudioArray.slice(0,audioItemIndex),\r\n newAudioItem,\r\n ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)\r\n ];\r\n // console.log('new played audio array - ');\r\n // console.log(newPLayedAudioArray);\r\n setPlayedAudioArray(newPLayedAudioArray);\r\n });\r\n } \r\n }\r\n \r\n function onReportAudioStop(src){\r\n\r\n const audioItem = playedAudioArray.find((i => i.musicSrc === src));\r\n const audioItemIndex = playedAudioArray.findIndex((i => i.musicSrc === src));\r\n const newAudioItem = {\r\n ...audioItem,\r\n stopped:audioItem.stopped + 1\r\n }\r\n const newPLayedAudioArray = [\r\n ...playedAudioArray.slice(0,audioItemIndex),\r\n newAudioItem,\r\n ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)\r\n ];\r\n setPlayedAudioArray(newPLayedAudioArray);\r\n \r\n if (playedAudioArray[audioItemIndex].stopped === 0){\r\n const audioStopUrl = \"https://\" + window.location.hostname + \"/p/\" + props.projectId + \"/\" + \"stopmediaviewajax?media_view_id=\" + playedAudioArray[audioItemIndex].mediaViewId;\r\n\r\n $.ajax({url: audioStopUrl}).done(function(res) { \r\n console.log(res);\r\n });\r\n }\r\n }\r\n\r\n let musicPlayerDisplay;\r\n if (productFiles) {\r\n\r\n const playButtonElement = (\r\n \r\n \r\n \r\n )\r\n\r\n const pauseButtonElement = (\r\n \r\n \r\n \r\n )\r\n\r\n const prevButtonElement = (\r\n \r\n \r\n \r\n )\r\n\r\n const nextButtonElement = (\r\n \r\n \r\n \r\n )\r\n\r\n let prevDisplay, nextDisplay;\r\n if (productFiles.length > 1 && showAudioControls){\r\n prevDisplay = onPrevTrackPlayClick()}>{prevButtonElement} \r\n nextDisplay = onNextTrackPlayClick()}>{nextButtonElement} \r\n }\r\n\r\n let playButtonDisplay;\r\n if (isPlaying === true) playButtonDisplay = onPauseClick()}>{pauseButtonElement} \r\n else playButtonDisplay = onPlayClick(playIndex)}>{playButtonElement} \r\n\r\n let trackCounterDisplay;\r\n if (showAudioControls === true){\r\n trackCounterDisplay = (\r\n \r\n {playIndex + 1}/{productFiles.length}\r\n
\r\n )\r\n }\r\n \r\n musicPlayerDisplay = (\r\n \r\n
\r\n
\r\n
\r\n {prevDisplay}\r\n {playButtonDisplay}\r\n {nextDisplay}\r\n
\r\n {trackCounterDisplay}\r\n
\r\n
\r\n )\r\n }\r\n\r\n let showControlsCssClass = \"\";\r\n if (showAudioControls === true) showControlsCssClass = \" show-controls\"\r\n\r\n let isMobileCssClass = \"\";\r\n if (isMobile === true) isMobileCssClass = \" mobile\";\r\n\r\n return (\r\n \r\n {musicPlayerDisplay}\r\n
\r\n )\r\n}*/\n\nfunction MusicPlayerWrapper(props) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(MusicPlayer, {\n product: props.product,\n items: props.items,\n containerWidth: props.width\n }));\n}\n\nfunction MusicPlayer(props) {\n /* COMPONENT */\n var _React$useContext = react__WEBPACK_IMPORTED_MODULE_0___default.a.useContext(_context_provider_js__WEBPACK_IMPORTED_MODULE_1__[\"Context\"]),\n productBrowseState = _React$useContext.productBrowseState,\n productBrowseDispatch = _React$useContext.productBrowseDispatch;\n\n var _useState7 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(0),\n _useState8 = _slicedToArray(_useState7, 2),\n playIndex = _useState8[0],\n setPlayIndex = _useState8[1];\n\n var prevIndex = usePrevious(playIndex);\n\n var _useState9 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(),\n _useState10 = _slicedToArray(_useState9, 2),\n isPlaying = _useState10[0],\n setIsPlaying = _useState10[1];\n\n var _useState11 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(),\n _useState12 = _slicedToArray(_useState11, 2),\n isPaused = _useState12[0],\n setIsPaused = _useState12[1];\n\n var initialPLayedAudioArray = [];\n props.items.forEach(function (i, index) {\n var pl = 0;\n if (index === 0) pl = -1;\n\n var pa = _objectSpread({}, i, {\n played: 0,\n stopped: 0\n });\n\n initialPLayedAudioArray.push(pa);\n });\n\n var _useState13 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(initialPLayedAudioArray),\n _useState14 = _slicedToArray(_useState13, 2),\n playedAudioArray = _useState14[0],\n setPlayedAudioArray = _useState14[1];\n\n var initialIsMobileValue = props.containerWidth < 600 ? true : false;\n\n var _useState15 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(initialIsMobileValue),\n _useState16 = _slicedToArray(_useState15, 2),\n isMobile = _useState16[0],\n setIsMobile = _useState16[1];\n\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n var playerElement = document.getElementById(\"music-player-container-\" + props.product.project_id).getElementsByTagName('audio');\n var currentSrc = props.items[playIndex].musicSrc;\n playerElement[0].src = currentSrc;\n playerElement[0].volume = 0.5;\n }, []);\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n if (isPlaying) playAudio(true);\n\n if (isPaused) {\n if (prevIndex === playIndex) playAudio();else playAudio(true);\n }\n\n if (isPlaying === true) onReportAudioStop(props.items[prevIndex].musicSrc, playIndex);\n }, [playIndex]);\n react__WEBPACK_IMPORTED_MODULE_0___default.a.useEffect(function () {\n if (productBrowseState.current === props.product.project_id) {\n if (productBrowseState.isPlaying === true) playAudio(true);else pauseAudio();\n } else {\n if (isPlaying === true) pauseAudio();\n }\n }, [productBrowseState.current, productBrowseState.isPlaying]); // audio player\n\n function _onPlayClick() {\n productBrowseDispatch({\n type: 'SET_CURRENT_ITEM',\n itemId: props.product.project_id,\n pIndex: playIndex\n });\n }\n\n function playAudio(reload, newPlayIndex) {\n var playerElement = document.getElementById(\"music-player-container-\" + props.product.project_id).getElementsByTagName('audio');\n var pi = newPlayIndex ? newPlayIndex : playIndex;\n var currentSrc = props.items[pi].musicSrc;\n if (isPaused === false || playerElement[0].currentTime && playerElement[0].currentTime === 0 || reload === true) playerElement[0].src = currentSrc;\n playerElement[0].play();\n setIsPlaying(true);\n setIsPaused(false);\n onReportAudioPlay(currentSrc, newPlayIndex);\n }\n\n function onPauseClick() {\n productBrowseDispatch({\n type: 'PAUSE'\n });\n }\n\n function pauseAudio() {\n var playerElement = document.getElementById(\"music-player-container-\" + props.product.project_id).getElementsByTagName('audio');\n playerElement[0].pause();\n setIsPlaying(false);\n setIsPaused(true);\n onReportAudioStop(props.items[playIndex].musicSrc);\n }\n\n function onPrevTrackPlayClick() {\n var prevTrackIndex;\n\n if (playIndex === 0) {\n prevTrackIndex = props.items.length - 1;\n } else {\n prevTrackIndex = playIndex - 1;\n }\n\n setPlayIndex(prevTrackIndex);\n }\n\n function onNextTrackPlayClick() {\n var nextTrackIndex;\n\n if (playIndex + 1 === props.items.length) {\n nextTrackIndex = 0;\n } else {\n nextTrackIndex = playIndex + 1;\n }\n\n setPlayIndex(nextTrackIndex);\n }\n\n function onReportAudioPlay(musicSrc, newPlayIndex) {\n var audioItem = playedAudioArray.find(function (i) {\n return i.musicSrc === musicSrc;\n });\n var audioItemIndex = newPlayIndex ? newPlayIndex : playedAudioArray.findIndex(function (i) {\n return i.musicSrc === musicSrc;\n });\n\n var newAudioItem = _objectSpread({}, audioItem, {\n played: audioItem.played + 1\n });\n\n var newPLayedAudioArray = [].concat(_toConsumableArray(playedAudioArray.slice(0, audioItemIndex)), [newAudioItem], _toConsumableArray(playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)));\n\n if (playedAudioArray[audioItemIndex].played === 0) {\n var audioStartUrl = \"https://\" + window.location.hostname + \"/p/\" + props.product.project_id + '/startmediaviewajax?collection_id=' + audioItem.collection_id + '&file_id=' + audioItem.id + '&type_id=2';\n $.ajax({\n url: audioStartUrl\n }).done(function (res) {\n var newAudioItem = _objectSpread({}, audioItem, {\n mediaViewId: res.MediaViewId,\n played: audioItem.played + 1\n });\n\n var newPLayedAudioArray = [].concat(_toConsumableArray(playedAudioArray.slice(0, audioItemIndex)), [newAudioItem], _toConsumableArray(playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)));\n setPlayedAudioArray(newPLayedAudioArray);\n });\n } else {\n setPlayedAudioArray(newPLayedAudioArray);\n }\n }\n\n function onReportAudioStop(musicSrc) {\n var audioItem = playedAudioArray.find(function (i) {\n return i.musicSrc === musicSrc;\n });\n var audioItemIndex = playedAudioArray.findIndex(function (i) {\n return i.musicSrc === musicSrc;\n });\n\n var newAudioItem = _objectSpread({}, audioItem, {\n stopped: audioItem.stopped + 1\n });\n\n var newPLayedAudioArray = [].concat(_toConsumableArray(playedAudioArray.slice(0, audioItemIndex)), [newAudioItem], _toConsumableArray(playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)));\n\n if (playedAudioArray[audioItemIndex].stopped === 0) {\n var audioStopUrl = \"https://\" + window.location.hostname + \"/p/\" + props.product.project_id + \"/stopmediaviewajax?media_view_id=\" + playedAudioArray[audioItemIndex].mediaViewId;\n $.ajax({\n url: audioStopUrl\n }).done(function (res) {\n setPlayedAudioArray(newPLayedAudioArray);\n });\n } else {\n setPlayedAudioArray(newPLayedAudioArray);\n }\n }\n /* RENDER */\n\n\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"music-player-container-\" + props.product.project_id,\n className: \"product-browse-music-player-wrapper\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"audio\", {\n volume: 0.5,\n id: \"music-player-audio-\" + props.product.project_id\n }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(MusicPlayerControlPanel, {\n playIndex: playIndex,\n isPlaying: isPlaying,\n isPaused: isPaused,\n isMobile: isMobile,\n onPlayClick: function onPlayClick(reload) {\n return _onPlayClick(reload);\n },\n onPauseClick: onPauseClick,\n onPrevTrackPlayClick: onPrevTrackPlayClick,\n onNextTrackPlayClick: onNextTrackPlayClick,\n items: props.items\n }));\n} // Hook\n\n\nfunction usePrevious(value) {\n // The ref object is a generic container whose current property is mutable ...\n // ... and can hold any value, similar to an instance property on a class\n var ref = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useRef\"])(); // Store current value in ref\n\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n ref.current = value;\n }, [value]); // Only re-run if value changes\n // Return previous value (happens before update in useEffect above)\n\n return ref.current;\n}\n\nfunction MusicPlayerControlPanel(props) {\n /* DISPLAY */\n // audio controls display\n var playButtonElement = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"svg\", {\n fill: \"currentColor\",\n preserveAspectRatio: \"xMidYMid meet\",\n height: \"1em\",\n width: \"1em\",\n viewBox: \"0 0 40 40\",\n className: \"play-icon\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"g\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"path\", {\n d: \"m20.1 2.9q4.7 0 8.6 2.3t6.3 6.2 2.3 8.6-2.3 8.6-6.3 6.2-8.6 2.3-8.6-2.3-6.2-6.2-2.3-8.6 2.3-8.6 6.2-6.2 8.6-2.3z m8.6 18.3q0.7-0.4 0.7-1.2t-0.7-1.2l-12.1-7.2q-0.7-0.4-1.5 0-0.7 0.4-0.7 1.3v14.2q0 0.9 0.7 1.3 0.4 0.2 0.8 0.2 0.3 0 0.7-0.2z\"\n })));\n var pauseButtonElement = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"svg\", {\n fill: \"currentColor\",\n preserveAspectRatio: \"xMidYMid meet\",\n height: \"1em\",\n width: \"1em\",\n viewBox: \"0 0 40 40\",\n className: \"pause-icon\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"g\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"path\", {\n d: \"m18.7 26.4v-12.8q0-0.3-0.2-0.5t-0.5-0.2h-5.7q-0.3 0-0.5 0.2t-0.2 0.5v12.8q0 0.3 0.2 0.5t0.5 0.2h5.7q0.3 0 0.5-0.2t0.2-0.5z m10 0v-12.8q0-0.3-0.2-0.5t-0.5-0.2h-5.7q-0.3 0-0.5 0.2t-0.2 0.5v12.8q0 0.3 0.2 0.5t0.5 0.2h5.7q0.3 0 0.5-0.2t0.2-0.5z m8.6-6.4q0 4.7-2.3 8.6t-6.3 6.2-8.6 2.3-8.6-2.3-6.2-6.2-2.3-8.6 2.3-8.6 6.2-6.2 8.6-2.3 8.6 2.3 6.3 6.2 2.3 8.6z\"\n })));\n var prevButtonElement = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"svg\", {\n fill: \"currentColor\",\n preserveAspectRatio: \"xMidYMid meet\",\n height: \"1em\",\n width: \"1em\",\n viewBox: \"0 0 40 40\",\n className: \"prev-icon\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"g\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"path\", {\n d: \"m15.9 20l14.1-10v20z m-5.9-10h3.4v20h-3.4v-20z\"\n })));\n var nextButtonElement = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"svg\", {\n fill: \"currentColor\",\n preserveAspectRatio: \"xMidYMid meet\",\n height: \"1em\",\n width: \"1em\",\n viewBox: \"0 0 40 40\",\n className: \"next-icon\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"g\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"path\", {\n d: \"m26.6 10h3.4v20h-3.4v-20z m-16.6 20v-20l14.1 10z\"\n })));\n var playButtonDisplay;\n\n if (props.isPlaying === true) {\n if (props.isMobile === true) playButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onTouchStart: function onTouchStart() {\n return props.onPauseClick();\n }\n }, pauseButtonElement);else playButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onClick: function onClick() {\n return props.onPauseClick();\n }\n }, pauseButtonElement);\n } else {\n if (props.isMobile === true) playButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onTouchStart: function onTouchStart() {\n return props.onPlayClick();\n }\n }, playButtonElement);else playButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onClick: function onClick() {\n return props.onPlayClick();\n }\n }, playButtonElement);\n }\n\n var audioControlsDisplay;\n\n if (props.isMobile === true) {\n audioControlsDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"music-player-audio-control\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onTouchStart: function onTouchStart() {\n return props.onPrevTrackPlayClick();\n }\n }, prevButtonElement), playButtonDisplay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onTouchStart: function onTouchStart() {\n return props.onNextTrackPlayClick();\n }\n }, nextButtonElement));\n } else {\n audioControlsDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"music-player-audio-control\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onClick: function onClick() {\n return props.onPrevTrackPlayClick();\n }\n }, prevButtonElement), playButtonDisplay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onClick: function onClick() {\n return props.onNextTrackPlayClick();\n }\n }, nextButtonElement));\n }\n /* RENDER */\n // music player css class\n\n\n var musicPlayerControlBarCssClass = \"music-player-controls-bar \";\n if (props.isPlaying) musicPlayerControlBarCssClass += \"is-playing\";\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"music-player-control-panel\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: musicPlayerControlBarCssClass\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"music-player-controls-wrapper\"\n }, audioControlsDisplay), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"track-number-display\"\n }, parseInt(props.playIndex + 1) + \" / \" + props.items.length)));\n}\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (ProductBrowseItem);\n\n//# sourceURL=webpack:///./app/product-browse-item.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"ProductBrowseItem\", function() { return ProductBrowseItem; });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _context_provider_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./context-provider.js */ \"./app/context-provider.js\");\n/* harmony import */ var react_device_detect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-device-detect */ \"./node_modules/react-device-detect/dist/index.js\");\n/* harmony import */ var react_device_detect__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_device_detect__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _product_browse_helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./product-browse-helpers */ \"./app/product-browse-helpers.js\");\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\nfunction ProductBrowseItem(props) {\n var p = props.product;\n\n var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(false),\n _useState2 = _slicedToArray(_useState, 2),\n productFilesFetched = _useState2[0],\n setProductFilesFetched = _useState2[1];\n\n var _useState3 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(),\n _useState4 = _slicedToArray(_useState3, 2),\n productFiles = _useState4[0],\n setProductFiles = _useState4[1];\n\n var _useState5 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_3__[\"getImageUrl\"])(p, props.itemWidth, props.imgHeight)),\n _useState6 = _slicedToArray(_useState5, 2),\n imgUrl = _useState6[0],\n setImgUrl = _useState6[1];\n\n react__WEBPACK_IMPORTED_MODULE_0___default.a.useEffect(function () {\n if (browseListType === \"music\" && productFilesFetched === false || browseListType === \"music-test\" && productFilesFetched === false) onMusicProductLoad();\n }, []);\n\n function onMusicProductLoad() {\n setProductFilesFetched(true);\n var ajaxUrl = window.location.origin + \"/p/\" + p.project_id + \"/loadfilesjson\";\n $.ajax({\n url: ajaxUrl\n }).done(function (res) {\n var newProductFiles = [];\n res.forEach(function (f, index) {\n if (f.type.split('/')[0] === \"audio\" || f.type.split('/')[1] === \"ogg\") {\n var nf = f;\n nf.musicSrc = f.url.replace(/%2F/g, '/').replace(/%3A/g, ':');\n nf.cover = imgUrl;\n newProductFiles.push(nf);\n }\n });\n setProductFiles(newProductFiles);\n });\n }\n\n function onImageLoadError() {\n var ajaxUrl = window.location.origin + \"/p/\" + p.project_id + \"/loadfilesjson\";\n $.ajax({\n url: ajaxUrl\n }).done(function (res) {\n var newImgUrl;\n res.forEach(function (f, index) {\n if (f.type.split('/')[0] === \"image\") {\n newImgUrl = f.url.replace(/%2F/g, '/').replace(/%3A/g, ':');\n }\n });\n\n if (!newImgUrl) {\n newImgUrl = \"https://cn.opendesktop.\";\n newImgUrl += window.location.host.endsWith('org') === true || window.location.host.endsWith('com') === true ? \"org\" : \"cc\";\n newImgUrl += \"/cache/\" + Math.ceil(props.itemWidth * 2) + \"x\" + Math.ceil(props.imgHeight * 2) + \"/img/default.png\";\n }\n\n setImgUrl(newImgUrl);\n });\n }\n\n var productBrowseItemLikesDislpay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"likes-counter\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"hearts-container\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"glyphicon glyphicon-heart\"\n }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"glyphicon glyphicon-heart-empty\"\n })), \"(\", p.count_follower, \") Likes\");\n var itemInfoDisplay, musicItemInfoDisplay, musicPlayerDisplay, showIndex, itemInfoHeight;\n\n if (browseListType === \"picture\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username)));\n } else if (browseListType === \"apps\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username)));\n } else if (browseListType === \"phone-pictures\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title));\n } else if (browseListType === \"comics\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), productBrowseItemLikesDislpay);\n } else if (browseListType === \"books\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.username), productBrowseItemLikesDislpay);\n } else if (browseListType === \"music\" || browseListType === \"music-test\") {\n musicItemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-music-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), productBrowseItemLikesDislpay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username)));\n\n if (productFiles && productFiles.length > 0) {\n musicPlayerDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(MusicPlayerWrapper, {\n product: p,\n items: productFiles\n });\n }\n } else if (browseListType === \"videos\") {\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), productBrowseItemLikesDislpay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"info-container\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username))));\n } else if (browseListType === \"skills\") {\n console.log(p);\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info browse-type-skills\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username)), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.description));\n } else if (browseListType === \"favorites\") {\n itemInfoHeight = props.imgHeight;\n showIndex = true;\n itemInfoDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-info\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"info-container\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"h2\", null, p.title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.cat_title), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, \"by \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"b\", null, p.username))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"score-container\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"explore-product-plings\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"rating\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"rating-text\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"small\", {\n className: \"center-block text-center\"\n }, \"Score \", p.laplace_score / 10, \"%\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"progress\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"progress-bar\",\n style: {\n \"backgroundColor\": \"#c8c8c8\",\n \"width\": p.laplace_score / 10 + \"%\"\n }\n }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"progress-bar\",\n style: {\n \"backgroundColor\": \"#eeeeee\",\n \"opacity\": \"0.5\",\n \"width\": 100 - p.laplace_score / 10 + \"%\"\n }\n }))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"collected\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", null, p.created_at)))));\n }\n\n var indexDisplay;\n\n if (showIndex === true) {\n indexDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"index\"\n }, props.rowIndex + 1);\n }\n\n var itemLink = json_serverUrl;\n itemLink = is_show_real_domain_as_url === 1 ? \"/\" : \"/s/\" + json_store_name + \"/\";\n itemLink += p.type_id === \"3\" ? \"c\" : \"p\";\n itemLink += \"/\" + p.project_id;\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item \" + browseListType,\n id: \"product-\" + p.project_id,\n style: {\n \"width\": props.itemWidth\n }\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"wrapper\"\n }, indexDisplay, musicPlayerDisplay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: itemLink,\n className: \"product-browse-item-wrapper\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-image\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"img\", {\n src: imgUrl,\n height: props.imgHeight,\n onError: onImageLoadError\n }), musicItemInfoDisplay), itemInfoDisplay)));\n}\n/*function ProductBrowseItemPreviewMusicPlayerTwo(props){\r\n\r\n const {productBrowseState, productBrowseDispatch} = React.useContext(Context);\r\n\r\n const [ productFiles, setProductFiles ] = useState(props.productFiles)\r\n\r\n const [ showAudioControls, setShowAudioControls ] = useState(false);\r\n const [ playIndex, setPlayIndex ] = useState(0);\r\n let initialPLayedAudioArray = [];\r\n if (productFiles){\r\n productFiles.forEach(function(i,index){\r\n const pa = {\r\n ...i,\r\n played:0,\r\n stopped:0\r\n }\r\n initialPLayedAudioArray.push(pa);\r\n })\r\n }\r\n const [ playedAudioArray, setPlayedAudioArray ] = useState(initialPLayedAudioArray);\r\n const [ isPlaying, setIsPlaying ] = useState(false);\r\n const [ isPaused, setIsPaused ] = useState(false);\r\n\r\n React.useEffect(() => {\r\n if (productBrowseState.current === props.projectId){\r\n if (productBrowseState.isPlaying === true){\r\n playTrack();\r\n } else {\r\n pauseTrack()\r\n }\r\n } else {\r\n if (isPlaying === true){\r\n pauseTrack();\r\n }\r\n }\r\n },[productBrowseState.current,productBrowseState.isPlaying])\r\n\r\n function onPlayClick(pIndex){\r\n productBrowseDispatch({type:'SET_CURRENT_ITEM',itemId:props.projectId,pIndex:pIndex});\r\n }\r\n\r\n function onPauseClick(){\r\n productBrowseDispatch({type:'PAUSE'});\r\n }\r\n\r\n function playTrack(){\r\n console.log('play track');\r\n const playerElement = document.getElementById(\"product-browse-music-player-\"+props.projectId).getElementsByTagName('audio');\r\n let currentSrc;\r\n if (isPaused === false) {\r\n currentSrc = productFiles[productBrowseState.currentPlayIndex].musicSrc;\r\n playerElement[0].src = currentSrc;\r\n }\r\n console.log('current src');\r\n console.log(currentSrc);\r\n playerElement[0].play();\r\n setShowAudioControls(true);\r\n setIsPlaying(true);\r\n setIsPaused(false);\r\n onReportAudioPlay(currentSrc);\r\n }\r\n\r\n function pauseTrack(){\r\n console.log('pause track');\r\n const playerElement = document.getElementById(\"product-browse-music-player-\"+props.projectId).getElementsByTagName('audio');\r\n playerElement[0].pause();\r\n setShowAudioControls(false);\r\n setIsPlaying(false);\r\n setIsPaused(true);\r\n onReportAudioStop(productFiles[playIndex].musicSrc)\r\n }\r\n\r\n function onPrevTrackPlayClick(){\r\n let prevTrackIndex;\r\n if (playIndex === 0){\r\n prevTrackIndex = productFiles.length - 1;\r\n } else {\r\n prevTrackIndex = playIndex - 1;\r\n }\r\n setPlayIndex(prevTrackIndex);\r\n onPlayClick(prevTrackIndex);\r\n }\r\n\r\n function onNextTrackPlayClick(){\r\n let nextTrackIndex;\r\n if (playIndex + 1 === productFiles.length){\r\n nextTrackIndex = 0;\r\n } else {\r\n nextTrackIndex = playIndex + 1;\r\n }\r\n setPlayIndex(nextTrackIndex);\r\n onPlayClick(nextTrackIndex);\r\n }\r\n\r\n function onReportAudioPlay(src){\r\n const audioItem = playedAudioArray.find((i => i.musicSrc === src));\r\n const audioItemIndex = playedAudioArray.findIndex((i => i.musicSrc === src));\r\n const newAudioItem = {\r\n ...audioItem,\r\n played:audioItem.played + 1\r\n }\r\n const newPLayedAudioArray = [\r\n ...playedAudioArray.slice(0,audioItemIndex),\r\n newAudioItem,\r\n ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)\r\n ];\r\n setPlayedAudioArray(newPLayedAudioArray);\r\n\r\n if (playedAudioArray[audioItemIndex].played === 0){\r\n \r\n const audioStartUrl = \"https://\" + window.location.hostname + \"/p/\" + props.projectId + \"/\" + 'startmediaviewajax?collection_id='+audioItem.collection_id+'&file_id='+audioItem.id+'&type_id=2';\r\n\r\n $.ajax({url: audioStartUrl}).done(function(res) { \r\n console.log(res);\r\n const newAudioItem = {\r\n ...audioItem,\r\n mediaViewId:res.MediaViewId,\r\n played:audioItem.played + 1\r\n }\r\n const newPLayedAudioArray = [\r\n ...playedAudioArray.slice(0,audioItemIndex),\r\n newAudioItem,\r\n ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)\r\n ];\r\n // console.log('new played audio array - ');\r\n // console.log(newPLayedAudioArray);\r\n setPlayedAudioArray(newPLayedAudioArray);\r\n });\r\n } \r\n }\r\n \r\n function onReportAudioStop(src){\r\n\r\n const audioItem = playedAudioArray.find((i => i.musicSrc === src));\r\n const audioItemIndex = playedAudioArray.findIndex((i => i.musicSrc === src));\r\n const newAudioItem = {\r\n ...audioItem,\r\n stopped:audioItem.stopped + 1\r\n }\r\n const newPLayedAudioArray = [\r\n ...playedAudioArray.slice(0,audioItemIndex),\r\n newAudioItem,\r\n ...playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)\r\n ];\r\n setPlayedAudioArray(newPLayedAudioArray);\r\n \r\n if (playedAudioArray[audioItemIndex].stopped === 0){\r\n const audioStopUrl = \"https://\" + window.location.hostname + \"/p/\" + props.projectId + \"/\" + \"stopmediaviewajax?media_view_id=\" + playedAudioArray[audioItemIndex].mediaViewId;\r\n\r\n $.ajax({url: audioStopUrl}).done(function(res) { \r\n console.log(res);\r\n });\r\n }\r\n }\r\n\r\n let musicPlayerDisplay;\r\n if (productFiles) {\r\n\r\n const playButtonElement = (\r\n \r\n \r\n \r\n )\r\n\r\n const pauseButtonElement = (\r\n \r\n \r\n \r\n )\r\n\r\n const prevButtonElement = (\r\n \r\n \r\n \r\n )\r\n\r\n const nextButtonElement = (\r\n \r\n \r\n \r\n )\r\n\r\n let prevDisplay, nextDisplay;\r\n if (productFiles.length > 1 && showAudioControls){\r\n prevDisplay = onPrevTrackPlayClick()}>{prevButtonElement} \r\n nextDisplay = onNextTrackPlayClick()}>{nextButtonElement} \r\n }\r\n\r\n let playButtonDisplay;\r\n if (isPlaying === true) playButtonDisplay = onPauseClick()}>{pauseButtonElement} \r\n else playButtonDisplay = onPlayClick(playIndex)}>{playButtonElement} \r\n\r\n let trackCounterDisplay;\r\n if (showAudioControls === true){\r\n trackCounterDisplay = (\r\n \r\n {playIndex + 1}/{productFiles.length}\r\n
\r\n )\r\n }\r\n \r\n musicPlayerDisplay = (\r\n \r\n
\r\n
\r\n
\r\n {prevDisplay}\r\n {playButtonDisplay}\r\n {nextDisplay}\r\n
\r\n {trackCounterDisplay}\r\n
\r\n
\r\n )\r\n }\r\n\r\n let showControlsCssClass = \"\";\r\n if (showAudioControls === true) showControlsCssClass = \" show-controls\"\r\n\r\n let isMobileCssClass = \"\";\r\n if (isMobile === true) isMobileCssClass = \" mobile\";\r\n\r\n return (\r\n \r\n {musicPlayerDisplay}\r\n
\r\n )\r\n}*/\n\nfunction MusicPlayerWrapper(props) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(MusicPlayer, {\n product: props.product,\n items: props.items,\n containerWidth: props.width\n }));\n}\n\nfunction MusicPlayer(props) {\n /* COMPONENT */\n var _React$useContext = react__WEBPACK_IMPORTED_MODULE_0___default.a.useContext(_context_provider_js__WEBPACK_IMPORTED_MODULE_1__[\"Context\"]),\n productBrowseState = _React$useContext.productBrowseState,\n productBrowseDispatch = _React$useContext.productBrowseDispatch;\n\n var _useState7 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(0),\n _useState8 = _slicedToArray(_useState7, 2),\n playIndex = _useState8[0],\n setPlayIndex = _useState8[1];\n\n var prevIndex = usePrevious(playIndex);\n\n var _useState9 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(),\n _useState10 = _slicedToArray(_useState9, 2),\n isPlaying = _useState10[0],\n setIsPlaying = _useState10[1];\n\n var _useState11 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(),\n _useState12 = _slicedToArray(_useState11, 2),\n isPaused = _useState12[0],\n setIsPaused = _useState12[1];\n\n var initialPLayedAudioArray = [];\n props.items.forEach(function (i, index) {\n var pl = 0;\n if (index === 0) pl = -1;\n\n var pa = _objectSpread({}, i, {\n played: 0,\n stopped: 0\n });\n\n initialPLayedAudioArray.push(pa);\n });\n\n var _useState13 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(initialPLayedAudioArray),\n _useState14 = _slicedToArray(_useState13, 2),\n playedAudioArray = _useState14[0],\n setPlayedAudioArray = _useState14[1];\n\n var initialIsMobileValue = props.containerWidth < 600 ? true : false;\n\n var _useState15 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(initialIsMobileValue),\n _useState16 = _slicedToArray(_useState15, 2),\n isMobile = _useState16[0],\n setIsMobile = _useState16[1];\n\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n var playerElement = document.getElementById(\"music-player-container-\" + props.product.project_id).getElementsByTagName('audio');\n var currentSrc = props.items[playIndex].musicSrc;\n playerElement[0].src = currentSrc;\n playerElement[0].volume = 0.5;\n }, []);\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n if (isPlaying) playAudio(true);\n\n if (isPaused) {\n if (prevIndex === playIndex) playAudio();else playAudio(true);\n }\n\n if (isPlaying === true) onReportAudioStop(props.items[prevIndex].musicSrc, playIndex);\n }, [playIndex]);\n react__WEBPACK_IMPORTED_MODULE_0___default.a.useEffect(function () {\n if (productBrowseState.current === props.product.project_id) {\n if (productBrowseState.isPlaying === true) playAudio(true);else pauseAudio();\n } else {\n if (isPlaying === true) pauseAudio();\n }\n }, [productBrowseState.current, productBrowseState.isPlaying]); // audio player\n\n function _onPlayClick() {\n productBrowseDispatch({\n type: 'SET_CURRENT_ITEM',\n itemId: props.product.project_id,\n pIndex: playIndex\n });\n }\n\n function playAudio(reload, newPlayIndex) {\n var playerElement = document.getElementById(\"music-player-container-\" + props.product.project_id).getElementsByTagName('audio');\n var pi = newPlayIndex ? newPlayIndex : playIndex;\n var currentSrc = props.items[pi].musicSrc;\n if (isPaused === false || playerElement[0].currentTime && playerElement[0].currentTime === 0 || reload === true) playerElement[0].src = currentSrc;\n playerElement[0].play();\n setIsPlaying(true);\n setIsPaused(false);\n onReportAudioPlay(currentSrc, newPlayIndex);\n }\n\n function onPauseClick() {\n productBrowseDispatch({\n type: 'PAUSE'\n });\n }\n\n function pauseAudio() {\n var playerElement = document.getElementById(\"music-player-container-\" + props.product.project_id).getElementsByTagName('audio');\n playerElement[0].pause();\n setIsPlaying(false);\n setIsPaused(true);\n onReportAudioStop(props.items[playIndex].musicSrc);\n }\n\n function onPrevTrackPlayClick() {\n var prevTrackIndex;\n\n if (playIndex === 0) {\n prevTrackIndex = props.items.length - 1;\n } else {\n prevTrackIndex = playIndex - 1;\n }\n\n setPlayIndex(prevTrackIndex);\n }\n\n function onNextTrackPlayClick() {\n var nextTrackIndex;\n\n if (playIndex + 1 === props.items.length) {\n nextTrackIndex = 0;\n } else {\n nextTrackIndex = playIndex + 1;\n }\n\n setPlayIndex(nextTrackIndex);\n }\n\n function onReportAudioPlay(musicSrc, newPlayIndex) {\n var audioItem = playedAudioArray.find(function (i) {\n return i.musicSrc === musicSrc;\n });\n var audioItemIndex = newPlayIndex ? newPlayIndex : playedAudioArray.findIndex(function (i) {\n return i.musicSrc === musicSrc;\n });\n\n var newAudioItem = _objectSpread({}, audioItem, {\n played: audioItem.played + 1\n });\n\n var newPLayedAudioArray = [].concat(_toConsumableArray(playedAudioArray.slice(0, audioItemIndex)), [newAudioItem], _toConsumableArray(playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)));\n\n if (playedAudioArray[audioItemIndex].played === 0) {\n var audioStartUrl = \"https://\" + window.location.hostname + \"/p/\" + props.product.project_id + '/startmediaviewajax?collection_id=' + audioItem.collection_id + '&file_id=' + audioItem.id + '&type_id=2';\n $.ajax({\n url: audioStartUrl\n }).done(function (res) {\n var newAudioItem = _objectSpread({}, audioItem, {\n mediaViewId: res.MediaViewId,\n played: audioItem.played + 1\n });\n\n var newPLayedAudioArray = [].concat(_toConsumableArray(playedAudioArray.slice(0, audioItemIndex)), [newAudioItem], _toConsumableArray(playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)));\n setPlayedAudioArray(newPLayedAudioArray);\n });\n } else {\n setPlayedAudioArray(newPLayedAudioArray);\n }\n }\n\n function onReportAudioStop(musicSrc) {\n var audioItem = playedAudioArray.find(function (i) {\n return i.musicSrc === musicSrc;\n });\n var audioItemIndex = playedAudioArray.findIndex(function (i) {\n return i.musicSrc === musicSrc;\n });\n\n var newAudioItem = _objectSpread({}, audioItem, {\n stopped: audioItem.stopped + 1\n });\n\n var newPLayedAudioArray = [].concat(_toConsumableArray(playedAudioArray.slice(0, audioItemIndex)), [newAudioItem], _toConsumableArray(playedAudioArray.slice(audioItemIndex + 1, playedAudioArray.length)));\n\n if (playedAudioArray[audioItemIndex].stopped === 0) {\n var audioStopUrl = \"https://\" + window.location.hostname + \"/p/\" + props.product.project_id + \"/stopmediaviewajax?media_view_id=\" + playedAudioArray[audioItemIndex].mediaViewId;\n $.ajax({\n url: audioStopUrl\n }).done(function (res) {\n setPlayedAudioArray(newPLayedAudioArray);\n });\n } else {\n setPlayedAudioArray(newPLayedAudioArray);\n }\n }\n /* RENDER */\n\n\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"music-player-container-\" + props.product.project_id,\n className: \"product-browse-music-player-wrapper\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"audio\", {\n volume: 0.5,\n id: \"music-player-audio-\" + props.product.project_id\n }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(MusicPlayerControlPanel, {\n playIndex: playIndex,\n isPlaying: isPlaying,\n isPaused: isPaused,\n isMobile: isMobile,\n onPlayClick: function onPlayClick(reload) {\n return _onPlayClick(reload);\n },\n onPauseClick: onPauseClick,\n onPrevTrackPlayClick: onPrevTrackPlayClick,\n onNextTrackPlayClick: onNextTrackPlayClick,\n items: props.items\n }));\n} // Hook\n\n\nfunction usePrevious(value) {\n // The ref object is a generic container whose current property is mutable ...\n // ... and can hold any value, similar to an instance property on a class\n var ref = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useRef\"])(); // Store current value in ref\n\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n ref.current = value;\n }, [value]); // Only re-run if value changes\n // Return previous value (happens before update in useEffect above)\n\n return ref.current;\n}\n\nfunction MusicPlayerControlPanel(props) {\n /* DISPLAY */\n // audio controls display\n var playButtonElement = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"svg\", {\n fill: \"currentColor\",\n preserveAspectRatio: \"xMidYMid meet\",\n height: \"1em\",\n width: \"1em\",\n viewBox: \"0 0 40 40\",\n className: \"play-icon\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"g\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"path\", {\n d: \"m20.1 2.9q4.7 0 8.6 2.3t6.3 6.2 2.3 8.6-2.3 8.6-6.3 6.2-8.6 2.3-8.6-2.3-6.2-6.2-2.3-8.6 2.3-8.6 6.2-6.2 8.6-2.3z m8.6 18.3q0.7-0.4 0.7-1.2t-0.7-1.2l-12.1-7.2q-0.7-0.4-1.5 0-0.7 0.4-0.7 1.3v14.2q0 0.9 0.7 1.3 0.4 0.2 0.8 0.2 0.3 0 0.7-0.2z\"\n })));\n var pauseButtonElement = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"svg\", {\n fill: \"currentColor\",\n preserveAspectRatio: \"xMidYMid meet\",\n height: \"1em\",\n width: \"1em\",\n viewBox: \"0 0 40 40\",\n className: \"pause-icon\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"g\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"path\", {\n d: \"m18.7 26.4v-12.8q0-0.3-0.2-0.5t-0.5-0.2h-5.7q-0.3 0-0.5 0.2t-0.2 0.5v12.8q0 0.3 0.2 0.5t0.5 0.2h5.7q0.3 0 0.5-0.2t0.2-0.5z m10 0v-12.8q0-0.3-0.2-0.5t-0.5-0.2h-5.7q-0.3 0-0.5 0.2t-0.2 0.5v12.8q0 0.3 0.2 0.5t0.5 0.2h5.7q0.3 0 0.5-0.2t0.2-0.5z m8.6-6.4q0 4.7-2.3 8.6t-6.3 6.2-8.6 2.3-8.6-2.3-6.2-6.2-2.3-8.6 2.3-8.6 6.2-6.2 8.6-2.3 8.6 2.3 6.3 6.2 2.3 8.6z\"\n })));\n var prevButtonElement = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"svg\", {\n fill: \"currentColor\",\n preserveAspectRatio: \"xMidYMid meet\",\n height: \"1em\",\n width: \"1em\",\n viewBox: \"0 0 40 40\",\n className: \"prev-icon\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"g\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"path\", {\n d: \"m15.9 20l14.1-10v20z m-5.9-10h3.4v20h-3.4v-20z\"\n })));\n var nextButtonElement = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"svg\", {\n fill: \"currentColor\",\n preserveAspectRatio: \"xMidYMid meet\",\n height: \"1em\",\n width: \"1em\",\n viewBox: \"0 0 40 40\",\n className: \"next-icon\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"g\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"path\", {\n d: \"m26.6 10h3.4v20h-3.4v-20z m-16.6 20v-20l14.1 10z\"\n })));\n var playButtonDisplay;\n\n if (props.isPlaying === true) {\n if (props.isMobile === true) playButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onTouchStart: function onTouchStart() {\n return props.onPauseClick();\n }\n }, pauseButtonElement);else playButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onClick: function onClick() {\n return props.onPauseClick();\n }\n }, pauseButtonElement);\n } else {\n if (props.isMobile === true) playButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onTouchStart: function onTouchStart() {\n return props.onPlayClick();\n }\n }, playButtonElement);else playButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onClick: function onClick() {\n return props.onPlayClick();\n }\n }, playButtonElement);\n }\n\n var audioControlsDisplay;\n\n if (props.isMobile === true) {\n audioControlsDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"music-player-audio-control\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onTouchStart: function onTouchStart() {\n return props.onPrevTrackPlayClick();\n }\n }, prevButtonElement), playButtonDisplay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onTouchStart: function onTouchStart() {\n return props.onNextTrackPlayClick();\n }\n }, nextButtonElement));\n } else {\n audioControlsDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"music-player-audio-control\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onClick: function onClick() {\n return props.onPrevTrackPlayClick();\n }\n }, prevButtonElement), playButtonDisplay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n onClick: function onClick() {\n return props.onNextTrackPlayClick();\n }\n }, nextButtonElement));\n }\n /* RENDER */\n // music player css class\n\n\n var musicPlayerControlBarCssClass = \"music-player-controls-bar \";\n if (props.isPlaying) musicPlayerControlBarCssClass += \"is-playing\";\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"music-player-control-panel\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: musicPlayerControlBarCssClass\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"music-player-controls-wrapper\"\n }, audioControlsDisplay), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"track-number-display\"\n }, parseInt(props.playIndex + 1) + \" / \" + props.items.length)));\n}\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (ProductBrowseItem);\n\n//# sourceURL=webpack:///./app/product-browse-item.js?");
/***/ }),
/***/ "./app/product-browse-reducer.js":
/*!***************************************!*\
!*** ./app/product-browse-reducer.js ***!
\***************************************/
/*! exports provided: productBrowseReducerInitialState, default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"productBrowseReducerInitialState\", function() { return productBrowseReducerInitialState; });\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar productBrowseReducerInitialState = {\n isPlaying: false,\n current: null,\n currentPlayIndex: null\n};\n\nfunction AppReducer(state, action) {\n switch (action.type) {\n case \"SET_CURRENT_ITEM\":\n {\n var s = {\n isPlaying: true,\n current: action.itemId,\n currentPlayIndex: action.pIndex\n };\n return s;\n }\n\n case \"PAUSE\":\n {\n var _s = _objectSpread({}, state, {\n isPlaying: false\n });\n\n return _s;\n }\n\n default:\n {\n return state;\n }\n }\n}\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (AppReducer);\n\n//# sourceURL=webpack:///./app/product-browse-reducer.js?");
/***/ }),
/***/ "./app/product-browse.js":
/*!*******************************!*\
!*** ./app/product-browse.js ***!
\*******************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_device_detect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-device-detect */ \"./node_modules/react-device-detect/dist/index.js\");\n/* harmony import */ var react_device_detect__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_device_detect__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _context_provider_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./context-provider.js */ \"./app/context-provider.js\");\n/* harmony import */ var _product_browse_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./product-browse-item */ \"./app/product-browse-item.js\");\n/* harmony import */ var _product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./product-browse-helpers */ \"./app/product-browse-helpers.js\");\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\n\n\n\nfunction ProductBrowse() {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_context_provider_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"], null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductTagGroupFilterContainer, null), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowseFilterContainer, null), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowseItemList, null)));\n}\n\nfunction ProductBrowseFilterContainer() {\n var filtersBaseUrl = json_serverUrl;\n filtersBaseUrl += json_store_name === \"ALL\" ? \"/\" : \"/s/\" + json_store_name + \"/\";\n filtersBaseUrl += \"browse/\";\n if (typeof filters.category === 'number') filtersBaseUrl += \"cat/\" + filters.category + \"/\";\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse-top-menu\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"pling-nav-tabs\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"ul\", {\n className: \"nav nav-tabs pling-nav-tabs\",\n id: \"sort\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", {\n className: filters.order === \"latest\" ? \"active\" : \"\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: filtersBaseUrl + \"ord/latest/\" + window.location.search\n }, \"Latest\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", {\n className: filters.order === \"rating\" ? \"active\" : \"\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: filtersBaseUrl + \"ord/rating/\" + window.location.search\n }, \"Score\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", {\n className: filters.order === \"plinged\" ? \"active\" : \"\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: filtersBaseUrl + \"ord/plinged/\" + window.location.search\n }, \"Plinged\")))));\n}\n\nfunction ProductTagGroupFilterContainer() {\n var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])([]),\n _useState2 = _slicedToArray(_useState, 2),\n tagGroups = _useState2[0],\n setTagGroups = _useState2[1];\n\n var _useState3 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])([]),\n _useState4 = _slicedToArray(_useState3, 2),\n tagGroupIds = _useState4[0],\n setTagGroupIds = _useState4[1];\n\n var _useState5 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])([]),\n _useState6 = _slicedToArray(_useState5, 2),\n selectedTags = _useState6[0],\n setSelectedTags = _useState6[1];\n\n react__WEBPACK_IMPORTED_MODULE_0___default.a.useState(function () {\n renderTagGroups();\n }, []);\n\n function renderTagGroups() {\n for (var i in tag_group_filter) {\n var newTagGroupIds = tagGroupIds;\n newTagGroupIds.push(i);\n setTagGroupIds(newTagGroupIds);\n var tagGroup = tag_group_filter[i];\n\n for (var ii in tagGroup) {\n if (ii === \"selected_tag\") {\n var newSelectedTags = selectedTags;\n newSelectedTags.push(tagGroup[ii]);\n setSelectedTags(newSelectedTags);\n } else {\n var newArray = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"ConvertObjectToArray\"])(tagGroup[ii], ii);\n var newTagGroupsArray = tagGroups;\n newTagGroupsArray.push(newArray);\n setTagGroups(newTagGroupsArray);\n }\n }\n }\n }\n\n var tagGroupsDropdownDisplay;\n\n if (tagGroups.length > 0) {\n tagGroupsDropdownDisplay = tagGroups.map(function (tagGroup, index) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(TagGroupDropDownMenu, {\n key: index,\n tagGroup: tagGroup,\n tagGroupId: tagGroupIds[index],\n selectedTag: selectedTags[index]\n });\n });\n }\n\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-tag-filter-container\",\n style: {\n \"width\": 140 * tagGroups.length + 1\n }\n }, tagGroupsDropdownDisplay);\n}\n\nfunction TagGroupDropDownMenu(props) {\n function onSelectTag(e) {\n var serverUrl = json_serverUrl.split('://')[1];\n var ajaxUrl = \"https://\" + serverUrl + \"/explore/savetaggroupfilter?group_id=\" + props.tagGroupId + \"&tag_id=\" + e.target.value;\n $.ajax({\n url: ajaxUrl\n }).done(function (res) {\n window.location.reload();\n });\n }\n\n var tagsDisplay = props.tagGroup.map(function (tag, index) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"option\", {\n key: index,\n selected: tag.id === props.selectedTag,\n value: tag.id\n }, tag.tag);\n });\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-tag-group-dropdown\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"select\", {\n onChange: function onChange(e) {\n return onSelectTag(e);\n }\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"option\", null), tagsDisplay));\n}\n\nfunction ProductBrowseItemList(props) {\n if (window.location.search === \"?index=7\") {\n window.browseListType === \"favorites\";\n browseListType = \"favorites\";\n }\n\n var _useState7 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])($('#product-browse-container').width() + 14),\n _useState8 = _slicedToArray(_useState7, 2),\n containerWidth = _useState8[0],\n setContainerWidth = _useState8[1];\n\n var _useState9 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getNumberOfItemsPerRow\"])(browseListType, react_device_detect__WEBPACK_IMPORTED_MODULE_2__[\"isMobile\"], containerWidth)),\n _useState10 = _slicedToArray(_useState9, 2),\n itemsInRow = _useState10[0],\n setItemsInRow = _useState10[1];\n\n var _useState11 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getItemWidth\"])(browseListType, containerWidth, itemsInRow)),\n _useState12 = _slicedToArray(_useState11, 2),\n itemWidth = _useState12[0],\n setItemWidth = _useState12[1];\n\n var _useState13 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getImageHeight\"])(browseListType, itemWidth)),\n _useState14 = _slicedToArray(_useState13, 2),\n imgHeight = _useState14[0],\n setImgHeight = _useState14[1];\n\n react__WEBPACK_IMPORTED_MODULE_0___default.a.useEffect(function () {\n window.addEventListener(\"resize\", function (event) {\n updateDimensions();\n });\n window.addEventListener(\"orientationchange\", function (event) {\n updateDimensions();\n });\n }, []);\n\n function updateDimensions() {\n var newContainerWidth = $('#product-browse-container').width() + 14;\n setContainerWidth(newContainerWidth);\n var newItemsInRow = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getNumberOfItemsPerRow\"])(browseListType, react_device_detect__WEBPACK_IMPORTED_MODULE_2__[\"isMobile\"], newContainerWidth);\n setItemsInRow(newItemsInRow);\n var newItemWidth = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getItemWidth\"])(browseListType, newContainerWidth, newItemsInRow);\n setItemWidth(newItemWidth);\n var newImgHeight = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getImageHeight\"])(browseListType, newItemWidth);\n setImgHeight(newImgHeight);\n }\n\n var productsRowsDisplay;\n\n if (itemsInRow) {\n productsRowsDisplay = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"chunkArray\"])(products, itemsInRow).map(function (ac, index) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowseItemsRow, {\n key: index,\n rowIndex: index,\n products: ac,\n itemWidth: itemWidth,\n imgHeight: imgHeight\n });\n });\n }\n\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse-item-list\",\n className: react_device_detect__WEBPACK_IMPORTED_MODULE_2__[\"isMobile\"] ? \"mobile\" : \"\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse-list-container\"\n }, productsRowsDisplay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowsePagination, null)));\n}\n\nfunction ProductBrowseItemsRow(props) {\n var productsDisplay = props.products.map(function (p, index) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_product_browse_item__WEBPACK_IMPORTED_MODULE_4__[\"ProductBrowseItem\"], {\n key: index,\n index: index,\n rowIndex: props.rowIndex,\n product: p,\n itemWidth: props.itemWidth,\n imgHeight: props.imgHeight\n });\n });\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-row \" + (browseListType ? browseListType + \"-row\" : \"\")\n }, productsDisplay);\n}\n\nfunction ProductBrowsePagination() {\n var _useState15 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(pagination.totalcount),\n _useState16 = _slicedToArray(_useState15, 2),\n totalItems = _useState16[0],\n setTotalItems = _useState16[1];\n\n var _useState17 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(50),\n _useState18 = _slicedToArray(_useState17, 2),\n itemsPerPage = _useState18[0],\n setItemsPerPage = _useState18[1];\n\n var _useState19 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(pagination.page),\n _useState20 = _slicedToArray(_useState19, 2),\n currentPage = _useState20[0],\n setCurrentPage = _useState20[1];\n\n var _useState21 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Math.ceil(totalItems / itemsPerPage)),\n _useState22 = _slicedToArray(_useState21, 2),\n totalPages = _useState22[0],\n setTotalPages = _useState22[1];\n\n var minPage = currentPage - 5 > 0 ? currentPage - 5 : 0;\n var maxPage = minPage + 10 < totalPages ? minPage + 10 : totalPages;\n var paginationArray = [];\n\n for (var i = minPage; i < maxPage; i++) {\n paginationArray.push(i + 1);\n }\n\n var pageLinkBase = json_serverUrl;\n pageLinkBase += is_show_real_domain_as_url === 1 ? \"/\" : \"/s/\" + json_store_name + \"/\";\n pageLinkBase += \"browse/page/\";\n var pageLinkSuffix = \"/\";\n if (typeof filters.category === 'number') pageLinkSuffix += \"cat/\" + filters.category + \"/\";\n pageLinkSuffix += \"ord/\" + filters.order + \"/\";\n var previousButtonDisplay;\n if (currentPage > 1) previousButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: pageLinkBase + (currentPage - 1) + pageLinkSuffix\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"glyphicon glyphicon-chevron-left\"\n }), \" Previous\"));\n var nextButtonDisplay;\n if (currentPage < totalPages) nextButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: pageLinkBase + (currentPage + 1) + pageLinkSuffix\n }, \"Next \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"glyphicon glyphicon-chevron-right\"\n })));\n var paginationDisplay = paginationArray.map(function (p, index) {\n var pageLinkDisplay;\n if (currentPage === p) pageLinkDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"no-link\"\n }, p);else pageLinkDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: pageLinkBase + p + pageLinkSuffix\n }, p);\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", {\n key: index\n }, pageLinkDisplay);\n });\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse-pagination\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"ul\", null, previousButtonDisplay, paginationDisplay, nextButtonDisplay));\n}\n\nvar rootElement = document.getElementById(\"product-browse-container\");\nreact_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowse, null), rootElement);\n\n//# sourceURL=webpack:///./app/product-browse.js?");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_device_detect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-device-detect */ \"./node_modules/react-device-detect/dist/index.js\");\n/* harmony import */ var react_device_detect__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_device_detect__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _context_provider_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./context-provider.js */ \"./app/context-provider.js\");\n/* harmony import */ var _product_browse_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./product-browse-item */ \"./app/product-browse-item.js\");\n/* harmony import */ var _product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./product-browse-helpers */ \"./app/product-browse-helpers.js\");\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n\n\n\n\n\n\n\nfunction ProductBrowse() {\n console.log('browse list type:');\n console.log(browseListType);\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_context_provider_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"], null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductTagGroupFilterContainer, null), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowseFilterContainer, null), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowseItemList, null)));\n}\n\nfunction ProductBrowseFilterContainer() {\n var filtersBaseUrl = json_serverUrl;\n filtersBaseUrl += json_store_name === \"ALL\" ? \"/\" : \"/s/\" + json_store_name + \"/\";\n filtersBaseUrl += \"browse/\";\n if (typeof filters.category === 'number') filtersBaseUrl += \"cat/\" + filters.category + \"/\";\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse-top-menu\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"pling-nav-tabs\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"ul\", {\n className: \"nav nav-tabs pling-nav-tabs\",\n id: \"sort\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", {\n className: filters.order === \"latest\" ? \"active\" : \"\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: filtersBaseUrl + \"ord/latest/\" + window.location.search\n }, \"Latest\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", {\n className: filters.order === \"rating\" ? \"active\" : \"\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: filtersBaseUrl + \"ord/rating/\" + window.location.search\n }, \"Score\")), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", {\n className: filters.order === \"plinged\" ? \"active\" : \"\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: filtersBaseUrl + \"ord/plinged/\" + window.location.search\n }, \"Plinged\")))));\n}\n\nfunction ProductTagGroupFilterContainer() {\n var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])([]),\n _useState2 = _slicedToArray(_useState, 2),\n tagGroups = _useState2[0],\n setTagGroups = _useState2[1];\n\n var _useState3 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])([]),\n _useState4 = _slicedToArray(_useState3, 2),\n tagGroupIds = _useState4[0],\n setTagGroupIds = _useState4[1];\n\n var _useState5 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])([]),\n _useState6 = _slicedToArray(_useState5, 2),\n selectedTags = _useState6[0],\n setSelectedTags = _useState6[1];\n\n react__WEBPACK_IMPORTED_MODULE_0___default.a.useState(function () {\n renderTagGroups();\n }, []);\n\n function renderTagGroups() {\n for (var i in tag_group_filter) {\n var newTagGroupIds = tagGroupIds;\n newTagGroupIds.push(i);\n setTagGroupIds(newTagGroupIds);\n var tagGroup = tag_group_filter[i];\n\n for (var ii in tagGroup) {\n if (ii === \"selected_tag\") {\n var newSelectedTags = selectedTags;\n newSelectedTags.push(tagGroup[ii]);\n setSelectedTags(newSelectedTags);\n } else {\n var newArray = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"ConvertObjectToArray\"])(tagGroup[ii], ii);\n var newTagGroupsArray = tagGroups;\n newTagGroupsArray.push(newArray);\n setTagGroups(newTagGroupsArray);\n }\n }\n }\n }\n\n var tagGroupsDropdownDisplay;\n\n if (tagGroups.length > 0) {\n tagGroupsDropdownDisplay = tagGroups.map(function (tagGroup, index) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(TagGroupDropDownMenu, {\n key: index,\n tagGroup: tagGroup,\n tagGroupId: tagGroupIds[index],\n selectedTag: selectedTags[index]\n });\n });\n }\n\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-tag-filter-container\",\n style: {\n \"width\": 140 * tagGroups.length + 1\n }\n }, tagGroupsDropdownDisplay);\n}\n\nfunction TagGroupDropDownMenu(props) {\n function onSelectTag(e) {\n var serverUrl = json_serverUrl.split('://')[1];\n var ajaxUrl = \"https://\" + serverUrl + \"/explore/savetaggroupfilter?group_id=\" + props.tagGroupId + \"&tag_id=\" + e.target.value;\n $.ajax({\n url: ajaxUrl\n }).done(function (res) {\n window.location.reload();\n });\n }\n\n var tagsDisplay = props.tagGroup.map(function (tag, index) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"option\", {\n key: index,\n selected: tag.id === props.selectedTag,\n value: tag.id\n }, tag.tag);\n });\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-tag-group-dropdown\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"select\", {\n onChange: function onChange(e) {\n return onSelectTag(e);\n }\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"option\", null), tagsDisplay));\n}\n\nfunction ProductBrowseItemList(props) {\n if (window.location.search === \"?index=7\") {\n window.browseListType === \"favorites\";\n browseListType = \"favorites\";\n }\n\n var _useState7 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])($('#product-browse-container').width() + 14),\n _useState8 = _slicedToArray(_useState7, 2),\n containerWidth = _useState8[0],\n setContainerWidth = _useState8[1];\n\n var _useState9 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getNumberOfItemsPerRow\"])(browseListType, react_device_detect__WEBPACK_IMPORTED_MODULE_2__[\"isMobile\"], containerWidth)),\n _useState10 = _slicedToArray(_useState9, 2),\n itemsInRow = _useState10[0],\n setItemsInRow = _useState10[1];\n\n var _useState11 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getItemWidth\"])(browseListType, containerWidth, itemsInRow)),\n _useState12 = _slicedToArray(_useState11, 2),\n itemWidth = _useState12[0],\n setItemWidth = _useState12[1];\n\n var _useState13 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getImageHeight\"])(browseListType, itemWidth)),\n _useState14 = _slicedToArray(_useState13, 2),\n imgHeight = _useState14[0],\n setImgHeight = _useState14[1];\n\n react__WEBPACK_IMPORTED_MODULE_0___default.a.useEffect(function () {\n window.addEventListener(\"resize\", function (event) {\n updateDimensions();\n });\n window.addEventListener(\"orientationchange\", function (event) {\n updateDimensions();\n });\n }, []);\n\n function updateDimensions() {\n var newContainerWidth = $('#product-browse-container').width() + 14;\n setContainerWidth(newContainerWidth);\n var newItemsInRow = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getNumberOfItemsPerRow\"])(browseListType, react_device_detect__WEBPACK_IMPORTED_MODULE_2__[\"isMobile\"], newContainerWidth);\n setItemsInRow(newItemsInRow);\n var newItemWidth = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getItemWidth\"])(browseListType, newContainerWidth, newItemsInRow);\n setItemWidth(newItemWidth);\n var newImgHeight = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"getImageHeight\"])(browseListType, newItemWidth);\n setImgHeight(newImgHeight);\n }\n\n var productsRowsDisplay;\n\n if (itemsInRow) {\n productsRowsDisplay = Object(_product_browse_helpers__WEBPACK_IMPORTED_MODULE_5__[\"chunkArray\"])(products, itemsInRow).map(function (ac, index) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowseItemsRow, {\n key: index,\n rowIndex: index,\n products: ac,\n itemWidth: itemWidth,\n imgHeight: imgHeight\n });\n });\n }\n\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse-item-list\",\n className: react_device_detect__WEBPACK_IMPORTED_MODULE_2__[\"isMobile\"] ? \"mobile\" : \"\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse-list-container\"\n }, productsRowsDisplay, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowsePagination, null)));\n}\n\nfunction ProductBrowseItemsRow(props) {\n var productsDisplay = props.products.map(function (p, index) {\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_product_browse_item__WEBPACK_IMPORTED_MODULE_4__[\"ProductBrowseItem\"], {\n key: index,\n index: index,\n rowIndex: props.rowIndex,\n product: p,\n itemWidth: props.itemWidth,\n imgHeight: props.imgHeight\n });\n });\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n className: \"product-browse-item-row \" + (browseListType ? browseListType + \"-row\" : \"\")\n }, productsDisplay);\n}\n\nfunction ProductBrowsePagination() {\n var _useState15 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(pagination.totalcount),\n _useState16 = _slicedToArray(_useState15, 2),\n totalItems = _useState16[0],\n setTotalItems = _useState16[1];\n\n var _useState17 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(50),\n _useState18 = _slicedToArray(_useState17, 2),\n itemsPerPage = _useState18[0],\n setItemsPerPage = _useState18[1];\n\n var _useState19 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(pagination.page),\n _useState20 = _slicedToArray(_useState19, 2),\n currentPage = _useState20[0],\n setCurrentPage = _useState20[1];\n\n var _useState21 = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(Math.ceil(totalItems / itemsPerPage)),\n _useState22 = _slicedToArray(_useState21, 2),\n totalPages = _useState22[0],\n setTotalPages = _useState22[1];\n\n var minPage = currentPage - 5 > 0 ? currentPage - 5 : 0;\n var maxPage = minPage + 10 < totalPages ? minPage + 10 : totalPages;\n var paginationArray = [];\n\n for (var i = minPage; i < maxPage; i++) {\n paginationArray.push(i + 1);\n }\n\n var pageLinkBase = json_serverUrl;\n pageLinkBase += is_show_real_domain_as_url === 1 ? \"/\" : \"/s/\" + json_store_name + \"/\";\n pageLinkBase += \"browse/page/\";\n var pageLinkSuffix = \"/\";\n if (typeof filters.category === 'number') pageLinkSuffix += \"cat/\" + filters.category + \"/\";\n pageLinkSuffix += \"ord/\" + filters.order + \"/\";\n var previousButtonDisplay;\n if (currentPage > 1) previousButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: pageLinkBase + (currentPage - 1) + pageLinkSuffix\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"glyphicon glyphicon-chevron-left\"\n }), \" Previous\"));\n var nextButtonDisplay;\n if (currentPage < totalPages) nextButtonDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: pageLinkBase + (currentPage + 1) + pageLinkSuffix\n }, \"Next \", react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"glyphicon glyphicon-chevron-right\"\n })));\n var paginationDisplay = paginationArray.map(function (p, index) {\n var pageLinkDisplay;\n if (currentPage === p) pageLinkDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"span\", {\n className: \"no-link\"\n }, p);else pageLinkDisplay = react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"a\", {\n href: pageLinkBase + p + pageLinkSuffix\n }, p);\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"li\", {\n key: index\n }, pageLinkDisplay);\n });\n return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n id: \"product-browse-pagination\"\n }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"ul\", null, previousButtonDisplay, paginationDisplay, nextButtonDisplay));\n}\n\nvar rootElement = document.getElementById(\"product-browse-container\");\nreact_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ProductBrowse, null), rootElement);\n\n//# sourceURL=webpack:///./app/product-browse.js?");
/***/ }),
/***/ "./node_modules/object-assign/index.js":
/*!*********************************************!*\
!*** ./node_modules/object-assign/index.js ***!
\*********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\n\n//# sourceURL=webpack:///./node_modules/object-assign/index.js?");
/***/ }),
/***/ "./node_modules/prop-types/checkPropTypes.js":
/*!***************************************************!*\
!*** ./node_modules/prop-types/checkPropTypes.js ***!
\***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\n\nvar printWarning = function() {};\n\nif (true) {\n var ReactPropTypesSecret = __webpack_require__(/*! ./lib/ReactPropTypesSecret */ \"./node_modules/prop-types/lib/ReactPropTypesSecret.js\");\n var loggedTypeFailures = {};\n var has = Function.call.bind(Object.prototype.hasOwnProperty);\n\n printWarning = function(text) {\n var message = 'Warning: ' + text;\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // --- Welcome to debugging React ---\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch (x) {}\n };\n}\n\n/**\n * Assert that the values match with the type specs.\n * Error messages are memorized and will only be shown once.\n *\n * @param {object} typeSpecs Map of name to a ReactPropType\n * @param {object} values Runtime values that need to be type-checked\n * @param {string} location e.g. \"prop\", \"context\", \"child context\"\n * @param {string} componentName Name of the component for error messages.\n * @param {?Function} getStack Returns the component stack.\n * @private\n */\nfunction checkPropTypes(typeSpecs, values, location, componentName, getStack) {\n if (true) {\n for (var typeSpecName in typeSpecs) {\n if (has(typeSpecs, typeSpecName)) {\n var error;\n // Prop type validation may throw. In case they do, we don't want to\n // fail the render phase where it didn't fail before. So we log it.\n // After these have been cleaned up, we'll let them throw.\n try {\n // This is intentionally an invariant that gets caught. It's the same\n // behavior as without this statement except with a better message.\n if (typeof typeSpecs[typeSpecName] !== 'function') {\n var err = Error(\n (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +\n 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'\n );\n err.name = 'Invariant Violation';\n throw err;\n }\n error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);\n } catch (ex) {\n error = ex;\n }\n if (error && !(error instanceof Error)) {\n printWarning(\n (componentName || 'React class') + ': type specification of ' +\n location + ' `' + typeSpecName + '` is invalid; the type checker ' +\n 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +\n 'You may have forgotten to pass an argument to the type checker ' +\n 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +\n 'shape all require an argument).'\n );\n }\n if (error instanceof Error && !(error.message in loggedTypeFailures)) {\n // Only monitor this failure once because there tends to be a lot of the\n // same error.\n loggedTypeFailures[error.message] = true;\n\n var stack = getStack ? getStack() : '';\n\n printWarning(\n 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')\n );\n }\n }\n }\n }\n}\n\n/**\n * Resets warning cache when testing.\n *\n * @private\n */\ncheckPropTypes.resetWarningCache = function() {\n if (true) {\n loggedTypeFailures = {};\n }\n}\n\nmodule.exports = checkPropTypes;\n\n\n//# sourceURL=webpack:///./node_modules/prop-types/checkPropTypes.js?");
/***/ }),
/***/ "./node_modules/prop-types/lib/ReactPropTypesSecret.js":
/*!*************************************************************!*\
!*** ./node_modules/prop-types/lib/ReactPropTypesSecret.js ***!
\*************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n\n\n//# sourceURL=webpack:///./node_modules/prop-types/lib/ReactPropTypesSecret.js?");
/***/ }),
/***/ "./node_modules/react-device-detect/dist/index.js":
/*!********************************************************!*\
!*** ./node_modules/react-device-detect/dist/index.js ***!
\********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
eval("module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 3);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar UAParser = __webpack_require__(6);\n\nvar UA = exports.UA = new UAParser();\n\nvar browser = exports.browser = UA.getBrowser();\nvar cpu = exports.cpu = UA.getCPU();\nvar device = exports.device = UA.getDevice();\nvar engine = exports.engine = UA.getEngine();\nvar os = exports.os = UA.getOS();\nvar ua = exports.ua = UA.getUA();\nvar setUA = exports.setUA = function setUA(uaStr) {\n return UA.setUA(uaStr);\n};\n\nvar mockUserAgent = exports.mockUserAgent = function mockUserAgent(userAgent) {\n window.navigator.__defineGetter__(\"userAgent\", function () {\n return userAgent;\n });\n};\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.isYandex = exports.isEdge = exports.getUA = exports.engineVersion = exports.engineName = exports.mobileModel = exports.mobileVendor = exports.browserName = exports.browserVersion = exports.fullBrowserVersion = exports.osName = exports.osVersion = exports.isIE = exports.isOpera = exports.isSafari = exports.isFirefox = exports.isChrome = exports.isIOS = exports.isWinPhone = exports.isAndroid = exports.isBrowser = exports.isTablet = exports.isMobileOnly = exports.isMobile = exports.isChromium = exports.isMobileSafari = exports.isWearable = exports.isConsole = exports.isSmartTV = undefined;\n\nvar _getUaData = __webpack_require__(0);\n\nvar _types = __webpack_require__(2);\n\nvar CHROME = _types.BROWSER_TYPES.CHROME,\n CHROMIUM = _types.BROWSER_TYPES.CHROMIUM,\n IE = _types.BROWSER_TYPES.IE,\n INTERNET_EXPLORER = _types.BROWSER_TYPES.INTERNET_EXPLORER,\n OPERA = _types.BROWSER_TYPES.OPERA,\n FIREFOX = _types.BROWSER_TYPES.FIREFOX,\n SAFARI = _types.BROWSER_TYPES.SAFARI,\n MOBILE_SAFARI = _types.BROWSER_TYPES.MOBILE_SAFARI,\n EDGE = _types.BROWSER_TYPES.EDGE,\n YANDEX = _types.BROWSER_TYPES.YANDEX;\nvar MOBILE = _types.DEVICE_TYPES.MOBILE,\n TABLET = _types.DEVICE_TYPES.TABLET,\n SMART_TV = _types.DEVICE_TYPES.SMART_TV,\n BROWSER = _types.DEVICE_TYPES.BROWSER,\n WEARABLE = _types.DEVICE_TYPES.WEARABLE,\n CONSOLE = _types.DEVICE_TYPES.CONSOLE;\nvar ANDROID = _types.OS_TYPES.ANDROID,\n WINDOWS_PHONE = _types.OS_TYPES.WINDOWS_PHONE,\n IOS = _types.OS_TYPES.IOS;\n\n\nvar isMobileType = function isMobileType() {\n return _getUaData.device.type === MOBILE;\n};\nvar isTabletType = function isTabletType() {\n return _getUaData.device.type === TABLET;\n};\n\nvar isMobileAndTabletType = function isMobileAndTabletType() {\n switch (_getUaData.device.type) {\n case MOBILE:\n case TABLET:\n return true;\n default:\n return false;\n }\n};\n\nvar isSmartTVType = function isSmartTVType() {\n return _getUaData.device.type === SMART_TV;\n};\nvar isBrowserType = function isBrowserType() {\n return _getUaData.device.type === BROWSER;\n};\nvar isWearableType = function isWearableType() {\n return _getUaData.device.type === WEARABLE;\n};\nvar isConsoleType = function isConsoleType() {\n return _getUaData.device.type === CONSOLE;\n};\nvar isAndroidType = function isAndroidType() {\n return _getUaData.os.name === ANDROID;\n};\nvar isWinPhoneType = function isWinPhoneType() {\n return _getUaData.os.name === WINDOWS_PHONE;\n};\nvar isIOSType = function isIOSType() {\n return _getUaData.os.name === IOS;\n};\nvar isChromeType = function isChromeType() {\n return _getUaData.browser.name === CHROME;\n};\nvar isFirefoxType = function isFirefoxType() {\n return _getUaData.browser.name === FIREFOX;\n};\nvar isChromiumType = function isChromiumType() {\n return _getUaData.browser.name === CHROMIUM;\n};\nvar isEdgeType = function isEdgeType() {\n return _getUaData.browser.name === EDGE;\n};\nvar isYandexType = function isYandexType() {\n return _getUaData.browser.name === YANDEX;\n};\nvar isSafariType = function isSafariType() {\n return _getUaData.browser.name === SAFARI || _getUaData.browser.name === MOBILE_SAFARI;\n};\nvar isMobileSafariType = function isMobileSafariType() {\n return _getUaData.browser.name === MOBILE_SAFARI;\n};\nvar isOperaType = function isOperaType() {\n return _getUaData.browser.name === OPERA;\n};\nvar isIEType = function isIEType() {\n return _getUaData.browser.name === INTERNET_EXPLORER || _getUaData.browser.name === IE;\n};\n\nvar getBrowserFullVersion = function getBrowserFullVersion() {\n return _getUaData.browser.major;\n};\nvar getBrowserVersion = function getBrowserVersion() {\n return _getUaData.browser.version;\n};\nvar getOsVersion = function getOsVersion() {\n return _getUaData.os.version ? _getUaData.os.version : \"none\";\n};\nvar getOsName = function getOsName() {\n return _getUaData.os.name ? _getUaData.os.name : \"none\";\n};\nvar getBrowserName = function getBrowserName() {\n return _getUaData.browser.name;\n};\nvar getMobileVendor = function getMobileVendor() {\n return _getUaData.device.vendor ? _getUaData.device.vendor : \"none\";\n};\nvar getMobileModel = function getMobileModel() {\n return _getUaData.device.model ? _getUaData.device.model : \"none\";\n};\nvar getEngineName = function getEngineName() {\n return _getUaData.engine.name;\n};\nvar getEngineVersion = function getEngineVersion() {\n return _getUaData.engine.version;\n};\nvar getUseragent = function getUseragent() {\n return _getUaData.ua;\n};\n\nvar isSmartTV = exports.isSmartTV = isSmartTVType();\nvar isConsole = exports.isConsole = isConsoleType();\nvar isWearable = exports.isWearable = isWearableType();\nvar isMobileSafari = exports.isMobileSafari = isMobileSafariType();\nvar isChromium = exports.isChromium = isChromiumType();\nvar isMobile = exports.isMobile = isMobileAndTabletType();\nvar isMobileOnly = exports.isMobileOnly = isMobileType();\nvar isTablet = exports.isTablet = isTabletType();\nvar isBrowser = exports.isBrowser = isBrowserType();\nvar isAndroid = exports.isAndroid = isAndroidType();\nvar isWinPhone = exports.isWinPhone = isWinPhoneType();\nvar isIOS = exports.isIOS = isIOSType();\nvar isChrome = exports.isChrome = isChromeType();\nvar isFirefox = exports.isFirefox = isFirefoxType();\nvar isSafari = exports.isSafari = isSafariType();\nvar isOpera = exports.isOpera = isOperaType();\nvar isIE = exports.isIE = isIEType();\nvar osVersion = exports.osVersion = getOsVersion();\nvar osName = exports.osName = getOsName();\nvar fullBrowserVersion = exports.fullBrowserVersion = getBrowserFullVersion();\nvar browserVersion = exports.browserVersion = getBrowserVersion();\nvar browserName = exports.browserName = getBrowserName();\nvar mobileVendor = exports.mobileVendor = getMobileVendor();\nvar mobileModel = exports.mobileModel = getMobileModel();\nvar engineName = exports.engineName = getEngineName();\nvar engineVersion = exports.engineVersion = getEngineVersion();\nvar getUA = exports.getUA = getUseragent();\nvar isEdge = exports.isEdge = isEdgeType();\nvar isYandex = exports.isYandex = isYandexType();\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.wearPayload = exports.consolePayload = exports.stvPayload = exports.mobilePayload = exports.broPayload = exports.getCurrentBrowser = exports.checkType = exports.OS_TYPES = exports.BROWSER_TYPES = exports.DEVICE_TYPES = undefined;\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _getUaData = __webpack_require__(0);\n\nvar DEVICE_TYPES = exports.DEVICE_TYPES = {\n MOBILE: 'mobile',\n TABLET: 'tablet',\n SMART_TV: 'smarttv',\n CONSOLE: 'console',\n WEARABLE: 'wearable',\n BROWSER: undefined\n};\n\nvar BROWSER_TYPES = exports.BROWSER_TYPES = {\n CHROME: 'Chrome',\n FIREFOX: \"Firefox\",\n OPERA: \"Opera\",\n YANDEX: \"Yandex\",\n SAFARI: \"Safari\",\n INTERNET_EXPLORER: \"Internet Explorer\",\n EDGE: \"Edge\",\n CHROMIUM: \"Chromium\",\n IE: 'IE',\n MOBILE_SAFARI: \"Mobile Safari\"\n};\n\nvar OS_TYPES = exports.OS_TYPES = {\n IOS: 'iOS',\n ANDROID: \"Android\",\n WINDOWS_PHONE: \"Windows Phone\"\n};\n\nvar initialData = {\n isMobile: false,\n isTablet: false,\n isBrowser: false,\n isSmartTV: false,\n isConsole: false,\n isWearable: false\n};\n\nvar checkType = exports.checkType = function checkType(type) {\n switch (type) {\n case DEVICE_TYPES.MOBILE:\n return { isMobile: true };\n case DEVICE_TYPES.TABLET:\n return { isTablet: true };\n case DEVICE_TYPES.SMART_TV:\n return { isSmartTV: true };\n case DEVICE_TYPES.CONSOLE:\n return { isConsole: true };\n case DEVICE_TYPES.WEARABLE:\n return { isWearable: true };\n case DEVICE_TYPES.BROWSER:\n return { isBrowser: true };\n default:\n return initialData;\n }\n};\n\nvar getCurrentBrowser = exports.getCurrentBrowser = function getCurrentBrowser(name) {\n switch (name) {\n case BROWSER_TYPES.CHROME:\n case BROWSER_TYPES.FIREFOX:\n case BROWSER_TYPES.OPERA:\n case BROWSER_TYPES.YANDEX:\n case BROWSER_TYPES.SAFARI:\n case BROWSER_TYPES.IE:\n case BROWSER_TYPES.EDGE:\n case BROWSER_TYPES.CHROMIUM:\n return true;\n default:\n return false;\n }\n};\n\nvar broPayload = exports.broPayload = function broPayload(isBrowser, browser, engine, os, ua) {\n return {\n isBrowser: isBrowser,\n browserMajorVersion: browser.major,\n browserFullVersion: browser.version,\n browserName: browser.name,\n engineName: engine.name || false,\n engineVersion: engine.version,\n osName: os.name,\n osVersion: os.version,\n userAgent: ua\n };\n};\n\nvar mobilePayload = exports.mobilePayload = function mobilePayload(type, device, os, ua) {\n return _extends({}, type, {\n vendor: device.vendor || \"none\",\n model: device.model || \"none\",\n os: os.name || \"none\",\n osVersion: os.version || \"none\",\n ua: ua || \"none\"\n });\n};\n\nvar stvPayload = exports.stvPayload = function stvPayload(isSmartTV, engine, os, ua) {\n return {\n isSmartTV: isSmartTV,\n engineName: engine.name || false,\n engineVersion: engine.version,\n osName: os.name,\n osVersion: os.version,\n userAgent: ua\n };\n};\n\nvar consolePayload = exports.consolePayload = function consolePayload(isConsole, engine, os, ua) {\n return {\n isConsole: isConsole,\n engineName: engine.name || false,\n engineVersion: engine.version,\n osName: os.name,\n osVersion: os.version,\n userAgent: ua\n };\n};\n\nvar wearPayload = exports.wearPayload = function wearPayload(isWearable, engine, os, ua) {\n return {\n isWearable: isWearable,\n engineName: engine.name || false,\n engineVersion: engine.version,\n osName: os.name,\n osVersion: os.version,\n userAgent: ua\n };\n};\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.deviceDetect = undefined;\n\nvar _views = __webpack_require__(4);\n\nObject.keys(_views).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n Object.defineProperty(exports, key, {\n enumerable: true,\n get: function get() {\n return _views[key];\n }\n });\n});\n\nvar _selectors = __webpack_require__(1);\n\nObject.keys(_selectors).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n Object.defineProperty(exports, key, {\n enumerable: true,\n get: function get() {\n return _selectors[key];\n }\n });\n});\n\nvar _detect = __webpack_require__(8);\n\nvar _detect2 = _interopRequireDefault(_detect);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.deviceDetect = _detect2.default;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.CustomView = exports.WearableView = exports.ConsoleView = exports.SmartTVView = exports.MobileOnlyView = exports.WinPhoneView = exports.TabletView = exports.MobileView = exports.IOSView = exports.IEView = exports.BrowserView = exports.AndroidView = undefined;\n\nvar _react = __webpack_require__(5);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _selectors = __webpack_require__(1);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar AndroidView = exports.AndroidView = function AndroidView(_ref) {\n var renderWithFragment = _ref.renderWithFragment,\n children = _ref.children,\n viewClassName = _ref.viewClassName,\n style = _ref.style;\n\n return _selectors.isAndroid ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar BrowserView = exports.BrowserView = function BrowserView(_ref2) {\n var renderWithFragment = _ref2.renderWithFragment,\n children = _ref2.children,\n viewClassName = _ref2.viewClassName,\n style = _ref2.style;\n\n return _selectors.isBrowser ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar IEView = exports.IEView = function IEView(_ref3) {\n var renderWithFragment = _ref3.renderWithFragment,\n children = _ref3.children,\n viewClassName = _ref3.viewClassName,\n style = _ref3.style;\n\n return _selectors.isIE ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar IOSView = exports.IOSView = function IOSView(_ref4) {\n var renderWithFragment = _ref4.renderWithFragment,\n children = _ref4.children,\n viewClassName = _ref4.viewClassName,\n style = _ref4.style;\n\n return _selectors.isIOS ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar MobileView = exports.MobileView = function MobileView(_ref5) {\n var renderWithFragment = _ref5.renderWithFragment,\n children = _ref5.children,\n viewClassName = _ref5.viewClassName,\n style = _ref5.style;\n\n return _selectors.isMobile ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar TabletView = exports.TabletView = function TabletView(_ref6) {\n var renderWithFragment = _ref6.renderWithFragment,\n children = _ref6.children,\n viewClassName = _ref6.viewClassName,\n style = _ref6.style;\n\n return _selectors.isTablet ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar WinPhoneView = exports.WinPhoneView = function WinPhoneView(_ref7) {\n var renderWithFragment = _ref7.renderWithFragment,\n children = _ref7.children,\n viewClassName = _ref7.viewClassName,\n style = _ref7.style;\n\n return _selectors.isWinPhone ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar MobileOnlyView = exports.MobileOnlyView = function MobileOnlyView(_ref8) {\n var renderWithFragment = _ref8.renderWithFragment,\n children = _ref8.children,\n viewClassName = _ref8.viewClassName,\n style = _ref8.style;\n\n return _selectors.isMobileOnly ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar SmartTVView = exports.SmartTVView = function SmartTVView(_ref9) {\n var renderWithFragment = _ref9.renderWithFragment,\n children = _ref9.children,\n viewClassName = _ref9.viewClassName,\n style = _ref9.style;\n\n return _selectors.isSmartTV ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar ConsoleView = exports.ConsoleView = function ConsoleView(_ref10) {\n var renderWithFragment = _ref10.renderWithFragment,\n children = _ref10.children,\n viewClassName = _ref10.viewClassName,\n style = _ref10.style;\n\n return _selectors.isConsole ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar WearableView = exports.WearableView = function WearableView(_ref11) {\n var renderWithFragment = _ref11.renderWithFragment,\n children = _ref11.children,\n viewClassName = _ref11.viewClassName,\n style = _ref11.style;\n\n return _selectors.isWearable ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\nvar CustomView = exports.CustomView = function CustomView(_ref12) {\n var renderWithFragment = _ref12.renderWithFragment,\n children = _ref12.children,\n viewClassName = _ref12.viewClassName,\n style = _ref12.style,\n condition = _ref12.condition;\n\n return condition ? renderWithFragment ? _react2.default.createElement(\n _react.Fragment,\n null,\n children\n ) : _react2.default.createElement(\n 'div',\n { className: viewClassName, style: style },\n children\n ) : null;\n};\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\nmodule.exports = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * UAParser.js v0.7.18\n * Lightweight JavaScript-based User-Agent string parser\n * https://github.com/faisalman/ua-parser-js\n *\n * Copyright © 2012-2016 Faisal Salman \n * Dual licensed under GPLv2 or MIT\n */\n(function(window,undefined){\"use strict\";var LIBVERSION=\"0.7.18\",EMPTY=\"\",UNKNOWN=\"?\",FUNC_TYPE=\"function\",UNDEF_TYPE=\"undefined\",OBJ_TYPE=\"object\",STR_TYPE=\"string\",MAJOR=\"major\",MODEL=\"model\",NAME=\"name\",TYPE=\"type\",VENDOR=\"vendor\",VERSION=\"version\",ARCHITECTURE=\"architecture\",CONSOLE=\"console\",MOBILE=\"mobile\",TABLET=\"tablet\",SMARTTV=\"smarttv\",WEARABLE=\"wearable\",EMBEDDED=\"embedded\";var util={extend:function(regexes,extensions){var margedRegexes={};for(var i in regexes){if(extensions[i]&&extensions[i].length%2===0){margedRegexes[i]=extensions[i].concat(regexes[i])}else{margedRegexes[i]=regexes[i]}}return margedRegexes},has:function(str1,str2){if(typeof str1===\"string\"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.replace(/[^\\d\\.]/g,\"\").split(\".\")[0]:undefined},trim:function(str){return str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\"\")}};var mapper={rgx:function(ua,arrays){var i=0,j,k,p,q,matches,match;while(i0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){this[q[0]]=q[1].call(this,match)}else{this[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){this[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{this[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){this[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{this[q]=match?match:undefined}}}}i+=2}},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;\n if (plugins[pluginIndex]) {\n continue;\n }\n !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;\n plugins[pluginIndex] = pluginModule;\n var publishedEvents = pluginModule.eventTypes;\n for (var eventName in publishedEvents) {\n !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;\n }\n }\n}\n\n/**\n * Publishes an event so that it can be dispatched by the supplied plugin.\n *\n * @param {object} dispatchConfig Dispatch configuration for the event.\n * @param {object} PluginModule Plugin publishing the event.\n * @return {boolean} True if the event was successfully published.\n * @private\n */\nfunction publishEventForPlugin(dispatchConfig, pluginModule, eventName) {\n !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;\n eventNameDispatchConfigs[eventName] = dispatchConfig;\n\n var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;\n if (phasedRegistrationNames) {\n for (var phaseName in phasedRegistrationNames) {\n if (phasedRegistrationNames.hasOwnProperty(phaseName)) {\n var phasedRegistrationName = phasedRegistrationNames[phaseName];\n publishRegistrationName(phasedRegistrationName, pluginModule, eventName);\n }\n }\n return true;\n } else if (dispatchConfig.registrationName) {\n publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);\n return true;\n }\n return false;\n}\n\n/**\n * Publishes a registration name that is used to identify dispatched events.\n *\n * @param {string} registrationName Registration name to add.\n * @param {object} PluginModule Plugin publishing the event.\n * @private\n */\nfunction publishRegistrationName(registrationName, pluginModule, eventName) {\n !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;\n registrationNameModules[registrationName] = pluginModule;\n registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;\n\n {\n var lowerCasedName = registrationName.toLowerCase();\n possibleRegistrationNames[lowerCasedName] = registrationName;\n\n if (registrationName === 'onDoubleClick') {\n possibleRegistrationNames.ondblclick = registrationName;\n }\n }\n}\n\n/**\n * Registers plugins so that they can extract and dispatch events.\n *\n * @see {EventPluginHub}\n */\n\n/**\n * Ordered list of injected plugins.\n */\nvar plugins = [];\n\n/**\n * Mapping from event name to dispatch config\n */\nvar eventNameDispatchConfigs = {};\n\n/**\n * Mapping from registration name to plugin module\n */\nvar registrationNameModules = {};\n\n/**\n * Mapping from registration name to event name\n */\nvar registrationNameDependencies = {};\n\n/**\n * Mapping from lowercase registration names to the properly cased version,\n * used to warn in the case of missing event handlers. Available\n * only in true.\n * @type {Object}\n */\nvar possibleRegistrationNames = {};\n// Trust the developer to only use possibleRegistrationNames in true\n\n/**\n * Injects an ordering of plugins (by plugin name). This allows the ordering\n * to be decoupled from injection of the actual plugins so that ordering is\n * always deterministic regardless of packaging, on-the-fly injection, etc.\n *\n * @param {array} InjectedEventPluginOrder\n * @internal\n * @see {EventPluginHub.injection.injectEventPluginOrder}\n */\nfunction injectEventPluginOrder(injectedEventPluginOrder) {\n !!eventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0;\n // Clone the ordering so it cannot be dynamically mutated.\n eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);\n recomputePluginOrdering();\n}\n\n/**\n * Injects plugins to be used by `EventPluginHub`. The plugin names must be\n * in the ordering injected by `injectEventPluginOrder`.\n *\n * Plugins can be injected as part of page initialization or on-the-fly.\n *\n * @param {object} injectedNamesToPlugins Map from names to plugin modules.\n * @internal\n * @see {EventPluginHub.injection.injectEventPluginsByName}\n */\nfunction injectEventPluginsByName(injectedNamesToPlugins) {\n var isOrderingDirty = false;\n for (var pluginName in injectedNamesToPlugins) {\n if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {\n continue;\n }\n var pluginModule = injectedNamesToPlugins[pluginName];\n if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {\n !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;\n namesToPlugins[pluginName] = pluginModule;\n isOrderingDirty = true;\n }\n }\n if (isOrderingDirty) {\n recomputePluginOrdering();\n }\n}\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar warningWithoutStack = function () {};\n\n{\n warningWithoutStack = function (condition, format) {\n for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n args[_key - 2] = arguments[_key];\n }\n\n if (format === undefined) {\n throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');\n }\n if (args.length > 8) {\n // Check before the condition to catch violations early.\n throw new Error('warningWithoutStack() currently supports at most 8 arguments.');\n }\n if (condition) {\n return;\n }\n if (typeof console !== 'undefined') {\n var argsWithFormat = args.map(function (item) {\n return '' + item;\n });\n argsWithFormat.unshift('Warning: ' + format);\n\n // We intentionally don't use spread (or .apply) directly because it\n // breaks IE9: https://github.com/facebook/react/issues/13610\n Function.prototype.apply.call(console.error, console, argsWithFormat);\n }\n try {\n // --- Welcome to debugging React ---\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n var argIndex = 0;\n var message = 'Warning: ' + format.replace(/%s/g, function () {\n return args[argIndex++];\n });\n throw new Error(message);\n } catch (x) {}\n };\n}\n\nvar warningWithoutStack$1 = warningWithoutStack;\n\nvar getFiberCurrentPropsFromNode = null;\nvar getInstanceFromNode = null;\nvar getNodeFromInstance = null;\n\nfunction setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {\n getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;\n getInstanceFromNode = getInstanceFromNodeImpl;\n getNodeFromInstance = getNodeFromInstanceImpl;\n {\n !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;\n }\n}\n\nvar validateEventDispatches = void 0;\n{\n validateEventDispatches = function (event) {\n var dispatchListeners = event._dispatchListeners;\n var dispatchInstances = event._dispatchInstances;\n\n var listenersIsArr = Array.isArray(dispatchListeners);\n var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;\n\n var instancesIsArr = Array.isArray(dispatchInstances);\n var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;\n\n !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;\n };\n}\n\n/**\n * Dispatch the event to the listener.\n * @param {SyntheticEvent} event SyntheticEvent to handle\n * @param {function} listener Application-level callback\n * @param {*} inst Internal component instance\n */\nfunction executeDispatch(event, listener, inst) {\n var type = event.type || 'unknown-event';\n event.currentTarget = getNodeFromInstance(inst);\n invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);\n event.currentTarget = null;\n}\n\n/**\n * Standard/simple iteration through an event's collected dispatches.\n */\nfunction executeDispatchesInOrder(event) {\n var dispatchListeners = event._dispatchListeners;\n var dispatchInstances = event._dispatchInstances;\n {\n validateEventDispatches(event);\n }\n if (Array.isArray(dispatchListeners)) {\n for (var i = 0; i < dispatchListeners.length; i++) {\n if (event.isPropagationStopped()) {\n break;\n }\n // Listeners and Instances are two parallel arrays that are always in sync.\n executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);\n }\n } else if (dispatchListeners) {\n executeDispatch(event, dispatchListeners, dispatchInstances);\n }\n event._dispatchListeners = null;\n event._dispatchInstances = null;\n}\n\n/**\n * @see executeDispatchesInOrderStopAtTrueImpl\n */\n\n\n/**\n * Execution of a \"direct\" dispatch - there must be at most one dispatch\n * accumulated on the event or it is considered an error. It doesn't really make\n * sense for an event with multiple dispatches (bubbled) to keep track of the\n * return values at each dispatch execution, but it does tend to make sense when\n * dealing with \"direct\" dispatches.\n *\n * @return {*} The return value of executing the single dispatch.\n */\n\n\n/**\n * @param {SyntheticEvent} event\n * @return {boolean} True iff number of dispatches accumulated is greater than 0.\n */\n\n/**\n * Accumulates items that must not be null or undefined into the first one. This\n * is used to conserve memory by avoiding array allocations, and thus sacrifices\n * API cleanness. Since `current` can be null before being passed in and not\n * null after this function, make sure to assign it back to `current`:\n *\n * `a = accumulateInto(a, b);`\n *\n * This API should be sparingly used. Try `accumulate` for something cleaner.\n *\n * @return {*|array<*>} An accumulation of items.\n */\n\nfunction accumulateInto(current, next) {\n !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;\n\n if (current == null) {\n return next;\n }\n\n // Both are not empty. Warning: Never call x.concat(y) when you are not\n // certain that x is an Array (x could be a string with concat method).\n if (Array.isArray(current)) {\n if (Array.isArray(next)) {\n current.push.apply(current, next);\n return current;\n }\n current.push(next);\n return current;\n }\n\n if (Array.isArray(next)) {\n // A bit too dangerous to mutate `next`.\n return [current].concat(next);\n }\n\n return [current, next];\n}\n\n/**\n * @param {array} arr an \"accumulation\" of items which is either an Array or\n * a single item. Useful when paired with the `accumulate` module. This is a\n * simple utility that allows us to reason about a collection of items, but\n * handling the case when there is exactly one item (and we do not need to\n * allocate an array).\n * @param {function} cb Callback invoked with each element or a collection.\n * @param {?} [scope] Scope used as `this` in a callback.\n */\nfunction forEachAccumulated(arr, cb, scope) {\n if (Array.isArray(arr)) {\n arr.forEach(cb, scope);\n } else if (arr) {\n cb.call(scope, arr);\n }\n}\n\n/**\n * Internal queue of events that have accumulated their dispatches and are\n * waiting to have their dispatches executed.\n */\nvar eventQueue = null;\n\n/**\n * Dispatches an event and releases it back into the pool, unless persistent.\n *\n * @param {?object} event Synthetic event to be dispatched.\n * @private\n */\nvar executeDispatchesAndRelease = function (event) {\n if (event) {\n executeDispatchesInOrder(event);\n\n if (!event.isPersistent()) {\n event.constructor.release(event);\n }\n }\n};\nvar executeDispatchesAndReleaseTopLevel = function (e) {\n return executeDispatchesAndRelease(e);\n};\n\nfunction isInteractive(tag) {\n return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';\n}\n\nfunction shouldPreventMouseEvent(name, type, props) {\n switch (name) {\n case 'onClick':\n case 'onClickCapture':\n case 'onDoubleClick':\n case 'onDoubleClickCapture':\n case 'onMouseDown':\n case 'onMouseDownCapture':\n case 'onMouseMove':\n case 'onMouseMoveCapture':\n case 'onMouseUp':\n case 'onMouseUpCapture':\n return !!(props.disabled && isInteractive(type));\n default:\n return false;\n }\n}\n\n/**\n * This is a unified interface for event plugins to be installed and configured.\n *\n * Event plugins can implement the following properties:\n *\n * `extractEvents` {function(string, DOMEventTarget, string, object): *}\n * Required. When a top-level event is fired, this method is expected to\n * extract synthetic events that will in turn be queued and dispatched.\n *\n * `eventTypes` {object}\n * Optional, plugins that fire events must publish a mapping of registration\n * names that are used to register listeners. Values of this mapping must\n * be objects that contain `registrationName` or `phasedRegistrationNames`.\n *\n * `executeDispatch` {function(object, function, string)}\n * Optional, allows plugins to override how an event gets dispatched. By\n * default, the listener is simply invoked.\n *\n * Each plugin that is injected into `EventsPluginHub` is immediately operable.\n *\n * @public\n */\n\n/**\n * Methods for injecting dependencies.\n */\nvar injection = {\n /**\n * @param {array} InjectedEventPluginOrder\n * @public\n */\n injectEventPluginOrder: injectEventPluginOrder,\n\n /**\n * @param {object} injectedNamesToPlugins Map from names to plugin modules.\n */\n injectEventPluginsByName: injectEventPluginsByName\n};\n\n/**\n * @param {object} inst The instance, which is the source of events.\n * @param {string} registrationName Name of listener (e.g. `onClick`).\n * @return {?function} The stored callback.\n */\nfunction getListener(inst, registrationName) {\n var listener = void 0;\n\n // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not\n // live here; needs to be moved to a better place soon\n var stateNode = inst.stateNode;\n if (!stateNode) {\n // Work in progress (ex: onload events in incremental mode).\n return null;\n }\n var props = getFiberCurrentPropsFromNode(stateNode);\n if (!props) {\n // Work in progress.\n return null;\n }\n listener = props[registrationName];\n if (shouldPreventMouseEvent(registrationName, inst.type, props)) {\n return null;\n }\n !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;\n return listener;\n}\n\n/**\n * Allows registered plugins an opportunity to extract events from top-level\n * native browser events.\n *\n * @return {*} An accumulation of synthetic events.\n * @internal\n */\nfunction extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var events = null;\n for (var i = 0; i < plugins.length; i++) {\n // Not every plugin in the ordering may be loaded at runtime.\n var possiblePlugin = plugins[i];\n if (possiblePlugin) {\n var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);\n if (extractedEvents) {\n events = accumulateInto(events, extractedEvents);\n }\n }\n }\n return events;\n}\n\nfunction runEventsInBatch(events) {\n if (events !== null) {\n eventQueue = accumulateInto(eventQueue, events);\n }\n\n // Set `eventQueue` to null before processing it so that we can tell if more\n // events get enqueued while processing.\n var processingEventQueue = eventQueue;\n eventQueue = null;\n\n if (!processingEventQueue) {\n return;\n }\n\n forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);\n !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;\n // This would be a good time to rethrow if any of the event handlers threw.\n rethrowCaughtError();\n}\n\nfunction runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);\n runEventsInBatch(events);\n}\n\nvar FunctionComponent = 0;\nvar ClassComponent = 1;\nvar IndeterminateComponent = 2; // Before we know whether it is function or class\nvar HostRoot = 3; // Root of a host tree. Could be nested inside another node.\nvar HostPortal = 4; // A subtree. Could be an entry point to a different renderer.\nvar HostComponent = 5;\nvar HostText = 6;\nvar Fragment = 7;\nvar Mode = 8;\nvar ContextConsumer = 9;\nvar ContextProvider = 10;\nvar ForwardRef = 11;\nvar Profiler = 12;\nvar SuspenseComponent = 13;\nvar MemoComponent = 14;\nvar SimpleMemoComponent = 15;\nvar LazyComponent = 16;\nvar IncompleteClassComponent = 17;\nvar DehydratedSuspenseComponent = 18;\n\nvar randomKey = Math.random().toString(36).slice(2);\nvar internalInstanceKey = '__reactInternalInstance$' + randomKey;\nvar internalEventHandlersKey = '__reactEventHandlers$' + randomKey;\n\nfunction precacheFiberNode(hostInst, node) {\n node[internalInstanceKey] = hostInst;\n}\n\n/**\n * Given a DOM node, return the closest ReactDOMComponent or\n * ReactDOMTextComponent instance ancestor.\n */\nfunction getClosestInstanceFromNode(node) {\n if (node[internalInstanceKey]) {\n return node[internalInstanceKey];\n }\n\n while (!node[internalInstanceKey]) {\n if (node.parentNode) {\n node = node.parentNode;\n } else {\n // Top of the tree. This node must not be part of a React tree (or is\n // unmounted, potentially).\n return null;\n }\n }\n\n var inst = node[internalInstanceKey];\n if (inst.tag === HostComponent || inst.tag === HostText) {\n // In Fiber, this will always be the deepest root.\n return inst;\n }\n\n return null;\n}\n\n/**\n * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent\n * instance, or null if the node was not rendered by this React.\n */\nfunction getInstanceFromNode$1(node) {\n var inst = node[internalInstanceKey];\n if (inst) {\n if (inst.tag === HostComponent || inst.tag === HostText) {\n return inst;\n } else {\n return null;\n }\n }\n return null;\n}\n\n/**\n * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding\n * DOM node.\n */\nfunction getNodeFromInstance$1(inst) {\n if (inst.tag === HostComponent || inst.tag === HostText) {\n // In Fiber this, is just the state node right now. We assume it will be\n // a host component or host text.\n return inst.stateNode;\n }\n\n // Without this first invariant, passing a non-DOM-component triggers the next\n // invariant for a missing parent, which is super confusing.\n invariant(false, 'getNodeFromInstance: Invalid argument.');\n}\n\nfunction getFiberCurrentPropsFromNode$1(node) {\n return node[internalEventHandlersKey] || null;\n}\n\nfunction updateFiberProps(node, props) {\n node[internalEventHandlersKey] = props;\n}\n\nfunction getParent(inst) {\n do {\n inst = inst.return;\n // TODO: If this is a HostRoot we might want to bail out.\n // That is depending on if we want nested subtrees (layers) to bubble\n // events to their parent. We could also go through parentNode on the\n // host node but that wouldn't work for React Native and doesn't let us\n // do the portal feature.\n } while (inst && inst.tag !== HostComponent);\n if (inst) {\n return inst;\n }\n return null;\n}\n\n/**\n * Return the lowest common ancestor of A and B, or null if they are in\n * different trees.\n */\nfunction getLowestCommonAncestor(instA, instB) {\n var depthA = 0;\n for (var tempA = instA; tempA; tempA = getParent(tempA)) {\n depthA++;\n }\n var depthB = 0;\n for (var tempB = instB; tempB; tempB = getParent(tempB)) {\n depthB++;\n }\n\n // If A is deeper, crawl up.\n while (depthA - depthB > 0) {\n instA = getParent(instA);\n depthA--;\n }\n\n // If B is deeper, crawl up.\n while (depthB - depthA > 0) {\n instB = getParent(instB);\n depthB--;\n }\n\n // Walk in lockstep until we find a match.\n var depth = depthA;\n while (depth--) {\n if (instA === instB || instA === instB.alternate) {\n return instA;\n }\n instA = getParent(instA);\n instB = getParent(instB);\n }\n return null;\n}\n\n/**\n * Return if A is an ancestor of B.\n */\n\n\n/**\n * Return the parent instance of the passed-in instance.\n */\n\n\n/**\n * Simulates the traversal of a two-phase, capture/bubble event dispatch.\n */\nfunction traverseTwoPhase(inst, fn, arg) {\n var path = [];\n while (inst) {\n path.push(inst);\n inst = getParent(inst);\n }\n var i = void 0;\n for (i = path.length; i-- > 0;) {\n fn(path[i], 'captured', arg);\n }\n for (i = 0; i < path.length; i++) {\n fn(path[i], 'bubbled', arg);\n }\n}\n\n/**\n * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that\n * should would receive a `mouseEnter` or `mouseLeave` event.\n *\n * Does not invoke the callback on the nearest common ancestor because nothing\n * \"entered\" or \"left\" that element.\n */\nfunction traverseEnterLeave(from, to, fn, argFrom, argTo) {\n var common = from && to ? getLowestCommonAncestor(from, to) : null;\n var pathFrom = [];\n while (true) {\n if (!from) {\n break;\n }\n if (from === common) {\n break;\n }\n var alternate = from.alternate;\n if (alternate !== null && alternate === common) {\n break;\n }\n pathFrom.push(from);\n from = getParent(from);\n }\n var pathTo = [];\n while (true) {\n if (!to) {\n break;\n }\n if (to === common) {\n break;\n }\n var _alternate = to.alternate;\n if (_alternate !== null && _alternate === common) {\n break;\n }\n pathTo.push(to);\n to = getParent(to);\n }\n for (var i = 0; i < pathFrom.length; i++) {\n fn(pathFrom[i], 'bubbled', argFrom);\n }\n for (var _i = pathTo.length; _i-- > 0;) {\n fn(pathTo[_i], 'captured', argTo);\n }\n}\n\n/**\n * Some event types have a notion of different registration names for different\n * \"phases\" of propagation. This finds listeners by a given phase.\n */\nfunction listenerAtPhase(inst, event, propagationPhase) {\n var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];\n return getListener(inst, registrationName);\n}\n\n/**\n * A small set of propagation patterns, each of which will accept a small amount\n * of information, and generate a set of \"dispatch ready event objects\" - which\n * are sets of events that have already been annotated with a set of dispatched\n * listener functions/ids. The API is designed this way to discourage these\n * propagation strategies from actually executing the dispatches, since we\n * always want to collect the entire set of dispatches before executing even a\n * single one.\n */\n\n/**\n * Tags a `SyntheticEvent` with dispatched listeners. Creating this function\n * here, allows us to not have to bind or create functions for each event.\n * Mutating the event's members allows us to not have to create a wrapping\n * \"dispatch\" object that pairs the event with the listener.\n */\nfunction accumulateDirectionalDispatches(inst, phase, event) {\n {\n !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;\n }\n var listener = listenerAtPhase(inst, event, phase);\n if (listener) {\n event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);\n event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);\n }\n}\n\n/**\n * Collect dispatches (must be entirely collected before dispatching - see unit\n * tests). Lazily allocate the array to conserve memory. We must loop through\n * each event and perform the traversal for each one. We cannot perform a\n * single traversal for the entire collection of events because each event may\n * have a different target.\n */\nfunction accumulateTwoPhaseDispatchesSingle(event) {\n if (event && event.dispatchConfig.phasedRegistrationNames) {\n traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);\n }\n}\n\n/**\n * Accumulates without regard to direction, does not look for phased\n * registration names. Same as `accumulateDirectDispatchesSingle` but without\n * requiring that the `dispatchMarker` be the same as the dispatched ID.\n */\nfunction accumulateDispatches(inst, ignoredDirection, event) {\n if (inst && event && event.dispatchConfig.registrationName) {\n var registrationName = event.dispatchConfig.registrationName;\n var listener = getListener(inst, registrationName);\n if (listener) {\n event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);\n event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);\n }\n }\n}\n\n/**\n * Accumulates dispatches on an `SyntheticEvent`, but only for the\n * `dispatchMarker`.\n * @param {SyntheticEvent} event\n */\nfunction accumulateDirectDispatchesSingle(event) {\n if (event && event.dispatchConfig.registrationName) {\n accumulateDispatches(event._targetInst, null, event);\n }\n}\n\nfunction accumulateTwoPhaseDispatches(events) {\n forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);\n}\n\n\n\nfunction accumulateEnterLeaveDispatches(leave, enter, from, to) {\n traverseEnterLeave(from, to, accumulateDispatches, leave, enter);\n}\n\nfunction accumulateDirectDispatches(events) {\n forEachAccumulated(events, accumulateDirectDispatchesSingle);\n}\n\nvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\n\n// Do not uses the below two methods directly!\n// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.\n// (It is the only module that is allowed to access these methods.)\n\nfunction unsafeCastStringToDOMTopLevelType(topLevelType) {\n return topLevelType;\n}\n\nfunction unsafeCastDOMTopLevelTypeToString(topLevelType) {\n return topLevelType;\n}\n\n/**\n * Generate a mapping of standard vendor prefixes using the defined style property and event name.\n *\n * @param {string} styleProp\n * @param {string} eventName\n * @returns {object}\n */\nfunction makePrefixMap(styleProp, eventName) {\n var prefixes = {};\n\n prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();\n prefixes['Webkit' + styleProp] = 'webkit' + eventName;\n prefixes['Moz' + styleProp] = 'moz' + eventName;\n\n return prefixes;\n}\n\n/**\n * A list of event names to a configurable list of vendor prefixes.\n */\nvar vendorPrefixes = {\n animationend: makePrefixMap('Animation', 'AnimationEnd'),\n animationiteration: makePrefixMap('Animation', 'AnimationIteration'),\n animationstart: makePrefixMap('Animation', 'AnimationStart'),\n transitionend: makePrefixMap('Transition', 'TransitionEnd')\n};\n\n/**\n * Event names that have already been detected and prefixed (if applicable).\n */\nvar prefixedEventNames = {};\n\n/**\n * Element to check for prefixes on.\n */\nvar style = {};\n\n/**\n * Bootstrap if a DOM exists.\n */\nif (canUseDOM) {\n style = document.createElement('div').style;\n\n // On some platforms, in particular some releases of Android 4.x,\n // the un-prefixed \"animation\" and \"transition\" properties are defined on the\n // style object but the events that fire will still be prefixed, so we need\n // to check if the un-prefixed events are usable, and if not remove them from the map.\n if (!('AnimationEvent' in window)) {\n delete vendorPrefixes.animationend.animation;\n delete vendorPrefixes.animationiteration.animation;\n delete vendorPrefixes.animationstart.animation;\n }\n\n // Same as above\n if (!('TransitionEvent' in window)) {\n delete vendorPrefixes.transitionend.transition;\n }\n}\n\n/**\n * Attempts to determine the correct vendor prefixed event name.\n *\n * @param {string} eventName\n * @returns {string}\n */\nfunction getVendorPrefixedEventName(eventName) {\n if (prefixedEventNames[eventName]) {\n return prefixedEventNames[eventName];\n } else if (!vendorPrefixes[eventName]) {\n return eventName;\n }\n\n var prefixMap = vendorPrefixes[eventName];\n\n for (var styleProp in prefixMap) {\n if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {\n return prefixedEventNames[eventName] = prefixMap[styleProp];\n }\n }\n\n return eventName;\n}\n\n/**\n * To identify top level events in ReactDOM, we use constants defined by this\n * module. This is the only module that uses the unsafe* methods to express\n * that the constants actually correspond to the browser event names. This lets\n * us save some bundle size by avoiding a top level type -> event name map.\n * The rest of ReactDOM code should import top level types from this file.\n */\nvar TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');\nvar TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));\nvar TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));\nvar TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));\nvar TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');\nvar TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');\nvar TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');\nvar TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');\nvar TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');\nvar TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');\nvar TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');\nvar TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');\nvar TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');\nvar TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');\nvar TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');\nvar TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');\nvar TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');\nvar TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');\nvar TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');\nvar TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');\nvar TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');\nvar TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');\nvar TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');\nvar TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');\nvar TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');\nvar TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');\nvar TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');\nvar TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');\nvar TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');\nvar TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');\nvar TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');\nvar TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');\nvar TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');\nvar TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');\nvar TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');\nvar TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');\nvar TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');\nvar TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');\nvar TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');\nvar TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');\nvar TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');\nvar TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');\nvar TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');\nvar TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');\nvar TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');\nvar TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');\nvar TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');\nvar TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');\nvar TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');\nvar TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');\nvar TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');\nvar TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');\nvar TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');\nvar TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');\nvar TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');\n\n\nvar TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');\nvar TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');\nvar TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');\nvar TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');\nvar TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');\nvar TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');\nvar TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');\nvar TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');\nvar TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');\nvar TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');\nvar TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');\nvar TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');\nvar TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');\nvar TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');\nvar TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');\nvar TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');\nvar TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');\nvar TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');\nvar TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');\nvar TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');\nvar TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');\nvar TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));\nvar TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');\nvar TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');\nvar TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');\n\n// List of events that need to be individually attached to media elements.\n// Note that events in this list will *not* be listened to at the top level\n// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.\nvar mediaEventTypes = [TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_VOLUME_CHANGE, TOP_WAITING];\n\nfunction getRawEventName(topLevelType) {\n return unsafeCastDOMTopLevelTypeToString(topLevelType);\n}\n\n/**\n * These variables store information about text content of a target node,\n * allowing comparison of content before and after a given event.\n *\n * Identify the node where selection currently begins, then observe\n * both its text content and its current position in the DOM. Since the\n * browser may natively replace the target node during composition, we can\n * use its position to find its replacement.\n *\n *\n */\n\nvar root = null;\nvar startText = null;\nvar fallbackText = null;\n\nfunction initialize(nativeEventTarget) {\n root = nativeEventTarget;\n startText = getText();\n return true;\n}\n\nfunction reset() {\n root = null;\n startText = null;\n fallbackText = null;\n}\n\nfunction getData() {\n if (fallbackText) {\n return fallbackText;\n }\n\n var start = void 0;\n var startValue = startText;\n var startLength = startValue.length;\n var end = void 0;\n var endValue = getText();\n var endLength = endValue.length;\n\n for (start = 0; start < startLength; start++) {\n if (startValue[start] !== endValue[start]) {\n break;\n }\n }\n\n var minEnd = startLength - start;\n for (end = 1; end <= minEnd; end++) {\n if (startValue[startLength - end] !== endValue[endLength - end]) {\n break;\n }\n }\n\n var sliceTail = end > 1 ? 1 - end : undefined;\n fallbackText = endValue.slice(start, sliceTail);\n return fallbackText;\n}\n\nfunction getText() {\n if ('value' in root) {\n return root.value;\n }\n return root.textContent;\n}\n\n/* eslint valid-typeof: 0 */\n\nvar EVENT_POOL_SIZE = 10;\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar EventInterface = {\n type: null,\n target: null,\n // currentTarget is set when dispatching; no use in copying it here\n currentTarget: function () {\n return null;\n },\n eventPhase: null,\n bubbles: null,\n cancelable: null,\n timeStamp: function (event) {\n return event.timeStamp || Date.now();\n },\n defaultPrevented: null,\n isTrusted: null\n};\n\nfunction functionThatReturnsTrue() {\n return true;\n}\n\nfunction functionThatReturnsFalse() {\n return false;\n}\n\n/**\n * Synthetic events are dispatched by event plugins, typically in response to a\n * top-level event delegation handler.\n *\n * These systems should generally use pooling to reduce the frequency of garbage\n * collection. The system should check `isPersistent` to determine whether the\n * event should be released into the pool after being dispatched. Users that\n * need a persisted event should invoke `persist`.\n *\n * Synthetic events (and subclasses) implement the DOM Level 3 Events API by\n * normalizing browser quirks. Subclasses do not necessarily have to implement a\n * DOM interface; custom application-specific events can also subclass this.\n *\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {*} targetInst Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @param {DOMEventTarget} nativeEventTarget Target node.\n */\nfunction SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {\n {\n // these have a getter/setter for warnings\n delete this.nativeEvent;\n delete this.preventDefault;\n delete this.stopPropagation;\n delete this.isDefaultPrevented;\n delete this.isPropagationStopped;\n }\n\n this.dispatchConfig = dispatchConfig;\n this._targetInst = targetInst;\n this.nativeEvent = nativeEvent;\n\n var Interface = this.constructor.Interface;\n for (var propName in Interface) {\n if (!Interface.hasOwnProperty(propName)) {\n continue;\n }\n {\n delete this[propName]; // this has a getter/setter for warnings\n }\n var normalize = Interface[propName];\n if (normalize) {\n this[propName] = normalize(nativeEvent);\n } else {\n if (propName === 'target') {\n this.target = nativeEventTarget;\n } else {\n this[propName] = nativeEvent[propName];\n }\n }\n }\n\n var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;\n if (defaultPrevented) {\n this.isDefaultPrevented = functionThatReturnsTrue;\n } else {\n this.isDefaultPrevented = functionThatReturnsFalse;\n }\n this.isPropagationStopped = functionThatReturnsFalse;\n return this;\n}\n\n_assign(SyntheticEvent.prototype, {\n preventDefault: function () {\n this.defaultPrevented = true;\n var event = this.nativeEvent;\n if (!event) {\n return;\n }\n\n if (event.preventDefault) {\n event.preventDefault();\n } else if (typeof event.returnValue !== 'unknown') {\n event.returnValue = false;\n }\n this.isDefaultPrevented = functionThatReturnsTrue;\n },\n\n stopPropagation: function () {\n var event = this.nativeEvent;\n if (!event) {\n return;\n }\n\n if (event.stopPropagation) {\n event.stopPropagation();\n } else if (typeof event.cancelBubble !== 'unknown') {\n // The ChangeEventPlugin registers a \"propertychange\" event for\n // IE. This event does not support bubbling or cancelling, and\n // any references to cancelBubble throw \"Member not found\". A\n // typeof check of \"unknown\" circumvents this issue (and is also\n // IE specific).\n event.cancelBubble = true;\n }\n\n this.isPropagationStopped = functionThatReturnsTrue;\n },\n\n /**\n * We release all dispatched `SyntheticEvent`s after each event loop, adding\n * them back into the pool. This allows a way to hold onto a reference that\n * won't be added back into the pool.\n */\n persist: function () {\n this.isPersistent = functionThatReturnsTrue;\n },\n\n /**\n * Checks if this event should be released back into the pool.\n *\n * @return {boolean} True if this should not be released, false otherwise.\n */\n isPersistent: functionThatReturnsFalse,\n\n /**\n * `PooledClass` looks for `destructor` on each instance it releases.\n */\n destructor: function () {\n var Interface = this.constructor.Interface;\n for (var propName in Interface) {\n {\n Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));\n }\n }\n this.dispatchConfig = null;\n this._targetInst = null;\n this.nativeEvent = null;\n this.isDefaultPrevented = functionThatReturnsFalse;\n this.isPropagationStopped = functionThatReturnsFalse;\n this._dispatchListeners = null;\n this._dispatchInstances = null;\n {\n Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));\n Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));\n Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));\n Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));\n Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));\n }\n }\n});\n\nSyntheticEvent.Interface = EventInterface;\n\n/**\n * Helper to reduce boilerplate when creating subclasses.\n */\nSyntheticEvent.extend = function (Interface) {\n var Super = this;\n\n var E = function () {};\n E.prototype = Super.prototype;\n var prototype = new E();\n\n function Class() {\n return Super.apply(this, arguments);\n }\n _assign(prototype, Class.prototype);\n Class.prototype = prototype;\n Class.prototype.constructor = Class;\n\n Class.Interface = _assign({}, Super.Interface, Interface);\n Class.extend = Super.extend;\n addEventPoolingTo(Class);\n\n return Class;\n};\n\naddEventPoolingTo(SyntheticEvent);\n\n/**\n * Helper to nullify syntheticEvent instance properties when destructing\n *\n * @param {String} propName\n * @param {?object} getVal\n * @return {object} defineProperty object\n */\nfunction getPooledWarningPropertyDefinition(propName, getVal) {\n var isFunction = typeof getVal === 'function';\n return {\n configurable: true,\n set: set,\n get: get\n };\n\n function set(val) {\n var action = isFunction ? 'setting the method' : 'setting the property';\n warn(action, 'This is effectively a no-op');\n return val;\n }\n\n function get() {\n var action = isFunction ? 'accessing the method' : 'accessing the property';\n var result = isFunction ? 'This is a no-op function' : 'This is set to null';\n warn(action, result);\n return getVal;\n }\n\n function warn(action, result) {\n var warningCondition = false;\n !warningCondition ? warningWithoutStack$1(false, \"This synthetic event is reused for performance reasons. If you're seeing this, \" + \"you're %s `%s` on a released/nullified synthetic event. %s. \" + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;\n }\n}\n\nfunction getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {\n var EventConstructor = this;\n if (EventConstructor.eventPool.length) {\n var instance = EventConstructor.eventPool.pop();\n EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);\n return instance;\n }\n return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);\n}\n\nfunction releasePooledEvent(event) {\n var EventConstructor = this;\n !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0;\n event.destructor();\n if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {\n EventConstructor.eventPool.push(event);\n }\n}\n\nfunction addEventPoolingTo(EventConstructor) {\n EventConstructor.eventPool = [];\n EventConstructor.getPooled = getPooledEvent;\n EventConstructor.release = releasePooledEvent;\n}\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents\n */\nvar SyntheticCompositionEvent = SyntheticEvent.extend({\n data: null\n});\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105\n * /#events-inputevents\n */\nvar SyntheticInputEvent = SyntheticEvent.extend({\n data: null\n});\n\nvar END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space\nvar START_KEYCODE = 229;\n\nvar canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;\n\nvar documentMode = null;\nif (canUseDOM && 'documentMode' in document) {\n documentMode = document.documentMode;\n}\n\n// Webkit offers a very useful `textInput` event that can be used to\n// directly represent `beforeInput`. The IE `textinput` event is not as\n// useful, so we don't use it.\nvar canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode;\n\n// In IE9+, we have access to composition events, but the data supplied\n// by the native compositionend event may be incorrect. Japanese ideographic\n// spaces, for instance (\\u3000) are not recorded correctly.\nvar useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);\n\nvar SPACEBAR_CODE = 32;\nvar SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);\n\n// Events and their corresponding property names.\nvar eventTypes = {\n beforeInput: {\n phasedRegistrationNames: {\n bubbled: 'onBeforeInput',\n captured: 'onBeforeInputCapture'\n },\n dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]\n },\n compositionEnd: {\n phasedRegistrationNames: {\n bubbled: 'onCompositionEnd',\n captured: 'onCompositionEndCapture'\n },\n dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]\n },\n compositionStart: {\n phasedRegistrationNames: {\n bubbled: 'onCompositionStart',\n captured: 'onCompositionStartCapture'\n },\n dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]\n },\n compositionUpdate: {\n phasedRegistrationNames: {\n bubbled: 'onCompositionUpdate',\n captured: 'onCompositionUpdateCapture'\n },\n dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]\n }\n};\n\n// Track whether we've ever handled a keypress on the space key.\nvar hasSpaceKeypress = false;\n\n/**\n * Return whether a native keypress event is assumed to be a command.\n * This is required because Firefox fires `keypress` events for key commands\n * (cut, copy, select-all, etc.) even though no character is inserted.\n */\nfunction isKeypressCommand(nativeEvent) {\n return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&\n // ctrlKey && altKey is equivalent to AltGr, and is not a command.\n !(nativeEvent.ctrlKey && nativeEvent.altKey);\n}\n\n/**\n * Translate native top level events into event types.\n *\n * @param {string} topLevelType\n * @return {object}\n */\nfunction getCompositionEventType(topLevelType) {\n switch (topLevelType) {\n case TOP_COMPOSITION_START:\n return eventTypes.compositionStart;\n case TOP_COMPOSITION_END:\n return eventTypes.compositionEnd;\n case TOP_COMPOSITION_UPDATE:\n return eventTypes.compositionUpdate;\n }\n}\n\n/**\n * Does our fallback best-guess model think this event signifies that\n * composition has begun?\n *\n * @param {string} topLevelType\n * @param {object} nativeEvent\n * @return {boolean}\n */\nfunction isFallbackCompositionStart(topLevelType, nativeEvent) {\n return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;\n}\n\n/**\n * Does our fallback mode think that this event is the end of composition?\n *\n * @param {string} topLevelType\n * @param {object} nativeEvent\n * @return {boolean}\n */\nfunction isFallbackCompositionEnd(topLevelType, nativeEvent) {\n switch (topLevelType) {\n case TOP_KEY_UP:\n // Command keys insert or clear IME input.\n return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;\n case TOP_KEY_DOWN:\n // Expect IME keyCode on each keydown. If we get any other\n // code we must have exited earlier.\n return nativeEvent.keyCode !== START_KEYCODE;\n case TOP_KEY_PRESS:\n case TOP_MOUSE_DOWN:\n case TOP_BLUR:\n // Events are not possible without cancelling IME.\n return true;\n default:\n return false;\n }\n}\n\n/**\n * Google Input Tools provides composition data via a CustomEvent,\n * with the `data` property populated in the `detail` object. If this\n * is available on the event object, use it. If not, this is a plain\n * composition event and we have nothing special to extract.\n *\n * @param {object} nativeEvent\n * @return {?string}\n */\nfunction getDataFromCustomEvent(nativeEvent) {\n var detail = nativeEvent.detail;\n if (typeof detail === 'object' && 'data' in detail) {\n return detail.data;\n }\n return null;\n}\n\n/**\n * Check if a composition event was triggered by Korean IME.\n * Our fallback mode does not work well with IE's Korean IME,\n * so just use native composition events when Korean IME is used.\n * Although CompositionEvent.locale property is deprecated,\n * it is available in IE, where our fallback mode is enabled.\n *\n * @param {object} nativeEvent\n * @return {boolean}\n */\nfunction isUsingKoreanIME(nativeEvent) {\n return nativeEvent.locale === 'ko';\n}\n\n// Track the current IME composition status, if any.\nvar isComposing = false;\n\n/**\n * @return {?object} A SyntheticCompositionEvent.\n */\nfunction extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var eventType = void 0;\n var fallbackData = void 0;\n\n if (canUseCompositionEvent) {\n eventType = getCompositionEventType(topLevelType);\n } else if (!isComposing) {\n if (isFallbackCompositionStart(topLevelType, nativeEvent)) {\n eventType = eventTypes.compositionStart;\n }\n } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {\n eventType = eventTypes.compositionEnd;\n }\n\n if (!eventType) {\n return null;\n }\n\n if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {\n // The current composition is stored statically and must not be\n // overwritten while composition continues.\n if (!isComposing && eventType === eventTypes.compositionStart) {\n isComposing = initialize(nativeEventTarget);\n } else if (eventType === eventTypes.compositionEnd) {\n if (isComposing) {\n fallbackData = getData();\n }\n }\n }\n\n var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);\n\n if (fallbackData) {\n // Inject data generated from fallback path into the synthetic event.\n // This matches the property of native CompositionEventInterface.\n event.data = fallbackData;\n } else {\n var customData = getDataFromCustomEvent(nativeEvent);\n if (customData !== null) {\n event.data = customData;\n }\n }\n\n accumulateTwoPhaseDispatches(event);\n return event;\n}\n\n/**\n * @param {TopLevelType} topLevelType Number from `TopLevelType`.\n * @param {object} nativeEvent Native browser event.\n * @return {?string} The string corresponding to this `beforeInput` event.\n */\nfunction getNativeBeforeInputChars(topLevelType, nativeEvent) {\n switch (topLevelType) {\n case TOP_COMPOSITION_END:\n return getDataFromCustomEvent(nativeEvent);\n case TOP_KEY_PRESS:\n /**\n * If native `textInput` events are available, our goal is to make\n * use of them. However, there is a special case: the spacebar key.\n * In Webkit, preventing default on a spacebar `textInput` event\n * cancels character insertion, but it *also* causes the browser\n * to fall back to its default spacebar behavior of scrolling the\n * page.\n *\n * Tracking at:\n * https://code.google.com/p/chromium/issues/detail?id=355103\n *\n * To avoid this issue, use the keypress event as if no `textInput`\n * event is available.\n */\n var which = nativeEvent.which;\n if (which !== SPACEBAR_CODE) {\n return null;\n }\n\n hasSpaceKeypress = true;\n return SPACEBAR_CHAR;\n\n case TOP_TEXT_INPUT:\n // Record the characters to be added to the DOM.\n var chars = nativeEvent.data;\n\n // If it's a spacebar character, assume that we have already handled\n // it at the keypress level and bail immediately. Android Chrome\n // doesn't give us keycodes, so we need to ignore it.\n if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {\n return null;\n }\n\n return chars;\n\n default:\n // For other native event types, do nothing.\n return null;\n }\n}\n\n/**\n * For browsers that do not provide the `textInput` event, extract the\n * appropriate string to use for SyntheticInputEvent.\n *\n * @param {number} topLevelType Number from `TopLevelEventTypes`.\n * @param {object} nativeEvent Native browser event.\n * @return {?string} The fallback string for this `beforeInput` event.\n */\nfunction getFallbackBeforeInputChars(topLevelType, nativeEvent) {\n // If we are currently composing (IME) and using a fallback to do so,\n // try to extract the composed characters from the fallback object.\n // If composition event is available, we extract a string only at\n // compositionevent, otherwise extract it at fallback events.\n if (isComposing) {\n if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {\n var chars = getData();\n reset();\n isComposing = false;\n return chars;\n }\n return null;\n }\n\n switch (topLevelType) {\n case TOP_PASTE:\n // If a paste event occurs after a keypress, throw out the input\n // chars. Paste events should not lead to BeforeInput events.\n return null;\n case TOP_KEY_PRESS:\n /**\n * As of v27, Firefox may fire keypress events even when no character\n * will be inserted. A few possibilities:\n *\n * - `which` is `0`. Arrow keys, Esc key, etc.\n *\n * - `which` is the pressed key code, but no char is available.\n * Ex: 'AltGr + d` in Polish. There is no modified character for\n * this key combination and no character is inserted into the\n * document, but FF fires the keypress for char code `100` anyway.\n * No `input` event will occur.\n *\n * - `which` is the pressed key code, but a command combination is\n * being used. Ex: `Cmd+C`. No character is inserted, and no\n * `input` event will occur.\n */\n if (!isKeypressCommand(nativeEvent)) {\n // IE fires the `keypress` event when a user types an emoji via\n // Touch keyboard of Windows. In such a case, the `char` property\n // holds an emoji character like `\\uD83D\\uDE0A`. Because its length\n // is 2, the property `which` does not represent an emoji correctly.\n // In such a case, we directly return the `char` property instead of\n // using `which`.\n if (nativeEvent.char && nativeEvent.char.length > 1) {\n return nativeEvent.char;\n } else if (nativeEvent.which) {\n return String.fromCharCode(nativeEvent.which);\n }\n }\n return null;\n case TOP_COMPOSITION_END:\n return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;\n default:\n return null;\n }\n}\n\n/**\n * Extract a SyntheticInputEvent for `beforeInput`, based on either native\n * `textInput` or fallback behavior.\n *\n * @return {?object} A SyntheticInputEvent.\n */\nfunction extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var chars = void 0;\n\n if (canUseTextInputEvent) {\n chars = getNativeBeforeInputChars(topLevelType, nativeEvent);\n } else {\n chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);\n }\n\n // If no characters are being inserted, no BeforeInput event should\n // be fired.\n if (!chars) {\n return null;\n }\n\n var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);\n\n event.data = chars;\n accumulateTwoPhaseDispatches(event);\n return event;\n}\n\n/**\n * Create an `onBeforeInput` event to match\n * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.\n *\n * This event plugin is based on the native `textInput` event\n * available in Chrome, Safari, Opera, and IE. This event fires after\n * `onKeyPress` and `onCompositionEnd`, but before `onInput`.\n *\n * `beforeInput` is spec'd but not implemented in any browsers, and\n * the `input` event does not provide any useful information about what has\n * actually been added, contrary to the spec. Thus, `textInput` is the best\n * available event to identify the characters that have actually been inserted\n * into the target node.\n *\n * This plugin is also responsible for emitting `composition` events, thus\n * allowing us to share composition fallback code for both `beforeInput` and\n * `composition` event types.\n */\nvar BeforeInputEventPlugin = {\n eventTypes: eventTypes,\n\n extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);\n\n var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);\n\n if (composition === null) {\n return beforeInput;\n }\n\n if (beforeInput === null) {\n return composition;\n }\n\n return [composition, beforeInput];\n }\n};\n\n// Use to restore controlled state after a change event has fired.\n\nvar restoreImpl = null;\nvar restoreTarget = null;\nvar restoreQueue = null;\n\nfunction restoreStateOfTarget(target) {\n // We perform this translation at the end of the event loop so that we\n // always receive the correct fiber here\n var internalInstance = getInstanceFromNode(target);\n if (!internalInstance) {\n // Unmounted\n return;\n }\n !(typeof restoreImpl === 'function') ? invariant(false, 'setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0;\n var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);\n restoreImpl(internalInstance.stateNode, internalInstance.type, props);\n}\n\nfunction setRestoreImplementation(impl) {\n restoreImpl = impl;\n}\n\nfunction enqueueStateRestore(target) {\n if (restoreTarget) {\n if (restoreQueue) {\n restoreQueue.push(target);\n } else {\n restoreQueue = [target];\n }\n } else {\n restoreTarget = target;\n }\n}\n\nfunction needsStateRestore() {\n return restoreTarget !== null || restoreQueue !== null;\n}\n\nfunction restoreStateIfNeeded() {\n if (!restoreTarget) {\n return;\n }\n var target = restoreTarget;\n var queuedTargets = restoreQueue;\n restoreTarget = null;\n restoreQueue = null;\n\n restoreStateOfTarget(target);\n if (queuedTargets) {\n for (var i = 0; i < queuedTargets.length; i++) {\n restoreStateOfTarget(queuedTargets[i]);\n }\n }\n}\n\n// Used as a way to call batchedUpdates when we don't have a reference to\n// the renderer. Such as when we're dispatching events or if third party\n// libraries need to call batchedUpdates. Eventually, this API will go away when\n// everything is batched by default. We'll then have a similar API to opt-out of\n// scheduled work and instead do synchronous work.\n\n// Defaults\nvar _batchedUpdatesImpl = function (fn, bookkeeping) {\n return fn(bookkeeping);\n};\nvar _interactiveUpdatesImpl = function (fn, a, b) {\n return fn(a, b);\n};\nvar _flushInteractiveUpdatesImpl = function () {};\n\nvar isBatching = false;\nfunction batchedUpdates(fn, bookkeeping) {\n if (isBatching) {\n // If we are currently inside another batch, we need to wait until it\n // fully completes before restoring state.\n return fn(bookkeeping);\n }\n isBatching = true;\n try {\n return _batchedUpdatesImpl(fn, bookkeeping);\n } finally {\n // Here we wait until all updates have propagated, which is important\n // when using controlled components within layers:\n // https://github.com/facebook/react/issues/1698\n // Then we restore state of any controlled component.\n isBatching = false;\n var controlledComponentsHavePendingUpdates = needsStateRestore();\n if (controlledComponentsHavePendingUpdates) {\n // If a controlled event was fired, we may need to restore the state of\n // the DOM node back to the controlled value. This is necessary when React\n // bails out of the update without touching the DOM.\n _flushInteractiveUpdatesImpl();\n restoreStateIfNeeded();\n }\n }\n}\n\nfunction interactiveUpdates(fn, a, b) {\n return _interactiveUpdatesImpl(fn, a, b);\n}\n\n\n\nfunction setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) {\n _batchedUpdatesImpl = batchedUpdatesImpl;\n _interactiveUpdatesImpl = interactiveUpdatesImpl;\n _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl;\n}\n\n/**\n * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary\n */\nvar supportedInputTypes = {\n color: true,\n date: true,\n datetime: true,\n 'datetime-local': true,\n email: true,\n month: true,\n number: true,\n password: true,\n range: true,\n search: true,\n tel: true,\n text: true,\n time: true,\n url: true,\n week: true\n};\n\nfunction isTextInputElement(elem) {\n var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n\n if (nodeName === 'input') {\n return !!supportedInputTypes[elem.type];\n }\n\n if (nodeName === 'textarea') {\n return true;\n }\n\n return false;\n}\n\n/**\n * HTML nodeType values that represent the type of the node\n */\n\nvar ELEMENT_NODE = 1;\nvar TEXT_NODE = 3;\nvar COMMENT_NODE = 8;\nvar DOCUMENT_NODE = 9;\nvar DOCUMENT_FRAGMENT_NODE = 11;\n\n/**\n * Gets the target node from a native browser event by accounting for\n * inconsistencies in browser DOM APIs.\n *\n * @param {object} nativeEvent Native browser event.\n * @return {DOMEventTarget} Target node.\n */\nfunction getEventTarget(nativeEvent) {\n // Fallback to nativeEvent.srcElement for IE9\n // https://github.com/facebook/react/issues/12506\n var target = nativeEvent.target || nativeEvent.srcElement || window;\n\n // Normalize SVG element events #4963\n if (target.correspondingUseElement) {\n target = target.correspondingUseElement;\n }\n\n // Safari may fire events on text nodes (Node.TEXT_NODE is 3).\n // @see http://www.quirksmode.org/js/events_properties.html\n return target.nodeType === TEXT_NODE ? target.parentNode : target;\n}\n\n/**\n * Checks if an event is supported in the current execution environment.\n *\n * NOTE: This will not work correctly for non-generic events such as `change`,\n * `reset`, `load`, `error`, and `select`.\n *\n * Borrows from Modernizr.\n *\n * @param {string} eventNameSuffix Event name, e.g. \"click\".\n * @return {boolean} True if the event is supported.\n * @internal\n * @license Modernizr 3.0.0pre (Custom Build) | MIT\n */\nfunction isEventSupported(eventNameSuffix) {\n if (!canUseDOM) {\n return false;\n }\n\n var eventName = 'on' + eventNameSuffix;\n var isSupported = eventName in document;\n\n if (!isSupported) {\n var element = document.createElement('div');\n element.setAttribute(eventName, 'return;');\n isSupported = typeof element[eventName] === 'function';\n }\n\n return isSupported;\n}\n\nfunction isCheckable(elem) {\n var type = elem.type;\n var nodeName = elem.nodeName;\n return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');\n}\n\nfunction getTracker(node) {\n return node._valueTracker;\n}\n\nfunction detachTracker(node) {\n node._valueTracker = null;\n}\n\nfunction getValueFromNode(node) {\n var value = '';\n if (!node) {\n return value;\n }\n\n if (isCheckable(node)) {\n value = node.checked ? 'true' : 'false';\n } else {\n value = node.value;\n }\n\n return value;\n}\n\nfunction trackValueOnNode(node) {\n var valueField = isCheckable(node) ? 'checked' : 'value';\n var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);\n\n var currentValue = '' + node[valueField];\n\n // if someone has already defined a value or Safari, then bail\n // and don't track value will cause over reporting of changes,\n // but it's better then a hard failure\n // (needed for certain tests that spyOn input values and Safari)\n if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {\n return;\n }\n var get = descriptor.get,\n set = descriptor.set;\n\n Object.defineProperty(node, valueField, {\n configurable: true,\n get: function () {\n return get.call(this);\n },\n set: function (value) {\n currentValue = '' + value;\n set.call(this, value);\n }\n });\n // We could've passed this the first time\n // but it triggers a bug in IE11 and Edge 14/15.\n // Calling defineProperty() again should be equivalent.\n // https://github.com/facebook/react/issues/11768\n Object.defineProperty(node, valueField, {\n enumerable: descriptor.enumerable\n });\n\n var tracker = {\n getValue: function () {\n return currentValue;\n },\n setValue: function (value) {\n currentValue = '' + value;\n },\n stopTracking: function () {\n detachTracker(node);\n delete node[valueField];\n }\n };\n return tracker;\n}\n\nfunction track(node) {\n if (getTracker(node)) {\n return;\n }\n\n // TODO: Once it's just Fiber we can move this to node._wrapperState\n node._valueTracker = trackValueOnNode(node);\n}\n\nfunction updateValueIfChanged(node) {\n if (!node) {\n return false;\n }\n\n var tracker = getTracker(node);\n // if there is no tracker at this point it's unlikely\n // that trying again will succeed\n if (!tracker) {\n return true;\n }\n\n var lastValue = tracker.getValue();\n var nextValue = getValueFromNode(node);\n if (nextValue !== lastValue) {\n tracker.setValue(nextValue);\n return true;\n }\n return false;\n}\n\nvar ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n\n// Prevent newer renderers from RTE when used with older react package versions.\n// Current owner and dispatcher used to share the same ref,\n// but PR #14548 split them out to better support the react-debug-tools package.\nif (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {\n ReactSharedInternals.ReactCurrentDispatcher = {\n current: null\n };\n}\n\nvar BEFORE_SLASH_RE = /^(.*)[\\\\\\/]/;\n\nvar describeComponentFrame = function (name, source, ownerName) {\n var sourceInfo = '';\n if (source) {\n var path = source.fileName;\n var fileName = path.replace(BEFORE_SLASH_RE, '');\n {\n // In DEV, include code for a common special case:\n // prefer \"folder/index.js\" instead of just \"index.js\".\n if (/^index\\./.test(fileName)) {\n var match = path.match(BEFORE_SLASH_RE);\n if (match) {\n var pathBeforeSlash = match[1];\n if (pathBeforeSlash) {\n var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');\n fileName = folderName + '/' + fileName;\n }\n }\n }\n }\n sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';\n } else if (ownerName) {\n sourceInfo = ' (created by ' + ownerName + ')';\n }\n return '\\n in ' + (name || 'Unknown') + sourceInfo;\n};\n\n// The Symbol used to tag the ReactElement-like types. If there is no native Symbol\n// nor polyfill, then a plain number is used for performance.\nvar hasSymbol = typeof Symbol === 'function' && Symbol.for;\n\nvar REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;\nvar REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;\nvar REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;\nvar REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;\nvar REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;\nvar REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;\nvar REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;\n\nvar REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;\nvar REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;\nvar REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;\nvar REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;\nvar REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;\n\nvar MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;\nvar FAUX_ITERATOR_SYMBOL = '@@iterator';\n\nfunction getIteratorFn(maybeIterable) {\n if (maybeIterable === null || typeof maybeIterable !== 'object') {\n return null;\n }\n var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];\n if (typeof maybeIterator === 'function') {\n return maybeIterator;\n }\n return null;\n}\n\nvar Pending = 0;\nvar Resolved = 1;\nvar Rejected = 2;\n\nfunction refineResolvedLazyComponent(lazyComponent) {\n return lazyComponent._status === Resolved ? lazyComponent._result : null;\n}\n\nfunction getWrappedName(outerType, innerType, wrapperName) {\n var functionName = innerType.displayName || innerType.name || '';\n return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);\n}\n\nfunction getComponentName(type) {\n if (type == null) {\n // Host root, text node or just invalid type.\n return null;\n }\n {\n if (typeof type.tag === 'number') {\n warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');\n }\n }\n if (typeof type === 'function') {\n return type.displayName || type.name || null;\n }\n if (typeof type === 'string') {\n return type;\n }\n switch (type) {\n case REACT_CONCURRENT_MODE_TYPE:\n return 'ConcurrentMode';\n case REACT_FRAGMENT_TYPE:\n return 'Fragment';\n case REACT_PORTAL_TYPE:\n return 'Portal';\n case REACT_PROFILER_TYPE:\n return 'Profiler';\n case REACT_STRICT_MODE_TYPE:\n return 'StrictMode';\n case REACT_SUSPENSE_TYPE:\n return 'Suspense';\n }\n if (typeof type === 'object') {\n switch (type.$$typeof) {\n case REACT_CONTEXT_TYPE:\n return 'Context.Consumer';\n case REACT_PROVIDER_TYPE:\n return 'Context.Provider';\n case REACT_FORWARD_REF_TYPE:\n return getWrappedName(type, type.render, 'ForwardRef');\n case REACT_MEMO_TYPE:\n return getComponentName(type.type);\n case REACT_LAZY_TYPE:\n {\n var thenable = type;\n var resolvedThenable = refineResolvedLazyComponent(thenable);\n if (resolvedThenable) {\n return getComponentName(resolvedThenable);\n }\n }\n }\n }\n return null;\n}\n\nvar ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;\n\nfunction describeFiber(fiber) {\n switch (fiber.tag) {\n case HostRoot:\n case HostPortal:\n case HostText:\n case Fragment:\n case ContextProvider:\n case ContextConsumer:\n return '';\n default:\n var owner = fiber._debugOwner;\n var source = fiber._debugSource;\n var name = getComponentName(fiber.type);\n var ownerName = null;\n if (owner) {\n ownerName = getComponentName(owner.type);\n }\n return describeComponentFrame(name, source, ownerName);\n }\n}\n\nfunction getStackByFiberInDevAndProd(workInProgress) {\n var info = '';\n var node = workInProgress;\n do {\n info += describeFiber(node);\n node = node.return;\n } while (node);\n return info;\n}\n\nvar current = null;\nvar phase = null;\n\nfunction getCurrentFiberOwnerNameInDevOrNull() {\n {\n if (current === null) {\n return null;\n }\n var owner = current._debugOwner;\n if (owner !== null && typeof owner !== 'undefined') {\n return getComponentName(owner.type);\n }\n }\n return null;\n}\n\nfunction getCurrentFiberStackInDev() {\n {\n if (current === null) {\n return '';\n }\n // Safe because if current fiber exists, we are reconciling,\n // and it is guaranteed to be the work-in-progress version.\n return getStackByFiberInDevAndProd(current);\n }\n return '';\n}\n\nfunction resetCurrentFiber() {\n {\n ReactDebugCurrentFrame.getCurrentStack = null;\n current = null;\n phase = null;\n }\n}\n\nfunction setCurrentFiber(fiber) {\n {\n ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;\n current = fiber;\n phase = null;\n }\n}\n\nfunction setCurrentPhase(lifeCyclePhase) {\n {\n phase = lifeCyclePhase;\n }\n}\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar warning = warningWithoutStack$1;\n\n{\n warning = function (condition, format) {\n if (condition) {\n return;\n }\n var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;\n var stack = ReactDebugCurrentFrame.getStackAddendum();\n // eslint-disable-next-line react-internal/warning-and-invariant-args\n\n for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n args[_key - 2] = arguments[_key];\n }\n\n warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));\n };\n}\n\nvar warning$1 = warning;\n\n// A reserved attribute.\n// It is handled by React separately and shouldn't be written to the DOM.\nvar RESERVED = 0;\n\n// A simple string attribute.\n// Attributes that aren't in the whitelist are presumed to have this type.\nvar STRING = 1;\n\n// A string attribute that accepts booleans in React. In HTML, these are called\n// \"enumerated\" attributes with \"true\" and \"false\" as possible values.\n// When true, it should be set to a \"true\" string.\n// When false, it should be set to a \"false\" string.\nvar BOOLEANISH_STRING = 2;\n\n// A real boolean attribute.\n// When true, it should be present (set either to an empty string or its name).\n// When false, it should be omitted.\nvar BOOLEAN = 3;\n\n// An attribute that can be used as a flag as well as with a value.\n// When true, it should be present (set either to an empty string or its name).\n// When false, it should be omitted.\n// For any other value, should be present with that value.\nvar OVERLOADED_BOOLEAN = 4;\n\n// An attribute that must be numeric or parse as a numeric.\n// When falsy, it should be removed.\nvar NUMERIC = 5;\n\n// An attribute that must be positive numeric or parse as a positive numeric.\n// When falsy, it should be removed.\nvar POSITIVE_NUMERIC = 6;\n\n/* eslint-disable max-len */\nvar ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\n/* eslint-enable max-len */\nvar ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\\\-.0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\n\n\nvar ROOT_ATTRIBUTE_NAME = 'data-reactroot';\nvar VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar illegalAttributeNameCache = {};\nvar validatedAttributeNameCache = {};\n\nfunction isAttributeNameSafe(attributeName) {\n if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {\n return true;\n }\n if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {\n return false;\n }\n if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {\n validatedAttributeNameCache[attributeName] = true;\n return true;\n }\n illegalAttributeNameCache[attributeName] = true;\n {\n warning$1(false, 'Invalid attribute name: `%s`', attributeName);\n }\n return false;\n}\n\nfunction shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {\n if (propertyInfo !== null) {\n return propertyInfo.type === RESERVED;\n }\n if (isCustomComponentTag) {\n return false;\n }\n if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {\n return true;\n }\n return false;\n}\n\nfunction shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {\n if (propertyInfo !== null && propertyInfo.type === RESERVED) {\n return false;\n }\n switch (typeof value) {\n case 'function':\n // $FlowIssue symbol is perfectly valid here\n case 'symbol':\n // eslint-disable-line\n return true;\n case 'boolean':\n {\n if (isCustomComponentTag) {\n return false;\n }\n if (propertyInfo !== null) {\n return !propertyInfo.acceptsBooleans;\n } else {\n var prefix = name.toLowerCase().slice(0, 5);\n return prefix !== 'data-' && prefix !== 'aria-';\n }\n }\n default:\n return false;\n }\n}\n\nfunction shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {\n if (value === null || typeof value === 'undefined') {\n return true;\n }\n if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {\n return true;\n }\n if (isCustomComponentTag) {\n return false;\n }\n if (propertyInfo !== null) {\n switch (propertyInfo.type) {\n case BOOLEAN:\n return !value;\n case OVERLOADED_BOOLEAN:\n return value === false;\n case NUMERIC:\n return isNaN(value);\n case POSITIVE_NUMERIC:\n return isNaN(value) || value < 1;\n }\n }\n return false;\n}\n\nfunction getPropertyInfo(name) {\n return properties.hasOwnProperty(name) ? properties[name] : null;\n}\n\nfunction PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {\n this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;\n this.attributeName = attributeName;\n this.attributeNamespace = attributeNamespace;\n this.mustUseProperty = mustUseProperty;\n this.propertyName = name;\n this.type = type;\n}\n\n// When adding attributes to this list, be sure to also add them to\n// the `possibleStandardNames` module to ensure casing and incorrect\n// name warnings.\nvar properties = {};\n\n// These props are reserved by React. They shouldn't be written to the DOM.\n['children', 'dangerouslySetInnerHTML',\n// TODO: This prevents the assignment of defaultValue to regular\n// elements (not just inputs). Now that ReactDOMInput assigns to the\n// defaultValue property -- do we need this?\n'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {\n properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty\n name, // attributeName\n null);\n} // attributeNamespace\n);\n\n// A few React string attributes have a different name.\n// This is a mapping from React prop names to the attribute names.\n[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {\n var name = _ref[0],\n attributeName = _ref[1];\n\n properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty\n attributeName, // attributeName\n null);\n} // attributeNamespace\n);\n\n// These are \"enumerated\" HTML attributes that accept \"true\" and \"false\".\n// In React, we let users pass `true` and `false` even though technically\n// these aren't boolean attributes (they are coerced to strings).\n['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {\n properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty\n name.toLowerCase(), // attributeName\n null);\n} // attributeNamespace\n);\n\n// These are \"enumerated\" SVG attributes that accept \"true\" and \"false\".\n// In React, we let users pass `true` and `false` even though technically\n// these aren't boolean attributes (they are coerced to strings).\n// Since these are SVG attributes, their attribute names are case-sensitive.\n['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {\n properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty\n name, // attributeName\n null);\n} // attributeNamespace\n);\n\n// These are HTML boolean attributes.\n['allowFullScreen', 'async',\n// Note: there is a special case that prevents it from being written to the DOM\n// on the client side because the browsers are inconsistent. Instead we call focus().\n'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',\n// Microdata\n'itemScope'].forEach(function (name) {\n properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty\n name.toLowerCase(), // attributeName\n null);\n} // attributeNamespace\n);\n\n// These are the few React props that we set as DOM properties\n// rather than attributes. These are all booleans.\n['checked',\n// Note: `option.selected` is not updated if `select.multiple` is\n// disabled with `removeAttribute`. We have special logic for handling this.\n'multiple', 'muted', 'selected'].forEach(function (name) {\n properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty\n name, // attributeName\n null);\n} // attributeNamespace\n);\n\n// These are HTML attributes that are \"overloaded booleans\": they behave like\n// booleans, but can also accept a string value.\n['capture', 'download'].forEach(function (name) {\n properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty\n name, // attributeName\n null);\n} // attributeNamespace\n);\n\n// These are HTML attributes that must be positive numbers.\n['cols', 'rows', 'size', 'span'].forEach(function (name) {\n properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty\n name, // attributeName\n null);\n} // attributeNamespace\n);\n\n// These are HTML attributes that must be numbers.\n['rowSpan', 'start'].forEach(function (name) {\n properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty\n name.toLowerCase(), // attributeName\n null);\n} // attributeNamespace\n);\n\nvar CAMELIZE = /[\\-\\:]([a-z])/g;\nvar capitalize = function (token) {\n return token[1].toUpperCase();\n};\n\n// This is a list of all SVG attributes that need special casing, namespacing,\n// or boolean value assignment. Regular attributes that just accept strings\n// and have the same names are omitted, just like in the HTML whitelist.\n// Some of these attributes can be hard to find. This list was created by\n// scrapping the MDN documentation.\n['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) {\n var name = attributeName.replace(CAMELIZE, capitalize);\n properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty\n attributeName, null);\n} // attributeNamespace\n);\n\n// String SVG attributes with the xlink namespace.\n['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {\n var name = attributeName.replace(CAMELIZE, capitalize);\n properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty\n attributeName, 'http://www.w3.org/1999/xlink');\n});\n\n// String SVG attributes with the xml namespace.\n['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {\n var name = attributeName.replace(CAMELIZE, capitalize);\n properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty\n attributeName, 'http://www.w3.org/XML/1998/namespace');\n});\n\n// These attribute exists both in HTML and SVG.\n// The attribute name is case-sensitive in SVG so we can't just use\n// the React name like we do for attributes that exist only in HTML.\n['tabIndex', 'crossOrigin'].forEach(function (attributeName) {\n properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty\n attributeName.toLowerCase(), // attributeName\n null);\n} // attributeNamespace\n);\n\n/**\n * Get the value for a property on a node. Only used in DEV for SSR validation.\n * The \"expected\" argument is used as a hint of what the expected value is.\n * Some properties have multiple equivalent values.\n */\nfunction getValueForProperty(node, name, expected, propertyInfo) {\n {\n if (propertyInfo.mustUseProperty) {\n var propertyName = propertyInfo.propertyName;\n\n return node[propertyName];\n } else {\n var attributeName = propertyInfo.attributeName;\n\n var stringValue = null;\n\n if (propertyInfo.type === OVERLOADED_BOOLEAN) {\n if (node.hasAttribute(attributeName)) {\n var value = node.getAttribute(attributeName);\n if (value === '') {\n return true;\n }\n if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {\n return value;\n }\n if (value === '' + expected) {\n return expected;\n }\n return value;\n }\n } else if (node.hasAttribute(attributeName)) {\n if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {\n // We had an attribute but shouldn't have had one, so read it\n // for the error message.\n return node.getAttribute(attributeName);\n }\n if (propertyInfo.type === BOOLEAN) {\n // If this was a boolean, it doesn't matter what the value is\n // the fact that we have it is the same as the expected.\n return expected;\n }\n // Even if this property uses a namespace we use getAttribute\n // because we assume its namespaced name is the same as our config.\n // To use getAttributeNS we need the local name which we don't have\n // in our config atm.\n stringValue = node.getAttribute(attributeName);\n }\n\n if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {\n return stringValue === null ? expected : stringValue;\n } else if (stringValue === '' + expected) {\n return expected;\n } else {\n return stringValue;\n }\n }\n }\n}\n\n/**\n * Get the value for a attribute on a node. Only used in DEV for SSR validation.\n * The third argument is used as a hint of what the expected value is. Some\n * attributes have multiple equivalent values.\n */\nfunction getValueForAttribute(node, name, expected) {\n {\n if (!isAttributeNameSafe(name)) {\n return;\n }\n if (!node.hasAttribute(name)) {\n return expected === undefined ? undefined : null;\n }\n var value = node.getAttribute(name);\n if (value === '' + expected) {\n return expected;\n }\n return value;\n }\n}\n\n/**\n * Sets the value for a property on a node.\n *\n * @param {DOMElement} node\n * @param {string} name\n * @param {*} value\n */\nfunction setValueForProperty(node, name, value, isCustomComponentTag) {\n var propertyInfo = getPropertyInfo(name);\n if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {\n return;\n }\n if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {\n value = null;\n }\n // If the prop isn't in the special list, treat it as a simple attribute.\n if (isCustomComponentTag || propertyInfo === null) {\n if (isAttributeNameSafe(name)) {\n var _attributeName = name;\n if (value === null) {\n node.removeAttribute(_attributeName);\n } else {\n node.setAttribute(_attributeName, '' + value);\n }\n }\n return;\n }\n var mustUseProperty = propertyInfo.mustUseProperty;\n\n if (mustUseProperty) {\n var propertyName = propertyInfo.propertyName;\n\n if (value === null) {\n var type = propertyInfo.type;\n\n node[propertyName] = type === BOOLEAN ? false : '';\n } else {\n // Contrary to `setAttribute`, object properties are properly\n // `toString`ed by IE8/9.\n node[propertyName] = value;\n }\n return;\n }\n // The rest are treated as attributes with special cases.\n var attributeName = propertyInfo.attributeName,\n attributeNamespace = propertyInfo.attributeNamespace;\n\n if (value === null) {\n node.removeAttribute(attributeName);\n } else {\n var _type = propertyInfo.type;\n\n var attributeValue = void 0;\n if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {\n attributeValue = '';\n } else {\n // `setAttribute` with objects becomes only `[object]` in IE8/9,\n // ('' + value) makes it output the correct toString()-value.\n attributeValue = '' + value;\n }\n if (attributeNamespace) {\n node.setAttributeNS(attributeNamespace, attributeName, attributeValue);\n } else {\n node.setAttribute(attributeName, attributeValue);\n }\n }\n}\n\n// Flow does not allow string concatenation of most non-string types. To work\n// around this limitation, we use an opaque type that can only be obtained by\n// passing the value through getToStringValue first.\nfunction toString(value) {\n return '' + value;\n}\n\nfunction getToStringValue(value) {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'object':\n case 'string':\n case 'undefined':\n return value;\n default:\n // function, symbol are assigned as empty strings\n return '';\n }\n}\n\nvar ReactDebugCurrentFrame$1 = null;\n\nvar ReactControlledValuePropTypes = {\n checkPropTypes: null\n};\n\n{\n ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;\n\n var hasReadOnlyValue = {\n button: true,\n checkbox: true,\n image: true,\n hidden: true,\n radio: true,\n reset: true,\n submit: true\n };\n\n var propTypes = {\n value: function (props, propName, componentName) {\n if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) {\n return null;\n }\n return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');\n },\n checked: function (props, propName, componentName) {\n if (props.onChange || props.readOnly || props.disabled || props[propName] == null) {\n return null;\n }\n return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');\n }\n };\n\n /**\n * Provide a linked `value` attribute for controlled forms. You should not use\n * this outside of the ReactDOM controlled form components.\n */\n ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {\n checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum);\n };\n}\n\nvar enableUserTimingAPI = true;\n\n// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:\nvar debugRenderPhaseSideEffects = false;\n\n// In some cases, StrictMode should also double-render lifecycles.\n// This can be confusing for tests though,\n// And it can be bad for performance in production.\n// This feature flag can be used to control the behavior:\nvar debugRenderPhaseSideEffectsForStrictMode = true;\n\n// To preserve the \"Pause on caught exceptions\" behavior of the debugger, we\n// replay the begin phase of a failed component inside invokeGuardedCallback.\nvar replayFailedUnitOfWorkWithInvokeGuardedCallback = true;\n\n// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:\nvar warnAboutDeprecatedLifecycles = false;\n\n// Gather advanced timing metrics for Profiler subtrees.\nvar enableProfilerTimer = true;\n\n// Trace which interactions trigger each commit.\nvar enableSchedulerTracing = true;\n\n// Only used in www builds.\nvar enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.\n\n// Only used in www builds.\n\n\n// Only used in www builds.\n\n\n// React Fire: prevent the value and checked attributes from syncing\n// with their related DOM properties\nvar disableInputAttributeSyncing = false;\n\n// These APIs will no longer be \"unstable\" in the upcoming 16.7 release,\n// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.\nvar enableStableConcurrentModeAPIs = false;\n\nvar warnAboutShorthandPropertyCollision = false;\n\n// TODO: direct imports like some-package/src/* are bad. Fix me.\nvar didWarnValueDefaultValue = false;\nvar didWarnCheckedDefaultChecked = false;\nvar didWarnControlledToUncontrolled = false;\nvar didWarnUncontrolledToControlled = false;\n\nfunction isControlled(props) {\n var usesChecked = props.type === 'checkbox' || props.type === 'radio';\n return usesChecked ? props.checked != null : props.value != null;\n}\n\n/**\n * Implements an host component that allows setting these optional\n * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.\n *\n * If `checked` or `value` are not supplied (or null/undefined), user actions\n * that affect the checked state or value will trigger updates to the element.\n *\n * If they are supplied (and not null/undefined), the rendered element will not\n * trigger updates to the element. Instead, the props must change in order for\n * the rendered element to be updated.\n *\n * The rendered element will be initialized as unchecked (or `defaultChecked`)\n * with an empty value (or `defaultValue`).\n *\n * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html\n */\n\nfunction getHostProps(element, props) {\n var node = element;\n var checked = props.checked;\n\n var hostProps = _assign({}, props, {\n defaultChecked: undefined,\n defaultValue: undefined,\n value: undefined,\n checked: checked != null ? checked : node._wrapperState.initialChecked\n });\n\n return hostProps;\n}\n\nfunction initWrapperState(element, props) {\n {\n ReactControlledValuePropTypes.checkPropTypes('input', props);\n\n if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {\n warning$1(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);\n didWarnCheckedDefaultChecked = true;\n }\n if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {\n warning$1(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);\n didWarnValueDefaultValue = true;\n }\n }\n\n var node = element;\n var defaultValue = props.defaultValue == null ? '' : props.defaultValue;\n\n node._wrapperState = {\n initialChecked: props.checked != null ? props.checked : props.defaultChecked,\n initialValue: getToStringValue(props.value != null ? props.value : defaultValue),\n controlled: isControlled(props)\n };\n}\n\nfunction updateChecked(element, props) {\n var node = element;\n var checked = props.checked;\n if (checked != null) {\n setValueForProperty(node, 'checked', checked, false);\n }\n}\n\nfunction updateWrapper(element, props) {\n var node = element;\n {\n var _controlled = isControlled(props);\n\n if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {\n warning$1(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);\n didWarnUncontrolledToControlled = true;\n }\n if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {\n warning$1(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);\n didWarnControlledToUncontrolled = true;\n }\n }\n\n updateChecked(element, props);\n\n var value = getToStringValue(props.value);\n var type = props.type;\n\n if (value != null) {\n if (type === 'number') {\n if (value === 0 && node.value === '' ||\n // We explicitly want to coerce to number here if possible.\n // eslint-disable-next-line\n node.value != value) {\n node.value = toString(value);\n }\n } else if (node.value !== toString(value)) {\n node.value = toString(value);\n }\n } else if (type === 'submit' || type === 'reset') {\n // Submit/reset inputs need the attribute removed completely to avoid\n // blank-text buttons.\n node.removeAttribute('value');\n return;\n }\n\n if (disableInputAttributeSyncing) {\n // When not syncing the value attribute, React only assigns a new value\n // whenever the defaultValue React prop has changed. When not present,\n // React does nothing\n if (props.hasOwnProperty('defaultValue')) {\n setDefaultValue(node, props.type, getToStringValue(props.defaultValue));\n }\n } else {\n // When syncing the value attribute, the value comes from a cascade of\n // properties:\n // 1. The value React property\n // 2. The defaultValue React property\n // 3. Otherwise there should be no change\n if (props.hasOwnProperty('value')) {\n setDefaultValue(node, props.type, value);\n } else if (props.hasOwnProperty('defaultValue')) {\n setDefaultValue(node, props.type, getToStringValue(props.defaultValue));\n }\n }\n\n if (disableInputAttributeSyncing) {\n // When not syncing the checked attribute, the attribute is directly\n // controllable from the defaultValue React property. It needs to be\n // updated as new props come in.\n if (props.defaultChecked == null) {\n node.removeAttribute('checked');\n } else {\n node.defaultChecked = !!props.defaultChecked;\n }\n } else {\n // When syncing the checked attribute, it only changes when it needs\n // to be removed, such as transitioning from a checkbox into a text input\n if (props.checked == null && props.defaultChecked != null) {\n node.defaultChecked = !!props.defaultChecked;\n }\n }\n}\n\nfunction postMountWrapper(element, props, isHydrating) {\n var node = element;\n\n // Do not assign value if it is already set. This prevents user text input\n // from being lost during SSR hydration.\n if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {\n var type = props.type;\n var isButton = type === 'submit' || type === 'reset';\n\n // Avoid setting value attribute on submit/reset inputs as it overrides the\n // default value provided by the browser. See: #12872\n if (isButton && (props.value === undefined || props.value === null)) {\n return;\n }\n\n var _initialValue = toString(node._wrapperState.initialValue);\n\n // Do not assign value if it is already set. This prevents user text input\n // from being lost during SSR hydration.\n if (!isHydrating) {\n if (disableInputAttributeSyncing) {\n var value = getToStringValue(props.value);\n\n // When not syncing the value attribute, the value property points\n // directly to the React prop. Only assign it if it exists.\n if (value != null) {\n // Always assign on buttons so that it is possible to assign an\n // empty string to clear button text.\n //\n // Otherwise, do not re-assign the value property if is empty. This\n // potentially avoids a DOM write and prevents Firefox (~60.0.1) from\n // prematurely marking required inputs as invalid. Equality is compared\n // to the current value in case the browser provided value is not an\n // empty string.\n if (isButton || value !== node.value) {\n node.value = toString(value);\n }\n }\n } else {\n // When syncing the value attribute, the value property should use\n // the wrapperState._initialValue property. This uses:\n //\n // 1. The value React property when present\n // 2. The defaultValue React property when present\n // 3. An empty string\n if (_initialValue !== node.value) {\n node.value = _initialValue;\n }\n }\n }\n\n if (disableInputAttributeSyncing) {\n // When not syncing the value attribute, assign the value attribute\n // directly from the defaultValue React property (when present)\n var defaultValue = getToStringValue(props.defaultValue);\n if (defaultValue != null) {\n node.defaultValue = toString(defaultValue);\n }\n } else {\n // Otherwise, the value attribute is synchronized to the property,\n // so we assign defaultValue to the same thing as the value property\n // assignment step above.\n node.defaultValue = _initialValue;\n }\n }\n\n // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug\n // this is needed to work around a chrome bug where setting defaultChecked\n // will sometimes influence the value of checked (even after detachment).\n // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416\n // We need to temporarily unset name to avoid disrupting radio button groups.\n var name = node.name;\n if (name !== '') {\n node.name = '';\n }\n\n if (disableInputAttributeSyncing) {\n // When not syncing the checked attribute, the checked property\n // never gets assigned. It must be manually set. We don't want\n // to do this when hydrating so that existing user input isn't\n // modified\n if (!isHydrating) {\n updateChecked(element, props);\n }\n\n // Only assign the checked attribute if it is defined. This saves\n // a DOM write when controlling the checked attribute isn't needed\n // (text inputs, submit/reset)\n if (props.hasOwnProperty('defaultChecked')) {\n node.defaultChecked = !node.defaultChecked;\n node.defaultChecked = !!props.defaultChecked;\n }\n } else {\n // When syncing the checked attribute, both the checked property and\n // attribute are assigned at the same time using defaultChecked. This uses:\n //\n // 1. The checked React property when present\n // 2. The defaultChecked React property when present\n // 3. Otherwise, false\n node.defaultChecked = !node.defaultChecked;\n node.defaultChecked = !!node._wrapperState.initialChecked;\n }\n\n if (name !== '') {\n node.name = name;\n }\n}\n\nfunction restoreControlledState(element, props) {\n var node = element;\n updateWrapper(node, props);\n updateNamedCousins(node, props);\n}\n\nfunction updateNamedCousins(rootNode, props) {\n var name = props.name;\n if (props.type === 'radio' && name != null) {\n var queryRoot = rootNode;\n\n while (queryRoot.parentNode) {\n queryRoot = queryRoot.parentNode;\n }\n\n // If `rootNode.form` was non-null, then we could try `form.elements`,\n // but that sometimes behaves strangely in IE8. We could also try using\n // `form.getElementsByName`, but that will only return direct children\n // and won't include inputs that use the HTML5 `form=` attribute. Since\n // the input might not even be in a form. It might not even be in the\n // document. Let's just use the local `querySelectorAll` to ensure we don't\n // miss anything.\n var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type=\"radio\"]');\n\n for (var i = 0; i < group.length; i++) {\n var otherNode = group[i];\n if (otherNode === rootNode || otherNode.form !== rootNode.form) {\n continue;\n }\n // This will throw if radio buttons rendered by different copies of React\n // and the same name are rendered into the same form (same as #1939).\n // That's probably okay; we don't support it just as we don't support\n // mixing React radio buttons with non-React ones.\n var otherProps = getFiberCurrentPropsFromNode$1(otherNode);\n !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;\n\n // We need update the tracked value on the named cousin since the value\n // was changed but the input saw no event or value set\n updateValueIfChanged(otherNode);\n\n // If this is a controlled radio button group, forcing the input that\n // was previously checked to update will cause it to be come re-checked\n // as appropriate.\n updateWrapper(otherNode, otherProps);\n }\n }\n}\n\n// In Chrome, assigning defaultValue to certain input types triggers input validation.\n// For number inputs, the display value loses trailing decimal points. For email inputs,\n// Chrome raises \"The specified value is not a valid email address\".\n//\n// Here we check to see if the defaultValue has actually changed, avoiding these problems\n// when the user is inputting text\n//\n// https://github.com/facebook/react/issues/7253\nfunction setDefaultValue(node, type, value) {\n if (\n // Focused number inputs synchronize on blur. See ChangeEventPlugin.js\n type !== 'number' || node.ownerDocument.activeElement !== node) {\n if (value == null) {\n node.defaultValue = toString(node._wrapperState.initialValue);\n } else if (node.defaultValue !== toString(value)) {\n node.defaultValue = toString(value);\n }\n }\n}\n\nvar eventTypes$1 = {\n change: {\n phasedRegistrationNames: {\n bubbled: 'onChange',\n captured: 'onChangeCapture'\n },\n dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]\n }\n};\n\nfunction createAndAccumulateChangeEvent(inst, nativeEvent, target) {\n var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);\n event.type = 'change';\n // Flag this event loop as needing state restore.\n enqueueStateRestore(target);\n accumulateTwoPhaseDispatches(event);\n return event;\n}\n/**\n * For IE shims\n */\nvar activeElement = null;\nvar activeElementInst = null;\n\n/**\n * SECTION: handle `change` event\n */\nfunction shouldUseChangeEvent(elem) {\n var nodeName = elem.nodeName && elem.nodeName.toLowerCase();\n return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';\n}\n\nfunction manualDispatchChangeEvent(nativeEvent) {\n var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));\n\n // If change and propertychange bubbled, we'd just bind to it like all the\n // other events and have it go through ReactBrowserEventEmitter. Since it\n // doesn't, we manually listen for the events and so we have to enqueue and\n // process the abstract event manually.\n //\n // Batching is necessary here in order to ensure that all event handlers run\n // before the next rerender (including event handlers attached to ancestor\n // elements instead of directly on the input). Without this, controlled\n // components don't work properly in conjunction with event bubbling because\n // the component is rerendered and the value reverted before all the event\n // handlers can run. See https://github.com/facebook/react/issues/708.\n batchedUpdates(runEventInBatch, event);\n}\n\nfunction runEventInBatch(event) {\n runEventsInBatch(event);\n}\n\nfunction getInstIfValueChanged(targetInst) {\n var targetNode = getNodeFromInstance$1(targetInst);\n if (updateValueIfChanged(targetNode)) {\n return targetInst;\n }\n}\n\nfunction getTargetInstForChangeEvent(topLevelType, targetInst) {\n if (topLevelType === TOP_CHANGE) {\n return targetInst;\n }\n}\n\n/**\n * SECTION: handle `input` event\n */\nvar isInputEventSupported = false;\nif (canUseDOM) {\n // IE9 claims to support the input event but fails to trigger it when\n // deleting text, so we ignore its input events.\n isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);\n}\n\n/**\n * (For IE <=9) Starts tracking propertychange events on the passed-in element\n * and override the value property so that we can distinguish user events from\n * value changes in JS.\n */\nfunction startWatchingForValueChange(target, targetInst) {\n activeElement = target;\n activeElementInst = targetInst;\n activeElement.attachEvent('onpropertychange', handlePropertyChange);\n}\n\n/**\n * (For IE <=9) Removes the event listeners from the currently-tracked element,\n * if any exists.\n */\nfunction stopWatchingForValueChange() {\n if (!activeElement) {\n return;\n }\n activeElement.detachEvent('onpropertychange', handlePropertyChange);\n activeElement = null;\n activeElementInst = null;\n}\n\n/**\n * (For IE <=9) Handles a propertychange event, sending a `change` event if\n * the value of the active element has changed.\n */\nfunction handlePropertyChange(nativeEvent) {\n if (nativeEvent.propertyName !== 'value') {\n return;\n }\n if (getInstIfValueChanged(activeElementInst)) {\n manualDispatchChangeEvent(nativeEvent);\n }\n}\n\nfunction handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {\n if (topLevelType === TOP_FOCUS) {\n // In IE9, propertychange fires for most input events but is buggy and\n // doesn't fire when text is deleted, but conveniently, selectionchange\n // appears to fire in all of the remaining cases so we catch those and\n // forward the event if the value has changed\n // In either case, we don't want to call the event handler if the value\n // is changed from JS so we redefine a setter for `.value` that updates\n // our activeElementValue variable, allowing us to ignore those changes\n //\n // stopWatching() should be a noop here but we call it just in case we\n // missed a blur event somehow.\n stopWatchingForValueChange();\n startWatchingForValueChange(target, targetInst);\n } else if (topLevelType === TOP_BLUR) {\n stopWatchingForValueChange();\n }\n}\n\n// For IE8 and IE9.\nfunction getTargetInstForInputEventPolyfill(topLevelType, targetInst) {\n if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {\n // On the selectionchange event, the target is just document which isn't\n // helpful for us so just check activeElement instead.\n //\n // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire\n // propertychange on the first input event after setting `value` from a\n // script and fires only keydown, keypress, keyup. Catching keyup usually\n // gets it and catching keydown lets us fire an event for the first\n // keystroke if user does a key repeat (it'll be a little delayed: right\n // before the second keystroke). Other input methods (e.g., paste) seem to\n // fire selectionchange normally.\n return getInstIfValueChanged(activeElementInst);\n }\n}\n\n/**\n * SECTION: handle `click` event\n */\nfunction shouldUseClickEvent(elem) {\n // Use the `click` event to detect changes to checkbox and radio inputs.\n // This approach works across all browsers, whereas `change` does not fire\n // until `blur` in IE8.\n var nodeName = elem.nodeName;\n return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');\n}\n\nfunction getTargetInstForClickEvent(topLevelType, targetInst) {\n if (topLevelType === TOP_CLICK) {\n return getInstIfValueChanged(targetInst);\n }\n}\n\nfunction getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {\n if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {\n return getInstIfValueChanged(targetInst);\n }\n}\n\nfunction handleControlledInputBlur(node) {\n var state = node._wrapperState;\n\n if (!state || !state.controlled || node.type !== 'number') {\n return;\n }\n\n if (!disableInputAttributeSyncing) {\n // If controlled, assign the value attribute to the current value on blur\n setDefaultValue(node, 'number', node.value);\n }\n}\n\n/**\n * This plugin creates an `onChange` event that normalizes change events\n * across form elements. This event fires at a time when it's possible to\n * change the element's value without seeing a flicker.\n *\n * Supported elements are:\n * - input (see `isTextInputElement`)\n * - textarea\n * - select\n */\nvar ChangeEventPlugin = {\n eventTypes: eventTypes$1,\n\n _isInputEventSupported: isInputEventSupported,\n\n extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;\n\n var getTargetInstFunc = void 0,\n handleEventFunc = void 0;\n if (shouldUseChangeEvent(targetNode)) {\n getTargetInstFunc = getTargetInstForChangeEvent;\n } else if (isTextInputElement(targetNode)) {\n if (isInputEventSupported) {\n getTargetInstFunc = getTargetInstForInputOrChangeEvent;\n } else {\n getTargetInstFunc = getTargetInstForInputEventPolyfill;\n handleEventFunc = handleEventsForInputEventPolyfill;\n }\n } else if (shouldUseClickEvent(targetNode)) {\n getTargetInstFunc = getTargetInstForClickEvent;\n }\n\n if (getTargetInstFunc) {\n var inst = getTargetInstFunc(topLevelType, targetInst);\n if (inst) {\n var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);\n return event;\n }\n }\n\n if (handleEventFunc) {\n handleEventFunc(topLevelType, targetNode, targetInst);\n }\n\n // When blurring, set the value attribute for number inputs\n if (topLevelType === TOP_BLUR) {\n handleControlledInputBlur(targetNode);\n }\n }\n};\n\n/**\n * Module that is injectable into `EventPluginHub`, that specifies a\n * deterministic ordering of `EventPlugin`s. A convenient way to reason about\n * plugins, without having to package every one of them. This is better than\n * having plugins be ordered in the same order that they are injected because\n * that ordering would be influenced by the packaging order.\n * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that\n * preventing default on events is convenient in `SimpleEventPlugin` handlers.\n */\nvar DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];\n\nvar SyntheticUIEvent = SyntheticEvent.extend({\n view: null,\n detail: null\n});\n\nvar modifierKeyToProp = {\n Alt: 'altKey',\n Control: 'ctrlKey',\n Meta: 'metaKey',\n Shift: 'shiftKey'\n};\n\n// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support\n// getModifierState. If getModifierState is not supported, we map it to a set of\n// modifier keys exposed by the event. In this case, Lock-keys are not supported.\n/**\n * Translation from modifier key to the associated property in the event.\n * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers\n */\n\nfunction modifierStateGetter(keyArg) {\n var syntheticEvent = this;\n var nativeEvent = syntheticEvent.nativeEvent;\n if (nativeEvent.getModifierState) {\n return nativeEvent.getModifierState(keyArg);\n }\n var keyProp = modifierKeyToProp[keyArg];\n return keyProp ? !!nativeEvent[keyProp] : false;\n}\n\nfunction getEventModifierState(nativeEvent) {\n return modifierStateGetter;\n}\n\nvar previousScreenX = 0;\nvar previousScreenY = 0;\n// Use flags to signal movementX/Y has already been set\nvar isMovementXSet = false;\nvar isMovementYSet = false;\n\n/**\n * @interface MouseEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar SyntheticMouseEvent = SyntheticUIEvent.extend({\n screenX: null,\n screenY: null,\n clientX: null,\n clientY: null,\n pageX: null,\n pageY: null,\n ctrlKey: null,\n shiftKey: null,\n altKey: null,\n metaKey: null,\n getModifierState: getEventModifierState,\n button: null,\n buttons: null,\n relatedTarget: function (event) {\n return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);\n },\n movementX: function (event) {\n if ('movementX' in event) {\n return event.movementX;\n }\n\n var screenX = previousScreenX;\n previousScreenX = event.screenX;\n\n if (!isMovementXSet) {\n isMovementXSet = true;\n return 0;\n }\n\n return event.type === 'mousemove' ? event.screenX - screenX : 0;\n },\n movementY: function (event) {\n if ('movementY' in event) {\n return event.movementY;\n }\n\n var screenY = previousScreenY;\n previousScreenY = event.screenY;\n\n if (!isMovementYSet) {\n isMovementYSet = true;\n return 0;\n }\n\n return event.type === 'mousemove' ? event.screenY - screenY : 0;\n }\n});\n\n/**\n * @interface PointerEvent\n * @see http://www.w3.org/TR/pointerevents/\n */\nvar SyntheticPointerEvent = SyntheticMouseEvent.extend({\n pointerId: null,\n width: null,\n height: null,\n pressure: null,\n tangentialPressure: null,\n tiltX: null,\n tiltY: null,\n twist: null,\n pointerType: null,\n isPrimary: null\n});\n\nvar eventTypes$2 = {\n mouseEnter: {\n registrationName: 'onMouseEnter',\n dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]\n },\n mouseLeave: {\n registrationName: 'onMouseLeave',\n dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]\n },\n pointerEnter: {\n registrationName: 'onPointerEnter',\n dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]\n },\n pointerLeave: {\n registrationName: 'onPointerLeave',\n dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]\n }\n};\n\nvar EnterLeaveEventPlugin = {\n eventTypes: eventTypes$2,\n\n /**\n * For almost every interaction we care about, there will be both a top-level\n * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that\n * we do not extract duplicate events. However, moving the mouse into the\n * browser from outside will not fire a `mouseout` event. In this case, we use\n * the `mouseover` top-level event.\n */\n extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;\n var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;\n\n if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {\n return null;\n }\n\n if (!isOutEvent && !isOverEvent) {\n // Must not be a mouse or pointer in or out - ignoring.\n return null;\n }\n\n var win = void 0;\n if (nativeEventTarget.window === nativeEventTarget) {\n // `nativeEventTarget` is probably a window object.\n win = nativeEventTarget;\n } else {\n // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.\n var doc = nativeEventTarget.ownerDocument;\n if (doc) {\n win = doc.defaultView || doc.parentWindow;\n } else {\n win = window;\n }\n }\n\n var from = void 0;\n var to = void 0;\n if (isOutEvent) {\n from = targetInst;\n var related = nativeEvent.relatedTarget || nativeEvent.toElement;\n to = related ? getClosestInstanceFromNode(related) : null;\n } else {\n // Moving to a node from outside the window.\n from = null;\n to = targetInst;\n }\n\n if (from === to) {\n // Nothing pertains to our managed components.\n return null;\n }\n\n var eventInterface = void 0,\n leaveEventType = void 0,\n enterEventType = void 0,\n eventTypePrefix = void 0;\n\n if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {\n eventInterface = SyntheticMouseEvent;\n leaveEventType = eventTypes$2.mouseLeave;\n enterEventType = eventTypes$2.mouseEnter;\n eventTypePrefix = 'mouse';\n } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {\n eventInterface = SyntheticPointerEvent;\n leaveEventType = eventTypes$2.pointerLeave;\n enterEventType = eventTypes$2.pointerEnter;\n eventTypePrefix = 'pointer';\n }\n\n var fromNode = from == null ? win : getNodeFromInstance$1(from);\n var toNode = to == null ? win : getNodeFromInstance$1(to);\n\n var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);\n leave.type = eventTypePrefix + 'leave';\n leave.target = fromNode;\n leave.relatedTarget = toNode;\n\n var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);\n enter.type = eventTypePrefix + 'enter';\n enter.target = toNode;\n enter.relatedTarget = fromNode;\n\n accumulateEnterLeaveDispatches(leave, enter, from, to);\n\n return [leave, enter];\n }\n};\n\n/**\n * inlined Object.is polyfill to avoid requiring consumers ship their own\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n */\nfunction is(x, y) {\n return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare\n ;\n}\n\nvar hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n/**\n * Performs equality by iterating through keys on an object and returning false\n * when any key has values which are not strictly equal between the arguments.\n * Returns true when the values of all keys are strictly equal.\n */\nfunction shallowEqual(objA, objB) {\n if (is(objA, objB)) {\n return true;\n }\n\n if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {\n return false;\n }\n\n var keysA = Object.keys(objA);\n var keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) {\n return false;\n }\n\n // Test for A's keys different from B.\n for (var i = 0; i < keysA.length; i++) {\n if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * `ReactInstanceMap` maintains a mapping from a public facing stateful\n * instance (key) and the internal representation (value). This allows public\n * methods to accept the user facing instance as an argument and map them back\n * to internal methods.\n *\n * Note that this module is currently shared and assumed to be stateless.\n * If this becomes an actual Map, that will break.\n */\n\n/**\n * This API should be called `delete` but we'd have to make sure to always\n * transform these to strings for IE support. When this transform is fully\n * supported we can rename it.\n */\n\n\nfunction get(key) {\n return key._reactInternalFiber;\n}\n\nfunction has(key) {\n return key._reactInternalFiber !== undefined;\n}\n\nfunction set(key, value) {\n key._reactInternalFiber = value;\n}\n\n// Don't change these two values. They're used by React Dev Tools.\nvar NoEffect = /* */0;\nvar PerformedWork = /* */1;\n\n// You can change the rest (and add more).\nvar Placement = /* */2;\nvar Update = /* */4;\nvar PlacementAndUpdate = /* */6;\nvar Deletion = /* */8;\nvar ContentReset = /* */16;\nvar Callback = /* */32;\nvar DidCapture = /* */64;\nvar Ref = /* */128;\nvar Snapshot = /* */256;\nvar Passive = /* */512;\n\n// Passive & Update & Callback & Ref & Snapshot\nvar LifecycleEffectMask = /* */932;\n\n// Union of all host effects\nvar HostEffectMask = /* */1023;\n\nvar Incomplete = /* */1024;\nvar ShouldCapture = /* */2048;\n\nvar ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;\n\nvar MOUNTING = 1;\nvar MOUNTED = 2;\nvar UNMOUNTED = 3;\n\nfunction isFiberMountedImpl(fiber) {\n var node = fiber;\n if (!fiber.alternate) {\n // If there is no alternate, this might be a new tree that isn't inserted\n // yet. If it is, then it will have a pending insertion effect on it.\n if ((node.effectTag & Placement) !== NoEffect) {\n return MOUNTING;\n }\n while (node.return) {\n node = node.return;\n if ((node.effectTag & Placement) !== NoEffect) {\n return MOUNTING;\n }\n }\n } else {\n while (node.return) {\n node = node.return;\n }\n }\n if (node.tag === HostRoot) {\n // TODO: Check if this was a nested HostRoot when used with\n // renderContainerIntoSubtree.\n return MOUNTED;\n }\n // If we didn't hit the root, that means that we're in an disconnected tree\n // that has been unmounted.\n return UNMOUNTED;\n}\n\nfunction isFiberMounted(fiber) {\n return isFiberMountedImpl(fiber) === MOUNTED;\n}\n\nfunction isMounted(component) {\n {\n var owner = ReactCurrentOwner$1.current;\n if (owner !== null && owner.tag === ClassComponent) {\n var ownerFiber = owner;\n var instance = ownerFiber.stateNode;\n !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;\n instance._warnedAboutRefsInRender = true;\n }\n }\n\n var fiber = get(component);\n if (!fiber) {\n return false;\n }\n return isFiberMountedImpl(fiber) === MOUNTED;\n}\n\nfunction assertIsMounted(fiber) {\n !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;\n}\n\nfunction findCurrentFiberUsingSlowPath(fiber) {\n var alternate = fiber.alternate;\n if (!alternate) {\n // If there is no alternate, then we only need to check if it is mounted.\n var state = isFiberMountedImpl(fiber);\n !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;\n if (state === MOUNTING) {\n return null;\n }\n return fiber;\n }\n // If we have two possible branches, we'll walk backwards up to the root\n // to see what path the root points to. On the way we may hit one of the\n // special cases and we'll deal with them.\n var a = fiber;\n var b = alternate;\n while (true) {\n var parentA = a.return;\n var parentB = parentA ? parentA.alternate : null;\n if (!parentA || !parentB) {\n // We're at the root.\n break;\n }\n\n // If both copies of the parent fiber point to the same child, we can\n // assume that the child is current. This happens when we bailout on low\n // priority: the bailed out fiber's child reuses the current child.\n if (parentA.child === parentB.child) {\n var child = parentA.child;\n while (child) {\n if (child === a) {\n // We've determined that A is the current branch.\n assertIsMounted(parentA);\n return fiber;\n }\n if (child === b) {\n // We've determined that B is the current branch.\n assertIsMounted(parentA);\n return alternate;\n }\n child = child.sibling;\n }\n // We should never have an alternate for any mounting node. So the only\n // way this could possibly happen is if this was unmounted, if at all.\n invariant(false, 'Unable to find node on an unmounted component.');\n }\n\n if (a.return !== b.return) {\n // The return pointer of A and the return pointer of B point to different\n // fibers. We assume that return pointers never criss-cross, so A must\n // belong to the child set of A.return, and B must belong to the child\n // set of B.return.\n a = parentA;\n b = parentB;\n } else {\n // The return pointers point to the same fiber. We'll have to use the\n // default, slow path: scan the child sets of each parent alternate to see\n // which child belongs to which set.\n //\n // Search parent A's child set\n var didFindChild = false;\n var _child = parentA.child;\n while (_child) {\n if (_child === a) {\n didFindChild = true;\n a = parentA;\n b = parentB;\n break;\n }\n if (_child === b) {\n didFindChild = true;\n b = parentA;\n a = parentB;\n break;\n }\n _child = _child.sibling;\n }\n if (!didFindChild) {\n // Search parent B's child set\n _child = parentB.child;\n while (_child) {\n if (_child === a) {\n didFindChild = true;\n a = parentB;\n b = parentA;\n break;\n }\n if (_child === b) {\n didFindChild = true;\n b = parentB;\n a = parentA;\n break;\n }\n _child = _child.sibling;\n }\n !didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;\n }\n }\n\n !(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;\n }\n // If the root is not a host container, we're in a disconnected tree. I.e.\n // unmounted.\n !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;\n if (a.stateNode.current === a) {\n // We've determined that A is the current branch.\n return fiber;\n }\n // Otherwise B has to be current branch.\n return alternate;\n}\n\nfunction findCurrentHostFiber(parent) {\n var currentParent = findCurrentFiberUsingSlowPath(parent);\n if (!currentParent) {\n return null;\n }\n\n // Next we'll drill down this component to find the first HostComponent/Text.\n var node = currentParent;\n while (true) {\n if (node.tag === HostComponent || node.tag === HostText) {\n return node;\n } else if (node.child) {\n node.child.return = node;\n node = node.child;\n continue;\n }\n if (node === currentParent) {\n return null;\n }\n while (!node.sibling) {\n if (!node.return || node.return === currentParent) {\n return null;\n }\n node = node.return;\n }\n node.sibling.return = node.return;\n node = node.sibling;\n }\n // Flow needs the return null here, but ESLint complains about it.\n // eslint-disable-next-line no-unreachable\n return null;\n}\n\nfunction findCurrentHostFiberWithNoPortals(parent) {\n var currentParent = findCurrentFiberUsingSlowPath(parent);\n if (!currentParent) {\n return null;\n }\n\n // Next we'll drill down this component to find the first HostComponent/Text.\n var node = currentParent;\n while (true) {\n if (node.tag === HostComponent || node.tag === HostText) {\n return node;\n } else if (node.child && node.tag !== HostPortal) {\n node.child.return = node;\n node = node.child;\n continue;\n }\n if (node === currentParent) {\n return null;\n }\n while (!node.sibling) {\n if (!node.return || node.return === currentParent) {\n return null;\n }\n node = node.return;\n }\n node.sibling.return = node.return;\n node = node.sibling;\n }\n // Flow needs the return null here, but ESLint complains about it.\n // eslint-disable-next-line no-unreachable\n return null;\n}\n\nfunction addEventBubbleListener(element, eventType, listener) {\n element.addEventListener(eventType, listener, false);\n}\n\nfunction addEventCaptureListener(element, eventType, listener) {\n element.addEventListener(eventType, listener, true);\n}\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface\n * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent\n */\nvar SyntheticAnimationEvent = SyntheticEvent.extend({\n animationName: null,\n elapsedTime: null,\n pseudoElement: null\n});\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/clipboard-apis/\n */\nvar SyntheticClipboardEvent = SyntheticEvent.extend({\n clipboardData: function (event) {\n return 'clipboardData' in event ? event.clipboardData : window.clipboardData;\n }\n});\n\n/**\n * @interface FocusEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar SyntheticFocusEvent = SyntheticUIEvent.extend({\n relatedTarget: null\n});\n\n/**\n * `charCode` represents the actual \"character code\" and is safe to use with\n * `String.fromCharCode`. As such, only keys that correspond to printable\n * characters produce a valid `charCode`, the only exception to this is Enter.\n * The Tab-key is considered non-printable and does not have a `charCode`,\n * presumably because it does not produce a tab-character in browsers.\n *\n * @param {object} nativeEvent Native browser event.\n * @return {number} Normalized `charCode` property.\n */\nfunction getEventCharCode(nativeEvent) {\n var charCode = void 0;\n var keyCode = nativeEvent.keyCode;\n\n if ('charCode' in nativeEvent) {\n charCode = nativeEvent.charCode;\n\n // FF does not set `charCode` for the Enter-key, check against `keyCode`.\n if (charCode === 0 && keyCode === 13) {\n charCode = 13;\n }\n } else {\n // IE8 does not implement `charCode`, but `keyCode` has the correct value.\n charCode = keyCode;\n }\n\n // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)\n // report Enter as charCode 10 when ctrl is pressed.\n if (charCode === 10) {\n charCode = 13;\n }\n\n // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.\n // Must not discard the (non-)printable Enter-key.\n if (charCode >= 32 || charCode === 13) {\n return charCode;\n }\n\n return 0;\n}\n\n/**\n * Normalization of deprecated HTML5 `key` values\n * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names\n */\nvar normalizeKey = {\n Esc: 'Escape',\n Spacebar: ' ',\n Left: 'ArrowLeft',\n Up: 'ArrowUp',\n Right: 'ArrowRight',\n Down: 'ArrowDown',\n Del: 'Delete',\n Win: 'OS',\n Menu: 'ContextMenu',\n Apps: 'ContextMenu',\n Scroll: 'ScrollLock',\n MozPrintableKey: 'Unidentified'\n};\n\n/**\n * Translation from legacy `keyCode` to HTML5 `key`\n * Only special keys supported, all others depend on keyboard layout or browser\n * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names\n */\nvar translateToKey = {\n '8': 'Backspace',\n '9': 'Tab',\n '12': 'Clear',\n '13': 'Enter',\n '16': 'Shift',\n '17': 'Control',\n '18': 'Alt',\n '19': 'Pause',\n '20': 'CapsLock',\n '27': 'Escape',\n '32': ' ',\n '33': 'PageUp',\n '34': 'PageDown',\n '35': 'End',\n '36': 'Home',\n '37': 'ArrowLeft',\n '38': 'ArrowUp',\n '39': 'ArrowRight',\n '40': 'ArrowDown',\n '45': 'Insert',\n '46': 'Delete',\n '112': 'F1',\n '113': 'F2',\n '114': 'F3',\n '115': 'F4',\n '116': 'F5',\n '117': 'F6',\n '118': 'F7',\n '119': 'F8',\n '120': 'F9',\n '121': 'F10',\n '122': 'F11',\n '123': 'F12',\n '144': 'NumLock',\n '145': 'ScrollLock',\n '224': 'Meta'\n};\n\n/**\n * @param {object} nativeEvent Native browser event.\n * @return {string} Normalized `key` property.\n */\nfunction getEventKey(nativeEvent) {\n if (nativeEvent.key) {\n // Normalize inconsistent values reported by browsers due to\n // implementations of a working draft specification.\n\n // FireFox implements `key` but returns `MozPrintableKey` for all\n // printable characters (normalized to `Unidentified`), ignore it.\n var key = normalizeKey[nativeEvent.key] || nativeEvent.key;\n if (key !== 'Unidentified') {\n return key;\n }\n }\n\n // Browser does not implement `key`, polyfill as much of it as we can.\n if (nativeEvent.type === 'keypress') {\n var charCode = getEventCharCode(nativeEvent);\n\n // The enter-key is technically both printable and non-printable and can\n // thus be captured by `keypress`, no other non-printable key should.\n return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);\n }\n if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {\n // While user keyboard layout determines the actual meaning of each\n // `keyCode` value, almost all function keys have a universal value.\n return translateToKey[nativeEvent.keyCode] || 'Unidentified';\n }\n return '';\n}\n\n/**\n * @interface KeyboardEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar SyntheticKeyboardEvent = SyntheticUIEvent.extend({\n key: getEventKey,\n location: null,\n ctrlKey: null,\n shiftKey: null,\n altKey: null,\n metaKey: null,\n repeat: null,\n locale: null,\n getModifierState: getEventModifierState,\n // Legacy Interface\n charCode: function (event) {\n // `charCode` is the result of a KeyPress event and represents the value of\n // the actual printable character.\n\n // KeyPress is deprecated, but its replacement is not yet final and not\n // implemented in any major browser. Only KeyPress has charCode.\n if (event.type === 'keypress') {\n return getEventCharCode(event);\n }\n return 0;\n },\n keyCode: function (event) {\n // `keyCode` is the result of a KeyDown/Up event and represents the value of\n // physical keyboard key.\n\n // The actual meaning of the value depends on the users' keyboard layout\n // which cannot be detected. Assuming that it is a US keyboard layout\n // provides a surprisingly accurate mapping for US and European users.\n // Due to this, it is left to the user to implement at this time.\n if (event.type === 'keydown' || event.type === 'keyup') {\n return event.keyCode;\n }\n return 0;\n },\n which: function (event) {\n // `which` is an alias for either `keyCode` or `charCode` depending on the\n // type of the event.\n if (event.type === 'keypress') {\n return getEventCharCode(event);\n }\n if (event.type === 'keydown' || event.type === 'keyup') {\n return event.keyCode;\n }\n return 0;\n }\n});\n\n/**\n * @interface DragEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar SyntheticDragEvent = SyntheticMouseEvent.extend({\n dataTransfer: null\n});\n\n/**\n * @interface TouchEvent\n * @see http://www.w3.org/TR/touch-events/\n */\nvar SyntheticTouchEvent = SyntheticUIEvent.extend({\n touches: null,\n targetTouches: null,\n changedTouches: null,\n altKey: null,\n metaKey: null,\n ctrlKey: null,\n shiftKey: null,\n getModifierState: getEventModifierState\n});\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-\n * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent\n */\nvar SyntheticTransitionEvent = SyntheticEvent.extend({\n propertyName: null,\n elapsedTime: null,\n pseudoElement: null\n});\n\n/**\n * @interface WheelEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar SyntheticWheelEvent = SyntheticMouseEvent.extend({\n deltaX: function (event) {\n return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).\n 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;\n },\n deltaY: function (event) {\n return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).\n 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).\n 'wheelDelta' in event ? -event.wheelDelta : 0;\n },\n\n deltaZ: null,\n\n // Browsers without \"deltaMode\" is reporting in raw wheel delta where one\n // notch on the scroll is always +/- 120, roughly equivalent to pixels.\n // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or\n // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.\n deltaMode: null\n});\n\n/**\n * Turns\n * ['abort', ...]\n * into\n * eventTypes = {\n * 'abort': {\n * phasedRegistrationNames: {\n * bubbled: 'onAbort',\n * captured: 'onAbortCapture',\n * },\n * dependencies: [TOP_ABORT],\n * },\n * ...\n * };\n * topLevelEventsToDispatchConfig = new Map([\n * [TOP_ABORT, { sameConfig }],\n * ]);\n */\n\nvar interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_AUX_CLICK, 'auxClick'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']];\nvar nonInteractiveEventTypeNames = [[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_DRAG, 'drag'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_LOAD_START, 'loadStart'], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_PLAYING, 'playing'], [TOP_POINTER_MOVE, 'pointerMove'], [TOP_POINTER_OUT, 'pointerOut'], [TOP_POINTER_OVER, 'pointerOver'], [TOP_PROGRESS, 'progress'], [TOP_SCROLL, 'scroll'], [TOP_SEEKING, 'seeking'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']];\n\nvar eventTypes$4 = {};\nvar topLevelEventsToDispatchConfig = {};\n\nfunction addEventTypeNameToConfig(_ref, isInteractive) {\n var topEvent = _ref[0],\n event = _ref[1];\n\n var capitalizedEvent = event[0].toUpperCase() + event.slice(1);\n var onEvent = 'on' + capitalizedEvent;\n\n var type = {\n phasedRegistrationNames: {\n bubbled: onEvent,\n captured: onEvent + 'Capture'\n },\n dependencies: [topEvent],\n isInteractive: isInteractive\n };\n eventTypes$4[event] = type;\n topLevelEventsToDispatchConfig[topEvent] = type;\n}\n\ninteractiveEventTypeNames.forEach(function (eventTuple) {\n addEventTypeNameToConfig(eventTuple, true);\n});\nnonInteractiveEventTypeNames.forEach(function (eventTuple) {\n addEventTypeNameToConfig(eventTuple, false);\n});\n\n// Only used in DEV for exhaustiveness validation.\nvar knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING];\n\nvar SimpleEventPlugin = {\n eventTypes: eventTypes$4,\n\n isInteractiveTopLevelEventType: function (topLevelType) {\n var config = topLevelEventsToDispatchConfig[topLevelType];\n return config !== undefined && config.isInteractive === true;\n },\n\n\n extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];\n if (!dispatchConfig) {\n return null;\n }\n var EventConstructor = void 0;\n switch (topLevelType) {\n case TOP_KEY_PRESS:\n // Firefox creates a keypress event for function keys too. This removes\n // the unwanted keypress events. Enter is however both printable and\n // non-printable. One would expect Tab to be as well (but it isn't).\n if (getEventCharCode(nativeEvent) === 0) {\n return null;\n }\n /* falls through */\n case TOP_KEY_DOWN:\n case TOP_KEY_UP:\n EventConstructor = SyntheticKeyboardEvent;\n break;\n case TOP_BLUR:\n case TOP_FOCUS:\n EventConstructor = SyntheticFocusEvent;\n break;\n case TOP_CLICK:\n // Firefox creates a click event on right mouse clicks. This removes the\n // unwanted click events.\n if (nativeEvent.button === 2) {\n return null;\n }\n /* falls through */\n case TOP_AUX_CLICK:\n case TOP_DOUBLE_CLICK:\n case TOP_MOUSE_DOWN:\n case TOP_MOUSE_MOVE:\n case TOP_MOUSE_UP:\n // TODO: Disabled elements should not respond to mouse events\n /* falls through */\n case TOP_MOUSE_OUT:\n case TOP_MOUSE_OVER:\n case TOP_CONTEXT_MENU:\n EventConstructor = SyntheticMouseEvent;\n break;\n case TOP_DRAG:\n case TOP_DRAG_END:\n case TOP_DRAG_ENTER:\n case TOP_DRAG_EXIT:\n case TOP_DRAG_LEAVE:\n case TOP_DRAG_OVER:\n case TOP_DRAG_START:\n case TOP_DROP:\n EventConstructor = SyntheticDragEvent;\n break;\n case TOP_TOUCH_CANCEL:\n case TOP_TOUCH_END:\n case TOP_TOUCH_MOVE:\n case TOP_TOUCH_START:\n EventConstructor = SyntheticTouchEvent;\n break;\n case TOP_ANIMATION_END:\n case TOP_ANIMATION_ITERATION:\n case TOP_ANIMATION_START:\n EventConstructor = SyntheticAnimationEvent;\n break;\n case TOP_TRANSITION_END:\n EventConstructor = SyntheticTransitionEvent;\n break;\n case TOP_SCROLL:\n EventConstructor = SyntheticUIEvent;\n break;\n case TOP_WHEEL:\n EventConstructor = SyntheticWheelEvent;\n break;\n case TOP_COPY:\n case TOP_CUT:\n case TOP_PASTE:\n EventConstructor = SyntheticClipboardEvent;\n break;\n case TOP_GOT_POINTER_CAPTURE:\n case TOP_LOST_POINTER_CAPTURE:\n case TOP_POINTER_CANCEL:\n case TOP_POINTER_DOWN:\n case TOP_POINTER_MOVE:\n case TOP_POINTER_OUT:\n case TOP_POINTER_OVER:\n case TOP_POINTER_UP:\n EventConstructor = SyntheticPointerEvent;\n break;\n default:\n {\n if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {\n warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);\n }\n }\n // HTML Events\n // @see http://www.w3.org/TR/html5/index.html#events-0\n EventConstructor = SyntheticEvent;\n break;\n }\n var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);\n accumulateTwoPhaseDispatches(event);\n return event;\n }\n};\n\nvar isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;\n\n\nvar CALLBACK_BOOKKEEPING_POOL_SIZE = 10;\nvar callbackBookkeepingPool = [];\n\n/**\n * Find the deepest React component completely containing the root of the\n * passed-in instance (for use when entire React trees are nested within each\n * other). If React trees are not nested, returns null.\n */\nfunction findRootContainerNode(inst) {\n // TODO: It may be a good idea to cache this to prevent unnecessary DOM\n // traversal, but caching is difficult to do correctly without using a\n // mutation observer to listen for all DOM changes.\n while (inst.return) {\n inst = inst.return;\n }\n if (inst.tag !== HostRoot) {\n // This can happen if we're in a detached tree.\n return null;\n }\n return inst.stateNode.containerInfo;\n}\n\n// Used to store ancestor hierarchy in top level callback\nfunction getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {\n if (callbackBookkeepingPool.length) {\n var instance = callbackBookkeepingPool.pop();\n instance.topLevelType = topLevelType;\n instance.nativeEvent = nativeEvent;\n instance.targetInst = targetInst;\n return instance;\n }\n return {\n topLevelType: topLevelType,\n nativeEvent: nativeEvent,\n targetInst: targetInst,\n ancestors: []\n };\n}\n\nfunction releaseTopLevelCallbackBookKeeping(instance) {\n instance.topLevelType = null;\n instance.nativeEvent = null;\n instance.targetInst = null;\n instance.ancestors.length = 0;\n if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {\n callbackBookkeepingPool.push(instance);\n }\n}\n\nfunction handleTopLevel(bookKeeping) {\n var targetInst = bookKeeping.targetInst;\n\n // Loop through the hierarchy, in case there's any nested components.\n // It's important that we build the array of ancestors before calling any\n // event handlers, because event handlers can modify the DOM, leading to\n // inconsistencies with ReactMount's node cache. See #1105.\n var ancestor = targetInst;\n do {\n if (!ancestor) {\n bookKeeping.ancestors.push(ancestor);\n break;\n }\n var root = findRootContainerNode(ancestor);\n if (!root) {\n break;\n }\n bookKeeping.ancestors.push(ancestor);\n ancestor = getClosestInstanceFromNode(root);\n } while (ancestor);\n\n for (var i = 0; i < bookKeeping.ancestors.length; i++) {\n targetInst = bookKeeping.ancestors[i];\n runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));\n }\n}\n\n// TODO: can we stop exporting these?\nvar _enabled = true;\n\nfunction setEnabled(enabled) {\n _enabled = !!enabled;\n}\n\nfunction isEnabled() {\n return _enabled;\n}\n\n/**\n * Traps top-level events by using event bubbling.\n *\n * @param {number} topLevelType Number from `TopLevelEventTypes`.\n * @param {object} element Element on which to attach listener.\n * @return {?object} An object with a remove function which will forcefully\n * remove the listener.\n * @internal\n */\nfunction trapBubbledEvent(topLevelType, element) {\n if (!element) {\n return null;\n }\n var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;\n\n addEventBubbleListener(element, getRawEventName(topLevelType),\n // Check if interactive and wrap in interactiveUpdates\n dispatch.bind(null, topLevelType));\n}\n\n/**\n * Traps a top-level event by using event capturing.\n *\n * @param {number} topLevelType Number from `TopLevelEventTypes`.\n * @param {object} element Element on which to attach listener.\n * @return {?object} An object with a remove function which will forcefully\n * remove the listener.\n * @internal\n */\nfunction trapCapturedEvent(topLevelType, element) {\n if (!element) {\n return null;\n }\n var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;\n\n addEventCaptureListener(element, getRawEventName(topLevelType),\n // Check if interactive and wrap in interactiveUpdates\n dispatch.bind(null, topLevelType));\n}\n\nfunction dispatchInteractiveEvent(topLevelType, nativeEvent) {\n interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);\n}\n\nfunction dispatchEvent(topLevelType, nativeEvent) {\n if (!_enabled) {\n return;\n }\n\n var nativeEventTarget = getEventTarget(nativeEvent);\n var targetInst = getClosestInstanceFromNode(nativeEventTarget);\n if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {\n // If we get an event (ex: img onload) before committing that\n // component's mount, ignore it for now (that is, treat it as if it was an\n // event on a non-React tree). We might also consider queueing events and\n // dispatching them after the mount.\n targetInst = null;\n }\n\n var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);\n\n try {\n // Event queue being processed in the same cycle allows\n // `preventDefault`.\n batchedUpdates(handleTopLevel, bookKeeping);\n } finally {\n releaseTopLevelCallbackBookKeeping(bookKeeping);\n }\n}\n\n/**\n * Summary of `ReactBrowserEventEmitter` event handling:\n *\n * - Top-level delegation is used to trap most native browser events. This\n * may only occur in the main thread and is the responsibility of\n * ReactDOMEventListener, which is injected and can therefore support\n * pluggable event sources. This is the only work that occurs in the main\n * thread.\n *\n * - We normalize and de-duplicate events to account for browser quirks. This\n * may be done in the worker thread.\n *\n * - Forward these native events (with the associated top-level type used to\n * trap it) to `EventPluginHub`, which in turn will ask plugins if they want\n * to extract any synthetic events.\n *\n * - The `EventPluginHub` will then process each event by annotating them with\n * \"dispatches\", a sequence of listeners and IDs that care about that event.\n *\n * - The `EventPluginHub` then dispatches the events.\n *\n * Overview of React and the event system:\n *\n * +------------+ .\n * | DOM | .\n * +------------+ .\n * | .\n * v .\n * +------------+ .\n * | ReactEvent | .\n * | Listener | .\n * +------------+ . +-----------+\n * | . +--------+|SimpleEvent|\n * | . | |Plugin |\n * +-----|------+ . v +-----------+\n * | | | . +--------------+ +------------+\n * | +-----------.--->|EventPluginHub| | Event |\n * | | . | | +-----------+ | Propagators|\n * | ReactEvent | . | | |TapEvent | |------------|\n * | Emitter | . | |<---+|Plugin | |other plugin|\n * | | . | | +-----------+ | utilities |\n * | +-----------.--->| | +------------+\n * | | | . +--------------+\n * +-----|------+ . ^ +-----------+\n * | . | |Enter/Leave|\n * + . +-------+|Plugin |\n * +-------------+ . +-----------+\n * | application | .\n * |-------------| .\n * | | .\n * | | .\n * +-------------+ .\n * .\n * React Core . General Purpose Event Plugin System\n */\n\nvar alreadyListeningTo = {};\nvar reactTopListenersCounter = 0;\n\n/**\n * To ensure no conflicts with other potential React instances on the page\n */\nvar topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);\n\nfunction getListeningForDocument(mountAt) {\n // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`\n // directly.\n if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {\n mountAt[topListenersIDKey] = reactTopListenersCounter++;\n alreadyListeningTo[mountAt[topListenersIDKey]] = {};\n }\n return alreadyListeningTo[mountAt[topListenersIDKey]];\n}\n\n/**\n * We listen for bubbled touch events on the document object.\n *\n * Firefox v8.01 (and possibly others) exhibited strange behavior when\n * mounting `onmousemove` events at some node that was not the document\n * element. The symptoms were that if your mouse is not moving over something\n * contained within that mount point (for example on the background) the\n * top-level listeners for `onmousemove` won't be called. However, if you\n * register the `mousemove` on the document object, then it will of course\n * catch all `mousemove`s. This along with iOS quirks, justifies restricting\n * top-level listeners to the document object only, at least for these\n * movement types of events and possibly all events.\n *\n * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html\n *\n * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but\n * they bubble to document.\n *\n * @param {string} registrationName Name of listener (e.g. `onClick`).\n * @param {object} mountAt Container where to mount the listener\n */\nfunction listenTo(registrationName, mountAt) {\n var isListening = getListeningForDocument(mountAt);\n var dependencies = registrationNameDependencies[registrationName];\n\n for (var i = 0; i < dependencies.length; i++) {\n var dependency = dependencies[i];\n if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {\n switch (dependency) {\n case TOP_SCROLL:\n trapCapturedEvent(TOP_SCROLL, mountAt);\n break;\n case TOP_FOCUS:\n case TOP_BLUR:\n trapCapturedEvent(TOP_FOCUS, mountAt);\n trapCapturedEvent(TOP_BLUR, mountAt);\n // We set the flag for a single dependency later in this function,\n // but this ensures we mark both as attached rather than just one.\n isListening[TOP_BLUR] = true;\n isListening[TOP_FOCUS] = true;\n break;\n case TOP_CANCEL:\n case TOP_CLOSE:\n if (isEventSupported(getRawEventName(dependency))) {\n trapCapturedEvent(dependency, mountAt);\n }\n break;\n case TOP_INVALID:\n case TOP_SUBMIT:\n case TOP_RESET:\n // We listen to them on the target DOM elements.\n // Some of them bubble so we don't want them to fire twice.\n break;\n default:\n // By default, listen on the top level to all non-media events.\n // Media events don't bubble so adding the listener wouldn't do anything.\n var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;\n if (!isMediaEvent) {\n trapBubbledEvent(dependency, mountAt);\n }\n break;\n }\n isListening[dependency] = true;\n }\n }\n}\n\nfunction isListeningToAllDependencies(registrationName, mountAt) {\n var isListening = getListeningForDocument(mountAt);\n var dependencies = registrationNameDependencies[registrationName];\n for (var i = 0; i < dependencies.length; i++) {\n var dependency = dependencies[i];\n if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {\n return false;\n }\n }\n return true;\n}\n\nfunction getActiveElement(doc) {\n doc = doc || (typeof document !== 'undefined' ? document : undefined);\n if (typeof doc === 'undefined') {\n return null;\n }\n try {\n return doc.activeElement || doc.body;\n } catch (e) {\n return doc.body;\n }\n}\n\n/**\n * Given any node return the first leaf node without children.\n *\n * @param {DOMElement|DOMTextNode} node\n * @return {DOMElement|DOMTextNode}\n */\nfunction getLeafNode(node) {\n while (node && node.firstChild) {\n node = node.firstChild;\n }\n return node;\n}\n\n/**\n * Get the next sibling within a container. This will walk up the\n * DOM if a node's siblings have been exhausted.\n *\n * @param {DOMElement|DOMTextNode} node\n * @return {?DOMElement|DOMTextNode}\n */\nfunction getSiblingNode(node) {\n while (node) {\n if (node.nextSibling) {\n return node.nextSibling;\n }\n node = node.parentNode;\n }\n}\n\n/**\n * Get object describing the nodes which contain characters at offset.\n *\n * @param {DOMElement|DOMTextNode} root\n * @param {number} offset\n * @return {?object}\n */\nfunction getNodeForCharacterOffset(root, offset) {\n var node = getLeafNode(root);\n var nodeStart = 0;\n var nodeEnd = 0;\n\n while (node) {\n if (node.nodeType === TEXT_NODE) {\n nodeEnd = nodeStart + node.textContent.length;\n\n if (nodeStart <= offset && nodeEnd >= offset) {\n return {\n node: node,\n offset: offset - nodeStart\n };\n }\n\n nodeStart = nodeEnd;\n }\n\n node = getLeafNode(getSiblingNode(node));\n }\n}\n\n/**\n * @param {DOMElement} outerNode\n * @return {?object}\n */\nfunction getOffsets(outerNode) {\n var ownerDocument = outerNode.ownerDocument;\n\n var win = ownerDocument && ownerDocument.defaultView || window;\n var selection = win.getSelection && win.getSelection();\n\n if (!selection || selection.rangeCount === 0) {\n return null;\n }\n\n var anchorNode = selection.anchorNode,\n anchorOffset = selection.anchorOffset,\n focusNode = selection.focusNode,\n focusOffset = selection.focusOffset;\n\n // In Firefox, anchorNode and focusNode can be \"anonymous divs\", e.g. the\n // up/down buttons on an . Anonymous divs do not seem to\n // expose properties, triggering a \"Permission denied error\" if any of its\n // properties are accessed. The only seemingly possible way to avoid erroring\n // is to access a property that typically works for non-anonymous divs and\n // catch any error that may otherwise arise. See\n // https://bugzilla.mozilla.org/show_bug.cgi?id=208427\n\n try {\n /* eslint-disable no-unused-expressions */\n anchorNode.nodeType;\n focusNode.nodeType;\n /* eslint-enable no-unused-expressions */\n } catch (e) {\n return null;\n }\n\n return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);\n}\n\n/**\n * Returns {start, end} where `start` is the character/codepoint index of\n * (anchorNode, anchorOffset) within the textContent of `outerNode`, and\n * `end` is the index of (focusNode, focusOffset).\n *\n * Returns null if you pass in garbage input but we should probably just crash.\n *\n * Exported only for testing.\n */\nfunction getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {\n var length = 0;\n var start = -1;\n var end = -1;\n var indexWithinAnchor = 0;\n var indexWithinFocus = 0;\n var node = outerNode;\n var parentNode = null;\n\n outer: while (true) {\n var next = null;\n\n while (true) {\n if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {\n start = length + anchorOffset;\n }\n if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {\n end = length + focusOffset;\n }\n\n if (node.nodeType === TEXT_NODE) {\n length += node.nodeValue.length;\n }\n\n if ((next = node.firstChild) === null) {\n break;\n }\n // Moving from `node` to its first child `next`.\n parentNode = node;\n node = next;\n }\n\n while (true) {\n if (node === outerNode) {\n // If `outerNode` has children, this is always the second time visiting\n // it. If it has no children, this is still the first loop, and the only\n // valid selection is anchorNode and focusNode both equal to this node\n // and both offsets 0, in which case we will have handled above.\n break outer;\n }\n if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {\n start = length;\n }\n if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {\n end = length;\n }\n if ((next = node.nextSibling) !== null) {\n break;\n }\n node = parentNode;\n parentNode = node.parentNode;\n }\n\n // Moving from `node` to its next sibling `next`.\n node = next;\n }\n\n if (start === -1 || end === -1) {\n // This should never happen. (Would happen if the anchor/focus nodes aren't\n // actually inside the passed-in node.)\n return null;\n }\n\n return {\n start: start,\n end: end\n };\n}\n\n/**\n * In modern non-IE browsers, we can support both forward and backward\n * selections.\n *\n * Note: IE10+ supports the Selection object, but it does not support\n * the `extend` method, which means that even in modern IE, it's not possible\n * to programmatically create a backward selection. Thus, for all IE\n * versions, we use the old IE API to create our selections.\n *\n * @param {DOMElement|DOMTextNode} node\n * @param {object} offsets\n */\nfunction setOffsets(node, offsets) {\n var doc = node.ownerDocument || document;\n var win = doc && doc.defaultView || window;\n\n // Edge fails with \"Object expected\" in some scenarios.\n // (For instance: TinyMCE editor used in a list component that supports pasting to add more,\n // fails when pasting 100+ items)\n if (!win.getSelection) {\n return;\n }\n\n var selection = win.getSelection();\n var length = node.textContent.length;\n var start = Math.min(offsets.start, length);\n var end = offsets.end === undefined ? start : Math.min(offsets.end, length);\n\n // IE 11 uses modern selection, but doesn't support the extend method.\n // Flip backward selections, so we can set with a single range.\n if (!selection.extend && start > end) {\n var temp = end;\n end = start;\n start = temp;\n }\n\n var startMarker = getNodeForCharacterOffset(node, start);\n var endMarker = getNodeForCharacterOffset(node, end);\n\n if (startMarker && endMarker) {\n if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {\n return;\n }\n var range = doc.createRange();\n range.setStart(startMarker.node, startMarker.offset);\n selection.removeAllRanges();\n\n if (start > end) {\n selection.addRange(range);\n selection.extend(endMarker.node, endMarker.offset);\n } else {\n range.setEnd(endMarker.node, endMarker.offset);\n selection.addRange(range);\n }\n }\n}\n\nfunction isTextNode(node) {\n return node && node.nodeType === TEXT_NODE;\n}\n\nfunction containsNode(outerNode, innerNode) {\n if (!outerNode || !innerNode) {\n return false;\n } else if (outerNode === innerNode) {\n return true;\n } else if (isTextNode(outerNode)) {\n return false;\n } else if (isTextNode(innerNode)) {\n return containsNode(outerNode, innerNode.parentNode);\n } else if ('contains' in outerNode) {\n return outerNode.contains(innerNode);\n } else if (outerNode.compareDocumentPosition) {\n return !!(outerNode.compareDocumentPosition(innerNode) & 16);\n } else {\n return false;\n }\n}\n\nfunction isInDocument(node) {\n return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);\n}\n\nfunction isSameOriginFrame(iframe) {\n try {\n // Accessing the contentDocument of a HTMLIframeElement can cause the browser\n // to throw, e.g. if it has a cross-origin src attribute.\n // Safari will show an error in the console when the access results in \"Blocked a frame with origin\". e.g:\n // iframe.contentDocument.defaultView;\n // A safety way is to access one of the cross origin properties: Window or Location\n // Which might result in \"SecurityError\" DOM Exception and it is compatible to Safari.\n // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl\n\n return typeof iframe.contentWindow.location.href === 'string';\n } catch (err) {\n return false;\n }\n}\n\nfunction getActiveElementDeep() {\n var win = window;\n var element = getActiveElement();\n while (element instanceof win.HTMLIFrameElement) {\n if (isSameOriginFrame(element)) {\n win = element.contentWindow;\n } else {\n return element;\n }\n element = getActiveElement(win.document);\n }\n return element;\n}\n\n/**\n * @ReactInputSelection: React input selection module. Based on Selection.js,\n * but modified to be suitable for react and has a couple of bug fixes (doesn't\n * assume buttons have range selections allowed).\n * Input selection module for React.\n */\n\n/**\n * @hasSelectionCapabilities: we get the element types that support selection\n * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`\n * and `selectionEnd` rows.\n */\nfunction hasSelectionCapabilities(elem) {\n var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();\n return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');\n}\n\nfunction getSelectionInformation() {\n var focusedElem = getActiveElementDeep();\n return {\n focusedElem: focusedElem,\n selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null\n };\n}\n\n/**\n * @restoreSelection: If any selection information was potentially lost,\n * restore it. This is useful when performing operations that could remove dom\n * nodes and place them back in, resulting in focus being lost.\n */\nfunction restoreSelection(priorSelectionInformation) {\n var curFocusedElem = getActiveElementDeep();\n var priorFocusedElem = priorSelectionInformation.focusedElem;\n var priorSelectionRange = priorSelectionInformation.selectionRange;\n if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {\n if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {\n setSelection(priorFocusedElem, priorSelectionRange);\n }\n\n // Focusing a node can change the scroll position, which is undesirable\n var ancestors = [];\n var ancestor = priorFocusedElem;\n while (ancestor = ancestor.parentNode) {\n if (ancestor.nodeType === ELEMENT_NODE) {\n ancestors.push({\n element: ancestor,\n left: ancestor.scrollLeft,\n top: ancestor.scrollTop\n });\n }\n }\n\n if (typeof priorFocusedElem.focus === 'function') {\n priorFocusedElem.focus();\n }\n\n for (var i = 0; i < ancestors.length; i++) {\n var info = ancestors[i];\n info.element.scrollLeft = info.left;\n info.element.scrollTop = info.top;\n }\n }\n}\n\n/**\n * @getSelection: Gets the selection bounds of a focused textarea, input or\n * contentEditable node.\n * -@input: Look up selection bounds of this input\n * -@return {start: selectionStart, end: selectionEnd}\n */\nfunction getSelection$1(input) {\n var selection = void 0;\n\n if ('selectionStart' in input) {\n // Modern browser with input or textarea.\n selection = {\n start: input.selectionStart,\n end: input.selectionEnd\n };\n } else {\n // Content editable or old IE textarea.\n selection = getOffsets(input);\n }\n\n return selection || { start: 0, end: 0 };\n}\n\n/**\n * @setSelection: Sets the selection bounds of a textarea or input and focuses\n * the input.\n * -@input Set selection bounds of this input or textarea\n * -@offsets Object of same form that is returned from get*\n */\nfunction setSelection(input, offsets) {\n var start = offsets.start,\n end = offsets.end;\n\n if (end === undefined) {\n end = start;\n }\n\n if ('selectionStart' in input) {\n input.selectionStart = start;\n input.selectionEnd = Math.min(end, input.value.length);\n } else {\n setOffsets(input, offsets);\n }\n}\n\nvar skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;\n\nvar eventTypes$3 = {\n select: {\n phasedRegistrationNames: {\n bubbled: 'onSelect',\n captured: 'onSelectCapture'\n },\n dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_DRAG_END, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE]\n }\n};\n\nvar activeElement$1 = null;\nvar activeElementInst$1 = null;\nvar lastSelection = null;\nvar mouseDown = false;\n\n/**\n * Get an object which is a unique representation of the current selection.\n *\n * The return value will not be consistent across nodes or browsers, but\n * two identical selections on the same node will return identical objects.\n *\n * @param {DOMElement} node\n * @return {object}\n */\nfunction getSelection(node) {\n if ('selectionStart' in node && hasSelectionCapabilities(node)) {\n return {\n start: node.selectionStart,\n end: node.selectionEnd\n };\n } else {\n var win = node.ownerDocument && node.ownerDocument.defaultView || window;\n var selection = win.getSelection();\n return {\n anchorNode: selection.anchorNode,\n anchorOffset: selection.anchorOffset,\n focusNode: selection.focusNode,\n focusOffset: selection.focusOffset\n };\n }\n}\n\n/**\n * Get document associated with the event target.\n *\n * @param {object} nativeEventTarget\n * @return {Document}\n */\nfunction getEventTargetDocument(eventTarget) {\n return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;\n}\n\n/**\n * Poll selection to see whether it's changed.\n *\n * @param {object} nativeEvent\n * @param {object} nativeEventTarget\n * @return {?SyntheticEvent}\n */\nfunction constructSelectEvent(nativeEvent, nativeEventTarget) {\n // Ensure we have the right element, and that the user is not dragging a\n // selection (this matches native `select` event behavior). In HTML5, select\n // fires only on input and textarea thus if there's no focused element we\n // won't dispatch.\n var doc = getEventTargetDocument(nativeEventTarget);\n\n if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {\n return null;\n }\n\n // Only fire when selection has actually changed.\n var currentSelection = getSelection(activeElement$1);\n if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {\n lastSelection = currentSelection;\n\n var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);\n\n syntheticEvent.type = 'select';\n syntheticEvent.target = activeElement$1;\n\n accumulateTwoPhaseDispatches(syntheticEvent);\n\n return syntheticEvent;\n }\n\n return null;\n}\n\n/**\n * This plugin creates an `onSelect` event that normalizes select events\n * across form elements.\n *\n * Supported elements are:\n * - input (see `isTextInputElement`)\n * - textarea\n * - contentEditable\n *\n * This differs from native browser implementations in the following ways:\n * - Fires on contentEditable fields as well as inputs.\n * - Fires for collapsed selection.\n * - Fires after user input.\n */\nvar SelectEventPlugin = {\n eventTypes: eventTypes$3,\n\n extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var doc = getEventTargetDocument(nativeEventTarget);\n // Track whether all listeners exists for this plugin. If none exist, we do\n // not extract events. See #3639.\n if (!doc || !isListeningToAllDependencies('onSelect', doc)) {\n return null;\n }\n\n var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;\n\n switch (topLevelType) {\n // Track the input node that has focus.\n case TOP_FOCUS:\n if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {\n activeElement$1 = targetNode;\n activeElementInst$1 = targetInst;\n lastSelection = null;\n }\n break;\n case TOP_BLUR:\n activeElement$1 = null;\n activeElementInst$1 = null;\n lastSelection = null;\n break;\n // Don't fire the event while the user is dragging. This matches the\n // semantics of the native select event.\n case TOP_MOUSE_DOWN:\n mouseDown = true;\n break;\n case TOP_CONTEXT_MENU:\n case TOP_MOUSE_UP:\n case TOP_DRAG_END:\n mouseDown = false;\n return constructSelectEvent(nativeEvent, nativeEventTarget);\n // Chrome and IE fire non-standard event when selection is changed (and\n // sometimes when it hasn't). IE's event fires out of order with respect\n // to key and input events on deletion, so we discard it.\n //\n // Firefox doesn't support selectionchange, so check selection status\n // after each key entry. The selection changes after keydown and before\n // keyup, but we check on keydown as well in the case of holding down a\n // key, when multiple keydown events are fired but only one keyup is.\n // This is also our approach for IE handling, for the reason above.\n case TOP_SELECTION_CHANGE:\n if (skipSelectionChangeEvent) {\n break;\n }\n // falls through\n case TOP_KEY_DOWN:\n case TOP_KEY_UP:\n return constructSelectEvent(nativeEvent, nativeEventTarget);\n }\n\n return null;\n }\n};\n\n/**\n * Inject modules for resolving DOM hierarchy and plugin ordering.\n */\ninjection.injectEventPluginOrder(DOMEventPluginOrder);\nsetComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);\n\n/**\n * Some important event plugins included by default (without having to require\n * them).\n */\ninjection.injectEventPluginsByName({\n SimpleEventPlugin: SimpleEventPlugin,\n EnterLeaveEventPlugin: EnterLeaveEventPlugin,\n ChangeEventPlugin: ChangeEventPlugin,\n SelectEventPlugin: SelectEventPlugin,\n BeforeInputEventPlugin: BeforeInputEventPlugin\n});\n\nvar didWarnSelectedSetOnOption = false;\nvar didWarnInvalidChild = false;\n\nfunction flattenChildren(children) {\n var content = '';\n\n // Flatten children. We'll warn if they are invalid\n // during validateProps() which runs for hydration too.\n // Note that this would throw on non-element objects.\n // Elements are stringified (which is normally irrelevant\n // but matters for ).\n React.Children.forEach(children, function (child) {\n if (child == null) {\n return;\n }\n content += child;\n // Note: we don't warn about invalid children here.\n // Instead, this is done separately below so that\n // it happens during the hydration codepath too.\n });\n\n return content;\n}\n\n/**\n * Implements an host component that warns when `selected` is set.\n */\n\nfunction validateProps(element, props) {\n {\n // This mirrors the codepath above, but runs for hydration too.\n // Warn about invalid children here so that client and hydration are consistent.\n // TODO: this seems like it could cause a DEV-only throw for hydration\n // if children contains a non-element object. We should try to avoid that.\n if (typeof props.children === 'object' && props.children !== null) {\n React.Children.forEach(props.children, function (child) {\n if (child == null) {\n return;\n }\n if (typeof child === 'string' || typeof child === 'number') {\n return;\n }\n if (typeof child.type !== 'string') {\n return;\n }\n if (!didWarnInvalidChild) {\n didWarnInvalidChild = true;\n warning$1(false, 'Only strings and numbers are supported as children.');\n }\n });\n }\n\n // TODO: Remove support for `selected` in .\n if (props.selected != null && !didWarnSelectedSetOnOption) {\n warning$1(false, 'Use the `defaultValue` or `value` props on instead of ' + 'setting `selected` on .');\n didWarnSelectedSetOnOption = true;\n }\n }\n}\n\nfunction postMountWrapper$1(element, props) {\n // value=\"\" should make a value attribute (#6219)\n if (props.value != null) {\n element.setAttribute('value', toString(getToStringValue(props.value)));\n }\n}\n\nfunction getHostProps$1(element, props) {\n var hostProps = _assign({ children: undefined }, props);\n var content = flattenChildren(props.children);\n\n if (content) {\n hostProps.children = content;\n }\n\n return hostProps;\n}\n\n// TODO: direct imports like some-package/src/* are bad. Fix me.\nvar didWarnValueDefaultValue$1 = void 0;\n\n{\n didWarnValueDefaultValue$1 = false;\n}\n\nfunction getDeclarationErrorAddendum() {\n var ownerName = getCurrentFiberOwnerNameInDevOrNull();\n if (ownerName) {\n return '\\n\\nCheck the render method of `' + ownerName + '`.';\n }\n return '';\n}\n\nvar valuePropNames = ['value', 'defaultValue'];\n\n/**\n * Validation function for `value` and `defaultValue`.\n */\nfunction checkSelectPropTypes(props) {\n ReactControlledValuePropTypes.checkPropTypes('select', props);\n\n for (var i = 0; i < valuePropNames.length; i++) {\n var propName = valuePropNames[i];\n if (props[propName] == null) {\n continue;\n }\n var isArray = Array.isArray(props[propName]);\n if (props.multiple && !isArray) {\n warning$1(false, 'The `%s` prop supplied to must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());\n } else if (!props.multiple && isArray) {\n warning$1(false, 'The `%s` prop supplied to must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());\n }\n }\n}\n\nfunction updateOptions(node, multiple, propValue, setDefaultSelected) {\n var options = node.options;\n\n if (multiple) {\n var selectedValues = propValue;\n var selectedValue = {};\n for (var i = 0; i < selectedValues.length; i++) {\n // Prefix to avoid chaos with special keys.\n selectedValue['$' + selectedValues[i]] = true;\n }\n for (var _i = 0; _i < options.length; _i++) {\n var selected = selectedValue.hasOwnProperty('$' + options[_i].value);\n if (options[_i].selected !== selected) {\n options[_i].selected = selected;\n }\n if (selected && setDefaultSelected) {\n options[_i].defaultSelected = true;\n }\n }\n } else {\n // Do not set `select.value` as exact behavior isn't consistent across all\n // browsers for all cases.\n var _selectedValue = toString(getToStringValue(propValue));\n var defaultSelected = null;\n for (var _i2 = 0; _i2 < options.length; _i2++) {\n if (options[_i2].value === _selectedValue) {\n options[_i2].selected = true;\n if (setDefaultSelected) {\n options[_i2].defaultSelected = true;\n }\n return;\n }\n if (defaultSelected === null && !options[_i2].disabled) {\n defaultSelected = options[_i2];\n }\n }\n if (defaultSelected !== null) {\n defaultSelected.selected = true;\n }\n }\n}\n\n/**\n * Implements a host component that allows optionally setting the\n * props `value` and `defaultValue`. If `multiple` is false, the prop must be a\n * stringable. If `multiple` is true, the prop must be an array of stringables.\n *\n * If `value` is not supplied (or null/undefined), user actions that change the\n * selected option will trigger updates to the rendered options.\n *\n * If it is supplied (and not null/undefined), the rendered options will not\n * update in response to user actions. Instead, the `value` prop must change in\n * order for the rendered options to update.\n *\n * If `defaultValue` is provided, any options with the supplied values will be\n * selected.\n */\n\nfunction getHostProps$2(element, props) {\n return _assign({}, props, {\n value: undefined\n });\n}\n\nfunction initWrapperState$1(element, props) {\n var node = element;\n {\n checkSelectPropTypes(props);\n }\n\n node._wrapperState = {\n wasMultiple: !!props.multiple\n };\n\n {\n if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {\n warning$1(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components');\n didWarnValueDefaultValue$1 = true;\n }\n }\n}\n\nfunction postMountWrapper$2(element, props) {\n var node = element;\n node.multiple = !!props.multiple;\n var value = props.value;\n if (value != null) {\n updateOptions(node, !!props.multiple, value, false);\n } else if (props.defaultValue != null) {\n updateOptions(node, !!props.multiple, props.defaultValue, true);\n }\n}\n\nfunction postUpdateWrapper(element, props) {\n var node = element;\n var wasMultiple = node._wrapperState.wasMultiple;\n node._wrapperState.wasMultiple = !!props.multiple;\n\n var value = props.value;\n if (value != null) {\n updateOptions(node, !!props.multiple, value, false);\n } else if (wasMultiple !== !!props.multiple) {\n // For simplicity, reapply `defaultValue` if `multiple` is toggled.\n if (props.defaultValue != null) {\n updateOptions(node, !!props.multiple, props.defaultValue, true);\n } else {\n // Revert the select back to its default unselected state.\n updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);\n }\n }\n}\n\nfunction restoreControlledState$2(element, props) {\n var node = element;\n var value = props.value;\n\n if (value != null) {\n updateOptions(node, !!props.multiple, value, false);\n }\n}\n\nvar didWarnValDefaultVal = false;\n\n/**\n * Implements a