<commit_before>define(function () {

    /**
     * Performs a PUT request
     * @param config.*          See #call
     */
    function put (config) {
        call($.extend(config, { method: 'PUT' }));
    }

    /**
     * Performs a POST request
     * @param config.*          See #call
     */
    function post (config) {
        call($.extend(config, { method: 'POST' }));
    }

    /**
     * Performs a GET request
     * @param config.*          See #call
     */
    function get (config) {
        call($.extend(config, { method: 'GET' }));
    }

    /**
     * Performs a DELETE request
     * @param config.*          See #call
     */
    function del (config) {
        call($.extend(config, { method: 'DELETE' }));
    }

    /**
     * Performs an AJAX call
     * @param config.loading        Loading indicator configuration (see #showLoading)
     * @param config.method         HTTP method (default: 'POST')
     * @param config.url            URL to call (required)
     * @param config.data           Data to send, or function that generates this data (optional)
     * @param config.contentType    Type of the data to send (default: 'application/json')
     * @param config.responseType   Type of the response (default: 'json')
     * @param config.successFn      (data -> void) function that is called with the data returned by the AJAX call (required)
     * @param config.errorFn        (jqXHR, textStatus, errorThrown -> void) function that allows for the treatment of the error (default: #defaultAjaxErrorFn)
     */
    function call (config) {
        // Default settings
        var c = $.extend({
            method: 'POST',
            responseType: 'json',
            contentType: 'application/json',
            errorFn: defaultAjaxErrorFn
        }, config);
        // Data to send
        var data = null;
        if (config.data) {
            if ($.isFunction(config.data)) {
                data = config.data();
            } else {
                data = config.data;
            }
            // Transformation?
            if (c.contentType == 'application/json' && $.isPlainObject(data)) {
                data = JSON.stringify(data);
            }
        }
        // Starting to load
        showLoading(c.loading, true);
        // Performing the call
		$.ajax({
			type: c.method,
			url: c.url,
			dataType: c.responseType,
			contentType: c.contentType,
			data: data,
			success: function (data) {
			    // Loading ending
                showLoading(c.loading, false);
                // Success :)
		  		c.successFn(data);
			},
			error: function (jqXHR, textStatus, errorThrown) {
			    // Loading ending
                showLoading(c.loading, false);
                // Error :(
                c.errorFn(jqXHR, textStatus, errorThrown);
			}
		});
    }

    /**
     * Shows a loading indicator on a element. If not element is defined, no loading occurs.
     * @param config.el     jQuery object or selector for the object which will contain the loading indicator (default: undefined)
     * @param config.mode   Way of displaying the loading indicator (default: append):
     *      'append' - appends a loading image at the end of the element
     *      'appendText' - appends a loading image and a text at the end of the element
     *      'container' - a loading element is set as the content of the el element
     *      'toggle' - the el element is directly shown or hidden according to show
     *      'none' - no loading indicator
     * @param show          Boolean that indicates if the the loading must be hidden or shown (default: false)
     */
    function showLoading (config, show) {
        if (config && config.el) {
            var c = $.extend({
                mode: 'append'
            }, config);
            if (c.mode == 'append') {
                if (show) {
                    $(config.el).addClass('disabled');
                    $(config.el).append(' ');
                } else {
                    $(config.el).removeClass('disabled');
                    $(config.el).find('.ajax-loader').remove();
                }
            } else if (c.mode == 'appendText') {
                if (show) {
                    $(config.el).addClass('disabled');
                    $(config.el).append('  {0}'.format(loc('general.loading')));
                } else {
                    $(config.el).removeClass('disabled');
                    $(config.el).find('.ajax-loader').remove();
                }
            } else if (c.mode == 'container') {
                $(config.el).empty();
                if (show) {
                    $(config.el).append('
{0}
'.format('general.loading'.loc()));
                }
            } else if (c.mode == 'toggle') {
                if (show) {
                    $(config.el).show();
                } else {
                    $(config.el).hide();
                }
            } else if (c.mode == 'none') {
                // Does nothing
            } else {
                throw 'ShowLoading: mode={0} not known'.format(c.mode);
            }
        }
    }

    /**
     * Default error function for an AJAX error handling
     */
    function defaultAjaxErrorFn (jqXHR, textStatus, errorThrown) {
        common.showError(getAjaxError(jqXHR, textStatus, errorThrown));
    }

    /**
     * Generates a AJAX error handler that just needs to deal
     * with a text message
     * @param errorMessageFn Function that takes the error message as a parameter
     * @return An AJAX error handler
     */
    function simpleAjaxErrorFn (errorMessageFn) {
        return function (jqXHR, textStatus, errorThrown) {
            var message = getAjaxError (jqXHR, textStatus, errorThrown);
            errorMessageFn(message);
        }
    }

    /**
     * Gets the AJAX error message
     */
	function getAjaxError (jqXHR, textStatus, errorThrown) {
	    if (jqXHR.status == 0) {
	        return loc('client.error.general');
	    } else if (jqXHR.status == 500 && jqXHR.responseText && jqXHR.responseText != '') {
	        return jqXHR.responseText;
	    } else {
		    return '[{0}] {1}'.format(jqXHR.status, jqXHR.statusText);
		}
	}

	/**
	 * Generates an error message handler that displays the message
	 * into an existing element.
	 * @param el Element that contains the error message
	 * @return An error message handler
	 */
	function elementErrorMessageFn (el) {
        return function (message) {
            if (message == null) {
                $(el).hide();
            } else {
                $(el).text(message);
                $(el).show();
            }
        }
	}

    return {
        // AJAX calls
        put: put,
        get: get,
        del: del,
        post: post,
        call: call,
        // Loading
        showLoading: showLoading,
        // Error management
        defaultAjaxErrorFn: defaultAjaxErrorFn,
        simpleAjaxErrorFn: simpleAjaxErrorFn,
        getAjaxError: getAjaxError,
        elementErrorMessageFn: elementErrorMessageFn
    };

});<commit_msg>requirejs: loc correction<commit_after>define(function () {

    /**
     * Performs a PUT request
     * @param config.*          See #call
     */
    function put (config) {
        call($.extend(config, { method: 'PUT' }));
    }

    /**
     * Performs a POST request
     * @param config.*          See #call
     */
    function post (config) {
        call($.extend(config, { method: 'POST' }));
    }

    /**
     * Performs a GET request
     * @param config.*          See #call
     */
    function get (config) {
        call($.extend(config, { method: 'GET' }));
    }

    /**
     * Performs a DELETE request
     * @param config.*          See #call
     */
    function del (config) {
        call($.extend(config, { method: 'DELETE' }));
    }

    /**
     * Performs an AJAX call
     * @param config.loading        Loading indicator configuration (see #showLoading)
     * @param config.method         HTTP method (default: 'POST')
     * @param config.url            URL to call (required)
     * @param config.data           Data to send, or function that generates this data (optional)
     * @param config.contentType    Type of the data to send (default: 'application/json')
     * @param config.responseType   Type of the response (default: 'json')
     * @param config.successFn      (data -> void) function that is called with the data returned by the AJAX call (required)
     * @param config.errorFn        (jqXHR, textStatus, errorThrown -> void) function that allows for the treatment of the error (default: #defaultAjaxErrorFn)
     */
    function call (config) {
        // Default settings
        var c = $.extend({
            method: 'POST',
            responseType: 'json',
            contentType: 'application/json',
            errorFn: defaultAjaxErrorFn
        }, config);
        // Data to send
        var data = null;
        if (config.data) {
            if ($.isFunction(config.data)) {
                data = config.data();
            } else {
                data = config.data;
            }
            // Transformation?
            if (c.contentType == 'application/json' && $.isPlainObject(data)) {
                data = JSON.stringify(data);
            }
        }
        // Starting to load
        showLoading(c.loading, true);
        // Performing the call
		$.ajax({
			type: c.method,
			url: c.url,
			dataType: c.responseType,
			contentType: c.contentType,
			data: data,
			success: function (data) {
			    // Loading ending
                showLoading(c.loading, false);
                // Success :)
		  		c.successFn(data);
			},
			error: function (jqXHR, textStatus, errorThrown) {
			    // Loading ending
                showLoading(c.loading, false);
                // Error :(
                c.errorFn(jqXHR, textStatus, errorThrown);
			}
		});
    }

    /**
     * Shows a loading indicator on a element. If not element is defined, no loading occurs.
     * @param config.el     jQuery object or selector for the object which will contain the loading indicator (default: undefined)
     * @param config.mode   Way of displaying the loading indicator (default: append):
     *      'append' - appends a loading image at the end of the element
     *      'appendText' - appends a loading image and a text at the end of the element
     *      'container' - a loading element is set as the content of the el element
     *      'toggle' - the el element is directly shown or hidden according to show
     *      'none' - no loading indicator
     * @param show          Boolean that indicates if the the loading must be hidden or shown (default: false)
     */
    function showLoading (config, show) {
        if (config && config.el) {
            var c = $.extend({
                mode: 'append'
            }, config);
            if (c.mode == 'append') {
                if (show) {
                    $(config.el).addClass('disabled');
                    $(config.el).append(' ');
                } else {
                    $(config.el).removeClass('disabled');
                    $(config.el).find('.ajax-loader').remove();
                }
            } else if (c.mode == 'appendText') {
                if (show) {
                    $(config.el).addClass('disabled');
                    $(config.el).append('  {0}'.format('general.loading'.loc()));
                } else {
                    $(config.el).removeClass('disabled');
                    $(config.el).find('.ajax-loader').remove();
                }
            } else if (c.mode == 'container') {
                $(config.el).empty();
                if (show) {
                    $(config.el).append('
{0}
'.format('general.loading'.loc()));
                }
            } else if (c.mode == 'toggle') {
                if (show) {
                    $(config.el).show();
                } else {
                    $(config.el).hide();
                }
            } else if (c.mode == 'none') {
                // Does nothing
            } else {
                throw 'ShowLoading: mode={0} not known'.format(c.mode);
            }
        }
    }

    /**
     * Default error function for an AJAX error handling
     */
    function defaultAjaxErrorFn (jqXHR, textStatus, errorThrown) {
        common.showError(getAjaxError(jqXHR, textStatus, errorThrown));
    }

    /**
     * Generates a AJAX error handler that just needs to deal
     * with a text message
     * @param errorMessageFn Function that takes the error message as a parameter
     * @return An AJAX error handler
     */
    function simpleAjaxErrorFn (errorMessageFn) {
        return function (jqXHR, textStatus, errorThrown) {
            var message = getAjaxError (jqXHR, textStatus, errorThrown);
            errorMessageFn(message);
        }
    }

    /**
     * Gets the AJAX error message
     */
	function getAjaxError (jqXHR, textStatus, errorThrown) {
	    if (jqXHR.status == 0) {
	        return loc('client.error.general');
	    } else if (jqXHR.status == 500 && jqXHR.responseText && jqXHR.responseText != '') {
	        return jqXHR.responseText;
	    } else {
		    return '[{0}] {1}'.format(jqXHR.status, jqXHR.statusText);
		}
	}

	/**
	 * Generates an error message handler that displays the message
	 * into an existing element.
	 * @param el Element that contains the error message
	 * @return An error message handler
	 */
	function elementErrorMessageFn (el) {
        return function (message) {
            if (message == null) {
                $(el).hide();
            } else {
                $(el).text(message);
                $(el).show();
            }
        }
	}

    return {
        // AJAX calls
        put: put,
        get: get,
        del: del,
        post: post,
        call: call,
        // Loading
        showLoading: showLoading,
        // Error management
        defaultAjaxErrorFn: defaultAjaxErrorFn,
        simpleAjaxErrorFn: simpleAjaxErrorFn,
        getAjaxError: getAjaxError,
        elementErrorMessageFn: elementErrorMessageFn
    };

});<|endoftext|>


<commit_before>var net = require('net');

Array.prototype.max = function() {
  return Math.max.apply(null, this);
};
Array.prototype.min = function() {
  return Math.min.apply(null, this);
};

var lista_pieter = []
if(process.argv[2]) {
  lista_pieter = JSON.parse(process.argv[2]);
} else {
  lista_pieter = [10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 8, 20];
}
console.log("floor list: " + lista_pieter);
console.log("max floor: " + lista_pieter.max());

var P = []; // External buttons state
var Q = []; // Internal buttons state
for(var i=0; i<lista_pieter.max(); i++) {
  P[i] = Array.apply(null, Array(2)).map(Number.prototype.valueOf,0);
}
for(var i=0; i<lista_pieter.length; i++) {
  Q[i] = Array.apply(null, Array(lista_pieter[i])).map(Number.prototype.valueOf,0);
}

console.log(P);
console.log(Q);

/*var sender = new net.Socket();
sender.connect('8089', 'localhost', function(){
  sender.write("1:1");
});

var listener = new net.Socket();
listener.on('data', function(data) {
  console.log(data.toString());
});
listener.connect('8090', 'localhost');*/
<commit_msg>update external buttons state list<commit_after>var net = require('net');

Array.prototype.max = function() {
  return Math.max.apply(null, this);
};
Array.prototype.min = function() {
  return Math.min.apply(null, this);
};

var lista_pieter = []
if(process.argv[2]) {
  lista_pieter = JSON.parse(process.argv[2]);
} else {
  lista_pieter = [10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 8, 20];
}
console.log("floor list: " + lista_pieter);
console.log("max floor: " + lista_pieter.max());

var P = []; // External buttons state
var Q = []; // Internal buttons state
for(var i=0; i<lista_pieter.max(); i++) {
  P[i] = Array.apply(null, Array(2)).map(Number.prototype.valueOf,0);
}
for(var i=0; i<lista_pieter.length; i++) {
  Q[i] = Array.apply(null, Array(lista_pieter[i])).map(Number.prototype.valueOf,0);
}

console.log(P);
console.log(Q);

/*var sender = new net.Socket();
sender.connect('8089', 'localhost', function(){
  sender.write("1:1");
}); */

var listener = new net.Socket();
listener.on('data', function(data) {
	var x = data.toString();
	var externalBtn = x.match(/(\d+):([u|d])/);
	if ((externalBtn[1] < lista_pieter.max()) && (externalBtn[1] >= 0)) {
			switch (externalBtn[2]) {
				case "u":
					P[externalBtn[1]][1] = 1;
					break;
				case "d":
					P[externalBtn[1]][0] = 1;
					break;
			}
  	console.log(P);
	}
});
listener.connect('8090', 'localhost');
<|endoftext|>


<commit_before>const assert = require('assert');
const config = require('collections-online/lib/config');
const cip = require('../services/cip');

const USER_FIELD = config.motifTagging && config.motifTagging.userField;
const VISION_FIELD = config.motifTagging && config.motifTagging.visionField;

if(config.features.motifTagging) {
  assert.ok(USER_FIELD, 'Missing a config.motifTagging.userField');
  assert.ok(VISION_FIELD, 'Missing a config.motifTagging.visionField');
}

module.exports.save = ({id, collection, userTags, visionTags}) => {
  assert.ok(collection, 'Missing the collection');
  assert.ok(id, 'Missing an asset id');

  // Save it using the CIP
  var values = {};

  if(userTags) {
    values[USER_FIELD] = userTags.join(',');
  }

  if(visionTags) {
    values[VISION_FIELD] = visionTags.join(',');
  }

  // Set the field values via the CIP
  return cip.setFieldValues(collection, id, values)
  .then(function(response) {
    if (response.statusCode !== 200) {
      throw new Error('Failed to set the field values');
    } else {
      return response;
    }
  });
};

module.exports.updateIndex = (metadata) => {
  const es = require('collections-online/lib/services/elasticsearch');
  const index = config.es && config.es.index;
  assert.ok(index, 'Missing config.es.index');

  return es.getSource({
    id: metadata.collection + '-' + metadata.id,
    type: 'asset',
    index
  }).then(metadataBefore => {
    const indexingState = {
      es,
      index
    };
    const transformations = [
      require('../indexing/transformations/tag-hierarchy')
    ];
    const indexAsset = require('../indexing/processing/asset');
    const metadataAfter = Object.assign({}, metadataBefore, metadata);
    return indexAsset(indexingState, metadataAfter, transformations)
    .then(id => {
      return metadataAfter;
    });
  });
};
<commit_msg>Vision tags will now save properly even if there's none left<commit_after>const assert = require('assert');
const config = require('collections-online/lib/config');
const cip = require('../services/cip');

const USER_FIELD = config.motifTagging && config.motifTagging.userField;
const VISION_FIELD = config.motifTagging && config.motifTagging.visionField;

if(config.features.motifTagging) {
  assert.ok(USER_FIELD, 'Missing a config.motifTagging.userField');
  assert.ok(VISION_FIELD, 'Missing a config.motifTagging.visionField');
}

module.exports.save = ({id, collection, userTags, visionTags}) => {
  assert.ok(collection, 'Missing the collection');
  assert.ok(id, 'Missing an asset id');

  // Save it using the CIP
  var values = {};

  if(userTags === typeof(String)) {
    values[USER_FIELD] = userTags.join(',');
  }

  if(visionTags === typeof(String)) {
    values[VISION_FIELD] = visionTags.join(',');
  }

  // Set the field values via the CIP
  return cip.setFieldValues(collection, id, values)
  .then(function(response) {
    if (response.statusCode !== 200) {
      throw new Error('Failed to set the field values');
    } else {
      return response;
    }
  });
};

module.exports.updateIndex = (metadata) => {
  const es = require('collections-online/lib/services/elasticsearch');
  const index = config.es && config.es.index;
  assert.ok(index, 'Missing config.es.index');

  return es.getSource({
    id: metadata.collection + '-' + metadata.id,
    type: 'asset',
    index
  }).then(metadataBefore => {
    const indexingState = {
      es,
      index
    };
    const transformations = [
      require('../indexing/transformations/tag-hierarchy')
    ];
    const indexAsset = require('../indexing/processing/asset');
    const metadataAfter = Object.assign({}, metadataBefore, metadata);
    return indexAsset(indexingState, metadataAfter, transformations)
    .then(id => {
      return metadataAfter;
    });
  });
};
<|endoftext|>


<commit_before>var models = require('../models');

exports.createStolperstein = function(req, res) {
	var stolperstein = new models.stolperstein.Stolperstein(req.body);
	stolperstein.save(function(err, stolperstein) {
		if (!err) {
			res.send(201, stolperstein);
		} else {
			res.send(400, err);
		}
	});
}

exports.retrieveStolpersteine = function(req, res) {
	var query = {};
	if (typeof req.query.q !== 'undefined') {
		var regex = new RegExp('^' + req.query.q, "i");
		query = {
			$or: [
				{"person.lastName": regex},
				{"person.firstName": regex},
				{"location.street": regex},
				{"location.zipCode": regex}
			]
		};
	}

	if (typeof req.query.street !== 'undefined') {
		var regex = new RegExp('^' + req.query.street, "i");
		query = {
			"location.street": regex
		};
	}

	// Use lean option to improve speed
	res.type('application/json');
	var stream = models.stolperstein.Stolperstein.find(query).select('-__v').lean().stream();
	stream.on('data', function(doc) {
		res.write(JSON.stringify(doc));
	}).on('err', function(err) {
		res.end();
	}).on('close', function() {
		res.end();
	});
}

exports.retrieveStolperstein = function(req, res) {
	models.stolperstein.Stolperstein.findById(req.params.id, function(err, stolperstein) {
		if (!err && stolperstein) {
			res.send(stolperstein);
		} else {
			res.send(404, err);
		}
	});
}

exports.deleteStolperstein = function(req, res) {
	models.stolperstein.Stolperstein.findByIdAndRemove(req.params.id, function(err, stolperstein) {
		if (!err && stolperstein) {
			res.send(204);
		} else {
			res.send(404, err);
		}
	});
}<commit_msg>Testing without streaming<commit_after>var models = require('../models');

exports.createStolperstein = function(req, res) {
	var stolperstein = new models.stolperstein.Stolperstein(req.body);
	stolperstein.save(function(err, stolperstein) {
		if (!err) {
			res.send(201, stolperstein);
		} else {
			res.send(400, err);
		}
	});
}

exports.retrieveStolpersteine = function(req, res) {
	var query = {};
	if (typeof req.query.q !== 'undefined') {
		var regex = new RegExp('^' + req.query.q, "i");
		query = {
			$or: [
				{"person.lastName": regex},
				{"person.firstName": regex},
				{"location.street": regex},
				{"location.zipCode": regex}
			]
		};
	}

	if (typeof req.query.street !== 'undefined') {
		var regex = new RegExp('^' + req.query.street, "i");
		query = {
			"location.street": regex
		};
	}

	// Use lean option to improve speed
	res.type('application/json');
	models.stolperstein.Stolperstein.find(query).select('-__v').lean().exec(function(err, stolpersteine) {
		if (!err) {
			for (var i = 0; i < stolpersteine.length; i++) {
				var stolperstein = stolpersteine[i];
				stolperstein.id = stolperstein._id;
				delete stolperstein._id;
			}
			res.write(JSON.stringify(stolpersteine));
			res.end();
		} else {
			res.send(400, err);
		}
	});
}

exports.retrieveStolperstein = function(req, res) {
	models.stolperstein.Stolperstein.findById(req.params.id, function(err, stolperstein) {
		if (!err && stolperstein) {
			res.send(stolperstein);
		} else {
			res.send(404, err);
		}
	});
}

exports.deleteStolperstein = function(req, res) {
	models.stolperstein.Stolperstein.findByIdAndRemove(req.params.id, function(err, stolperstein) {
		if (!err && stolperstein) {
			res.send(204);
		} else {
			res.send(404, err);
		}
	});
}<|endoftext|>


<commit_before>var convert_home_js = (function($){
    // init drag file uploader
    var init_video_parts = function(){
        var _drag_container = document.getElementById('drag-file-container');
        var _video = document.getElementById('video-prop');
        var _video_drag_slider = document.getElementById('video-control-drag');
        var _timeout_id, _video_start_time = 0, _video_end_time = 5, _video_duration = 30;
        var _youtube_player, _youtube_video_id, _video_played = false;
        var _upload_file_handle, _current_video_type;

        // when meta data for the video is loaded
        _video.onloadedmetadata = function() {
            _video_duration = _video.duration;
            _reset_video_slider(0, 5, _video_duration);
        };

        // when video play
        _video.onplay = function(){
            if( !_video_played ){
                _video_played = true;

                $('#video-control-drag').fadeIn();
            }
        }

        // video drag envet
        _drag_container.ondragover = function (event) {
            event.preventDefault();
            event.stopPropagation();
            return false;
        };

        _drag_container.ondragend = function (event) {
            event.preventDefault();
            event.stopPropagation();
            return false;
        };

        _drag_container.ondrop = function (event) {
            event.preventDefault();
            event.stopPropagation();

            reset_video_from_page();

            var files = event.dataTransfer.files;
            _upload_file_handle = files[0];
            _read_video_blob_data(_upload_file_handle)
        };

        // create video slider
        noUiSlider.create(_video_drag_slider, {
            start: [ _video_start_time, _video_end_time ],
            behaviour: 'drag',
            connect: true,
            margin: 1,
            step : 1,
            tooltips: [ wNumb({ decimals: 0 }), wNumb({ decimals: 0 }) ],
            range: {
                'min':  0,
                'max':  _video_duration
            }
        });

        // listening the video slider evnet
        _video_drag_slider.noUiSlider.on('change', function( data, handle){
            _video_start_time = data[0],
            _video_end_time = data[1];

            if(_current_video_type == 'youtube'){
                _youtube_player.loadVideoById({
                    videoId:_youtube_video_id,
                    startSeconds:_video_start_time
                });

                // clear timeout
                clearTimeout(_timeout_id);
                // paused when reach the end time
                _timeout_id = setTimeout(function(){
                    _youtube_player.pauseVideo();
                }, (_video_end_time-_video_start_time+1)*1000);
            }else{
                // clear timeout
                clearTimeout(_timeout_id);

                // set start time
                _video.currentTime = _video_start_time;
                _video.play();

                // paused when reach the end time
                _timeout_id = setTimeout(function(){
                    _video.pause();
                }, (_video_end_time-_video_start_time+1)*1000);
            }
        });

        // test browser support
        var _test_browser = function(){
            // test browser support html5 video or not
            var test_env = {
                filereader: typeof FileReader != 'undefined',
                dnd: 'draggable' in document.createElement('span'),
                formdata: !!window.FormData,
                progress: "upload" in new XMLHttpRequest
            };

            "filereader formdata progress".split(' ').forEach(function (api) {
                if (test_env[api] === false) {
                    alert('do not support drag upload!');
                }
            });
        }

        // reset all div
        var _reset_all_elements = function(){
            $('.video-convert-result').hide();
            $('.video-progress-bar-wrap').hide();
            $('#video-control-drag').hide();
            $('#drag-file-container').show();
            $('#vp-mp4').attr('src', '');
        }

        // send uploaded video data to server
        var send_request = function(form_data){
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/convert/video');

            xhr.upload.onloadstart = function (event) {
                $('.video-progress-bar-wrap').show();
                $('.video-convert-result').hide();
                $('.vup-text').text('Converting...');
            }

            xhr.upload.onprogress = function (event) {
                if (event.lengthComputable) {
                    var complete_percentage = (event.loaded / event.total * 100 | 0);
                    $('.video-upload-progress').width(complete_percentage+'%');
                }
            }

            xhr.onload = function(result) {
                var res_json = jQuery.parseJSON(xhr.responseText);
                if(!res_json.error){
                    $('.video-convert-result').show();
                    $('.video-progress-bar-wrap').hide();

                    $('.vcr-a').attr('href', res_json.response_file).text(res_json.response_file);
                    $('.generate-video-gif').attr('data-local-file', res_json.local_file);
                }
            };

            xhr.send(form_data);
        }

        // generate gif from video
        var generate_gif = function(event){
            var _gif_time_length = _video_end_time - _video_start_time,
                local_file = $('.generate-video-gif').attr('data-local-file');
            var form_data = new FormData();

            if(_current_video_type == 'video'){
                if( $('#vp-mp4').attr('src') == '' ){
                    swal({
                        title: "Error!",
                        text: "Please upload a video first.",
                        type: "error",
                        confirmButtonText: "Cool"
                    });
                    return;
                }
            }

            form_data.append('start_timestamps', _video_start_time);
            form_data.append('gif_duration', _gif_time_length);
            form_data.append('local_file', local_file);

            if(_current_video_type == 'video'){
                form_data.append('file', _upload_file_handle);
                form_data.append('type', 'video');
            }else if(_current_video_type == 'youtube'){
                form_data.append('type', 'youtube');
                form_data.append('youtube_id', _youtube_video_id);
            }

            send_request(form_data);
        }

        // upload file trigger event
        var upload_file_trigger = function(){
            $('#upload-file-input').trigger('click');
        }

        // upload file
        var upload_file = function(event){
            var files = document.getElementById('upload-file-input').files;
            _upload_file_handle = files[0];

            reset_video_from_page();
            _read_video_blob_data(_upload_file_handle);
        }

        // reset video slider
        var _reset_video_slider = function(starttime, endtime, duration){
            // update video slider range
            _video_drag_slider.noUiSlider.set([starttime, endtime]);
            _video_drag_slider.noUiSlider.updateOptions({
                range: {
                    'min': 0,
                    'max': parseInt(duration)
                }
            });
        }

        // display related video div
        var _show_related_video_elements = function(){
            if(_current_video_type == 'video'){
                $('#video-prop').show();

                $('#player-youtube').hide();
                $('#drag-file-container').hide();
                if(_youtube_player && _youtube_player.f != null){
                    _youtube_player.destroy();
                }
            }else if(_current_video_type == 'youtube'){
                $('#player-youtube').show();

                $('#video-prop').hide();
                $('#drag-file-container').hide();
            }
        }

        // read video blob data
        var _read_video_blob_data = function(file){
            var reader = new FileReader(),
                mime = file.type;

            // only support mp4 video
            if(mime != 'video/mp4'){
                swal({
                    title: "Error!",
                    text: "Sorry, we only support mp4 video!",
                    type: "error",
                    confirmButtonText: "Cool"
                });
                return;
            }

            // read video data as buffer
            reader.readAsArrayBuffer(file);

            // The load event is fired when a resource and its dependent resources have finished loading.
            reader.onload = function(evt) {
                if (evt.target.readyState == FileReader.DONE) {
                    var blob = new Blob([evt.target.result], {type: mime}),
                        video_blob_url = (URL || webkitURL).createObjectURL(blob);

                    _show_video_preview(video_blob_url);
                }
            }
        }

        // show video preview
        var _show_video_preview = function(video_blob_url){
            _current_video_type = 'video';
            _video_played = false;
            $('.generate-video-gif').attr('data-local-file', '');

            // set the video source
            $('#vp-mp4').attr('src', video_blob_url);
            _video.load();

            // display related video div
            _show_related_video_elements();
        }

        // reset/remove video from page
        var reset_video_from_page = function(event){
            _reset_all_elements();
        }

        // add a video link
        var add_video_link = function(event){
            var $obj = $(event.target),
                video_link = $obj.closest('.modal-content').find('.video-add-link-input').val();

            if(video_link==''){
                swal({
                    title: "Error!",
                    text: "Sorry, your video link is invalid, please try another one.",
                    type: "error",
                    confirmButtonText: "Cool"
                });
                return;
            }

            $obj.closest('.modal-content').find('.video-add-link-input').val('');
            $('#video-control-drag').hide();
            $('.video-convert-result').hide();

            _youtube_video_id = video_link.replace(/.*\?v=/, '');
            load_youtube_video(_youtube_video_id);

            // close modal
            $('#video-add-link').modal('hide')
        }

        // load youtube video
        var load_youtube_video = function(_youtube_video_id){
            _current_video_type = 'youtube';
            _video_played = false;
            $('.generate-video-gif').attr('data-local-file', '');

            if(_youtube_player && _youtube_player.f != null){
                _youtube_player.destroy();
            }

            // load new youtube video
            _youtube_player = new YT.Player('player-youtube', {
                height: '300',
                videoId: _youtube_video_id,
                events: {
                    'onReady': youtube_ready_play,
                    'onStateChange': youtube_state_change
                }
            });

            // display related video div
            _show_related_video_elements();
        }

        // youtube video load
        var init_youtube_video_libs = function(){
            var tag = document.createElement('script');
            var firstScriptTag = document.getElementsByTagName('script')[0];

            tag.src = "https://www.youtube.com/iframe_api";
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        }

        // The API will call this function when the video player is ready.
        var youtube_ready_play = function (event) {
            event.target.pauseVideo();
        }

        // if youtube finished load
        var youtube_state_change = function(event){
            if (event.data == YT.PlayerState.PLAYING && !_video_played) {
                _video_played = true;

                // reset video slider
                _reset_video_slider(0, 5, _youtube_player.getDuration());
                $('#video-control-drag').fadeIn();
            }
        }

        return {
            load : function(){
                _test_browser();
                init_youtube_video_libs();
                $('.generate-video-gif').on('click', generate_gif);
                $('.reset-video').on('click', reset_video_from_page);
                $('.upload-file-bottom').on('click', upload_file_trigger);
                $('#upload-file-input').on('change', upload_file);
                $('.video-add-link-button').on('click', add_video_link);
            }
        }
    }

    // content scroll
    var init_content_scroll = function(){
        window.sr = ScrollReveal({
            reset:true
        }).reveal('.wrap-3, .wrap-4, .wrap-5');

        sr.reveal('.top-content-1', {
            delay    : 200,
            distance : '90px',
            origin : 'bottom',
            scale    : 1.1
        });

        sr.reveal('.top-content-2', {
            delay    : 200,
            origin : 'top',
            distance : '90px',
            scale    : 1.1
        });
    }

    // init image scroll
    var init_image_scroll = function(){
        $('.img-scroll-holder').imageScroll({
            coverRatio: 0.5
        });
    }

    // init carousel
    var init_carousel = function(){
        $('.owl-carousel').owlCarousel({
            loop:true,
            margin:10,
            nav:false,
            responsive:{
                0:{
                    items:1
                },
                600:{
                    items:3
                },
                1000:{
                    items:5
                }
            }
        })
    }

    return {
        bind : function(){

        },
        init : function(){
            init_video_parts().load();
            init_content_scroll();
            init_image_scroll();
            init_carousel();
        }
    }
})($);<commit_msg>reset start end time<commit_after>var convert_home_js = (function($){
    // init drag file uploader
    var init_video_parts = function(){
        var _drag_container = document.getElementById('drag-file-container');
        var _video = document.getElementById('video-prop');
        var _video_drag_slider = document.getElementById('video-control-drag');
        var _timeout_id, _video_start_time = 0, _video_end_time = 5, _video_duration = 30;
        var _youtube_player, _youtube_video_id, _video_played = false;
        var _upload_file_handle, _current_video_type;

        // when meta data for the video is loaded
        _video.onloadedmetadata = function() {
            _video_duration = _video.duration;
            _video_start_time=0;
            _video_end_time=5
            _reset_video_slider(_video_duration);
        };

        // when video play
        _video.onplay = function(){
            if( !_video_played ){
                _video_played = true;

                $('#video-control-drag').fadeIn();
            }
        }

        // video drag envet
        _drag_container.ondragover = function (event) {
            event.preventDefault();
            event.stopPropagation();
            return false;
        };

        _drag_container.ondragend = function (event) {
            event.preventDefault();
            event.stopPropagation();
            return false;
        };

        _drag_container.ondrop = function (event) {
            event.preventDefault();
            event.stopPropagation();

            reset_video_from_page();

            var files = event.dataTransfer.files;
            _upload_file_handle = files[0];
            _read_video_blob_data(_upload_file_handle)
        };

        // create video slider
        noUiSlider.create(_video_drag_slider, {
            start: [ _video_start_time, _video_end_time ],
            behaviour: 'drag',
            connect: true,
            margin: 1,
            step : 1,
            tooltips: [ wNumb({ decimals: 0 }), wNumb({ decimals: 0 }) ],
            range: {
                'min':  0,
                'max':  _video_duration
            }
        });

        // listening the video slider evnet
        _video_drag_slider.noUiSlider.on('change', function( data, handle){
            _video_start_time = data[0],
            _video_end_time = data[1];

            if(_current_video_type == 'youtube'){
                _youtube_player.loadVideoById({
                    videoId:_youtube_video_id,
                    startSeconds:_video_start_time
                });

                // clear timeout
                clearTimeout(_timeout_id);
                // paused when reach the end time
                _timeout_id = setTimeout(function(){
                    _youtube_player.pauseVideo();
                }, (_video_end_time-_video_start_time+1)*1000);
            }else{
                // clear timeout
                clearTimeout(_timeout_id);

                // set start time
                _video.currentTime = _video_start_time;
                _video.play();

                // paused when reach the end time
                _timeout_id = setTimeout(function(){
                    _video.pause();
                }, (_video_end_time-_video_start_time+1)*1000);
            }
        });

        // test browser support
        var _test_browser = function(){
            // test browser support html5 video or not
            var test_env = {
                filereader: typeof FileReader != 'undefined',
                dnd: 'draggable' in document.createElement('span'),
                formdata: !!window.FormData,
                progress: "upload" in new XMLHttpRequest
            };

            "filereader formdata progress".split(' ').forEach(function (api) {
                if (test_env[api] === false) {
                    alert('do not support drag upload!');
                }
            });
        }

        // reset all div
        var _reset_all_elements = function(){
            $('.video-convert-result').hide();
            $('.video-progress-bar-wrap').hide();
            $('#video-control-drag').hide();
            $('#drag-file-container').show();
            $('#vp-mp4').attr('src', '');
        }

        // send uploaded video data to server
        var send_request = function(form_data){
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/convert/video');

            xhr.upload.onloadstart = function (event) {
                $('.video-progress-bar-wrap').show();
                $('.video-convert-result').hide();
                $('.vup-text').text('Converting...');
            }

            xhr.upload.onprogress = function (event) {
                if (event.lengthComputable) {
                    var complete_percentage = (event.loaded / event.total * 100 | 0);
                    $('.video-upload-progress').width(complete_percentage+'%');
                }
            }

            xhr.onload = function(result) {
                var res_json = jQuery.parseJSON(xhr.responseText);
                if(!res_json.error){
                    $('.video-convert-result').show();
                    $('.video-progress-bar-wrap').hide();

                    $('.vcr-a').attr('href', res_json.response_file).text(res_json.response_file);
                    $('.generate-video-gif').attr('data-local-file', res_json.local_file);
                }
            };

            xhr.send(form_data);
        }

        // generate gif from video
        var generate_gif = function(event){
            var _gif_time_length = _video_end_time - _video_start_time,
                local_file = $('.generate-video-gif').attr('data-local-file');
            var form_data = new FormData();

            if(_current_video_type == 'video'){
                if( $('#vp-mp4').attr('src') == '' ){
                    swal({
                        title: "Error!",
                        text: "Please upload a video first.",
                        type: "error",
                        confirmButtonText: "Cool"
                    });
                    return;
                }
            }

            form_data.append('start_timestamps', _video_start_time);
            form_data.append('gif_duration', _gif_time_length);
            form_data.append('local_file', local_file);

            if(_current_video_type == 'video'){
                form_data.append('file', _upload_file_handle);
                form_data.append('type', 'video');
            }else if(_current_video_type == 'youtube'){
                form_data.append('type', 'youtube');
                form_data.append('youtube_id', _youtube_video_id);
            }

            send_request(form_data);
        }

        // upload file trigger event
        var upload_file_trigger = function(){
            $('#upload-file-input').trigger('click');
        }

        // upload file
        var upload_file = function(event){
            var files = document.getElementById('upload-file-input').files;
            _upload_file_handle = files[0];

            reset_video_from_page();
            _read_video_blob_data(_upload_file_handle);
        }

        // reset video slider
        var _reset_video_slider = function(duration){
            // update video slider range
            _video_drag_slider.noUiSlider.set([_video_start_time, _video_end_time]);
            _video_drag_slider.noUiSlider.updateOptions({
                range: {
                    'min': 0,
                    'max': parseInt(duration)
                }
            });
        }

        // display related video div
        var _show_related_video_elements = function(){
            if(_current_video_type == 'video'){
                $('#video-prop').show();

                $('#player-youtube').hide();
                $('#drag-file-container').hide();
                if(_youtube_player && _youtube_player.f != null){
                    _youtube_player.destroy();
                }
            }else if(_current_video_type == 'youtube'){
                $('#player-youtube').show();

                $('#video-prop').hide();
                $('#drag-file-container').hide();
            }
        }

        // read video blob data
        var _read_video_blob_data = function(file){
            var reader = new FileReader(),
                mime = file.type;

            // only support mp4 video
            if(mime != 'video/mp4'){
                swal({
                    title: "Error!",
                    text: "Sorry, we only support mp4 video!",
                    type: "error",
                    confirmButtonText: "Cool"
                });
                return;
            }

            // read video data as buffer
            reader.readAsArrayBuffer(file);

            // The load event is fired when a resource and its dependent resources have finished loading.
            reader.onload = function(evt) {
                if (evt.target.readyState == FileReader.DONE) {
                    var blob = new Blob([evt.target.result], {type: mime}),
                        video_blob_url = (URL || webkitURL).createObjectURL(blob);

                    _show_video_preview(video_blob_url);
                }
            }
        }

        // show video preview
        var _show_video_preview = function(video_blob_url){
            _current_video_type = 'video';
            _video_played = false;
            $('.generate-video-gif').attr('data-local-file', '');

            // set the video source
            $('#vp-mp4').attr('src', video_blob_url);
            _video.load();

            // display related video div
            _show_related_video_elements();
        }

        // reset/remove video from page
        var reset_video_from_page = function(event){
            _reset_all_elements();
        }

        // add a video link
        var add_video_link = function(event){
            var $obj = $(event.target),
                video_link = $obj.closest('.modal-content').find('.video-add-link-input').val();

            if(video_link==''){
                swal({
                    title: "Error!",
                    text: "Sorry, your video link is invalid, please try another one.",
                    type: "error",
                    confirmButtonText: "Cool"
                });
                return;
            }

            $obj.closest('.modal-content').find('.video-add-link-input').val('');
            $('#video-control-drag').hide();
            $('.video-convert-result').hide();

            _youtube_video_id = video_link.replace(/.*\?v=/, '');
            load_youtube_video(_youtube_video_id);

            // close modal
            $('#video-add-link').modal('hide')
        }

        // load youtube video
        var load_youtube_video = function(_youtube_video_id){
            _current_video_type = 'youtube';
            _video_played = false;
            $('.generate-video-gif').attr('data-local-file', '');

            if(_youtube_player && _youtube_player.f != null){
                _youtube_player.destroy();
            }

            // load new youtube video
            _youtube_player = new YT.Player('player-youtube', {
                height: '300',
                videoId: _youtube_video_id,
                events: {
                    'onReady': youtube_ready_play,
                    'onStateChange': youtube_state_change
                }
            });

            // display related video div
            _show_related_video_elements();
        }

        // youtube video load
        var init_youtube_video_libs = function(){
            var tag = document.createElement('script');
            var firstScriptTag = document.getElementsByTagName('script')[0];

            tag.src = "https://www.youtube.com/iframe_api";
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        }

        // The API will call this function when the video player is ready.
        var youtube_ready_play = function (event) {
            event.target.pauseVideo();
        }

        // if youtube finished load
        var youtube_state_change = function(event){
            if (event.data == YT.PlayerState.PLAYING && !_video_played) {
                _video_played = true;

                // reset video slider
                _video_start_time=0;
                _video_end_time=5
                _reset_video_slider(_youtube_player.getDuration());
                $('#video-control-drag').fadeIn();
            }
        }

        return {
            load : function(){
                _test_browser();
                init_youtube_video_libs();
                $('.generate-video-gif').on('click', generate_gif);
                $('.reset-video').on('click', reset_video_from_page);
                $('.upload-file-bottom').on('click', upload_file_trigger);
                $('#upload-file-input').on('change', upload_file);
                $('.video-add-link-button').on('click', add_video_link);
            }
        }
    }

    // content scroll
    var init_content_scroll = function(){
        window.sr = ScrollReveal({
            reset:true
        }).reveal('.wrap-3, .wrap-4, .wrap-5');

        sr.reveal('.top-content-1', {
            delay    : 200,
            distance : '90px',
            origin : 'bottom',
            scale    : 1.1
        });

        sr.reveal('.top-content-2', {
            delay    : 200,
            origin : 'top',
            distance : '90px',
            scale    : 1.1
        });
    }

    // init image scroll
    var init_image_scroll = function(){
        $('.img-scroll-holder').imageScroll({
            coverRatio: 0.5
        });
    }

    // init carousel
    var init_carousel = function(){
        $('.owl-carousel').owlCarousel({
            loop:true,
            margin:10,
            nav:false,
            responsive:{
                0:{
                    items:1
                },
                600:{
                    items:3
                },
                1000:{
                    items:5
                }
            }
        })
    }

    return {
        bind : function(){

        },
        init : function(){
            init_video_parts().load();
            init_content_scroll();
            init_image_scroll();
            init_carousel();
        }
    }
})($);<|endoftext|>


<commit_before>define([
    'jquery', //requires jquery
    'stripe-checkout'
], function ($) {
    var $donationForm = $('.stripe-custom-checkout');
    var $submitButton = $donationForm.find('.cta');

    var handler = StripeCheckout.configure({
        key: $donationForm.data('stripeKey'),
        image: $donationForm.data('stripeIcon'),
        token: function (token) {
            $submitButton.prop('disabled', true).addClass('disabled');
            var campaign = $donationForm.find('[name=campaign]').val();
            var amount = $donationForm.find('[name=amount]').val();
            var csrfToken = $donationForm.find('[name=csrfmiddlewaretoken]').val();
            var interval = $donationForm.find('[name=interval]').val();
            var data = {
                'stripe_token': token.id,
                'receipt_email': token.email,
                'campaign': campaign,
                'amount': amount,
                'interval': interval,
                'csrfmiddlewaretoken': csrfToken
            };

            $.ajax({
                type: "POST",
                url: $donationForm.attr('action'),
                data: data,
                dataType: 'json',
                success: function (data) {
                    if (data.success) {
                        window.location = data.redirect;
                    } else {
                        $submitButton.prop('disabled', false).removeClass('disabled');
                        alert(data.error);
                    }
                }
            })
        }
    });

    // Close Checkout on page navigation
    $(window).on('popstate', function () {
        handler.close();
    });

    $donationForm.on('submit', function (e) {
        e.preventDefault();
        var interval = $donationForm.find('[name=interval]').val();
        var amountDollars = $donationForm.find('[name=amount]').val();
        var amountCents = parseFloat(amountDollars) * 100;

        handler.open({
            name: 'Django Software Foundation',
            description: $donationForm.data('campaignName'),
            amount: amountCents,
            currency: 'USD',
            bitcoin: true
        });
    });
});
<commit_msg>Added zip code and address checks to Stripe integration.<commit_after>define([
    'jquery', //requires jquery
    'stripe-checkout'
], function ($) {
    var $donationForm = $('.stripe-custom-checkout');
    var $submitButton = $donationForm.find('.cta');

    var handler = StripeCheckout.configure({
        key: $donationForm.data('stripeKey'),
        image: $donationForm.data('stripeIcon'),
        token: function (token) {
            $submitButton.prop('disabled', true).addClass('disabled');
            var campaign = $donationForm.find('[name=campaign]').val();
            var amount = $donationForm.find('[name=amount]').val();
            var csrfToken = $donationForm.find('[name=csrfmiddlewaretoken]').val();
            var interval = $donationForm.find('[name=interval]').val();
            var data = {
                'stripe_token': token.id,
                'receipt_email': token.email,
                'campaign': campaign,
                'amount': amount,
                'interval': interval,
                'csrfmiddlewaretoken': csrfToken
            };

            $.ajax({
                type: "POST",
                url: $donationForm.attr('action'),
                data: data,
                dataType: 'json',
                success: function (data) {
                    if (data.success) {
                        window.location = data.redirect;
                    } else {
                        $submitButton.prop('disabled', false).removeClass('disabled');
                        alert(data.error);
                    }
                }
            })
        }
    });

    // Close Checkout on page navigation
    $(window).on('popstate', function () {
        handler.close();
    });

    $donationForm.on('submit', function (e) {
        e.preventDefault();
        var interval = $donationForm.find('[name=interval]').val();
        var amountDollars = $donationForm.find('[name=amount]').val();
        var amountCents = parseFloat(amountDollars) * 100;

        handler.open({
            name: 'Django Software Foundation',
            description: $donationForm.data('campaignName'),
            amount: amountCents,
            currency: 'USD',
            bitcoin: true,
            zipCode: true,
            billingAddress: true
        });
    });
});
<|endoftext|>


<commit_before>/*
    deps: Sortable
    see https://github.com/RubaXa/Sortable

    Required html data attributes:
    * data-row - elements which need to be dragged)

    Optional
    * data-handle - handle for draggable item
    * data-delete - to delete a row, delete -requires- placeholder
 */

var sortable = {
    element: $( '[data-sortable]' ),
    row: "",
    placeholder: "",
    handle: "",
    delete: "",

    init: function () {
        var self = this;

        if ( self.element.size() ) {

            // get required data
            self.rowClass = self.element.data( 'row' );
            self.row = self.element.find( self.rowClass );
            self.placeholder = self.element.data( 'placeholder' );
            self.handle = self.element.data( 'handle' );
            self.delete = self.element.data( 'delete' );
            self.delete = self.row.find( self.delete );

            // error handling
            if ( !self.row.size() ) {
                console.log( 'Sortable: data-to-sort not valid or empty' )
                return
            }

            // optional delete, which requires placeholder
            if ( self.delete.size() && self.placeholder.size()) {

                self.delete.on( 'click', function ( event ) {
                    self.remove( this, self );
                });
            }

            // create a sortable list
            self.sorting();
        };
    },

    sorting: function () {
        var self = this

        // convert jquery element in javascript element
        let htmlElement = self.element.get(0);

        // sortable config
        var config = {
            animation: 200,
            onUpdate: function ( event ) {
                self.recalc()
            }
        }

        // is there a handle?
        if ( self.handle != undefined ) {
            config.handle = self.handle;
        }

        // init sortable
        var sortable = Sortable.create( htmlElement, config );
    },

    recalc: function () {
        var self = this;
        var items = $( self.rowClass );

        items.each( function ( i, el ) {
            let element = $( el );
            let index = parseInt( items.index( element ) );
            let placeholder = element.find( self.placeholder );

            // update placeholders with new positions
            placeholder.val(  index  );
        });
    },

    remove: function ( el, self ) {
        let element = $( el );
        let rule = element.closest( '.rule' );
        let ruleWrapper = rule.parent();

        // flag for deletion
        rule.find( '.delete input' ).prop( "checked", true );

        // hide rule
        rule.addClass( 'removed' ).appendTo( ruleWrapper );

        // recalc positions
        self.recalc();
    }
}

sortable.init()<commit_msg>terminology, added delete placeholder, codestyle and some comments<commit_after>/*
    deps: Sortable
    see https://github.com/RubaXa/Sortable

    Required html data attributes:
    * data-sortable - initiates sortable)
    * data-row - defines a row to sort

    Optional
    * data-sort-handle - to specify a specific dragging handle
    * data-sort-placeholder - field to save position of row

    * data-delete-handle - delete button
    * data-delete-placeholder - field to check as delete
 */

var sortable = {
    element: $( '[data-sortable]' ),
    rowClass: "",
    row: "",
    sortHandle: "",
    sortPlaceholder: "",
    deleteHandle: "",
    deletePlaceholder: "",

    init: function () {
        var self = this;

        // is there a sortable element?
        if ( self.element.size() ) {
            self.rowClass = self.element.data( 'row' );
            self.row = self.element.find( self.rowClass );

            // error handling, is there something to sort?
            if ( !self.row.size() ) {
                console.log( 'Sortable: data-to-sort not valid or empty' )
                return
            }

            // optional delete
            self.deleteHandle = self.row.find( self.element.data( 'delete-handle' ) );
            if ( self.deleteHandle.size() ) {

                self.deleteHandle.on( 'click', function ( event ) {
                    self.remove( this, self );
                });
            }

            // create a sortable list
            self.sorting();
        };
    },

    sorting: function () {
        var self = this

        // convert jquery element in javascript element
        let htmlElement = self.element.get(0);

        // sortable config
        var config = {
            animation: 200,
            onUpdate: function ( event ) {
                // recalc positions when sorting is updated
                self.recalc()
            }
        }

        // is there a sort handle?
        self.sortHandle = self.element.data( 'sort-handle' );
        if ( self.sortHandle != undefined ) {
            config.handle = self.sortHandle;
        }

        // init sortable
        var sortable = Sortable.create( htmlElement, config );
    },

    recalc: function () {
        var self = this;
        var items = $( self.rowClass );

        // where to same positions?
        self.sortPlaceholder = self.element.data( 'sort-placeholder' );

        // update positions
        items.each( function ( i, el ) {
            let element = $( el );
            let index = parseInt( items.index( element ) );
            let placeholder = element.find( self.sortPlaceholder );

            // is there something to save to?
            if ( placeholder.size() ) {
                placeholder.val(  index  );
            }
        });
    },

    remove: function ( el, self ) {
        let element = $( el );
        let rule = element.closest( self.rowClass );
        let ruleWrapper = rule.parent();

        // flag for deletion if there's a placeholder
        self.deletePlaceholderClass = self.element.data( 'delete-placeholder' );
        self.deletePlaceholder = rule.find( self.deletePlaceholderClass );

        if ( self.deletePlaceholder.size() ){
            self.deletePlaceholder.prop( "checked", true );
        }

        // hide rule
        rule.addClass( 'removed' ).appendTo( ruleWrapper );

        // recalc positions
        self.recalc();
    }
}

sortable.init()<|endoftext|>


<commit_before>import BulkTopicSelection from 'discourse/mixins/bulk-topic-selection';

export default Ember.Controller.extend(BulkTopicSelection, {
  tag: null,
  list: null,

  canAdminTag: Ember.computed.alias('currentUser.staff'),

  isTrue: true,
  canFavorite: true,

  canFavoriteTag: function() {

    const self = this;
    var ticker = this.get('tag.id');
    console.log('checking can fav stock:' + ticker);

    Discourse.ajax("/stock/get_users_favorite_stocks", {
          type: "GET",
        }).then(function(data) {
          console.log(data.stock);
          console.log('checking can fav stock step 2:' + ticker);
          //data = data.toString;

          var favable = true;
          for (var i = data.stock.length - 1; i >= 0; i--) {
            var stock = jQuery.parseJSON(data.stock[i]);
            console.log('checking can fav stock step 3:' + ticker + i);
            if(ticker.toLowerCase() == stock.symbol.toLowerCase()) { console.log(ticker + ' is a favorite stock: ' + stock.symbol.toLowerCase()); favable = false; }
          }
          console.log('favable: ' + favable);
          //self.set('canFavorite', favable);
          //console.log('canfavorite: ' + self.get('canFavorite'));
          //return self.get('canFavorite');
          return favable;

    });

    //return isStockUsersFavorite(ticker);

  }.property('canFavorite'),

  loadMoreTopics() {
    return this.get('list').loadMore();
  },

  actions: {
    refresh() {
      const self = this;
      return Discourse.TopicList.list('tags/' + this.get('tag.id')).then(function(list) {
        self.set('list', list);
        self.resetSelected();
      });
    },

    deleteTag() {
      const self = this;
      bootbox.confirm(I18n.t('tagging.delete_confirm'), function(result) {
        if (!result) { return; }

        self.get('tag').destroyRecord().then(function() {
          self.transitionToRoute('tags.index');
        }).catch(function() {
          bootbox.alert(I18n.t('generic_error'));
        });
      });
    },

    favoriteTag() {
      const self = this;
      console.log('favoriting');
      //Discourse.ajax("/stock/add_stock_to_users_favorite_stocks?ticker=" + this.get('tag.id') + ".ol", {
       // type: "GET",
      //});
      addStockToUsersFavoriteStocks(this.get('tag.id'));
    },
    unFavoriteTag() {
      const self = this;
      console.log('unfavoriting');
      removeStockFromUsersFavoriteStocks(this.get('tag.id'));
    },

    changeTagNotification(id) {
      const tagNotification = this.get('tagNotification');
      tagNotification.update({ notification_level: id });
    }
  }
});
<commit_msg>Update tags-show.js.es6<commit_after>import BulkTopicSelection from 'discourse/mixins/bulk-topic-selection';

export default Ember.Controller.extend(BulkTopicSelection, {
  tag: null,
  list: null,

  canAdminTag: Ember.computed.alias('currentUser.staff'),

  isTrue: true,
  canFavorite: true,

  canFavoriteTag: function() {

    const self = this;
    var ticker = this.get('tag.id');
    console.log('checking can fav stock:' + ticker);

    Discourse.ajax("/stock/get_users_favorite_stocks", {
          type: "GET",
        }).then(function(data) {
          console.log(data.stock);
          console.log('checking can fav stock step 2:' + ticker);
          //data = data.toString;

          var favable = true;
          for (var i = data.stock.length - 1; i >= 0; i--) {
            var stock = jQuery.parseJSON(data.stock[i]);
            console.log('checking can fav stock step 3:' + ticker + i);
            if(ticker.toLowerCase() == stock.symbol.toLowerCase()) { console.log(ticker + ' is a favorite stock: ' + stock.symbol.toLowerCase()); favable = false; }
          }
          console.log('favable: ' + favable);
          self.set('canFavorite', favable);
          console.log('canfavorite: ' + self.get('canFavorite'));
          //return self.get('canFavorite');
          return favable;

    });

    //return isStockUsersFavorite(ticker);

  }.property('canFavorite'),

  loadMoreTopics() {
    return this.get('list').loadMore();
  },

  actions: {
    refresh() {
      const self = this;
      return Discourse.TopicList.list('tags/' + this.get('tag.id')).then(function(list) {
        self.set('list', list);
        self.resetSelected();
      });
    },

    deleteTag() {
      const self = this;
      bootbox.confirm(I18n.t('tagging.delete_confirm'), function(result) {
        if (!result) { return; }

        self.get('tag').destroyRecord().then(function() {
          self.transitionToRoute('tags.index');
        }).catch(function() {
          bootbox.alert(I18n.t('generic_error'));
        });
      });
    },

    favoriteTag() {
      const self = this;
      console.log('favoriting');
      //Discourse.ajax("/stock/add_stock_to_users_favorite_stocks?ticker=" + this.get('tag.id') + ".ol", {
       // type: "GET",
      //});
      addStockToUsersFavoriteStocks(this.get('tag.id'));
    },
    unFavoriteTag() {
      const self = this;
      console.log('unfavoriting');
      removeStockFromUsersFavoriteStocks(this.get('tag.id'));
    },

    changeTagNotification(id) {
      const tagNotification = this.get('tagNotification');
      tagNotification.update({ notification_level: id });
    }
  }
});
<|endoftext|>


<commit_before>import BulkTopicSelection from 'discourse/mixins/bulk-topic-selection';

export default Ember.Controller.extend(BulkTopicSelection, {
  tag: null,
  list: null,

  canAdminTag: Ember.computed.alias('currentUser.staff'),

  canFavoriteTag: function() {

    const self = this;
    ticker = this.get('tag.id');
    console.log('checking can fav stock:' + ticker);

    Discourse.ajax("/stock/get_users_favorite_stocks", {
          type: "GET",
        }).then(function(data) {
          console.log(data.stock);
          console.log('checking can fav stock step 2:' + ticker);
          //data = data.toString;

          for (var i = data.stock.length - 1; i >= 0; i--) {
            stock = jQuery.parseJSON(data.stock[i]);
            console.log('checking can fav stock step 3:' + ticker + i);
            if(ticker.toLowerCase() == stock.symbol.toLowerCase()) { console.log(ticker + ' is a favorite stock: ' + stock.symbol.toLowerCase()); return true; }
          }
          console.log(ticker + ' is not a favorite stock');
          return false;

    });

    //console.log(isStockUsersFavorite(this.get('tag.id') + ".ol"));

  },

  loadMoreTopics() {
    return this.get('list').loadMore();
  },

  actions: {
    refresh() {
      const self = this;
      return Discourse.TopicList.list('tags/' + this.get('tag.id')).then(function(list) {
        self.set('list', list);
        self.resetSelected();
      });
    },

    deleteTag() {
      const self = this;
      bootbox.confirm(I18n.t('tagging.delete_confirm'), function(result) {
        if (!result) { return; }

        self.get('tag').destroyRecord().then(function() {
          self.transitionToRoute('tags.index');
        }).catch(function() {
          bootbox.alert(I18n.t('generic_error'));
        });
      });
    },

    favoriteTag() {
      const self = this;
      console.log('favoriting');
      //Discourse.ajax("/stock/add_stock_to_users_favorite_stocks?ticker=" + this.get('tag.id') + ".ol", {
       // type: "GET",
      //});
      addStockToUsersFavoriteStocks(this.get('tag.id') + ".ol");

    },

    changeTagNotification(id) {
      const tagNotification = this.get('tagNotification');
      tagNotification.update({ notification_level: id });
    }
  }
});
<commit_msg>remove .ol<commit_after>import BulkTopicSelection from 'discourse/mixins/bulk-topic-selection';

export default Ember.Controller.extend(BulkTopicSelection, {
  tag: null,
  list: null,

  canAdminTag: Ember.computed.alias('currentUser.staff'),

  canFavoriteTag: function() {

    const self = this;
    ticker = this.get('tag.id');
    console.log('checking can fav stock:' + ticker);

    Discourse.ajax("/stock/get_users_favorite_stocks", {
          type: "GET",
        }).then(function(data) {
          console.log(data.stock);
          console.log('checking can fav stock step 2:' + ticker);
          //data = data.toString;

          for (var i = data.stock.length - 1; i >= 0; i--) {
            stock = jQuery.parseJSON(data.stock[i]);
            console.log('checking can fav stock step 3:' + ticker + i);
            if(ticker.toLowerCase() == stock.symbol.toLowerCase()) { console.log(ticker + ' is a favorite stock: ' + stock.symbol.toLowerCase()); return true; }
          }
          console.log(ticker + ' is not a favorite stock');
          return false;

    });

    //console.log(isStockUsersFavorite(this.get('tag.id') + ".ol"));

  },

  loadMoreTopics() {
    return this.get('list').loadMore();
  },

  actions: {
    refresh() {
      const self = this;
      return Discourse.TopicList.list('tags/' + this.get('tag.id')).then(function(list) {
        self.set('list', list);
        self.resetSelected();
      });
    },

    deleteTag() {
      const self = this;
      bootbox.confirm(I18n.t('tagging.delete_confirm'), function(result) {
        if (!result) { return; }

        self.get('tag').destroyRecord().then(function() {
          self.transitionToRoute('tags.index');
        }).catch(function() {
          bootbox.alert(I18n.t('generic_error'));
        });
      });
    },

    favoriteTag() {
      const self = this;
      console.log('favoriting');
      //Discourse.ajax("/stock/add_stock_to_users_favorite_stocks?ticker=" + this.get('tag.id') + ".ol", {
       // type: "GET",
      //});
      addStockToUsersFavoriteStocks(this.get('tag.id'));

    },

    changeTagNotification(id) {
      const tagNotification = this.get('tagNotification');
      tagNotification.update({ notification_level: id });
    }
  }
});
<|endoftext|>


<commit_before>/**
 * Notification component.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { map } from 'lodash';

/*
 * WordPress dependencies
 */
import { useState, useRef, useEffect, Fragment, isValidElement } from '@wordpress/element';

/*
 * Internal dependencies
 */
import GoogleLogoIcon from '../../../svg/logo-g.svg';
import { sanitizeHTML } from '../../util/sanitize';
import DataBlock from '../DataBlock';
import Button from '../Button';
import Warning from './warning';
import Error from './error';
import Link from '../Link';
import ModuleIcon from '../ModuleIcon';
import { getItem, setItem, deleteItem } from '../../googlesitekit/api/cache';

function Notification( {
	dismissExpires,
	showOnce,
	onDismiss,
	onCTAClick,
	children,
	id,
	className,
	title,
	description,
	blockData,
	WinImageSVG,
	SmallImageSVG,
	format,
	learnMoreURL,
	learnMoreDescription,
	learnMoreLabel,
	ctaLink,
	ctaLabel,
	ctaTarget,
	type,
	dismiss,
	isDismissable,
	logo,
	module,
	moduleName,
	pageIndex,
	anchorLink,
	anchorLinkLabel,
} ) {
	const [ isClosed, setIsClosed ] = useState( false );
	const [ isDismissed, setIsDismissed ] = useState( false );
	const cardRef = useRef();

	useEffect( () => ( async () => {
		if ( showOnce ) {
			await setItem( `notification::displayed::${ id }`, new Date() );
		}
		if ( dismissExpires > 0 ) {
			await expireDismiss();
		}
		const { cacheHit } = await getItem( `notification::dismissed::${ id }` );
		setIsDismissed( cacheHit );
	} ) );

	async function handleDismiss( e ) {
		e.persist();
		e.preventDefault();

		if ( onDismiss ) {
			await onDismiss( e );
		}
		dismissNotification();
	}

	function dismissNotification() {
		const card = cardRef.current;

		setIsClosed( true );

		setTimeout( async () => {
			await setItem( `notification::dismissed::${ id }`, new Date() );
			if ( card?.style ) {
				card.style.display = 'none';
			}

			const event = new Event( 'notificationDismissed' );
			document.dispatchEvent( event );
		}, 350 );
	}

	async function handleCTAClick( e ) {
		e.persist();

		if ( onCTAClick ) {
			await onCTAClick( e );
		}

		if ( isDismissable ) {
			dismissNotification();
		}
	}

	async function expireDismiss() {
		const dismissed = await getItem( `notification::dismissed::${ id }` );

		if ( dismissed ) {
			const expiration = new Date( dismissed );
			expiration.setSeconds( expiration.getSeconds() + parseInt( dismissExpires, 10 ) );

			if ( expiration < new Date() ) {
				await deleteItem( `notification::dismissed::${ id }` );
			}
		}
	}

	if ( isDismissed.value ) {
		return null;
	}

	const closedClass = isClosed ? 'is-closed' : 'is-open';
	const inlineLayout = 'large' === format && 'win-stats-increase' === type;

	let layout = 'mdc-layout-grid__cell--span-12';
	if ( 'large' === format ) {
		layout = 'mdc-layout-grid__cell--order-2-phone ' +
				'mdc-layout-grid__cell--order-1-tablet ' +
				'mdc-layout-grid__cell--span-6-tablet ' +
				'mdc-layout-grid__cell--span-8-desktop ';

		if ( inlineLayout ) {
			layout = 'mdc-layout-grid__cell--order-2-phone ' +
						'mdc-layout-grid__cell--order-1-tablet ' +
						'mdc-layout-grid__cell--span-5-tablet ' +
						'mdc-layout-grid__cell--span-8-desktop ';
		}
	} else if ( 'small' === format ) {
		layout = 'mdc-layout-grid__cell--span-11-desktop ' +
				'mdc-layout-grid__cell--span-7-tablet ' +
				'mdc-layout-grid__cell--span-3-phone';
	}

	let icon;
	if ( 'win-warning' === type ) {
		icon = <Warning />;
	} else if ( 'win-error' === type ) {
		icon = <Error />;
	} else {
		icon = '';
	}

	const dataBlockMarkup = (
		<Fragment>
			{ blockData &&

				{
					map( blockData, ( block, i ) => {
						return (

									<DataBlock { ...block } />

						);
					} )
				}

			}
		</Fragment>
	);

	const inlineMarkup = (
		<Fragment>
			{ title &&

				{ title }

			}
			{ anchorLink && anchorLinkLabel &&

				<Link href={ anchorLink }>
					{ anchorLinkLabel }
				</Link>

			}
			{ description &&

					{ isValidElement( description ) ? description : (

					) }

					{ learnMoreLabel &&
					<Fragment>
						{ ' ' }
						<Link href={ learnMoreURL } external inherit>
							{ learnMoreLabel }
						</Link>
						{ learnMoreDescription }
					</Fragment>
					}
					{ pageIndex &&
					{ pageIndex }
					}

			}
			{ children }
		</Fragment>
	);

	const logoSVG = module
		? <ModuleIcon slug={ module } size={ 19 } />
		: <GoogleLogoIcon height="34" width="32" />;

	return (
		<section
			id={ id }
			ref={ cardRef }
			className={ classnames(
				className,
				'googlesitekit-publisher-win',
				{
					[ `googlesitekit-publisher-win--${ format }` ]: format,
					[ `googlesitekit-publisher-win--${ type }` ]: type,
					[ `googlesitekit-publisher-win--${ closedClass }` ]: closedClass,
				},
			) }
		>

					{ logo &&

							{ logoSVG }

						{ moduleName &&

							{ moduleName }

						}

					}

					{ SmallImageSVG &&

						<SmallImageSVG />

					}

						{ inlineLayout ? (

									{ inlineMarkup }

									{ dataBlockMarkup }

						) : (
							<Fragment>
								{ inlineMarkup }
								{ dataBlockMarkup }
							</Fragment>
						) }

						{ ctaLink &&
						<Button
							className="googlesitekit-notification__cta"
							href={ ctaLink }
							target={ ctaTarget }
							onClick={ handleCTAClick }
						>
							{ ctaLabel }
						</Button>
						}

						{ isDismissable && dismiss &&
						<Link onClick={ handleDismiss }>
							{ dismiss }
						</Link>
						}

					{ WinImageSVG &&

							<WinImageSVG />

					}

					{ ( 'win-error' === type || 'win-warning' === type ) &&

							{ icon }

					}

	);
}

Notification.propTypes = {
	id: PropTypes.string.isRequired,
	className: PropTypes.string,
	title: PropTypes.string.isRequired,
	description: PropTypes.node,
	learnMoreURL: PropTypes.string,
	learnMoreDescription: PropTypes.string,
	learnMoreLabel: PropTypes.string,
	blockData: PropTypes.array,
	WinImageSVG: PropTypes.elementType,
	SmallImageSVG: PropTypes.elementType,
	format: PropTypes.string,
	ctaLink: PropTypes.string,
	ctaLabel: PropTypes.string,
	type: PropTypes.string,
	dismiss: PropTypes.string,
	isDismissable: PropTypes.bool,
	logo: PropTypes.bool,
	module: PropTypes.string,
	moduleName: PropTypes.string,
	pageIndex: PropTypes.string,
	dismissExpires: PropTypes.number,
	showOnce: PropTypes.bool,
	onCTAClick: PropTypes.func,
	onDismiss: PropTypes.func,
	anchorLink: PropTypes.string,
	anchorLinkLabel: PropTypes.string,
};

Notification.defaultProps = {
	isDismissable: true,
	className: '',
	dismissExpires: 0,
	showOnce: false,
};

export default Notification;
<commit_msg>Rename accidentally misspelt className.<commit_after>/**
 * Notification component.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { map } from 'lodash';

/*
 * WordPress dependencies
 */
import { useState, useRef, useEffect, Fragment, isValidElement } from '@wordpress/element';

/*
 * Internal dependencies
 */
import GoogleLogoIcon from '../../../svg/logo-g.svg';
import { sanitizeHTML } from '../../util/sanitize';
import DataBlock from '../DataBlock';
import Button from '../Button';
import Warning from './warning';
import Error from './error';
import Link from '../Link';
import ModuleIcon from '../ModuleIcon';
import { getItem, setItem, deleteItem } from '../../googlesitekit/api/cache';

function Notification( {
	dismissExpires,
	showOnce,
	onDismiss,
	onCTAClick,
	children,
	id,
	className,
	title,
	description,
	blockData,
	WinImageSVG,
	SmallImageSVG,
	format,
	learnMoreURL,
	learnMoreDescription,
	learnMoreLabel,
	ctaLink,
	ctaLabel,
	ctaTarget,
	type,
	dismiss,
	isDismissable,
	logo,
	module,
	moduleName,
	pageIndex,
	anchorLink,
	anchorLinkLabel,
} ) {
	const [ isClosed, setIsClosed ] = useState( false );
	const [ isDismissed, setIsDismissed ] = useState( false );
	const cardRef = useRef();

	useEffect( () => ( async () => {
		if ( showOnce ) {
			await setItem( `notification::displayed::${ id }`, new Date() );
		}
		if ( dismissExpires > 0 ) {
			await expireDismiss();
		}
		const { cacheHit } = await getItem( `notification::dismissed::${ id }` );
		setIsDismissed( cacheHit );
	} ) );

	async function handleDismiss( e ) {
		e.persist();
		e.preventDefault();

		if ( onDismiss ) {
			await onDismiss( e );
		}
		dismissNotification();
	}

	function dismissNotification() {
		const card = cardRef.current;

		setIsClosed( true );

		setTimeout( async () => {
			await setItem( `notification::dismissed::${ id }`, new Date() );
			if ( card?.style ) {
				card.style.display = 'none';
			}

			const event = new Event( 'notificationDismissed' );
			document.dispatchEvent( event );
		}, 350 );
	}

	async function handleCTAClick( e ) {
		e.persist();

		if ( onCTAClick ) {
			await onCTAClick( e );
		}

		if ( isDismissable ) {
			dismissNotification();
		}
	}

	async function expireDismiss() {
		const dismissed = await getItem( `notification::dismissed::${ id }` );

		if ( dismissed ) {
			const expiration = new Date( dismissed );
			expiration.setSeconds( expiration.getSeconds() + parseInt( dismissExpires, 10 ) );

			if ( expiration < new Date() ) {
				await deleteItem( `notification::dismissed::${ id }` );
			}
		}
	}

	if ( isDismissed.value ) {
		return null;
	}

	const closedClass = isClosed ? 'is-closed' : 'is-open';
	const inlineLayout = 'large' === format && 'win-stats-increase' === type;

	let layout = 'mdc-layout-grid__cell--span-12';
	if ( 'large' === format ) {
		layout = 'mdc-layout-grid__cell--order-2-phone ' +
				'mdc-layout-grid__cell--order-1-tablet ' +
				'mdc-layout-grid__cell--span-6-tablet ' +
				'mdc-layout-grid__cell--span-8-desktop ';

		if ( inlineLayout ) {
			layout = 'mdc-layout-grid__cell--order-2-phone ' +
						'mdc-layout-grid__cell--order-1-tablet ' +
						'mdc-layout-grid__cell--span-5-tablet ' +
						'mdc-layout-grid__cell--span-8-desktop ';
		}
	} else if ( 'small' === format ) {
		layout = 'mdc-layout-grid__cell--span-11-desktop ' +
				'mdc-layout-grid__cell--span-7-tablet ' +
				'mdc-layout-grid__cell--span-3-phone';
	}

	let icon;
	if ( 'win-warning' === type ) {
		icon = <Warning />;
	} else if ( 'win-error' === type ) {
		icon = <Error />;
	} else {
		icon = '';
	}

	const dataBlockMarkup = (
		<Fragment>
			{ blockData &&

				{
					map( blockData, ( block, i ) => {
						return (

									<DataBlock { ...block } />

						);
					} )
				}

			}
		</Fragment>
	);

	const inlineMarkup = (
		<Fragment>
			{ title &&

				{ title }

			}
			{ anchorLink && anchorLinkLabel &&

				<Link href={ anchorLink }>
					{ anchorLinkLabel }
				</Link>

			}
			{ description &&

					{ isValidElement( description ) ? description : (

					) }

					{ learnMoreLabel &&
					<Fragment>
						{ ' ' }
						<Link href={ learnMoreURL } external inherit>
							{ learnMoreLabel }
						</Link>
						{ learnMoreDescription }
					</Fragment>
					}
					{ pageIndex &&
					{ pageIndex }
					}

			}
			{ children }
		</Fragment>
	);

	const logoSVG = module
		? <ModuleIcon slug={ module } size={ 19 } />
		: <GoogleLogoIcon height="34" width="32" />;

	return (
		<section
			id={ id }
			ref={ cardRef }
			className={ classnames(
				className,
				'googlesitekit-publisher-win',
				{
					[ `googlesitekit-publisher-win--${ format }` ]: format,
					[ `googlesitekit-publisher-win--${ type }` ]: type,
					[ `googlesitekit-publisher-win--${ closedClass }` ]: closedClass,
				},
			) }
		>

					{ logo &&

							{ logoSVG }

						{ moduleName &&

							{ moduleName }

						}

					}

					{ SmallImageSVG &&

						<SmallImageSVG />

					}

						{ inlineLayout ? (

									{ inlineMarkup }

									{ dataBlockMarkup }

						) : (
							<Fragment>
								{ inlineMarkup }
								{ dataBlockMarkup }
							</Fragment>
						) }

						{ ctaLink &&
						<Button
							className="googlesitekit-notification__cta"
							href={ ctaLink }
							target={ ctaTarget }
							onClick={ handleCTAClick }
						>
							{ ctaLabel }
						</Button>
						}

						{ isDismissable && dismiss &&
						<Link onClick={ handleDismiss }>
							{ dismiss }
						</Link>
						}

					{ WinImageSVG &&

							<WinImageSVG />

					}

					{ ( 'win-error' === type || 'win-warning' === type ) &&

							{ icon }

					}

	);
}

Notification.propTypes = {
	id: PropTypes.string.isRequired,
	className: PropTypes.string,
	title: PropTypes.string.isRequired,
	description: PropTypes.node,
	learnMoreURL: PropTypes.string,
	learnMoreDescription: PropTypes.string,
	learnMoreLabel: PropTypes.string,
	blockData: PropTypes.array,
	WinImageSVG: PropTypes.elementType,
	SmallImageSVG: PropTypes.elementType,
	format: PropTypes.string,
	ctaLink: PropTypes.string,
	ctaLabel: PropTypes.string,
	type: PropTypes.string,
	dismiss: PropTypes.string,
	isDismissable: PropTypes.bool,
	logo: PropTypes.bool,
	module: PropTypes.string,
	moduleName: PropTypes.string,
	pageIndex: PropTypes.string,
	dismissExpires: PropTypes.number,
	showOnce: PropTypes.bool,
	onCTAClick: PropTypes.func,
	onDismiss: PropTypes.func,
	anchorLink: PropTypes.string,
	anchorLinkLabel: PropTypes.string,
};

Notification.defaultProps = {
	isDismissable: true,
	className: '',
	dismissExpires: 0,
	showOnce: false,
};

export default Notification;
<|endoftext|>