<commit_before>(function ( mw, $ ) {
    "use strict";

    // Add chromecast player:
    $( mw ).bind( 'EmbedPlayerUpdateMediaPlayers', function ( event, mediaPlayers ) {
        var chromecastSupportedProtocols = [ 'video/mp4' ];
        var chromecastPlayer = new mw.MediaPlayer( 'chromecast', chromecastSupportedProtocols, 'Chromecast' );
        mediaPlayers.addPlayer( chromecastPlayer );
    } );

    mw.PluginManager.add( 'chromecast', mw.KBaseComponent.extend( {

        defaultConfig: {
            'parent': 'controlsContainer',
            'order': 7,
            'visible': false,
            'align': "right",
            'applicationID': "61EB4CBF",
            'showTooltip': true,
            'tooltip': gM( 'mwe-chromecast-chromecast' ),
            'title': gM( 'mwe-chromecast-chromecast' )
        },
        startCastTitle: gM( 'mwe-chromecast-startcast' ),
        stopCastTitle: gM( 'mwe-chromecast-stopcast' ),
        savedPlayer: null,
        isDisabled: false,
        casting: false,
        remotePlayer: null,
        remotePlayerController: null,
        sessionStateChangedCallback: null,
        CAST_SENDER_V3_URL: '//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1',

        /**
         * Setup the Chromecast plugin - loads Google Cast Chrome sender SDK and bind his handler.
         */
        setup: function () {
            if ( mw.getConfig( 'EmbedPlayer.IsFriendlyIframe' ) ) {
                try {
                    top[ '__onGCastApiAvailable' ] = this.toggleCastButton.bind( this );
                    kWidget.appendScriptUrl( this.CAST_SENDER_V3_URL, null, top.document );
                } catch ( e ) {
                    window[ '__onGCastApiAvailable' ] = this.toggleCastButton.bind( this );
                    kWidget.appendScriptUrl( this.CAST_SENDER_V3_URL );
                }
            } else {
                window[ '__onGCastApiAvailable' ] = this.toggleCastButton.bind( this );
                kWidget.appendScriptUrl( this.CAST_SENDER_V3_URL );
            }
        },

        /**
         * Setup the Chromecast plugin bindings.
         */
        addBindings: function () {
            this.bind( 'chromecastError', this.launchError.bind( this ) );
            this.bind( 'castSessionEnded', this.switchToLocalPlayer.bind( this ) );
        },

        /**
         * Handles the Chromecast player button when receiver is discovered.
         * @param isAvailable
         * @param reason
         */
        toggleCastButton: function ( isAvailable, reason ) {
            this.log( "toggleCastButton: isAvailable=" + isAvailable + ", reason=" + reason );
            if ( isAvailable ) {
                this.initializeCastApi();
                this.show();
            } else {
                this.hide();
            }
        },

        /**
         * Initialize the cast framework.
         * 1) Defines the application id of the receiver.
         * 2) Check if a session is already opened.
         */
        initializeCastApi: function () {
            this.log( "initializeCastApi" );
            window.chrome = top.chrome || window.chrome;
            window.cast = top.cast || window.cast;

            var options = {};
            options.receiverApplicationId = this.getConfig( "applicationID" ).toString();
            options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;
            cast.framework.CastContext.getInstance().setOptions( options );

            this.sessionStateChangedCallback = this.onSessionStateChanged.bind(this);
            this.toggleSessionStateChangedListener(true);

            this.remotePlayer = new cast.framework.RemotePlayer();
            this.remotePlayerController = new cast.framework.RemotePlayerController( this.remotePlayer );
        },

        isSafeEnviornment: function () {
            return mw.isChrome();
        },

        /**
         * Responsible for the logic which happens when we clicking the cast button.
         * @returns {boolean}
         */
        toggleCast: function () {
            this.toggleSessionStateChangedListener(false);
            this.log( "toggleCast: isDisabled=" + this.isDisabled + ", isCasting=" + this.casting );
            if ( this.isDisabled ) {
                return false;
            }
            // If we're casting - disconnect
            if ( this.casting ) {
                this.switchToLocalPlayer();
            } else {
                // If we're not - connect
                this.showConnectingMessage();
                this.embedPlayer.disablePlayControls( [ "chromecast" ] );
                cast.framework.CastContext.getInstance().requestSession().then(
                    this.switchToRemotePlayer.bind( this ),
                    this.launchError.bind( this )
                );
            }
        },

        onSessionStateChanged: function (event) {
            var sessionState = event.sessionState;
            switch (sessionState) {
                case cast.framework.SessionState.SESSION_RESUMED: {
                    this.switchToRemotePlayer();
                    break;
                }
                case cast.framework.SessionState.SESSION_STARTED: {
                    if (!this.casting) {
                        this.showConnectingMessage();
                        this.embedPlayer.disablePlayControls(["chromecast"]);
                        this.switchToRemotePlayer();
                    }
                    break;
                }
                case cast.framework.SessionState.SESSION_ENDED: {
                    if (this.casting) {
                        this.switchToLocalPlayer();
                    }
                    break;
                }
                default:
                    break;
            }
        },

        toggleSessionStateChangedListener: function (enable) {
            if (enable) {
                cast.framework.CastContext.getInstance().addEventListener(cast.framework.CastContextEventType.SESSION_STATE_CHANGED, this.sessionStateChangedCallback);
            } else {
                cast.framework.CastContext.getInstance().removeEventListener(cast.framework.CastContextEventType.SESSION_STATE_CHANGED, this.sessionStateChangedCallback);
            }
        },

        /**
         * Returning the cast button ui.
         */
        getComponent: function () {
            if ( !this.$el ) {
                this.$el = $( '<button/>' )
                    .attr( 'title', this.startCastTitle )
                    .addClass( "btn icon-chromecast" + this.getCssClass() )
                    .click( this.toggleCast.bind( this ) );
            }
            return this.$el;
        },

        /**
         * After cast session has opened, switch to Chromecast player and save the old one.
         */
        switchToRemotePlayer: function () {
            this.log( "switchToChromecastPlayer" );
            var _this = this;
            var playbackParams = this.getEmbedPlayerPlaybackParams();
            this.casting = true;
            this.embedPlayer.casting = true;
            $( this.embedPlayer ).trigger( 'casting', true );
            this.savedPlayer = this.embedPlayer.selectedPlayer;
            this.embedPlayer.clean();
            this.embedPlayer.selectPlayer( mw.EmbedTypes.mediaPlayers.getPlayerById( 'chromecast' ) );
            this.embedPlayer.updatePlaybackInterface( function () {
                _this.embedPlayer.layoutBuilder.closeAlert();
                _this.getComponent().css( "color", "#35BCDA" );
                _this.updateTooltip( _this.stopCastTitle );
                _this.showLoadingMessage();
                _this.embedPlayer.setupRemotePlayer( _this.remotePlayer, _this.remotePlayerController, playbackParams );
                _this.toggleSessionStateChangedListener(true);
            } );
        },

        /**
         * Gets the current playback data.
         * @returns {{currentTime: *, duration: *, volume: (*|Float)}}
         */
        getEmbedPlayerPlaybackParams: function () {
            var playbackParams= {
                currentTime: this.embedPlayer.getPlayerElementTime(),
                duration: this.embedPlayer.getDuration(),
                volume: this.embedPlayer.getPlayerElementVolume(),
                state: this.embedPlayer.currentState,
                captions: null
            };
            if (this.embedPlayer.plugins && this.embedPlayer.plugins.closedCaptions){
                playbackParams.captions = this.embedPlayer.plugins.closedCaptions.selectedSource;
            }
            return playbackParams;
        },

        /**
         * After cast session has been closed, switch to the player that was active before casting.
         */
        switchToLocalPlayer: function () {
            this.log( "switchToSavedPlayer" );
            var _this = this;
            var seekTo = this.embedPlayer.currentTime;
            var stopAfterSeek = (this.embedPlayer.currentState === "pause");
            this.casting = false;
            $( this.embedPlayer ).trigger( 'casting', false );
            this.embedPlayer.shutdownRemotePlayer();
            this.getComponent().css( "color", "white" );
            this.updateTooltip( this.startCastTitle );
            this.embedPlayer.getInterface().find( ".chromecastScreen" ).remove();
            this.embedPlayer.selectPlayer( this.savedPlayer );
            this.embedPlayer.casting = false;
            this.embedPlayer.updatePlaybackInterface( function () {
                _this.embedPlayer.addPlayerSpinner();
                _this.embedPlayer.seek( seekTo, stopAfterSeek );
                _this.toggleSessionStateChangedListener(true);
            } );
        },

        /**
         * Launch an error and restoring the player ui.
         * @param errorCode
         */
        launchError: function ( errorCode ) {
            this.log( "launchError: " + this.getErrorMessage( errorCode ) );
            this.embedPlayer.layoutBuilder.closeAlert();
            this.embedPlayer.enablePlayControls();
            this.toggleSessionStateChangedListener(true);
        },

        /**
         * Gets a human readable error message based on the errorCode which cast sdk provides.
         * @param errorCode
         * @returns {*}
         */
        getErrorMessage: function ( errorCode ) {
            this.log( "getErrorMessage: errorCode=" + errorCode );
            switch ( errorCode ) {
                case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
                    return 'The API is not initialized.';
                case chrome.cast.ErrorCode.CANCEL:
                    return 'The operation was canceled by the user';
                case chrome.cast.ErrorCode.CHANNEL_ERROR:
                    return 'A channel to the receiver is not available.';
                case chrome.cast.ErrorCode.EXTENSION_MISSING:
                    return 'The Cast extension is not available.';
                case chrome.cast.ErrorCode.INVALID_PARAMETER:
                    return 'The parameters to the operation were not valid.';
                case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
                    return 'No receiver was compatible with the session request.';
                case chrome.cast.ErrorCode.SESSION_ERROR:
                    return 'A session could not be created, or a session was invalid.';
                case chrome.cast.ErrorCode.TIMEOUT:
                    return 'The operation timed out.';
            }
        },

        /**
         * Displays connecting message on the player ui.
         */
        showConnectingMessage: function () {
            this.displayMessage( gM( 'mwe-chromecast-connecting' ) );
        },

        /**
         * Displays loading message on the player ui.
         */
        showLoadingMessage: function () {
            this.displayMessage( gM( 'mwe-chromecast-loading' ) );
        },

        /**
         * Displays a certain message on the player ui.
         * @param msg
         */
        displayMessage: function ( msg ) {
            this.embedPlayer.layoutBuilder.displayAlert( {
                    'title': 'Chromecast Player',
                    'message': msg,
                    'isModal': true,
                    'keepOverlay': true,
                    'noButtons': true,
                    'isError': true,
                    'props': {
                        'customAlertContainerCssClass': 'connectingMsg',
                        'customAlertTitleCssClass': 'hidden',
                        'textColor': '#ffffff'
                    }
                }
            );
        }
    } ) );
})( window.mw, window.jQuery );
<commit_msg>fix(sup-14798): fixed the issue with chrome cast in Iframe (#3861)<commit_after>(function ( mw, $ ) {
    "use strict";

    // Add chromecast player:
    $( mw ).bind( 'EmbedPlayerUpdateMediaPlayers', function ( event, mediaPlayers ) {
        var chromecastSupportedProtocols = [ 'video/mp4' ];
        var chromecastPlayer = new mw.MediaPlayer( 'chromecast', chromecastSupportedProtocols, 'Chromecast' );
        mediaPlayers.addPlayer( chromecastPlayer );
    } );

    mw.PluginManager.add( 'chromecast', mw.KBaseComponent.extend( {

        defaultConfig: {
            'parent': 'controlsContainer',
            'order': 7,
            'visible': false,
            'align': "right",
            'applicationID': "61EB4CBF",
            'showTooltip': true,
            'tooltip': gM( 'mwe-chromecast-chromecast' ),
            'title': gM( 'mwe-chromecast-chromecast' )
        },
        startCastTitle: gM( 'mwe-chromecast-startcast' ),
        stopCastTitle: gM( 'mwe-chromecast-stopcast' ),
        savedPlayer: null,
        isDisabled: false,
        casting: false,
        remotePlayer: null,
        remotePlayerController: null,
        sessionStateChangedCallback: null,
        CAST_SENDER_V3_URL: '//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1',
        isInIframeApi: false,

        /**
         * Setup the Chromecast plugin - loads Google Cast Chrome sender SDK and bind his handler.
         */
        setup: function () {
            if ( mw.getConfig( 'EmbedPlayer.IsFriendlyIframe' ) ) {
                try {
                    top[ '__onGCastApiAvailable' ] = this.toggleCastButton.bind( this );
                    kWidget.appendScriptUrl( this.CAST_SENDER_V3_URL, null, top.document );
                    this.isInIframeApi = false;
                } catch ( e ) {
                    window[ '__onGCastApiAvailable' ] = this.toggleCastButton.bind( this );
                    kWidget.appendScriptUrl( this.CAST_SENDER_V3_URL );
                    this.isInIframeApi = true;
                }
            } else {
                window[ '__onGCastApiAvailable' ] = this.toggleCastButton.bind( this );
                kWidget.appendScriptUrl( this.CAST_SENDER_V3_URL );
                this.isInIframeApi = true;
            }
        },

        /**
         * Setup the Chromecast plugin bindings.
         */
        addBindings: function () {
            this.bind( 'chromecastError', this.launchError.bind( this ) );
            this.bind( 'castSessionEnded', this.switchToLocalPlayer.bind( this ) );
        },

        /**
         * Handles the Chromecast player button when receiver is discovered.
         * @param isAvailable
         * @param reason
         */
        toggleCastButton: function ( isAvailable, reason ) {
            this.log( "toggleCastButton: isAvailable=" + isAvailable + ", reason=" + reason );
            if ( isAvailable ) {
                this.initializeCastApi();
                this.show();
            } else {
                this.hide();
            }
        },

        /**
         * Initialize the cast framework.
         * 1) Defines the application id of the receiver.
         * 2) Check if a session is already opened.
         */
        initializeCastApi: function () {
            try {
                window.chrome = this.isInIframeApi ? window.chrome : top.chrome;
                window.cast = this.isInIframeApi ? window.cast : top.cast;
            } catch (e) {
                this.log( "Error: unable to initialize cast API");
                return;
            }

            var options = {};
            options.receiverApplicationId = this.getConfig( "applicationID" ).toString();
            options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;
            cast.framework.CastContext.getInstance().setOptions( options );

            this.sessionStateChangedCallback = this.onSessionStateChanged.bind(this);
            this.toggleSessionStateChangedListener(true);

            this.remotePlayer = new cast.framework.RemotePlayer();
            this.remotePlayerController = new cast.framework.RemotePlayerController( this.remotePlayer );
        },

        isSafeEnviornment: function () {
            return mw.isChrome();
        },

        /**
         * Responsible for the logic which happens when we clicking the cast button.
         * @returns {boolean}
         */
        toggleCast: function () {
            this.toggleSessionStateChangedListener(false);
            this.log( "toggleCast: isDisabled=" + this.isDisabled + ", isCasting=" + this.casting );
            if ( this.isDisabled ) {
                return false;
            }
            // If we're casting - disconnect
            if ( this.casting ) {
                this.switchToLocalPlayer();
            } else {
                // If we're not - connect
                this.showConnectingMessage();
                this.embedPlayer.disablePlayControls( [ "chromecast" ] );
                cast.framework.CastContext.getInstance().requestSession().then(
                    this.switchToRemotePlayer.bind( this ),
                    this.launchError.bind( this )
                );
            }
        },

        onSessionStateChanged: function (event) {
            var sessionState = event.sessionState;
            switch (sessionState) {
                case cast.framework.SessionState.SESSION_RESUMED: {
                    this.switchToRemotePlayer();
                    break;
                }
                case cast.framework.SessionState.SESSION_STARTED: {
                    if (!this.casting) {
                        this.showConnectingMessage();
                        this.embedPlayer.disablePlayControls(["chromecast"]);
                        this.switchToRemotePlayer();
                    }
                    break;
                }
                case cast.framework.SessionState.SESSION_ENDED: {
                    if (this.casting) {
                        this.switchToLocalPlayer();
                    }
                    break;
                }
                default:
                    break;
            }
        },

        toggleSessionStateChangedListener: function (enable) {
            if (enable) {
                cast.framework.CastContext.getInstance().addEventListener(cast.framework.CastContextEventType.SESSION_STATE_CHANGED, this.sessionStateChangedCallback);
            } else {
                cast.framework.CastContext.getInstance().removeEventListener(cast.framework.CastContextEventType.SESSION_STATE_CHANGED, this.sessionStateChangedCallback);
            }
        },

        /**
         * Returning the cast button ui.
         */
        getComponent: function () {
            if ( !this.$el ) {
                this.$el = $( '<button/>' )
                    .attr( 'title', this.startCastTitle )
                    .addClass( "btn icon-chromecast" + this.getCssClass() )
                    .click( this.toggleCast.bind( this ) );
            }
            return this.$el;
        },

        /**
         * After cast session has opened, switch to Chromecast player and save the old one.
         */
        switchToRemotePlayer: function () {
            this.log( "switchToChromecastPlayer" );
            var _this = this;
            var playbackParams = this.getEmbedPlayerPlaybackParams();
            this.casting = true;
            this.embedPlayer.casting = true;
            $( this.embedPlayer ).trigger( 'casting', true );
            this.savedPlayer = this.embedPlayer.selectedPlayer;
            this.embedPlayer.clean();
            this.embedPlayer.selectPlayer( mw.EmbedTypes.mediaPlayers.getPlayerById( 'chromecast' ) );
            this.embedPlayer.updatePlaybackInterface( function () {
                _this.embedPlayer.layoutBuilder.closeAlert();
                _this.getComponent().css( "color", "#35BCDA" );
                _this.updateTooltip( _this.stopCastTitle );
                _this.showLoadingMessage();
                _this.embedPlayer.setupRemotePlayer( _this.remotePlayer, _this.remotePlayerController, playbackParams );
                _this.toggleSessionStateChangedListener(true);
            } );
        },

        /**
         * Gets the current playback data.
         * @returns {{currentTime: *, duration: *, volume: (*|Float)}}
         */
        getEmbedPlayerPlaybackParams: function () {
            var playbackParams= {
                currentTime: this.embedPlayer.getPlayerElementTime(),
                duration: this.embedPlayer.getDuration(),
                volume: this.embedPlayer.getPlayerElementVolume(),
                state: this.embedPlayer.currentState,
                captions: null
            };
            if (this.embedPlayer.plugins && this.embedPlayer.plugins.closedCaptions){
                playbackParams.captions = this.embedPlayer.plugins.closedCaptions.selectedSource;
            }
            return playbackParams;
        },

        /**
         * After cast session has been closed, switch to the player that was active before casting.
         */
        switchToLocalPlayer: function () {
            this.log( "switchToSavedPlayer" );
            var _this = this;
            var seekTo = this.embedPlayer.currentTime;
            var stopAfterSeek = (this.embedPlayer.currentState === "pause");
            this.casting = false;
            $( this.embedPlayer ).trigger( 'casting', false );
            this.embedPlayer.shutdownRemotePlayer();
            this.getComponent().css( "color", "white" );
            this.updateTooltip( this.startCastTitle );
            this.embedPlayer.getInterface().find( ".chromecastScreen" ).remove();
            this.embedPlayer.selectPlayer( this.savedPlayer );
            this.embedPlayer.casting = false;
            this.embedPlayer.updatePlaybackInterface( function () {
                _this.embedPlayer.addPlayerSpinner();
                _this.embedPlayer.seek( seekTo, stopAfterSeek );
                _this.toggleSessionStateChangedListener(true);
            } );
        },

        /**
         * Launch an error and restoring the player ui.
         * @param errorCode
         */
        launchError: function ( errorCode ) {
            this.log( "launchError: " + this.getErrorMessage( errorCode ) );
            this.embedPlayer.layoutBuilder.closeAlert();
            this.embedPlayer.enablePlayControls();
            this.toggleSessionStateChangedListener(true);
        },

        /**
         * Gets a human readable error message based on the errorCode which cast sdk provides.
         * @param errorCode
         * @returns {*}
         */
        getErrorMessage: function ( errorCode ) {
            this.log( "getErrorMessage: errorCode=" + errorCode );
            switch ( errorCode ) {
                case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
                    return 'The API is not initialized.';
                case chrome.cast.ErrorCode.CANCEL:
                    return 'The operation was canceled by the user';
                case chrome.cast.ErrorCode.CHANNEL_ERROR:
                    return 'A channel to the receiver is not available.';
                case chrome.cast.ErrorCode.EXTENSION_MISSING:
                    return 'The Cast extension is not available.';
                case chrome.cast.ErrorCode.INVALID_PARAMETER:
                    return 'The parameters to the operation were not valid.';
                case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
                    return 'No receiver was compatible with the session request.';
                case chrome.cast.ErrorCode.SESSION_ERROR:
                    return 'A session could not be created, or a session was invalid.';
                case chrome.cast.ErrorCode.TIMEOUT:
                    return 'The operation timed out.';
            }
        },

        /**
         * Displays connecting message on the player ui.
         */
        showConnectingMessage: function () {
            this.displayMessage( gM( 'mwe-chromecast-connecting' ) );
        },

        /**
         * Displays loading message on the player ui.
         */
        showLoadingMessage: function () {
            this.displayMessage( gM( 'mwe-chromecast-loading' ) );
        },

        /**
         * Displays a certain message on the player ui.
         * @param msg
         */
        displayMessage: function ( msg ) {
            this.embedPlayer.layoutBuilder.displayAlert( {
                    'title': 'Chromecast Player',
                    'message': msg,
                    'isModal': true,
                    'keepOverlay': true,
                    'noButtons': true,
                    'isError': true,
                    'props': {
                        'customAlertContainerCssClass': 'connectingMsg',
                        'customAlertTitleCssClass': 'hidden',
                        'textColor': '#ffffff'
                    }
                }
            );
        }
    } ) );
})( window.mw, window.jQuery );
<|endoftext|>


