<commit_before>const {Action, api} = require('actionhero');
const dal = require('@dal');
const _ = require('lodash');
const joi = require('joi');

module.exports.GetSamplesForProjectAction = class GetSamplesForProjectAction extends Action {
    constructor() {
        super();
        this.name = 'getSamplesForProject';
        this.description = 'Returns all samples in the given project';
        this.inputs = {
            project_id: {
                required: true,
            }
        };
        this.outputExample = sampleExample;
    }

    async run({response, params}) {
        let results = await dal.tryCatch(async() => await api.mc.samples.getSamplesForProject(params.project_id));
        if (results === null) {
            throw new Error(`Unable to retrieve samples for project ${params.project_id}`);
        }
        response.data = results;
    }
};

module.exports.GetSamplesWithConditionsForProjectAction = class GetSamplesWithConditionsForProjectAction extends Action {
    constructor() {
        super();
        this.name = 'getSamplesWithConditionsForProject';
        this.description = 'Returns all samples in the given project';
        this.inputs = {
            project_id: {
                required: true,
            }
        };
    }

    async run({response, params}) {
        const samples = await dal.tryCatch(async() => await api.mc.samples.getSamplesWithConditionsForProject(params.project_id));
        if (samples === null) {
            throw new Error(`Unable to retrieve samples for project ${params.project_id}`);
        }
        response.data = samples;
    }
};

module.exports.GetSampleAction = class GetSampleAction extends Action {
    constructor() {
        super();
        this.name = 'getSample';
        this.description = 'Returns the given sample';
        this.inputs = {
            sample_id: {
                required: true,
            }
        };
        this.outputExample = {};
    }

    async run({response, params, user}) {
        const results = await dal.tryCatch(async() => await api.mc.samples.getSample(params.sample_id, user.id));
        if (!results) {
            throw new Error(`Unable to retrieve samples ${params.sample_id}`);
        }
        response.data = results;
    }
};

module.exports.CreateSampleInProcessAction = class CreateSampleInProcessAction extends Action {
    constructor() {
        super();
        this.name = 'createSampleInProcess';
        this.description = 'Creates a new sample in the given process';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            name: {
                required: true,
            },

            description: {
                required: true,
            },

            attributes: {
                default: [],
                validator: (attrs) => {
                    if (!_.isArray(attrs)) {
                        throw new Error('attributes must be an array');
                    }
                    for (let attr of attrs) {
                        if (!_.isString(attr.name)) {
                            throw new Error(`Attribute must contain a name`);
                        }
                        if (!_.isArray(attr.measurements)) {
                            throw new Error(`Attribute must contain measurements`);
                        }
                        for (let m of attr.measurements) {
                            let results = joi.validate(m, this.measSchema);
                            if (results.error !== null) {
                                throw new Error(`Invalid measurement ${results.error}`);
                            }
                        }
                    }
                }
            }
        };

        this.measSchema = {
            name: joi.string().min(1).max(30),
            value: joi.any(),
            unit: joi.string(),
            otype: joi.string(),
            is_best_measure: joi.boolean(),
        };
    }

    async run({response, params, user}) {
        const {project_id, experiment_id, process_id, name, description, attributes} = params;
        let sample = await dal.tryCatch(async() => await api.mc.samples.createSampleInProcess(name, description, user.id, process_id, project_id));
        if (!sample) {
            throw new Error(`Unable to create sample ${name} for process ${process_id} in project ${project_id}/experiment ${experiment_id}`);
        }

        await api.mc.samples.addSampleToExperiment(sample.id, experiment_id);

        if (attributes.length !== 0) {
            let sample2 = await dal.tryCatch(async() => await api.mc.samples.addMeasurementsToSampleInProcess(attributes, sample.id, sample.property_set_id, process_id));

            // Adding the attributes changes what we return for the sample. If adding the attributes failed, but we did successfully create the
            // sample then this is a partial failure condition. In this case its not clear what the user would consider the correct thing to do.
            // So, if there is a failure we return the sample to this point and indicate a failure condition to the user.
            if (sample2 !== null) {
                sample = sample2;
            } else {
                api.mc.log.info(`Unable to add attributes to sample ${name}/${sample.id}`);
                sample.error = `Unable to add attributes to sample`;
            }
        }

        response.data = sample;
    }
};

module.exports.CreateSampleAction = class CreateSampleAction extends Action {
    constructor() {
        super();
        this.name = 'createSample';
        this.description = 'Creates a new sample';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            name: {
                required: true,
            },

            description: {
                default: '',
            },

            attributes: {
                default: [],
                validator: (param) => {
                    if (!_.isArray(param)) {
                        throw new Error('attributes must be an array');
                    }
                }
            }
        };
    }

    async run({response, params, user}) {
        const {project_id, experiment_id, name, description, attributes} = params;

        let process = await dal.tryCatch(async() => await api.mc.processes.createProcess(project_id, experiment_id, 'Create Samples', user.id, []));
        if (!process) {
            throw new Error(`Unable to create process to add sample ${name} to`);
        }

        let sample = await dal.tryCatch(async() => await api.mc.samples.createSampleInProcess(name, description, user.id, process.id, project_id));

        if (!sample) {
            throw new Error(`Unable to create sample ${name} in project ${project_id}/experiment ${experiment_id}`);
        }

        await api.mc.samples.addSampleToExperiment(sample.id, experiment_id);

        if (attributes.length !== 0) {
            let result = await dal.tryCatch(async() => await api.mc.samples.addMeasurementsToSampleInProcess(attributes, sample.id, sample.property_set_id, process.id));
            if (!result) {
                // addMeasurementsToSampleInProcess returned an error
                api.mc.log.info('addMeasurementsToSampleInProcess failed for attributes', attributes);
            }
        }

        response.data = sample;
    }
};

module.exports.AddSampleToProcessAction = class AddSampleToProcessAction extends Action {
    constructor() {
        super();
        this.name = 'addSampleToProcess';
        this.description = 'Add sample to process. Optionally create a new attribute set.';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            sample_id: {
                required: true,
            },

            property_set_id: {
                required: true,
            },

            return_full_sample: {
                default: true,
            },

            transform: {
                default: false,
            }
        };
    }

    async run({response, params, user}) {
        const {sample_id, property_set_id, process_id, transform} = params;
        const propertySetId = await dal.tryCatch(async() => await api.mc.samples.addSampleToProcess(sample_id, property_set_id, process_id, transform));
        if (!propertySetId) {
            throw new Error(`Unable to add sample ${sample_id}/${property_set_id} to process ${process_id}`);
        }

        let sample;
        if (params.return_full_sample) {
            sample = await dal.tryCatch(async() => await api.mc.samples.getSample(sample_id, user.id));
            if (!sample) {
                throw new Error(`Unable to retrieve sample ${sample_id}`);
            }
        } else {
            sample = await api.mc.samples.getSampleSimple(sample_id);
        }

        sample.property_set_id = propertySetId;

        response.data = sample;
    }
};

module.exports.AddSamplesToProcessAction = class AddSamplesToProcessAction extends Action {
    constructor() {
        super();
        this.name = 'addSamplesToProcess';
        this.description = 'Add sample to process. Optionally create a new attribute set.';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            samples: {
                required: true,
                validator: param => {
                    if (!_.isArray(param)) {
                        throw new Error('sample parameter must be an array');
                    }
                }
            },

            transform: {
                default: false,
            }
        };
    }

    async run({response, params}) {
        const {samples, process_id, transform} = params;
        const updatedSamples = await dal.tryCatch(async() => await api.mc.samples.addSamplesToProcess(samples, process_id, transform));
        if (updatedSamples === null) {
            throw new Error(`Unable to add samples to process ${process_id}`);
        }

        // add name back to samples and map s.sample_id to s.id, this allows the client to map samples.
        const samplesMap = _.keyBy(samples, 'sample_id');
        api.mc.log.info('samplesMap', samplesMap);
        updatedSamples.forEach(s => {
            api.mc.log.info('s', s);
            let sampleWithName = samplesMap[s.sample_id];
            s.name = sampleWithName.name;
            s.id = s.sample_id;
        });

        response.data = updatedSamples;
    }
};

module.exports.AddSampleAndFilesToProcessAction = class AddSampleAndFilesToProcessAction extends Action {
    constructor() {
        super();
        this.name = 'addSampleAndFilesToProcess';
        this.description = 'Add sample and files to process. Connect files to process and sample. Optionally create a new attribute set.';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            sample_id: {
                required: true,
            },

            property_set_id: {
                required: true,
            },

            transform: {
                default: false,
            },

            files_by_name: {
                default: [],
            },

            files_by_id: {
                default: [],
            }
        };
    }

    async run({response, params, user}) {
        const {sample_id, property_set_id, process_id, transform} = params;
        const propertySetId = await dal.tryCatch(async() => await api.mc.samples.addSampleToProcess(sample_id, property_set_id, process_id, transform));
        if (!propertySetId) {
            throw new Error(`Unable to add sample ${sample_id}/${property_set_id} to process ${process_id}`);
        }

        if (params.files_by_name.length) {
            const result = await dal.tryCatch(async() => api.mc.samples.linkFilesByNameToProcessAndSample(params.files_by_name, process_id, sample_id));
            if (!result) {
                throw new Error(`Unable to link files to process ${process_id} and sample ${sample_id}`);
            }
        }

        if (params.files_by_id.length) {
            const result = await dal.tryCatch(async() => api.mc.samples.linkFilesByIdToProcessAndSample(params.files_by_id, process_id, sample_id));
            if (!result) {
                throw new Error(`Unable to link files to process ${process_id} and sample ${sample_id}`);
            }
        }

        const sample = await dal.tryCatch(async() => await api.mc.samples.getSample(sample_id, user.id));
        if (!sample) {
            throw new Error(`Unable to retrieve sample ${sample_id}`);
        }

        sample.property_set_id = propertySetId;

        response.data = sample;
    }
};

module.exports.AddMeasurementsToSampleInProcessAction = class AddMeasurementsToSampleInProcessAction extends Action {
    constructor() {
        super();
        this.name = 'addMeasurementsToSampleInProcess';
        this.description = 'Adds measurements to the sample in the process';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            sample_id: {
                required: true,
            },

            property_set_id: {
                required: true,
            },

            return_full_sample: {
                default: true,
            },

            attributes: {

                /*
                An attribute looks as follows:
                {
                   name,
                   id (optional),
                   measurements:[
                       {
                          value,
                          unit,
                          otype,
                          is_best_measure
                       }
                   ]
                }
                 */
                required: true,
                validator: (param) => {
                    if (!_.isArray(param)) {
                        throw new Error('attributes must be an array');
                    }
                }
            }
        };
    }

    async run({response, params, user}) {
        const {sample_id, property_set_id, process_id, attributes} = params;
        const result = await dal.tryCatch(async() => await api.mc.samples.addMeasurementsToSampleInProcess(attributes, sample_id, property_set_id, process_id));
        if (!result) {
            throw new Error(`Unable to add measurements to sample ${sample_id}/${property_set_id} in process ${process_id}`);
        }

        let sample;
        if (params.return_full_sample) {
            sample = await dal.tryCatch(async() => await api.mc.samples.getSample(sample_id, user.id));
            if (!sample) {
                throw new Error(`Unable to retrieve sample ${sample_id}`);
            }
        } else {
            sample = {
                id: sample_id,
            };
        }

        sample.property_set_id = property_set_id;

        response.data = sample;
    }
};

