<commit_before>var savedModel;

function actionFormatter(value, row, index) {
    return [
        '',
        '',
        ''
    ].join('');
}

function CandidateCreateModel(){
    ko.bindingHandlers.valueWithInit = {
        init: function(element, valueAccessor, allBindingsAccessor, data) {
            var property = valueAccessor(),
                value = element.value;

            //create the observable, if it doesn't exist
            if (!ko.isWriteableObservable(data[property])) {
                data[property] = ko.observable();
            }

            data[property](value);

            ko.applyBindingsToNode(element, { value: data[property] });
        }
    };

    ko.bindingHandlers.initDisplay = {
        init: function(element, valueAccessor, allBindingsAccessor, data) {
            self.modify(true);
        }
    };

    var self = this;
    self.errorResponse = ko.observable(null);
    self.showError = ko.observable(false);

    self.ajaxCall = function() {
        var form = $("#candidate-create-form");
        $.ajax({
            url: form.attr('action'),
            method: form.attr('method'),
            contentType: 'application/json',
            dataType: "json",
            data: JSON.stringify({
                id: self.id(),
                name: self.name(),
                referer: self.referer(),
                email: self.email(),
                languageSkill: self.languageSkill(),
                phone: self.phone(),
                description: self.description()
            })
        }).done(function (xhr) {
            window.location = form.attr('action')+ '/' + xhr.id;
        }).error(function (xhr) {
            self.errorResponse(xhr.responseJSON);

            self.showError(true);
        });
    }

    self.errorMessage = ko.pureComputed(function() {
      if (self.errorResponse() === null) {
        return ""
      }

      return self.errorResponse().errorMessage;
    });

    self.fieldMessages = ko.pureComputed(function() {
        if (self.errorResponse() === null) {
          return [];
        }

        return Object.keys(self.errorResponse().fields).map(function(key) {
            return self.errorResponse().fields[key];
        });
    });

    self.modify = ko.observable(false);
    modify_display_true = function() {
        self.modify(true);
        self.showError(false);
        $("#candidate-create-form").validator('destroy');
        candidateModel.id(savedModel.id);
        candidateModel.name(savedModel.name);
        candidateModel.referer(savedModel.referer);
        candidateModel.email(savedModel.email);
        candidateModel.languageSkill(savedModel.languageSkill);
        candidateModel.phone(savedModel.phone);
        candidateModel.referer(savedModel.referer);
    };
    modify_display_false = function() {
        self.modify(false);
        savedModel = ko.toJS(candidateModel);
    };
    save_button = function() {
        self.ajaxCall();
    };

    self.cssclass = ko.computed(function() {
        if (self.modify == true) {
            return "display";
        } else {
            return "";
        }
    });
}

var candidateModel = new CandidateCreateModel();

$('#candidate-create-form').validator().on('submit', function (e) {
  if (e.isDefaultPrevented()) {
    // handle the invalid form...
  } else {
    candidateModel.ajaxCall();
    return false;
  }
});

ko.applyBindings(candidateModel);

function creationDateFormatter(value, row, index) {
    var dateTime = new Date(row.creationDate);
    return dateTimeFormatter(dateTime);
}

function modificationDateFormatter(value, row, index) {
    var dateTime = new Date(row.modificationDate);
    return dateTimeFormatter(dateTime);
}

function dateTimeFormatter(dateTime) {
    var year = dateTime.getFullYear();
    var month = dateTime.getMonth() + 1;
    month = month.length == 2 ? month : ('0' + month);

    var day = dateTime.getDate();
    day = day.length == 2 ? day : ('0' + day);

    var hour = dateTime.getHours();
    hour = hour.toString().length == 2 ? hour : ('0' + hour);

    var minute = dateTime.getMinutes();
    minute = minute.toString().length == 2 ? minute : ('0' + minute);

    var second = dateTime.getSeconds();
    second = second.toString().length == 2 ? second : ('0' + second);

    return year + '-' + month + '-' + day + " " + hour + ":" + minute + ':' + second;
}
<commit_msg>Fixed dateTimeFormatter issue<commit_after>var savedModel;

function actionFormatter(value, row, index) {
    return [
        '',
        '',
        ''
    ].join('');
}

function CandidateCreateModel(){
    ko.bindingHandlers.valueWithInit = {
        init: function(element, valueAccessor, allBindingsAccessor, data) {
            var property = valueAccessor(),
                value = element.value;

            //create the observable, if it doesn't exist
            if (!ko.isWriteableObservable(data[property])) {
                data[property] = ko.observable();
            }

            data[property](value);

            ko.applyBindingsToNode(element, { value: data[property] });
        }
    };

    ko.bindingHandlers.initDisplay = {
        init: function(element, valueAccessor, allBindingsAccessor, data) {
            self.modify(true);
        }
    };

    var self = this;
    self.errorResponse = ko.observable(null);
    self.showError = ko.observable(false);

    self.ajaxCall = function() {
        var form = $("#candidate-create-form");
        $.ajax({
            url: form.attr('action'),
            method: form.attr('method'),
            contentType: 'application/json',
            dataType: "json",
            data: JSON.stringify({
                id: self.id(),
                name: self.name(),
                referer: self.referer(),
                email: self.email(),
                languageSkill: self.languageSkill(),
                phone: self.phone(),
                description: self.description()
            })
        }).done(function (xhr) {
            window.location = form.attr('action')+ '/' + xhr.id;
        }).error(function (xhr) {
            self.errorResponse(xhr.responseJSON);

            self.showError(true);
        });
    }

    self.errorMessage = ko.pureComputed(function() {
      if (self.errorResponse() === null) {
        return ""
      }

      return self.errorResponse().errorMessage;
    });

    self.fieldMessages = ko.pureComputed(function() {
        if (self.errorResponse() === null) {
          return [];
        }

        return Object.keys(self.errorResponse().fields).map(function(key) {
            return self.errorResponse().fields[key];
        });
    });

    self.modify = ko.observable(false);
    modify_display_true = function() {
        self.modify(true);
        self.showError(false);
        $("#candidate-create-form").validator('destroy');
        candidateModel.id(savedModel.id);
        candidateModel.name(savedModel.name);
        candidateModel.referer(savedModel.referer);
        candidateModel.email(savedModel.email);
        candidateModel.languageSkill(savedModel.languageSkill);
        candidateModel.phone(savedModel.phone);
        candidateModel.referer(savedModel.referer);
    };
    modify_display_false = function() {
        self.modify(false);
        savedModel = ko.toJS(candidateModel);
    };
    save_button = function() {
        self.ajaxCall();
    };

    self.cssclass = ko.computed(function() {
        if (self.modify == true) {
            return "display";
        } else {
            return "";
        }
    });
}

var candidateModel = new CandidateCreateModel();

$('#candidate-create-form').validator().on('submit', function (e) {
  if (e.isDefaultPrevented()) {
    // handle the invalid form...
  } else {
    candidateModel.ajaxCall();
    return false;
  }
});

ko.applyBindings(candidateModel);

function creationDateFormatter(value, row, index) {
    var dateTime = new Date(row.creationDate);
    return dateTimeFormatter(dateTime);
}

function modificationDateFormatter(value, row, index) {
    var dateTime = new Date(row.modificationDate);
    return dateTimeFormatter(dateTime);
}

function dateTimeFormatter(dateTime) {
    var year = dateTime.getFullYear();
    var month = dateTime.getMonth() + 1;
    month = month.toString().length == 2 ? month : ('0' + month);

    var day = dateTime.getDate();
    day = day.toString().length == 2 ? day : ('0' + day);

    var hour = dateTime.getHours();
    hour = hour.toString().length == 2 ? hour : ('0' + hour);

    var minute = dateTime.getMinutes();
    minute = minute.toString().length == 2 ? minute : ('0' + minute);

    var second = dateTime.getSeconds();
    second = second.toString().length == 2 ? second : ('0' + second);

    return year + '-' + month + '-' + day + " " + hour + ":" + minute + ':' + second;
}
<|endoftext|>


<commit_before>import qs from "query-string";
import {autorun, observable, computed, action, extendObservable} from "mobx";

import {CUTOFF_DIST, SEARCH_OFFSET} from "./consts";
import {VIS, createVisCalc} from "./visibility";

import {
    calcDist,
    calcRxPower,
    createPathLossCalc,
    milliWattToDbm,
} from "./util";

const calcPathLoss = createPathLossCalc(3.0);

export function State(hist) {
    let map = new MapState();

    extendObservable(this, {
        map,

        rawLocs: observable.ref([]),
        jitterLocs: observable.ref([]),
        distLocs: observable.ref([]),
        freqLocs: observable.ref([]),
        locs: observable.ref([]),

        curLoc: null,

        previewLoc: null,
        exitPreviewTimer: null,

        filters: {
            freqLower: 0,
            freqUpper: 5000.0e6,
            rxPowerLower: -121.0,
            vis: VIS.DEFAULT,
        },
        editFilters: {},
        locCat: observable.map(),

        curTab: "info",
        docTitle: "",

        curError: null,

        search: new SearchFormState(),

        setError: action(err => {
            this.curError = err;
        }),

        setLocs: action(locs => {
            this.rawLocs = locs;
        }),

        selectLoc: action(lkey => {
            let idx = this.locs.findIndex(loc => loc.lkey === lkey);

            if (idx < 0) {
                throw new Error("location not visible");
            }

            this.curLoc = this.locs[idx];
        }),

        setTab: action(tab => {
            this.curTab = tab;
        }),

        setFilters: action(args => {
            let freqLower = parseFloat(args.freqLower);
            let freqUpper = parseFloat(args.freqUpper);
            let rxPowerLower = parseFloat(args.rxPowerLower);
            let vis = parseInt(args.vis, 10);

            Object.assign(this.filters, {
                freqLower: isNaN(freqLower) ? this.filters.freqLower : freqLower,
                freqUpper: isNaN(freqUpper) ? this.filters.freqUpper : freqUpper,
                rxPowerLower: isNaN(rxPowerLower) ? this.filters.rxPowerLower : rxPowerLower,
                vis: isNaN(vis) ? this.filters.vis : vis,
            });

            this.editFilters = Object.assign({}, this.filters);
        }),

        changeFilter: action((filter, value) => {
            if (isNaN(value)) {
                return;
            }

            this.editFilters[filter] = value;
        }),

        toggleFilterVis: action(visFlag => {
            this.editFilters.vis ^= visFlag;
        }),

        setCurCenter: action(() => {
            this.map.saveCenter();
            this.map.setCenter(this.curLoc);
        }),

        setPreviewLoc: action(loc => {
            this.previewLoc = loc;
        }),

        resetPreviewLoc: action(() => {
            this.setPreviewLoc(null);
        }),

        setDocTitle: action(title => {
            this.docTitle = title;
        }),

        toggleCat: action((lkey, cat) => {
            this.locCat.set(lkey, (this.locCat.get(lkey) & cat) ^ cat);
        }),

        loadState: action(state => {
            if (!state) {
                return;
            }

            this.locCat.merge(state.locCat || {});

            if (state.basePos) {
                this.map.basePos = state.basePos;
            }
        }),

        commitFilters: action(() => {
            hist.push(Object.assign({}, hist.location, {
                search: `?${qs.stringify(this.editFilters)}`
            }));
        }),

        searchLocs: computed(() => {
            if (isNaN(this.search.committedFreq)) {
                return [];
            }

            let center = this.search.committedFreq * 1.0e6;
            let lower = center - SEARCH_OFFSET;
            let upper = center + SEARCH_OFFSET;

            return this.locs.map(loc => Object.assign({}, loc, {
                freqs: loc.freqs.filter(f => f.freq >= lower && f.freq <= upper)
            })).filter(loc => loc.freqs.length > 0);
        }),

        enterPreview: action(loc => {
            // Only save center when initially entering preview.
            if (this.exitPreviewTimer === null) {
                this.map.saveCenter();
            }

            clearTimeout(this.exitPreviewTimer);
            this.exitPreviewTimer = null;

            this.map.setCenter(loc);
            this.setPreviewLoc(loc);
        }),

        exitPreview: action(delay => {
            this.exitPreviewTimer = setTimeout(() => {
                this.map.restoreCenter();
                this.resetPreviewLoc();
            }, delay);
        }),
    });

    autorun(() => {
        this.jitterLocs = this.rawLocs.map(loc => Object.assign(loc, {
            jitterLat: (Math.random() - 0.5) * 10.0e-3,
            jitterLng: (Math.random() - 0.5) * 10.0e-3,
        }));
    });

    autorun(() => {
        this.distLocs = this.jitterLocs.map(loc => Object.assign(loc, {
            dist: calcDist(map.basePos, loc),
        })).filter(loc => loc.dist < CUTOFF_DIST);
    });

    autorun(() => {
        let {freqLower, freqUpper, rxPowerLower} = this.filters;

        this.freqLocs = this.distLocs.map(loc => Object.assign({}, loc, {
            freqs: loc.freqs.filter(f => (
                f.freq > freqLower && f.freq < freqUpper
            )).map(f => Object.assign(f, {
                rxPower: calcRxPower(milliWattToDbm(f.power),
                                     calcPathLoss(f.freq, loc.dist)),
            })).filter(f => (
                f.rxPower > rxPowerLower
            )).sort((a, b) => (
                b.rxPower - a.rxPower
            )),
        })).filter(loc => loc.freqs.length > 0);
    });

    autorun(() => {
        let {vis} = this.filters;
        let calcVis = createVisCalc(this.locCat);

        this.locs = this.freqLocs.map(loc => Object.assign(loc, {
            vis: calcVis(loc.lkey),
        })).filter(loc => (
            (loc.vis & vis) !== 0
        )).sort((a, b) => (
            b.freqs[0].rxPower - a.freqs[0].rxPower
        ));
    });
}