<commit_before>/*!
 * Edit Row Form v1.0
 * Docs & License: http://coreleo.com/editrowform/
 * (c) 2015 Leon Samaroo
 */

!function(root, factory) {
	if (typeof define === 'function' && define.amd) {
		define([ 'jquery' ], factory);
	}
	else {
		factory(root.jQuery);
	}
}( this,

		function($){

		    // Add plugin to JQuery
		    $.fn.editrowform = function(options){
		    	var args = Array.prototype.slice.call(arguments, 1); // for a possible method call
		    	var ret = this; // what this function will return (this jQuery object by default)
		    	var singleRes; // the returned value of this single method call

		        this.each(function(i, el){
		        	var element = $(el);
			    	var thisplugin = element.data('editrowform'); // get the existing plugin object (if any)

					// a method call
					if (typeof options === 'string') {
						if (thisplugin && $.isFunction(thisplugin[options])) {
							singleRes = thisplugin[options].apply(thisplugin, args);
							if (!i) {
								ret = singleRes; // record the first method call result
							}
						}
					}
					// a new plugin initialization
					else {
						thisplugin = (new $.editrowform(el, options));
						thisplugin.init();
					}
		        });

		        return ret;
		    };

		    // Plugin definition
		    $.editrowform = function(el, options){
		        // To avoid scope issues, use 'base' instead of 'this'
		        // to reference this class from internal events and functions.
		        var base = this;

		        // Access to jQuery and DOM versions of element
		        base.$el = $(el);
		        base.el = el;

		        base.init = function(){
			        // Add a reverse reference to the DOM object
			        base.$el.data("editrowform", base);
		            base.options = $.extend({},$.editrowform.defaultOptions, options);
		            rowCount =  getRowCount();
		            colCount =  getColumnCount();
		            build();

		            if( getOptions().doubleClick ){
		            	$( "tr", base.el ).dblclick( function(e){
		            		base.show( $(this).index() );
		            	});
		            }
		        };

				base.show = function(rowIndex){
					if( formDiv != null ){
						formDiv.show();
						setFormValues(rowIndex);
					}

				};

				base.hide = function(rowIndex){
					if( formDiv != null ){
						formDiv.hide();
					}

				};

				base.destroy = function(){
					 base.$el.removeData( "editrowform" );
				};

				//private variables
		        var rowCount = 0;
		        var colCount = 0;
		        var formDiv = null;

				// private functions
				function getOptions(){
					return base.options;
				};

				function getRow( rowIndex ){
					return $( 'tbody tr', base.el ).eq( rowIndex );
				};

				function getCellValue( rowIndex, colIndex, row ){
					var cell = $( 'td', row )[colIndex];

					if( util.functionExists( getOptions().getCellValue ) ){
						return getOptions().getCellValue( rowIndex, colIndex, cell );
					}
					else{
						return $(cell).html().trim();
					}

					return base.getCellValue( rowIndex, colIndex, cell );
				};

				function getColumnCount(){
					return $( 'td', getRow(0) ).length;
				};

				function getRowCount(){
					return $( 'tbody tr', base.el ).length;
				};

				function setFormValues(rowIndex){
					var row = getRow( rowIndex );
					for( var i = 0; i < colCount; i++ ){
						var value = getCellValue( rowIndex, i, row );
						$( "#" + idGen.getInputId( i ) ).val( value );
					}
				};

				function build(){
					var div = $( template.div );
					div.attr( "id", idGen.getEditRowFormId() );
					div.addClass( "erf" );
					div.appendTo( document.body );

					var form = buildForm();
					form.appendTo( div );
				};

				function buildForm(){
					var div = $( template.div );
					div.attr( "id", idGen.getFormId() );
					div.addClass( "form" );
					div.hide();

					var row = buildFormRow();
					row.appendTo( div );
					return div;
				};

				function buildFormRow(){
					var div = $( template.div );
					div.attr( "id", idGen.getFormRowId() );
					div.addClass( "row" );

					var cell = null;
					for( var i = 0; i < colCount; i++ ){
						cell =  buildFormCell( i );
						cell.appendTo( div );
					}
					return div;
				};

				function buildFormCell(colIndex){
					var div = $( template.div );
					div.attr( "id", idGen.getFormCellId( colIndex ) );
					div.addClass( "cell" );
					var input = getInput( colIndex );
					input.appendTo( div );
					return div;
				};

				function getColumnType(colIndex){
					return "text";
				};

				function getInput( colIndex ){
					var input = null;
					var inputId = idGen.getInputId(colIndex);
					var colType = getColumnType( colIndex );

					if( colType == "checkbox" ){
						input = $( template.checkbox );
					}
					else {
						input = $( template.textfield );
					}

					input.attr( "id", inputId );
					return input;
				};

				var idGen = {
						idPrefix: "erf-",

						getEditRowFormId: function( colIndex ){
							var id = options.id;
							if( util.isEmpty( id ) ){
								id = base.el.id;
							}

							if( util.isEmpty( id ) ){
								id = "defaultid";
							}
							return this.idPrefix + id;
						},

						getInputId: function( colIndex ){
							return this.getEditRowFormId() + "-input" + colIndex;
						},

						getFormCellId: function( colIndex ){
							return this.getEditRowFormId() + "-cell-" + colIndex;
						},

						getFormRowId: function( ){
							return this.getEditRowFormId() + "-row";
						},

						getFormId: function( ){
							return this.getEditRowFormId() + "-form";
						}
				};

				var util = {
						functionExists: function( myFunc ){
							return typeof myfunc !== 'undefined' && $.isFunction(myfunc);
						},

						isEmpty: function( text ){
							return (
									 text == null || text === null ||
									 text === undefined ||
									 $.trim(text) == 'null' ||
									 $.trim(text) == ''
								   );
						},

						getTableWidth: function( table ){
							return $(table).width();
						}
				};

				var template = {
						div: "<div />",
						textfield: "<input type='text' />",
						checkbox: "<input type='checkbox' />"
				};

		    };

			// Default options
		    $.editrowform.defaultOptions = {
		    		id: "",
		    		doubleClick: true,
		    		getCellValue: ""
		    };

		}

);<commit_msg>Add columns property to options to set column attributes.<commit_after>/*!
 * Edit Row Form v1.0
 * Docs & License: http://coreleo.com/editrowform/
 * (c) 2015 Leon Samaroo
 */

