<commit_before>'use strict';

treeherder.factory('thPinboard', [
    '$http', 'thUrl', 'ThJobClassificationModel', '$rootScope', 'thEvents',
    'ThBugJobMapModel', 'thNotify', 'ThLog', 'ThResultSetModel',
    function(
        $http, thUrl, ThJobClassificationModel, $rootScope, thEvents,
        ThBugJobMapModel, thNotify, ThLog, ThResultSetModel) {

    var $log = new ThLog("thPinboard");

    var pinnedJobs = {};
    var relatedBugs = {};

    var saveClassification = function(job) {
        var classification = new ThJobClassificationModel(this);

        // classification can be left unset making this a no-op
        if (classification.failure_classification_id > 0) {
            job.failure_classification_id = classification.failure_classification_id;

            // update the unclassified failure count for the page
            ThResultSetModel.updateUnclassifiedFailureMap($rootScope.repoName, job);

            classification.job_id = job.id;
            classification.create().
                success(function(data) {
                    thNotify.send("classification saved for " + job.platform + ": " + job.job_type_name, "success");
                }).error(function(data) {
                    thNotify.send("error saving classification for " + job.platform + ": " + job.job_type_name, "danger");
                });
        }
    };

    var saveBugs = function(job) {
        _.forEach(relatedBugs, function(bug) {
            var bjm = new ThBugJobMapModel({
                bug_id : bug.id,
                job_id: job.id,
                type: 'annotation'
            });
            bjm.create().
            success(function(data) {
                thNotify.send("bug association saved for " + job.platform + ": " + job.job_type_name, "success");
            }).error(function(data) {
                thNotify.send("error saving bug association for " + job.platform + ": " + job.job_type_name, "danger");
            });
        });
    };

    var api = {
        pinJob: function(job) {
            if (api.spaceRemaining() > 0) {
                pinnedJobs[job.id] = job;
                api.count.numPinnedJobs = _.size(pinnedJobs);
            } else {
                thNotify.send("Pinboard is already at maximum size of " + api.maxNumPinned, "danger", true);
            }
        },

        unPinJob: function(id) {
            delete pinnedJobs[id];
            api.count.numPinnedJobs = _.size(pinnedJobs);
        },

        // clear all pinned jobs and related bugs
        unPinAll: function() {
            for (var jid in pinnedJobs) {
                if (pinnedJobs.hasOwnProperty(jid)) { delete pinnedJobs[jid]; } }
            for (var bid in relatedBugs) {
                if (relatedBugs.hasOwnProperty(bid)) { delete relatedBugs[bid]; } }
            api.count.numPinnedJobs = _.size(pinnedJobs);
        },

        addBug: function(bug, job) {
            $log.debug("adding bug ", bug);
            relatedBugs[bug.id] = bug;
            api.count.numRelatedBugs = _.size(relatedBugs);
            $log.debug("related bugs", relatedBugs);
            if (job) {
                api.pinJob(job);
            }

        },

        removeBug: function(id) {
            delete relatedBugs[id];
            api.count.numRelatedBugs = _.size(relatedBugs);
        },

        // open form to create a new note
        createNewClassification: function() {
            return new ThJobClassificationModel({
                note: "",
                who: null,
                failure_classification_id: -1
            });
        },

        // save the classification and related bugs to all pinned jobs
        save: function(classification) {

            var pinnedJobsClone = {};
            var jid;
            for (jid in pinnedJobs) {
                if (pinnedJobs.hasOwnProperty(jid)) {
                    pinnedJobsClone[jid] = pinnedJobs[jid];
                }
            }

            _.each(pinnedJobs, saveClassification, classification);
            $rootScope.$broadcast(thEvents.jobsClassified, {jobs: pinnedJobsClone});

            _.each(pinnedJobs, saveBugs);
            $rootScope.$broadcast(thEvents.bugsAssociated, {jobs: pinnedJobsClone});

            api.unPinAll();
        },

        // save the classification only on all pinned jobs
        saveClassificationOnly: function(classification) {
            _.each(pinnedJobs, saveClassification, classification);
            $rootScope.$broadcast(thEvents.jobsClassified, {jobs: pinnedJobs});
        },

        // save bug associations only on all pinned jobs
        saveBugsOnly: function() {
            _.each(pinnedJobs, saveBugs);
            $rootScope.$broadcast(thEvents.bugsAssociated, {jobs: pinnedJobs});
        },

        hasPinnedJobs: function() {
            return !_.isEmpty(pinnedJobs);
        },

        spaceRemaining: function() {
            return api.maxNumPinned - api.count.numPinnedJobs;
        },

        pinnedJobs: pinnedJobs,
        relatedBugs: relatedBugs,
        count: {
            numPinnedJobs: 0,
            numRelatedBugs: 0
        },
        // not sure what this should be, but we need some limit, I think.
        maxNumPinned: 500
    };

    return api;
}]);

<commit_msg>default to intermittent in the pinboard<commit_after>'use strict';

treeherder.factory('thPinboard', [
    '$http', 'thUrl', 'ThJobClassificationModel', '$rootScope', 'thEvents',
    'ThBugJobMapModel', 'thNotify', 'ThLog', 'ThResultSetModel',
    function(
        $http, thUrl, ThJobClassificationModel, $rootScope, thEvents,
        ThBugJobMapModel, thNotify, ThLog, ThResultSetModel) {

    var $log = new ThLog("thPinboard");

    var pinnedJobs = {};
    var relatedBugs = {};

    var saveClassification = function(job) {
        var classification = new ThJobClassificationModel(this);

        // classification can be left unset making this a no-op
        if (classification.failure_classification_id > 0) {
            job.failure_classification_id = classification.failure_classification_id;

            // update the unclassified failure count for the page
            ThResultSetModel.updateUnclassifiedFailureMap($rootScope.repoName, job);

            classification.job_id = job.id;
            classification.create().
                success(function(data) {
                    thNotify.send("classification saved for " + job.platform + ": " + job.job_type_name, "success");
                }).error(function(data) {
                    thNotify.send("error saving classification for " + job.platform + ": " + job.job_type_name, "danger");
                });
        }
    };

    var saveBugs = function(job) {
        _.forEach(relatedBugs, function(bug) {
            var bjm = new ThBugJobMapModel({
                bug_id : bug.id,
                job_id: job.id,
                type: 'annotation'
            });
            bjm.create().
            success(function(data) {
                thNotify.send("bug association saved for " + job.platform + ": " + job.job_type_name, "success");
            }).error(function(data) {
                thNotify.send("error saving bug association for " + job.platform + ": " + job.job_type_name, "danger");
            });
        });
    };

    var api = {
        pinJob: function(job) {
            if (api.spaceRemaining() > 0) {
                pinnedJobs[job.id] = job;
                api.count.numPinnedJobs = _.size(pinnedJobs);
            } else {
                thNotify.send("Pinboard is already at maximum size of " + api.maxNumPinned, "danger", true);
            }
        },

        unPinJob: function(id) {
            delete pinnedJobs[id];
            api.count.numPinnedJobs = _.size(pinnedJobs);
        },

        // clear all pinned jobs and related bugs
        unPinAll: function() {
            for (var jid in pinnedJobs) {
                if (pinnedJobs.hasOwnProperty(jid)) { delete pinnedJobs[jid]; } }
            for (var bid in relatedBugs) {
                if (relatedBugs.hasOwnProperty(bid)) { delete relatedBugs[bid]; } }
            api.count.numPinnedJobs = _.size(pinnedJobs);
        },

        addBug: function(bug, job) {
            $log.debug("adding bug ", bug);
            relatedBugs[bug.id] = bug;
            api.count.numRelatedBugs = _.size(relatedBugs);
            $log.debug("related bugs", relatedBugs);
            if (job) {
                api.pinJob(job);
            }

        },

        removeBug: function(id) {
            delete relatedBugs[id];
            api.count.numRelatedBugs = _.size(relatedBugs);
        },

        // open form to create a new note. default to intermittent
        createNewClassification: function() {
            return new ThJobClassificationModel({
                note: "",
                who: null,
                failure_classification_id: 4
            });
        },

        // save the classification and related bugs to all pinned jobs
        save: function(classification) {

            var pinnedJobsClone = {};
            var jid;
            for (jid in pinnedJobs) {
                if (pinnedJobs.hasOwnProperty(jid)) {
                    pinnedJobsClone[jid] = pinnedJobs[jid];
                }
            }

            _.each(pinnedJobs, saveClassification, classification);
            $rootScope.$broadcast(thEvents.jobsClassified, {jobs: pinnedJobsClone});

            _.each(pinnedJobs, saveBugs);
            $rootScope.$broadcast(thEvents.bugsAssociated, {jobs: pinnedJobsClone});

            api.unPinAll();
        },

        // save the classification only on all pinned jobs
        saveClassificationOnly: function(classification) {
            _.each(pinnedJobs, saveClassification, classification);
            $rootScope.$broadcast(thEvents.jobsClassified, {jobs: pinnedJobs});
        },

        // save bug associations only on all pinned jobs
        saveBugsOnly: function() {
            _.each(pinnedJobs, saveBugs);
            $rootScope.$broadcast(thEvents.bugsAssociated, {jobs: pinnedJobs});
        },

        hasPinnedJobs: function() {
            return !_.isEmpty(pinnedJobs);
        },

        spaceRemaining: function() {
            return api.maxNumPinned - api.count.numPinnedJobs;
        },

        pinnedJobs: pinnedJobs,
        relatedBugs: relatedBugs,
        count: {
            numPinnedJobs: 0,
            numRelatedBugs: 0
        },
        // not sure what this should be, but we need some limit, I think.
        maxNumPinned: 500
    };

    return api;
}]);

<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Regents of the University of California
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * Author:  Jim Robinson,  2018
 */

"use strict";