function SearchFormState() {
    extendObservable(this, {
        changeFreq: action(search => {
            this.editFreq = search;
        }),
        commitFreq: action(() => {
            this.committedFreq = this.parsedFreq;
        }),
        editFreq: "150.0",
        parsedFreq: computed(() => {
            return Number(this.editFreq);
        }),
        freqInvalid: computed(() => {
            return Number.isNaN(this.parsedFreq);
        }),
        committedFreq: NaN,
    });
}

function MapState() {
    extendObservable(this, {
        google: null,
        map: null,
        basePos: observable.ref(null),
        projection: null,
        baseMarker: null,
        savedCenter: null,

        init: action((google, map) => {
            if (this.google !== null) {
                throw new Error("map already initialized");
            }

            let baseMarker = new google.maps.Marker({
                map,
                position: this.basePos,
                draggable: true,
            });

            baseMarker.addListener("dragend", () => {
                let pos = this.baseMarker.getPosition();

                this.setBasePos({
                    lat: pos.lat(),
                    lng: pos.lng(),
                });
            });

            Object.assign(this, {google, map, baseMarker});
        }),

        setBasePos: action(basePos => {
            this.basePos = basePos;
        }),

        setProjection: action(projection => {
            this.projection = Object.create(projection);
        }),

        setCenter: action(loc => {
            if (this.map) {
                this.map.setCenter(loc);
            }
        }),

        saveCenter: action(() => {
            this.savedCenter = this.map.getCenter();
        }),

        restoreCenter: action(() => {
            this.map.setCenter(this.savedCenter);
        }),
    });
}
<commit_msg>Add a prefix to doc title<commit_after>import qs from "query-string";
import {autorun, observable, computed, action, extendObservable} from "mobx";

import {CUTOFF_DIST, SEARCH_OFFSET} from "./consts";
import {VIS, createVisCalc} from "./visibility";

import {
    calcDist,
    calcRxPower,
    createPathLossCalc,
    milliWattToDbm,
} from "./util";

const calcPathLoss = createPathLossCalc(3.0);

export function State(hist) {
    let map = new MapState();

    extendObservable(this, {
        map,

        rawLocs: observable.ref([]),
        jitterLocs: observable.ref([]),
        distLocs: observable.ref([]),
        freqLocs: observable.ref([]),
        locs: observable.ref([]),

        curLoc: null,

        previewLoc: null,
        exitPreviewTimer: null,

        filters: {
            freqLower: 0,
            freqUpper: 5000.0e6,
            rxPowerLower: -121.0,
            vis: VIS.DEFAULT,
        },
        editFilters: {},
        locCat: observable.map(),

        curTab: "info",
        docTitle: null,

        curError: null,

        search: new SearchFormState(),

        setError: action(err => {
            this.curError = err;
        }),

        setLocs: action(locs => {
            this.rawLocs = locs;
        }),

        selectLoc: action(lkey => {
            let idx = this.locs.findIndex(loc => loc.lkey === lkey);

            if (idx < 0) {
                throw new Error("location not visible");
            }

            this.curLoc = this.locs[idx];
        }),

        setTab: action(tab => {
            this.curTab = tab;
        }),

        setFilters: action(args => {
            let freqLower = parseFloat(args.freqLower);
            let freqUpper = parseFloat(args.freqUpper);
            let rxPowerLower = parseFloat(args.rxPowerLower);
            let vis = parseInt(args.vis, 10);

            Object.assign(this.filters, {
                freqLower: isNaN(freqLower) ? this.filters.freqLower : freqLower,
                freqUpper: isNaN(freqUpper) ? this.filters.freqUpper : freqUpper,
                rxPowerLower: isNaN(rxPowerLower) ? this.filters.rxPowerLower : rxPowerLower,
                vis: isNaN(vis) ? this.filters.vis : vis,
            });

            this.editFilters = Object.assign({}, this.filters);
        }),

        changeFilter: action((filter, value) => {
            if (isNaN(value)) {
                return;
            }

            this.editFilters[filter] = value;
        }),

        toggleFilterVis: action(visFlag => {
            this.editFilters.vis ^= visFlag;
        }),

        setCurCenter: action(() => {
            this.map.saveCenter();
            this.map.setCenter(this.curLoc);
        }),

        setPreviewLoc: action(loc => {
            this.previewLoc = loc;
        }),

        resetPreviewLoc: action(() => {
            this.setPreviewLoc(null);
        }),

        setDocTitle: action(title => {
            this.docTitle = `ULS Map | ${title}`;
        }),

        toggleCat: action((lkey, cat) => {
            this.locCat.set(lkey, (this.locCat.get(lkey) & cat) ^ cat);
        }),

        loadState: action(state => {
            if (!state) {
                return;
            }

            this.locCat.merge(state.locCat || {});

            if (state.basePos) {
                this.map.basePos = state.basePos;
            }
        }),

        commitFilters: action(() => {
            hist.push(Object.assign({}, hist.location, {
                search: `?${qs.stringify(this.editFilters)}`
            }));
        }),

        searchLocs: computed(() => {
            if (isNaN(this.search.committedFreq)) {
                return [];
            }

            let center = this.search.committedFreq * 1.0e6;
            let lower = center - SEARCH_OFFSET;
            let upper = center + SEARCH_OFFSET;

            return this.locs.map(loc => Object.assign({}, loc, {
                freqs: loc.freqs.filter(f => f.freq >= lower && f.freq <= upper)
            })).filter(loc => loc.freqs.length > 0);
        }),

        enterPreview: action(loc => {
            // Only save center when initially entering preview.
            if (this.exitPreviewTimer === null) {
                this.map.saveCenter();
            }

            clearTimeout(this.exitPreviewTimer);
            this.exitPreviewTimer = null;

            this.map.setCenter(loc);
            this.setPreviewLoc(loc);
        }),

        exitPreview: action(delay => {
            this.exitPreviewTimer = setTimeout(() => {
                this.map.restoreCenter();
                this.resetPreviewLoc();
            }, delay);
        }),
    });

    autorun(() => {
        this.jitterLocs = this.rawLocs.map(loc => Object.assign(loc, {
            jitterLat: (Math.random() - 0.5) * 10.0e-3,
            jitterLng: (Math.random() - 0.5) * 10.0e-3,
        }));
    });

    autorun(() => {
        this.distLocs = this.jitterLocs.map(loc => Object.assign(loc, {
            dist: calcDist(map.basePos, loc),
        })).filter(loc => loc.dist < CUTOFF_DIST);
    });

    autorun(() => {
        let {freqLower, freqUpper, rxPowerLower} = this.filters;

        this.freqLocs = this.distLocs.map(loc => Object.assign({}, loc, {
            freqs: loc.freqs.filter(f => (
                f.freq > freqLower && f.freq < freqUpper
            )).map(f => Object.assign(f, {
                rxPower: calcRxPower(milliWattToDbm(f.power),
                                     calcPathLoss(f.freq, loc.dist)),
            })).filter(f => (
                f.rxPower > rxPowerLower
            )).sort((a, b) => (
                b.rxPower - a.rxPower
            )),
        })).filter(loc => loc.freqs.length > 0);
    });

    autorun(() => {
        let {vis} = this.filters;
        let calcVis = createVisCalc(this.locCat);

        this.locs = this.freqLocs.map(loc => Object.assign(loc, {
            vis: calcVis(loc.lkey),
        })).filter(loc => (
            (loc.vis & vis) !== 0
        )).sort((a, b) => (
            b.freqs[0].rxPower - a.freqs[0].rxPower
        ));
    });

    this.setDocTitle("Initializing...");
}

function SearchFormState() {
    extendObservable(this, {
        changeFreq: action(search => {
            this.editFreq = search;
        }),
        commitFreq: action(() => {
            this.committedFreq = this.parsedFreq;
        }),
        editFreq: "150.0",
        parsedFreq: computed(() => {
            return Number(this.editFreq);
        }),
        freqInvalid: computed(() => {
            return Number.isNaN(this.parsedFreq);
        }),
        committedFreq: NaN,
    });
}

function MapState() {
    extendObservable(this, {
        google: null,
        map: null,
        basePos: observable.ref(null),
        projection: null,
        baseMarker: null,
        savedCenter: null,

        init: action((google, map) => {
            if (this.google !== null) {
                throw new Error("map already initialized");
            }

            let baseMarker = new google.maps.Marker({
                map,
                position: this.basePos,
                draggable: true,
            });

            baseMarker.addListener("dragend", () => {
                let pos = this.baseMarker.getPosition();

                this.setBasePos({
                    lat: pos.lat(),
                    lng: pos.lng(),
                });
            });

            Object.assign(this, {google, map, baseMarker});
        }),

        setBasePos: action(basePos => {
            this.basePos = basePos;
        }),

        setProjection: action(projection => {
            this.projection = Object.create(projection);
        }),

        setCenter: action(loc => {
            if (this.map) {
                this.map.setCenter(loc);
            }
        }),

        saveCenter: action(() => {
            this.savedCenter = this.map.getCenter();
        }),

        restoreCenter: action(() => {
            this.map.setCenter(this.savedCenter);
        }),
    });
}
<|endoftext|>


<commit_before>isic.views.ImagesViewSubViews = isic.views.ImagesViewSubViews || {};