!function(root, factory) {
	if (typeof define === 'function' && define.amd) {
		define([ 'jquery' ], factory);
	}
	else {
		factory(root.jQuery);
	}
}( this,

		function($){

		    // Add plugin to JQuery
		    $.fn.editrowform = function(options){
		    	var args = Array.prototype.slice.call(arguments, 1); // for a possible method call
		    	var ret = this; // what this function will return (this jQuery object by default)
		    	var singleRes; // the returned value of this single method call

		        this.each(function(i, el){
		        	var element = $(el);
			    	var thisplugin = element.data('editrowform'); // get the existing plugin object (if any)

					// a method call
					if (typeof options === 'string') {
						if (thisplugin && $.isFunction(thisplugin[options])) {
							singleRes = thisplugin[options].apply(thisplugin, args);
							if (!i) {
								ret = singleRes; // record the first method call result
							}
						}
					}
					// a new plugin initialization
					else {
						thisplugin = (new $.editrowform(el, options));
						thisplugin.init();
					}
		        });

		        return ret;
		    };

		    // Plugin definition
		    $.editrowform = function(el, options){
		        // To avoid scope issues, use 'base' instead of 'this'
		        // to reference this class from internal events and functions.
		        var base = this;

		        // Access to jQuery and DOM versions of element
		        base.$el = $(el);
		        base.el = el;

		        base.init = function(){
			        // Add a reverse reference to the DOM object
			        base.$el.data("editrowform", base);
		            base.options = $.extend({},$.editrowform.defaultOptions, options);
		            rowCount =  getRowCount();
		            colCount =  getColumnCount();

		            build();

		            // add listeners
		            if( base.options.doubleClick ){
		            	$( "tr", base.el ).dblclick( function(e){
		            		base.show( $(this).index() );
		            	});
		            }
		        };

				base.show = function(rowIndex){
					if( formDiv != null ){
						formDiv.show();
						setFormValues(rowIndex);
					}

				};

				base.hide = function(rowIndex){
					if( formDiv != null ){
						formDiv.hide();
					}

				};

				base.destroy = function(){
					 base.$el.removeData( "editrowform" );
				};

				// ---------------------------------------
				// private variables and functions
				// ---------------------------------------
		        var rowCount = 0;
		        var colCount = 0;
		        var formDiv = null;
		        var columnMap = {};

				// private functions
		        function buildColumnMap(){
		            var columns = base.options.columns;
		        	var i = 0;
		        	var col = null;

		            if( !util.isEmpty( columns ) && $.isArray(columns) ){
		            	col = columns[i];
		            	if( !util.isEmpty( col ) ){
		            		columnMap[i] = col;
		            	}
		            	else{
		            		columnMap[i] = $(base.options.defaultColumn).clone();
		            	}
		            }
		            else{
		            	for( i = 0; i < getColumnCount(); i++ ){
		            		columnMap[i] = util.clone(base.options.defaultColumn);
		            	}
		            }
		        };

				function getOptions(){
					return base.options;
				};

				function getRow( rowIndex ){
					return $( 'tbody tr', base.el ).eq( rowIndex );
				};

				function getCellValue( rowIndex, colIndex, row ){
					var cell = $( 'td', row )[colIndex];

					if( util.functionExists( getOptions().getCellValue ) ){
						return getOptions().getCellValue( rowIndex, colIndex, cell );
					}
					else{
						return $(cell).html().trim();
					}

					return base.getCellValue( rowIndex, colIndex, cell );
				};

				function getColumnCount(){
					return $( 'td', getRow(0) ).length;
				};

				function getRowCount(){
					return $( 'tbody tr', base.el ).length;
				};

				function setFormValues(rowIndex){
					var row = getRow( rowIndex );
					for( var i = 0; i < colCount; i++ ){
						var value = getCellValue( rowIndex, i, row );
						$( "#" + idGen.getInputId( i ) ).val( value );
					}
				};

				function build(){
					buildColumnMap();
					buildForm();
				};

				function buildForm(){
					var div = $( template.div );
					div.attr( "id", idGen.getEditRowFormId() );
					div.addClass( "erf" );
					div.hide();
					div.appendTo( document.body );

					var form = $( template.form );
					form.attr( "id", idGen.getFormId() );
					form.addClass( "form" );
					form.appendTo( div );

					var row = buildFormRow();
					row.appendTo( form );

					formDiv = div;
				};

				function buildFormRow(){
					var div = $( template.div );
					div.attr( "id", idGen.getFormRowId() );
					div.addClass( "row" );

					var cell = null;
					for( var i = 0; i < colCount; i++ ){
						cell =  buildFormCell( i );
						cell.appendTo( div );
					}
					return div;
				};

				function buildFormCell(colIndex){
					var div = $( template.div );
					div.attr( "id", idGen.getFormCellId( colIndex ) );
					div.addClass( "cell" );
					var input = getInput( colIndex );
					input.appendTo( div );
					return div;
				};

				function getColumnType(colIndex){
					return "text";
				};

				function getInput( colIndex ){
					var input = null;
					var inputId = idGen.getInputId(colIndex);
					var colType = getColumnType( colIndex );

					if( colType == "checkbox" ){
						input = $( template.checkbox );
					}
					else {
						input = $( template.textfield );
					}

					input.attr( "id", inputId );
					return input;
				};

				var idGen = {
						idPrefix: "erf-",

						getEditRowFormId: function( colIndex ){
							var id = options.id;
							if( util.isEmpty( id ) ){
								id = base.el.id;
							}

							if( util.isEmpty( id ) ){
								id = "defaultid";
							}
							return this.idPrefix + id;
						},

						getInputId: function( colIndex ){
							return this.getEditRowFormId() + "-input" + colIndex;
						},

						getFormCellId: function( colIndex ){
							return this.getEditRowFormId() + "-cell-" + colIndex;
						},

						getFormRowId: function( ){
							return this.getEditRowFormId() + "-row";
						},

						getFormId: function( ){
							return this.getEditRowFormId() + "-form";
						}
				};

				var util = {
						functionExists: function( myFunc ){
							return typeof myfunc !== 'undefined' && $.isFunction(myfunc);
						},

						isEmpty: function( text ){
							return (
									 text == null || text === null ||
									 text === undefined ||
									 $.trim(text) == 'null' ||
									 $.trim(text) == ''
								   );
						},

						getTableWidth: function( table ){
							return $(table).width();
						},

						clone: function( obj ){
							return $.extend(true, {}, obj);
						}
				};

				var template = {
						div: "<div />",
						form: "<form />",
						textfield: "<input type='text' />",
						checkbox: "<input type='checkbox' />"
				};

		    };

			// Default options
		    $.editrowform.defaultOptions = {
		    		id: "",
		    		columns: "",
		    		defaultColumn: {
		    			colType: "text",
		    			editable: true
		    		},
		    		doubleClick: true,
		    		getCellValue: ""
		    };

		}

);<|endoftext|>


<commit_before>var cv = require('../lib/opencv');