const sampleExample = {};
<commit_msg>Changed name of API - update to new name<commit_after>const {Action, api} = require('actionhero');
const dal = require('@dal');
const _ = require('lodash');
const joi = require('joi');

module.exports.GetSamplesForProjectAction = class GetSamplesForProjectAction extends Action {
    constructor() {
        super();
        this.name = 'getSamplesForProject';
        this.description = 'Returns all samples in the given project';
        this.inputs = {
            project_id: {
                required: true,
            }
        };
        this.outputExample = sampleExample;
    }

    async run({response, params}) {
        let results = await dal.tryCatch(async() => await api.mc.samples.getSamplesForProject(params.project_id));
        if (results === null) {
            throw new Error(`Unable to retrieve samples for project ${params.project_id}`);
        }
        response.data = results;
    }
};

module.exports.GetSamplesWithConditionsForProjectAction = class GetSamplesWithConditionsForProjectAction extends Action {
    constructor() {
        super();
        this.name = 'getSamplesWithConditionsForProject';
        this.description = 'Returns all samples in the given project';
        this.inputs = {
            project_id: {
                required: true,
            }
        };
    }

    async run({response, params}) {
        const samples = await dal.tryCatch(async() => await api.mc.samples.getSamplesWithConditionsForProject(params.project_id));
        if (samples === null) {
            throw new Error(`Unable to retrieve samples for project ${params.project_id}`);
        }
        response.data = samples;
    }
};

module.exports.GetSampleAction = class GetSampleAction extends Action {
    constructor() {
        super();
        this.name = 'getSample';
        this.description = 'Returns the given sample';
        this.inputs = {
            sample_id: {
                required: true,
            }
        };
        this.outputExample = {};
    }

    async run({response, params, user}) {
        const results = await dal.tryCatch(async() => await api.mc.samples.getSample(params.sample_id, user.id));
        if (!results) {
            throw new Error(`Unable to retrieve samples ${params.sample_id}`);
        }
        response.data = results;
    }
};

module.exports.CreateSampleInProcessAction = class CreateSampleInProcessAction extends Action {
    constructor() {
        super();
        this.name = 'createSampleInProcess';
        this.description = 'Creates a new sample in the given process';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            name: {
                required: true,
            },

            description: {
                required: true,
            },

            attributes: {
                default: [],
                validator: (attrs) => {
                    if (!_.isArray(attrs)) {
                        throw new Error('attributes must be an array');
                    }
                    for (let attr of attrs) {
                        if (!_.isString(attr.name)) {
                            throw new Error(`Attribute must contain a name`);
                        }
                        if (!_.isArray(attr.measurements)) {
                            throw new Error(`Attribute must contain measurements`);
                        }
                        for (let m of attr.measurements) {
                            let results = joi.validate(m, this.measSchema);
                            if (results.error !== null) {
                                throw new Error(`Invalid measurement ${results.error}`);
                            }
                        }
                    }
                }
            }
        };

        this.measSchema = {
            name: joi.string().min(1).max(30),
            value: joi.any(),
            unit: joi.string(),
            otype: joi.string(),
            is_best_measure: joi.boolean(),
        };
    }

    async run({response, params, user}) {
        const {project_id, experiment_id, process_id, name, description, attributes} = params;
        let sample = await dal.tryCatch(async() => await api.mc.samples.createSampleInProcess(name, description, user.id, process_id, project_id));
        if (!sample) {
            throw new Error(`Unable to create sample ${name} for process ${process_id} in project ${project_id}/experiment ${experiment_id}`);
        }

        await api.mc.samples.addSampleToExperiment(sample.id, experiment_id);

        if (attributes.length !== 0) {
            let sample2 = await dal.tryCatch(async() => await api.mc.samples.addMeasurementsToSampleInProcess(attributes, sample.id, sample.property_set_id, process_id));

            // Adding the attributes changes what we return for the sample. If adding the attributes failed, but we did successfully create the
            // sample then this is a partial failure condition. In this case its not clear what the user would consider the correct thing to do.
            // So, if there is a failure we return the sample to this point and indicate a failure condition to the user.
            if (sample2 !== null) {
                sample = sample2;
            } else {
                api.mc.log.info(`Unable to add attributes to sample ${name}/${sample.id}`);
                sample.error = `Unable to add attributes to sample`;
            }
        }

        response.data = sample;
    }
};

module.exports.CreateSampleAction = class CreateSampleAction extends Action {
    constructor() {
        super();
        this.name = 'createSample';
        this.description = 'Creates a new sample';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            name: {
                required: true,
            },

            description: {
                default: '',
            },

            attributes: {
                default: [],
                validator: (param) => {
                    if (!_.isArray(param)) {
                        throw new Error('attributes must be an array');
                    }
                }
            }
        };
    }

    async run({response, params, user}) {
        const {project_id, experiment_id, name, description, attributes} = params;

        let process = await dal.tryCatch(async() => await api.mc.processes.createTransformProcessFromTemplate(project_id, experiment_id, 'Create Samples', user.id, []));
        if (!process) {
            throw new Error(`Unable to create process to add sample ${name} to`);
        }

        let sample = await dal.tryCatch(async() => await api.mc.samples.createSampleInProcess(name, description, user.id, process.id, project_id));

        if (!sample) {
            throw new Error(`Unable to create sample ${name} in project ${project_id}/experiment ${experiment_id}`);
        }

        await api.mc.samples.addSampleToExperiment(sample.id, experiment_id);

        if (attributes.length !== 0) {
            let result = await dal.tryCatch(async() => await api.mc.samples.addMeasurementsToSampleInProcess(attributes, sample.id, sample.property_set_id, process.id));
            if (!result) {
                // addMeasurementsToSampleInProcess returned an error
                api.mc.log.info('addMeasurementsToSampleInProcess failed for attributes', attributes);
            }
        }

        response.data = sample;
    }
};

module.exports.AddSampleToProcessAction = class AddSampleToProcessAction extends Action {
    constructor() {
        super();
        this.name = 'addSampleToProcess';
        this.description = 'Add sample to process. Optionally create a new attribute set.';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            sample_id: {
                required: true,
            },

            property_set_id: {
                required: true,
            },

            return_full_sample: {
                default: true,
            },

            transform: {
                default: false,
            }
        };
    }

    async run({response, params, user}) {
        const {sample_id, property_set_id, process_id, transform} = params;
        const propertySetId = await dal.tryCatch(async() => await api.mc.samples.addSampleToProcess(sample_id, property_set_id, process_id, transform));
        if (!propertySetId) {
            throw new Error(`Unable to add sample ${sample_id}/${property_set_id} to process ${process_id}`);
        }

        let sample;
        if (params.return_full_sample) {
            sample = await dal.tryCatch(async() => await api.mc.samples.getSample(sample_id, user.id));
            if (!sample) {
                throw new Error(`Unable to retrieve sample ${sample_id}`);
            }
        } else {
            sample = await api.mc.samples.getSampleSimple(sample_id);
        }

        sample.property_set_id = propertySetId;

        response.data = sample;
    }
};

module.exports.AddSamplesToProcessAction = class AddSamplesToProcessAction extends Action {
    constructor() {
        super();
        this.name = 'addSamplesToProcess';
        this.description = 'Add sample to process. Optionally create a new attribute set.';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            samples: {
                required: true,
                validator: param => {
                    if (!_.isArray(param)) {
                        throw new Error('sample parameter must be an array');
                    }
                }
            },

            transform: {
                default: false,
            }
        };
    }

    async run({response, params}) {
        const {samples, process_id, transform} = params;
        const updatedSamples = await dal.tryCatch(async() => await api.mc.samples.addSamplesToProcess(samples, process_id, transform));
        if (updatedSamples === null) {
            throw new Error(`Unable to add samples to process ${process_id}`);
        }

        // add name back to samples and map s.sample_id to s.id, this allows the client to map samples.
        const samplesMap = _.keyBy(samples, 'sample_id');
        api.mc.log.info('samplesMap', samplesMap);
        updatedSamples.forEach(s => {
            api.mc.log.info('s', s);
            let sampleWithName = samplesMap[s.sample_id];
            s.name = sampleWithName.name;
            s.id = s.sample_id;
        });

        response.data = updatedSamples;
    }
};

module.exports.AddSampleAndFilesToProcessAction = class AddSampleAndFilesToProcessAction extends Action {
    constructor() {
        super();
        this.name = 'addSampleAndFilesToProcess';
        this.description = 'Add sample and files to process. Connect files to process and sample. Optionally create a new attribute set.';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            sample_id: {
                required: true,
            },

            property_set_id: {
                required: true,
            },

            transform: {
                default: false,
            },

            files_by_name: {
                default: [],
            },

            files_by_id: {
                default: [],
            }
        };
    }

    async run({response, params, user}) {
        const {sample_id, property_set_id, process_id, transform} = params;
        const propertySetId = await dal.tryCatch(async() => await api.mc.samples.addSampleToProcess(sample_id, property_set_id, process_id, transform));
        if (!propertySetId) {
            throw new Error(`Unable to add sample ${sample_id}/${property_set_id} to process ${process_id}`);
        }

        if (params.files_by_name.length) {
            const result = await dal.tryCatch(async() => api.mc.samples.linkFilesByNameToProcessAndSample(params.files_by_name, process_id, sample_id));
            if (!result) {
                throw new Error(`Unable to link files to process ${process_id} and sample ${sample_id}`);
            }
        }

        if (params.files_by_id.length) {
            const result = await dal.tryCatch(async() => api.mc.samples.linkFilesByIdToProcessAndSample(params.files_by_id, process_id, sample_id));
            if (!result) {
                throw new Error(`Unable to link files to process ${process_id} and sample ${sample_id}`);
            }
        }

        const sample = await dal.tryCatch(async() => await api.mc.samples.getSample(sample_id, user.id));
        if (!sample) {
            throw new Error(`Unable to retrieve sample ${sample_id}`);
        }

        sample.property_set_id = propertySetId;

        response.data = sample;
    }
};