// View for image details
isic.views.ImagesViewSubViews.ImageDetailsPane = isic.View.extend({
    events: {
        'click .button': 'clearSelectedImage',
        'click .openwindow': 'openwindow',
        'click .fullscreen': 'fullscreen'
    },

    initialize: function (settings) {
        this.image = settings.image;

        this.listenTo(this.image, 'changed:_id g:fetched g:error', this.render);

        this.segmentationsDisplayView = new isic.views.SegmentationsDisplayView({
            image: this.image,
            parentView: this
        });

    },

    render: function () {
        var created = null;
        var license = {
            name: null,
            url: null
        };
        var acquisitionMetadata = null;
        var clinicalMetadata = null;

        // Get image data
        if (this.image.id) {
            created = girder.formatDate(this.image.get('created'), girder.DATE_SECOND);

            // Get license, default to CC-0
            if (this.image.has('license')) {
                license.name = this.image.get('license');
            } else {
                license.name = 'CC-0';
                license.url = 'https://creativecommons.org/publicdomain/zero/1.0/';
            }

            var meta = this.image.get('meta');
            acquisitionMetadata = meta['acquisition'];
            clinicalMetadata = meta['clinical'];

            // Reformat some acquisition metadata
            acquisitionMetadata['Dimensions (pixels)'] =
                acquisitionMetadata['pixelsX'] + ' × ' + acquisitionMetadata['pixelsY'];
            delete acquisitionMetadata['pixelsX'];
            delete acquisitionMetadata['pixelsY'];
        }

        this.$el.html(isic.templates.imageDetailsPage({
            imgRoot: girder.staticRoot + '/built/plugins/isic_archive/extra/img',
            image: this.image,
            created: created,
            license: license,
            acquisitionMetadata: acquisitionMetadata,
            clinicalMetadata: clinicalMetadata
        }));

        this.segmentationsDisplayView.setElement(
            this.$('#isic-image-details-segmentations-display-view-container')).render();

        this.initializeTooltips();

        return this;
    },

    openwindow: function () {
      this.clearTooltips();
      window.open('/api/v1/image/' + this.image.id + '/download?contentDisposition=inline');
    },

    fullscreen: function () {
      this.clearTooltips();

      var img = $('.focusimage');
      var modal = $('#focusmodal');

      // Supply the image element with a new src attribute to display the image.
      var src = '/api/v1/image/' + this.image.id + '/download?contentDisposition=inline';
      img.attr('src', src);

      // Create a dummy image element so we can learn the size of the new image.
      // When the image is loaded, we can use its size to properly resize and
      // situate the modal.
      var image = new Image();
      image.onload = function () {
        // Add thirty to represent the 15px padding that comes stock with a
        // Bootstrap modal.
        var modalWidth = image.width + 30;
        var modalHeight = image.height + 30;

        // Set the CSS of the dialog so it appears vertically and horizontally
        // centered in the webpage (even with browser resizing).
        modal.find('.modal-dialog').css({
          width: modalWidth + 'px',
          position: 'absolute',
          top: '50%',
          left: '50%',
          'margin-top': (-modalHeight / 2) + 'px',
          'margin-left': (-modalWidth / 2) + 'px'
        });

        // Now that the image and CSS are ready, show the modal.
        modal.modal('show');
      };

      // Allow clicking on the image itself to dismiss the modal.
      img.on('click.dismiss', function () {
        $('#focusmodal').modal('hide');
      });

      image.src = src;
    },

    clearSelectedImage: function () {
        this.image.clear();
    },

    initializeTooltips: function () {
        this.$('[data-toggle="tooltip"]').tooltip({
            trigger: 'hover'
        });
    },

    clearTooltips: function () {
      $('[data-toggle="tooltip"]').tooltip('hide');
    }
});
<commit_msg>Fix style in ImageDetailsPane<commit_after>isic.views.ImagesViewSubViews = isic.views.ImagesViewSubViews || {};

// View for image details
isic.views.ImagesViewSubViews.ImageDetailsPane = isic.View.extend({
    events: {
        'click .button': 'clearSelectedImage',
        'click .openwindow': 'openwindow',
        'click .fullscreen': 'fullscreen'
    },

    initialize: function (settings) {
        this.image = settings.image;

        this.listenTo(this.image, 'changed:_id g:fetched g:error', this.render);

        this.segmentationsDisplayView = new isic.views.SegmentationsDisplayView({
            image: this.image,
            parentView: this
        });
    },

    render: function () {
        var created = null;
        var license = {
            name: null,
            url: null
        };
        var acquisitionMetadata = null;
        var clinicalMetadata = null;

        // Get image data
        if (this.image.id) {
            created = girder.formatDate(this.image.get('created'), girder.DATE_SECOND);

            // Get license, default to CC-0
            if (this.image.has('license')) {
                license.name = this.image.get('license');
            } else {
                license.name = 'CC-0';
                license.url = 'https://creativecommons.org/publicdomain/zero/1.0/';
            }

            var meta = this.image.get('meta');
            acquisitionMetadata = meta['acquisition'];
            clinicalMetadata = meta['clinical'];

            // Reformat some acquisition metadata
            acquisitionMetadata['Dimensions (pixels)'] =
                acquisitionMetadata['pixelsX'] + ' × ' + acquisitionMetadata['pixelsY'];
            delete acquisitionMetadata['pixelsX'];
            delete acquisitionMetadata['pixelsY'];
        }

        this.$el.html(isic.templates.imageDetailsPage({
            imgRoot: girder.staticRoot + '/built/plugins/isic_archive/extra/img',
            image: this.image,
            created: created,
            license: license,
            acquisitionMetadata: acquisitionMetadata,
            clinicalMetadata: clinicalMetadata
        }));

        this.segmentationsDisplayView.setElement(
            this.$('#isic-image-details-segmentations-display-view-container')).render();

        this.initializeTooltips();

        return this;
    },

    openwindow: function () {
        this.clearTooltips();
        window.open('/api/v1/image/' + this.image.id + '/download?contentDisposition=inline');
    },

    fullscreen: function () {
        this.clearTooltips();

        var img = $('.focusimage');
        var modal = $('#focusmodal');

        // Supply the image element with a new src attribute to display the image.
        var src = '/api/v1/image/' + this.image.id + '/download?contentDisposition=inline';
        img.attr('src', src);

        // Create a dummy image element so we can learn the size of the new image.
        // When the image is loaded, we can use its size to properly resize and
        // situate the modal.
        var image = new Image();
        image.onload = function () {
            // Add thirty to represent the 15px padding that comes stock with a
            // Bootstrap modal.
            var modalWidth = image.width + 30;
            var modalHeight = image.height + 30;

            // Set the CSS of the dialog so it appears vertically and horizontally
            // centered in the webpage (even with browser resizing).
            modal.find('.modal-dialog').css({
                width: modalWidth + 'px',
                position: 'absolute',
                top: '50%',
                left: '50%',
                'margin-top': (-modalHeight / 2) + 'px',
                'margin-left': (-modalWidth / 2) + 'px'
            });

            // Now that the image and CSS are ready, show the modal.
            modal.modal('show');
        };

        // Allow clicking on the image itself to dismiss the modal.
        img.on('click.dismiss', function () {
            $('#focusmodal').modal('hide');
        });

        image.src = src;
    },

    clearSelectedImage: function () {
        this.image.clear();
    },

    initializeTooltips: function () {
        this.$('[data-toggle="tooltip"]').tooltip({
            trigger: 'hover'
        });
    },

    clearTooltips: function () {
        $('[data-toggle="tooltip"]').tooltip('hide');
    }
});
<|endoftext|>


<commit_before>let origUser = null;
const Message = require("./Message")
class User {
    constructor(user) {
        origUser = user;
        this.avatar = user.avatar;
        this.avatarURL = user.avatarURL;
        this.bot = user.bot;
        this.createdAt = user.createdAt;
        this.defaultAvatar = user.defaultAvatar;
        this.defaultAvatarURL = user.defaultAvatarURL;
        this.discriminator = user.discriminator;
        this.id = user.id;
        this.mention = user.mention;
        this.staticAvatarURL = user.staticAvatarURL;
        this.username = user.username;
    }

    dynamicAvatarURL(format, size) {
        return origUser.dynamicAvatarURL(format, size);
    }

    createMessage(content, file) {
        if (this.bot) return Promise.reject({
            code: 50017,
            message: "Cannot send messages to this user"
        });
        return origUser.getDMChannel().then(dm => dm.createMessage(content, file)).then(m => new Message(m))
    }
}
module.exports = User;<commit_msg>Avoid leaking full request data<commit_after>let origUser = null;
const Message = require("./Message");
class User {
    constructor(user) {
        origUser = user;
        this.avatar = user.avatar;
        this.avatarURL = user.avatarURL;
        this.bot = user.bot;
        this.createdAt = user.createdAt;
        this.defaultAvatar = user.defaultAvatar;
        this.defaultAvatarURL = user.defaultAvatarURL;
        this.discriminator = user.discriminator;
        this.id = user.id;
        this.mention = user.mention;
        this.staticAvatarURL = user.staticAvatarURL;
        this.username = user.username;
    }

    dynamicAvatarURL(format, size) {
        return origUser.dynamicAvatarURL(format, size);
    }

    createMessage(content, file) {
        if (this.bot) return Promise.reject({
            code: 50017,
            message: "Cannot send messages to this user"
        });
        return origUser.getDMChannel().then(dm => dm.createMessage(content, file)).then(m => new Message(m)).catch(e => "Error sending the message");
    }
}
module.exports = User;<|endoftext|>


<commit_before>dojo.provide("dojox.widget.Roller");
dojo.require("dijit._Widget");