cv.readImage("./mona.png", function(err, im) {
  if (err) throw err;

  var width = im.width();
  var height = im.height();
  if (width < 1 || height < 1) throw new Error('Image has no size');

  var srcArray = [0, 0, width, 0, width, height, 0, height];
  var dstArray = [0, 0, width * 0.9, height * 0.1, width, height, width * 0.2, height * 0.8];
  var xfrmMat = im.getPerspectiveTransform(srcArray, dstArray);
  im.warpPerspective(xfrmMat, width, height, [255, 255, 255]);
  im.save("./warp-image.png");
  console.log('Image saved to ./tmp/warp-image.png');
});
<commit_msg>fix warp image example<commit_after>var cv = require('../lib/opencv');

cv.readImage("./examples/files/mona.png", function(err, im) {
  if (err) throw err;

  var width = im.width();
  var height = im.height();
  if (width < 1 || height < 1) throw new Error('Image has no size');

  var srcArray = [0, 0, width, 0, width, height, 0, height];
  var dstArray = [0, 0, width * 0.9, height * 0.1, width, height, width * 0.2, height * 0.8];
  var xfrmMat = im.getPerspectiveTransform(srcArray, dstArray);
  im.warpPerspective(xfrmMat, width, height, [255, 255, 255]);
  im.save("./examples/tmp/warp-image.png");
  console.log('Image saved to ./tmp/warp-image.png');
});
<|endoftext|>


<commit_before>( function () {
    'use strict';

    var OSG = window.OSG;
    var osg = OSG.osg;
    var osgDB = OSG.osgDB;
    var osgUtil = OSG.osgUtil;
    var osgGA = OSG.osgGA;
    var ExampleOSGJS = window.ExampleOSGJS;
    var Hammer = window.Hammer;
    var $ = window.$;

    var Example = function () {

        ExampleOSGJS.call( this );

        $( '#button-enter-fullscreen' ).click( function () {
            this.requestFullScreenVR();
        }.bind( this ) );

        $( '#button-exit-fullscreen' ).click( function () {
            this.exitFullScreenVR();
        }.bind( this ) );

    };

    Example.prototype = osg.objectInherit( ExampleOSGJS.prototype, {

        run: function () {

            ExampleOSGJS.prototype.run.call( this );

            if ( window.screenfull ) {
                document.addEventListener( window.screenfull.raw.fullscreenchange, function () {
                    console.log( 'toggle VR mode' );
                    this.toggleVR();
                }.bind( this ) );
            }

        },

        toggleVR: function () {

            var viewer = this._viewer;

            viewer.setPresentVR( !this._vrState ).then(
                function () {
                    // Enable VR
                    if ( !this._vrState ) {

                        // Detach the model from scene and cache it
                        this.getRootNode().removeChild( this._modelNode );

                        // If no vrNode (first time vr is toggled), create one
                        // The modelNode will be attached to it
                        if ( !this._vrNode ) {
                            if ( navigator.getVRDisplays ) {

                                viewer.getEventProxy().WebVR.setEnable( true );
                                this._vrNode = osgUtil.WebVR.createScene( viewer, this._modelNode, viewer._eventProxy.WebVR.getHmd() );

                            } else {

                                viewer.getEventProxy().DeviceOrientation.setEnable( true );
                                this._vrNode = osgUtil.WebVRCustom.createScene( viewer, this._modelNode, {
                                    isCardboard: true,
                                    vResolution: this._canvas.height,
                                    hResolution: this._canvas.width
                                } );

                            }
                        }

                        // Attach the vrNode to scene instead of the model
                        this.getRootNode().addChild( this._vrNode );

                        $( '#button-enter-fullscreen' ).hide();
                        $( '#button-exit-fullscreen' ).show();
                    } else {

                        // Disable VR
                        viewer._eventProxy.WebVR.setEnable( false );
                        viewer._eventProxy.DeviceOrientation.setEnable( false );
                        // Detach the vrNode and reattach the modelNode
                        this.getRootNode().removeChild( this._vrNode );
                        this.getRootNode().addChild( this._modelNode );

                        $( '#button-enter-fullscreen' ).show();
                        $( '#button-exit-fullscreen' ).hide();
                    }

                    this._vrState = !this._vrState;

                }.bind( this ) );
        },

        requestFullScreenVR: function () {

            if ( !navigator.getVRDisplays && window.screenfull ) {
                window.screenfull.request( this._canvas );

            } else {
                // no fullscreen use the canvas or webvr
                this.toggleVR();
            }

            $( '#button-enter-fullscreen' ).hide();
            $( '#button-exit-fullscreen' ).show();
        },

        exitFullScreenVR: function () {

            if ( !navigator.getVRDisplays && window.screenfull ) {
                window.screenfull.exit();
            } else {
                this.toggleVR();
            }
        },

        initFullscreenEvent: function () {

            if ( window.screenfull && window.screenfull.enabled ) {
                document.addEventListener( window.screenfull.raw.fullscreenchange, function () {
                    console.log( 'Am I fullscreen? ' + ( window.screenfull.isFullscreen ? 'Yes' : 'No' ) );
                    this.toggleVR();
                } );
            }
        },

        createScene: function () {

            var root = new osg.MatrixTransform();
            this._modelNode = root;
            osg.mat4.fromRotation( root.getMatrix(), Math.PI, [ 0, 0, 1 ] );

            osgDB.readNodeURL( '../media/models/material-test/file.osgjs' ).then( function ( model ) {
                root.addChild( model );

                // setup manipulator
                // disable easing for VR
                var manipulator = this._viewer.getManipulator();

                manipulator.setDelay( 1.0 );
                // it's not really clear how the controllers are overriding (or not) the
                // delay property of the manipulators
                var ctrls = manipulator._controllerList;
                var ctrlNames = Object.keys( ctrls );
                for ( var i = 0, nbCtrlNames = ctrlNames.length; i < nbCtrlNames; ++i ) {
                    var ct = ctrls[ ctrlNames[ i ] ];
                    if ( ct._delay !== undefined )
                        ct._delay = 1.0;
                }

                manipulator.setNode( root );
                manipulator.computeHomePosition();

            }.bind( this ) );

            this.getRootNode().addChild( root );
            this._manipulator = new osgGA.FirstPersonManipulator();
            this._viewer.setManipulator( this._manipulator );

            this.initTouch();

        },

        touch: function ( e ) {
            // assume the first touch in the 1/4 of the top canvas is a google cardboard touch
            console.log( 'cardboard touch' );
            this._manipulator.getForwardInterpolator().setTarget( 1 );
        },

        unTouch: function ( e ) {
            console.log( 'cardboard unTouch' );
            this._manipulator.getForwardInterpolator().setTarget( 0 );
        },

        initTouch: function () {
            this._canvas.addEventListener( 'touchstart', this.touch.bind( this ), false );
            this._canvas.addEventListener( 'touchend', this.unTouch.bind( this ), false );
        }

    } );

    window.addEventListener( 'load', function () {
        var example = new Example();
        example.run();
        window.example = example;
    }, true );

} )();
<commit_msg>Fixes webvr example<commit_after>( function () {
    'use strict';

    var OSG = window.OSG;
    var osg = OSG.osg;
    var osgDB = OSG.osgDB;
    var osgUtil = OSG.osgUtil;
    var osgGA = OSG.osgGA;
    var ExampleOSGJS = window.ExampleOSGJS;
    var $ = window.$;

    var Example = function () {

        ExampleOSGJS.call( this );

        $( '#button-enter-fullscreen' ).click( function () {
            this.requestFullScreenVR();
        }.bind( this ) );

        $( '#button-exit-fullscreen' ).click( function () {
            this.exitFullScreenVR();
        }.bind( this ) );

    };

    Example.prototype = osg.objectInherit( ExampleOSGJS.prototype, {

        run: function () {

            ExampleOSGJS.prototype.run.call( this );

            if ( window.screenfull ) {
                document.addEventListener( window.screenfull.raw.fullscreenchange, function () {
                    console.log( 'toggle VR mode' );
                    this.toggleVR();
                }.bind( this ) );
            }

        },

        switchVR: function () {

            var viewer = this._viewer;

            // Enable VR
            if ( !this._vrState ) {

                // Detach the model from scene and cache it
                this.getRootNode().removeChild( this._modelNode );

                // If no vrNode (first time vr is toggled), create one
                // The modelNode will be attached to it
                if ( !this._vrNode ) {
                    if ( navigator.getVRDisplays ) {

                        viewer.getEventProxy().WebVR.setEnable( true );
                        this._vrNode = osgUtil.WebVR.createScene( viewer, this._modelNode, viewer._eventProxy.WebVR.getHmd() );

                    } else {

                        viewer.getEventProxy().DeviceOrientation.setEnable( true );
                        this._vrNode = osgUtil.WebVRCustom.createScene( viewer, this._modelNode, {
                            isCardboard: true,
                            vResolution: this._canvas.height,
                            hResolution: this._canvas.width
                        } );

                    }
                }

                // Attach the vrNode to scene instead of the model
                this.getRootNode().addChild( this._vrNode );

                $( '#button-enter-fullscreen' ).hide();
                $( '#button-exit-fullscreen' ).show();
            } else {

                // Disable VR
                viewer._eventProxy.WebVR.setEnable( false );
                viewer._eventProxy.DeviceOrientation.setEnable( false );
                // Detach the vrNode and reattach the modelNode
                this.getRootNode().removeChild( this._vrNode );
                this.getRootNode().addChild( this._modelNode );

                $( '#button-enter-fullscreen' ).show();
                $( '#button-exit-fullscreen' ).hide();
            }

            this._vrState = !this._vrState;
        },

        toggleVR: function () {

            var viewer = this._viewer;
            if ( viewer.getVRDisplay() ) viewer.setPresentVR( !this._vrState ).then( this.switchVR.bind( this ) );
            else this.switchVR();
        },

        requestFullScreenVR: function () {

            if ( !navigator.getVRDisplays && window.screenfull ) {
                window.screenfull.request( this._canvas );

            } else {
                // no fullscreen use the canvas or webvr
                this.toggleVR();
            }

            $( '#button-enter-fullscreen' ).hide();
            $( '#button-exit-fullscreen' ).show();
        },

        exitFullScreenVR: function () {

            if ( !navigator.getVRDisplays && window.screenfull ) {
                window.screenfull.exit();
            } else {
                this.toggleVR();
            }
        },

        initFullscreenEvent: function () {

            if ( window.screenfull && window.screenfull.enabled ) {
                document.addEventListener( window.screenfull.raw.fullscreenchange, function () {
                    console.log( 'Am I fullscreen? ' + ( window.screenfull.isFullscreen ? 'Yes' : 'No' ) );
                    this.toggleVR();
                } );
            }
        },

        createScene: function () {

            var root = new osg.MatrixTransform();
            this._modelNode = root;
            osg.mat4.fromRotation( root.getMatrix(), Math.PI, [ 0, 0, 1 ] );

            osgDB.readNodeURL( '../media/models/material-test/file.osgjs' ).then( function ( model ) {
                root.addChild( model );

                // setup manipulator
                // disable easing for VR
                var manipulator = this._viewer.getManipulator();

                manipulator.setDelay( 1.0 );
                // it's not really clear how the controllers are overriding (or not) the
                // delay property of the manipulators
                var ctrls = manipulator._controllerList;
                var ctrlNames = Object.keys( ctrls );
                for ( var i = 0, nbCtrlNames = ctrlNames.length; i < nbCtrlNames; ++i ) {
                    var ct = ctrls[ ctrlNames[ i ] ];
                    if ( ct._delay !== undefined )
                        ct._delay = 1.0;
                }

                manipulator.setNode( root );
                manipulator.computeHomePosition();

            }.bind( this ) );

            this.getRootNode().addChild( root );
            this._manipulator = new osgGA.FirstPersonManipulator();
            this._viewer.setManipulator( this._manipulator );

            this.initTouch();

        },

        touch: function ( /*e*/) {
            // assume the first touch in the 1/4 of the top canvas is a google cardboard touch
            console.log( 'cardboard touch' );
            this._manipulator.getForwardInterpolator().setTarget( 1 );
        },

        unTouch: function ( /*e*/) {
            console.log( 'cardboard unTouch' );
            this._manipulator.getForwardInterpolator().setTarget( 0 );
        },

        initTouch: function () {
            this._canvas.addEventListener( 'touchstart', this.touch.bind( this ), false );
            this._canvas.addEventListener( 'touchend', this.unTouch.bind( this ), false );
        }

    } );

    window.addEventListener( 'load', function () {
        var example = new Example();
        example.run();
        window.example = example;
    }, true );

} )();
<|endoftext|>