module.exports.AddMeasurementsToSampleInProcessAction = class AddMeasurementsToSampleInProcessAction extends Action {
    constructor() {
        super();
        this.name = 'addMeasurementsToSampleInProcess';
        this.description = 'Adds measurements to the sample in the process';
        this.inputs = {
            project_id: {
                required: true,
            },

            experiment_id: {
                required: true,
            },

            process_id: {
                required: true,
            },

            sample_id: {
                required: true,
            },

            property_set_id: {
                required: true,
            },

            return_full_sample: {
                default: true,
            },

            attributes: {

                /*
                An attribute looks as follows:
                {
                   name,
                   id (optional),
                   measurements:[
                       {
                          value,
                          unit,
                          otype,
                          is_best_measure
                       }
                   ]
                }
                 */
                required: true,
                validator: (param) => {
                    if (!_.isArray(param)) {
                        throw new Error('attributes must be an array');
                    }
                }
            }
        };
    }

    async run({response, params, user}) {
        const {sample_id, property_set_id, process_id, attributes} = params;
        const result = await dal.tryCatch(async() => await api.mc.samples.addMeasurementsToSampleInProcess(attributes, sample_id, property_set_id, process_id));
        if (!result) {
            throw new Error(`Unable to add measurements to sample ${sample_id}/${property_set_id} in process ${process_id}`);
        }

        let sample;
        if (params.return_full_sample) {
            sample = await dal.tryCatch(async() => await api.mc.samples.getSample(sample_id, user.id));
            if (!sample) {
                throw new Error(`Unable to retrieve sample ${sample_id}`);
            }
        } else {
            sample = {
                id: sample_id,
            };
        }

        sample.property_set_id = property_set_id;

        response.data = sample;
    }
};

const sampleExample = {};
<|endoftext|>


<commit_before>/*
Copyright 2020 The Matrix.org Foundation C.I.C.

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
    http://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.
*/

const defer = require("../utils/promiseutil").defer;

function generateRequestId() {
    return (Math.random() * 1e20).toString(36);
}

/**
 * Construct a new Request.
 * @constructor
 * @param {Object} opts Options for this request.
 * @param {string=} opts.id Optional ID to set on this request. One will be
 * generated if this is not provided.
 * @param {*=} opts.data Optional data to associate with this request.
 */
function Request(opts) {
    opts = opts || {};
    this.id = opts.id || generateRequestId();
    this.data = opts.data;
    this.startTs = Date.now();
    this.defer = new defer();
}

/**
 * Get any optional data set on this request.
 * @return {*} The data
 */
Request.prototype.getData = function() {
    return this.data;
}

/**
 * Get this request's ID.
 * @return {String} The ID.
 */
Request.prototype.getId = function() {
    return this.id;
}

/**
 * Get the number of elapsed milliseconds since this request was created.
 * @return {number} The number of milliseconds since this request was made.
 */
Request.prototype.getDuration = function() {
    return Date.now() - this.startTs;
};

/**
 * Retrieve a promise for this request which will be resolved/rejected when the
 * respective methods are called on this Request.
 * @return {Promise} A promise
 */
Request.prototype.getPromise = function() {
    return this.defer.promise;
};

/**
 * Resolve a request. This should be invoked for the successful processing
 * of this request. This doesn't necessarily mean that the request was sent
 * through, e.g. suppressing AS virtual users' messages is still a success.
 * @param {*} msg The thing to resolve with.
 */
Request.prototype.resolve = function(msg) {
    this.defer.resolve(msg);
};

/**
 * Reject a request. This should be invoked for requests which failed to be
 * processed correctly.
 * @param {*} msg The thing to reject with.
 */
Request.prototype.reject = function(msg) {
    this.defer.reject(msg);
};

/**
 * Resolve or reject the promise depending on the outcome of this promise.
 * @param {Promise} The promise whose resolution determines the outcome of this
 * request.
 */
Request.prototype.outcomeFrom = function(promise) {
    return promise.then(
        (msg) => this.resolve(msg)
    ).catch(
        (msg) => this.reject(msg)
    );
}

module.exports = Request;
<commit_msg>defer() doesn't need new<commit_after>/*
Copyright 2020 The Matrix.org Foundation C.I.C.

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
    http://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.
*/

const defer = require("../utils/promiseutil").defer;

function generateRequestId() {
    return (Math.random() * 1e20).toString(36);
}

/**
 * Construct a new Request.
 * @constructor
 * @param {Object} opts Options for this request.
 * @param {string=} opts.id Optional ID to set on this request. One will be
 * generated if this is not provided.
 * @param {*=} opts.data Optional data to associate with this request.
 */
function Request(opts) {
    opts = opts || {};
    this.id = opts.id || generateRequestId();
    this.data = opts.data;
    this.startTs = Date.now();
    this.defer = defer();
}

/**
 * Get any optional data set on this request.
 * @return {*} The data
 */
Request.prototype.getData = function() {
    return this.data;
}

/**
 * Get this request's ID.
 * @return {String} The ID.
 */
Request.prototype.getId = function() {
    return this.id;
}

/**
 * Get the number of elapsed milliseconds since this request was created.
 * @return {number} The number of milliseconds since this request was made.
 */
Request.prototype.getDuration = function() {
    return Date.now() - this.startTs;
};

/**
 * Retrieve a promise for this request which will be resolved/rejected when the
 * respective methods are called on this Request.
 * @return {Promise} A promise
 */
Request.prototype.getPromise = function() {
    return this.defer.promise;
};

/**
 * Resolve a request. This should be invoked for the successful processing
 * of this request. This doesn't necessarily mean that the request was sent
 * through, e.g. suppressing AS virtual users' messages is still a success.
 * @param {*} msg The thing to resolve with.
 */
Request.prototype.resolve = function(msg) {
    this.defer.resolve(msg);
};

/**
 * Reject a request. This should be invoked for requests which failed to be
 * processed correctly.
 * @param {*} msg The thing to reject with.
 */
Request.prototype.reject = function(msg) {
    this.defer.reject(msg);
};

/**
 * Resolve or reject the promise depending on the outcome of this promise.
 * @param {Promise} The promise whose resolution determines the outcome of this
 * request.
 */
Request.prototype.outcomeFrom = function(promise) {
    return promise.then(
        (msg) => this.resolve(msg)
    ).catch(
        (msg) => this.reject(msg)
    );
}

module.exports = Request;
<|endoftext|>


<commit_before><commit_msg>feat(analytics): Push pagination (#2337)<commit_after><|endoftext|>


<commit_before>// title      : dedos
// author     : Gino Tubaro
// license    : MIT License
// description: Conector inferior x1 (bottom)
// file       : xbottom.jscad

//Hay que corregir los agujeros en el agulo

include('lodash.js');

include("node_modules/jscad-utils/jscad-utils.jscad");
include("node_modules/jscad-utils/jscad-utils-color.jscad");

include('node_modules/jscad-utils/jscad-utils-parts.jscad');
include('node_modules/jscad-utils/jscad-boxes.jscad');

function getParameterDefinitions() {
  return [
    { name: 'largodedos', type: 'float', initial: 5, caption: "x:" },
    { name: 'y', type: 'float', initial: 30, caption: "y:" },
    { name: 'z', type: 'float', initial: 8, caption: "z:" },
    { name: 'altopata', type: 'float', initial: 20, caption: "altopata" },
    { name: 'colors', type: 'choice', caption: "Colores", values:["red", "blue", "black"], captions:["Rojo", "Azul", "Negro"], initial: "Rojo" },
  ];
}
 var r = [], y = [], t = [];
 var result,xbottom,cono, ext, int, pata, l;

function CuatroDedos(largodedos){ //Cuatro dedos
var w = [];
   for (var i =0; i<=3; i+=1) {
          l = largodedos+abs((sin(i*50))); //curva dedos
          w.push(translate([ 0, 0, i*10], dedo(l))); //uno arriba del otro separado
          if (i <=2){ // cubos en el medio
            w.push(cube({size:[10,5,8], center:[true,true,false], round:true}).translate([5,0,(i*10+3)]).rotateZ(25));
          }else{}
    }

    return w;
}

function dedo(largo){ //Un dedo con largo variable

 var o = [];
 var oin=[];
 var y=0;
   var x;
   for(var i=0; i<4; i++) {
    x = i*1.5*(largo);
    y = floor(i*i*2);
      o.push(circle({center: true}).scale(6-i/1.5).translate([x,y,0]));
    if (i>=2) { //guardo ultimos los cilindro para sacarlos
      oin.push(circle({center: true}).scale(5-i/1).translate([x,y,0]));
    }
   }

     var fwhole=difference(
    linear_extrude({height: 5}, chain_hull(o))
       .fillet(2,'z+')
       .fillet(2,'z-'),
    linear_extrude({height:7}, chain_hull(oin)))
   return [fwhole];
}

function main(params) {
    util.init(CSG);
  var result =
    difference(
            union(
              CuatroDedos(params.largodedos)),
            union(
                cylinder({d: 30, h: 2}), // cilindro bajo
                cylinder({d: 20, h: 25}).translate([3,0,5]), //cilindro pasador
                cylinder({d: 30, h: 20}).translate([0,0,32.5]), //cilindro superior
                cylinder({d: 45, h: 50, fn:32}).translate([-13,0,0])
             ).translate([-11,0,0]), //desfasaje
                cylinder({d:3, h:40}).translate([1,-2,0]),
                cylinder({d:3, h:40}).translate([1,3,0])
              //  cube({size: [params.largodedos*2.5,5,45],round:true}).rotateZ(43-params.largodedos).translate([3.4*(params.largodedos),1.2*(log(params.largodedos*2)*2),-5])
    );
   return result;

}

   //
<commit_msg>Dedos parametrizados Funcion fingers(largo,alto,r) largo = largo de dedos alto = alto de conectores r = Right?<commit_after>// title      : dedos
// author     : Gino Tubaro
// license    : MIT License
// description: Conector inferior x1 (bottom)
// file       : xbottom.jscad

//Hay que corregir los agujeros en el agulo

include('lodash.js');

include("node_modules/jscad-utils/jscad-utils.jscad");
include("node_modules/jscad-utils/jscad-utils-color.jscad");

include('node_modules/jscad-utils/jscad-utils-parts.jscad');
include('node_modules/jscad-utils/jscad-boxes.jscad');

function CuatroDedos(largodedos,alto){ //Cuatro dedos
var w = [];
var separaciondedos = alto/4;
   for (var i =0; i<=3; i+=1) {
          l = largodedos+abs((sin(i*50))); //curva dedos
          console.log(l);
          w.push(translate([ 0, 0, i*separaciondedos], dedo(l))); //uno arriba del otro separado
          if (i <=2){ // cubos en el medio
            w.push(cube({size:[separaciondedos,5,8], center:[true,true,false], round:true}).translate([5,0,(i*separaciondedos+3)]).rotateZ(25));
          }
    }

    return w;
}

function dedo(largo){ //Un dedo con largo variable

 var o = [];
 var oin=[];
 var y=0;
   var x;
   for(var i=0; i<4; i++) {
    x = i*1.5*(largo);
    y = floor(i*i*2);
      o.push(circle({center: true}).scale(6-i/1.5).translate([x,y,0]));
    if (i>=2) { //guardo ultimos los cilindro para sacarlos
      oin.push(circle({center: true}).scale(5-i/1).translate([x,y,0]));
    }
   }

     var fwhole=difference(
    linear_extrude({height: 5}, chain_hull(o)) //anchodedos
       .fillet(2,'z+')
       .fillet(2,'z-'),
    linear_extrude({height:7}, chain_hull(oin)))//anchocorteinternodedos
   return [fwhole];
}

function fingers(largo,alto,r) {

  var result =
    difference(
            union(
              CuatroDedos(largo,alto)),
            union(
                cylinder({d: 30, h: 2}), // cilindro bajo
                cylinder({d: 20, h: alto/1.5}).translate([3,0,4]), //cilindro pasador
                cylinder({d: 30, h: 20}).translate([0,0,(alto/1.5)+6]), //cilindro superior
                cylinder({d: 45, h: alto, fn:32}).translate([-13,0,0])
             ).translate([-11,0,0]), //desfasaje
                cylinder({d:3, h:alto}).translate([1,-2,0]),
                cylinder({d:3, h:alto}).translate([1,3,0])
              //  cube({size: [params.largodedos*2.5,5,45],round:true}).rotateZ(43-params.largodedos).translate([3.4*(params.largodedos),1.2*(log(params.largodedos*2)*2),-5])
    );

    if (r==1) {
      return  result; //Dedos Der
    }else {
      var piso= cube({size: [1, 1, 1], center: [true, true, false]})
      return  result
                  .mirroredZ()
                  .snap(piso,'z-','inside-'); //dedos IZQ
    }

}

function main() {

  var largo=6;
  var alto=30;
  var r=1; //Der = 1, Izq = 0;
  util.init(CSG);
  return fingers(largo,alto,r);

}

   //
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  AlertIOS,
  AsyncStorage,
  TouchableHighlight,
  Image
} from 'react-native';
import ModalView from './tagsModal';
import { Container, Content, Button, Spinner } from 'native-base';