dojo.declare("dojox.widget.Roller", dijit._Widget, {
	// summary: A simple widget to take an unordered-list of Text and roll through them
	//
	// description:
	//		The Roller widget takes an unordered-list of items, and converts
	//		them to a single-area (the size of one list-item, however you so choose
	//		to style it) and loops continually, fading between items.
	//
	//		In it's current state, it requires it be created from an unordered (or ordered)
	//		list, though can contain complex markup.
	//
	//		You can manipulate the `items` array at any point during the cycle with
	//		standard array manipulation techniques.
	//
	//		The class "dojoxRoller" is added to the UL element for styling purposes.
	//
	//	example:
	//	|	// create a scroller from a unordered list with id="lister"
	//  |	var thinger = new dojox.widget.Roller.Roller({},"lister");
	//
	//	example:
	//	|	// create a scroller from a fixed array, and place in the DOM:
	//	|	new dojox.widget.Roller({ items:["one","two","three"] }).placeAt(dojo.body());
	//
	//	example:
	//	|	// add an item:
	//	|	dijit.byId("roller").items.push("I am a new Label");
	//
	//  example:
	//	|	// stop a roller from rolling:
	//	|	dijit.byId("roller").stop();
	//
	// delay: Integer
	//		Interval between rolls
	delay: 2000,

	// autoStart: Boolean
	//		Toggle to control starup behavior. Call .start() manually
	//		if set to `false`
	autoStart: true,

	// itemSelector: String
	//		A CSS selector to be used by `dojo.query` to find the children
	//		items in this widget. Defaults to "> li", finding only first-children
	//		list-items in the list, allowing for embedded lists to occur.
	itemSelector: "> li",

/*=====
	// items: Array
	//		If populated prior to instantiation, is used as the Items over the children
	items: []
=====*/

	postCreate: function(){

		// add some instance vars:
		if(!this["items"]){
			this.items = [];
		}
		this._idx = -1;

		dojo.addClass(this.domNode,"dojoxRoller");

		// find all the items in this list, and popuplate
		dojo.query(this.itemSelector, this.domNode).forEach(function(item, i){
			this.items.push(item.innerHTML);
			// reuse the first match, destroy the rest
			if(i == 0){
				this._roller = item;
				this._idx = 0;
			}else{ dojo._destroyElement(item); }
		}, this);

		// handle the case where items[] were passed, and no srcNodeRef exists
		if(!this._roller){
			this._roller = this.domNode.appendChild(dojo.doc.createElement('li'));
		}
		// stub out animation creation (for overloading maybe later)
		this.makeAnims();

		// and start, if true:
		if(this.autoStart){ this.start(); }

	},

	makeAnims: function(){
		// summary: Animation creator function. Need to create an 'in' and 'out'
		// 		_Animation stored in _anim Object, which the rest of the widget
		//		will reuse.
		var n = this.domNode;
		dojo.mixin(this, {
			_anim: {
				"in": dojo.fadeIn({ node:n, duration: 400 }),
				"out": dojo.fadeOut({ node:n, duration: 275 })
			}
		});
		this._setupConnects();

	},

	_setupConnects: function(){
		// summary: setup the loop connection logic
		var anim = this._anim;

		this.connect(anim["out"], "onEnd", function(){
			// onEnd of the `out` animation, select the next items and play `in` animation
			this._set(this._idx + 1);
			anim["in"].play(15);
		});

		this.connect(anim["in"], "onEnd", function(){
			// onEnd of the `in` animation, call `start` again after some delay:
			this._timeout = setTimeout(dojo.hitch(this, "_run"), this.delay);
		});
	},

	start: function(){
		// summary: Starts to Roller looping
		if(!this.rolling){
			this.rolling = true;
			this._run();
		}
	},

	_run: function(){
		this._anim["out"].gotoPercent(0, true);
	},

	stop: function(){
		// summary: Stops the Roller from looping anymore.
		this.rolling = false;

		var m = this._anim,
			t = this._timeout;

		if(t){ clearTimeout(t); }
		m["in"].stop();
		m["out"].stop();
	},

	_set: function(i){
		// summary: Set the Roller to some passed index. If beyond range, go to first.
		var l = this.items.length - 1;
		if(i < 0){ i = l; }
		if(i > l){ i = 0; }
		this._roller.innerHTML = this.items[i] || "error!";
		this._idx = i;
	}

});

dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
	// summary: An add-on to the Roller to modify animations. This produces
	//		a slide-from-bottom like effect. See `dojox.widget.Roller` for
	//		full API information.

	makeAnims: function(){
		// summary: Animation creator function. Need to create an 'in' and 'out'
		// 		_Animation stored in _anim Object, which the rest of the widget
		//		will reuse.
		var n = this.domNode;

		var pos = "position";
		dojo.style(n, pos, "relative");
		dojo.style(this._roller, pos, "absolute");

		var props = {
			top: { end: 0, start: 25 },
			opacity: 1
		};

		dojo.mixin(this, {
			_anim: {

				"in": dojo.animateProperty({
					node: n,
					duration: 400,
					properties: props
				}),

				"out": dojo.fadeOut({ node: n, duration: 175 })
			}
		});
		// don't forget to do this in the class. override if necessary.
		this._setupConnects();
	}

});

dojo.declare("dojox.widget._RollerHover", null, {
	// summary: A mixin class to provide a way to automate the "stop on hover" functionality.
	//
	// description:
	//		A mixin class used to provide a way to automate a "stop on hover" behavior,
	//		while still allowing for ambigious subclassing for custom animations.
	//		Simply mix this class into a `dojox.widget.Roller` variant, and instantiate
	//		as you would. The hover connection is done automatically.
	//
	//		The "hover" functionality is as such: Stop rotation while the mouse is over the
	//		instance, and resume again once leaving. Even if autoStart is disabled, the widget
	//		will start if a mouse enters and leaves the node in this case.
	//
	// example:
	// | dojo.declare("my.Roller", [dojox.widget.RollerSlide, dojox.widget._RollerHover], {});
	// | new my.Roller({}, "myList");

	postCreate: function(){
		this.inherited(arguments);
		this.connect(this.domNode, "onmouseenter", "stop");
		this.connect(this.domNode, "onmouseleave", "start");
	}

});
<commit_msg>provide durationIn and durationOut values for roller and friends. helps refining the animations. consider easing? (is this a patter we want to get into? eg: a show/hide propery pair for animations)<commit_after>dojo.provide("dojox.widget.Roller");
dojo.require("dijit._Widget");

dojo.declare("dojox.widget.Roller", dijit._Widget, {
	// summary: A simple widget to take an unordered-list of Text and roll through them
	//
	// description:
	//		The Roller widget takes an unordered-list of items, and converts
	//		them to a single-area (the size of one list-item, however you so choose
	//		to style it) and loops continually, fading between items.
	//
	//		In it's current state, it requires it be created from an unordered (or ordered)
	//		list, though can contain complex markup.
	//
	//		You can manipulate the `items` array at any point during the cycle with
	//		standard array manipulation techniques.
	//
	//		The class "dojoxRoller" is added to the UL element for styling purposes.
	//
	//	example:
	//	|	// create a scroller from a unordered list with id="lister"
	//  |	var thinger = new dojox.widget.Roller.Roller({},"lister");
	//
	//	example:
	//	|	// create a scroller from a fixed array, and place in the DOM:
	//	|	new dojox.widget.Roller({ items:["one","two","three"] }).placeAt(dojo.body());
	//
	//	example:
	//	|	// add an item:
	//	|	dijit.byId("roller").items.push("I am a new Label");
	//
	//  example:
	//	|	// stop a roller from rolling:
	//	|	dijit.byId("roller").stop();
	//
	// delay: Integer
	//		Interval between rolls
	delay: 2000,

	// autoStart: Boolean
	//		Toggle to control starup behavior. Call .start() manually
	//		if set to `false`
	autoStart: true,

	// itemSelector: String
	//		A CSS selector to be used by `dojo.query` to find the children
	//		items in this widget. Defaults to "> li", finding only first-children
	//		list-items in the list, allowing for embedded lists to occur.
	itemSelector: "> li",

	// durationIn: Integer
	// 		Speed (in ms) to apply to the "in" animation (show the node)
	durationIn: 400,

	// durationOut: Integer
	//		Speed (in ms) to apply to the "out" animation (hide the showing node)
	durationOut: 275,
/*=====
	// items: Array
	//		If populated prior to instantiation, is used as the Items over the children
	items: []
=====*/

	// _idx: Integer
	//		Index of the the currently visible item in the list of items[]
	_idx: -1,

	postCreate: function(){

		// add some instance vars:
		if(!this["items"]){
			this.items = [];
		}

		dojo.addClass(this.domNode,"dojoxRoller");

		// find all the items in this list, and popuplate
		dojo.query(this.itemSelector, this.domNode).forEach(function(item, i){
			this.items.push(item.innerHTML);
			// reuse the first match, destroy the rest
			if(i == 0){
				this._roller = item;
				this._idx = 0;
			}else{ dojo.destroyElement(item); }
		}, this);

		// handle the case where items[] were passed, and no srcNodeRef exists
		if(!this._roller){
		//	this._roller = dojo.element('li', null, this.domNode);
			this._roller = this.domNode.appendChild(dojo.doc.createElement('li'));
		}
		// stub out animation creation (for overloading maybe later)
		this.makeAnims();

		// and start, if true:
		if(this.autoStart){ this.start(); }

	},

	makeAnims: function(){
		// summary: Animation creator function. Need to create an 'in' and 'out'
		// 		_Animation stored in _anim Object, which the rest of the widget
		//		will reuse.
		var n = this.domNode;
		dojo.mixin(this, {
			_anim: {
				"in": dojo.fadeIn({ node:n, duration: this.durationIn }),
				"out": dojo.fadeOut({ node:n, duration: this.durationOut })
			}
		});
		this._setupConnects();

	},

	_setupConnects: function(){
		// summary: setup the loop connection logic
		var anim = this._anim;

		this.connect(anim["out"], "onEnd", function(){
			// onEnd of the `out` animation, select the next items and play `in` animation
			this._set(this._idx + 1);
			anim["in"].play(15);
		});

		this.connect(anim["in"], "onEnd", function(){
			// onEnd of the `in` animation, call `start` again after some delay:
			this._timeout = setTimeout(dojo.hitch(this, "_run"), this.delay);
		});
	},

	start: function(){
		// summary: Starts to Roller looping
		if(!this.rolling){
			this.rolling = true;
			this._run();
		}
	},

	_run: function(){
		this._anim["out"].gotoPercent(0, true);
	},

	stop: function(){
		// summary: Stops the Roller from looping anymore.
		this.rolling = false;

		var m = this._anim,
			t = this._timeout;

		if(t){ clearTimeout(t); }
		m["in"].stop();
		m["out"].stop();
	},

	_set: function(i){
		// summary: Set the Roller to some passed index. If beyond range, go to first.
		var l = this.items.length - 1;
		if(i < 0){ i = l; }
		if(i > l){ i = 0; }
		this._roller.innerHTML = this.items[i] || "error!";
		this._idx = i;
	}

});

dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
	// summary: An add-on to the Roller to modify animations. This produces
	//		a slide-from-bottom like effect. See `dojox.widget.Roller` for
	//		full API information.

	durationOut: 175, // slightly faster than default

	makeAnims: function(){
		// summary: Animation creator function. Need to create an 'in' and 'out'
		// 		_Animation stored in _anim Object, which the rest of the widget
		//		will reuse.

		var n = this.domNode, pos = "position",
			props = {
				top: { end: 0, start: 25 },
				opacity: 1
			}
		;

		dojo.style(n, pos, "relative");
		dojo.style(this._roller, pos, "absolute");

		dojo.mixin(this, {
			_anim: {

				"in": dojo.animateProperty({
					node: n,
					duration: this.durationIn,
					properties: props
				}),

				"out": dojo.fadeOut({ node: n, duration: this.durationOut })
			}
		});
		// don't forget to do this in the class. override if necessary.
		this._setupConnects();
	}

});

dojo.declare("dojox.widget._RollerHover", null, {
	// summary: A mixin class to provide a way to automate the "stop on hover" functionality.
	//
	// description:
	//		A mixin class used to provide a way to automate a "stop on hover" behavior,
	//		while still allowing for ambigious subclassing for custom animations.
	//		Simply mix this class into a `dojox.widget.Roller` variant, and instantiate
	//		as you would. The hover connection is done automatically.
	//
	//		The "hover" functionality is as such: Stop rotation while the mouse is over the
	//		instance, and resume again once leaving. Even if autoStart is disabled, the widget
	//		will start if a mouse enters and leaves the node in this case.
	//
	// example:
	// | dojo.declare("my.Roller", [dojox.widget.RollerSlide, dojox.widget._RollerHover], {});
	// | new my.Roller({}, "myList");

	postCreate: function(){
		this.inherited(arguments);
		this.connect(this.domNode, "onmouseenter", "stop");
		this.connect(this.domNode, "onmouseleave", "start");
	}

});
<|endoftext|>


<commit_before>// ==UserScript==
// @name      redirector.uc.js
// @include   main
// @startup   Redirector.init();
// @shutdown  Redirector.destroy();
// ==/UserScript==