<commit_before>import constants from '../misc/constants'
import { axisTop, axisLeft, axisRight, axisBottom } from 'd3-axis'
import { format } from 'd3-format'

export default class Axis {
  label = ''
  top = 0
  left = 0
  scale = null
  orientation = 'bottom'
  axisObject = null
  compact = false
  buffer = 0
  isVertical = false

  constructor ({
    orientation,
    label,
    top,
    left,
    scale,
    tickFormat,
    tickCount,
    compact,
    buffer
  }) {
    // cry if no scale is set
    if (!scale) throw new Error('an axis needs a scale')

    this.scale = scale
    this.label = label ?? this.label
    this.buffer = buffer ?? this.buffer
    this.top = top ?? this.top
    this.left = left ?? this.left
    this.orientation = orientation ?? this.orientation
    this.compact = compact ?? this.compact
    this.isVertical = [constants.axisOrientation.left, constants.axisOrientation.right].includes(this.orientation)

    this.setupAxisObject()

    // set or compute tickFormat
    this.tickFormat = tickFormat ?? format('.0f') // TODO
    this.tickCount = tickCount ?? (this.isVertical ? 3 : 6)
  }

  setupAxisObject () {
    switch (this.orientation) {
      case constants.axisOrientation.top:
        this.axisObject = axisTop(this.scale.scaleObject)
        break
      case constants.axisOrientation.left:
        this.axisObject = axisLeft(this.scale.scaleObject)
        break
      case constants.axisOrientation.right:
        this.axisObject = axisRight(this.scale.scaleObject)
        break
      default:
        this.axisObject = axisBottom(this.scale.scaleObject)
        break
    }
  }

  domainObject () {
    let x1 = 0
    let y1 = 0
    let x2 = 0
    let y2 = 0
    if (this.isVertical) {
      x1 = 0.5
      x2 = 0.5
      y1 = this.compact ? this.top + 0.5 : 0.5
      y2 = this.compact
        ? this.scale.range[0] + 0.5
        : this.scale.range[0] + 2 * this.buffer + 0.5
    } else {
      x1 = this.compact ? this.buffer : 0
      x2 = this.compact
        ? this.scale.range[1]
        : this.scale.range[1] + 2 * this.buffer
    }
    return g => g
      .append('line')
      .classed('domain', true)
      .attr('x1', x1)
      .attr('x2', x2)
      .attr('y1', y1)
      .attr('y2', y2)
  }

  mountTo (svg) {
    const innerLeft = this.isVertical ? 0 : this.buffer
    const innerTop = this.isVertical ? this.buffer : 0
    const axisContainer = svg.append('g')
      .attr('transform', `translate(${this.left},${this.top})`)
      .classed('mg-axis', true)
      .call(this.domainObject())
    axisContainer
      .append('g')
      .attr('transform', `translate(${innerLeft},${innerTop})`)
      .call(this.axisObject)
      .call(g => g.select('.domain').remove())
  }

  set tickFormat (tickFormat) { this.axisObject.tickFormat(tickFormat) }
  set tickCount (tickCount) { this.axisObject.ticks(tickCount) }
}
<commit_msg>let d3 decide on the default axis format<commit_after>import constants from '../misc/constants'
import { axisTop, axisLeft, axisRight, axisBottom } from 'd3-axis'

export default class Axis {
  label = ''
  top = 0
  left = 0
  scale = null
  orientation = 'bottom'
  axisObject = null
  compact = false
  buffer = 0
  isVertical = false

  constructor ({
    orientation,
    label,
    top,
    left,
    scale,
    tickFormat,
    tickCount,
    compact,
    buffer
  }) {
    // cry if no scale is set
    if (!scale) throw new Error('an axis needs a scale')

    this.scale = scale
    this.label = label ?? this.label
    this.buffer = buffer ?? this.buffer
    this.top = top ?? this.top
    this.left = left ?? this.left
    this.orientation = orientation ?? this.orientation
    this.compact = compact ?? this.compact
    this.isVertical = [constants.axisOrientation.left, constants.axisOrientation.right].includes(this.orientation)

    this.setupAxisObject()

    // set or compute tickFormat
    if (tickFormat) this.tickFormat = tickFormat
    this.tickCount = tickCount ?? (this.isVertical ? 3 : 6)
  }

  setupAxisObject () {
    switch (this.orientation) {
      case constants.axisOrientation.top:
        this.axisObject = axisTop(this.scale.scaleObject)
        break
      case constants.axisOrientation.left:
        this.axisObject = axisLeft(this.scale.scaleObject)
        break
      case constants.axisOrientation.right:
        this.axisObject = axisRight(this.scale.scaleObject)
        break
      default:
        this.axisObject = axisBottom(this.scale.scaleObject)
        break
    }
  }

  domainObject () {
    let x1 = 0
    let y1 = 0
    let x2 = 0
    let y2 = 0
    if (this.isVertical) {
      x1 = 0.5
      x2 = 0.5
      y1 = this.compact ? this.top + 0.5 : 0.5
      y2 = this.compact
        ? this.scale.range[0] + 0.5
        : this.scale.range[0] + 2 * this.buffer + 0.5
    } else {
      x1 = this.compact ? this.buffer : 0
      x2 = this.compact
        ? this.scale.range[1]
        : this.scale.range[1] + 2 * this.buffer
    }
    return g => g
      .append('line')
      .classed('domain', true)
      .attr('x1', x1)
      .attr('x2', x2)
      .attr('y1', y1)
      .attr('y2', y2)
  }

  mountTo (svg) {
    const innerLeft = this.isVertical ? 0 : this.buffer
    const innerTop = this.isVertical ? this.buffer : 0
    const axisContainer = svg.append('g')
      .attr('transform', `translate(${this.left},${this.top})`)
      .classed('mg-axis', true)
      .call(this.domainObject())
    axisContainer
      .append('g')
      .attr('transform', `translate(${innerLeft},${innerTop})`)
      .call(this.axisObject)
      .call(g => g.select('.domain').remove())
  }

  set tickFormat (tickFormat) { this.axisObject.tickFormat(tickFormat) }
  set tickCount (tickCount) { this.axisObject.ticks(tickCount) }
}
<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

// Imported Components
import Post from '../components/Post';

// Imported Actions
import * as actions from '../actions/index';

const mapStateToProps = (state) => {
  return {
    posts: state.posts
  };
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators(actions, dispatch);
};

class Home extends React.Component {
  render() {
    // Post Loop
    const posts = this.props.posts.map((post, index) => <Post key={index} index={index} post={post} />);

    return (

          {posts}

    );
  }
}

// Proptype Validation
Home.propTypes = {
  posts: React.PropTypes.string
};

export default connect(mapStateToProps, mapDispatchToProps)(Home);
<commit_msg>Fixed bootstrap row forrendering children post components<commit_after>import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

// Imported Components
import Post from '../components/Post';

// Imported Actions
import * as actions from '../actions/index';

const mapStateToProps = (state) => {
  return {
    posts: state.posts
  };
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators(actions, dispatch);
};

class Home extends React.Component {
  render() {
    // Post Loop
    const posts = this.props.posts.map((post, index) => <Post key={index} index={index} post={post} />);

    return (

          {posts}

    );
  }
}

// Proptype Validation
Home.propTypes = {
  posts: React.PropTypes.string
};

export default connect(mapStateToProps, mapDispatchToProps)(Home);
<|endoftext|>


<commit_before>/**
 * Kaltura style analytics reporting class
 */