var STORAGE_KEY = 'id_token';

export default class Memory extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      image: this.props.image,
      tags: [],
      filteredTags: [],
      status: false,
      databaseId: ''
    };
  }

  componentDidMount() {
    if (this.props.prevScene === 'Homescreen') {
      this.uploadPhoto();
    } else {
      this.getMemoryData(this.props.id);
    }
  }

  async uploadPhoto() {
    var context = this;
    var photo = {
      uri: this.state.image.uri,
      type: 'image/jpeg',
      name: 'image.jpg'
    };

    try {
      var token =  await AsyncStorage.getItem(STORAGE_KEY);
    } catch (error) {
      console.log('AsyncStorage error: ' + error.message);
    }

    var form = new FormData();
    form.append('memoryImage', photo);
    fetch('https://invalid-memories-greenfield.herokuapp.com/api/memories/upload',
      {
        body: form,
        method: 'POST',
        headers: {
          'Content-Type': 'multipart/form-data',
          'Authorization': 'Bearer ' + token
        }
      }).then(function(res) {
        var databaseId = JSON.parse(res['_bodyInit']);
        context.getMemoryData(databaseId);
      });
  }

  async getMemoryData(id) {
    var context = this;
    try {
      var token =  await AsyncStorage.getItem(STORAGE_KEY);
    } catch (error) {
      console.log('AsyncStorage error: ' + error.message);
    }

    fetch('https://invalid-memories-greenfield.herokuapp.com/api/memories/id/' + id, {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer ' + token
      }
    }).then(function(res) {
      var memory = JSON.parse(res['_bodyInit']);
      var analyses = memory.analyses.reduce(function(analysis) {
        if (analysis.tags && analysis.tags.length > 0) {
          return [].concat(analysis.tags);
        }
      });
      var savedTags = memory.tags;
      context.setState({
        tags: analyses,
        filteredTags: savedTags,
        statusMessage: 'Tags:',
        databaseId: id,
        status: true
      });
    }).catch(function(err) {
      console.log('ERROR', err);
      // Try pinging database again
      context.getMemoryData(id);
    });
  }

  async updateTags(filteredTags) {
    this.setState({
      filteredTags: filteredTags
    });

    try {
      var token =  await AsyncStorage.getItem(STORAGE_KEY);
    } catch (error) {
      console.log('AsyncStorage error: ' + error.message);
    }

    fetch('https://invalid-memories-greenfield.herokuapp.com/api/memories/id/' + this.state.databaseId, {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer ' + token,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        tags: this.state.filteredTags
      })
    }).catch(function(err) {

    })
  }

  render() {
    var loading = this.state.status ?
      <ModalView
        prevScene={this.props.prevScene}
        tags={this.state.tags}
        updateTags={this.updateTags.bind(this)}
        status={this.state.status}
      />
      : null;
    return (
      <Container style={{paddingTop: 70}}>
        <Content>
          <Image style={{width:200, height:200}} source={{uri: this.state.image.uri}}/>
          <MemoryDetails
            status={this.state.status}
            tags={this.state.filteredTags}
          />
          {loading}
        </Content>
      </Container>
    );
  }
}

class MemoryDetails extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    var loading = !this.props.status ?
      <Spinner
        color='red'
        animating={true}
        size='large'
        style={{padding: 100}}>
      </Spinner>
      : null;
    return (
      <View style={{flex: 1}}>
        {
          this.props.tags.map(tag =>
            <Button rounded info>{tag}</Button>
          )
        }
        {loading}
      </View>
    );
  }
}<commit_msg>Revert back to not handling multiple APIs; also get rid of duplicates if microsoft and clarifai gave same tag<commit_after>import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  AlertIOS,
  AsyncStorage,
  TouchableHighlight,
  Image
} from 'react-native';
import ModalView from './tagsModal';
import { Container, Content, Button, Spinner } from 'native-base';

var STORAGE_KEY = 'id_token';

export default class Memory extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      image: this.props.image,
      tags: [],
      filteredTags: [],
      status: false,
      databaseId: ''
    };
  }

  componentDidMount() {
    if (this.props.prevScene === 'Homescreen') {
      this.uploadPhoto();
    } else {
      this.getMemoryData(this.props.id);
    }
  }

  async uploadPhoto() {
    var context = this;
    var photo = {
      uri: this.state.image.uri,
      type: 'image/jpeg',
      name: 'image.jpg'
    };

    try {
      var token =  await AsyncStorage.getItem(STORAGE_KEY);
    } catch (error) {
      console.log('AsyncStorage error: ' + error.message);
    }

    var form = new FormData();
    form.append('memoryImage', photo);
    fetch('https://invalid-memories-greenfield.herokuapp.com/api/memories/upload',
      {
        body: form,
        method: 'POST',
        headers: {
          'Content-Type': 'multipart/form-data',
          'Authorization': 'Bearer ' + token
        }
      }).then(function(res) {
        var databaseId = JSON.parse(res['_bodyInit']);
        context.getMemoryData(databaseId);
      });
  }

  async getMemoryData(id) {
    var context = this;
    try {
      var token =  await AsyncStorage.getItem(STORAGE_KEY);
    } catch (error) {
      console.log('AsyncStorage error: ' + error.message);
    }

    fetch('https://invalid-memories-greenfield.herokuapp.com/api/memories/id/' + id, {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer ' + token
      }
    }).then(function(res) {
      var memory = JSON.parse(res['_bodyInit']);
      console.log(memory);
      var microsoftTags = [];
      var clarifaiTags = [];
      if (memory.analyses[0].tags && memory.analyses[0].tags.length > 0) {
        microsoftTags = memory.analyses[0].tags;
      }
      if (memory.analyses[1].tags && memory.analyses[1].tags.length > 0) {
        clarifaiTags = memory.analyses[1].tags;
      }
      var analyses = _.uniq(microsoftTags.concat(clarifaiTags));
      var savedTags = memory.tags;
      context.setState({
        tags: analyses,
        filteredTags: savedTags,
        status: true,
        statusMessage: 'Tags:',
        databaseId: id
      });
    }).catch(function(err) {
      console.log('ERROR', err);
      // Try pinging database again
      context.getMemoryData(id);
    });
  }

  async updateTags(filteredTags) {
    this.setState({
      filteredTags: filteredTags
    });

    try {
      var token =  await AsyncStorage.getItem(STORAGE_KEY);
    } catch (error) {
      console.log('AsyncStorage error: ' + error.message);
    }

    fetch('https://invalid-memories-greenfield.herokuapp.com/api/memories/id/' + this.state.databaseId, {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer ' + token,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        tags: this.state.filteredTags
      })
    }).catch(function(err) {

    })
  }

  render() {
    var loading = this.state.status ?
      <ModalView
        prevScene={this.props.prevScene}
        tags={this.state.tags}
        updateTags={this.updateTags.bind(this)}
        status={this.state.status}
      />
      : null;
    return (
      <Container style={{paddingTop: 70}}>
        <Content>
          <Image style={{width:200, height:200}} source={{uri: this.state.image.uri}}/>
          <MemoryDetails
            status={this.state.status}
            tags={this.state.filteredTags}
          />
          {loading}
        </Content>
      </Container>
    );
  }
}

class MemoryDetails extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    var loading = !this.props.status ?
      <Spinner
        color='red'
        animating={true}
        size='large'
        style={{padding: 100}}>
      </Spinner>
      : null;
    return (
      <View style={{flex: 1}}>
        {
          this.props.tags.map(tag =>
            <Button rounded info>{tag}</Button>
          )
        }
        {loading}
      </View>
    );
  }
}<|endoftext|>


<commit_before>// ==UserScript==
// @name           Google personal blocklist
// @namespace      curipha
// @description    Remove sites from Google search results
// @include        http://www.google.tld/search?*
// @include        https://www.google.tld/search?*
// @version        0.2.2
// @grant          none
// @noframes
// ==/UserScript==