(function () {

  Redirector = {

    // [regex, replace, decode]
    rules: [[
      /^https?:\/\/redir\.folha\.com\.br\/redir\/online\/.+?\*(.+)/,
      '$1',
      true
    ], [
      /^https?:\/\/www\.google\.com\/url\?q=(.+?)&.*/,
      '$1',
      true
    ], [
      /^https:\/\/outgoing\.prod\.mozaws\.net\/v1\/\w+\/(.+)/,
      '$1',
      true
    ], [
      /^https?:\/\/click\.uol\.com.br\/.*?(?:\?|&)u=(.*?)(?:&.*|$)/,
      '$1',
      true
    ], [
      /^https?:\/\/(?:(?:m|new)\.)?vk\.com\/away\.php\?to=(.+)/,
      '$1',
      true
    ], [
      /^https?:\/\/l\.instagram\.com\/\?u=(.+?)&.*/,
      '$1',
      true
    ], [
      /^https?:\/\/youtu\.be\/(.+)/,
      'https://www.youtube.com/watch?v=$1'
    ], [
      /^https?:\/\/(userscripts\.org(?:\:8080|)|(?:www.|)webextender.net)\/(.*)/,
      'http://userscripts-mirror.org/$2'
    ], [
      /^http:\/\/ftp\.(mozilla\.org.*)/,
      'http://archive.$1'
    ], [
      //Remove universal parameters
      /(?:(\?)|&)(?:(?:(?:utm_\w+|ref|referer|soc_\w+|cc_key|PHPSESSID|ved|cmpid|lang)=).*?|sid=[0-9A-Fa-f]{32})(?=&|$)/g,
      '$1'
    ], [
      //Remove unnecesary ? and &
      /(?:(\?)(?:&+(?!$|&)))|(?:&(?=&))|(?:(?:\??&+|\?)$)/g,
      '$1'
    ]],

    get frameScript () {
      return 'data:application/javascript;charset=UTF-8,(' + encodeURIComponent(function (rules) {
        var {
          interfaces: Ci,
          results: Cr,
          manager: Cm
        } = Components;

        this.policy = {
          contractID: '@xiao/redirector;1',
          classID: Components.ID('{009e4d80-b13f-11e7-8f1a-0800200c9a66}'),

          init: function () {
            Cm.QueryInterface(Ci.nsIComponentRegistrar).registerFactory(this.classID, 'Redirector', this.contractID, this);
            XPCOMUtils.categoryManager.addCategoryEntry(['content-policy'], this.contractID, this.contractID, false, true);
          },

          destroy: function () {
            Cm.QueryInterface(Ci.nsIComponentRegistrar).unregisterFactory(this.classID, this);
            XPCOMUtils.categoryManager.deleteCategoryEntry(['content-policy'], this.contractID, false);
          },

          shouldLoad: function (contentType, contentLocation, requestOrigin, node) {
            let redirectUrl = this.getRedirectUrl(contentLocation.spec);
            if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT && redirectUrl && node) {
              node.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).loadURI(redirectUrl, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, requestOrigin, null, null);
              return Ci.nsIContentPolicy.REJECT_REQUEST;
            }
            return Ci.nsIContentPolicy.ACCEPT;
          },

          createInstance: function (outer, iid) {
            if (outer)
              throw Cr.NS_ERROR_NO_AGGREGATION;
            return this.QueryInterface(iid);
          },

          QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy]),

          rules: rules,

          getRedirectUrl: function (originUrl) {
            var redirectUrl = false;
            this.rules.forEach( function (rule) {
              if (rule[0].test(originUrl)) {
                if (!redirectUrl)
                  redirectUrl = true;
                originUrl = typeof rule[1] == 'function'
                  ? rule[2]
                    ? decodeURIComponent(rule[1](originUrl.match(rule[0])))
                    : rule[1](originUrl.match(rule[0]))
                  : rule[2]
                    ? decodeURIComponent(originUrl.replace(rule[0], rule[1]))
                    : originUrl.replace(rule[0], rule[1]);
              }
            });
            return redirectUrl ? originUrl : false;
          }
        };

        policy.init();
      }.toString() + ')(' + this.rules.toSource() + ')');
    },

    init: function () {
      Services.ppmm.loadProcessScript(this.frameScript, true);
    },

    destroy: function () {
      Services.ppmm.loadProcessScript('data:application/javascript;charset=UTF-8,' + encodeURIComponent('('+(function () {
        this.policy.destroy();
        delete this.policy;
      }).toString() + ')();'), false);
      Services.ppmm.removeDelayedProcessScript(this.frameScript);
      delete Redirector;
    }
  }

  Redirector.init();
})()
<commit_msg>implement nsIChannelEventSink to handle HTTP 3xx redirection<commit_after>// ==UserScript==
// @name      redirector.uc.js
// @include   main
// @startup   Redirector.init();
// @shutdown  Redirector.destroy();
// ==/UserScript==

(function () {

  Redirector = {

    // [regex, replace, decode]
    rules: [[
      /^https?:\/\/redir\.folha\.com\.br\/redir\/online\/.+?\*(.+)/,
      '$1',
      true
    ], [
      /^https?:\/\/www\.google\.com\/url\?q=(.+?)&.*/,
      '$1',
      true
    ], [
      /^https:\/\/outgoing\.prod\.mozaws\.net\/v1\/\w+\/(.+)/,
      '$1',
      true
    ], [
      /^https?:\/\/click\.uol\.com.br\/.*?(?:\?|&)u=(.*?)(?:&.*|$)/,
      '$1',
      true
    ], [
      /^https?:\/\/(?:(?:m|new)\.)?vk\.com\/away\.php\?to=(.+)/,
      '$1',
      true
    ], [
      /^https?:\/\/l\.instagram\.com\/\?u=(.+?)&.*/,
      '$1',
      true
    ], [
      /^https?:\/\/youtu\.be\/(.+)/,
      'https://www.youtube.com/watch?v=$1'
    ], [
      /^https?:\/\/(userscripts\.org(?:\:8080|)|(?:www.|)webextender.net)\/(.*)/,
      'http://userscripts-mirror.org/$2'
    ], [
      /^http:\/\/ftp\.(mozilla\.org.*)/,
      'http://archive.$1'
    ], [
      //Remove universal parameters
      /(?:(\?)|&)(?:(?:(?:utm_\w+|ref|referer|soc_\w+|cc_key|PHPSESSID|ved|cmpid|lang)=).*?|sid=[0-9A-Fa-f]{32})(?=&|$)/g,
      '$1'
    ], [
      //Remove unnecesary ? and &
      /(?:(\?)(?:&+(?!$|&)))|(?:&(?=&))|(?:(?:\??&+|\?)$)/g,
      '$1'
    ]],

    get processScript () {
      return 'data:application/javascript;charset=UTF-8,(' + encodeURIComponent(function (rules) {
        var {
          interfaces: Ci,
          results: Cr,
          manager: Cm
        } = Components;

        this.policy = {
          contractID: '@xiao/redirector;1',
          classID: Components.ID('{009e4d80-b13f-11e7-8f1a-0800200c9a66}'),
          xpcom_categories: ['content-policy', 'net-channel-event-sinks'],

          init: function () {
            Cm.QueryInterface(Ci.nsIComponentRegistrar).registerFactory(this.classID, 'Redirector', this.contractID, this);
            for (let category of this.xpcom_categories)
              XPCOMUtils.categoryManager.addCategoryEntry(category, this.contractID, this.contractID, false, true);
          },

          destroy: function () {
            Cm.QueryInterface(Ci.nsIComponentRegistrar).unregisterFactory(this.classID, this);
            for (let category of this.xpcom_categories)
              XPCOMUtils.categoryManager.deleteCategoryEntry(category, this.contractID, false);
          },

          // nsIContentPolicy interface implementation
          shouldLoad: function (contentType, contentLocation, requestOrigin, node) {
            let redirectUrl = this.getRedirectUrl(contentLocation.spec);
            if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT && redirectUrl && node) {
              node.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).loadURI(redirectUrl, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, requestOrigin, null, null);
              return Ci.nsIContentPolicy.REJECT_REQUEST;
            }
            return Ci.nsIContentPolicy.ACCEPT;
          },

          // nsIChannelEventSink interface implementation
          asyncOnChannelRedirect: function (oldChannel, newChannel, flags, redirectCallback) {
            this.onChannelRedirect(oldChannel, newChannel, flags);
            redirectCallback.onRedirectVerifyCallback(Cr.NS_OK);
          },

          onChannelRedirect: function (oldChannel, newChannel, flags) {
              if (!(newChannel.loadFlags & Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI))
                return;
              let newLocation = newChannel.URI.spec;
              if (!newLocation)
                return;
              let callbacks = [];
              if (newChannel.notificationCallbacks)
                callbacks.push(newChannel.notificationCallbacks);
              if (newChannel.loadGroup && newChannel.loadGroup.notificationCallbacks)
                callbacks.push(newChannel.loadGroup.notificationCallbacks);
              let webNav;
              for (let callback of callbacks) {
                try {
                  webNav = callback.getInterface(Ci.nsILoadContext).associatedWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation);
                  break;
                } catch(e) {}
              }
              if (!webNav)
                return;
              let redirectUrl = this.getRedirectUrl(newLocation);
              if (redirectUrl)
                webNav.loadURI(redirectUrl, null, null, null, null);
          },

          createInstance: function (outer, iid) {
            if (outer)
              throw Cr.NS_ERROR_NO_AGGREGATION;
            return this.QueryInterface(iid);
          },

          QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIChannelEventSink]),

          rules: rules,

          getRedirectUrl: function (originUrl) {
            var redirectUrl = false;
            this.rules.forEach( function (rule) {
              if (rule[0].test(originUrl)) {
                if (!redirectUrl)
                  redirectUrl = true;
                originUrl = typeof rule[1] == 'function'
                  ? rule[2]
                    ? decodeURIComponent(rule[1](originUrl.match(rule[0])))
                    : rule[1](originUrl.match(rule[0]))
                  : rule[2]
                    ? decodeURIComponent(originUrl.replace(rule[0], rule[1]))
                    : originUrl.replace(rule[0], rule[1]);
              }
            });
            return redirectUrl ? originUrl : false;
          }
        };

        policy.init();
      }.toString() + ')(' + this.rules.toSource() + ')');
    },

    init: function () {
      Services.ppmm.loadProcessScript(this.processScript, true);
    },

    destroy: function () {
      Services.ppmm.loadProcessScript('data:application/javascript;charset=UTF-8,' + encodeURIComponent('('+(function () {
        this.policy.destroy();
        delete this.policy;
      }).toString() + ')();'), false);
      Services.ppmm.removeDelayedProcessScript(this.processScript);
      delete Redirector;
    }
  }

  Redirector.init();
})()
<|endoftext|>


<commit_before>/*
 * TODO
 *   templates: @<foo> %map:{ my:specimen.container.code=.1.code, my:specimen.container.disp=.1.display %}
 *   node identifiers: @foo> %map:{ foo.id=substr(20) %}
 *   multiplicity: ...
 */
var N3 = require("n3");
var N3Util = N3.Util;
var ShExUtil = require("../lib/ShExUtil");

var MapExt = "http://shex.io/extensions/Map/#";
var pattern = /^ *(?:<([^>]*)>|([^:]*):([^ ]*)) *$/;
function register (validator) {
  var prefixes = validator.schema.prefixes;

  validator.semActHandler.results[MapExt] = {};
  validator.semActHandler.register(
    MapExt,
    {
      /**
       * Callback for extension invocation.
       *
       * @param {string} code - text of the semantic action.
       * @param {object} ctx - matched triple or results subset.
       * @param {object} extensionStorage - place where the extension writes into the result structure.
       * @return {bool} false if the extension failed or did not accept the ctx object.
       */
      dispatch: function (code, ctx, extensionStorage) {
        var m = code.match(pattern);
        if (!m) {
          throw Error("Invocation error: " + MapExt + " code \"" + code + "\" didn't match " + pattern);
        }
        var arg = m[1] ? m[1] : prefixes[m[2]] + m[3];
        validator.semActHandler.results[MapExt][arg] = ctx.object;
        if (!(arg in extensionStorage))
          extensionStorage[arg] = [];
        extensionStorage[arg].push(ctx.object);
        return true;
      }
    }
  );
  return validator.semActHandler.results[MapExt];
}