( function( mw, $ ) { "use strict";

// Avoid undefined symbol for javascript response "Kaltura" from the api
window['Kaltura'] = true;

// KAnalytics Constructor
mw.KAnalytics = function( embedPlayer ){
	this.init( embedPlayer );
};

// Add analytics to the embed player:
mw.addKAnalytics = function( embedPlayer ) {
	embedPlayer.kAnalytics = new mw.KAnalytics( embedPlayer );
}
mw.KAnalytics.prototype = {

	// Local reference to embedPlayer
	embedPlayer: null,

	// Report Set object
	reportSet : null,

	// Stores the last time we issued a seek event
	// avoids sending lots of seeks while scrubbing
	lastSeekEventTime: 0,

	bindPostFix: '.kAnalytics',

	// Start Time
	startReportTime: 0,

	kEventTypes : {
		'WIDGET_LOADED' : 1,
		'MEDIA_LOADED' : 2,
		'PLAY' : 3,
		'PLAY_REACHED_25' : 4,
		'PLAY_REACHED_50' : 5,
		'PLAY_REACHED_75' : 6,
		'PLAY_REACHED_100' : 7,
		'OPEN_EDIT' : 8,
		'OPEN_VIRAL' : 9,
		'OPEN_DOWNLOAD' : 10,
		'OPEN_REPORT' : 11,
		'BUFFER_START' : 12,
		'BUFFER_END' : 13,
		'OPEN_FULL_SCREEN' : 14,
		'CLOSE_FULL_SCREEN' : 15,
		'REPLAY' : 16,
		'SEEK' : 17,
		'OPEN_UPLOAD' : 18,
		'SAVE_PUBLISH' : 19,
		'CLOSE_EDITOR' : 20,
		'PRE_BUMPER_PLAYED' : 21,
		'POST_BUMPER_PLAYED' : 22,
		'BUMPER_CLICKED' : 23,
		'FUTURE_USE_1' : 24,
		'FUTURE_USE_2' : 25,
		'FUTURE_USE_3' : 26
	},

	/**
	 * Constructor for kAnalytics
	 *
	 * @param {Object}
	 *		  embedPlayer Player to apply Kaltura analytics to.
	 * @parma {Object}
	 * 			kalturaClient Kaltura client object for the api session.
	 */
	init: function( embedPlayer ) {
		// set the version of html5 player
		this.version = mw.getConfig( 'version' );
		// Setup the local reference to the embed player
		this.embedPlayer = embedPlayer;
		if( ! this.kClient ) {
			this.kClient = mw.kApiGetPartnerClient( embedPlayer.kwidgetid );
		}
		// Remove any old bindings:
		$( embedPlayer ).unbind( this.bindPostFix );

		// Setup the initial state of some flags
		this.resetPlayerflags();

		// Add relevant hooks for reporting beacons
		this.bindPlayerEvents();
	},
	resetPlayerflags:function(){
		this._p25Once = false;
		this._p50Once = false;
		this._p75Once = false;
		this._p100Once = false;
		this.hasSeeked = false;
		this.lastSeek = 0;
	},
	/**
	 * Get the current report set
	 *
	 * @param {Number}
	 *			KalturaStatsEventType The eventType number.
	 */
	sendAnalyticsEvent: function( KalturaStatsEventKey ){
		var _this = this;
		mw.log("KAnalytics :: doSendAnalyticsEvent > " + KalturaStatsEventKey );
		// Kalutra analytics does not collect info for ads:
		if( this.embedPlayer.evaluate('{sequenceProxy.isInSequence}') ){
			return ;
		}

		// get the id for the given event:
		var eventKeyId = this.kEventTypes[ KalturaStatsEventKey ];

		// Generate the status event
		var eventSet = {
			'eventType'			: eventKeyId,
			'clientVer'			: this.version,
			'currentPoint'		: parseInt( this.embedPlayer.currentTime * 1000 ),
			'duration'			: this.embedPlayer.getDuration(),
			'eventTimestamp'	: new Date().getTime(),
			'isFirstInSession'	: 'false',
			'objectType'		: 'KalturaStatsEvent',
			'partnerId'			: this.embedPlayer.kpartnerid,
			'sessionId'			: this.embedPlayer.evaluate('{configProxy.sessionId}'),
			'uiconfId'			: 0
		};
		if( isNaN( eventSet.duration )  ){
			eventSet.duration = 0;
		}

		// Set the seek condition:
		eventSet[ 'seek' ] = ( this.hasSeeked ) ? 'true' : 'false';

		// Set the 'event:entryId'
		if( this.embedPlayer.kentryid ){
			eventSet[ 'entryId' ] = this.embedPlayer.kentryid;
		} else {
			// if kentryid is not set, use the selected source url
			eventSet[ 'entryId' ] = this.embedPlayer.getSrc();
		}

		// Set the 'event:uiconfId'
		if( this.embedPlayer.kuiconfid ) {
			eventSet[ 'uiconfId' ] = this.embedPlayer.kuiconfid;
		}
		// Set the 'event:widgetId'
		if( this.embedPlayer.kwidgetid ) {
			eventSet[ 'widgetId' ] = this.embedPlayer.kwidgetid;
		}
		var flashVarEvents = {
				'playbackContext' : 'contextId',
				'originFeature' : 'featureType',
				'applicationName' : 'applicationId',
				'userId' : 'userId'
		}
		// support legacy ( deprecated ) top level config
		for( var fvKey in flashVarEvents){
			if( this.embedPlayer.getKalturaConfig( '', fvKey ) ){
				eventSet[ flashVarEvents[ fvKey ] ] = encodeURIComponent( this.embedPlayer.getKalturaConfig('', fvKey ) );
			}
		}
		// check for the vars in the correct location:
		for( var fvKey in flashVarEvents){
			if( this.embedPlayer.getKalturaConfig( 'statistics', fvKey ) ){
				eventSet[ flashVarEvents[ fvKey ] ] = encodeURIComponent( this.embedPlayer.getKalturaConfig('', fvKey ) );
			}
		}

		// Add referrer parameter
		eventSet[ 'referrer' ] = encodeURIComponent( mw.getConfig('EmbedPlayer.IframeParentUrl') );

		// Add in base service and action calls:
		var eventRequest = {'service' : 'stats', 'action' : 'collect'};
		// Add event parameters
		for( var i in eventSet){
			eventRequest[ 'event:' + i] = eventSet[i];
		}

		// Send events for this player:
		$( this.embedPlayer ).trigger( 'KalturaSendAnalyticEvent', [ KalturaStatsEventKey, eventSet ] );

		// check for defined callback:
		var parentTrackName = this.embedPlayer.getKalturaConfig( 'statistics', 'trackEventMonitor');
		if(  mw.getConfig('EmbedPlayer.IsFriendlyIframe') ){
			try {
				if( window.parent[ parentTrackName ] ){
					 window.parent[ parentTrackName ]( KalturaStatsEventKey, eventSet );
				}
			} catch( e ){
				// error in calling parent page event
			}
		}

		// Do the api request:
		this.kClient.doRequest( eventRequest, null, true );
	},

	/**
	 * Binds player events for analytics reporting
	 */
	bindPlayerEvents: function(){

		// Setup local reference to embedPlayer
		var embedPlayer = this.embedPlayer;
		var _this = this;

		// Setup shortcut anonymous function for player bindings
		var b = function( hookName, eventType ){
			$( _this.embedPlayer ).bind( hookName + _this.bindPostFix, function(){
				_this.sendAnalyticsEvent( eventType );
			});
		};

		// When the player is ready
		b( 'widgetLoaded', 'WIDGET_LOADED' );

		// When the poster or video ( when autoplay ) media is loaded
		b( 'KalturaSupport_EntryDataReady', 'MEDIA_LOADED' );

		// When the play button is pressed or called from javascript
		b( 'firstPlay', 'PLAY' );

		// When the show Share menu is displayed
		b( 'showShareEvent', 'OPEN_VIRAL' );

		// When the show download menu is displayed
		b( 'downloadMedia', 'OPEN_DOWNLOAD' );

		// When the clip starts to buffer ( not all player types )
		b( 'bufferStartEvent', 'BUFFER_START' );

		// When the clip is full buffered
		b( 'bufferEndEvent', 'BUFFER_END' );

		// When the fullscreen button is pressed
		// ( presently does not register iPhone / iPad until it has js bindings )
		b( 'onOpenFullScreen', 'OPEN_FULL_SCREEN' );

		// When the close fullscreen button is pressed.
		// ( presently does not register iphone / ipad until it has js bindings )
		b( 'onCloseFullScreen', 'CLOSE_FULL_SCREEN' );

		// When the user plays (after the ondone event was fired )
		b( 'replayEvent', 'REPLAY' );

		// Bind on the seek event
		$( embedPlayer ).bind( 'seeked' + this.bindPostFix, function( seekTarget ) {
			// Don't send a bunch of seeks on scrub:
			if( _this.lastSeekEventTime == 0 ||
				_this.lastSeekEventTime + 2000	< new Date().getTime() )
			{
				_this.sendAnalyticsEvent( 'SEEK' );
			}

			// Update the last seekTime
			_this.lastSeekEventTime =  new Date().getTime();

			// Then set local seek flags
			this.hasSeeked = true;
			this.lastSeek = seekTarget;
		} );

		// Let updateTimeStats handle the currentTime monitor timing

		$( embedPlayer ).bind( 'monitorEvent' + this.bindPostFix, function(){
			_this.updateTimeStats();
		});

		/*
		 * Other kaltura event types that are presently not usable in the
		 * html5 player at this point in time:
		 *
		 * OPEN_EDIT = 8;
		 * OPEN_REPORT = 11;
		 * OPEN_UPLOAD = 18;
		 * SAVE_PUBLISH = 19;
		 * CLOSE_EDITOR = 20;
		 *
		 * PRE_BUMPER_PLAYED = 21;
		 * POST_BUMPER_PLAYED = 22;
		 * BUMPER_CLICKED = 23;
		 *
		 * FUTURE_USE_1 = 24;
		 * FUTURE_USE_2 = 25;
		 * FUTURE_USE_3 = 26;
		 */
	},

	/**
	 * Send updates for time stats
	 */
	updateTimeStats: function() {
		// Setup local references:
		var embedPlayer = this.embedPlayer;
		var _this = this;

		// Set the seek and time percent:
		var percent = embedPlayer.currentTime / embedPlayer.duration;
		var seekPercent = this.lastSeek/ embedPlayer.duration;

		// Send updates based on logic present in StatisticsMediator.as
		if( !_this._p25Once && percent >= .25  &&  seekPercent <= .25 ) {

			_this._p25Once = true;
			_this.sendAnalyticsEvent( 'PLAY_REACHED_25' );
			$( embedPlayer ).trigger( "firstQuartile" );

		} else if ( !_this._p50Once && percent >= .50 && seekPercent < .50 ) {

			_this._p50Once = true;
			_this.sendAnalyticsEvent( 'PLAY_REACHED_50' );
			$( embedPlayer ).trigger( "secondQuartile" );

		} else if( !_this._p75Once && percent >= .75 && seekPercent < .75 ) {

			_this._p75Once = true;
			_this.sendAnalyticsEvent( 'PLAY_REACHED_75' );
			$( embedPlayer ).trigger( "thirdQuartile" );

		} else if(  !_this._p100Once && percent >= .98 && seekPercent < 1) {

			_this._p100Once = true;
			_this.sendAnalyticsEvent( 'PLAY_REACHED_100' );
		}
	}
};

})( window.mw, window.jQuery );<commit_msg>FEC-2875 #comment return ks to analytics stats event #time 1h<commit_after>/**
 * Kaltura style analytics reporting class
 */
