<commit_before>// Create a client-only Collection to store our Validation Errors
ValidationErrors = new Meteor.Collection(null);
ValidationErrors._debugName = 'ValidationErrors';

// Set Validate.js Library's default options
validate.options = {
    format: 'detailed'
};

/**
 * Creates an array of validation error messages given an Object of validation errors
 * and an optional prefix for the messages. An example of a useful prefix would be
 * the location of the measurement or something like 'Target 1 '.
 *
 * @param validationErrors
 * @param prefix
 */
function addValidationErrorsToCollection(validationErrors, prefix, type) {
    // If no input was given, stop here
    if (!validationErrors || !validationErrors.length) {
        return;
    }

    // Loop through each of the entries in the validationErrors Array
    validationErrors.forEach(function(validationError) {
        var existingError = ValidationErrors.findOne({
            attribute: validationError.attribute,
            validator: validationError.validator,
            error: validationError.error,
            prefix: prefix
        });

        if (existingError) {
            ValidationErrors.update(existingError._id, {
                $set: {
                    value: validationError.value
                }
            });
        } else {
            validationError.type = type;
            validationError.prefix = prefix;
            ValidationErrors.insert(validationError);
        }
    });
}

/**
 * Runs conformance checks related to a group of measurements. This function
 * searches the input object of Constraints and looks for the 'group' attribute.
 *
 * It calculates some general group-level values for the current set of Measurements
 * and validates these using the input constraints.
 *
 * @param constraints
 * @returns {Array} Array of error messages related to the input conformance checks
 */
function assessGroupOfMeasurements(constraints) {
    log.info('assessGroupOfMeasurements');

    // Retrieve the group-level constraints
    var groupConstraints = constraints.group;

    // If no group-level constraints exist, stop here
    if (!groupConstraints) {
        return;
    }

    var type = 'group';
    ValidationErrors.remove({
        type: type
    });

    // Get the criteria type so we can calculate total lesion burden
    var criteriaType = Session.get('TrialResponseAssessmentCriteria');

    // Calculate some simple group-level Measurement statistics for validation
    var testStructure = {
        totalNumberOfLesions: Measurements.find().count(),
        totalLesionBurden: calculateTotalLesionBurden(criteriaType)
    };

    // Run the conformance checks with the validate.js library
    var validationErrors = validate(testStructure, groupConstraints);

    // Return any error messages as a flattened array of errors
    addValidationErrorsToCollection(validationErrors, '', type);
}

/**
 * Runs conformance checks related to per-organ sets of measurements.
 *
 * This function searches the input object of Constraints and looks for the
 * 'perOrgan' attribute.
 *
 * It calculates some general per-organ statistics for the current set of Measurements
 * and validates these using the input constraints.
 *
 * @param constraints
 * @returns {Array} Array of error messages related to the input conformance checks
 */
function assessMeasurementPerOrgan(constraints) {
    log.info('assessMeasurementPerOrgan');

    // Retrieve the per-organ constraints
    var perOrganConstraints = constraints.perOrgan;

    // If no per-organ constraints exist, stop here
    if (!perOrganConstraints) {
        return;
    }

    // Create a list of all unique locations that contain measurements
    // by looping through the Measurements Collection
    var organLocations = [];
    Measurements.find().forEach(function(measurement) {
        if (organLocations.indexOf(measurement.location) > -1) {
            return;
        }

        organLocations.push(measurement.location);
    });

    var type = 'perOrgan';
    ValidationErrors.remove({
        type: type
    });

    // Loop through each unique organ location in order to validate
    // the per-organ constraints for each organ
    organLocations.forEach(function(location) {
        // Calculate the number of Lesions per Organ
        var numberOfLesionsPerOrgan = Measurements.find({
            location: location
        }).count();

        // Store per-organ Measurement statistics for validation
        // Right now this is only the numberOfLesionsPerOrgan, but later
        // this may include other checks
        var testStructure = {
            numberOfLesionsPerOrgan: numberOfLesionsPerOrgan
        };

        // Run the conformance checks with the validate.js library
        var validationErrors = validate(testStructure, perOrganConstraints);

        // Obtain any error messages as a flattened array of errors, prefixed
        // with the Organ name, in the form 'Liver Left: '
        addValidationErrorsToCollection(validationErrors, location + ': ', type);
    });
}

/**
 * Runs conformance checks on a single Measurement given the
 * cornerstone toolData related to it.
 *
 * @param constraints
 * @param measurementData CornerstoneTools toolData Object for this specific Measurement
 * @returns {Array} Array of error messages related to the input conformance checks
 */
function assessSingleMeasurement(constraints, measurementData) {
    log.info('assessSingleMeasurement');

    // Check whether this is a Target or Non-Target Measurement
    var targetType = measurementData.isTarget ? 'target' : 'nonTarget';

    // Retrieve any target/non-target-specific single-measurement constraints
    // from the input constraint structure
    var measurementConstraints = constraints[targetType];

    // If no relevant constraints exist, stop here
    if (!measurementConstraints) {
        return;
    }

    // Check whether this is a Nodal or Extranodal Measurement
    var nodalType = measurementData.isNodal ? 'nodal' : 'extraNodal';

    // Retrieve any nodal/extra-nodal-specific constraints to see if we can apply them
    var constraintsToApply;
    if (measurementData.isNodal !== undefined && measurementConstraints[nodalType]) {
        // Check if we have enough information (about nodality of this Measurement,
        // and nodality-specific constraints) to apply nodality-specific constraints
        constraintsToApply = measurementConstraints[nodalType];
    } else if (measurementConstraints.all) {
        // If we have no data about the nodality of this Measurement, or no relevant
        // specific constraints, we should apply the constraints valid for 'all' nodality
        // types
        constraintsToApply = measurementConstraints.all;
    }

    // Calculate a lesion name based on whether or not we have a Target or Non-target
    // Measurement, and the lesion number of this Measurement.
    var lesionName = measurementData.isTarget ? 'Target' : 'Non-target';
    lesionName = lesionName + ' ' + measurementData.lesionNumber + ': ';

    ValidationErrors.remove({
        prefix: lesionName
    });

    // Use validate.js to check the criteria
    var validationErrors = validate(measurementData, constraintsToApply);

    if (validationErrors) {
        validationErrors.forEach(function(error) {
            error.measurementId = measurementData._id;
        });
    }

    // Use the Lesion Name as a prefix to concatenate any validation error messages into
    // an array to return
    addValidationErrorsToCollection(validationErrors, lesionName);
}

/**
 * Validate from a single Measurement up the chain to include group and perOrgan
 * conformance checks
 *
 * @param measurementData The CornerstoneTools toolData for a single Measurement
 */
function validateSingleMeasurement(measurementData) {
    // Obtain the name of the current TrialResponseAssessmentCriteria that
    // we are using.
    var criteriaType = Session.get('TrialResponseAssessmentCriteria');
    var currentConstraints = getTrialCriteriaConstraints(criteriaType, measurementData.imageId);

    // If we have no relevant constraints, stop here
    if (!currentConstraints) {
        return;
    }

    // Find the relevant Measurement in the Measurements Collection
    var measurement = Measurements.findOne(measurementData.id);

    // If no such Measurement exists, stop here
    if (!measurement) {
        return;
    }

    // Find the current timepointId that the user was editing the Measurement on
    var timepointId = measurementData.timepointId;

    // Find the specific measurement data for this Measurement at this Timepoint
    var currentMeasurement = measurement.timepoints[timepointId];

    // Return here if the measurement was removed during validation
    if (!currentMeasurement) {
        return;
    }

    // Include target and nodal flags on the timepoint-specific data so it is easier to validate
    // TODO: Rethink what to pass to assessSingleMeasurement?
    currentMeasurement.isTarget = measurement.isTarget;
    currentMeasurement.isNodal = measurement.isNodal;
    currentMeasurement.lesionNumber = measurement.lesionNumber;
    currentMeasurement._id = measurement._id;

    // Run the single-measurement-specific conformance checks
    // If any messages exist, add them to the array of messages
    assessSingleMeasurement(currentConstraints, currentMeasurement);

    validateGroups();
}

function validateGroups() {
    log.info('validateGroups');

    // Obtain the name of the current TrialResponseAssessmentCriteria that
    // we are using.
    var criteriaType = Session.get('TrialResponseAssessmentCriteria');

    // Criteria for the specific image are retrieved from the general set of criteria.
    var currentConstraints = getTrialCriteriaConstraints(criteriaType);
    if (!currentConstraints) {
        return;
    }

    // TODO: Revisit this! We can't use the Timepoints collection inside ANY
    // of these functions, since it causes an infinite loop, since Measurement
    // validation is performed inside the observe:added hook for the Measurements
    // Collection.

    var timepointTypes = ['baseline', 'followup'];
    timepointTypes.forEach(function(timepoint) {
        // Retrieve the current constraints which apply to the specific Timepoint type
        // (e.g. baseline, followup) that this Measurement is being edited on.
        var timepointConstraints = currentConstraints[timepoint.timepointType];
        if (!timepointConstraints) {
            return;
        }

        // Run the group-level conformance checks
        assessGroupOfMeasurements(timepointConstraints);

        // Run the per-organ conformance checks
        assessMeasurementPerOrgan(timepointConstraints);
    });
}

function validateAll() {
    log.info('validateAll');
    // Obtain the name of the current TrialResponseAssessmentCriteria that
    // we are using.
    var criteriaType = Session.get('TrialResponseAssessmentCriteria');

    Measurements.find().forEach(function(measurement) {
        Object.keys(measurement.timepoints).forEach(function(timepointId) {
            var currentMeasurement = measurement.timepoints[timepointId];
            currentMeasurement.isTarget = measurement.isTarget;
            currentMeasurement.isNodal = measurement.isNodal;
            currentMeasurement.lesionNumber = measurement.lesionNumber;
            currentMeasurement._id = measurement._id;

            // Criteria for the specific image are retrieved from the general set of criteria.
            var currentConstraints = getTrialCriteriaConstraints(criteriaType, currentMeasurement.imageId);
            if (!currentConstraints) {
                return;
            }

            // Run the single-measurement-specific conformance checks
            // If any messages exist, add them to the array of messages
            assessSingleMeasurement(currentConstraints, currentMeasurement);
        });
    });

    validateGroups();
}

var validationTimeout = 400;

/**
 * Validate the measurements after a set delay period
 *
 * @param measurementData Input measurement data from CornerstoneTools
 */
function validateDelayed(measurementData) {
    log.info('validateAllDelayed');

    // Erase any currently-waiting validation call
    clearTimeout(validationTimeout);

    // Set a timeout to run validation after a delay
    // Currently this is 400 milliseconds
    setTimeout(function() {
        validateSingleMeasurement(measurementData);
    }, validationTimeout);
}