function done (validator) {
  if (Object.keys(validator.semActHandler.results[MapExt]).length === 0)
    delete validator.semActHandler.results[MapExt];
}

function materializer (schema, nextBNode) {
  var blankNodeCount = 0;
  nextBNode = nextBNode || function () {
    return '_:b' + blankNodeCount++;
  };
  return {
    materialize: function (bindings, createRoot, target) {
      target = target || N3.Store();
      target.addPrefixes(schema.prefixes); // not used, but seems polite

      // utility functions for e.g. s = add(B(), P(":value"), L("70", P("xsd:float")))
      function P (pname) { return N3Util.expandPrefixedName(pname, schema.prefixes); }
      function L (value, modifier) { return N3Util.createLiteral(value, modifier); }
      function B () { return nextBNode(); }
      function add (s, p, o) { target.addTriple({ subject: s, predicate: p, object: o }); return s; }

      var curSubject = createRoot || B();

      var v = ShExUtil.Visitor();

      v.visitReference = function (r) {
        this.visitShape(schema.shapes[r], r);
        return this._visitValue(r);
      };

      v.visitTripleConstraint = function (expr) {
        var mapExts = (expr.semActs || []).filter(function (ext) { return ext.name === MapExt; });
        if (mapExts.length) {
          mapExts.forEach(function (ext) {
            var code = ext.code;
            var m = code.match(pattern);
            if (!m) {
              throw Error("Invocation error: " + MapExt + " code \"" + code + "\" didn't match " + pattern);
            }
            var arg = m[1] ? m[1] : P(m[2] + ":" + m[3]);
            add(curSubject, expr.predicate, bindings[arg]);
          });
        } else if ("values" in expr.valueExpr && expr.valueExpr.values.length === 1) {
          add(curSubject, expr.predicate, expr.valueExpr.values[0]);
        } else {
          var oldSubject = curSubject;
          curSubject = B();
          add(oldSubject, expr.predicate, curSubject);
          this._maybeSet(expr, { type: "TripleConstraint" }, "TripleConstraint",
                         ["inverse", "negated", "predicate", "valueExprRef", "valueExpr",
                          "min", "max", "annotations", "semActs"])
          curSubject = oldSubject;
        }
      };

      v.visitShape(schema.shapes[schema.start], schema.start);
      return target;
    }
  };
}

module.exports = {
  register: register,
  done: done,
  materializer: materializer,
  url: MapExt
};
<commit_msg>+ extractBindings<commit_after>/*
 * TODO
 *   templates: @<foo> %map:{ my:specimen.container.code=.1.code, my:specimen.container.disp=.1.display %}
 *   node identifiers: @foo> %map:{ foo.id=substr(20) %}
 *   multiplicity: ...
 */
var N3 = require("n3");
var N3Util = N3.Util;
var ShExUtil = require("../lib/ShExUtil");

var MapExt = "http://shex.io/extensions/Map/#";
var pattern = /^ *(?:<([^>]*)>|([^:]*):([^ ]*)) *$/;
function register (validator) {
  var prefixes = validator.schema.prefixes;

  validator.semActHandler.results[MapExt] = {};
  validator.semActHandler.register(
    MapExt,
    {
      /**
       * Callback for extension invocation.
       *
       * @param {string} code - text of the semantic action.
       * @param {object} ctx - matched triple or results subset.
       * @param {object} extensionStorage - place where the extension writes into the result structure.
       * @return {bool} false if the extension failed or did not accept the ctx object.
       */
      dispatch: function (code, ctx, extensionStorage) {
        var m = code.match(pattern);
        if (!m) {
          throw Error("Invocation error: " + MapExt + " code \"" + code + "\" didn't match " + pattern);
        }
        var arg = m[1] ? m[1] : prefixes[m[2]] + m[3];
        validator.semActHandler.results[MapExt][arg] = ctx.object;
        if (!(arg in extensionStorage))
          extensionStorage[arg] = [];
        extensionStorage[arg].push(ctx.object);
        return true;
      }
    }
  );
  return validator.semActHandler.results[MapExt];
}

function done (validator) {
  if (Object.keys(validator.semActHandler.results[MapExt]).length === 0)
    delete validator.semActHandler.results[MapExt];
}

function materializer (schema, nextBNode) {
  var blankNodeCount = 0;
  nextBNode = nextBNode || function () {
    return '_:b' + blankNodeCount++;
  };
  return {
    materialize: function (bindings, createRoot, target) {
      target = target || N3.Store();
      target.addPrefixes(schema.prefixes); // not used, but seems polite

      // utility functions for e.g. s = add(B(), P(":value"), L("70", P("xsd:float")))
      function P (pname) { return N3Util.expandPrefixedName(pname, schema.prefixes); }
      function L (value, modifier) { return N3Util.createLiteral(value, modifier); }
      function B () { return nextBNode(); }
      function add (s, p, o) { target.addTriple({ subject: s, predicate: p, object: o }); return s; }

      var curSubject = createRoot || B();

      var v = ShExUtil.Visitor();

      v.visitReference = function (r) {
        this.visitShape(schema.shapes[r], r);
        return this._visitValue(r);
      };

      v.visitTripleConstraint = function (expr) {
        var mapExts = (expr.semActs || []).filter(function (ext) { return ext.name === MapExt; });
        if (mapExts.length) {
          mapExts.forEach(function (ext) {
            var code = ext.code;
            var m = code.match(pattern);
            if (!m) {
              throw Error("Invocation error: " + MapExt + " code \"" + code + "\" didn't match " + pattern);
            }
            var arg = m[1] ? m[1] : P(m[2] + ":" + m[3]);
            add(curSubject, expr.predicate, bindings[arg]);
          });
        } else if ("values" in expr.valueExpr && expr.valueExpr.values.length === 1) {
          add(curSubject, expr.predicate, expr.valueExpr.values[0]);
        } else {
          var oldSubject = curSubject;
          curSubject = B();
          add(oldSubject, expr.predicate, curSubject);
          this._maybeSet(expr, { type: "TripleConstraint" }, "TripleConstraint",
                         ["inverse", "negated", "predicate", "valueExprRef", "valueExpr",
                          "min", "max", "annotations", "semActs"])
          curSubject = oldSubject;
        }
      };

      v.visitShape(schema.shapes[schema.start], schema.start);
      return target;
    }
  };
}

function extractBindings (soln, min, max, depth) {
  if ("min" in soln && soln.min < min)
    min = soln.min
  var myMax = "max" in soln ?
      (soln.max === "*" ?
       Infinity :
       soln.max) :
      1;
  if (myMax > max)
    max = myMax

  function walkExpressions (s) {
    return s.expressions.reduce((inner, e) => {
      return inner.concat(extractBindings(e, min, max, depth+1));
    }, []);
  }

  function walkTriple (s) {
    var fromTriple = "extensions" in s && MapExt in s.extensions ?
        [{ depth: depth, min: min, max: max, obj: s.extensions[MapExt] }] :
        [];
    return "referenced" in s ?
      fromTriple.concat(extractBindings(s.referenced.solution, min, max, depth+1)) :
      fromTriple;
  }

  function structuralError (msg) { throw Error(msg); }

  var walk = // function to explore each solution
      soln.type === "someOfSolutions" ||
      soln.type === "eachOfSolutions" ? walkExpressions :
      soln.type === "tripleConstraintSolutions" ? walkTriple :
      structuralError("unknown type: " + soln.type);

  if (myMax > 1) // preserve important associations:
    // map: e.g. [[1,2],[3,4]]
    // [walk(soln.solutions[0]), walk(soln.solutions[1]),...]
    return soln.solutions.map(walk);
  else // hide unimportant nesting:
    // flatmap: e.g. [1,2,3,4]
    // [].concat(walk(soln.solutions[0])).concat(walk(soln.solutions[1]))...
    return [].concat.apply([], soln.solutions.map(walk));
}

module.exports = {
  register: register,
  extractBindings: extractBindings,
  done: done,
  materializer: materializer,
  url: MapExt
};
<|endoftext|>


<commit_before>// Hardcoded export for the node.js version:
var sigma = this.sigma,
    conrad = this.conrad;

sigma.conrad = conrad;

if (typeof exports !== 'undefined') {
  if (typeof module !== 'undefined' && module.exports)
    exports = module.exports = sigma;
  exports.sigma = sigma;
}
<commit_msg>Temporary dirty tricks to permit usage of sigma in node<commit_after>// Hardcoded export for the node.js version:
var sigma = this.sigma,
    conrad = this.conrad;

sigma.conrad = conrad;

// Dirty polyfills to permit sigma usage in node
if (HTMLElement === undefined)
  var HTMLElement = function() {};

if (window === undefined)
  var window = {
    addEventListener: function() {}
  };

if (typeof exports !== 'undefined') {
  if (typeof module !== 'undefined' && module.exports)
    exports = module.exports = sigma;
  exports.sigma = sigma;
}
<|endoftext|>


<commit_before>var Promise = require('bluebird');