( function( mw, $ ) { "use strict";

// Avoid undefined symbol for javascript response "Kaltura" from the api
window['Kaltura'] = true;

// KAnalytics Constructor
mw.KAnalytics = function( embedPlayer ){
	this.init( embedPlayer );
};

// Add analytics to the embed player:
mw.addKAnalytics = function( embedPlayer ) {
	embedPlayer.kAnalytics = new mw.KAnalytics( embedPlayer );
}
mw.KAnalytics.prototype = {

	// Local reference to embedPlayer
	embedPlayer: null,

	// Report Set object
	reportSet : null,

	// Stores the last time we issued a seek event
	// avoids sending lots of seeks while scrubbing
	lastSeekEventTime: 0,

	bindPostFix: '.kAnalytics',

	// Start Time
	startReportTime: 0,

	kEventTypes : {
		'WIDGET_LOADED' : 1,
		'MEDIA_LOADED' : 2,
		'PLAY' : 3,
		'PLAY_REACHED_25' : 4,
		'PLAY_REACHED_50' : 5,
		'PLAY_REACHED_75' : 6,
		'PLAY_REACHED_100' : 7,
		'OPEN_EDIT' : 8,
		'OPEN_VIRAL' : 9,
		'OPEN_DOWNLOAD' : 10,
		'OPEN_REPORT' : 11,
		'BUFFER_START' : 12,
		'BUFFER_END' : 13,
		'OPEN_FULL_SCREEN' : 14,
		'CLOSE_FULL_SCREEN' : 15,
		'REPLAY' : 16,
		'SEEK' : 17,
		'OPEN_UPLOAD' : 18,
		'SAVE_PUBLISH' : 19,
		'CLOSE_EDITOR' : 20,
		'PRE_BUMPER_PLAYED' : 21,
		'POST_BUMPER_PLAYED' : 22,
		'BUMPER_CLICKED' : 23,
		'FUTURE_USE_1' : 24,
		'FUTURE_USE_2' : 25,
		'FUTURE_USE_3' : 26
	},

	/**
	 * Constructor for kAnalytics
	 *
	 * @param {Object}
	 *		  embedPlayer Player to apply Kaltura analytics to.
	 * @parma {Object}
	 * 			kalturaClient Kaltura client object for the api session.
	 */
	init: function( embedPlayer ) {
		// set the version of html5 player
		this.version = mw.getConfig( 'version' );
		// Setup the local reference to the embed player
		this.embedPlayer = embedPlayer;
		if( ! this.kClient ) {
			this.kClient = mw.kApiGetPartnerClient( embedPlayer.kwidgetid );
		}
		// Remove any old bindings:
		$( embedPlayer ).unbind( this.bindPostFix );

		// Setup the initial state of some flags
		this.resetPlayerflags();

		// Add relevant hooks for reporting beacons
		this.bindPlayerEvents();
	},
	resetPlayerflags:function(){
		this._p25Once = false;
		this._p50Once = false;
		this._p75Once = false;
		this._p100Once = false;
		this.hasSeeked = false;
		this.lastSeek = 0;
	},
	/**
	 * Get the current report set
	 *
	 * @param {Number}
	 *			KalturaStatsEventType The eventType number.
	 */
	sendAnalyticsEvent: function( KalturaStatsEventKey ){
		var _this = this;
		mw.log("KAnalytics :: doSendAnalyticsEvent > " + KalturaStatsEventKey );
		// Kalutra analytics does not collect info for ads:
		if( this.embedPlayer.evaluate('{sequenceProxy.isInSequence}') ){
			return ;
		}

		// get the id for the given event:
		var eventKeyId = this.kEventTypes[ KalturaStatsEventKey ];

		// Generate the status event
		var eventSet = {
			'eventType'			: eventKeyId,
			'clientVer'			: this.version,
			'currentPoint'		: parseInt( this.embedPlayer.currentTime * 1000 ),
			'duration'			: this.embedPlayer.getDuration(),
			'eventTimestamp'	: new Date().getTime(),
			'isFirstInSession'	: 'false',
			'objectType'		: 'KalturaStatsEvent',
			'partnerId'			: this.embedPlayer.kpartnerid,
			'sessionId'			: this.embedPlayer.evaluate('{configProxy.sessionId}'),
			'uiconfId'			: 0
		};
		if( isNaN( eventSet.duration )  ){
			eventSet.duration = 0;
		}

		// Set the seek condition:
		eventSet[ 'seek' ] = ( this.hasSeeked ) ? 'true' : 'false';

		// Set the 'event:entryId'
		if( this.embedPlayer.kentryid ){
			eventSet[ 'entryId' ] = this.embedPlayer.kentryid;
		} else {
			// if kentryid is not set, use the selected source url
			eventSet[ 'entryId' ] = this.embedPlayer.getSrc();
		}

		// Set the 'event:uiconfId'
		if( this.embedPlayer.kuiconfid ) {
			eventSet[ 'uiconfId' ] = this.embedPlayer.kuiconfid;
		}
		// Set the 'event:widgetId'
		if( this.embedPlayer.kwidgetid ) {
			eventSet[ 'widgetId' ] = this.embedPlayer.kwidgetid;
		}
		var flashVarEvents = {
				'playbackContext' : 'contextId',
				'originFeature' : 'featureType',
				'applicationName' : 'applicationId',
				'userId' : 'userId'
		}
		// support legacy ( deprecated ) top level config
		for( var fvKey in flashVarEvents){
			if( this.embedPlayer.getKalturaConfig( '', fvKey ) ){
				eventSet[ flashVarEvents[ fvKey ] ] = encodeURIComponent( this.embedPlayer.getKalturaConfig('', fvKey ) );
			}
		}
		// check for the vars in the correct location:
		for( var fvKey in flashVarEvents){
			if( this.embedPlayer.getKalturaConfig( 'statistics', fvKey ) ){
				eventSet[ flashVarEvents[ fvKey ] ] = encodeURIComponent( this.embedPlayer.getKalturaConfig('', fvKey ) );
			}
		}

		// Add referrer parameter
		eventSet[ 'referrer' ] = encodeURIComponent( mw.getConfig('EmbedPlayer.IframeParentUrl') );

		// Add in base service and action calls:
		var eventRequest = {'service' : 'stats', 'action' : 'collect'};
		// Add event parameters
		for( var i in eventSet){
			eventRequest[ 'event:' + i] = eventSet[i];
		}

		// Send events for this player:
		$( this.embedPlayer ).trigger( 'KalturaSendAnalyticEvent', [ KalturaStatsEventKey, eventSet ] );

		// check for defined callback:
		var parentTrackName = this.embedPlayer.getKalturaConfig( 'statistics', 'trackEventMonitor');
		if(  mw.getConfig('EmbedPlayer.IsFriendlyIframe') ){
			try {
				if( window.parent[ parentTrackName ] ){
					 window.parent[ parentTrackName ]( KalturaStatsEventKey, eventSet );
				}
			} catch( e ){
				// error in calling parent page event
			}
		}
		if (this.embedPlayer.getFlashvars('ks')){
			eventRequest['ks'] = this.embedPlayer.getFlashvars('ks');
		}

		// Do the api request:
		this.kClient.doRequest( eventRequest, null, true );
	},

	/**
	 * Binds player events for analytics reporting
	 */
	bindPlayerEvents: function(){

		// Setup local reference to embedPlayer
		var embedPlayer = this.embedPlayer;
		var _this = this;

		// Setup shortcut anonymous function for player bindings
		var b = function( hookName, eventType ){
			$( _this.embedPlayer ).bind( hookName + _this.bindPostFix, function(){
				_this.sendAnalyticsEvent( eventType );
			});
		};

		// When the player is ready
		b( 'widgetLoaded', 'WIDGET_LOADED' );

		// When the poster or video ( when autoplay ) media is loaded
		b( 'KalturaSupport_EntryDataReady', 'MEDIA_LOADED' );

		// When the play button is pressed or called from javascript
		b( 'firstPlay', 'PLAY' );

		// When the show Share menu is displayed
		b( 'showShareEvent', 'OPEN_VIRAL' );

		// When the show download menu is displayed
		b( 'downloadMedia', 'OPEN_DOWNLOAD' );

		// When the clip starts to buffer ( not all player types )
		b( 'bufferStartEvent', 'BUFFER_START' );

		// When the clip is full buffered
		b( 'bufferEndEvent', 'BUFFER_END' );

		// When the fullscreen button is pressed
		// ( presently does not register iPhone / iPad until it has js bindings )
		b( 'onOpenFullScreen', 'OPEN_FULL_SCREEN' );

		// When the close fullscreen button is pressed.
		// ( presently does not register iphone / ipad until it has js bindings )
		b( 'onCloseFullScreen', 'CLOSE_FULL_SCREEN' );

		// When the user plays (after the ondone event was fired )
		b( 'replayEvent', 'REPLAY' );

		// Bind on the seek event
		$( embedPlayer ).bind( 'seeked' + this.bindPostFix, function( seekTarget ) {
			// Don't send a bunch of seeks on scrub:
			if( _this.lastSeekEventTime == 0 ||
				_this.lastSeekEventTime + 2000	< new Date().getTime() )
			{
				_this.sendAnalyticsEvent( 'SEEK' );
			}

			// Update the last seekTime
			_this.lastSeekEventTime =  new Date().getTime();

			// Then set local seek flags
			this.hasSeeked = true;
			this.lastSeek = seekTarget;
		} );

		// Let updateTimeStats handle the currentTime monitor timing

		$( embedPlayer ).bind( 'monitorEvent' + this.bindPostFix, function(){
			_this.updateTimeStats();
		});

		/*
		 * Other kaltura event types that are presently not usable in the
		 * html5 player at this point in time:
		 *
		 * OPEN_EDIT = 8;
		 * OPEN_REPORT = 11;
		 * OPEN_UPLOAD = 18;
		 * SAVE_PUBLISH = 19;
		 * CLOSE_EDITOR = 20;
		 *
		 * PRE_BUMPER_PLAYED = 21;
		 * POST_BUMPER_PLAYED = 22;
		 * BUMPER_CLICKED = 23;
		 *
		 * FUTURE_USE_1 = 24;
		 * FUTURE_USE_2 = 25;
		 * FUTURE_USE_3 = 26;
		 */
	},

	/**
	 * Send updates for time stats
	 */
	updateTimeStats: function() {
		// Setup local references:
		var embedPlayer = this.embedPlayer;
		var _this = this;

		// Set the seek and time percent:
		var percent = embedPlayer.currentTime / embedPlayer.duration;
		var seekPercent = this.lastSeek/ embedPlayer.duration;

		// Send updates based on logic present in StatisticsMediator.as
		if( !_this._p25Once && percent >= .25  &&  seekPercent <= .25 ) {

			_this._p25Once = true;
			_this.sendAnalyticsEvent( 'PLAY_REACHED_25' );
			$( embedPlayer ).trigger( "firstQuartile" );

		} else if ( !_this._p50Once && percent >= .50 && seekPercent < .50 ) {

			_this._p50Once = true;
			_this.sendAnalyticsEvent( 'PLAY_REACHED_50' );
			$( embedPlayer ).trigger( "secondQuartile" );

		} else if( !_this._p75Once && percent >= .75 && seekPercent < .75 ) {

			_this._p75Once = true;
			_this.sendAnalyticsEvent( 'PLAY_REACHED_75' );
			$( embedPlayer ).trigger( "thirdQuartile" );

		} else if(  !_this._p100Once && percent >= .98 && seekPercent < 1) {

			_this._p100Once = true;
			_this.sendAnalyticsEvent( 'PLAY_REACHED_100' );
		}
	}
};

})( window.mw, window.jQuery );<|endoftext|>


<commit_before>define(['summernote/core/range'], function (range) {
  /**
   * @class editing.History
   *
   * Editor History
   *
   */
  var History = function ($editable) {
    var stack = [], stackOffset = -1;
    var editable = $editable[0];

    var makeSnapshot = function () {
      var rng = range.create();
      var emptyBookmark = {s: {path: [0], offset: 0}, e: {path: [0], offset: 0}};

      return {
        contents: $editable.html(),
        bookmark: (rng ? rng.bookmark(editable) : emptyBookmark)
      };
    };

    var applySnapshot = function (snapshot) {
      if (snapshot.contents !== null) {
        $editable.html(snapshot.contents);
      }
      if (snapshot.bookmark !== null) {
        range.createFromBookmark(editable, snapshot.bookmark).select();
      }
    };

    /**
     * undo
     */
    this.undo = function () {
      if (0 < stackOffset) {
        stackOffset--;
        applySnapshot(stack[stackOffset]);
      }
    };

    /**
     * redo
     */
    this.redo = function () {
      if (stack.length - 1 > stackOffset) {
        stackOffset++;
        applySnapshot(stack[stackOffset]);
      }
    };

    /**
     * recorded undo
     */
    this.recordUndo = function () {
      stackOffset++;

      // Wash out stack after stackOffset
      if (stack.length > stackOffset) {
        stack = stack.slice(0, stackOffset);
      }

      // Create new snapshot and push it to the end
      stack.push(makeSnapshot());
    };

    // Create first undo stack
    this.recordUndo();
  };

  return History;
});
<commit_msg>Fix script error when last undo.<commit_after>define(['summernote/core/range'], function (range) {
  /**
   * @class editing.History
   *
   * Editor History
   *
   */
  var History = function ($editable) {
    var stack = [], stackOffset = -1;
    var editable = $editable[0];

    var makeSnapshot = function () {
      var rng = range.create();
      var emptyBookmark = {s: {path: [], offset: 0}, e: {path: [], offset: 0}};

      return {
        contents: $editable.html(),
        bookmark: (rng ? rng.bookmark(editable) : emptyBookmark)
      };
    };

    var applySnapshot = function (snapshot) {
      if (snapshot.contents !== null) {
        $editable.html(snapshot.contents);
      }
      if (snapshot.bookmark !== null) {
        range.createFromBookmark(editable, snapshot.bookmark).select();
      }
    };

    /**
     * undo
     */
    this.undo = function () {
      if (0 < stackOffset) {
        stackOffset--;
        applySnapshot(stack[stackOffset]);
      }
    };

    /**
     * redo
     */
    this.redo = function () {
      if (stack.length - 1 > stackOffset) {
        stackOffset++;
        applySnapshot(stack[stackOffset]);
      }
    };

    /**
     * recorded undo
     */
    this.recordUndo = function () {
      stackOffset++;

      // Wash out stack after stackOffset
      if (stack.length > stackOffset) {
        stack = stack.slice(0, stackOffset);
      }

      // Create new snapshot and push it to the end
      stack.push(makeSnapshot());
    };

    // Create first undo stack
    this.recordUndo();
  };

  return History;
});
<|endoftext|>