(function(){
  var block = [
    // General doorways
    'ceron.jp/', 'page2rss.com/', 'zenback.itmedia.co.jp/',
    '([^/]+.)?tweetbuzz.jp/',

    // Application doorways
    'www.altech-ads.com/', 'www.freewarelovers.com/', 'www.appbrain.com/',
    '([^/]+.)?filehippo.com/', '[^/]+.softonic.(com|jp)/', '[^/]+.softpedia.com', '[^/]+.uptodown.com',
    '[^/]+.dll-files.com',

    // SNS doorways
    'twtrp.jp/', 'twtrland.com/',
    '([^/]+.)?tweettunnel.com/', '([^/]+.)?favstar.fm/',

    // Knowledge communities
    'questionbox.jp.msn.com/', 'ziddy.japan.zdnet.com/', 'soudan1.biglobe.ne.jp/', 'qanda.rakuten.ne.jp/', 'www.itmedia.co.jp/qa/',
    'oshiete1?.(nifty.com|goo.ne.jp)/',
    '([^/]+.)?okwave.jp/', '([^/]+.)?chiebukuro(.travel)?.yahoo.co.jp/',

    // EC
    '(e?search|item).rakuten.co.jp/',
    '([^/]+.)?.animate-onlineshop.jp',

    // Anime leakers
    'anime.dougasouko.com/',
    '([^/]+.)?anitube.se/',
    '([^/]*(anime|youtube)[^/]*|mvnavian).blog[0-9]*.(fc2.com|fc2blog.us)/',

    // Torrents
    '([^/]+.)?nyaa.se',

    // Dll listing
    'systemexplorer.net/',

    // Mobile pages
    'www.amazon.co.jp/gp/aw/'
  ];

  var opacity = 0.2;
  var pattern = new RegExp('^https?:\/\/(?:' + block.join('|').replace(/([.\/])/g, '\\$1') + ')', 'i');
  var googler = /^https?:\/\/www\.google\.com\/url\?/i;
  var t = 0;

  var blocker = function() {
    var result = document.querySelectorAll('li.g');
    for (var li of result) {
      var a = li.querySelector('h3 > a[href]');
      if (!a) continue;

      if (googler.test(a.href)) {
        var alturi = li.querySelector('cite._Rm').textContent;
        if (typeof(alturi) !== 'string') continue;

        alturi = alturi.replace(/\s+\u203A\s+/g, '/');
        var uri = /^https?:\/\//.test(uri) ? alturi : 'http://' + alturi;
      }
      else {
        var uri = a.href;
      }

      if (pattern.test(uri)) li.style.opacity = opacity;
    }
  };
  var blocker_wrap = function() {
    if (t) return;
    ｔ = setTimeout(function() {
      blocker();
      t = 0;
    }, 120);
  };

  blocker();

  var mo = new MutationObserver(blocker_wrap);
  mo.observe(document.body, { childList: true, subtree: true });
})();
<commit_msg>Update block list<commit_after>// ==UserScript==
// @name           Google personal blocklist
// @namespace      curipha
// @description    Remove sites from Google search results
// @include        http://www.google.tld/search?*
// @include        https://www.google.tld/search?*
// @version        0.2.2
// @grant          none
// @noframes
// ==/UserScript==

(function(){
  var block = [
    // General doorways
    'ceron.jp/', 'page2rss.com/', 'zenback.itmedia.co.jp/',
    '([^/]+.)?tweetbuzz.jp/',

    // Application doorways
    'www.altech-ads.com/', 'www.freewarelovers.com/', 'www.appbrain.com/', 'www.vector.co.jp/soft/',
    '([^/]+.)?filehippo.com/', '[^/]+.softonic.(com|jp)/', '[^/]+.softpedia.com', '[^/]+.uptodown.com',
    '[^/]+.dll-files.com',

    // SNS doorways
    'twtrp.jp/', 'twtrland.com/',
    '([^/]+.)?tweettunnel.com/', '([^/]+.)?favstar.fm/',

    // Knowledge communities
    'questionbox.jp.msn.com/', 'ziddy.japan.zdnet.com/', 'soudan1.biglobe.ne.jp/', 'qanda.rakuten.ne.jp/', 'www.itmedia.co.jp/qa/',
    'oshiete1?.(nifty.com|goo.ne.jp)/',
    '([^/]+.)?okwave.jp/', '([^/]+.)?chiebukuro(.travel)?.yahoo.co.jp/',

    // EC
    '(e?search|item).rakuten.co.jp/',
    '([^/]+.)?.animate-onlineshop.jp',

    // Anime leakers
    'anime.dougasouko.com/',
    '([^/]+.)?anitube.se/',
    '([^/]*(anime|youtube)[^/]*|mvnavian).blog[0-9]*.(fc2.com|fc2blog.us)/',

    // Torrents
    '([^/]+.)?nyaa.se',

    // Dll listing
    'systemexplorer.net/',

    // Mobile pages
    'www.amazon.co.jp/gp/aw/'
  ];

  var opacity = 0.2;
  var pattern = new RegExp('^https?:\/\/(?:' + block.join('|').replace(/([.\/])/g, '\\$1') + ')', 'i');
  var googler = /^https?:\/\/www\.google\.com\/url\?/i;
  var t = 0;

  var blocker = function() {
    var result = document.querySelectorAll('li.g');
    for (var li of result) {
      var a = li.querySelector('h3 > a[href]');
      if (!a) continue;

      if (googler.test(a.href)) {
        var alturi = li.querySelector('cite._Rm').textContent;
        if (typeof(alturi) !== 'string') continue;

        alturi = alturi.replace(/\s+\u203A\s+/g, '/');
        var uri = /^https?:\/\//.test(uri) ? alturi : 'http://' + alturi;
      }
      else {
        var uri = a.href;
      }

      if (pattern.test(uri)) li.style.opacity = opacity;
    }
  };
  var blocker_wrap = function() {
    if (t) return;
    ｔ = setTimeout(function() {
      blocker();
      t = 0;
    }, 120);
  };

  blocker();

  var mo = new MutationObserver(blocker_wrap);
  mo.observe(document.body, { childList: true, subtree: true });
})();
<|endoftext|>


<commit_before>"use strict";

let HTTP = require('http');
let LRU = require('lru-cache');

let BrowserCache = new LRU(50);