module.exports = {
  infect: function (req, res) {
    var errors = [];

    var humanId = req.param('human');
    var zombieId = req.param('zombie');

    var hasLocation = req.param('location') || false;
    var latitude = req.param('latitude');
    var longitude = req.param('longitude');

    if (sails.config.hvz.endDate < new Date()) {
      errors.push("You cannot infect a player after the game has ended");
    }

    if (!humanId) {
      errors.push("Missing parameter 'human'");
    }

    if (!zombieId) {
      errors.push("Missing parameter 'zombie'");
    }

    if (hasLocation && (!latitude || !longitude)) {
      hasLocation = false;
      latitude = 0;
      longitude = 0;
    }

    if (errors.length > 0) {
      return res.badRequest({
        message: "There was an error with your request",
        problems: errors
      });
    }

    HumanId.findOne({
      active: true,
      idString: humanId
    }).populate('user').exec(function (err, humanIdObj) {
      if (err) {
        res.negotiate(err);
      }
      else {
        User.findOne({
          team: 'zombie',
          zombieId: zombieId
        }).exec(function (err, zombie) {
          if (err) {
            res.negotiate(err);
          }
          else {
            var shouldCauseFailure = false;

            if (humanIdObj === undefined || !AuthService.hasPermission(humanIdObj.user, 'player')) {
              errors.push("Invalid human id.");
              shouldCauseFailure = true;
            }

            if (humanIdObj !== undefined && humanIdObj.user.team !== 'human') {
              errors.push("The human id entered belongs to a zombie.");
            }

            if (zombie == undefined || !AuthService.hasPermission(zombie, 'player')) {
              errors.push("Invalid zombie id.");
            }

            if (shouldCauseFailure) {
              req.user.failures++;
              req.user.save();
            }

            if (shouldCauseFailure || errors.length > 0) {
              return res.badRequest({
                message: "There was an error with your request",
                problems: errors
              });
            }

            var human = humanIdObj.user;

            InfectionSpread.create({
              hasLocation: hasLocation,
              latitude: latitude,
              longitude: longitude,
              zombie: zombie,
              human: human
            }, function (err, infection) {
              if (err) {
                res.negotiate(err);
              }
              else {
                BadgeRegistry.processInfectionBadges(human, zombie, infection)
                  .then(function () {
                    human.team = 'zombie';

                    humanIdObj.active = false;

                    zombie.humansTagged++;

                    Promise.join(
                      human.save(),
                      humanIdObj.save(),
                      zombie.save(),
                      function() {
                        sails.log.info(zombie.email + " infected " + human.email);

                        res.ok({
                          human: human.getPublicData(),
                          zombie: zombie.getPublicData()
                        });
                      }
                    ).catch(function (err) {
                      res.negotiate(err);
                    });
                  }, function (err) {
                    InfectionSpread.destroy({id: infection.id}).exec(function () {
                      res.negotiate(err);
                    });
                  });
              }
            });
          }
        });
      }
    });
  },

  antivirus: function (req, res) {
    var errors = [];

    var zombieId = req.param('zombie');
    var avId = req.param('antivirus');

    if (sails.config.hvz.endDate < new Date()) {
      errors.push("You cannot infect a player after the game has ended");
    }

    if (!zombieId) {
      errors.push("Missing parameter 'zombie'");
    }

    if (!avId) {
      errors.push("Missing parameter 'antivirus'");
    }

    if (errors.length > 0) {
      return res.badRequest({
        message: "There was an error with your request",
        problems: errors
      });
    }

    AntivirusId.findOne({
      idString: avId
    }).exec(function (err, av) {
      if (err) {
        res.negotiate(err);
      }
      else {
        if (av === undefined) {
          req.user.failures++;
          req.user.save();

          return res.badRequest({
            message: "There was a problem using the antivirus.",
            problems: ['Invalid antivirus']
          });
        }

        if (!av.active) {
          return res.badRequest({
            message: "There was a problem using the antivirus.",
            problems: ['That antivirus has already been used.']
          });
        }

        if (av.expirationTime < new Date()) {
          return res.badRequest({
            message: "There was a problem using the antivirus.",
            problems: ['That antivirus has expired.']
          });
        }

        User.findOne({
          team: 'zombie',
          zombieId: zombieId
        }).exec(function (err, zombie) {
          if (err) {
            res.negotiate(err);
          }
          else {
            if (zombie == undefined || !AuthService.hasPermission(zombie, 'player')) {
              return res.badRequest({
                message: "There was a problem using the antivirus.",
                problems: ['Invalid zombie id.']
              });
            }

            if (zombie.usedAV) {
              return res.badRequest({
                message: "There was a problem using the antivirus.",
                problems: ['The zombie has already used an antivirus.']
              });
            }

            av.active = false;
            av.user = zombie.id;

            zombie.team = 'human';
            zombie.usedAV = true;
            zombie.addBadge('antivirus');

            Promise.join(
              av.save(),
              zombie.save(),
              function () {
                sails.log.info(zombie.email + " has used an antivirus");

                res.ok({
                  zombie: zombie.getPublicData()
                });
              }
            ).catch(function (err) {
              res.negotiate(err);
            });
          }
        });
      }
    });
  }
};
<commit_msg>minor fix to infect locations<commit_after>var Promise = require('bluebird');

module.exports = {
  infect: function (req, res) {
    var errors = [];

    var humanId = req.param('human');
    var zombieId = req.param('zombie');

    var hasLocation = req.param('location') || false;
    var latitude = req.param('latitude');
    var longitude = req.param('longitude');

    if (sails.config.hvz.endDate < new Date()) {
      errors.push("You cannot infect a player after the game has ended");
    }

    if (!humanId) {
      errors.push("Missing parameter 'human'");
    }

    if (!zombieId) {
      errors.push("Missing parameter 'zombie'");
    }

    if (hasLocation && (!latitude || !longitude)) {
      hasLocation = false;
      latitude = 0;
      longitude = 0;
    }

    if (!hasLocation) {
      latitude = 0;
      longitude = 0;
    }

    if (errors.length > 0) {
      return res.badRequest({
        message: "There was an error with your request",
        problems: errors
      });
    }

    HumanId.findOne({
      active: true,
      idString: humanId
    }).populate('user').exec(function (err, humanIdObj) {
      if (err) {
        res.negotiate(err);
      }
      else {
        User.findOne({
          team: 'zombie',
          zombieId: zombieId
        }).exec(function (err, zombie) {
          if (err) {
            res.negotiate(err);
          }
          else {
            var shouldCauseFailure = false;

            if (humanIdObj === undefined || !AuthService.hasPermission(humanIdObj.user, 'player')) {
              errors.push("Invalid human id.");
              shouldCauseFailure = true;
            }

            if (humanIdObj !== undefined && humanIdObj.user.team !== 'human') {
              errors.push("The human id entered belongs to a zombie.");
            }

            if (zombie == undefined || !AuthService.hasPermission(zombie, 'player')) {
              errors.push("Invalid zombie id.");
            }

            if (shouldCauseFailure) {
              req.user.failures++;
              req.user.save();
            }

            if (shouldCauseFailure || errors.length > 0) {
              return res.badRequest({
                message: "There was an error with your request",
                problems: errors
              });
            }

            var human = humanIdObj.user;

            InfectionSpread.create({
              hasLocation: hasLocation,
              latitude: latitude,
              longitude: longitude,
              zombie: zombie,
              human: human
            }, function (err, infection) {
              if (err) {
                res.negotiate(err);
              }
              else {
                BadgeRegistry.processInfectionBadges(human, zombie, infection)
                  .then(function () {
                    human.team = 'zombie';

                    humanIdObj.active = false;

                    zombie.humansTagged++;

                    Promise.join(
                      human.save(),
                      humanIdObj.save(),
                      zombie.save(),
                      function() {
                        sails.log.info(zombie.email + " infected " + human.email);

                        res.ok({
                          human: human.getPublicData(),
                          zombie: zombie.getPublicData()
                        });
                      }
                    ).catch(function (err) {
                      res.negotiate(err);
                    });
                  }, function (err) {
                    InfectionSpread.destroy({id: infection.id}).exec(function () {
                      res.negotiate(err);
                    });
                  });
              }
            });
          }
        });
      }
    });
  },

  antivirus: function (req, res) {
    var errors = [];

    var zombieId = req.param('zombie');
    var avId = req.param('antivirus');

    if (sails.config.hvz.endDate < new Date()) {
      errors.push("You cannot infect a player after the game has ended");
    }

    if (!zombieId) {
      errors.push("Missing parameter 'zombie'");
    }

    if (!avId) {
      errors.push("Missing parameter 'antivirus'");
    }

    if (errors.length > 0) {
      return res.badRequest({
        message: "There was an error with your request",
        problems: errors
      });
    }

    AntivirusId.findOne({
      idString: avId
    }).exec(function (err, av) {
      if (err) {
        res.negotiate(err);
      }
      else {
        if (av === undefined) {
          req.user.failures++;
          req.user.save();

          return res.badRequest({
            message: "There was a problem using the antivirus.",
            problems: ['Invalid antivirus']
          });
        }

        if (!av.active) {
          return res.badRequest({
            message: "There was a problem using the antivirus.",
            problems: ['That antivirus has already been used.']
          });
        }

        if (av.expirationTime < new Date()) {
          return res.badRequest({
            message: "There was a problem using the antivirus.",
            problems: ['That antivirus has expired.']
          });
        }

        User.findOne({
          team: 'zombie',
          zombieId: zombieId
        }).exec(function (err, zombie) {
          if (err) {
            res.negotiate(err);
          }
          else {
            if (zombie == undefined || !AuthService.hasPermission(zombie, 'player')) {
              return res.badRequest({
                message: "There was a problem using the antivirus.",
                problems: ['Invalid zombie id.']
              });
            }

            if (zombie.usedAV) {
              return res.badRequest({
                message: "There was a problem using the antivirus.",
                problems: ['The zombie has already used an antivirus.']
              });
            }

            av.active = false;
            av.user = zombie.id;

            zombie.team = 'human';
            zombie.usedAV = true;
            zombie.addBadge('antivirus');

            Promise.join(
              av.save(),
              zombie.save(),
              function () {
                sails.log.info(zombie.email + " has used an antivirus");

                res.ok({
                  zombie: zombie.getPublicData()
                });
              }
            ).catch(function (err) {
              res.negotiate(err);
            });
          }
        });
      }
    });
  }
};
<|endoftext|>


<commit_before>class PublicDatasetsAPIService {
    /*@ngInject*/
    constructor(publicAPIRoute, Restangular) {
        this.publicAPIRoute = publicAPIRoute;
        this.Restangular = Restangular;
    }

    getTopViewed() {
        return this.Restangular.one('v3').one('getTopViewedPublishedDatasets').customPOST().then(
            (ds) => {
                let datasets = ds.plain().data;
                datasets = this.augmentDatasets(datasets);
                return datasets;
            }
        );
    }

    getRecent() {
        return this.Restangular.one('v3').one('getRecentlyPublishedDatasets').customPOST().then(
            (ds) => {
                let datasets = ds.plain().data;
                for (let dataset of datasets) {
                    dataset.birthtime = new Date(ds.birthtime);
                }
                datasets = this.augmentDatasets(datasets);
                return datasets;
            }
        );
    }

    getDataset(datasetId) {
        return this.Restangular.one('v3').one('getPublishedDataset').customPOST({dataset_id: datasetId}).then(
            (ds) => {
                let dataset = ds.plain().data;
                return this.augmentDataset(dataset);
            }
        );
    }

    getDatasetProcess(datasetId, processId) {
        return this.Restangular.one('v3').one('getPublishedDatasetProcess').customPOST({
            dataset_id: datasetId,
            process_id: processId
        }).then(
            (process) => process.plain().data
        );
    }

    getDatasetsForTag(tag) {
        // return this.publicAPIRoute('tags', tag).one('datasets').getList().then(
        //     (datasets) => {
        //         datasets = datasets.plain();
        //         datasets = this.augmentDatasets(datasets);
        //         return datasets;
        //     }
        // );
        return this.Restangular.one('v3').one('getPublishedDatasetsForTag').customPOST({tag_id: tag}).then(
            (ds) => {
                let datasets = ds.plain().data;
                return this.augmentDatasets(datasets);
            }
        );
    }

    datasetWasViewed(userId, datasetId) {
        // let viewParams = {
        //     item_type: 'dataset',
        //     item_id: datasetId,
        //     user_id: userId
        // };
        // return this.publicAPIRoute('views').customPOST(viewParams).then(
        //     () => {
        //         return this.getDataset(datasetId).then(
        //             (dataset) => {
        //                 return dataset;
        //             }
        //         );
        //     }
        // );
        return this.Restangular.one('v3').one('incrementPublishedDatasetViews').customPOST({
            dataset_id: datasetId,
            user_id: userId,
        }).then(
            (ds) => {
                let dataset = ds.plain().data;
                return this.augmentDataset(dataset);
            }
        );
    }

    datasetWasDownloaded(userId, datasetId) {
        return this.getDataset(datasetId).then(
            (dataset) => {
                return dataset;
            }
        );
    }

    updateUseful(userId, datasetId, isUseful) {
        // let usefulParams = {
        //     item_type: 'dataset',
        //     item_id: datasetId,
        //     user_id: userId,
        //     action: isUseful ? 'add' : 'delete'
        // };
        // return this.publicAPIRoute('useful').customPOST(usefulParams).then(
        //     () => {
        //         return this.getDataset(datasetId).then(
        //             (dataset) => {
        //                 return dataset;
        //             }
        //         );
        //     }
        // );
        return this.Restangular.one('v3').one('updatePublishedDatasetUsefulCount').customPOST({
            dataset_id: datasetId,
            user_id: userId,
            action: isUseful ? 'add' : 'delete'
        }).then(
            ds => {
                let dataset = ds.plain().data;
                return this.augmentDataset(dataset);
            }
        );
    }

    augmentDataset(dataset) {
        dataset.stats.useful_count = dataset.stats.interested_users.length;
        dataset.stats.download_count = dataset.download_count || 0;
        return dataset;
    }

    augmentDatasets(datasets) {
        for (let i = 0; i < datasets.length; i++) {
            datasets[i] = this.augmentDataset(datasets[i]);
        }
        return datasets;
    }
}