var igv = (function (igv) {

    igv.extend = function (parent, child) {

        child.prototype = Object.create(parent.prototype);
        child.prototype.constructor = child;
        child.prototype._super = Object.getPrototypeOf(child.prototype);
        return child;
    }

    /**
     * A collection of properties and methods shared by all (or most) track types.   Used as a mixin
     * by prototype chaining.
     *
     * @param config
     * @param browser
     * @constructor
     */
    igv.TrackBase = function (config, browser) {

        if (config.displayMode) {
            config.displayMode = config.displayMode.toUpperCase();
        }

        this.config = config;
        this.browser = browser;
        this.url = config.url;
        this.type = config.type;

        config.name = config.name || config.label;   // synonym for name, label is deprecated
        if (config.name) {
            this.name = config.name;
        }
        else {
            if (igv.isFilePath(config.url)) this.name = config.url.name;
            else this.name = config.url;
        }

        this.order = config.order;

        if ("civic-ws" === config.sourceType) {    // Ugly proxy for specialized track type
            this.color = "rgb(155,20,20)";
        }
        else {
            this.color = config.color || config.defaultColor || "rgb(0,0,150)";
        }

        this.autoscaleGroup = config.autoscaleGroup;

        this.removable = config.removable === undefined ? true : config.removable;      // Defaults to true

        this.height = config.height || 100;
        this.autoHeight = config.autoHeight === undefined ? (config.height === undefined) : config.autoHeight;
        this.minHeight = config.minHeight || Math.min(25, this.height);
        this.maxHeight = config.maxHeight || Math.max(1000, this.height);

        this.visibilityWindow = config.visibilityWindow;

    };

    /**
     * Default implementation -- return the current state of the "this" object, which should be a this.  Used
     * to create session object for bookmarking, sharing.  Updates the track "config" object to reflect the
     * current state.  Only simple properties (string, number, boolean) are updated.
     */
    igv.TrackBase.prototype.getState = function () {

        const config = Object.assign({}, this.config);
        const self = this;

        Object.keys(config).forEach(function (key) {
            const value = self[key];
            if (value && (igv.isSimpleType(value) || typeof value === "boolean")) {
                config[key] = value;
            }
        })

        return config;
    };

    igv.TrackBase.prototype.supportsWholeGenome = function () {
        return false;
    }

    igv.TrackBase.prototype.clickedFeatures = function (clickState) {

        // We use the cached features rather than method to avoid async load.  If the
        // feature is not already loaded this won't work,  but the user wouldn't be mousing over it either.
        const features = clickState.viewport.getCachedFeatures();

        if (!features || features.length === 0) {
            return [];
        }

        const genomicLocation = clickState.genomicLocation;

        // We need some tolerance around genomicLocation
        const tolerance = 3 * clickState.referenceFrame.bpPerPixel;
        const ss = Math.floor(genomicLocation) - tolerance;
        const ee = Math.ceil(genomicLocation) + tolerance;

        return (igv.FeatureUtils.findOverlapping(features, ss, ee));
    };

    /**
     * Default popup text function -- just extracts string and number properties in random order.
     * @param feature
     * @returns {Array}
     */
    igv.TrackBase.prototype.extractPopupData = function (feature) {

        const filteredProperties = new Set(['row', 'color']);
        const data = [];

        let alleles, alleleFreqs;
        for (var property in feature) {

            if (feature.hasOwnProperty(property) && !filteredProperties.has(property) &&
                igv.isSimpleType(feature[property])) {

                data.push({name: property, value: feature[property]});

                if (property === "alleles") {
                    alleles = feature[property];
                } else if (property === "alleleFreqs") {
                    alleleFreqs = feature[property];
                }
            }
        }

        const genomeId = this.getGenomeId()
        if (alleles && alleleFreqs) {

            if (alleles.endsWith(",")) {
                alleles = alleles.substr(0, alleles.length - 1);
            }
            if (alleleFreqs.endsWith(",")) {
                alleleFreqs = alleleFreqs.substr(0, alleleFreqs.length - 1);
            }

            let a = alleles.split(",");
            let af = alleleFreqs.split(",");
            if (af.length > 1) {
                let b = [];
                for (let i = 0; i < af.length; i++) {
                    b.push({a: a[i], af: Number.parseFloat(af[i])});
                }
                b.sort(function (x, y) {
                    return x.af - y.af
                });

                let ref = b[b.length - 1].a;
                if (ref.length === 1) {
                    for (let i = b.length - 2; i >= 0; i--) {
                        let alt = b[i].a;
                        if (alt.length === 1) {
                            const cravatLink = igv.TrackBase.getCravatLink(feature.chr, feature.start + 1, ref, alt, genomeId)
                            if(cravatLink) {
                                data.push("
");
                                data.push(cravatLink);
                            }
                        }
                    }
                }
            }
        }

        return data;

    }

    igv.TrackBase.prototype.getGenomeId = function () {
        return this.browser.genome ? this.browser.genome.id : undefined
    }

    igv.TrackBase.getCravatLink = function (chr, position, ref, alt, genomeID) {

        if ("hg38" === genomeID || "GRCh38" === genomeID) {

            return "Cravat " + ref + "->" + alt + ""
        }
        else {
            return undefined
        }
    }

    return igv;

})(igv || {});
<commit_msg>cravat tweak<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Regents of the University of California
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * Author:  Jim Robinson,  2018
 */

"use strict";

var igv = (function (igv) {

    igv.extend = function (parent, child) {

        child.prototype = Object.create(parent.prototype);
        child.prototype.constructor = child;
        child.prototype._super = Object.getPrototypeOf(child.prototype);
        return child;
    }

    /**
     * A collection of properties and methods shared by all (or most) track types.   Used as a mixin
     * by prototype chaining.
     *
     * @param config
     * @param browser
     * @constructor
     */
    igv.TrackBase = function (config, browser) {

        if (config.displayMode) {
            config.displayMode = config.displayMode.toUpperCase();
        }

        this.config = config;
        this.browser = browser;
        this.url = config.url;
        this.type = config.type;

        config.name = config.name || config.label;   // synonym for name, label is deprecated
        if (config.name) {
            this.name = config.name;
        }
        else {
            if (igv.isFilePath(config.url)) this.name = config.url.name;
            else this.name = config.url;
        }

        this.order = config.order;

        if ("civic-ws" === config.sourceType) {    // Ugly proxy for specialized track type
            this.color = "rgb(155,20,20)";
        }
        else {
            this.color = config.color || config.defaultColor || "rgb(0,0,150)";
        }

        this.autoscaleGroup = config.autoscaleGroup;

        this.removable = config.removable === undefined ? true : config.removable;      // Defaults to true

        this.height = config.height || 100;
        this.autoHeight = config.autoHeight === undefined ? (config.height === undefined) : config.autoHeight;
        this.minHeight = config.minHeight || Math.min(25, this.height);
        this.maxHeight = config.maxHeight || Math.max(1000, this.height);

        this.visibilityWindow = config.visibilityWindow;

    };

    /**
     * Default implementation -- return the current state of the "this" object, which should be a this.  Used
     * to create session object for bookmarking, sharing.  Updates the track "config" object to reflect the
     * current state.  Only simple properties (string, number, boolean) are updated.
     */
    igv.TrackBase.prototype.getState = function () {

        const config = Object.assign({}, this.config);
        const self = this;

        Object.keys(config).forEach(function (key) {
            const value = self[key];
            if (value && (igv.isSimpleType(value) || typeof value === "boolean")) {
                config[key] = value;
            }
        })

        return config;
    };

    igv.TrackBase.prototype.supportsWholeGenome = function () {
        return false;
    }

    igv.TrackBase.prototype.clickedFeatures = function (clickState) {

        // We use the cached features rather than method to avoid async load.  If the
        // feature is not already loaded this won't work,  but the user wouldn't be mousing over it either.
        const features = clickState.viewport.getCachedFeatures();

        if (!features || features.length === 0) {
            return [];
        }

        const genomicLocation = clickState.genomicLocation;

        // We need some tolerance around genomicLocation
        const tolerance = 3 * clickState.referenceFrame.bpPerPixel;
        const ss = Math.floor(genomicLocation) - tolerance;
        const ee = Math.ceil(genomicLocation) + tolerance;

        return (igv.FeatureUtils.findOverlapping(features, ss, ee));
    };

    /**
     * Default popup text function -- just extracts string and number properties in random order.
     * @param feature
     * @returns {Array}
     */
    igv.TrackBase.prototype.extractPopupData = function (feature) {

        const filteredProperties = new Set(['row', 'color']);
        const data = [];

        let alleles, alleleFreqs;
        for (var property in feature) {

            if (feature.hasOwnProperty(property) && !filteredProperties.has(property) &&
                igv.isSimpleType(feature[property])) {

                data.push({name: property, value: feature[property]});

                if (property === "alleles") {
                    alleles = feature[property];
                } else if (property === "alleleFreqs") {
                    alleleFreqs = feature[property];
                }
            }
        }

        const genomeId = this.getGenomeId()
        if (alleles && alleleFreqs) {

            if (alleles.endsWith(",")) {
                alleles = alleles.substr(0, alleles.length - 1);
            }
            if (alleleFreqs.endsWith(",")) {
                alleleFreqs = alleleFreqs.substr(0, alleleFreqs.length - 1);
            }

            let a = alleles.split(",");
            let af = alleleFreqs.split(",");
            if (af.length > 1) {
                let b = [];
                for (let i = 0; i < af.length; i++) {
                    b.push({a: a[i], af: Number.parseFloat(af[i])});
                }
                b.sort(function (x, y) {
                    return x.af - y.af
                });

                let ref = b[b.length - 1].a;
                if (ref.length === 1) {
                    for (let i = b.length - 2; i >= 0; i--) {
                        let alt = b[i].a;
                        if (alt.length === 1) {
                            const cravatLink = igv.TrackBase.getCravatLink(feature.chr, feature.start + 1, ref, alt, genomeId)
                            if(cravatLink) {
                                data.push("
");
                                data.push(cravatLink);
                            }
                        }
                    }
                }
            }
        }

        return data;

    }

    igv.TrackBase.prototype.getGenomeId = function () {
        return this.browser.genome ? this.browser.genome.id : undefined
    }

    igv.TrackBase.getCravatLink = function (chr, position, ref, alt, genomeID) {

        if ("hg38" === genomeID || "GRCh38" === genomeID) {

            const cravatChr = chr.startsWith("chr") ? chr : "chr" + chr

            return "Cravat " + ref + "->" + alt + ""
        }
        else {
            return undefined
        }
    }
//chr22 40418496 - A G

    return igv;

})(igv || {});
<|endoftext|>


<commit_before>import { Sparkline } from 'lib/visualizations'

window.GobiertoCharters.ChartersController = (function() {

  function ChartersController() {}

  ChartersController.prototype.show = function(opts){

    // DEBUG: Esta funcion DEBE ser eliminada cuando se obtengan datos verdaderos
    function mock(length = 2) {
      let json = [];
      for (var i = 0; i < length; i++) {
        json.push({
          date: new Date().getFullYear() - i,
          value: Math.floor(Math.random() * Math.floor(100))
        })
      }
      return json
    }

    const $sparklines = $('.sparkline')

    $sparklines.each((i, container) => {
      let options = {
        axes: true,
        aspectRatio: 3,
        margins: {
          top: 0,
          bottom: 0,
          left: 0,
          right: 0
        },
        freq: opts.freq
      }

      if (opts.sparklinesData[container.id] && opts.sparklinesData[container.id].length > 1) {
        let chart = new Sparkline(`#${container.id}`, opts.sparklinesData[container.id], options)
        chart.render()
      }
    })
  };

  return ChartersController;
})();

window.GobiertoCharters.charters_controller = new GobiertoCharters.ChartersController;
<commit_msg>Prevent repeated sparklines on reload<commit_after>import { Sparkline } from 'lib/visualizations'

window.GobiertoCharters.ChartersController = (function() {

  function ChartersController() {}

  ChartersController.prototype.show = function(opts){

    // DEBUG: Esta funcion DEBE ser eliminada cuando se obtengan datos verdaderos
    function mock(length = 2) {
      let json = [];
      for (var i = 0; i < length; i++) {
        json.push({
          date: new Date().getFullYear() - i,
          value: Math.floor(Math.random() * Math.floor(100))
        })
      }
      return json
    }

    const $sparklines = $('.sparkline')

    $sparklines.each((i, container) => {
      let options = {
        axes: true,
        aspectRatio: 3,
        margins: {
          top: 0,
          bottom: 0,
          left: 0,
          right: 0
        },
        freq: opts.freq
      }

      if (opts.sparklinesData[container.id] && opts.sparklinesData[container.id].length > 1 && $(`#${container.id} svg`).length === 0) {
        let chart = new Sparkline(`#${container.id}`, opts.sparklinesData[container.id], options)
        chart.render()
      }
    })
  };

  return ChartersController;
})();

window.GobiertoCharters.charters_controller = new GobiertoCharters.ChartersController;
<|endoftext|>


<commit_before><commit_msg>Add 'draggable' module for modular-module<commit_after><|endoftext|>


<commit_before>
var GOVUK = GOVUK || {};

GOVUK.BusinessSupportFinder = (function () {
  var selectedItems = (function () {
    var items = [];

    return {
      add: function(id) {
        items.push(id + '');
      },
      remove: function(id) {
        var idx = items.length,
            found = false,
            tmpArr = [];

        while (idx--) {
            if (items[idx] !== id) {
                tmpArr.push(items[idx]);
            } else {
                found = true;
            }
        }

        items = tmpArr;

        return found;
      },
      get: function() {
        return items.slice(0);
      }
    };
  }());

  return {
    init: function () {
      var checkExisting = function () {
        var $pickedItems = $('.picked-items ul li');
        if ($pickedItems.length) {
          $pickedItems.each(function (idx) {
            var id = $(this).data('slug');

            selectedItems.add(id);
          });
        }
      };

      checkExisting();

      $(".search-picker").on("click", "li[data-slug] a.add", {
        linkText: "Remove",
        action: "add"
      }, GOVUK.BusinessSupportFinder.swapper);

      // event handler to remove a list item from the picked list.
      $(".picked-items, .search-picker").on("click", "li[data-slug] a.remove", {
        linkText: "Add",
        action: "remove"
      }, GOVUK.BusinessSupportFinder.swapper);
    },

    swapper: function(event) {

      function createNextUrl() {
        var sector_slugs = selectedItems.get();
        sector_slugs.sort();
        return window.location.pathname.replace(/\/[^\/]+$/, "/stage") + "?sectors=" + sector_slugs.join("_");
      }

      event.preventDefault();

      var li = $(this).parent(), // the list item that is being moved
          source = $(event.delegateTarget), // container for list that item is coming from
          target = $('.picked-items'), // container for list that item is going to
          targetList = $("ul", target),
          newli = li.clone(),
          itemLabel = $('span', newli),
          prefix = 'sector',
          itemId,
          newlis;

      if (event.data.action === 'add') {
        li.addClass('selected')
          .find('a')
          .removeClass('add')
          .addClass('remove')
          .text(event.data.linkText);

        // Move and update the li
        itemId = itemLabel.attr('id').replace(prefix + '-', '');
        itemLabel.attr('id', prefix + '-' + itemId + '-selected');
        $('a', newli)
          .removeClass()
          .addClass(event.data.linkText.toLowerCase())
          .attr('aria-labelledby', prefix + '-' + itemId + '-selected')
          .text(event.data.linkText);
        targetList.append(newli);

        // show/hide picked-items hint and next link
        $(".hint", target).removeClass("hint").addClass("hidden");
        if ($("#next-step").length === 0) {
          target.append('
Next step
');
        }

        selectedItems.add(itemId);
      } else {
        itemId = $(this).attr('aria-labelledby').replace('-selected', '');

        $('#' + itemId + '-selected').parent('li').remove();
        $('#' + itemId).parent('li')
          .removeClass('selected')
          .find('a')
          .removeClass('remove')
          .addClass('add')
          .text(event.data.linkText);

        if (source.find("li").length === 0) { // removing an item
          $(".hidden", source).removeClass("hidden").addClass("hint");
          $("#next-step").remove();
        }
        selectedItems.remove(itemId.replace(prefix + '-', ''));
      }

      if (selectedItems.get().length > 0) {
        // sort the target list
        newlis = $('>li', targetList);
        newlis.remove();
        newlis = $.makeArray(newlis).sort(function(a, b) {
          return $("span", a).text().localeCompare($("span", b).text());
        });
        targetList.append(newlis);
      }

      // update Next link URL
      $("#next-step").attr("href", createNextUrl());
    }
  }
}());

$(function() {
  GOVUK.BusinessSupportFinder.init();
});
<commit_msg>Fixes to spacing issues<commit_after>var GOVUK = GOVUK || {};

GOVUK.BusinessSupportFinder = (function () {
  var selectedItems = (function () {
    var items = [];

    return {
      add: function(id) {
        items.push(id + '');
      },
      remove: function(id) {
        var idx = items.length,
            found = false,
            tmpArr = [];

        while (idx--) {
            if (items[idx] !== id) {
                tmpArr.push(items[idx]);
            } else {
                found = true;
            }
        }
        items = tmpArr;

        return found;
      },
      get: function() {
        return items.slice(0);
      }
    };
  }());

  return {
    init: function () {
      var checkExisting = function () {
        var $pickedItems = $('.picked-items ul li');

        if ($pickedItems.length) {
          $pickedItems.each(function (idx) {
            var id = $(this).data('slug');

            selectedItems.add(id);
          });
        }
      };

      checkExisting();

      $(".search-picker").on("click", "li[data-slug] a.add", {
        linkText: "Remove",
        action: "add"
      }, GOVUK.BusinessSupportFinder.swapper);

      // event handler to remove a list item from the picked list.
      $(".picked-items, .search-picker").on("click", "li[data-slug] a.remove", {
        linkText: "Add",
        action: "remove"
      }, GOVUK.BusinessSupportFinder.swapper);
    },

    swapper: function(event) {

      function createNextUrl() {
        var sector_slugs = selectedItems.get();

        sector_slugs.sort();
        return window.location.pathname.replace(/\/[^\/]+$/, "/stage") + "?sectors=" + sector_slugs.join("_");
      }

      event.preventDefault();

      var li = $(this).parent(), // the list item that is being moved
          source = $(event.delegateTarget), // container for list that item is coming from
          target = $('.picked-items'), // container for list that item is going to
          targetList = $("ul", target),
          newli = li.clone(),
          itemLabel = $('span', newli),
          prefix = 'sector',
          itemId,
          newlis;

      if (event.data.action === 'add') {
        li.addClass('selected')
          .find('a')
          .removeClass('add')
          .addClass('remove')
          .text(event.data.linkText);

        // Move and update the li
        itemId = itemLabel.attr('id').replace(prefix + '-', '');
        itemLabel.attr('id', prefix + '-' + itemId + '-selected');
        $('a', newli)
          .removeClass()
          .addClass(event.data.linkText.toLowerCase())
          .attr('aria-labelledby', prefix + '-' + itemId + '-selected')
          .text(event.data.linkText);
        targetList.append(newli);

        // show/hide picked-items hint and next link
        $(".hint", target).removeClass("hint").addClass("hidden");
        if ($("#next-step").length === 0) {
          target.append('
Next step
');
        }

        selectedItems.add(itemId);
      } else {
        itemId = $(this).attr('aria-labelledby').replace('-selected', '');

        $('#' + itemId + '-selected').parent('li').remove();
        $('#' + itemId).parent('li')
          .removeClass('selected')
          .find('a')
          .removeClass('remove')
          .addClass('add')
          .text(event.data.linkText);

        if (source.find("li").length === 0) { // removing an item
          $(".hidden", source).removeClass("hidden").addClass("hint");
          $("#next-step").remove();
        }

        selectedItems.remove(itemId.replace(prefix + '-', ''));
      }

      if (selectedItems.get().length > 0) {
        // sort the target list
        newlis = $('>li', targetList);
        newlis.remove();
        newlis = $.makeArray(newlis).sort(function(a, b) {
          return $("span", a).text().localeCompare($("span", b).text());
        });
        targetList.append(newlis);
      }

      // update Next link URL
      $("#next-step").attr("href", createNextUrl());
    }
  }
}());

$(function() {
  GOVUK.BusinessSupportFinder.init();
});
<|endoftext|>


<commit_before><commit_msg>FIO-5149: fixed processing of custom component using complex data (#4741)<commit_after><|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import createHistory from 'history/createBrowserHistory';

export default class ModalRoot extends React.PureComponent {
  static contextTypes = {
    router: PropTypes.object,
  };

  static propTypes = {
    children: PropTypes.node,
    onClose: PropTypes.func.isRequired,
    noEsc: PropTypes.bool,
  };

  state = {
    revealed: !!this.props.children,
  };

  activeElement = this.state.revealed ? document.activeElement : null;

  handleKeyUp = (e) => {
    if ((e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27)
         && !!this.props.children && !this.props.noEsc) {
      this.props.onClose();
    }
  }

  componentDidMount () {
    window.addEventListener('keyup', this.handleKeyUp, false);
    this.history = this.context.router ? this.context.router.history : createHistory();
  }

  componentWillReceiveProps (nextProps) {
    if (!!nextProps.children && !this.props.children) {
      this.activeElement = document.activeElement;

      this.getSiblings().forEach(sibling => sibling.setAttribute('inert', true));
    } else if (!nextProps.children) {
      this.setState({ revealed: false });
    }
  }

  componentDidUpdate (prevProps) {
    if (!this.props.children && !!prevProps.children) {
      this.getSiblings().forEach(sibling => sibling.removeAttribute('inert'));
      this.activeElement.focus();
      this.activeElement = null;
      this.handleModalClose();
    }
    if (this.props.children) {
      requestAnimationFrame(() => {
        this.setState({ revealed: true });
      });
      if (!prevProps.children) this.handleModalOpen();
    }
  }

  componentWillUnmount () {
    window.removeEventListener('keyup', this.handleKeyUp);
  }

  handleModalClose () {
    this.unlistenHistory();

    const state = this.history.location.state;
    if (state && state.mastodonModalOpen) {
      this.history.goBack();
    }
  }

  handleModalOpen () {
    const history = this.history;
    const state   = {...history.location.state, mastodonModalOpen: true};
    history.push(history.location.pathname, state);
    this.unlistenHistory = history.listen(() => {
      this.props.onClose();
    });
  }

  getSiblings = () => {
    return Array(...this.node.parentElement.childNodes).filter(node => node !== this.node);
  }

  setRef = ref => {
    this.node = ref;
  }

  render () {
    const { children, onClose } = this.props;
    const { revealed } = this.state;
    const visible = !!children;

    if (!visible) {
      return (

      );
    }

    return (

{children}

    );
  }

}
<commit_msg>Fix composer not getting focus after reply confirmation dialog<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import createHistory from 'history/createBrowserHistory';

export default class ModalRoot extends React.PureComponent {
  static contextTypes = {
    router: PropTypes.object,
  };

  static propTypes = {
    children: PropTypes.node,
    onClose: PropTypes.func.isRequired,
    noEsc: PropTypes.bool,
  };

  state = {
    revealed: !!this.props.children,
  };

  activeElement = this.state.revealed ? document.activeElement : null;

  handleKeyUp = (e) => {
    if ((e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27)
         && !!this.props.children && !this.props.noEsc) {
      this.props.onClose();
    }
  }

  componentDidMount () {
    window.addEventListener('keyup', this.handleKeyUp, false);
    this.history = this.context.router ? this.context.router.history : createHistory();
  }

  componentWillReceiveProps (nextProps) {
    if (!!nextProps.children && !this.props.children) {
      this.activeElement = document.activeElement;

      this.getSiblings().forEach(sibling => sibling.setAttribute('inert', true));
    } else if (!nextProps.children) {
      this.setState({ revealed: false });
    }
    if (!nextProps.children && !!this.props.children) {
      this.activeElement.focus();
      this.activeElement = null;
    }
  }

  componentDidUpdate (prevProps) {
    if (!this.props.children && !!prevProps.children) {
      this.getSiblings().forEach(sibling => sibling.removeAttribute('inert'));
      this.handleModalClose();
    }
    if (this.props.children) {
      requestAnimationFrame(() => {
        this.setState({ revealed: true });
      });
      if (!prevProps.children) this.handleModalOpen();
    }
  }

  componentWillUnmount () {
    window.removeEventListener('keyup', this.handleKeyUp);
  }

  handleModalClose () {
    this.unlistenHistory();

    const state = this.history.location.state;
    if (state && state.mastodonModalOpen) {
      this.history.goBack();
    }
  }

  handleModalOpen () {
    const history = this.history;
    const state   = {...history.location.state, mastodonModalOpen: true};
    history.push(history.location.pathname, state);
    this.unlistenHistory = history.listen(() => {
      this.props.onClose();
    });
  }

  getSiblings = () => {
    return Array(...this.node.parentElement.childNodes).filter(node => node !== this.node);
  }

  setRef = ref => {
    this.node = ref;
  }

  render () {
    const { children, onClose } = this.props;
    const { revealed } = this.state;
    const visible = !!children;

    if (!visible) {
      return (

      );
    }

    return (

{children}

    );
  }

}
<|endoftext|>


<commit_before>"use strict";
let firebase = require("firebase");
firebase.initializeApp({
  databaseURL: "https://ubenzer.firebaseio.com/",
  serviceAccount: "firebase-key.json"
});

// As an admin, the app has access to read and write all data, regardless of Security Rules
let db = firebase.database();
let allComments = db.ref("comments");
allComments.set({});

let xml2js = require("xml2js");
let fs = require("fs-extra");
let path = require("path");
let toMarkdown = require("to-markdown");
let shortcode = require("shortcode-parser");
let eol = require("eol");
let httpreq = require("httpreq");
let Batch = require("batch");

shortcode.add("php", function(buf) {
  return "```php\n" + buf + "\n```";
});
shortcode.add("c", function(buf) {
  return "```c\n" + buf + "\n```";
});
shortcode.add("java", function(buf) {
  return "```java\n" + buf + "\n```";
});
shortcode.add("caption", function(buf, opts) {
  if (opts.caption) {
    return opts.caption + "\n" + buf;
  }
  return buf;
});

let downloadedFiles = new Set();
let batch = new Batch;
batch.concurrency(30);

//fs.emptyDirSync("./out/posts");

let idLookup = {};
let parser = new xml2js.Parser();
let data = fs.readFileSync("/Users/ub/Downloads/ubenzerumutbenzerodakim.wordpress.2016-05-19.xml");
parser.parseString(data, function (err, result) {
  if (err) {
    console.log("Error parsing xml: " + err);
  }
  console.log("Parsed XML");
  var posts = result.rss.channel[0].item;
  posts.forEach(createIdLookup);
  posts.forEach(processPost);
});

batch.on("progress", function(e) {
  console.log(`${e.percent}% - ${e.complete} of ${e.total}`);
});
batch.end(function() {
  console.log(`Batch jobs done!`);
  process.exit(0);
});

function isPostValid(post) {
  if (post["wp:status"][0] !== "publish") {
    return false;
  }
  if (post["wp:post_type"][0] !== "post") {
    return false;
  }
  return true;
}
function createIdLookup(post) {
  if (!isPostValid(post)) { return; }

  var slug = post["wp:post_name"][0];
  var postDate = new Date(post.pubDate[0]);
  var id = postDate.getFullYear() + "/" + getPaddedNumber(postDate.getMonth() + 1) + "/" + slug;

  idLookup[slug] = id;
}

function processPost(post) {
  if (!isPostValid(post)) { return; }

  var postTitle = post.title;

  console.log("Processing Post: " + postTitle);

  var postDate = new Date(post.pubDate[0]);
  var postData = post["content:encoded"][0];
  var slug = post["wp:post_name"][0];
  var categories = [];
  var id = postDate.getFullYear() + "/" + getPaddedNumber(postDate.getMonth() + 1) + "/" + slug;

  // process post comments
  let comments = post["wp:comment"];
  if (comments instanceof Array) {
    comments.forEach((comment) => {
      uploadComment(id, comment);
    });
  }

  // end comments

  post.category.forEach(function(categoryBlob) {
    var cat = categoryBlob._;
    if (categoryBlob.$.domain !== "category") {
      return;
    }
    if (cat === "İlişkiler" || cat === "Kişisel" || cat === "Markalar" || cat == "Türkçe") {
      cat = "Hayat/" +  cat;
    } else if (cat === "Scala" || cat === "PHP" || cat === "JAVA" || cat == "ANSI C" || cat == ".NET") {
      cat = "Bilgisayar/Programlama/" +  cat;
    } else if (cat === "Windows" || cat === "Programlama" || cat === "Bilmuh’çular için" ||
        cat === "İnternet" || cat === "Linux" || cat === "Mac" || cat === "Bilgisayar Oyunları" ||
        cat === "Android") {
      cat = "Bilgisayar/" +  cat;
    } else if (cat === "Minecraft") {
      cat = "Bilgisayar/Bilgisayar Oyunları/" +  cat;
    }
    categories.push(cat);
  });

  var fullPath = "./out/posts/" + postDate.getFullYear() + "/" + getPaddedNumber(postDate.getMonth() + 1) + "/" + slug;
  fs.ensureDirSync(fullPath);

  // Convert two new lines to paragraphs
  postData = eol.lf(postData);
  postData = postData.split("");
  postData = postData.join("
---more---
");
  postData = postData.split("\n\n");
  postData = postData.map(function(aData) {
    return `<p>${aData}</p>`;
  });
  postData = postData.join("\n");

  var markdown = null;
  try {
    markdown = toMarkdown(postData, {
      converters: [
        {
          filter: function (node) {
            return node.nodeName === 'A' && node.getAttribute('href');
          },
          replacement: function(content, node) {
            let href = node.getAttribute('href');
            let isTargetBlank = node.getAttribute('target') === "_blank";

            if (isUBenzerUrl(href)) {
              let source = normalizeUBenzerUrl(href);
              let target = normalizeUBenzerUrl(href, true);
              let downloadPath = fullPath + "/" + target;

              if (isFileImage(target)) {
                downloadFile(source, downloadPath);
                if (node.querySelectorAll("*").length === 1 && node.querySelectorAll("img").length === 1) {
                  let imgSrc = node.querySelectorAll("img")[0].getAttribute("src");
                  if (isUBenzerUrl(imgSrc)) {
                    imgSrc = normalizeUBenzerUrl(imgSrc, true);
                    if (imgSrc === target) {
                      let title = "";
                      if (node.querySelectorAll("img")[0].getAttribute("title")) {
                        title = node.querySelectorAll("img")[0].getAttribute("title");
                      } else if (node.querySelectorAll("img")[0].getAttribute("alt")) {
                        title = node.querySelectorAll("img")[0].getAttribute("alt");
                      } else {
                        title = postTitle;
                      }
                      return `![${title}](${target}){link${isTargetBlank?',new':''}}`;
                    }
                  }
                }
                return `[${content}](${target})${isTargetBlank?'{new}':''}`;
              } else if (path.extname(target) !== "") {
                downloadFile(source, downloadPath);
                return `[${content}](${target})${isTargetBlank?'{new}':''}`;
              } else {
                // this is an internal link
                if (!idLookup[target]) {
                  throw new Error("NOT FOUND INTERNAL LINK: " + href);
                }
                return `[${content}](@${idLookup[target]})${isTargetBlank?'{new}':''}`;
              }
            }
            return `[${content}](${href})${isTargetBlank?'{new}':''}`;
          }
        },
        {
          filter: 'img',
          replacement: function(innerHtml, node) {
            let src = node.getAttribute("src");
            if (!src) { throw new Error("IMG WITHOUT SRC!"); }
            let title = "";
            if (node.getAttribute("title")) {
              title = node.getAttribute("title");
            } else if (node.getAttribute("alt")) {
              title = node.getAttribute("alt");
            } else {
              title = postTitle;
            }

            if (src === "https://go.microsoft.com/fwlink/?LinkId=161376") {
              return "";
            }

            var targetSrc = src;
            if (isUBenzerUrl(src)) {
              let source = normalizeUBenzerUrl(src);
              let target = normalizeUBenzerUrl(src, true);

              let downloadPath = fullPath + "/" + target;
              downloadFile(source, downloadPath);
              targetSrc = target;
            }

            let classes = [];
            if (node.classList.contains("alignright")) {
              classes.push("right");
            } else if (node.classList.contains("alignleft")) {
              classes.push("left");
            } else if (node.classList.contains("aligncenter")) {
              classes.push("center");
            }

            let text = `![${title}](${targetSrc})`;
            if (classes.length > 0) {
              text = `${text}{${classes.join(",")}}`;
            }
            console.log(text);
            return text;
          }
        },
        {
          filter: 'strong',
          replacement: function(innerHtml) {
            return `*${innerHtml}*`;
          }
        }
      ]
    });
  } catch(e) {
    console.error(postData);
    throw e;
  }

  markdown = shortcode.parse(markdown);

  markdown = "# " + postTitle + "\n\n" + markdown;

  var header = "";
  header += "---\n";
  header += "created: " + postDate.getFullYear() + "-" + getPaddedNumber(postDate.getMonth() + 1) + "-" + getPaddedNumber(postDate.getDate()) + "\n";
  if (categories.length > 0) {
    header += "category:\n";
    categories.forEach(function(category) {
      header += "  - " + category + "\n";
    });
  }

  header += "---\n";

  fs.outputFile(fullPath + "/index.md", header + markdown, function(err) {
    if(err !== null) {
      console.error("Error writing post " + postTitle + " to disk!");
      throw err;
    }
  });
}

function downloadFile(url, path) {
  return;
  if (url.startsWith("/deepo/")) {
    url = "http://www.ubenzer.com" + url;
  }
  if (downloadedFiles.has(url+path)) { return; }
  downloadedFiles.add(url+path);
  batch.push(function(done){
    console.log(`Downloading ${url} to ${path}...`);
    httpreq.download(url, path,
        function (err, progress) {},
        function (err){
          if (err) {
            console.log("FAILED DOWNLOAD :" + url, err);
          }
          done();
        });
  });
}

function uploadComment(id, comment) {
  batch.push(function(done) {
    let postCommentsRef = allComments.child(id);
    postCommentsRef.push({
      name: comment["wp:comment_author"][0],
      date: new Date(comment["wp:comment_date_gmt"][0]).toISOString(),
      data: comment["wp:comment_content"][0]
    }, function (error) {
      if (error) {
        console.error(error);
        throw new Error(error);
      }
      done();
    });
  });
}

function getPaddedNumber(num) {
  if (num < 10) {
    return "0" + num;
  }
  return num;
}

function isFileImage(file) {
  file = file.toLowerCase();
  return file.endsWith(".jpg") || file.endsWith(".png") || file.endsWith(".gif");
}

function isUBenzerUrl(url) {
  return url.startsWith("/deepo/") || url.startsWith("http://www.ubenzer.com/") ||
    url.startsWith("https://www.ubenzer.com") || url.startsWith("//www.ubenzer.com") ||
    url.startsWith("http://ubenzer.com/") ||
    url.startsWith("https://ubenzer.com") || url.startsWith("//ubenzer.com");
}

function normalizeUBenzerUrl(url, isTarget) {
  // if this is an image, we don't give a shit about small versions
  url = url.replace(/-\d+x\d+\.(jpg|png|gif|JPG|PNG|GIF)$/, '.$1');
  url = url.replace(".thumbnail", "");

  if (!isTarget) { return url; }

  if (url.endsWith("/")) {
    url = url.slice(0, -1);
  }
  let urlParts = url.split("/");
  let fileName = urlParts[urlParts.length - 1].toLowerCase();
  return fileName;
}
<commit_msg>Convert to new firebase schema with security rules<commit_after>"use strict";
let firebase = require("firebase");
firebase.initializeApp({
  databaseURL: "https://ubenzer.firebaseio.com/",
  serviceAccount: "firebase-key.json"
});

// As an admin, the app has access to read and write all data, regardless of Security Rules
let db = firebase.database();
let allComments = db.ref("comments/byPost");
let allPosts = db.ref("posts");
allComments.set({});
allPosts.set({});

let xml2js = require("xml2js");
let fs = require("fs-extra");
let path = require("path");
let toMarkdown = require("to-markdown");
let shortcode = require("shortcode-parser");
let eol = require("eol");
let httpreq = require("httpreq");
let Batch = require("batch");

shortcode.add("php", function(buf) {
  return "```php\n" + buf + "\n```";
});
shortcode.add("c", function(buf) {
  return "```c\n" + buf + "\n```";
});
shortcode.add("java", function(buf) {
  return "```java\n" + buf + "\n```";
});
shortcode.add("caption", function(buf, opts) {
  if (opts.caption) {
    return opts.caption + "\n" + buf;
  }
  return buf;
});

let downloadedFiles = new Set();
let batch = new Batch;
batch.concurrency(30);

//fs.emptyDirSync("./out/posts");

let idLookup = {};
let parser = new xml2js.Parser();
let data = fs.readFileSync("/Users/ub/Downloads/ubenzerumutbenzerodakim.wordpress.2016-06-12.xml");
parser.parseString(data, function (err, result) {
  if (err) {
    console.log("Error parsing xml: " + err);
  }
  console.log("Parsed XML");
  var posts = result.rss.channel[0].item;
  posts.forEach(createIdLookup);
  posts.forEach(processPost);
});

batch.on("progress", function(e) {
  console.log(`${e.percent}% - ${e.complete} of ${e.total}`);
});
batch.end(function() {
  console.log(`Batch jobs done!`);
  process.exit(0);
});

function isPostValid(post) {
  if (post["wp:status"][0] !== "publish") {
    return false;
  }
  if (post["wp:post_type"][0] !== "post") {
    return false;
  }
  return true;
}
function createIdLookup(post) {
  if (!isPostValid(post)) { return; }

  var slug = post["wp:post_name"][0];
  var postDate = new Date(post.pubDate[0]);
  var id = postDate.getFullYear() + "/" + getPaddedNumber(postDate.getMonth() + 1) + "/" + slug;

  idLookup[slug] = id;
}

function processPost(post) {
  if (!isPostValid(post)) { return; }

  var postTitle = post.title;

  console.log("Processing Post: " + postTitle);

  var postDate = new Date(post.pubDate[0]);
  var postData = post["content:encoded"][0];
  var slug = post["wp:post_name"][0];
  var categories = [];
  var id = postDate.getFullYear() + "/" + getPaddedNumber(postDate.getMonth() + 1) + "/" + slug;

  // process post comments
  registerPost(id);
  let comments = post["wp:comment"];
  if (comments instanceof Array) {
    comments.forEach((comment) => {
      uploadComment(id, comment);
    });
  }

  // end comments

  post.category.forEach(function(categoryBlob) {
    var cat = categoryBlob._;
    if (categoryBlob.$.domain !== "category") {
      return;
    }
    if (cat === "İlişkiler" || cat === "Kişisel" || cat === "Markalar" || cat == "Türkçe") {
      cat = "Hayat/" +  cat;
    } else if (cat === "Scala" || cat === "PHP" || cat === "JAVA" || cat == "ANSI C" || cat == ".NET") {
      cat = "Bilgisayar/Programlama/" +  cat;
    } else if (cat === "Windows" || cat === "Programlama" || cat === "Bilmuh’çular için" ||
        cat === "İnternet" || cat === "Linux" || cat === "Mac" || cat === "Bilgisayar Oyunları" ||
        cat === "Android") {
      cat = "Bilgisayar/" +  cat;
    } else if (cat === "Minecraft") {
      cat = "Bilgisayar/Bilgisayar Oyunları/" +  cat;
    }
    categories.push(cat);
  });

  var fullPath = "./out/posts/" + postDate.getFullYear() + "/" + getPaddedNumber(postDate.getMonth() + 1) + "/" + slug;
  fs.ensureDirSync(fullPath);

  // Convert two new lines to paragraphs
  postData = eol.lf(postData);
  postData = postData.split("");
  postData = postData.join("
---more---
");
  postData = postData.split("\n\n");
  postData = postData.map(function(aData) {
    return `<p>${aData}</p>`;
  });
  postData = postData.join("\n");

  var markdown = null;
  try {
    markdown = toMarkdown(postData, {
      converters: [
        {
          filter: function (node) {
            return node.nodeName === 'A' && node.getAttribute('href');
          },
          replacement: function(content, node) {
            let href = node.getAttribute('href');
            let isTargetBlank = node.getAttribute('target') === "_blank";

            if (isUBenzerUrl(href)) {
              let source = normalizeUBenzerUrl(href);
              let target = normalizeUBenzerUrl(href, true);
              let downloadPath = fullPath + "/" + target;

              if (isFileImage(target)) {
                downloadFile(source, downloadPath);
                if (node.querySelectorAll("*").length === 1 && node.querySelectorAll("img").length === 1) {
                  let imgSrc = node.querySelectorAll("img")[0].getAttribute("src");
                  if (isUBenzerUrl(imgSrc)) {
                    imgSrc = normalizeUBenzerUrl(imgSrc, true);
                    if (imgSrc === target) {
                      let title = "";
                      if (node.querySelectorAll("img")[0].getAttribute("title")) {
                        title = node.querySelectorAll("img")[0].getAttribute("title");
                      } else if (node.querySelectorAll("img")[0].getAttribute("alt")) {
                        title = node.querySelectorAll("img")[0].getAttribute("alt");
                      } else {
                        title = postTitle;
                      }
                      return `![${title}](${target}){link${isTargetBlank?',new':''}}`;
                    }
                  }
                }
                return `[${content}](${target})${isTargetBlank?'{new}':''}`;
              } else if (path.extname(target) !== "") {
                downloadFile(source, downloadPath);
                return `[${content}](${target})${isTargetBlank?'{new}':''}`;
              } else {
                // this is an internal link
                if (!idLookup[target]) {
                  throw new Error("NOT FOUND INTERNAL LINK: " + href);
                }
                return `[${content}](@${idLookup[target]})${isTargetBlank?'{new}':''}`;
              }
            }
            return `[${content}](${href})${isTargetBlank?'{new}':''}`;
          }
        },
        {
          filter: 'img',
          replacement: function(innerHtml, node) {
            let src = node.getAttribute("src");
            if (!src) { throw new Error("IMG WITHOUT SRC!"); }
            let title = "";
            if (node.getAttribute("title")) {
              title = node.getAttribute("title");
            } else if (node.getAttribute("alt")) {
              title = node.getAttribute("alt");
            } else {
              title = postTitle;
            }

            if (src === "https://go.microsoft.com/fwlink/?LinkId=161376") {
              return "";
            }

            var targetSrc = src;
            if (isUBenzerUrl(src)) {
              let source = normalizeUBenzerUrl(src);
              let target = normalizeUBenzerUrl(src, true);

              let downloadPath = fullPath + "/" + target;
              downloadFile(source, downloadPath);
              targetSrc = target;
            }

            let classes = [];
            if (node.classList.contains("alignright")) {
              classes.push("right");
            } else if (node.classList.contains("alignleft")) {
              classes.push("left");
            } else if (node.classList.contains("aligncenter")) {
              classes.push("center");
            }

            let text = `![${title}](${targetSrc})`;
            if (classes.length > 0) {
              text = `${text}{${classes.join(",")}}`;
            }
            console.log(text);
            return text;
          }
        },
        {
          filter: 'strong',
          replacement: function(innerHtml) {
            return `*${innerHtml}*`;
          }
        }
      ]
    });
  } catch(e) {
    console.error(postData);
    throw e;
  }

  markdown = shortcode.parse(markdown);

  markdown = "# " + postTitle + "\n\n" + markdown;

  var header = "";
  header += "---\n";
  header += "created: " + postDate.getFullYear() + "-" + getPaddedNumber(postDate.getMonth() + 1) + "-" + getPaddedNumber(postDate.getDate()) + "\n";
  if (categories.length > 0) {
    header += "category:\n";
    categories.forEach(function(category) {
      header += "  - " + category + "\n";
    });
  }

  header += "---\n";

  fs.outputFile(fullPath + "/index.md", header + markdown, function(err) {
    if(err !== null) {
      console.error("Error writing post " + postTitle + " to disk!");
      throw err;
    }
  });
}

function downloadFile(url, path) {
  return
  if (url.startsWith("/deepo/")) {
    url = "http://www.ubenzer.com" + url;
  }
  if (downloadedFiles.has(url+path)) { return; }
  downloadedFiles.add(url+path);
  batch.push(function(done){
    console.log(`Downloading ${url} to ${path}...`);
    httpreq.download(url, path,
        function (err, progress) {},
        function (err){
          if (err) {
            console.log("FAILED DOWNLOAD :" + url, err);
          }
          done();
        });
  });
}

function registerPost(id) {
  id = replaceAll(id, "/", "___");
  batch.push(function(done) {
    allPosts.child(id).set({
      commentsEnabled: true,
      commentsVisible:true
    }, function (error) {
      if (error) {
        console.error(error);
        throw new Error(error);
      }
      done();
    });
  });
}
function uploadComment(id, comment) {
  id = replaceAll(id, "/", "___");
  batch.push(function(done) {
    let postCommentsRef = allComments.child(id);
    postCommentsRef.push({
      date: +new Date(comment["wp:comment_date_gmt"][0]),
      isDeleted: false,
      isPublished: true,
      name: comment["wp:comment_author"][0],
      text: comment["wp:comment_content"][0],
      userId: "$legacy"
    }, function (error) {
      if (error) {
        console.error(error);
        throw new Error(error);
      }
      done();
    });
  });
}

function getPaddedNumber(num) {
  if (num < 10) {
    return "0" + num;
  }
  return num;
}

function isFileImage(file) {
  file = file.toLowerCase();
  return file.endsWith(".jpg") || file.endsWith(".png") || file.endsWith(".gif");
}

function isUBenzerUrl(url) {
  return url.startsWith("/deepo/") || url.startsWith("http://www.ubenzer.com/") ||
    url.startsWith("https://www.ubenzer.com") || url.startsWith("//www.ubenzer.com") ||
    url.startsWith("http://ubenzer.com/") ||
    url.startsWith("https://ubenzer.com") || url.startsWith("//ubenzer.com");
}

function normalizeUBenzerUrl(url, isTarget) {
  // if this is an image, we don't give a shit about small versions
  url = url.replace(/-\d+x\d+\.(jpg|png|gif|JPG|PNG|GIF)$/, '.$1');
  url = url.replace(".thumbnail", "");

  if (!isTarget) { return url; }

  if (url.endsWith("/")) {
    url = url.slice(0, -1);
  }
  let urlParts = url.split("/");
  let fileName = urlParts[urlParts.length - 1].toLowerCase();
  return fileName;
}

function replaceAll(str, what, withWhat) {
  return str.replace(new RegExp(what, 'g'), withWhat);
}
<|endoftext|>


<commit_before>import Immutable from 'immutable';
import React, { createElement } from 'react';
import { Field } from 'redux-form';
import Locale from '../i18n/en';

/**
 * Renderer for a react-redux (v6) form via an Immutable JSON Schema
 *
 * Basic HTML is generated; Style yourself!
 */
export default class Renderer {

  constructor (options) {
    if (typeof options !== Immutable.Map) {
      options = new Immutable.Map(options);
    }
    this.options = new Immutable.Map({
      path: [],
      locale: new Locale()
    }).mergeDeep(options);
  }

  renderObject = (schema, path, data) => {
    let chunkPromises = [];
    data = data || {};

    if (!schema.get('properties')) {
      if (schema.get('allOf') || schema.get('extends')) {
        return <fieldset key={path} />;
      }
      if (schema.get('oneOf')) {
        return this.renderOneOf(schema, path, data);
      }
      if (schema.get('$ref')) {
        return this.getRef(schema.get('$ref')).then((subSchema) => {
          if (subSchema.get('properties')) {
            return this.renderObject(subSchema, path, data);
          } else {
            return this.renderChunk(path, subSchema, data);
          }
        });
      }

      if (schema.get('type') && schema.get('type') === 'array' && schema.get('items')) {
        chunkPromises.push(this.renderChunk(path, schema, data));
      }
    }

    let container = {
      key: path,
      disabled: schema.get('disabled'),
      children: []
    };

    if (schema.get('title')) {
      container.children.push(createElement('legend', {
        className: 'legend', children: [schema.get('title')]
      }));
    }

    if (schema.get('description')) {
      container.children.push(createElement('p', {
        children: [schema.get('description')]
      }));
    }

    schema.get('properties').map((propSchema, propName) => {
      if (schema.get('required') && schema.get('required').findEntry && schema.get('required').findEntry((prop) => {
        return prop === propName;
      })) {
        if (propSchema.get('type') !== 'object') {
          propSchema = propSchema.set('required', true);
        }
      }

      path.slice(0);
      path.push(propName);
      container.children.push(this.renderChunk(path, propSchema/*, data.get(propName)*/));
    });

    return createElement('fieldset', container);
  };

  /**
   * @TODO klevera
   *
   * @param {Object} schema
   * @param {Array} path
   * @param {Object} data
   *
   * @returns {*}
   */
  renderOneOf (schema, path, data) {
    const propName = path.pop();
    // const name = 'root' + (path.length ? '[' + path.join('][') + ']' : '') + '[' + propName + ']';
    const id = (path.length ? path.join('-') + '-' : '') + propName;

    path.push(propName);

    let classNames = ['schema-property', 'schema-property-oneOf'];
    if (this.options.get('groupClass') && schema.get('type') !== 'object') {
      classNames.push(this.options.get('groupClass'));
    }

    let container = {
      className: classNames.join(' '),
      children: []
    };

    const me = this;
    let realPath = path.concat([]);

    container.children.push(this.renderChunk(path, new Immutable.Map({
      'type': 'string',
      'title': schema.get('title'),
      'name': propName,
      'enum': schema.get('oneOf').map((subSchema) => {
        return subSchema.get('title');
      }),
      'onChange': (event) => {
        let state = {};
        state[id + 'selected'] = event.target.value;
        me.setState(state);
      }
    }), data));

    // render each enum as block
    container.children = container.children.concat(schema.get('oneOf').map(function (subSchema, idx) {
      if (me.getState() && me.getState()[id + 'selected'] === subSchema.get('title')) {
        return me.renderChunk(realPath.concat(), subSchema.delete('title'), data);
      }
      // subSchema = subSchema.delete('title').set('disabled', false);
      // if (subSchema.get('disabled')) {
      //   return null;
      // }
      return null;
    }));

    return createElement('div', container);
  }

  /**
   * @param {Array} path
   * @param {Object} schema
   * @param {*} value
   */
  renderChunk = (path, schema, value) => {
    let propName = path.pop();
    let className = propName;
    if (!isNaN(parseInt(propName, 10))) {
      // singular class name from assumed multiple
      className = path[path.length - 1].slice(0, -1);
    }
    let id = 'root-' + (path.length ? path.join('-') + '-' : '') + propName;

    let classNames = ['schema-property', 'schema-property-' + className, 'schema-datatype-' + schema.get('type')];
    if (this.options.get('groupClass') && schema.get('type') !== 'object' && schema.get('type') !== 'array') {
      classNames.push(this.options.get('groupClass'));
    }

    let subPath = path.slice(0);
    let name = 'root' + (path.length ? '[' + path.join('][') + ']' : '') + '[' + propName + ']';
    subPath.push(propName);

    if ((value === undefined) && (schema.get('default') !== undefined)) {
      value = schema.get('default');
    }

    if (schema.get('renderer') === 'hidden') {
      return this.renderInput('hidden', schema, subPath, value, id, name);
    }

    let container = {className: classNames.join(' '), children: [], key: id};

    switch (schema.get('type')) {
      case undefined: // complex type
      case 'object':
        container.children.push(this.renderObject(schema, subPath, value));
        break;

      case 'array':
        container.children.push(this.renderArray(schema, subPath, id, name, value));
        break;

      default:

        if (this.options.get('hasLabels') || this.options.get('hasLabels') === undefined) {
          container.children.push(this.renderLabel(schema, subPath, id));
        }

        container.children.push(this.renderType(schema, subPath, value, id, name));
        break;
    }

    return createElement('div', container);
  };

  renderArray = (schema, path, id, name, value) => {
    // multiple select
    if (schema.get('items').get('enum')) {
      return this.renderChunk(path, schema.get('items').set('title', schema.get('title')), value);
    }

    // TODO other array
    let container = {
      children: []
    };
    if (schema.get('title')) {
      container.children.push(createElement('div', {
        className: 'legend'
      }));
    }
    return createElement('fieldset', container);
  };

  renderLabel = (schema, path, id) => {
    return createElement('label', {
      className: this.options.get('labelClass'),
      htmlFor: id,
      key: id + '-label',
      children: [
        (schema.get('title') ? schema.get('title') : schema.get('description')) +
        (this.options.get('showRequired') ? (schema.get('required') ? ' *' : '') : '')]
    });
  };

  renderType = (schema, subPath, value, id, name) => {
    if (schema.get('enum')) {
      return this.renderEnum(schema, subPath, value, id, name);
    }

    let type = 'text';

    // could not be a string (array of types is allowed). .in this case wew render a "string" input
    if (typeof schema.get('type') !== 'string') {
      schema = schema.set('type', 'string');
    }

    switch (schema.get('type')) {
      case 'string':
        if (schema.get('format') === 'date') {
          type = 'date';
        }
        if (schema.get('format') === 'datetime') {
          type = 'datetime-local';
        }
        if (schema.get('format') === 'email') {
          type = 'email';
        }
        if (schema.get('renderer') === 'textarea') {
          type = 'textarea';
        }
        if (schema.get('renderer') === 'password') {
          type = 'password';
        }
        break;
      case 'integer':
      case 'number':
        type = 'number';
        break;
      case 'boolean':
        type = 'checkbox';
        break;
      default:
        throw new Error('Schema item "' + subPath.join('.') + '" is not valid');
    }
    if (schema.get('renderer') === 'display') {
      type = 'display';
    }
    return this.renderInput(type, schema, subPath, value, id, name);
  };

  renderInput = (type, schema, path, value, id, name) => {
    let component = this.renderInputComponent;
    if (type === 'textarea') {
      component = this.renderTextareaComponent;
    }
    if (type === 'hidden') {
      component = 'input';
    }
    if (type === 'display') {
      component = this.renderDisplayComponent;
    }

    let cfg = {
      key: id + '-input',
      component: component,
      id: id,
      type: type,
      name: name,
      required: schema.get('required') ? 'required' : '',
      minLength: schema.get('minLength'),
      maxLength: schema.get('maxLength'),
      min: schema.get('min'),
      max: schema.get('max'),
      pattern: schema.get('pattern'),
      placeholder: schema.get('description') || schema.get('title'),
      autoComplete: schema.get('autocomplete')
    };

    if (schema.get('renderer') === 'multiselect') {
      cfg.multiselect = true;
    }

    /*
     Since iOS 5, type="email" has auto-capitalization disabled automatically, so you simply need:

     <input type="email">
     For other input types, there are attributes available that do what they say:

     <input type="text" autocorrect="off" autocapitalize="none">
     If for some reason you want to support iOS prior to version 5, use this for type="email":

     <input type="email" autocorrect="off" autocapitalize="none">

     */
    if (type === 'email') {
      cfg.autoCapitalize = 'none';
      cfg.autoCorrect = 'off';
    }

    return createElement(Field, cfg);
  };

  renderEnum = (schema, path, value, id, name) => {
    if (schema.get('renderer') === 'radiogroup') {
      return this.renderBooleanEnum(schema, path, value, id, name);
    }

    let cfg = {
      component: this.renderSelectComponent,
      key: id + '-input',
      name: name,
      id: id,
      required: schema.get('required') ? 'required' : '',
      multiple: schema.get('multiple'),
      pattern: schema.get('pattern'),
      placeholder: schema.get('description'),
      autoComplete: schema.get('autocomplete'),
      onChange: schema.get('onChange'),
      children: schema.get('enum').map((value, idx) => {
        return createElement('option', {
          key: value + idx,
          value: value,
          children: [
            schema.get('enum_titles') &&
            schema.get('enum_titles').get(idx) ? schema.get('enum_titles').get(idx) : value
          ]
        });
      })
    };

    return createElement(Field, cfg);
  };

  renderBooleanEnum = (schema, path, value, id, name) => {
    return createElement('div', {
      className: 'radiogroup ' + this.options.get('inputWrapperClass'),
      children: schema.get('enum').map((itemValue, idx) => {
        return createElement('label', {
          key: idx + itemValue,
          className: this.options.get('radioGroupInlineClass'),
          children: [
            createElement(Field, {
              key: name + itemValue,
              component: this.renderInputComponent,
              id: id + '-' + idx,
              type: 'radio',
              name: name,
              required: schema.get('required') ? 'required' : '',
              autoComplete: schema.get('autocomplete'),
              value: itemValue
            }),
            schema.get('enum_titles') &&
            schema.get('enum_titles').get(idx) ? schema.get('enum_titles').get(idx) : itemValue
          ]
        });
      })
    });
  };

  renderDisplayComponent = (field) => {
    return this.renderFieldComponent('div', field);
  };

  renderSelectComponent = (field) => {
    return this.renderFieldComponent('select', field);
  };

  renderTextareaComponent = (field) => {
    return this.renderFieldComponent('textarea', field);
  };

  renderInputComponent = (field) => {
    return this.renderFieldComponent('input', field);
  };

  renderFieldComponent = (type, field) => {
    if (field.type === 'radio') {
      return this.renderFieldInputComponent(type, field);
    }

    let children = [
      this.renderFieldInputComponent(type, field),
      // <small class="form-text text-muted">Example help text that remains unchanged.</small>
      field.meta.touched && field.meta.error ? createElement('div', {
        className: 'form-control-feedback', children: [
          this.options.get('locale') ? this.options.get('locale').getString(field.meta.error) : field.meta.error
        ]
      }) : null
    ];

    let cfg = {
      className: this.options.get('inputWrapperClass'),
      key: field.id + '-wrapper',
      children: field.type === 'checkbox' ? createElement('div', {
        className: 'checkbox',
        children: children
      }) : children
    };

    if (field.meta.touched) {
      cfg.className += ' ' + this.options.get(field.meta.error ? 'groupErrorClass' : 'groupSuccessClass');
    }

    return createElement('div', cfg);
  };

  renderFieldInputComponent (type, field) {
    if (type === 'div') {
      return createElement(type, {
        className: this.options.get('inputClass') + ' form-control-display',
        children: [field.input.value]
      });
    }

    return createElement(type, {
      className: (['checkbox', 'radio'].indexOf(field.type) !== -1 ? '' : this.options.get('inputClass')) +
      (field.meta.touched ? ' ' + this.options.get(field.meta.error ? 'inputErrorClass' : 'inputSuccessClass') : ''),
      ... field,
      ... field.input
    });
  }

}
<commit_msg>added array renderer<commit_after>import Immutable from 'immutable';
import React, { createElement } from 'react';
import { Field } from 'redux-form';
import Locale from '../i18n/en';

/**
 * Renderer for a react-redux (v6) form via an Immutable JSON Schema
 *
 * Basic HTML is generated; Style yourself!
 */
export default class Renderer {

  constructor (options) {
    if (typeof options !== Immutable.Map) {
      options = new Immutable.Map(options);
    }
    this.options = new Immutable.Map({
      path: [],
      locale: new Locale()
    }).mergeDeep(options);
  }

  renderObject = (schema, path, data) => {
    let chunkPromises = [];
    data = data || {};

    if (!schema.get('properties')) {
      if (schema.get('allOf') || schema.get('extends')) {
        return <fieldset key={path} />;
      }
      if (schema.get('oneOf')) {
        return this.renderOneOf(schema, path, data);
      }
      if (schema.get('$ref')) {
        return this.getRef(schema.get('$ref')).then((subSchema) => {
          if (subSchema.get('properties')) {
            return this.renderObject(subSchema, path, data);
          } else {
            return this.renderChunk(path, subSchema, data);
          }
        });
      }

      if (schema.get('type') && schema.get('type') === 'array' && schema.get('items')) {
        chunkPromises.push(this.renderChunk(path, schema, data));
      }
    }

    let container = {
      key: path,
      disabled: schema.get('disabled'),
      children: []
    };

    if (schema.get('title')) {
      container.children.push(createElement('legend', {
        className: 'legend', children: [schema.get('title')]
      }));
    }

    if (schema.get('description')) {
      container.children.push(createElement('p', {
        children: [schema.get('description')]
      }));
    }

    if (schema.get('properties')) {
      schema.get('properties').map((propSchema, propName) => {
        if (schema.get('required') && schema.get('required').findEntry && schema.get('required').findEntry((prop) => {
          return prop === propName;
        })) {
          if (propSchema.get('type') !== 'object') {
            propSchema = propSchema.set('required', true);
          }
        }

        path.slice(0);
        path.push(propName);
        container.children.push(this.renderChunk(path, propSchema/*, data.get(propName)*/));
      });
    }

    return createElement('fieldset', container);
  };

  /**
   * @TODO klevera
   *
   * @param {Object} schema
   * @param {Array} path
   * @param {Object} data
   *
   * @returns {*}
   */
  renderOneOf (schema, path, data) {
    const propName = path.pop();
    // const name = 'root' + (path.length ? '[' + path.join('][') + ']' : '') + '[' + propName + ']';
    const id = (path.length ? path.join('-') + '-' : '') + propName;

    path.push(propName);

    let classNames = ['schema-property', 'schema-property-oneOf'];
    if (this.options.get('groupClass') && schema.get('type') !== 'object') {
      classNames.push(this.options.get('groupClass'));
    }

    let container = {
      className: classNames.join(' '),
      children: []
    };

    const me = this;
    let realPath = path.concat([]);

    container.children.push(this.renderChunk(path, new Immutable.Map({
      'type': 'string',
      'title': schema.get('title'),
      'name': propName,
      'enum': schema.get('oneOf').map((subSchema) => {
        return subSchema.get('title');
      }),
      'onChange': (event) => {
        let state = {};
        state[id + 'selected'] = event.target.value;
        me.setState(state);
      }
    }), data));

    // render each enum as block
    container.children = container.children.concat(schema.get('oneOf').map(function (subSchema, idx) {
      if (me.getState() && me.getState()[id + 'selected'] === subSchema.get('title')) {
        return me.renderChunk(realPath.concat(), subSchema.delete('title'), data);
      }
      // subSchema = subSchema.delete('title').set('disabled', false);
      // if (subSchema.get('disabled')) {
      //   return null;
      // }
      return null;
    }));

    return createElement('div', container);
  }

  /**
   * @param {Array} path
   * @param {Object} schema
   * @param {*} value
   */
  renderChunk = (path, schema, value) => {
    let propName = path.pop();
    let className = propName;
    if (!isNaN(parseInt(propName, 10))) {
      // singular class name from assumed multiple
      className = path[path.length - 1].slice(0, -1);
    }
    let id = 'root-' + (path.length ? path.join('-') + '-' : '') + propName;

    let classNames = ['schema-property', 'schema-property-' + className, 'schema-datatype-' + schema.get('type')];
    if (this.options.get('groupClass') && schema.get('type') !== 'object' && schema.get('type') !== 'array') {
      classNames.push(this.options.get('groupClass'));
    }

    let subPath = path.slice(0);
    let name = 'root' + (path.length ? '[' + path.join('][') + ']' : '') + '[' + propName + ']';
    subPath.push(propName);

    if ((value === undefined) && (schema.get('default') !== undefined)) {
      value = schema.get('default');
    }

    if (schema.get('renderer') === 'hidden') {
      return this.renderInput('hidden', schema, subPath, value, id, name);
    }

    let container = {className: classNames.join(' '), children: [], key: id};

    switch (schema.get('type')) {
      case undefined: // complex type
      case 'object':
        container.children.push(this.renderObject(schema, subPath, value));
        break;

      case 'array':
        container.children.push(this.renderArray(schema, subPath, id, name, value));
        break;

      default:

        if (this.options.get('hasLabels') || this.options.get('hasLabels') === undefined) {
          container.children.push(this.renderLabel(schema, subPath, id));
        }

        container.children.push(this.renderType(schema, subPath, value, id, name));
        break;
    }

    return createElement('div', container);
  };

  renderArray = (schema, path, id, name, value) => {
    // multiple select
    if (schema.get('items').get('enum')) {
      return this.renderChunk(path, schema.get('items').set('title', schema.get('title')), value);
    }

    // TODO other array
    let container = {
      children: []
    };
    if (schema.get('title')) {
      container.children.push(createElement('div', {
        className: 'legend'
      }));
    }
    return createElement('fieldset', container);
  };

  renderLabel = (schema, path, id) => {
    return createElement('label', {
      className: this.options.get('labelClass'),
      htmlFor: id,
      key: id + '-label',
      children: [
        (schema.get('title') ? schema.get('title') : schema.get('description')) +
        (this.options.get('showRequired') ? (schema.get('required') ? ' *' : '') : '')]
    });
  };

  renderType = (schema, subPath, value, id, name) => {
    if (schema.get('enum')) {
      return this.renderEnum(schema, subPath, value, id, name);
    }

    let type = 'text';

    // could not be a string (array of types is allowed). .in this case wew render a "string" input
    if (typeof schema.get('type') !== 'string') {
      schema = schema.set('type', 'string');
    }

    switch (schema.get('type')) {
      case 'string':
        if (schema.get('format') === 'date') {
          type = 'date';
        }
        if (schema.get('format') === 'datetime') {
          type = 'datetime-local';
        }
        if (schema.get('format') === 'email') {
          type = 'email';
        }
        if (schema.get('renderer') === 'textarea') {
          type = 'textarea';
        }
        if (schema.get('renderer') === 'password') {
          type = 'password';
        }
        break;
      case 'integer':
      case 'number':
        type = 'number';
        break;
      case 'boolean':
        type = 'checkbox';
        break;
      default:
        throw new Error('Schema item "' + subPath.join('.') + '" is not valid');
    }
    if (schema.get('renderer') === 'display') {
      type = 'display';
    }
    return this.renderInput(type, schema, subPath, value, id, name);
  };

  renderInput = (type, schema, path, value, id, name) => {
    let component = this.renderInputComponent;
    if (type === 'textarea') {
      component = this.renderTextareaComponent;
    }
    if (type === 'hidden') {
      component = 'input';
    }
    if (type === 'display') {
      component = this.renderDisplayComponent;
    }

    let cfg = {
      key: id + '-input',
      component: component,
      id: id,
      type: type,
      name: name,
      required: schema.get('required') ? 'required' : '',
      minLength: schema.get('minLength'),
      maxLength: schema.get('maxLength'),
      min: schema.get('min'),
      max: schema.get('max'),
      pattern: schema.get('pattern'),
      placeholder: schema.get('description') || schema.get('title'),
      autoComplete: schema.get('autocomplete')
    };

    if (schema.get('renderer') === 'multiselect') {
      cfg.multiselect = true;
    }

    /*
     Since iOS 5, type="email" has auto-capitalization disabled automatically, so you simply need:

     <input type="email">
     For other input types, there are attributes available that do what they say:

     <input type="text" autocorrect="off" autocapitalize="none">
     If for some reason you want to support iOS prior to version 5, use this for type="email":

     <input type="email" autocorrect="off" autocapitalize="none">

     */
    if (type === 'email') {
      cfg.autoCapitalize = 'none';
      cfg.autoCorrect = 'off';
    }

    return createElement(Field, cfg);
  };

  renderEnum = (schema, path, value, id, name) => {
    if (schema.get('renderer') === 'radiogroup') {
      return this.renderBooleanEnum(schema, path, value, id, name);
    }

    let cfg = {
      component: this.renderSelectComponent,
      key: id + '-input',
      name: name,
      id: id,
      required: schema.get('required') ? 'required' : '',
      multiple: schema.get('multiple'),
      pattern: schema.get('pattern'),
      placeholder: schema.get('description'),
      autoComplete: schema.get('autocomplete'),
      onChange: schema.get('onChange'),
      children: schema.get('enum').map((value, idx) => {
        return createElement('option', {
          key: value + idx,
          value: value,
          children: [
            schema.get('enum_titles') &&
            schema.get('enum_titles').get(idx) ? schema.get('enum_titles').get(idx) : value
          ]
        });
      })
    };

    return createElement(Field, cfg);
  };

  renderBooleanEnum = (schema, path, value, id, name) => {
    return createElement('div', {
      className: 'radiogroup ' + this.options.get('inputWrapperClass'),
      children: schema.get('enum').map((itemValue, idx) => {
        return createElement('label', {
          key: idx + itemValue,
          className: this.options.get('radioGroupInlineClass'),
          children: [
            createElement(Field, {
              key: name + itemValue,
              component: this.renderInputComponent,
              id: id + '-' + idx,
              type: 'radio',
              name: name,
              required: schema.get('required') ? 'required' : '',
              autoComplete: schema.get('autocomplete'),
              value: itemValue
            }),
            schema.get('enum_titles') &&
            schema.get('enum_titles').get(idx) ? schema.get('enum_titles').get(idx) : itemValue
          ]
        });
      })
    });
  };

  renderDisplayComponent = (field) => {
    return this.renderFieldComponent('div', field);
  };

  renderSelectComponent = (field) => {
    return this.renderFieldComponent('select', field);
  };

  renderTextareaComponent = (field) => {
    return this.renderFieldComponent('textarea', field);
  };

  renderInputComponent = (field) => {
    return this.renderFieldComponent('input', field);
  };

  renderFieldComponent = (type, field) => {
    if (field.type === 'radio') {
      return this.renderFieldInputComponent(type, field);
    }

    let children = [
      this.renderFieldInputComponent(type, field),
      // <small class="form-text text-muted">Example help text that remains unchanged.</small>
      field.meta.touched && field.meta.error ? createElement('div', {
        className: 'form-control-feedback', children: [
          this.options.get('locale') ? this.options.get('locale').getString(field.meta.error) : field.meta.error
        ]
      }) : null
    ];

    let cfg = {
      className: this.options.get('inputWrapperClass'),
      key: field.id + '-wrapper',
      children: field.type === 'checkbox' ? createElement('div', {
        className: 'checkbox',
        children: children
      }) : children
    };

    if (field.meta.touched) {
      cfg.className += ' ' + this.options.get(field.meta.error ? 'groupErrorClass' : 'groupSuccessClass');
    }

    return createElement('div', cfg);
  };

  renderFieldInputComponent (type, field) {
    if (type === 'div') {
      return createElement(type, {
        className: this.options.get('inputStaticClass'),
        children: [field.input.value]
      });
    }

    return createElement(type, {
      className: (['checkbox', 'radio'].indexOf(field.type) !== -1 ? '' : this.options.get('inputClass')) +
      (field.meta.touched ? ' ' + this.options.get(field.meta.error ? 'inputErrorClass' : 'inputSuccessClass') : ''),
      ... field,
      ... field.input
    });
  }

}
<|endoftext|>


<commit_before>(function () {
  var h = require('virtual-dom/h');
  var _ = {
    forEach: require('lodash.foreach')
  };

  function constructor(property, configService, configValue, disabled) {
    var options = [];
    values = property.values.replace(/\[|\]|\"|\s/g, '').split(',');
    _.forEach(values, function (value) {
      var selected = value == configValue;

      var item = h('option', {
        value   : value,
        selected: selected
      }, value === 'null' ? '' : value);
      options.push(item);
    });

    return h('div.form-item', [
      h('div.form-item__label', h('label', {
        title     : property.description,
        'ev-click': function (e) {
          if(!disabled) {
            e.target.parentNode.parentNode.querySelector('select').focus();
          }
        }
      }, [property.title])),
      h('div.form-item__input', h('select', {
        disabled  : disabled,
        'ev-change': function (e) {
          if (e.target.value === 'null') {
            configService.removeValue(property.fullname);
          } else {
            configService.setValue(property.fullname, e.target.value);
          }
        }
      }, options))
    ]);
  }

  module.exports = constructor;
})();
<commit_msg>fix for properties where the defaults-value isn't in the values array e.g. { name: "plotOptions-series--step", fullname: "plotOptions.series.step", title: "step", parent: "plotOptions-series", isParent: false, returnType: "String", defaults: "false", values: "["left", "center", "right"]", since: "1.2.5", description: "Whether to apply steps to the line. Possible values are left, center and right. Prior to 2.3.5, only left was supported.", demo: "Different step line options. Stepped, stacked area.", deprecated: false },<commit_after>(function () {
  var h = require('virtual-dom/h');
  var _ = {
    forEach: require('lodash.foreach')
  };

  function constructor(property, configService, configValue, disabled) {
    var options = [];
    values = property.values.replace(/\[|\]|\"|\s/g, '').split(',');

      if(values.indexOf(property.defaults) == -1 && values.indexOf('') == -1 && values.indexOf('null') == -1){
         values.unshift(property.defaults);
      }
    _.forEach(values, function (value) {
      var selected = value == configValue;

      var item = h('option', {
        value   : value === 'false' ? '' : value,
        selected: selected
      }, value === 'null' ? '' : value);
      options.push(item);
    });

    return h('div.form-item', [
      h('div.form-item__label', h('label', {
        title     : property.description,
        'ev-click': function (e) {
          if(!disabled) {
            e.target.parentNode.parentNode.querySelector('select').focus();
          }
        }
      }, [property.title])),
      h('div.form-item__input', h('select', {
        disabled  : disabled,
        'ev-change': function (e) {
          if (e.target.value === 'null') {
            configService.removeValue(property.fullname);
          } else {
            configService.setValue(property.fullname, e.target.value);
          }
        }
      }, options))
    ]);
  }

  module.exports = constructor;
})();<|endoftext|>


<commit_before>if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
        navigator.serviceWorker
      .register('pwa-worker.js')
      .then(reg => {
          console.log('Service worker registered.', reg);
      })
      .catch(err => {
          console.log(err);
      });
    });
}
<commit_msg>fix(pwa) remove window.load event handler for pwa registrator<commit_after>if ('serviceWorker' in navigator) {
    navigator.serviceWorker
        .register('pwa-worker.js')
        .then(reg => {
            console.log('Service worker registered.', reg);
        })
        .catch(err => {
            console.log(err);
        });
}
<|endoftext|>