<commit_before>var FactfinderSCIC = Class.create({
	url:  null,
	data: null,
	classname: null,
	mapping: null,
	request: null,
	regex: new RegExp(/product\/([0-9]+)\//),
	asynchronous: true,
	initialize: function(classname, data, mapping, url, asynchronous) {
		this.classname = classname;
		this.data = data;
		this.mapping = mapping;
		this.url = url;
		if(typeof asynchronous !== 'undefined')
			this.asynchronous = asynchronous;
	},

	init: function() {
		$$(this.classname+' a',this.classname+' button').each(function(element) {
			this.mapping.each(function(pair, index) {
				if(element.readAttribute('href') && element.readAttribute('href') == pair.key){
					return this.prepareElement(element, pair.value, 'click');
				}
				if(element.readAttribute('onclick') && element.readAttribute('onclick').indexOf(pair.key) >= 0){
					return this.prepareElement(element, pair.value, 'click');
				}
			}.bind(this));

			if(element.readAttribute('href')) {
				var match = this.regex.exec(element.readAttribute('href'));
				if(match && match[1]) {
					return this.prepareElement(element, match[1], 'click');
				}
			}

			if(element.readAttribute('onclick')) {
				var match = this.regex.exec(element.readAttribute('onclick'));
				if(match && match[1]) {
					return this.prepareElement(element, match[1], 'click');
				}
			}
		}.bind(this));
	},

	prepareElement: function(element, id, eventType) {
		Event.observe(element, 'click', function(event) {
			this.recordRequest(id, eventType);
		}.bind(this));
	},

	recordRequest: function(id, eventType) {

		var data = this.data.get(id);
		data.event = eventType;

		this.request = new Ajax.Request(this.url, {
			asynchronous: this.asynchronous,
			method: 'post',
			parameters: data
		});
		return false;
	}
});<commit_msg>[+BUGFIX] make scic also work with urls that have appended parameters<commit_after>var FactfinderSCIC = Class.create({
	url:  null,
	data: null,
	classname: null,
	mapping: null,
	request: null,
	regex: new RegExp(/product\/([0-9]+)\//),
	asynchronous: true,
	initialize: function(classname, data, mapping, url, asynchronous) {
		this.classname = classname;
		this.data = data;
		this.mapping = mapping;
		this.url = url;
		if(typeof asynchronous !== 'undefined')
			this.asynchronous = asynchronous;
	},

	init: function() {
		$$(this.classname+' a',this.classname+' button').each(function(element) {
			this.mapping.each(function(pair, index) {
				if(element.readAttribute('href') && element.readAttribute('href').indexOf(pair.key) >= 0){
					return this.prepareElement(element, pair.value, 'click');
				}
				if(element.readAttribute('onclick') && element.readAttribute('onclick').indexOf(pair.key) >= 0){
					return this.prepareElement(element, pair.value, 'click');
				}
			}.bind(this));

			if(element.readAttribute('href')) {
				var match = this.regex.exec(element.readAttribute('href'));
				if(match && match[1]) {
					return this.prepareElement(element, match[1], 'click');
				}
			}

			if(element.readAttribute('onclick')) {
				var match = this.regex.exec(element.readAttribute('onclick'));
				if(match && match[1]) {
					return this.prepareElement(element, match[1], 'click');
				}
			}
		}.bind(this));
	},

	prepareElement: function(element, id, eventType) {
		Event.observe(element, 'click', function(event) {
			this.recordRequest(id, eventType);
		}.bind(this));
	},

	recordRequest: function(id, eventType) {

		var data = this.data.get(id);
		data.event = eventType;

		this.request = new Ajax.Request(this.url, {
			asynchronous: this.asynchronous,
			method: 'post',
			parameters: data
		});
		return false;
	}
});<|endoftext|>


<commit_before>/* ===============================================================================
************   Infinite Scroll   ************
=============================================================================== */
function handleInfiniteScroll() {
    /*jshint validthis:true */
    var inf = $(this);
    var scrollTop = inf[0].scrollTop;
    var scrollHeight = inf[0].scrollHeight;
    var height = inf[0].offsetHeight;
    var distance = inf[0].getAttribute('data-distance');
    var virtualListContainer = inf.find('.virtual-list');
    var virtualList;
    var onTop = inf.hasClass('infinite-scroll-top');
    if (!distance) distance = 50;
    if (typeof distance === 'string' && distance.indexOf('%') >= 0) {
        distance = parseInt(distance, 10) / 100 * height;
    }
    if (distance > height) distance = height;
    if (onTop) {
        if (scrollTop < distance) {
            inf.trigger('infinite');
        }
    }
    else {
        if (scrollTop + height >= scrollHeight - distance) {
            if (virtualListContainer.length > 0) {
                virtualList = virtualListContainer[0].f7VirtualList;
                if (virtualList && !virtualList.reachEnd) return;
            }
            inf.trigger('infinite');
        }
    }

}
app.attachInfiniteScroll = function (infiniteContent) {
    $(infiniteContent).on('scroll', handleInfiniteScroll);
};
app.detachInfiniteScroll = function (infiniteContent) {
    $(infiniteContent).off('scroll', handleInfiniteScroll);
};

app.initPageInfiniteScroll = function (pageContainer) {
    pageContainer = $(pageContainer);
    var infiniteContent = pageContainer.find('.infinite-scroll');
    if (infiniteContent.length === 0) return;
    app.attachInfiniteScroll(infiniteContent);
    function detachEvents() {
        app.detachInfiniteScroll(infiniteContent);
        pageContainer.off('page:beforeremove', detachEvents);
    }
    pageContainer.on('page:beforeremove', detachEvents);
};<commit_msg>Fix case for multiple VLs on a page<commit_after>/* ===============================================================================
************   Infinite Scroll   ************
=============================================================================== */
function handleInfiniteScroll() {
    /*jshint validthis:true */
    var inf = $(this);
    var scrollTop = inf[0].scrollTop;
    var scrollHeight = inf[0].scrollHeight;
    var height = inf[0].offsetHeight;
    var distance = inf[0].getAttribute('data-distance');
    var virtualListContainer = inf.find('.virtual-list');
    var virtualList;
    var onTop = inf.hasClass('infinite-scroll-top');
    if (!distance) distance = 50;
    if (typeof distance === 'string' && distance.indexOf('%') >= 0) {
        distance = parseInt(distance, 10) / 100 * height;
    }
    if (distance > height) distance = height;
    if (onTop) {
        if (scrollTop < distance) {
            inf.trigger('infinite');
        }
    }
    else {
        if (scrollTop + height >= scrollHeight - distance) {
            if (virtualListContainer.length > 0) {
                virtualList = virtualListContainer.eq(-1)[0].f7VirtualList;
                if (virtualList && !virtualList.reachEnd) return;
            }
            inf.trigger('infinite');
        }
    }

}
app.attachInfiniteScroll = function (infiniteContent) {
    $(infiniteContent).on('scroll', handleInfiniteScroll);
};
app.detachInfiniteScroll = function (infiniteContent) {
    $(infiniteContent).off('scroll', handleInfiniteScroll);
};

app.initPageInfiniteScroll = function (pageContainer) {
    pageContainer = $(pageContainer);
    var infiniteContent = pageContainer.find('.infinite-scroll');
    if (infiniteContent.length === 0) return;
    app.attachInfiniteScroll(infiniteContent);
    function detachEvents() {
        app.detachInfiniteScroll(infiniteContent);
        pageContainer.off('page:beforeremove', detachEvents);
    }
    pageContainer.on('page:beforeremove', detachEvents);
};<|endoftext|>


<commit_before>define(['jquery', 'lodash', 'bootstrap', 'models/Field'], function($, _, bootstrap, Field){
	var Card = function(collection_id, deck_id, card_id){
		this.collection_id = collection_id;
		this.deck_id = deck_id;
		this.card_id = card_id;
		this.field_data = '';
		this.fields = [];
	}

	_.extend(Card.prototype, {
		// initiate new card
		initNewCard: function(){
			collection_id = this.collection_id;
			// get the field data for the collection
			if(this.field_data){
				this.setupFieldUI();
				this.saveCardButton();
			} else {
				this.getFieldData(collection_id);
			}
		},

		getFieldData: function(){
			var that = this;
			var collection_id = this.collection_id;
			$.ajax({
				type: 'POST',
				url: '/collection/fields/',
				data: {collection_id: collection_id},
				success: function(data, statusText){
					if(data.fields !== undefined){
						that.setFieldData(data.fields);
						that.initNewCard();
					} else {
						alert("Error: "+data.error)
					}
				},
				error: function(request, statusText){
					alert("Request failed.");
				}
			});
		},

		setFieldData: function(field_data){
			var that = this;
			this.field_data = field_data;
			this.field_data.forEach(function(field){
				f = new Field(field.label, field.field_type, field.id, field.display);
				that.fields.push(f);
			});
		},

		setupFieldUI: function(){
			// run through each field item
			var hide_bar = '
  ';
			var display = true;
			this.fields.forEach(function(field){
				// insert into card-main
				if(display && !field.display) {
					display = false;
					$('.card-main').append(hide_bar);
				}
				$('.card-main').append(field.template);
			});

		},
		saveCardButton: function(){
			$('.save-card-btn').click(function(){
				card_id = '';
				// collect data
				var fields = [];
				$('.field-template input').each(function(keys, input){
					var field = {};
					field['value'] = $(input).val();
					field['field_id'] = $(input).data("id");
					fields.push(field);
				});
				// send data to the server
				$.ajax({
					type: 'POST',
					url: '/card/create/',
					data: {fields: fields, card_id: card_id},
					success: function(data, statusText){
						if(data.card_id !== undefined){
							alert("success!");
						} else {
							alert("Error: no card_id returned\n"+data.error)
						}
					},
					error: function(request, statusText){
						alert("Request failed.");
					}
				});

			});
		}

	});

	return Card;

});<commit_msg>ajax for creating a card ironed out<commit_after>define(['jquery', 'lodash', 'bootstrap', 'models/Field'], function($, _, bootstrap, Field){
	var Card = function(collection_id, deck_id, card_id){
		this.collection_id = collection_id;
		this.deck_id = deck_id;
		this.card_id = card_id;
		this.field_data = '';
		this.fields = [];
	}

	_.extend(Card.prototype, {
		// initiate new card
		initNewCard: function(){
			collection_id = this.collection_id;
			// get the field data for the collection
			if(this.field_data){
				this.setupFieldUI();
				this.saveCardButton();
			} else {
				this.getFieldData(collection_id);
			}
		},

		getFieldData: function(){
			var that = this;
			var collection_id = this.collection_id;
			$.ajax({
				type: 'POST',
				url: '/collection/fields/',
				data: {collection_id: collection_id},
				success: function(data, statusText){
					if(data.fields !== undefined){
						that.setFieldData(data.fields);
						that.initNewCard();
					} else {
						alert("Error: "+data.error)
					}
				},
				error: function(request, statusText){
					alert("Request failed.");
				}
			});
		},

		setFieldData: function(field_data){
			var that = this;
			this.field_data = field_data;
			this.field_data.forEach(function(field){
				f = new Field(field.label, field.field_type, field.id, field.display);
				that.fields.push(f);
			});
		},

		setupFieldUI: function(){
			// run through each field item
			var hide_bar = '
  ';
			var display = true;
			this.fields.forEach(function(field){
				// insert into card-main
				if(display && !field.display) {
					display = false;
					$('.card-main').append(hide_bar);
				}
				$('.card-main').append(field.template);
			});

		},
		saveCardButton: function(){
			var that = this;
			$('.save-card-btn').click(function(){
				card_id = '';
				// collect data
				var fields = [];
				$('.field-template input').each(function(keys, input){
					var field = {};
					field['value'] = $(input).val();
					field['field_id'] = $(input).data("id");
					fields.push(field);
				});
				// json stringify the fields object
				json_fields = JSON.stringify(fields);
				// send data to the server
				$.ajax({
					type: 'POST',
					url: '/card/create/',
					data: {fields: json_fields, card_id: card_id, collection_id: that.collection_id, deck_id: that.deck_id},
					success: function(data, statusText){
						if(data.card_id !== undefined){
							alert("success!");
						} else {
							alert("Error: no card_id returned\n"+data.error)
						}
					},
					error: function(request, statusText){
						alert("Request failed.");
					}
				});

			});
		}

	});

	return Card;

});<|endoftext|>