angular.module('materialscommons').service('publicDatasetsAPI', PublicDatasetsAPIService);
<commit_msg>publicAPIRoute is no longer used<commit_after>class PublicDatasetsAPIService {
    /*@ngInject*/
    constructor(Restangular) {
        this.Restangular = Restangular;
    }

    getTopViewed() {
        return this.Restangular.one('v3').one('getTopViewedPublishedDatasets').customPOST().then(
            (ds) => {
                let datasets = ds.plain().data;
                datasets = this.augmentDatasets(datasets);
                return datasets;
            }
        );
    }

    getRecent() {
        return this.Restangular.one('v3').one('getRecentlyPublishedDatasets').customPOST().then(
            (ds) => {
                let datasets = ds.plain().data;
                for (let dataset of datasets) {
                    dataset.birthtime = new Date(ds.birthtime);
                }
                datasets = this.augmentDatasets(datasets);
                return datasets;
            }
        );
    }

    getDataset(datasetId) {
        return this.Restangular.one('v3').one('getPublishedDataset').customPOST({dataset_id: datasetId}).then(
            (ds) => {
                let dataset = ds.plain().data;
                return this.augmentDataset(dataset);
            }
        );
    }

    getDatasetProcess(datasetId, processId) {
        return this.Restangular.one('v3').one('getPublishedDatasetProcess').customPOST({
            dataset_id: datasetId,
            process_id: processId
        }).then(
            (process) => process.plain().data
        );
    }

    getDatasetsForTag(tag) {
        // return this.publicAPIRoute('tags', tag).one('datasets').getList().then(
        //     (datasets) => {
        //         datasets = datasets.plain();
        //         datasets = this.augmentDatasets(datasets);
        //         return datasets;
        //     }
        // );
        return this.Restangular.one('v3').one('getPublishedDatasetsForTag').customPOST({tag_id: tag}).then(
            (ds) => {
                let datasets = ds.plain().data;
                return this.augmentDatasets(datasets);
            }
        );
    }

    datasetWasViewed(userId, datasetId) {
        // let viewParams = {
        //     item_type: 'dataset',
        //     item_id: datasetId,
        //     user_id: userId
        // };
        // return this.publicAPIRoute('views').customPOST(viewParams).then(
        //     () => {
        //         return this.getDataset(datasetId).then(
        //             (dataset) => {
        //                 return dataset;
        //             }
        //         );
        //     }
        // );
        return this.Restangular.one('v3').one('incrementPublishedDatasetViews').customPOST({
            dataset_id: datasetId,
            user_id: userId,
        }).then(
            (ds) => {
                let dataset = ds.plain().data;
                return this.augmentDataset(dataset);
            }
        );
    }

    datasetWasDownloaded(userId, datasetId) {
        return this.getDataset(datasetId).then(
            (dataset) => {
                return dataset;
            }
        );
    }

    updateUseful(userId, datasetId, isUseful) {
        // let usefulParams = {
        //     item_type: 'dataset',
        //     item_id: datasetId,
        //     user_id: userId,
        //     action: isUseful ? 'add' : 'delete'
        // };
        // return this.publicAPIRoute('useful').customPOST(usefulParams).then(
        //     () => {
        //         return this.getDataset(datasetId).then(
        //             (dataset) => {
        //                 return dataset;
        //             }
        //         );
        //     }
        // );
        return this.Restangular.one('v3').one('updatePublishedDatasetUsefulCount').customPOST({
            dataset_id: datasetId,
            user_id: userId,
            action: isUseful ? 'add' : 'delete'
        }).then(
            ds => {
                let dataset = ds.plain().data;
                return this.augmentDataset(dataset);
            }
        );
    }

    augmentDataset(dataset) {
        dataset.stats.useful_count = dataset.stats.interested_users.length;
        dataset.stats.download_count = dataset.download_count || 0;
        return dataset;
    }

    augmentDatasets(datasets) {
        for (let i = 0; i < datasets.length; i++) {
            datasets[i] = this.augmentDataset(datasets[i]);
        }
        return datasets;
    }
}

angular.module('materialscommons').service('publicDatasetsAPI', PublicDatasetsAPIService);
<|endoftext|>


<commit_before>import { Accounts } from 'meteor/accounts-base';
import {
  getUserById,
  handleError,
  tokenValidator,
  userQueryValidator,
} from './server_utils';
import { Random } from 'meteor/random';

Accounts.constructor.prototype._onCreateLoginTokenHook = () => true;

Accounts.constructor.prototype.Accounts._checkToken = ({ user, token }) => {
  const result = {
    userId: user._id,
  };

  const userStoredToken = user.services.passwordless.token;
  const { createdAt, sequence } = userStoredToken;

  if (
    new Date(
      createdAt.getTime() +
        Accounts._options.loginTokenExpirationHours * 60 * 60 * 1000
    ) >= new Date()
  ) {
    result.error = handleError('Expired token', false);
  }
  if (sequence !== token) {
    result.error = handleError('Sequence not found', false);
  }

  return result;
};
const checkToken = Accounts._checkToken;

// Handler to login with an ott.
Accounts.registerLoginHandler('passwordless', options => {
  if (!options.token) return undefined; // don't handle

  check(options, {
    user: userQueryValidator,
    token: tokenValidator(),
  });

  const user = Accounts._findUserByQuery(options.user, {
    fields: {
      services: 1,
    },
  });
  if (!user) {
    handleError('User not found');
  }

  if (
    !user.services ||
    !user.services.passwordless ||
    !user.services.passwordless.token
  ) {
    handleError('User has no token set');
  }

  return checkToken({ ...options, user });
});

// Utility for plucking addresses from emails
const pluckAddresses = (emails = []) => emails.map(email => email.address);

Meteor.methods({
  requestLoginTokenForUser: ({ selector, userObject }) => {
    let user = Accounts._findUserByQuery(selector, {
      fields: { emails: 1 },
    });

    if (!user && !userObject) {
      handleError('User not found');
    }
    if (!user) {
      Accounts.createUser(userObject);
      user = Accounts._findUserByQuery(selector, {
        fields: { emails: 1 },
      });
    }

    if (!user) {
      handleError('User could not be created');
    }

    const sequence = Random.hexString(
      Accounts._options.tokenSequenceLength || 6
    );
    Meteor.users.update({
      $set: {
        'services.passwordless': {
          createdAt: new Date(),
          sequence,
        },
      },
    });
    const shouldContinue = Accounts._onCreateLoginTokenHook({
      token: sequence,
      userId: user._id,
    });

    const emails = pluckAddresses(user.emails);

    if (shouldContinue) {
      for (const email of emails) {
        Accounts.sendLoginTokenEmail({ userId: user._id, sequence, email });
      }
    }
  },
});

/**
 * @summary Send an email with a link the user can use to reset their password.
 * @locus Server
 * @param {String} userId The id of the user to send email to.
 * @param {String} [email] Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first email in the list.
 * @returns {Object} Object with {email, user, token, url, options} values.
 * @importFromPackage accounts-base
 */
Accounts.sendLoginTokenEmail = ({ userId, sequence, email }) => {
  const user = getUserById(userId);
  const url = Accounts.urls.loginToken(token, extraParams);
  const options = Accounts.generateOptionsForEmail(
    email,
    user,
    url,
    'sendLoginToken'
  );
  Email.send(options);
  if (Meteor.isDevelopment) {
    console.log(`\nLogin Token url: ${url}`);
  }
  return { email, user, token: sequence, url, options };
};
<commit_msg>Fixing accounts-passwordless initial issues<commit_after>import { Accounts } from 'meteor/accounts-base';
import {
  getUserById,
  handleError,
  tokenValidator,
  userQueryValidator,
} from './server_utils';
import { Random } from 'meteor/random';

Accounts.constructor.prototype._onCreateLoginTokenHook = () => true;

Accounts.constructor.prototype._checkToken = ({ user, token }) => {
  const result = {
    userId: user._id,
  };

  const userStoredToken = user.services.passwordless.token;
  const { createdAt, sequence } = userStoredToken;

  if (
    new Date(
      createdAt.getTime() +
        Accounts._options.loginTokenExpirationHours * 60 * 60 * 1000
    ) >= new Date()
  ) {
    result.error = handleError('Expired token', false);
  }
  if (sequence !== token) {
    result.error = handleError('Sequence not found', false);
  }

  return result;
};
const checkToken = Accounts._checkToken;

// Handler to login with an ott.
Accounts.registerLoginHandler('passwordless', options => {
  if (!options.token) return undefined; // don't handle

  check(options, {
    user: userQueryValidator,
    token: tokenValidator(),
  });

  const user = Accounts._findUserByQuery(options.user, {
    fields: {
      services: 1,
    },
  });
  if (!user) {
    handleError('User not found');
  }

  if (
    !user.services ||
    !user.services.passwordless ||
    !user.services.passwordless.token
  ) {
    handleError('User has no token set');
  }

  return checkToken({ ...options, user });
});

// Utility for plucking addresses from emails
const pluckAddresses = (emails = []) => emails.map(email => email.address);

Meteor.methods({
  requestLoginTokenForUser: ({ selector, userObject }) => {
    let user = Accounts._findUserByQuery(selector, {
      fields: { emails: 1 },
    });

    if (!user && !userObject) {
      handleError('User not found');
    }
    if (!user) {
      Accounts.createUser(userObject);
      user = Accounts._findUserByQuery(selector, {
        fields: { emails: 1 },
      });
    }

    if (!user) {
      handleError('User could not be created');
    }

    const sequence = Random.hexString(
      Accounts._options.tokenSequenceLength || 6
    );
    Meteor.users.update(user._id, {
      $set: {
        'services.passwordless': {
          createdAt: new Date(),
          sequence,
        },
      },
    });
    const shouldContinue = Accounts._onCreateLoginTokenHook({
      token: sequence,
      userId: user._id,
    });

    const emails = pluckAddresses(user.emails);

    if (shouldContinue) {
      emails.forEach(email => {
        Accounts.sendLoginTokenEmail({ userId: user._id, sequence, email });
      });
    }
  },
});

/**
 * @summary Send an email with a link the user can use to reset their password.
 * @locus Server
 * @param {String} userId The id of the user to send email to.
 * @param {String} [email] Optional. Which address of the user's to send the email to. This address must be in the user's `emails` list. Defaults to the first email in the list.
 * @returns {Object} Object with {email, user, token, url, options} values.
 * @importFromPackage accounts-base
 */
Accounts.sendLoginTokenEmail = ({ userId, sequence, email }) => {
  const user = getUserById(userId);
  const url = Accounts.urls.loginToken(sequence);
  const options = Accounts.generateOptionsForEmail(
    email,
    user,
    url,
    'sendLoginToken'
  );
  Email.send(options);
  if (Meteor.isDevelopment) {
    console.log(`\nLogin Token url: ${url}`);
  }
  return { email, user, token: sequence, url, options };
};
<|endoftext|>