/**
 * Validate all measurements after a set delay period
 */
function validateAllDelayed() {
    // Erase any currently-waiting validation call
    clearTimeout(validationTimeout);

    // Set a timeout to run validation after a delay
    // Currently this is 400 milliseconds
    setTimeout(function() {
        validateAll();
    }, validationTimeout);
}

TrialResponseCriteria = {
    validateAll: validateAll,
    validateAllDelayed: validateAllDelayed,
    validateSingleMeasurement: validateSingleMeasurement,
    validateDelayed: validateDelayed,
    validateGroups: validateGroups
};
<commit_msg>Fix broken group-level conformance checks (LT-187)<commit_after>// Create a client-only Collection to store our Validation Errors
ValidationErrors = new Meteor.Collection(null);
ValidationErrors._debugName = 'ValidationErrors';

// Set Validate.js Library's default options
validate.options = {
    format: 'detailed'
};

/**
 * Creates an array of validation error messages given an Object of validation errors
 * and an optional prefix for the messages. An example of a useful prefix would be
 * the location of the measurement or something like 'Target 1 '.
 *
 * @param validationErrors
 * @param prefix
 */
function addValidationErrorsToCollection(validationErrors, prefix, type) {
    // If no input was given, stop here
    if (!validationErrors || !validationErrors.length) {
        return;
    }

    // Loop through each of the entries in the validationErrors Array
    validationErrors.forEach(function(validationError) {
        var existingError = ValidationErrors.findOne({
            attribute: validationError.attribute,
            validator: validationError.validator,
            error: validationError.error,
            prefix: prefix
        });

        if (existingError) {
            ValidationErrors.update(existingError._id, {
                $set: {
                    value: validationError.value
                }
            });
        } else {
            validationError.type = type;
            validationError.prefix = prefix;
            ValidationErrors.insert(validationError);
        }
    });
}

/**
 * Runs conformance checks related to a group of measurements. This function
 * searches the input object of Constraints and looks for the 'group' attribute.
 *
 * It calculates some general group-level values for the current set of Measurements
 * and validates these using the input constraints.
 *
 * @param constraints
 * @returns {Array} Array of error messages related to the input conformance checks
 */
function assessGroupOfMeasurements(constraints) {
    log.info('assessGroupOfMeasurements');

    // Retrieve the group-level constraints
    var groupConstraints = constraints.group;

    // If no group-level constraints exist, stop here
    if (!groupConstraints) {
        return;
    }

    var type = 'group';
    ValidationErrors.remove({
        type: type
    });

    // Get the criteria type so we can calculate total lesion burden
    var criteriaType = Session.get('TrialResponseAssessmentCriteria');

    // Calculate some simple group-level Measurement statistics for validation
    var testStructure = {
        totalNumberOfLesions: Measurements.find().count(),
        totalLesionBurden: calculateTotalLesionBurden(criteriaType)
    };

    // Run the conformance checks with the validate.js library
    var validationErrors = validate(testStructure, groupConstraints);

    // Return any error messages as a flattened array of errors
    addValidationErrorsToCollection(validationErrors, '', type);
}

/**
 * Runs conformance checks related to per-organ sets of measurements.
 *
 * This function searches the input object of Constraints and looks for the
 * 'perOrgan' attribute.
 *
 * It calculates some general per-organ statistics for the current set of Measurements
 * and validates these using the input constraints.
 *
 * @param constraints
 * @returns {Array} Array of error messages related to the input conformance checks
 */
function assessMeasurementPerOrgan(constraints) {
    log.info('assessMeasurementPerOrgan');

    // Retrieve the per-organ constraints
    var perOrganConstraints = constraints.perOrgan;

    // If no per-organ constraints exist, stop here
    if (!perOrganConstraints) {
        return;
    }

    // Create a list of all unique locations that contain measurements
    // by looping through the Measurements Collection
    var organLocations = [];
    Measurements.find().forEach(function(measurement) {
        if (organLocations.indexOf(measurement.location) > -1) {
            return;
        }

        organLocations.push(measurement.location);
    });

    var type = 'perOrgan';
    ValidationErrors.remove({
        type: type
    });

    // Loop through each unique organ location in order to validate
    // the per-organ constraints for each organ
    organLocations.forEach(function(location) {
        // Calculate the number of Lesions per Organ
        var numberOfLesionsPerOrgan = Measurements.find({
            location: location
        }).count();

        // Store per-organ Measurement statistics for validation
        // Right now this is only the numberOfLesionsPerOrgan, but later
        // this may include other checks
        var testStructure = {
            numberOfLesionsPerOrgan: numberOfLesionsPerOrgan
        };

        // Run the conformance checks with the validate.js library
        var validationErrors = validate(testStructure, perOrganConstraints);

        // Obtain any error messages as a flattened array of errors, prefixed
        // with the Organ name, in the form 'Liver Left: '
        addValidationErrorsToCollection(validationErrors, location + ': ', type);
    });
}

/**
 * Runs conformance checks on a single Measurement given the
 * cornerstone toolData related to it.
 *
 * @param constraints
 * @param measurementData CornerstoneTools toolData Object for this specific Measurement
 * @returns {Array} Array of error messages related to the input conformance checks
 */
function assessSingleMeasurement(constraints, measurementData) {
    log.info('assessSingleMeasurement');

    // Check whether this is a Target or Non-Target Measurement
    var targetType = measurementData.isTarget ? 'target' : 'nonTarget';

    // Retrieve any target/non-target-specific single-measurement constraints
    // from the input constraint structure
    var measurementConstraints = constraints[targetType];

    // If no relevant constraints exist, stop here
    if (!measurementConstraints) {
        return;
    }

    // Check whether this is a Nodal or Extranodal Measurement
    var nodalType = measurementData.isNodal ? 'nodal' : 'extraNodal';

    // Retrieve any nodal/extra-nodal-specific constraints to see if we can apply them
    var constraintsToApply;
    if (measurementData.isNodal !== undefined && measurementConstraints[nodalType]) {
        // Check if we have enough information (about nodality of this Measurement,
        // and nodality-specific constraints) to apply nodality-specific constraints
        constraintsToApply = measurementConstraints[nodalType];
    } else if (measurementConstraints.all) {
        // If we have no data about the nodality of this Measurement, or no relevant
        // specific constraints, we should apply the constraints valid for 'all' nodality
        // types
        constraintsToApply = measurementConstraints.all;
    }

    // Calculate a lesion name based on whether or not we have a Target or Non-target
    // Measurement, and the lesion number of this Measurement.
    var lesionName = measurementData.isTarget ? 'Target' : 'Non-target';
    lesionName = lesionName + ' ' + measurementData.lesionNumber + ': ';

    ValidationErrors.remove({
        prefix: lesionName
    });

    // Use validate.js to check the criteria
    var validationErrors = validate(measurementData, constraintsToApply);

    if (validationErrors) {
        validationErrors.forEach(function(error) {
            error.measurementId = measurementData._id;
        });
    }

    // Use the Lesion Name as a prefix to concatenate any validation error messages into
    // an array to return
    addValidationErrorsToCollection(validationErrors, lesionName);
}

/**
 * Validate from a single Measurement up the chain to include group and perOrgan
 * conformance checks
 *
 * @param measurementData The CornerstoneTools toolData for a single Measurement
 */
function validateSingleMeasurement(measurementData) {
    // Obtain the name of the current TrialResponseAssessmentCriteria that
    // we are using.
    var criteriaType = Session.get('TrialResponseAssessmentCriteria');
    var currentConstraints = getTrialCriteriaConstraints(criteriaType, measurementData.imageId);

    // If we have no relevant constraints, stop here
    if (!currentConstraints) {
        return;
    }

    // Find the relevant Measurement in the Measurements Collection
    var measurement = Measurements.findOne(measurementData.id);

    // If no such Measurement exists, stop here
    if (!measurement) {
        return;
    }

    // Find the current timepointId that the user was editing the Measurement on
    var timepointId = measurementData.timepointId;

    // Find the specific measurement data for this Measurement at this Timepoint
    var currentMeasurement = measurement.timepoints[timepointId];

    // Return here if the measurement was removed during validation
    if (!currentMeasurement) {
        return;
    }

    // Include target and nodal flags on the timepoint-specific data so it is easier to validate
    // TODO: Rethink what to pass to assessSingleMeasurement?
    currentMeasurement.isTarget = measurement.isTarget;
    currentMeasurement.isNodal = measurement.isNodal;
    currentMeasurement.lesionNumber = measurement.lesionNumber;
    currentMeasurement._id = measurement._id;

    // Run the single-measurement-specific conformance checks
    // If any messages exist, add them to the array of messages
    assessSingleMeasurement(currentConstraints, currentMeasurement);

    validateGroups();
}

function validateGroups() {
    log.info('validateGroups');

    // Obtain the name of the current TrialResponseAssessmentCriteria that
    // we are using.
    var criteriaType = Session.get('TrialResponseAssessmentCriteria');

    // Criteria for the specific image are retrieved from the general set of criteria.
    var currentConstraints = getTrialCriteriaConstraints(criteriaType);
    if (!currentConstraints) {
        return;
    }

    // TODO: Revisit this! We can't use the Timepoints collection inside ANY
    // of these functions, since it causes an infinite loop, since Measurement
    // validation is performed inside the observe:added hook for the Measurements
    // Collection.

    var timepointTypes = ['baseline', 'followup'];
    timepointTypes.forEach(function(timepointType) {
        // Retrieve the current constraints which apply to the specific Timepoint type
        // (e.g. baseline, followup) that this Measurement is being edited on.
        var timepointConstraints = currentConstraints[timepointType];
        if (!timepointConstraints) {
            return;
        }

        // Run the group-level conformance checks
        assessGroupOfMeasurements(timepointConstraints);

        // Run the per-organ conformance checks
        assessMeasurementPerOrgan(timepointConstraints);
    });
}

function validateAll() {
    log.info('validateAll');
    // Obtain the name of the current TrialResponseAssessmentCriteria that
    // we are using.
    var criteriaType = Session.get('TrialResponseAssessmentCriteria');

    Measurements.find().forEach(function(measurement) {
        Object.keys(measurement.timepoints).forEach(function(timepointId) {
            var currentMeasurement = measurement.timepoints[timepointId];
            currentMeasurement.isTarget = measurement.isTarget;
            currentMeasurement.isNodal = measurement.isNodal;
            currentMeasurement.lesionNumber = measurement.lesionNumber;
            currentMeasurement._id = measurement._id;

            // Criteria for the specific image are retrieved from the general set of criteria.
            var currentConstraints = getTrialCriteriaConstraints(criteriaType, currentMeasurement.imageId);
            if (!currentConstraints) {
                return;
            }

            // Run the single-measurement-specific conformance checks
            // If any messages exist, add them to the array of messages
            assessSingleMeasurement(currentConstraints, currentMeasurement);
        });
    });

    validateGroups();
}