class Polyfill{
  static Listen(Port){
    return HTTP.createServer(function(Request, Response){
      try {
        Polyfill.serverRequest(Request, Response);
        Response.end("")
      } catch(e){
        Response.statusCode = 404;
        Response.end("Not Found");
      }
    }).listen(Port);
  }
  static serverRequest(Request, Response){
    var Browser;
    if(Request.url !== '/polyfill.js'){
      throw null
    }
    Response.writeHeader("Content-Type", "application/javascript");

    Browser = Polyfill.recognizeBrowser(Request.headers['user-agent'] || '');

    if(Browser.Version === 0) return ;
    console.log(Browser);
  }
  static recognizeBrowser(UserAgent){

    if(BrowserCache.has(UserAgent)) return BrowserCache.get(UserAgent);

    // Taken from http://stackoverflow.com/a/8754134/2652018
    var Browser = {Name: '', Version: 0};
    try {
      if (/Opera[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Opera;
      } else if (/MSIE (\d+\.\d+);/.test(UserAgent)) {
        Browser.Name = Polyfill.IE;
      } else if (/Navigator[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Netscape;
      } else if (/Chrome[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Chrome;
      } else if (/Safari[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Safari;
        /Version[\/\s](\d+\.\d+)/.test(UserAgent);
        Browser.Version = Number(RegExp.$1);
      } else if (/Firefox[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Firefox;
      }
      if(Browser.Version === 0){
        Browser.Version = parseFloat(Number(RegExp.$1));
      }
    } catch(e) {}

    BrowserCache.set(UserAgent, Browser);
    return Browser;
  }
}

Polyfill.Opera = 'Opera';
Polyfill.IE = 'IE';
Polyfill.Netscape = 'Netscape';
Polyfill.Chrome = 'Chrome';
Polyfill.Safari = 'Safari';
Polyfill.Firefox = 'Firefox';

module.exports = Polyfill;<commit_msg>:new: Implement Matches, Polyfill Cache and Registry<commit_after>"use strict";

let HTTP = require('http');
let LRU = require('lru-cache');

let BrowserCache = new LRU(50);
let PolyfillCache = new LRU(500);
let Polyfills = [];

class Polyfill{
  static listen(Port){
    return HTTP.createServer(function(Request, Response){
      try {
        Polyfill.serverRequest(Request, Response);
        Response.end("");
      } catch(e){
        Response.statusCode = 404;
        Response.end("Not Found");
      }
    }).listen(Port);
  }
  static register(Name, Browsers, Function){
    Polyfills.push({Name: Name, Browsers: Browsers, Function: Function.toString()});
  }
  static serverRequest(Request, Response){
    if(Request.url !== '/polyfill.js' && Request.url !== '/polyfill.min.js'){
      throw null
    }
    Response.writeHeader("Content-Type", "application/javascript");

    var Browser = Polyfill.recognizeBrowser(Request.headers['user-agent'] || '');
    let IsMinified = Request.url === '/polyfill.min.js';
    let CacheKey = Browser.Name + ':' + Browser.Version + ':' + IsMinified;

    if(Browser.Version === 0) return ;
    if(PolyfillCache.has(CacheKey)) return Response.write(PolyfillCache.get(CacheKey));

    let Content = [];
    let PolyFillsAdded = [];
    Polyfills.forEach(function(Info){ // O YEE DUSTRUCTURING WHY U NO SUPPORT?!
      let Name = Info.Name;
      let Browsers = Info.Browsers;
      let Function = Info.Function;
      if(!(Browser.Name in Browsers)) return ;
      if(Browsers[Browser.Name] !== '*' && !Polyfill.matches(Browser, Browsers[Browser.Name])) return ;
      PolyFillsAdded.push(Name);
      Content.push(Name + ' = ' + Function);
    });
    Content = "(function(){\n\n// Polyfills Added:  " + PolyFillsAdded.join(', ') + "\n\n" + Content.join(";\n") + ";\n})()";
    PolyfillCache.set(CacheKey, Content);
    Response.write(Content);
  }
  static matches(Browser, Condition){
    if(Condition.indexOf('-') !== -1){
      let Chunks = Condition.split('-');
      return Browser.Version >= Number(Chunks[0].trim()) && Browser.Version <= Number(Chunks[1].trim());
    } else {
      return Browser.Version === Number(Condition);
    }
  }
  static recognizeBrowser(UserAgent){

    if(BrowserCache.has(UserAgent)) return BrowserCache.get(UserAgent);

    // Taken from http://stackoverflow.com/a/8754134/2652018
    var Browser = {Name: '', Version: 0};
    try {
      if (/Opera[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Opera;
      } else if (/MSIE (\d+\.\d+);/.test(UserAgent)) {
        Browser.Name = Polyfill.IE;
      } else if (/Navigator[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Netscape;
      } else if (/Chrome[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Chrome;
      } else if (/Safari[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Safari;
        /Version[\/\s](\d+\.\d+)/.test(UserAgent);
        Browser.Version = Number(RegExp.$1);
      } else if (/Firefox[\/\s](\d+\.\d+)/.test(UserAgent)) {
        Browser.Name = Polyfill.Firefox;
      }
      if(Browser.Version === 0){
        Browser.Version = parseFloat(Number(RegExp.$1));
      }
    } catch(e) {}

    BrowserCache.set(UserAgent, Browser);
    return Browser;
  }
}

Polyfill.Opera = 'Opera';
Polyfill.IE = 'IE';
Polyfill.Netscape = 'Netscape';
Polyfill.Chrome = 'Chrome';
Polyfill.Safari = 'Safari';
Polyfill.Firefox = 'Firefox';

global.SmartPolyfill = Polyfill;

module.exports = Polyfill;<|endoftext|>


<commit_before>/*
 * The Application Management extension.
 */

var management = module.exports;

/**
 * The navigation() hook.
 */
management.navigation = function(navigations, callback) {
  var newNavigations = {};

  newNavigations['manage'] = {
    title: 'Manage',
    description: 'Site management navigation.',
    classes: ['nav-pills'],
    stacked: true,
    items: [
      {
        title: 'Overview',
        url: '/manage'
      },
      {
        title: 'Pages',
        url: '/manage/pages'
      },
      {
        title: 'Panels',
        url: '/manage/panels'
      },
      {
        title: 'Contexts',
        url: '/manage/contexts'
      },
      {
        title: 'Layouts',
        url: '/manage/layouts'
      },
      {
        title: 'Navigations',
        url: '/manage/navigations'
      },
      {
        title: 'Types',
        url: '/manage/types'
      },
      {
        title: 'Extensions',
        url: '/manage/extensions'
      }
    ]
  };

  // Add main navigation item for the management pages.
  navigations['main'].items.push({
    title: 'Manage',
    url: '/manage'
  });

  callback(null, newNavigations);
};

/**
 * The page() hook.
 */
management.page = function(pages, callback) {
  var self= this;
  var newPages = {};

  newPages['manage'] = {
    path: '/manage',
    title: 'Dashboard',
    access: 'manage application',
    content: '
Dashboard content.
'
  };

  newPages['manage-pages'] = {
    path: '/manage/pages',
    title: 'Pages',
    access: 'manage panels',
    type: 'list',
    itemType: 'panel',
    template: 'templates/list-group.html'
  };

  newPages['manage-panels'] = {
    path: '/manage/panels',
    title: 'Panels',
    subtitle: 'Chunks of information',
    description: 'Panels are chunks of content or UI that can be added to layout regions.',
    access: 'manage panels',
    type: 'list',
    itemType: 'panel',
    template: 'templates/list-group.html'
  };

  newPages['manage-contexts'] = {
    path: '/manage/contexts',
    title: 'Contexts',
    access: 'manage contexts',
    type: 'list',
    itemType: 'context',
    template: 'templates/list-group.html'
  };

  newPages['manage-layouts'] = {
    path: '/manage/layouts',
    title: 'Layouts',
    access: 'manage layouts',
    type: 'list',
    itemType: 'layout',
    template: 'templates/list-group.html'
  };

  newPages['manage-navigations'] = {
    path: '/manage/navigations',
    title: 'Navigations',
    access: 'manage navigations',
    type: 'list',
    itemType: 'navigation',
    template: 'templates/list-group.html'
  };

  newPages['manage-types'] = {
    path: '/manage/types',
    title: 'Types',
    access: 'manage types',
    callback: function(request, response, callback) {
      var types = self.application.types;
      var result = {};
      for (var typeName in types) {
        var type = types[typeName];
        result[typeName] = {
          title: type.type.settings.title,
          description: type.type.settings.description
        };
      }
      response.payload.page.items = result;
      callback();
    },
    template: 'templates/list-group.html'
  };

  newPages['manage-extensions'] = {
    path: '/manage/extensions',
    title: 'Extensions',
    access: 'manage extensions',
    callback: function(request, response, callback) {
      var extensions = self.application.extensions;
      var result = {};
      for (var extensionName in extensions) {
        var extension = extensions[extensionName];
        result[extensionName] = {
          title: extension.settings.title,
          description: extension.settings.description
        };
      }
      response.payload.page.items = result;
      callback();
    },
    template: 'templates/list-group.html'
  };

  callback(null, newPages);
};

/**
 * The context() hook.
 */
management.context = function(contexts, callback) {
  var newContexts = {};

  newContexts['manage'] = {
    title: 'Management pages',
    description: 'Management pages context.',
    access: 'access application',
    weight: -1,
    conditions: {
      path: ['/manage', '/manage/*']
    },
    reactions: {
      theme: 'default',
      layout: 'two-columns-3-9',
      panel: {
        'sidebar': [{
          name: 'navigation-manage',
          weight: 0
        }]
      }
    }
  };

  callback(null, newContexts);
};
<commit_msg>Adding subtitle and description to all management pages.<commit_after>/*
 * The Application Management extension.
 */

var management = module.exports;

/**
 * The navigation() hook.
 */
management.navigation = function(navigations, callback) {
  var newNavigations = {};

  newNavigations['manage'] = {
    title: 'Manage',
    description: 'Site management navigation.',
    classes: ['nav-pills'],
    stacked: true,
    items: [
      {
        title: 'Overview',
        url: '/manage'
      },
      {
        title: 'Pages',
        url: '/manage/pages'
      },
      {
        title: 'Panels',
        url: '/manage/panels'
      },
      {
        title: 'Contexts',
        url: '/manage/contexts'
      },
      {
        title: 'Layouts',
        url: '/manage/layouts'
      },
      {
        title: 'Navigations',
        url: '/manage/navigations'
      },
      {
        title: 'Types',
        url: '/manage/types'
      },
      {
        title: 'Extensions',
        url: '/manage/extensions'
      }
    ]
  };

  // Add main navigation item for the management pages.
  navigations['main'].items.push({
    title: 'Manage',
    url: '/manage'
  });

  callback(null, newNavigations);
};

/**
 * The page() hook.
 */
management.page = function(pages, callback) {
  var self= this;
  var newPages = {};

  newPages['manage'] = {
    path: '/manage',
    title: 'Dashboard',
    access: 'manage application',
    content: '
Dashboard content.
'
  };

  newPages['manage-pages'] = {
    path: '/manage/pages',
    title: 'Pages',
    subtitle: 'Application screens',
    description: 'Pages are used to create sections and display application content and UI elements on the application.',
    access: 'manage panels',
    type: 'list',
    itemType: 'panel',
    template: 'templates/list-group.html'
  };

  newPages['manage-panels'] = {
    path: '/manage/panels',
    title: 'Panels',
    subtitle: 'Pieces of information',
    description: 'Panels are chunks of content or UI that can be added to layout regions.',
    access: 'manage panels',
    type: 'list',
    itemType: 'panel',
    template: 'templates/list-group.html'
  };

  newPages['manage-contexts'] = {
    path: '/manage/contexts',
    title: 'Contexts',
    subtitle: 'Add dynamicity',
    description: 'Contexts are a set of conditions that creates a particular scenario on the application.',
    access: 'manage contexts',
    type: 'list',
    itemType: 'context',
    template: 'templates/list-group.html'
  };

  newPages['manage-layouts'] = {
    path: '/manage/layouts',
    title: 'Layouts',
    subtitle: 'Page structure',
    description: 'Layouts rule how pages are structured in rows, columns and regions.',
    access: 'manage layouts',
    type: 'list',
    itemType: 'layout',
    template: 'templates/list-group.html'
  };

  newPages['manage-navigations'] = {
    path: '/manage/navigations',
    title: 'Navigations',
    subtitle: 'Navigation menus and links',
    description: 'Groups of structured links that allow users to change application state.',
    access: 'manage navigations',
    type: 'list',
    itemType: 'navigation',
    template: 'templates/list-group.html'
  };

  newPages['manage-types'] = {
    path: '/manage/types',
    title: 'Types',
    subtitle: 'Resource types',
    description: 'Types can be everything from application metadata to media objects.',
    access: 'manage types',
    callback: function(request, response, callback) {
      var types = self.application.types;
      var result = {};
      for (var typeName in types) {
        var type = types[typeName];
        result[typeName] = {
          title: type.type.settings.title,
          description: type.type.settings.description
        };
      }
      response.payload.page.items = result;
      callback();
    },
    template: 'templates/list-group.html'
  };

  newPages['manage-extensions'] = {
    path: '/manage/extensions',
    title: 'Extensions',
    subtitle: 'The building blocks',
    description: 'Extensions are groups of functionality.',
    access: 'manage extensions',
    callback: function(request, response, callback) {
      var extensions = self.application.extensions;
      var result = {};
      for (var extensionName in extensions) {
        var extension = extensions[extensionName];
        result[extensionName] = {
          title: extension.settings.title,
          description: extension.settings.description
        };
      }
      response.payload.page.items = result;
      callback();
    },
    template: 'templates/list-group.html'
  };

  callback(null, newPages);
};

/**
 * The context() hook.
 */
management.context = function(contexts, callback) {
  var newContexts = {};

  newContexts['manage'] = {
    title: 'Management pages',
    description: 'Management pages context.',
    access: 'access application',
    weight: -1,
    conditions: {
      path: ['/manage', '/manage/*']
    },
    reactions: {
      theme: 'default',
      layout: 'two-columns-3-9',
      panel: {
        'sidebar': [{
          name: 'navigation-manage',
          weight: 0
        }]
      }
    }
  };

  callback(null, newContexts);
};
<|endoftext|>


<commit_before>/**
 * @author tschw
 * @author Ben Houston / http://clara.io/
 * @author David Sarno / http://lighthaus.us/
 */

var AnimationUtils = {

	// same as Array.prototype.slice, but also works on typed arrays
	arraySlice: function( array, from, to ) {

		if ( AnimationUtils.isTypedArray( array ) ) {

			return new array.constructor( array.subarray( from, to ) );

		}

		return array.slice( from, to );

	},

	// converts an array to a specific type
	convertArray: function( array, type, forceClone ) {

		if ( ! array || // let 'undefined' and 'null' pass
				! forceClone && array.constructor === type ) return array;

		if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {

			return new type( array ); // create typed array

		}

		return Array.prototype.slice.call( array ); // create Array

	},

	isTypedArray: function( object ) {

		return ArrayBuffer.isView( object ) &&
				! ( object instanceof DataView );

	},

	// returns an array by which times and values can be sorted
	getKeyframeOrder: function( times ) {

		function compareTime( i, j ) {

			return times[ i ] - times[ j ];

		}

		var n = times.length;
		var result = new Array( n );
		for ( var i = 0; i !== n; ++ i ) result[ i ] = i;

		result.sort( compareTime );

		return result;

	},

	// uses the array previously returned by 'getKeyframeOrder' to sort data
	sortedArray: function( values, stride, order ) {

		var nValues = values.length;
		var result = new values.constructor( nValues );

		for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {

			var srcOffset = order[ i ] * stride;

			for ( var j = 0; j !== stride; ++ j ) {

				result[ dstOffset ++ ] = values[ srcOffset + j ];

			}

		}

		return result;

	},

	// function for parsing AOS keyframe formats
	flattenJSON: function( jsonKeys, times, values, valuePropertyName ) {

		var i = 1, key = jsonKeys[ 0 ];

		while ( key !== undefined && key[ valuePropertyName ] === undefined ) {

			key = jsonKeys[ i ++ ];

		}

		if ( key === undefined ) return; // no data

		var value = key[ valuePropertyName ];
		if ( value === undefined ) return; // no data

		if ( Array.isArray( value ) ) {

			do {

				value = key[ valuePropertyName ];

				if ( value !== undefined ) {

					times.push( key.time );
					values.push.apply( values, value ); // push all elements

				}

				key = jsonKeys[ i ++ ];

			} while ( key !== undefined );

		} else if ( value.toArray !== undefined ) {
			// ...assume THREE.Math-ish

			do {

				value = key[ valuePropertyName ];

				if ( value !== undefined ) {

					times.push( key.time );
					value.toArray( values, values.length );

				}

				key = jsonKeys[ i ++ ];

			} while ( key !== undefined );

		} else {
			// otherwise push as-is

			do {

				value = key[ valuePropertyName ];

				if ( value !== undefined ) {

					times.push( key.time );
					values.push( value );

				}

				key = jsonKeys[ i ++ ];

			} while ( key !== undefined );

		}

	}

};

export { AnimationUtils };
<commit_msg>fix ios9 TypedArray.subarray(from, undefined) bug<commit_after>/**
 * @author tschw
 * @author Ben Houston / http://clara.io/
 * @author David Sarno / http://lighthaus.us/
 */

var AnimationUtils = {

	// same as Array.prototype.slice, but also works on typed arrays
	arraySlice: function( array, from, to ) {

		if ( AnimationUtils.isTypedArray( array ) ) {

			// in ios9 array.subarray(from, undefined) will return empty array
			// but array.subarray(from) or array.subarray(from, len) is correct
			return new array.constructor( array.subarray( from, to || array.length ) );

		}

		return array.slice( from, to );

	},

	// converts an array to a specific type
	convertArray: function( array, type, forceClone ) {

		if ( ! array || // let 'undefined' and 'null' pass
				! forceClone && array.constructor === type ) return array;

		if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {

			return new type( array ); // create typed array

		}

		return Array.prototype.slice.call( array ); // create Array

	},

	isTypedArray: function( object ) {

		return ArrayBuffer.isView( object ) &&
				! ( object instanceof DataView );

	},

	// returns an array by which times and values can be sorted
	getKeyframeOrder: function( times ) {

		function compareTime( i, j ) {

			return times[ i ] - times[ j ];

		}

		var n = times.length;
		var result = new Array( n );
		for ( var i = 0; i !== n; ++ i ) result[ i ] = i;

		result.sort( compareTime );

		return result;

	},

	// uses the array previously returned by 'getKeyframeOrder' to sort data
	sortedArray: function( values, stride, order ) {

		var nValues = values.length;
		var result = new values.constructor( nValues );

		for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {

			var srcOffset = order[ i ] * stride;

			for ( var j = 0; j !== stride; ++ j ) {

				result[ dstOffset ++ ] = values[ srcOffset + j ];

			}

		}

		return result;

	},

	// function for parsing AOS keyframe formats
	flattenJSON: function( jsonKeys, times, values, valuePropertyName ) {

		var i = 1, key = jsonKeys[ 0 ];

		while ( key !== undefined && key[ valuePropertyName ] === undefined ) {

			key = jsonKeys[ i ++ ];

		}

		if ( key === undefined ) return; // no data

		var value = key[ valuePropertyName ];
		if ( value === undefined ) return; // no data

		if ( Array.isArray( value ) ) {

			do {

				value = key[ valuePropertyName ];

				if ( value !== undefined ) {

					times.push( key.time );
					values.push.apply( values, value ); // push all elements

				}

				key = jsonKeys[ i ++ ];

			} while ( key !== undefined );

		} else if ( value.toArray !== undefined ) {
			// ...assume THREE.Math-ish

			do {

				value = key[ valuePropertyName ];

				if ( value !== undefined ) {

					times.push( key.time );
					value.toArray( values, values.length );

				}

				key = jsonKeys[ i ++ ];

			} while ( key !== undefined );

		} else {
			// otherwise push as-is

			do {

				value = key[ valuePropertyName ];

				if ( value !== undefined ) {

					times.push( key.time );
					values.push( value );

				}

				key = jsonKeys[ i ++ ];

			} while ( key !== undefined );

		}

	}

};

export { AnimationUtils };
<|endoftext|>


<commit_before>var readline = require('readline');
var Vlc = require('../vlc');
var EventEmitter = require('events').EventEmitter;
var VLCevent = new EventEmitter();

var vlc = new Vlc([
  '-I', 'dummy',
  '--no-video-title-show',
]);

	var rl = readline.createInterface({
		input: process.stdin,
	  	output: process.stdout
	})

function Choose_Video(lien, pos)
{
	var media = vlc.mediaFromFile(lien);//ici le lien de la vidéo. mediaFromFile est une fonction dans le fichier vlc.js
	media.parseSync();

	media.track_info.forEach(function (info) {
	  console.log(info);
	});

	console.log(media.artist, '--', media.album, '--', media.title);

	var player = vlc.mediaplayer;
	player.media = media;
	console.log('Media duration:', media.duration);

	player.play();
	var POS = pos;
	player.position = POS;

	return {'1':player, '2':media};

}

function Video_Paused(player, media, POS)
{
	player.on('Paused',function(){
	    	PausedQuest(player, media, POS);
	});
}

function Video_Playing(player, media)
{
	player.on('Playing',function(){
		SecondQuest(player, media);
	});
}

function SecondQuest(player, media)
{
	rl.question("type q to exit or p to pause: ", function(answer) {
		if(answer=="q"){
			 player.stop();
			 media.release();
			 vlc.release();
			 rl.close();
		}
		else if (answer=="p"){
			player.pause();

		}
		else {
			console.log("\nYou're answer is not correct please try again!!");
			SecondQuest(player,media);
		}

	});
}

function PausedQuest(player, media, POS)
{
	rl.question('type : \n q to exit \n b to return back to the Menu '+
		'\n c to continue playing \n r to replay \n ===> ', function(answer) {
			ans=answer;
			if(answer=="q"){
				 player.stop();
				 media.release();
				 vlc.release();
				 rl.close();
			}
			else if (answer=="r"){
			   player.stop();
			   player.play();
			}
			else if (answer=="c"){
			   player.play();
			}
			else if (answer == "b"){
			   Menu();
			}
			else{
			   console.log("\nYou're answer is not correct please try again!!");
			   PausedQuest(player, media, POS);
			}
		});
}

function Menu()
{
   rl.question("\t\t\tMENU \ntype 1 or 2 to see each video or q to exit : ", function(answer) {
	   switch (answer){
		case '1':
			var Dico = Choose_Video('/home/khamaily/Stage Holusion/mars.mp4',0.0);
			Video_Paused(Dico['1'], Dico['2'], 0.0);
			Video_Playing(Dico['1'], Dico['2'], 0.0);
			SecondQuest(Dico['1'], Dico['2']);
			break;
		case 'q':
			vlc.release();
			rl.close();
			break;
		case '2':
			var Dico = Choose_Video('/home/khamaily/Stage Holusion/test.mp4',0.0);
			Video_Paused(Dico['1'], Dico['2'], 0.0);
			Video_Playing(Dico['1'], Dico['2'], 0.0);
			SecondQuest(Dico['1'], Dico['2']);
			break;
		default:
			console.log("\nYou're answer is not correct please try again!!");
			Menu();
			break;
	   }
   });
}

Menu();

<commit_msg>refctored example app<commit_after>var readline = require('readline');
var Vlc = require('../vlc');
var EventEmitter = require('events').EventEmitter;
var VLCevent = new EventEmitter();

var vlc = new Vlc([
  '-I', 'dummy',
  '--no-video-title-show',
  '--logmode','syslog',
  '--syslog',
  '--syslog-facility','local7',

]);
var media = vlc.mediaFromFile(process.argv[2]);
media.parseSync();

media.track_info.forEach(function (info) {
  console.log(info);
});

console.log(media.artist, '--', media.album, '--', media.title);

var player = vlc.mediaplayer;
player.media = media;
console.log('Media duration:', media.duration);

player.play();

player.on('Paused',function(){
	console.log("paused");
});
player.on('EncounteredError',function(){

	console.log(vlc.errmsg());
	console.log("error")
})

setTimeout(function(){
	player.stop();
    media.release();
    vlc.release();
},10000)
<|endoftext|>


<commit_before>
/* globals Erizo */

/* eslint-env browser */
/* eslint-disable no-param-reassign, no-console */

const serverUrl = '/';
let localStream;
let room;
let recording;
let recordingId;

const getParameterByName = (name) => {
  // eslint-disable-next-line
  name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]');
  const regex = new RegExp(`[\\?&]${name}=([^&#]*)`);
  const results = regex.exec(location.search);
  return results == null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
};

// eslint-disable-next-line no-unused-vars
const testConnection = () => {
  window.location = '/connection_test.html';
};

// eslint-disable-next-line no-unused-vars
function startRecording() {
  if (room !== undefined) {
    if (!recording) {
      room.startRecording(localStream, (id) => {
        recording = true;
        recordingId = id;
      });
    } else {
      room.stopRecording(recordingId);
      recording = false;
    }
  }
}

let slideShowMode = false;

// eslint-disable-next-line no-unused-vars
function toggleSlideShowMode() {
  const streams = room.remoteStreams;
  const cb = (evt) => {
    console.log('SlideShowMode changed', evt);
  };
  slideShowMode = !slideShowMode;
  streams.forEach((stream) => {
    if (localStream.getID() !== stream.getID()) {
      console.log('Updating config');
      stream.updateConfiguration({ slideShowMode }, cb);
    }
  });
}

const startBasicExample = () => {
  document.getElementById('startButton').disabled = true;
  document.getElementById('slideShowMode').disabled = false;
  document.getElementById('startWarning').hidden = true;
  document.getElementById('startButton').hidden = true;
  recording = false;
  const screen = getParameterByName('screen');
  const roomName = getParameterByName('room') || 'basicExampleRoom';
  const singlePC = getParameterByName('singlePC') || false;
  const roomType = getParameterByName('type') || 'erizo';
  const audioOnly = getParameterByName('onlyAudio') || false;
  const mediaConfiguration = getParameterByName('mediaConfiguration') || 'default';
  const onlySubscribe = getParameterByName('onlySubscribe');
  const onlyPublish = getParameterByName('onlyPublish');
  const autoSubscribe = getParameterByName('autoSubscribe');
  const offerFromErizo = getParameterByName('offerFromErizo');
  console.log('Selected Room', roomName, 'of type', roomType);
  const config = { audio: true,
    video: !audioOnly,
    data: true,
    screen,
    attributes: {} };
  // If we want screen sharing we have to put our Chrome extension id.
  // The default one only works in our Lynckia test servers.
  // If we are not using chrome, the creation of the stream will fail regardless.
  if (screen) {
    config.extensionId = 'okeephmleflklcdebijnponpabbmmgeo';
  }
  Erizo.Logger.setLogLevel(Erizo.Logger.INFO);
  localStream = Erizo.Stream(config);
  const createToken = (roomData, callback) => {
    const req = new XMLHttpRequest();
    const url = `${serverUrl}createToken/`;

    req.onreadystatechange = () => {
      if (req.readyState === 4) {
        callback(req.responseText);
      }
    };

    req.open('POST', url, true);
    req.setRequestHeader('Content-Type', 'application/json');
    req.send(JSON.stringify(roomData));
  };

  const roomData = { username: `user ${parseInt(Math.random() * 100, 10)}`,
    role: 'presenter',
    room: roomName,
    type: roomType,
    mediaConfiguration };

  createToken(roomData, (response) => {
    const token = response;
    console.log(token);
    room = Erizo.Room({ token });

    const subscribeToStreams = (streams) => {
      if (autoSubscribe) {
        return;
      }
      if (onlyPublish) {
        return;
      }
      const cb = (evt) => {
        console.log('Bandwidth Alert', evt.msg, evt.bandwidth);
      };

      streams.forEach((stream) => {
        if (localStream.getID() !== stream.getID()) {
          room.subscribe(stream, { slideShowMode, metadata: { type: 'subscriber' }, offerFromErizo });
          stream.addEventListener('bandwidth-alert', cb);
        }
      });
    };

    room.addEventListener('room-connected', (roomEvent) => {
      const options = { metadata: { type: 'publisher' } };
      const enableSimulcast = getParameterByName('simulcast');
      if (enableSimulcast) options.simulcast = { numSpatialLayers: 2 };
      subscribeToStreams(roomEvent.streams);

      if (!onlySubscribe) {
        room.publish(localStream, options);
      }
      room.addEventListener('quality-level', (qualityEvt) => {
        console.log(`New Quality Event, connection quality: ${qualityEvt.message}`);
      });
      if (autoSubscribe) {
        room.autoSubscribe({ '/attributes/type': 'publisher' }, {}, { audio: true, video: true, data: false }, () => {});
      }
    });

    room.addEventListener('stream-subscribed', (streamEvent) => {
      const stream = streamEvent.stream;
      const div = document.createElement('div');
      div.setAttribute('style', 'width: 320px; height: 240px;float:left;');
      div.setAttribute('id', `test${stream.getID()}`);

      document.getElementById('videoContainer').appendChild(div);
      stream.show(`test${stream.getID()}`);
    });

    room.addEventListener('stream-added', (streamEvent) => {
      const streams = [];
      streams.push(streamEvent.stream);
      if (localStream) {
        localStream.setAttributes({ type: 'publisher' });
      }
      subscribeToStreams(streams);
      document.getElementById('recordButton').disabled = false;
    });

    room.addEventListener('stream-removed', (streamEvent) => {
      // Remove stream from DOM
      const stream = streamEvent.stream;
      if (stream.elementID !== undefined) {
        const element = document.getElementById(stream.elementID);
        document.getElementById('videoContainer').removeChild(element);
      }
    });

    room.addEventListener('stream-failed', () => {
      console.log('Stream Failed, act accordingly');
    });

    if (onlySubscribe) {
      room.connect({ singlePC });
    } else {
      const div = document.createElement('div');
      div.setAttribute('style', 'width: 320px; height: 240px; float:left');
      div.setAttribute('id', 'myVideo');
      document.getElementById('videoContainer').appendChild(div);

      localStream.addEventListener('access-accepted', () => {
        room.connect({ singlePC });
        localStream.show('myVideo');
      });
      localStream.init();
    }
  });
};

window.onload = () => {
  const onlySubscribe = getParameterByName('onlySubscribe');
  const bypassStartButton = getParameterByName('noStart');
  if (!onlySubscribe || bypassStartButton) {
    startBasicExample();
  } else {
    document.getElementById('startButton').disabled = false;
  }
};
<commit_msg>Make global variables part of window in basicExample (#1605)<commit_after>
/* globals Erizo */

/* eslint-env browser */
/* eslint-disable no-param-reassign, no-console */

const serverUrl = '/';
window.localStream = undefined;
window.room = undefined;
window.recording = false;
window.recordingId = '';

const getParameterByName = (name) => {
  // eslint-disable-next-line
  name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]');
  const regex = new RegExp(`[\\?&]${name}=([^&#]*)`);
  const results = regex.exec(location.search);
  return results == null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
};

// eslint-disable-next-line no-unused-vars
const testConnection = () => {
  window.location = '/connection_test.html';
};

// eslint-disable-next-line no-unused-vars
function startRecording() {
  if (window.room !== undefined) {
    if (!window.recording) {
      window.room.startRecording(window.localStream, (id) => {
        window.recording = true;
        window.recordingId = id;
      });
    } else {
      window.room.stopRecording(window.recordingId);
      window.recording = false;
    }
  }
}

let slideShowMode = false;

// eslint-disable-next-line no-unused-vars
function toggleSlideShowMode() {
  const streams = window.room.remoteStreams;
  const cb = (evt) => {
    console.log('SlideShowMode changed', evt);
  };
  slideShowMode = !slideShowMode;
  streams.forEach((stream) => {
    if (window.localStream.getID() !== stream.getID()) {
      console.log('Updating config');
      stream.updateConfiguration({ slideShowMode }, cb);
    }
  });
}

const startBasicExample = () => {
  document.getElementById('startButton').disabled = true;
  document.getElementById('slideShowMode').disabled = false;
  document.getElementById('startWarning').hidden = true;
  document.getElementById('startButton').hidden = true;
  window.recording = false;
  const screen = getParameterByName('screen');
  const roomName = getParameterByName('room') || 'basicExampleRoom';
  const singlePC = getParameterByName('singlePC') || false;
  const roomType = getParameterByName('type') || 'erizo';
  const audioOnly = getParameterByName('onlyAudio') || false;
  const mediaConfiguration = getParameterByName('mediaConfiguration') || 'default';
  const onlySubscribe = getParameterByName('onlySubscribe');
  const onlyPublish = getParameterByName('onlyPublish');
  const autoSubscribe = getParameterByName('autoSubscribe');
  const offerFromErizo = getParameterByName('offerFromErizo');
  console.log('Selected Room', roomName, 'of type', roomType);
  const config = { audio: true,
    video: !audioOnly,
    data: true,
    screen,
    attributes: {} };
  // If we want screen sharing we have to put our Chrome extension id.
  // The default one only works in our Lynckia test servers.
  // If we are not using chrome, the creation of the stream will fail regardless.
  if (screen) {
    config.extensionId = 'okeephmleflklcdebijnponpabbmmgeo';
  }
  Erizo.Logger.setLogLevel(Erizo.Logger.INFO);
  window.localStream = Erizo.Stream(config);
  const createToken = (roomData, callback) => {
    const req = new XMLHttpRequest();
    const url = `${serverUrl}createToken/`;

    req.onreadystatechange = () => {
      if (req.readyState === 4) {
        callback(req.responseText);
      }
    };

    req.open('POST', url, true);
    req.setRequestHeader('Content-Type', 'application/json');
    req.send(JSON.stringify(roomData));
  };

  const roomData = { username: `user ${parseInt(Math.random() * 100, 10)}`,
    role: 'presenter',
    room: roomName,
    type: roomType,
    mediaConfiguration };

  createToken(roomData, (response) => {
    const token = response;
    console.log(token);
    window.room = Erizo.Room({ token });

    const subscribeToStreams = (streams) => {
      if (autoSubscribe) {
        return;
      }
      if (onlyPublish) {
        return;
      }
      const cb = (evt) => {
        console.log('Bandwidth Alert', evt.msg, evt.bandwidth);
      };

      streams.forEach((stream) => {
        if (window.localStream.getID() !== stream.getID()) {
          window.room.subscribe(stream, { slideShowMode, metadata: { type: 'subscriber' }, offerFromErizo });
          stream.addEventListener('bandwidth-alert', cb);
        }
      });
    };

    window.room.addEventListener('room-connected', (roomEvent) => {
      const options = { metadata: { type: 'publisher' } };
      const enableSimulcast = getParameterByName('simulcast');
      if (enableSimulcast) options.simulcast = { numSpatialLayers: 2 };
      subscribeToStreams(roomEvent.streams);

      if (!onlySubscribe) {
        window.room.publish(window.localStream, options);
      }
      window.room.addEventListener('quality-level', (qualityEvt) => {
        console.log(`New Quality Event, connection quality: ${qualityEvt.message}`);
      });
      if (autoSubscribe) {
        window.room.autoSubscribe({ '/attributes/type': 'publisher' }, {}, { audio: true, video: true, data: false }, () => {});
      }
    });

    window.room.addEventListener('stream-subscribed', (streamEvent) => {
      const stream = streamEvent.stream;
      const div = document.createElement('div');
      div.setAttribute('style', 'width: 320px; height: 240px;float:left;');
      div.setAttribute('id', `test${stream.getID()}`);

      document.getElementById('videoContainer').appendChild(div);
      stream.show(`test${stream.getID()}`);
    });

    window.room.addEventListener('stream-added', (streamEvent) => {
      const streams = [];
      streams.push(streamEvent.stream);
      if (window.localStream) {
        window.localStream.setAttributes({ type: 'publisher' });
      }
      subscribeToStreams(streams);
      document.getElementById('recordButton').disabled = false;
    });

    window.room.addEventListener('stream-removed', (streamEvent) => {
      // Remove stream from DOM
      const stream = streamEvent.stream;
      if (stream.elementID !== undefined) {
        const element = document.getElementById(stream.elementID);
        document.getElementById('videoContainer').removeChild(element);
      }
    });

    window.room.addEventListener('stream-failed', () => {
      console.log('Stream Failed, act accordingly');
    });

    if (onlySubscribe) {
      window.room.connect({ singlePC });
    } else {
      const div = document.createElement('div');
      div.setAttribute('style', 'width: 320px; height: 240px; float:left');
      div.setAttribute('id', 'myVideo');
      document.getElementById('videoContainer').appendChild(div);

      window.localStream.addEventListener('access-accepted', () => {
        window.room.connect({ singlePC });
        window.localStream.show('myVideo');
      });
      window.localStream.init();
    }
  });
};

window.onload = () => {
  const onlySubscribe = getParameterByName('onlySubscribe');
  const bypassStartButton = getParameterByName('noStart');
  if (!onlySubscribe || bypassStartButton) {
    startBasicExample();
  } else {
    document.getElementById('startButton').disabled = false;
  }
};
<|endoftext|>