var validationTimeout = 400;

/**
 * Validate the measurements after a set delay period
 *
 * @param measurementData Input measurement data from CornerstoneTools
 */
function validateDelayed(measurementData) {
    log.info('validateAllDelayed');

    // Erase any currently-waiting validation call
    clearTimeout(validationTimeout);

    // Set a timeout to run validation after a delay
    // Currently this is 400 milliseconds
    setTimeout(function() {
        validateSingleMeasurement(measurementData);
    }, validationTimeout);
}

/**
 * Validate all measurements after a set delay period
 */
function validateAllDelayed() {
    // Erase any currently-waiting validation call
    clearTimeout(validationTimeout);

    // Set a timeout to run validation after a delay
    // Currently this is 400 milliseconds
    setTimeout(function() {
        validateAll();
    }, validationTimeout);
}

TrialResponseCriteria = {
    validateAll: validateAll,
    validateAllDelayed: validateAllDelayed,
    validateSingleMeasurement: validateSingleMeasurement,
    validateDelayed: validateDelayed,
    validateGroups: validateGroups
};
<|endoftext|>


<commit_before>// Based on http://petecleary.github.io/DecisionTreeJS/examples/Node-BasicApp/index.html
var DecisionApp = require("./decision-app.js");
var DecisionTree = require("./decision-tree.js");
var DecisionTreeLib = require("./decisiontree-full.min.js");

//create a data object to process
var data = { "question": {"id": 2, "display": "Gebruik je reeds Speedo?"}, "answer": {"id": 2, "display": "Minox Online"}};

//execute the tree on the root shape
DecisionTreeLib.execute(DecisionTree.shape, data, DecisionApp.complete, { "DecisionApp": DecisionApp });<commit_msg>Rename to Speedo<commit_after>// Based on http://petecleary.github.io/DecisionTreeJS/examples/Node-BasicApp/index.html
var DecisionApp = require("./decision-app.js");
var DecisionTree = require("./decision-tree.js");
var DecisionTreeLib = require("./decisiontree-full.min.js");

//create a data object to process
var data = { "question": {"id": 2, "display": "Gebruik je reeds Speedo?"}, "answer": {"id": 2, "display": "Speedo Online"}};

//execute the tree on the root shape
DecisionTreeLib.execute(DecisionTree.shape, data, DecisionApp.complete, { "DecisionApp": DecisionApp });<|endoftext|>


<commit_before>
define(function(require) {
    var Crafty = require('crafty');
    var Expires = require('Expires');
    var Vec2d = Crafty.math.Vector2D;

    Crafty.sprite(20, 20, "image/blood.png", {bloodspray:[0, 0]});
    Crafty.sprite(30, 30, "image/slash.png", {slash:[0, 0]});

    var bombmeter_max = 30;
    var special_combo_val = 50;
    var normal_combo_val = 10;

    Crafty.c("EnemyDestroyer", {
        _destroy: false,

        _score: 0,
        _combo: -1,
        _comboval: 0,
        _bombmeter: 0,
        _bombtimer: 0,
        _bombtime: 100,
        _bombing: false,

        _bombslashes: [],

        _destroyEnemy: function(entityHit, isBomb) {
            var rotation = this.rotation + 90;
            if(isBomb) {
                rotation = Math.random() * 360;
            }

            var eCenter = new Vec2d(entityHit.x + entityHit.w/2.0, entityHit.y + entityHit.h/2.0);

            var bloodsprite = Crafty.e('2D, Canvas, bloodspray, SpriteAnimation')
                .attr({x: eCenter.x - 10, y: eCenter.y - 10, z: -1000, w:20, h:20})
                .reel('spray', 100, 0, 0, 5)
                .animate('spray')
                .origin(10, 10);
            //For some reason, setting rotation in attr really screws things up
            bloodsprite.rotation = rotation;

            if(isBomb) {
                var slashimg = Crafty.e('2D, Canvas, slash, SpriteAnimation')
                    .attr({x: eCenter.x - 15, y: eCenter.y - 15, z: -999, w:30, h:30})
                    .reel('slash', 100, 0, 0, 5)
                    .reel('endslash', 100, 0, 5, 8)
                    .animate('slash')
                    .origin(15, 15);
                slashimg.rotation = rotation;
                this._bombslashes.push(slashimg);
            } else {
                var slashimg = Crafty.e('2D, Canvas, slash, SpriteAnimation, Expires')
                    .attr({x: eCenter.x - 15, y: eCenter.y - 15, z: -999, w:30, h:30})
                    .reel('slash', 100, 0, 0, 8)
                    .animate('slash')
                    .expires(120)
                    .origin(15, 15);
                slashimg.rotation = rotation;
            }

            if(this._combo >= 0) {
                if(this._bombing) {
                    this._comboval += 5;
                } else if(entityHit.isSpecialEnemy()) {
                    this._comboval += special_combo_val;
                } else {
                    this._comboval += normal_combo_val;
                }
                this._score += this._comboval;

                var textsize = 8 + this._comboval / 5.0;
                var redness = Math.min(this._comboval/2.0, 255);
                var rednessHex = redness.toString(16);
                if(rednessHex.length < 2) {
                    rednessHex = '0' + rednessHex;
                }

                Crafty.e('2D, Canvas, Text, Expires')
                    .attr({x: entityHit.x, y: entityHit.y, w:20, h:20})
                    .textFont({size:textsize + 'px'})
                    .textColor('#' + rednessHex + '0000')
                    .text('+' + this._comboval)
                    .expires(1000 + this._comboval * 5);
                this._combo++;
            }

            entityHit.destroy();
            this.trigger('EnemyKill');
            this.trigger('ScoreChange', this._score);
        },

        _bombframe: function(data) {
            this._bombtimer += data.dt;
            if(this._bombtimer >= this._bombtime) {
                var enemy = Crafty('Enemy').get(0);
                if(enemy === undefined) {
                    this._bombing = false;
                    //Don't count the bomb as a combo - just reset without
                    // telling anyone
                    this._combo = -1;
                    this._comboval = 0;

                    //Finish slashes
                    while(this._bombslashes.length) {
                        var bombslash = this._bombslashes.pop();
                        bombslash.addComponent('Expires')
                            .animate('endslash')
                            .expires(120);
                    }

                    this.unbind('EnterFrame', this._bombframe);
                    this.trigger('EndBomb');
                } else {
                    this._destroyEnemy(enemy, true);
                    this.trigger('BombKill');
                }
                this._bombtimer -= this._bombtime;
            }
        },

        _startbomb: function() {
            this._bombmeter = 0;
            this._bombing = true;
            this._combo = 0;
            this.trigger('NewMeter', this._bombmeter / bombmeter_max * 100);
            this.bind('EnterFrame', this._bombframe);
        },

        _canBomb: function() {
            return this._bombmeter >= bombmeter_max;
        },

        _onHit: function(hitData) {
            for(var i = 0; i < hitData.length; i++) {
                var entityHit = hitData[i].obj;
                if(this._destroy) {
                    this._destroyEnemy(entityHit, false);
                }
            }
        },

        _onMaxMove: function() {
        },

        _onStartDash: function() {
            this._destroy= true;
            this._combo = 0;
        },

        _onEndDash: function() {
            this._bombmeter = Math.min(this._bombmeter + Math.max(0, this._combo - 1), bombmeter_max);
            this.trigger('NewCombo', this._combo);
            this.trigger('NewMeter', this._bombmeter / bombmeter_max * 100);
            this._comboval = 0;
            this._destroy= false;
            this._combo = -1;
        },

        init: function() {
            this.onHit('Enemy', this._onHit);
            //this.bind("HitOn", this._onHit);
            this.bind('HitMaxSpeed', this._onMaxMove);
            this.bind('StartDash', this._onStartDash);
            this.bind('StopDash', this._onEndDash);
            this.bind('StartBomb', this._startbomb);
        },

        enemydestroyer: function() {
            return this;
        },
    });
});
<commit_msg>Reduce textsize too<commit_after>
define(function(require) {
    var Crafty = require('crafty');
    var Expires = require('Expires');
    var Vec2d = Crafty.math.Vector2D;

    Crafty.sprite(20, 20, "image/blood.png", {bloodspray:[0, 0]});
    Crafty.sprite(30, 30, "image/slash.png", {slash:[0, 0]});

    var bombmeter_max = 30;
    var special_combo_val = 50;
    var normal_combo_val = 10;

    Crafty.c("EnemyDestroyer", {
        _destroy: false,

        _score: 0,
        _combo: -1,
        _comboval: 0,
        _bombmeter: 0,
        _bombtimer: 0,
        _bombtime: 100,
        _bombing: false,

        _bombslashes: [],

        _destroyEnemy: function(entityHit, isBomb) {
            var rotation = this.rotation + 90;
            if(isBomb) {
                rotation = Math.random() * 360;
            }

            var eCenter = new Vec2d(entityHit.x + entityHit.w/2.0, entityHit.y + entityHit.h/2.0);

            var bloodsprite = Crafty.e('2D, Canvas, bloodspray, SpriteAnimation')
                .attr({x: eCenter.x - 10, y: eCenter.y - 10, z: -1000, w:20, h:20})
                .reel('spray', 100, 0, 0, 5)
                .animate('spray')
                .origin(10, 10);
            //For some reason, setting rotation in attr really screws things up
            bloodsprite.rotation = rotation;

            if(isBomb) {
                var slashimg = Crafty.e('2D, Canvas, slash, SpriteAnimation')
                    .attr({x: eCenter.x - 15, y: eCenter.y - 15, z: -999, w:30, h:30})
                    .reel('slash', 100, 0, 0, 5)
                    .reel('endslash', 100, 0, 5, 8)
                    .animate('slash')
                    .origin(15, 15);
                slashimg.rotation = rotation;
                this._bombslashes.push(slashimg);
            } else {
                var slashimg = Crafty.e('2D, Canvas, slash, SpriteAnimation, Expires')
                    .attr({x: eCenter.x - 15, y: eCenter.y - 15, z: -999, w:30, h:30})
                    .reel('slash', 100, 0, 0, 8)
                    .animate('slash')
                    .expires(120)
                    .origin(15, 15);
                slashimg.rotation = rotation;
            }

            if(this._combo >= 0) {
                if(this._bombing) {
                    this._comboval += 5;
                } else if(entityHit.isSpecialEnemy()) {
                    this._comboval += special_combo_val;
                } else {
                    this._comboval += normal_combo_val;
                }
                this._score += this._comboval;

                var textsize = 8 + this._comboval / 10.0;
                var redness = Math.min(this._comboval/2.0, 255);
                var rednessHex = redness.toString(16);
                if(rednessHex.length < 2) {
                    rednessHex = '0' + rednessHex;
                }

                Crafty.e('2D, Canvas, Text, Expires')
                    .attr({x: entityHit.x, y: entityHit.y, w:20, h:20})
                    .textFont({size:textsize + 'px'})
                    .textColor('#' + rednessHex + '0000')
                    .text('+' + this._comboval)
                    .expires(1000 + this._comboval * 5);
                this._combo++;
            }

            entityHit.destroy();
            this.trigger('EnemyKill');
            this.trigger('ScoreChange', this._score);
        },

        _bombframe: function(data) {
            this._bombtimer += data.dt;
            if(this._bombtimer >= this._bombtime) {
                var enemy = Crafty('Enemy').get(0);
                if(enemy === undefined) {
                    this._bombing = false;
                    //Don't count the bomb as a combo - just reset without
                    // telling anyone
                    this._combo = -1;
                    this._comboval = 0;

                    //Finish slashes
                    while(this._bombslashes.length) {
                        var bombslash = this._bombslashes.pop();
                        bombslash.addComponent('Expires')
                            .animate('endslash')
                            .expires(120);
                    }

                    this.unbind('EnterFrame', this._bombframe);
                    this.trigger('EndBomb');
                } else {
                    this._destroyEnemy(enemy, true);
                    this.trigger('BombKill');
                }
                this._bombtimer -= this._bombtime;
            }
        },

        _startbomb: function() {
            this._bombmeter = 0;
            this._bombing = true;
            this._combo = 0;
            this.trigger('NewMeter', this._bombmeter / bombmeter_max * 100);
            this.bind('EnterFrame', this._bombframe);
        },

        _canBomb: function() {
            return this._bombmeter >= bombmeter_max;
        },

        _onHit: function(hitData) {
            for(var i = 0; i < hitData.length; i++) {
                var entityHit = hitData[i].obj;
                if(this._destroy) {
                    this._destroyEnemy(entityHit, false);
                }
            }
        },

        _onMaxMove: function() {
        },

        _onStartDash: function() {
            this._destroy= true;
            this._combo = 0;
        },

        _onEndDash: function() {
            this._bombmeter = Math.min(this._bombmeter + Math.max(0, this._combo - 1), bombmeter_max);
            this.trigger('NewCombo', this._combo);
            this.trigger('NewMeter', this._bombmeter / bombmeter_max * 100);
            this._comboval = 0;
            this._destroy= false;
            this._combo = -1;
        },

        init: function() {
            this.onHit('Enemy', this._onHit);
            //this.bind("HitOn", this._onHit);
            this.bind('HitMaxSpeed', this._onMaxMove);
            this.bind('StartDash', this._onStartDash);
            this.bind('StopDash', this._onEndDash);
            this.bind('StartBomb', this._startbomb);
        },

        enemydestroyer: function() {
            return this;
        },
    });
});
<|endoftext|>


<commit_before>import React from 'react';
import ReactDomServer from 'react-dom/server';
import msonZoo from 'mson-zoo';
import jsBeautify from 'js-beautify';
import fs from 'fs';
import path from 'path';
import assert from 'assert';
import dedent from 'dedent';

import parseMson from '../playground/parseMson';
import { Attributes } from '../dist/attributes-kit-server';

describe('Comparision with reference fixtures', () => {

  msonZoo.samples.forEach((sample) => {
    let renderedElement = null;
    let htmlString = null;

    describe(`If I render ${sample.name} on the server`, (done) => {
      let header = '# Data Structures';

      parseMson(`${header}\n${sample.fileContent}`, (err, dataStructureElements) => {
        if (err) {
          return done(err);
        }

        renderedElement = React.createElement(Attributes, {
          element: dataStructureElements[0],
          collapseByDefault: false,
          maxInheritanceDepth: undefined,
          includedProperties: 'show',
          inheritedProperties: 'show',
        });

        htmlString = jsBeautify.html(ReactDomServer.renderToStaticMarkup(renderedElement));
      });

      describe('And I compare that with the reference fixture', () => {
        const reference = fs.readFileSync(path.join('./fixtures', `${sample.name}`));

        it('They should be equal', () => {
          assert.equal(htmlString, reference);
        });
      });
    });
  });
});
<commit_msg>Fix samples comparison after upgrading to MSON Zoo 3.0.<commit_after>import React from 'react';
import ReactDomServer from 'react-dom/server';
import msonZoo from 'mson-zoo';
import jsBeautify from 'js-beautify';
import fs from 'fs';
import path from 'path';
import assert from 'assert';
import dedent from 'dedent';

import parseMson from '../playground/parseMson';
import { Attributes } from '../dist/attributes-kit-server';

describe('Comparision with reference fixtures', () => {

  msonZoo.samples.forEach((sample) => {
    let renderedElement = null;
    let htmlString = null;

    describe(`If I render ${sample.fileName} on the server`, (done) => {
      let header = '# Data Structures';

      parseMson(`${header}\n${sample.fileContent}`, (err, dataStructureElements) => {
        if (err) {
          return done(err);
        }

        renderedElement = React.createElement(Attributes, {
          element: dataStructureElements[0],
          dataStructures: dataStructureElements,
          collapseByDefault: false,
          maxInheritanceDepth: undefined,
          includedProperties: 'show',
          inheritedProperties: 'show',
        });

        htmlString = jsBeautify.html(ReactDomServer.renderToStaticMarkup(renderedElement));
      });

      describe('And I compare that with the reference fixture', () => {
        const reference = fs.readFileSync(
          path.join('./fixtures', `${sample.fileName}`),
          'utf8'
        );

        it('They should be equal', () => {
          assert.equal(htmlString, reference);
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>meetingRoomsTwo.js
<commit_msg>add new description<commit_after>// Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei),
// find the minimum number of conference rooms required.

// For example,
// Given [[0, 30],[5, 10],[15, 20]],
// return 2.
<|endoftext|>


<commit_before>define([
	'goo/entities/systems/System',
	'goo/renderer/Renderer',
	'goo/math/Matrix4x4',
	'goo/math/MathUtils',
	'goo/math/Vector3'
],
/** @lends */
function (
	System,
	Renderer,
	Matrix4x4,
	MathUtils,
	Vector3
	) {
	'use strict';

	/**
	 * @class
	 * @extends System
	 */
	function HtmlSystem(renderer) {
		System.call(this, 'HtmlSystem', ['TransformComponent', 'HtmlComponent']);
		this.renderer = renderer;
	}

	HtmlSystem.prototype = Object.create(System.prototype);

	//
	// Browsers implement z-index as signed 32bit int.
	// Overflowing pushes the element to the back.
	//
	var MAX_Z_INDEX = 2147483647;

	var tmpVector = new Vector3();

	// Copied from CSSTransformComponent
	var prefixes = ["", "-webkit-", "-moz-", "-ms-", "-o-"];
	var setStyle = function(element, property, style) {
		for (var j = 0; j < prefixes.length; j++) {
			element.style[prefixes[j] + property] = style;
		}
	};

	HtmlSystem.prototype.process = function(entities) {
		if (entities.length === 0) {
			return;
		}

		var camera = Renderer.mainCamera;
		var screenWidth = this.renderer.domElement.width;
		var screenHeight = this.renderer.domElement.height;

		for (var i = 0; i < entities.length; i++) {
			var entity = entities[i];
			var component = entity.htmlComponent;

			// Always show if not using transform
			if (!component.useTransformComponent) {
				component.domElement.style.display = '';
				setStyle(component.domElement, 'transform', '');
				continue;
			}

			// Hidden
			if (component.hidden) {
				component.domElement.style.display = 'none';
				continue;
			}

			// Behind camera
			tmpVector.setv(camera.translation)
				.subv(entity.transformComponent.worldTransform.translation);
			if (camera._direction.dot(tmpVector) > 0) {
				component.domElement.style.display = 'none';
				continue;
			}

			// compute world position.
			camera.getScreenCoordinates(entity.transformComponent.worldTransform.translation, screenWidth, screenHeight, tmpVector);
			// Behind near plane
			if (tmpVector.z < 0) {
				if (component.hidden !== true) {
					component.domElement.style.display = 'none';
					//component.hidden = true;
				}
				continue;
			}
			// Else visible
			component.domElement.style.display = '';

			var renderer = this.renderer;
			var devicePixelRatio = renderer._useDevicePixelRatio && window.devicePixelRatio ? window.devicePixelRatio / renderer.svg.currentScale : 1;
			var fx = Math.floor(tmpVector.x/devicePixelRatio);
			var fy = Math.floor(tmpVector.y/devicePixelRatio);

			setStyle(component.domElement, 'transform',
				'translate(-50%, -50%) '+
				'translate(' + fx + 'px, ' + fy + 'px)'+
				'translate(' + renderer.domElement.offsetLeft + 'px, ' + renderer.domElement.offsetTop + 'px)');

			setStyle(component.domElement, 'z-index', MAX_Z_INDEX - Math.round(tmpVector.z * MAX_Z_INDEX));
		}
	};

	return HtmlSystem;
});
<commit_msg>Review on htmlsystem z-index #1476<commit_after>define([
	'goo/entities/systems/System',
	'goo/renderer/Renderer',
	'goo/math/Matrix4x4',
	'goo/math/MathUtils',
	'goo/math/Vector3'
],
/** @lends */
function (
	System,
	Renderer,
	Matrix4x4,
	MathUtils,
	Vector3
	) {
	'use strict';

	/**
	 * @class
	 * @extends System
	 */
	function HtmlSystem(renderer) {
		System.call(this, 'HtmlSystem', ['TransformComponent', 'HtmlComponent']);
		this.renderer = renderer;
	}

	HtmlSystem.prototype = Object.create(System.prototype);

	//
	// Browsers implement z-index as signed 32bit int.
	// Overflowing pushes the element to the back.
	//
	var MAX_Z_INDEX = 2147483647;

	var tmpVector = new Vector3();

	// Copied from CSSTransformComponent
	var prefixes = ["", "-webkit-", "-moz-", "-ms-", "-o-"];
	var setStyle = function(element, property, style) {
		for (var j = 0; j < prefixes.length; j++) {
			element.style[prefixes[j] + property] = style;
		}
	};

	HtmlSystem.prototype.process = function(entities) {
		if (entities.length === 0) {
			return;
		}

		var camera = Renderer.mainCamera;
		var screenWidth = this.renderer.domElement.width;
		var screenHeight = this.renderer.domElement.height;

		for (var i = 0; i < entities.length; i++) {
			var entity = entities[i];
			var component = entity.htmlComponent;

			// Always show if not using transform
			if (!component.useTransformComponent) {
				component.domElement.style.display = '';
				setStyle(component.domElement, 'transform', '');
				continue;
			}

			// Hidden
			if (component.hidden) {
				component.domElement.style.display = 'none';
				continue;
			}

			// Behind camera
			tmpVector.setv(camera.translation)
				.subv(entity.transformComponent.worldTransform.translation);
			if (camera._direction.dot(tmpVector) > 0) {
				component.domElement.style.display = 'none';
				continue;
			}

			// compute world position.
			camera.getScreenCoordinates(entity.transformComponent.worldTransform.translation, screenWidth, screenHeight, tmpVector);
			// Behind near plane
			if (tmpVector.z < 0) {
				if (component.hidden !== true) {
					component.domElement.style.display = 'none';
					//component.hidden = true;
				}
				continue;
			}
			// Else visible
			component.domElement.style.display = '';

			var renderer = this.renderer;
			var devicePixelRatio = renderer._useDevicePixelRatio && window.devicePixelRatio ? window.devicePixelRatio / renderer.svg.currentScale : 1;
			var fx = Math.floor(tmpVector.x/devicePixelRatio);
			var fy = Math.floor(tmpVector.y/devicePixelRatio);

			setStyle(component.domElement, 'transform',
				'translate(-50%, -50%) '+
				'translate(' + fx + 'px, ' + fy + 'px)'+
				'translate(' + renderer.domElement.offsetLeft + 'px, ' + renderer.domElement.offsetTop + 'px)');
			// REVIEW z-index isn't prefixed, set it yourself
			setStyle(component.domElement, 'z-index', MAX_Z_INDEX - Math.round(tmpVector.z * MAX_Z_INDEX));
		}
	};

	return HtmlSystem;
});
<|endoftext|>


<commit_before>import defaults from './defaults'
import noop from './noop'

import clean from './methods/clean'
import destroy from './methods/destroy'
import reveal from './methods/reveal'
import sync from './methods/sync'

import delegate from './functions/delegate'

import isMobile from '../utils/is-mobile'
import transformSupported from '../utils/transform-supported'
import transitionSupported from '../utils/transition-supported'

import deepAssign from '../utils/deep-assign'
import logger from '../utils/logger'
import $ from 'tealight'

import { version } from '../../package.json'

let _config
let _debug
let _instance

export default function ScrollReveal(options = {}) {
	const invokedWithoutNew =
		typeof this === 'undefined' ||
		Object.getPrototypeOf(this) !== ScrollReveal.prototype

	if (invokedWithoutNew) {
		return new ScrollReveal(options)
	}

	if (!ScrollReveal.isSupported()) {
		logger.call(this, 'Instantiation failed.', 'This browser is not supported.')
		return noop
	}

	/**
	 * Here we use `buffer` to validate our configuration, before
	 * assigning the contents to the private variable `_config`.
	 */
	let buffer
	{
		try {
			buffer = _config
				? deepAssign({}, _config, options)
				: deepAssign({}, defaults, options)
		} catch (e) {
			logger.call(
				this,
				'Instantiation failed.',
				'Invalid configuration.',
				e.message
			)
			return noop
		}

		try {
			const container = $(buffer.container)[0]
			if (!container) {
				throw new Error('Invalid container.')
			}
			if ((!buffer.mobile && isMobile()) || (!buffer.desktop && !isMobile())) {
				throw new Error('This device is disabled.')
			}
		} catch (e) {
			logger.call(this, 'Instantiation failed.', e.message)
			return noop
		}

		_config = buffer
	}

	/**
	 * Modify the DOM to reflect successful instantiation.
	 */
	document.documentElement.classList.add('sr')
	if (document.body) {
		document.body.style.height = '100%'
	} else {
		document.addEventListener('DOMContentLoaded', () => {
			document.body.style.height = '100%'
		})
	}

	this.store = {
		containers: {},
		elements: {},
		history: [],
		sequences: {}
	}

	this.pristine = true

	Object.defineProperty(this, 'delegate', { get: () => delegate.bind(this) })
	Object.defineProperty(this, 'destroy', { get: () => destroy.bind(this) })
	Object.defineProperty(this, 'reveal', { get: () => reveal.bind(this) })
	Object.defineProperty(this, 'clean', { get: () => clean.bind(this) })
	Object.defineProperty(this, 'sync', { get: () => sync.bind(this) })

	Object.defineProperty(this, 'defaults', { get: () => _config })
	Object.defineProperty(this, 'version', { get: () => version })
	Object.defineProperty(this, 'noop', { get: () => false })

	return _instance ? _instance : (_instance = this)
}

/**
 * Static members are available immediately during instantiation,
 * so debugging and browser support details are handled here.
 */
ScrollReveal.isSupported = () => transformSupported() && transitionSupported()

Object.defineProperty(ScrollReveal, 'debug', {
	get: () => _debug || false,
	set: value => (_debug = typeof value === 'boolean' ? value : _debug)
})
<commit_msg>cache method getters<commit_after>import defaults from './defaults'
import noop from './noop'

import clean from './methods/clean'
import destroy from './methods/destroy'
import reveal from './methods/reveal'
import sync from './methods/sync'

import delegate from './functions/delegate'

import isMobile from '../utils/is-mobile'
import transformSupported from '../utils/transform-supported'
import transitionSupported from '../utils/transition-supported'

import deepAssign from '../utils/deep-assign'
import logger from '../utils/logger'
import $ from 'tealight'

import { version } from '../../package.json'

let boundDelegate
let boundDestroy
let boundReveal
let boundClean
let boundSync
let config
let debug
let instance

export default function ScrollReveal(options = {}) {
	const invokedWithoutNew =
		typeof this === 'undefined' ||
		Object.getPrototypeOf(this) !== ScrollReveal.prototype

	if (invokedWithoutNew) {
		return new ScrollReveal(options)
	}

	if (!ScrollReveal.isSupported()) {
		logger.call(this, 'Instantiation failed.', 'This browser is not supported.')
		return noop
	}

	/**
	 * Here we use `buffer` to validate our configuration, before
	 * assigning the contents to the private variable `_config`.
	 */
	let buffer
	try {
		buffer = config
			? deepAssign({}, config, options)
			: deepAssign({}, defaults, options)
	} catch (e) {
		logger.call(this, 'Instantiation failed.', 'Invalid configuration.', e.message)
		return noop
	}

	try {
		const container = $(buffer.container)[0]
		if (!container) {
			throw new Error('Invalid container.')
		}
		if ((!buffer.mobile && isMobile()) || (!buffer.desktop && !isMobile())) {
			throw new Error('This device is disabled.')
		}
	} catch (e) {
		logger.call(this, 'Instantiation failed.', e.message)
		return noop
	}

	config = buffer

	/**
	 * Modify the DOM to reflect successful instantiation.
	 */
	document.documentElement.classList.add('sr')
	if (document.body) {
		document.body.style.height = '100%'
	} else {
		document.addEventListener('DOMContentLoaded', () => {
			document.body.style.height = '100%'
		})
	}

	this.store = {
		containers: {},
		elements: {},
		history: [],
		sequences: {}
	}

	this.pristine = true

	boundDelegate = boundDelegate || delegate.bind(this)
	boundDestroy = boundDestroy || destroy.bind(this)
	boundReveal = boundReveal || reveal.bind(this)
	boundClean = boundClean || clean.bind(this)
	boundSync = boundSync || sync.bind(this)

	Object.defineProperty(this, 'delegate', { get: () => boundDelegate })
	Object.defineProperty(this, 'destroy', { get: () => boundDestroy })
	Object.defineProperty(this, 'reveal', { get: () => boundReveal })
	Object.defineProperty(this, 'clean', { get: () => boundClean })
	Object.defineProperty(this, 'sync', { get: () => boundSync })

	Object.defineProperty(this, 'defaults', { get: () => config })
	Object.defineProperty(this, 'version', { get: () => version })
	Object.defineProperty(this, 'noop', { get: () => false })

	return instance ? instance : (instance = this)
}

/**
 * Static members are available immediately during instantiation,
 * so debugging and browser support details are handled here.
 */
ScrollReveal.isSupported = () => transformSupported() && transitionSupported()

Object.defineProperty(ScrollReveal, 'debug', {
	get: () => debug || false,
	set: value => (debug = typeof value === 'boolean' ? value : debug)
})
<|endoftext|>


<commit_before>import defaults from './defaults'
import noop from './noop'

import clean from './methods/clean'
import destroy from './methods/destroy'
import reveal from './methods/reveal'
import sync from './methods/sync'

import delegate from './functions/delegate'

import isMobile from '../utils/is-mobile'
import transformSupported from '../utils/transform-supported'
import transitionSupported from '../utils/transition-supported'

import deepAssign from '../utils/deep-assign'
import logger from '../utils/logger'
import $ from 'tealight'

import { version } from '../../package.json'

let _config
let _debug
let _instance

export default function ScrollReveal(options = {}) {
	const invokedWithoutNew =
		typeof this === 'undefined' ||
		Object.getPrototypeOf(this) !== ScrollReveal.prototype

	if (invokedWithoutNew) {
		return new ScrollReveal(options)
	}

	if (!ScrollReveal.isSupported()) {
		logger.call(this, 'Instantiation aborted.', 'This browser is not supported.')
		return noop
	}

	/**
	 * Here we use `buffer` to validate our configuration, before
	 * assigning the contents to the private variable `_config`.
	 */
	let buffer
	{
		try {
			buffer = _config
				? deepAssign({}, _config, options)
				: deepAssign({}, defaults, options)
		} catch (e) {
			logger.call(
				this,
				'Instantiation failed.',
				'Invalid configuration.',
				e.message
			)
			return noop
		}

		try {
			const container = $(buffer.container)[0]
			if (!container) {
				throw new Error('Invalid container.')
			}
		} catch (e) {
			logger.call(this, 'Instantiation failed.', e.message)
			return noop
		}

		_config = buffer
	}

	Object.defineProperty(this, 'defaults', { get: () => _config })

	/**
	 * Now that we have our configuration, we can
	 * make our last check for disabled platforms.
	 */
	if (this.defaults.mobile === isMobile() || this.defaults.desktop === !isMobile()) {
		/**
		 * Modify the DOM to reflect successful instantiation.
		 */
		document.documentElement.classList.add('sr')
		if (document.body) {
			document.body.style.height = '100%'
		} else {
			document.addEventListener('DOMContentLoaded', () => {
				document.body.style.height = '100%'
			})
		}
	}

	this.store = {
		containers: {},
		elements: {},
		history: [],
		sequences: {}
	}

	this.pristine = true

	Object.defineProperty(this, 'delegate', { get: () => delegate.bind(this) })
	Object.defineProperty(this, 'destroy', { get: () => destroy.bind(this) })
	Object.defineProperty(this, 'reveal', { get: () => reveal.bind(this) })
	Object.defineProperty(this, 'clean', { get: () => clean.bind(this) })
	Object.defineProperty(this, 'sync', { get: () => sync.bind(this) })

	Object.defineProperty(this, 'version', { get: () => version })
	Object.defineProperty(this, 'noop', { get: () => false })

	return _instance ? _instance : (_instance = this)
}

/**
 * Static members are available immediately during instantiation,
 * so debugging and browser support details are handled here.
 */
ScrollReveal.isSupported = () => transformSupported() && transitionSupported()

Object.defineProperty(ScrollReveal, 'debug', {
	get: () => _debug || false,
	set: value => {
		if (typeof value === 'boolean') _debug = value
	}
})
<commit_msg>fix disabled devices constructor bug<commit_after>import defaults from './defaults'
import noop from './noop'

import clean from './methods/clean'
import destroy from './methods/destroy'
import reveal from './methods/reveal'
import sync from './methods/sync'

import delegate from './functions/delegate'

import isMobile from '../utils/is-mobile'
import transformSupported from '../utils/transform-supported'
import transitionSupported from '../utils/transition-supported'

import deepAssign from '../utils/deep-assign'
import logger from '../utils/logger'
import $ from 'tealight'

import { version } from '../../package.json'

let _config
let _debug
let _instance

export default function ScrollReveal(options = {}) {
	const invokedWithoutNew =
		typeof this === 'undefined' ||
		Object.getPrototypeOf(this) !== ScrollReveal.prototype

	if (invokedWithoutNew) {
		return new ScrollReveal(options)
	}

	if (!ScrollReveal.isSupported()) {
		logger.call(this, 'Instantiation aborted.', 'This browser is not supported.')
		return noop
	}

	/**
	 * Here we use `buffer` to validate our configuration, before
	 * assigning the contents to the private variable `_config`.
	 */
	let buffer
	{
		try {
			buffer = _config
				? deepAssign({}, _config, options)
				: deepAssign({}, defaults, options)
		} catch (e) {
			logger.call(
				this,
				'Instantiation failed.',
				'Invalid configuration.',
				e.message
			)
			return noop
		}

		try {
			const container = $(buffer.container)[0]
			if (!container) {
				throw new Error('Invalid container.')
			}
			if ((!buffer.mobile && isMobile()) || (!buffer.desktop && !isMobile())) {
				throw new Error('This device is disabled.')
			}
		} catch (e) {
			logger.call(this, 'Instantiation failed.', e.message)
			return noop
		}

		_config = buffer
	}

	/**
	 * Modify the DOM to reflect successful instantiation.
	 */
	document.documentElement.classList.add('sr')
	if (document.body) {
		document.body.style.height = '100%'
	} else {
		document.addEventListener('DOMContentLoaded', () => {
			document.body.style.height = '100%'
		})
	}

	this.store = {
		containers: {},
		elements: {},
		history: [],
		sequences: {}
	}

	this.pristine = true

	Object.defineProperty(this, 'delegate', { get: () => delegate.bind(this) })
	Object.defineProperty(this, 'destroy', { get: () => destroy.bind(this) })
	Object.defineProperty(this, 'reveal', { get: () => reveal.bind(this) })
	Object.defineProperty(this, 'clean', { get: () => clean.bind(this) })
	Object.defineProperty(this, 'sync', { get: () => sync.bind(this) })

	Object.defineProperty(this, 'defaults', { get: () => _config })
	Object.defineProperty(this, 'version', { get: () => version })
	Object.defineProperty(this, 'noop', { get: () => false })

	return _instance ? _instance : (_instance = this)
}

/**
 * Static members are available immediately during instantiation,
 * so debugging and browser support details are handled here.
 */
ScrollReveal.isSupported = () => transformSupported() && transitionSupported()

Object.defineProperty(ScrollReveal, 'debug', {
	get: () => _debug || false,
	set: value => {
		if (typeof value === 'boolean') _debug = value
	}
})
<|endoftext|>


<commit_before>'use strict';

var d3 = require('./d3'),
    format = require('./format');

module.exports = function (container, directions) {
    var control = {}, map;

    control.addTo = function (_) {
        map = _;
        return control;
    };

    container = d3.select(L.DomUtil.get(container));

    directions.on('load', function (e) {
        var route = e.routes[0];

        container
            .html('')
            .classed('mapbox-directions-instructions', true);

        var legs = container.append('ol')
            .selectAll('li')
            .data(route.legs)
            .enter().append('li')
            .attr('class', 'mapbox-directions-leg');

        var steps = legs.append('ol')
            .selectAll('li')
            .data(function (leg) { return leg.steps; })
            .enter().append('li')
            .attr('class', 'mapbox-directions-step');

        steps.append('span')
            .attr('class', function (step) { return step.maneuver.type.replace(/\s+/g, '-').toLowerCase() + ' icon mapbox-directions-step-maneuver';})
            .html(function (step) { return step.maneuver.instruction; });
        steps.append('span')
            .attr('class', 'mapbox-directions-step-distance')
            .text(function (step) { return step.distance ? format.imperial(step.distance) : ''; });

        steps.on('mouseover', function (step) {
            directions.highlightStep(step);
        });

        steps.on('mouseout', function () {
            directions.highlightStep(null);
        });

        steps.on('click', function (step) {
            map.panTo(L.GeoJSON.coordsToLatLng(step.maneuver.location.coordinates));
        });
    });

    return control;
};
<commit_msg>linebreak<commit_after>'use strict';

var d3 = require('./d3'),
    format = require('./format');

module.exports = function (container, directions) {
    var control = {}, map;

    control.addTo = function (_) {
        map = _;
        return control;
    };

    container = d3.select(L.DomUtil.get(container));

    directions.on('load', function (e) {
        var route = e.routes[0];

        container
            .html('')
            .classed('mapbox-directions-instructions', true);

        var legs = container.append('ol')
            .selectAll('li')
            .data(route.legs)
            .enter().append('li')
            .attr('class', 'mapbox-directions-leg');

        var steps = legs.append('ol')
            .selectAll('li')
            .data(function (leg) { return leg.steps; })
            .enter().append('li')
            .attr('class', 'mapbox-directions-step');

        steps.append('span')
            .attr('class', function (step) { return step.maneuver.type.replace(/\s+/g, '-').toLowerCase() + ' icon mapbox-directions-step-maneuver';})
            .html(function (step) { return step.maneuver.instruction; });

        steps.append('span')
            .attr('class', 'mapbox-directions-step-distance')
            .text(function (step) { return step.distance ? format.imperial(step.distance) : ''; });

        steps.on('mouseover', function (step) {
            directions.highlightStep(step);
        });

        steps.on('mouseout', function () {
            directions.highlightStep(null);
        });

        steps.on('click', function (step) {
            map.panTo(L.GeoJSON.coordsToLatLng(step.maneuver.location.coordinates));
        });
    });

    return control;
};
<|endoftext|>


<commit_before>jQuery(function($, undefined) {
	$.fn.extend({
		autocompleteSelMul: function() {
			return this.not('.autocompleteSelMulInited').each(function() {
				var me = $(this).hide().addClass('autocompleteSelMulInited'),
					meCont = me.parent().is('.selectCont') ? me.parent().hide() : me,
					val = me.val(),
					options = me.children('option'),
                    keepValue = me.data('keepvalue'),
					input = $('<input type="text" name="'+(keepValue && keepValue.length > 2 ? keepValue : me.attr('id')+'_new')+'" />').insertBefore(meCont),
					list = [],
					cur = [],
					sep = me.data('sep') || ',',
					sepJoin = me.data('sepjoin') || sep+' ',
					split = function (val) {
						return val.split(new RegExp(sep+'\s*'));
					},
					extractLast = function (term) {
						return split(term).pop();
					},
					writeForm = function() {
						var tmp = split(input.val()),
							val = [],
                            others = [];
						$.each(tmp, function() {
							var cur = $.trim(this),
                                curOpt = options.filter('[rel="'+cur+'"]');
							if (curOpt.length) {
								val.push(curOpt.attr('value'));
                            } else {
                                others.push(cur);
                            }
						});
						me.val(val);
                        if (keepValue) {
                            input.val(others.join(sepJoin));
                        } else {
                            input.attr('disabled', 'disabled');
                        }
					},
					reenable = function() {
						input.removeAttr('disabled');
					};

				me.removeProp('required').removeAttr('required');

				if (me.attr('placeholder'))
					input.attr('placeholder', me.attr('placeholder'));

				options.each(function() {
					var opt = $(this),
						txt = $.trim(opt.text());
					opt.attr('rel', txt);
					list.push({
						value: opt.attr('value'),
						label: txt
					});
				});
				if (val && val.length) {
					$.each(val, function(k, v) {
						cur.push(options.filter('[value="'+v+'"]').text());
					});
					cur.push('');
					input.val(cur.join(sepJoin));
				}

				input.autocomplete({
					minLength: 1,
					source: function(request, response) {
						// delegate back to autocomplete, but extract the last term
						response($.ui.autocomplete.filter(list, $.trim(extractLast(request.term))));
					},
					focus: function() {
						return false;
					},
					select: function(event, ui) {
						var terms = split(this.value);
						// remove the current input
						terms.pop();
						// add the selected item
						terms.push(ui.item.label);
						// add placeholder to get the comma-and-space at the end
						terms.push('');
						this.value = terms.join(sepJoin);
													$(this).trigger('change');
						return false;
					}
				});

				me
					.on('autocompleteWriteForm', writeForm)
					.on('autocompleteReenable', reenable)
					.closest('form').on('submit', function(e) {
						if (!e.isDefaultPrevented())
							writeForm();
					});
			}).end();
		},
		autocompleteSel: function() {
			return this.not('.autocompleteSelInited').each(function() {
				var me = $(this).hide().addClass('autocompleteSelInited'),
					meCont = me.parent().is('.selectCont') ? me.parent().hide() : me,
					val = me.val(),
					options = me.children('option'),
					input = $('<input type="text" name="'+me.attr('id')+'_new" '+(me.attr('required') ? 'required="required"' : '')+'/>').insertBefore(meCont),
					list = [],
					writeForm = function() {
						var val = input.val(),
							curOpt = options.filter('[rel="'+$.trim(val)+'"]');
						if (curOpt.length)
							me.val(curOpt.attr('value'));
						input.attr('disabled', 'disabled');
					},
					reenable = function() {
						input.removeAttr('disabled');
					};

				me.removeProp('required').removeAttr('required');
				if (me.attr('placeholder'))
					input.attr('placeholder', me.attr('placeholder'));

				options.each(function() {
					var opt = $(this),
						txt = $.trim(opt.text());
					opt.attr('rel', txt);
					list.push({
						value: opt.attr('value'),
						label: txt
					});
				});
				if (val && val.length)
					input.val(options.filter('[value="'+val+'"]').text());

				input.autocomplete({
					minLength: 1,
					source: function(request, response) {
						// delegate back to autocomplete, but extract the last term
						response($.ui.autocomplete.filter(list, $.trim(request.term)));
					},
					focus: function() {
						return false;
					},
					select: function(event, ui) {
						this.value = ui.item.label;
						$(this).trigger('change');
						me.val(ui.item.value);
						me.trigger('change');
						return false;
					}
				});

				me
					.on('autocompleteWriteForm', writeForm)
					.on('autocompleteReenable', reenable)
					.closest('form').on('submit', function(e) {
						if (!e.isDefaultPrevented())
							writeForm();
					});
			}).end();
		}
	});

	$('select.autocompleteSelMul').autocompleteSelMul();
	$('select.autocompleteSel').autocompleteSel();
});
<commit_msg>[UPD] One lined change val + trigger<commit_after>jQuery(function($, undefined) {
	$.fn.extend({
		autocompleteSelMul: function() {
			return this.not('.autocompleteSelMulInited').each(function() {
				var me = $(this).hide().addClass('autocompleteSelMulInited'),
					meCont = me.parent().is('.selectCont') ? me.parent().hide() : me,
					val = me.val(),
					options = me.children('option'),
                    keepValue = me.data('keepvalue'),
					input = $('<input type="text" name="'+(keepValue && keepValue.length > 2 ? keepValue : me.attr('id')+'_new')+'" />').insertBefore(meCont),
					list = [],
					cur = [],
					sep = me.data('sep') || ',',
					sepJoin = me.data('sepjoin') || sep+' ',
					split = function (val) {
						return val.split(new RegExp(sep+'\s*'));
					},
					extractLast = function (term) {
						return split(term).pop();
					},
					writeForm = function() {
						var tmp = split(input.val()),
							val = [],
                            others = [];
						$.each(tmp, function() {
							var cur = $.trim(this),
                                curOpt = options.filter('[rel="'+cur+'"]');
							if (curOpt.length) {
								val.push(curOpt.attr('value'));
                            } else {
                                others.push(cur);
                            }
						});
						me.val(val);
                        if (keepValue) {
                            input.val(others.join(sepJoin));
                        } else {
                            input.attr('disabled', 'disabled');
                        }
					},
					reenable = function() {
						input.removeAttr('disabled');
					};

				me.removeProp('required').removeAttr('required');

				if (me.attr('placeholder'))
					input.attr('placeholder', me.attr('placeholder'));

				options.each(function() {
					var opt = $(this),
						txt = $.trim(opt.text());
					opt.attr('rel', txt);
					list.push({
						value: opt.attr('value'),
						label: txt
					});
				});
				if (val && val.length) {
					$.each(val, function(k, v) {
						cur.push(options.filter('[value="'+v+'"]').text());
					});
					cur.push('');
					input.val(cur.join(sepJoin));
				}

				input.autocomplete({
					minLength: 1,
					source: function(request, response) {
						// delegate back to autocomplete, but extract the last term
						response($.ui.autocomplete.filter(list, $.trim(extractLast(request.term))));
					},
					focus: function() {
						return false;
					},
					select: function(event, ui) {
						var terms = split(this.value);
						// remove the current input
						terms.pop();
						// add the selected item
						terms.push(ui.item.label);
						// add placeholder to get the comma-and-space at the end
						terms.push('');
						this.value = terms.join(sepJoin);
													$(this).trigger('change');
						return false;
					}
				});

				me
					.on('autocompleteWriteForm', writeForm)
					.on('autocompleteReenable', reenable)
					.closest('form').on('submit', function(e) {
						if (!e.isDefaultPrevented())
							writeForm();
					});
			}).end();
		},
		autocompleteSel: function() {
			return this.not('.autocompleteSelInited').each(function() {
				var me = $(this).hide().addClass('autocompleteSelInited'),
					meCont = me.parent().is('.selectCont') ? me.parent().hide() : me,
					val = me.val(),
					options = me.children('option'),
					input = $('<input type="text" name="'+me.attr('id')+'_new" '+(me.attr('required') ? 'required="required"' : '')+'/>').insertBefore(meCont),
					list = [],
					writeForm = function() {
						var val = input.val(),
							curOpt = options.filter('[rel="'+$.trim(val)+'"]');
						if (curOpt.length)
							me.val(curOpt.attr('value'));
						input.attr('disabled', 'disabled');
					},
					reenable = function() {
						input.removeAttr('disabled');
					};

				me.removeProp('required').removeAttr('required');
				if (me.attr('placeholder'))
					input.attr('placeholder', me.attr('placeholder'));

				options.each(function() {
					var opt = $(this),
						txt = $.trim(opt.text());
					opt.attr('rel', txt);
					list.push({
						value: opt.attr('value'),
						label: txt
					});
				});
				if (val && val.length)
					input.val(options.filter('[value="'+val+'"]').text());

				input.autocomplete({
					minLength: 1,
					source: function(request, response) {
						// delegate back to autocomplete, but extract the last term
						response($.ui.autocomplete.filter(list, $.trim(request.term)));
					},
					focus: function() {
						return false;
					},
					select: function(event, ui) {
						this.value = ui.item.label;
						$(this).trigger('change');
						me.val(ui.item.value).trigger('change');
						return false;
					}
				});

				me
					.on('autocompleteWriteForm', writeForm)
					.on('autocompleteReenable', reenable)
					.closest('form').on('submit', function(e) {
						if (!e.isDefaultPrevented())
							writeForm();
					});
			}).end();
		}
	});

	$('select.autocompleteSelMul').autocompleteSelMul();
	$('select.autocompleteSel').autocompleteSel();
});
<|endoftext|>


<commit_before>/*
 * Tree view control
 *
 * Author   : Mikhail Shiryaev
 * Created  : 2016
 * Modified : 2016
 */

/*
 * Requires:
 * - jquery
 * - scadautils.js
 */

// Rapid SCADA namespace
var scada = scada || {};

// Tree views processing object
scada.treeView = {
    // Expand or collapse tree node
    _toggleTreeNode: function (divExpander) {
        var treeNode = divExpander.parent().parent();
        var childNodes = treeNode.next(".child-nodes");

        if (divExpander.hasClass("expanded")) {
            divExpander.removeClass("expanded");
            childNodes.css("display", "none");
        } else {
            divExpander.addClass("expanded");
            childNodes.css("display", "block");
        }
    },

    // Expand selected tree node
    _expandSelectedTreeNode: function (allNodes) {
        var selNodes = allNodes.filter(".selected");
        var parDivs = selNodes.parentsUntil(".tree-view", ".child-nodes");

        parDivs.prev(".node").find(".expander").addClass("expanded");
        parDivs.css("display", "block");
    },

    // Tune tree view elements and bind events
    prepare: function () {
        var treeViews = $(".tree-view");
        var oneIndent = treeViews.find(".indent:first").width();
        var allNodes = treeViews.find(".node");

        // set width of indents according to their level
        allNodes.each(function () {
            var level = $(this).attr("data-level");
            $(this).find(".indent").width(oneIndent * level);
        });

        // expand selected tree node
        this._expandSelectedTreeNode(allNodes);

        // go to link or toggle tree node on click
        var thisTreeView = this;
        allNodes
        .off()
        .click(function (event) {
            if (event.ctrlKey || event.button == 1 /*middle*/) {
                return; // allow the default link behavior
            }

            event.preventDefault();
            var node = $(this);
            var script = node.attr("data-script");
            var expander = node.find(".expander");
            var link = node.find("a");

            if ($(event.target).is(".expander")) {
                thisTreeView._toggleTreeNode(expander);
            } else if (script) {
                allNodes.removeClass("selected");
                node.addClass("selected");
                eval(script);
            } else if (link.length > 0) {
                allNodes.removeClass("selected");
                node.addClass("selected");
                scada.utils.clickLink(link);
            } else {
                if (!expander.hasClass("empty")) {
                    thisTreeView._toggleTreeNode(expander);
                }
            }
        });
    }
};<commit_msg>ScadaWeb5: tree view fix<commit_after>/*
 * Tree view control
 *
 * Author   : Mikhail Shiryaev
 * Created  : 2016
 * Modified : 2016
 */

/*
 * Requires:
 * - jquery
 * - scadautils.js
 */

// Rapid SCADA namespace
var scada = scada || {};

// Tree views processing object
scada.treeView = {
    // Expand or collapse tree node
    _toggleTreeNode: function (divExpander) {
        var treeNode = divExpander.parent().parent();
        var childNodes = treeNode.next(".child-nodes");

        if (divExpander.hasClass("expanded")) {
            divExpander.removeClass("expanded");
            childNodes.css("display", "none");
        } else {
            divExpander.addClass("expanded");
            childNodes.css("display", "block");
        }
    },

    // Expand selected tree node
    _expandSelectedTreeNode: function (allNodes) {
        var selNodes = allNodes.filter(".selected");
        var parDivs = selNodes.parentsUntil(".tree-view", ".child-nodes");

        parDivs.prev(".node").find(".expander").addClass("expanded");
        parDivs.css("display", "block");
    },

    // Tune tree view elements and bind events
    prepare: function () {
        var treeViews = $(".tree-view");
        var oneIndent = treeViews.find(".indent:first").width();
        var allNodes = treeViews.find(".node");

        // set width of indents according to their level
        allNodes.each(function () {
            var level = $(this).attr("data-level");
            $(this).find(".indent").width(oneIndent * level);
        });

        // expand selected tree node
        this._expandSelectedTreeNode(allNodes);

        // go to link or toggle tree node on click
        var thisTreeView = this;
        allNodes
        .off()
        .click(function (event) {
            if (event.ctrlKey || event.button == 1 /*middle*/) {
                return; // allow the default link behavior
            }

            event.preventDefault();
            var node = $(this);
            var script = node.attr("data-script");
            var expander = node.find(".expander");
            var href = node.attr("href");

            if ($(event.target).is(".expander")) {
                thisTreeView._toggleTreeNode(expander);
            } else if (script) {
                allNodes.removeClass("selected");
                node.addClass("selected");
                eval(script);
            } else if (href.length > 0) {
                allNodes.removeClass("selected");
                node.addClass("selected");
                scada.utils.clickLink(node);
            } else {
                if (!expander.hasClass("empty")) {
                    thisTreeView._toggleTreeNode(expander);
                }
            }
        });
    }
};<|endoftext|>


<commit_before>import { MJMLElement } from 'mjml-core'
import merge from 'lodash/merge'
import url from 'url'
import React, { Component } from 'react'
import crypto from 'crypto'

const tagName = 'mj-inline-links'
const defaultMJMLDefinition = {
  attributes: {
    'align': 'center',
    'ico-align': 'center',
    'ico-open': '9776',
    'ico-close': '8855',
    'ico-color': '#000000',
    'ico-font-size': '30px',
    'ico-font-family': 'Ubuntu, Helvetica, Arial, sans-serif',
    'ico-text-transform': 'uppercase',
    'ico-padding': '10px',
    'ico-text-decoration': 'none',
    'ico-line-height': '30px',
    'ico-letter-spacing': '3px'
  }
}

const baseStyles = {
  div: {
    'width': '100%'
  },
  trigger: {
    display: 'none',
    maxHeight: 0,
    maxWidth: 0,
    fontSize: 0,
    overflow: 'hidden'
  },
  label: {
    display: 'block',
    cursor: 'pointer',
    msoHide: 'all',
    MozUserSelect: 'none',
    userSelect: 'none'
  },
  icoOpen: {
    msoHide: 'all'
  },
  icoClose: {
    display: 'none',
    msoHide: 'all'
  }
}
const columnElement = true
const postRender = $ => {
  $('.mj-inline-links').each(function () {
    $(this)
      .prepend(``)
      .append(``)
      .removeAttr('data-align')
  })

  $('.mj-menu-trigger').each(function () {
    const id = $(this).children('label').attr('for')

    $(this).before(`
      <input type="checkbox" id="${id}" class="mj-menu-checkbox" style="display:none !important; max-height:0; visibility:hidden;" />
    `)
  })

  if ($('.mj-menu-trigger').length) {
    $('head').append(`

    `)
  }

  return $
}

@MJMLElement
class InlineLinks extends Component {

  styles = this.getStyles()

  getStyles () {
    const { mjAttribute, defaultUnit, getPadding } = this.props

    return merge({}, baseStyles, {
      div: {
        textAlign: mjAttribute('align')
      },
      label: {
        textAlign: mjAttribute('ico-align'),
        color: mjAttribute('ico-color'),
        fontSize: defaultUnit(mjAttribute('ico-font-size'), 'px'),
        fontFamily: mjAttribute('ico-font-family'),
        textTransform: mjAttribute('ico-text-transform'),
        textDecoration: mjAttribute('ico-text-decoration'),
        letterSpacing: defaultUnit(mjAttribute('ico-letter-spacing'), 'px'),
        lineHeight: defaultUnit(mjAttribute('ico-line-height'), 'px'),
        paddingTop: getPadding('top', 'ico-'),
        paddingLeft: getPadding('left', 'ico-'),
        paddingRight: getPadding('right', 'ico-'),
        paddingBottom: getPadding('bottom', 'ico-')
      }
    })
  }

  renderChildren () {
    const { children, mjAttribute } = this.props
    const baseUrl = mjAttribute('base-url')
    const perform = (mjml) => {
      if (mjml.get('tagName') === 'mj-link') {
        mjml = mjml.setIn(['attributes', 'href'], url.resolve(baseUrl, mjml.getIn(['attributes', 'href'])))
      }
      return mjml
    }

    return children.map(child => React.cloneElement(child, { mjml: perform(child.props.mjml) }))
  }

  renderHamburger() {
    const { mjAttribute } = this.props
    const key = crypto.randomBytes(8).toString('hex')

    return (

            { String.fromCharCode(mjAttribute('ico-open')) }

            { String.fromCharCode(mjAttribute('ico-close')) }

    )
  }

  render () {
    const { mjAttribute } = this.props

    return (

        { mjAttribute('hamburger') === 'hamburger' ? this.renderHamburger() : null }

          {this.renderChildren()}

    )
  }
}

InlineLinks.tagName = tagName
InlineLinks.defaultMJMLDefinition = defaultMJMLDefinition
InlineLinks.baseStyles = baseStyles
InlineLinks.columnElement = columnElement
InlineLinks.postRender = postRender

export default InlineLinks
<commit_msg>remove unused mj-attribute letter-spacing<commit_after>import { MJMLElement } from 'mjml-core'
import merge from 'lodash/merge'
import url from 'url'
import React, { Component } from 'react'
import crypto from 'crypto'

const tagName = 'mj-inline-links'
const defaultMJMLDefinition = {
  attributes: {
    'align': 'center',
    'ico-align': 'center',
    'ico-open': '9776',
    'ico-close': '8855',
    'ico-color': '#000000',
    'ico-font-size': '30px',
    'ico-font-family': 'Ubuntu, Helvetica, Arial, sans-serif',
    'ico-text-transform': 'uppercase',
    'ico-padding': '10px',
    'ico-text-decoration': 'none',
    'ico-line-height': '30px'
  }
}

const baseStyles = {
  div: {
    'width': '100%'
  },
  trigger: {
    display: 'none',
    maxHeight: 0,
    maxWidth: 0,
    fontSize: 0,
    overflow: 'hidden'
  },
  label: {
    display: 'block',
    cursor: 'pointer',
    msoHide: 'all',
    MozUserSelect: 'none',
    userSelect: 'none'
  },
  icoOpen: {
    msoHide: 'all'
  },
  icoClose: {
    display: 'none',
    msoHide: 'all'
  }
}
const columnElement = true
const postRender = $ => {
  $('.mj-inline-links').each(function () {
    $(this)
      .prepend(``)
      .append(``)
      .removeAttr('data-align')
  })

  $('.mj-menu-trigger').each(function () {
    const id = $(this).children('label').attr('for')

    $(this).before(`
      <input type="checkbox" id="${id}" class="mj-menu-checkbox" style="display:none !important; max-height:0; visibility:hidden;" />
    `)
  })

  if ($('.mj-menu-trigger').length) {
    $('head').append(`

    `)
  }

  return $
}

@MJMLElement
class InlineLinks extends Component {

  styles = this.getStyles()

  getStyles () {
    const { mjAttribute, defaultUnit, getPadding } = this.props

    return merge({}, baseStyles, {
      div: {
        textAlign: mjAttribute('align')
      },
      label: {
        textAlign: mjAttribute('ico-align'),
        color: mjAttribute('ico-color'),
        fontSize: defaultUnit(mjAttribute('ico-font-size'), 'px'),
        fontFamily: mjAttribute('ico-font-family'),
        textTransform: mjAttribute('ico-text-transform'),
        textDecoration: mjAttribute('ico-text-decoration'),
        letterSpacing: defaultUnit(mjAttribute('ico-letter-spacing'), 'px'),
        lineHeight: defaultUnit(mjAttribute('ico-line-height'), 'px'),
        paddingTop: getPadding('top', 'ico-'),
        paddingLeft: getPadding('left', 'ico-'),
        paddingRight: getPadding('right', 'ico-'),
        paddingBottom: getPadding('bottom', 'ico-')
      }
    })
  }

  renderChildren () {
    const { children, mjAttribute } = this.props
    const baseUrl = mjAttribute('base-url')
    const perform = (mjml) => {
      if (mjml.get('tagName') === 'mj-link') {
        mjml = mjml.setIn(['attributes', 'href'], url.resolve(baseUrl, mjml.getIn(['attributes', 'href'])))
      }
      return mjml
    }

    return children.map(child => React.cloneElement(child, { mjml: perform(child.props.mjml) }))
  }

  renderHamburger() {
    const { mjAttribute } = this.props
    const key = crypto.randomBytes(8).toString('hex')

    return (

            { String.fromCharCode(mjAttribute('ico-open')) }

            { String.fromCharCode(mjAttribute('ico-close')) }

    )
  }

  render () {
    const { mjAttribute } = this.props

    return (

        { mjAttribute('hamburger') === 'hamburger' ? this.renderHamburger() : null }

          {this.renderChildren()}

    )
  }
}

InlineLinks.tagName = tagName
InlineLinks.defaultMJMLDefinition = defaultMJMLDefinition
InlineLinks.baseStyles = baseStyles
InlineLinks.columnElement = columnElement
InlineLinks.postRender = postRender

export default InlineLinks
<|endoftext|>


<commit_before>angular.module('mwUI.UiComponents')
//TODO rename
  .directive('mwTabsPane', function () {
    return {
      scope: {
        title: '@mwTabsPane',
        id: '@',
        icon: '@',
        tooltip: '@',
        isInvalid: '=',
        badge: '@'
      },
      transclude: true,
      replace: true,
      require: '^mwTabs',
      templateUrl: 'uikit/mw-ui-components/directives/templates/mw_tab_pane.html',
      controller: function ($scope) {
        var selected = false;
        $scope.getId = function () {
          return $scope.id || $scope.$id;
        };

        $scope.deselect = function () {
          selected = false;
        };

        $scope.select = function () {
          selected = true;
        };

        $scope.isSelected = function () {
          return selected;
        };
      },
      link: function (scope, el, attr, mwTabsCtrl) {
        mwTabsCtrl.registerPane(scope);

        scope.$on('$destroy', function () {
          el.remove();
          scope.deselect();
          mwTabsCtrl.unRegisterPane(scope);
        });
      }
    };
  });<commit_msg>Set scope attrs to optional<commit_after>angular.module('mwUI.UiComponents')
//TODO rename
  .directive('mwTabsPane', function () {
    return {
      scope: {
        title: '@mwTabsPane',
        id: '@?',
        icon: '@?',
        tooltip: '@?',
        badge: '@?',
        isInvalid: '=?'
      },
      transclude: true,
      replace: true,
      require: ['^mwTabs', '^?form'],
      templateUrl: 'uikit/mw-ui-components/directives/templates/mw_tab_pane.html',
      controller: function ($scope) {
        var selected = false;
        $scope.getId = function () {
          return $scope.id || $scope.$id;
        };

        $scope.deselect = function () {
          selected = false;
        };

        $scope.select = function () {
          selected = true;
        };

        $scope.isSelected = function () {
          return selected;
        };
      },
      link: function (scope, el, attr, mwTabsCtrl) {
        mwTabsCtrl.registerPane(scope);

        scope.$on('$destroy', function () {
          el.remove();
          scope.deselect();
          mwTabsCtrl.unRegisterPane(scope);
        });
      }
    };
  });<|endoftext|>