<commit_before>#!/usr/bin/env node

/*
 * Copyright 2014 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of fiware-iotagent-lib
 *
 * fiware-iotagent-lib is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * fiware-iotagent-lib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with fiware-iotagent-lib.
 * If not, seehttp://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::[contacto@tid.es]
 */

var config = require('../config'),
    clUtils = require('../lib/commandLineUtils'),
    lwm2mClient = require('../').client,
    async = require('async'),
    globalDeviceInfo,
    separator = '\n\n\t';

function printObject(result) {
    var resourceIds = Object.keys(result.attributes);
    console.log('\nObject:\n--------------------------------\nObjectType: %s\nObjectId: %s\nObjectUri: %s',
        result.objectType, result.objectId, result.objectUri);

    if (resourceIds.length > 0) {
        console.log('\nAttributes:');
        for (var i=0; i < resourceIds.length; i++) {
            console.log('\t-> %s: %s', resourceIds[i], result.attributes[resourceIds[i]]);
        }
        console.log('\n');
    }
}

function handleObjectFunction(error, result) {
    if (error) {
        clUtils.handleError(error);
    } else {
        printObject(result);
    }
}

function create(command) {
    lwm2mClient.registry.create(command[0], handleObjectFunction);
}

function get(command) {
    lwm2mClient.registry.get(command[0], handleObjectFunction);
}

function remove(command) {
    lwm2mClient.registry.remove(command[0], handleObjectFunction);
}

function set(command) {
    lwm2mClient.registry.setResource(command[0], command[1], command[2], handleObjectFunction);
}

function unset(command) {
    lwm2mClient.registry.unsetResource(command[0], command[1], handleObjectFunction);
}

function list() {
    lwm2mClient.registry.list(function(error, objList) {
        if (error){
            clUtils.handleError(error);
        } else {
            console.log('\nList:\n--------------------------------\n');
            for (var i=0; i < objList.length; i++) {
                console.log('\t-> ObjURI: %s / Obj Type: %s / Obj ID: %s / Resource Num: %d',
                    objList[i].objectUri, objList[i].objectType, objList[i].objectId,
                    Object.keys(objList[i].attributes).length);
            }
        }
    });
}

function handleWrite(objectType, objectId, resourceId, value, callback) {
    console.log('\Value written:\n--------------------------------\n');
    console.log('-> ObjectType: %s', objectType);
    console.log('-> ObjectId: %s', objectId);
    console.log('-> ResourceId: %s', resourceId);
    console.log('-> Written value: %s', value);
    clUtils.prompt();

    callback(null);
}

function handleRead(objectType, objectId, resourceId, value, callback) {
    console.log('\Value read:\n--------------------------------\n');
    console.log('-> ObjectType: %s', objectType);
    console.log('-> ObjectId: %s', objectId);
    console.log('-> ResourceId: %s', resourceId);
    console.log('-> Read Value: %s', value);
    clUtils.prompt();

    callback(null);
}

function setHandlers(deviceInfo) {
    lwm2mClient.setHandler(deviceInfo.serverInfo, 'write', handleWrite);
    lwm2mClient.setHandler(deviceInfo.serverInfo, 'read', handleRead);
}

function connect(command) {
    console.log('\nConnecting to the server. This may take a while.\n');
    lwm2mClient.register(command[0], command[1], command[3], command[2], function (error, deviceInfo) {
        if (error) {
            clUtils.handleError(error);
        } else {
            globalDeviceInfo = deviceInfo;
            setHandlers(deviceInfo);
            console.log('\nConnected:\n--------------------------------\nDevice location: %s', deviceInfo.location);
            clUtils.prompt();
        }
    });
}

var commands = {
    'create': {
        parameters: ['objectUri'],
        description: '\tCreate a new object. The object is specified using the /type/id OMA notation.',
        handler: create
    },
    'get': {
        parameters: ['objectUri'],
        description: '\tGet all the information on the selected object.',
        handler: get
    },
    'remove': {
        parameters: ['objectUri'],
        description: '\tRemove an object. The object is specified using the /type/id OMA notation.',
        handler: remove
    },
    'set': {
        parameters: ['objectUri', 'resourceId', 'resourceValue'],
        description: '\tSet the value for a resource. If the resource does not exist, it is created.',
        handler: set
    },
    'unset': {
        parameters: ['objectUri', 'resourceId'],
        description: '\tRemoves a resource from the selected object.',
        handler: unset
    },
    'list': {
        parameters: [],
        description: '\tList all the available objects along with its resource names and values.',
        handler: list
    },
    'connect': {
        parameters: ['host', 'port', 'endpointName', 'url'],
        description: '\tConnect to the server in the selected host and port, using the selected endpointName. An ' +
        'optional url can be specified',
        handler: connect
    },
    'updateConnection': {
        parameters: [],
        description: '\tUpdates the current connection to a server.',
        handler: clUtils.notImplemented
    },
    'disconnect': {
        parameters: [],
        description: '\tDisconnect from the current server.',
        handler: clUtils.notImplemented
    },
    'config': {
        parameters: [],
        description: '\tPrint the current config.',
        handler: clUtils.showConfig(config, 'client')
    }
};

clUtils.initialize(commands, '\033[36mLWM2M-Client> \033[0m');<commit_msg>FIX Root path<commit_after>#!/usr/bin/env node

/*
 * Copyright 2014 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of fiware-iotagent-lib
 *
 * fiware-iotagent-lib is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * fiware-iotagent-lib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with fiware-iotagent-lib.
 * If not, seehttp://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::[contacto@tid.es]
 */

var config = require('../config'),
    clUtils = require('../lib/commandLineUtils'),
    lwm2mClient = require('../').client,
    async = require('async'),
    globalDeviceInfo,
    separator = '\n\n\t';

function printObject(result) {
    var resourceIds = Object.keys(result.attributes);
    console.log('\nObject:\n--------------------------------\nObjectType: %s\nObjectId: %s\nObjectUri: %s',
        result.objectType, result.objectId, result.objectUri);

    if (resourceIds.length > 0) {
        console.log('\nAttributes:');
        for (var i=0; i < resourceIds.length; i++) {
            console.log('\t-> %s: %s', resourceIds[i], result.attributes[resourceIds[i]]);
        }
        console.log('\n');
    }
}

function handleObjectFunction(error, result) {
    if (error) {
        clUtils.handleError(error);
    } else {
        printObject(result);
    }
}

function create(command) {
    lwm2mClient.registry.create(command[0], handleObjectFunction);
}

function get(command) {
    lwm2mClient.registry.get(command[0], handleObjectFunction);
}

function remove(command) {
    lwm2mClient.registry.remove(command[0], handleObjectFunction);
}

function set(command) {
    lwm2mClient.registry.setResource(command[0], command[1], command[2], handleObjectFunction);
}

function unset(command) {
    lwm2mClient.registry.unsetResource(command[0], command[1], handleObjectFunction);
}

function list() {
    lwm2mClient.registry.list(function(error, objList) {
        if (error){
            clUtils.handleError(error);
        } else {
            console.log('\nList:\n--------------------------------\n');
            for (var i=0; i < objList.length; i++) {
                console.log('\t-> ObjURI: %s / Obj Type: %s / Obj ID: %s / Resource Num: %d',
                    objList[i].objectUri, objList[i].objectType, objList[i].objectId,
                    Object.keys(objList[i].attributes).length);
            }
        }
    });
}

function handleWrite(objectType, objectId, resourceId, value, callback) {
    console.log('\Value written:\n--------------------------------\n');
    console.log('-> ObjectType: %s', objectType);
    console.log('-> ObjectId: %s', objectId);
    console.log('-> ResourceId: %s', resourceId);
    console.log('-> Written value: %s', value);
    clUtils.prompt();

    callback(null);
}

function handleRead(objectType, objectId, resourceId, value, callback) {
    console.log('\Value read:\n--------------------------------\n');
    console.log('-> ObjectType: %s', objectType);
    console.log('-> ObjectId: %s', objectId);
    console.log('-> ResourceId: %s', resourceId);
    console.log('-> Read Value: %s', value);
    clUtils.prompt();

    callback(null);
}

function setHandlers(deviceInfo) {
    lwm2mClient.setHandler(deviceInfo.serverInfo, 'write', handleWrite);
    lwm2mClient.setHandler(deviceInfo.serverInfo, 'read', handleRead);
}

function connect(command) {
    var url;

    console.log('\nConnecting to the server. This may take a while.\n');

    if (command[2] === '/') {
        url = command[2];
    }

    lwm2mClient.register(command[0], command[1], command[3], command[2], function (error, deviceInfo) {
        if (error) {
            clUtils.handleError(error);
        } else {
            globalDeviceInfo = deviceInfo;
            setHandlers(deviceInfo);
            console.log('\nConnected:\n--------------------------------\nDevice location: %s', deviceInfo.location);
            clUtils.prompt();
        }
    });
}

var commands = {
    'create': {
        parameters: ['objectUri'],
        description: '\tCreate a new object. The object is specified using the /type/id OMA notation.',
        handler: create
    },
    'get': {
        parameters: ['objectUri'],
        description: '\tGet all the information on the selected object.',
        handler: get
    },
    'remove': {
        parameters: ['objectUri'],
        description: '\tRemove an object. The object is specified using the /type/id OMA notation.',
        handler: remove
    },
    'set': {
        parameters: ['objectUri', 'resourceId', 'resourceValue'],
        description: '\tSet the value for a resource. If the resource does not exist, it is created.',
        handler: set
    },
    'unset': {
        parameters: ['objectUri', 'resourceId'],
        description: '\tRemoves a resource from the selected object.',
        handler: unset
    },
    'list': {
        parameters: [],
        description: '\tList all the available objects along with its resource names and values.',
        handler: list
    },
    'connect': {
        parameters: ['host', 'port', 'endpointName', 'url'],
        description: '\tConnect to the server in the selected host and port, using the selected endpointName.',
        handler: connect
    },
    'updateConnection': {
        parameters: [],
        description: '\tUpdates the current connection to a server.',
        handler: clUtils.notImplemented
    },
    'disconnect': {
        parameters: [],
        description: '\tDisconnect from the current server.',
        handler: clUtils.notImplemented
    },
    'config': {
        parameters: [],
        description: '\tPrint the current config.',
        handler: clUtils.showConfig(config, 'client')
    }
};

clUtils.initialize(commands, '\033[36mLWM2M-Client> \033[0m');<|endoftext|>


<commit_before>Package.describe({
  name: 'pauli:accounts-linkedin',
  summary: "Login service for LinkedIn accounts",
  version: "1.5.0",
  git: "https://github.com/PoBuchi/meteor-accounts-linkedin.git"
});

Package.onUse(function(api) {
  api.versionsFrom('1.4.3.1')

  api.use('accounts-base', ['client', 'server']);
  api.imply('accounts-base', ['client', 'server']);

  api.use('accounts-oauth', ['client', 'server']);
  api.use('pauli:linkedin-oauth@1.0.0', ['client', 'server']);

  api.imply('pauli:linkedin-oauth');

  // If users use accounts-ui but not facebook-config-ui, give them a tip.
  api.use(['accounts-ui', 'pauli:linkedin-config-ui'], ['client', 'server'], { weak: true });
  api.addFiles("notice.js");

  api.addFiles("linkedin.js");
});<commit_msg>v2.0.0<commit_after>Package.describe({
  name: 'pauli:accounts-linkedin',
  summary: "Login service for LinkedIn accounts",
  version: "2.0.0",
  git: "https://github.com/PoBuchi/meteor-accounts-linkedin.git"
});

Package.onUse(function(api) {
  api.versionsFrom('1.4.3.1')

  api.use('accounts-base', ['client', 'server']);
  api.imply('accounts-base', ['client', 'server']);

  api.use('accounts-oauth', ['client', 'server']);
  api.use('pauli:linkedin-oauth@1.0.0', ['client', 'server']);

  api.imply('pauli:linkedin-oauth');

  // If users use accounts-ui but not facebook-config-ui, give them a tip.
  api.use(['accounts-ui', 'pauli:linkedin-config-ui'], ['client', 'server'], { weak: true });
  api.addFiles("notice.js");

  api.addFiles("linkedin.js");
});<|endoftext|>


<commit_before>$(function() {

  var studyRegex = /\.org\/study\/(?:embed\/)?(\w{8})\/(\w{8})\b/;
  var gameRegex = /\.org\/(?:embed\/)?(\w{8})(?:(?:\/(white|black))|\w{4}|)\b/;
  var notGames = ['training'];
  var wait = 100;

  var parseUrl = function(url) {
    var matches = url.match(studyRegex);
    if (matches && matches[2]) return {
      type: 'study',
      src: '/study/embed/' + matches[1] + '/' + matches[2]
    };
    var matches = url.match(gameRegex);
    if (matches && matches[1] && notGames.indexOf(matches[1]) === -1) {
      var src = '/embed/' + matches[1];
      if (matches[2]) src += '/' + matches[2];
      return {
        type: 'game',
        src: src
      };
    }
  };

  var expand = function(as) {
    var a = as.shift();
    if (!a) return;
    var src = a.getAttribute('data-src');
    var type = a.getAttribute('data-type');
    console.log(a, src, type);
    if (src) {
      var $iframe = $('<iframe>').addClass('analyse ' + type).attr('src', src);
      $(a).replaceWith($iframe);
      $iframe.on('load', function() {
        if (this.contentDocument.title.indexOf("404") >= 0)
          this.style.height = '100px';
      }).on('mouseenter', function() {
        $(this).focus();
      });
      wait = Math.min(2000, wait *= 2);
      setTimeout(function() {
        expand(as);
      }, wait);
    } else expand(as);
  };

  // detect study links and convert them to iframes
  expand($('div.embed_analyse a').filter(function() {
    var parsed = parseUrl(this.href);
    if (!parsed) return false;
    this.setAttribute('data-src', parsed.src);
    this.setAttribute('data-type', parsed.type);
    return true;
  }).addClass('embedding_analyse').html(lichess.spinnerHtml).toArray());
});

lichess.startEmbeddedAnalyse = function(opts) {
  opts.socketSend = $.noop
  opts.initialPly = 'url';
  LichessAnalyse(opts);

  var board = opts.element.querySelector('.cg-board-wrap');
  var ground = opts.element.querySelector('.lichess_ground');

  var onResize = function() {
    var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
    var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
    var boardSize = h - 26;
    var gr = 1.618;
    if (boardSize > w / gr) boardSize = w / gr;
    var groundSize = Math.min(500, Math.max(120, w - boardSize));
    board.style.width = boardSize + 'px';
    board.style.height = boardSize + 'px';
    ground.style.width = groundSize + 'px';
    ground.style.maxWidth = groundSize + 'px';
    document.body.dispatchEvent(new Event('chessground.resize'));
  };
  onResize();
  window.addEventListener('resize', onResize);
};
<commit_msg>to embed a study/game in the forum, have the link text == href<commit_after>$(function() {

  var studyRegex = /\.org\/study\/(?:embed\/)?(\w{8})\/(\w{8})\b/;
  var gameRegex = /\.org\/(?:embed\/)?(\w{8})(?:(?:\/(white|black))|\w{4}|)\b/;
  var notGames = ['training'];
  var wait = 100;

  var parseLink = function(a) {
    var matches = a.href.match(studyRegex);
    if (matches && matches[2] && a.text.match(studyRegex)) return {
      type: 'study',
      src: '/study/embed/' + matches[1] + '/' + matches[2]
    };
    var matches = a.href.match(gameRegex);
    if (matches && matches[1] && notGames.indexOf(matches[1]) === -1 && a.text.match(gameRegex)) {
      var src = '/embed/' + matches[1];
      if (matches[2]) src += '/' + matches[2];
      return {
        type: 'game',
        src: src
      };
    }
  };

  var expand = function(as) {
    var a = as.shift();
    if (!a) return;
    var src = a.getAttribute('data-src');
    var type = a.getAttribute('data-type');
    if (src) {
      var $iframe = $('<iframe>').addClass('analyse ' + type).attr('src', src);
      $(a).replaceWith($iframe);
      $iframe.on('load', function() {
        if (this.contentDocument.title.indexOf("404") >= 0)
          this.style.height = '100px';
      }).on('mouseenter', function() {
        $(this).focus();
      });
      wait = Math.min(2000, wait *= 2);
      setTimeout(function() {
        expand(as);
      }, wait);
    } else expand(as);
  };

  // detect study links and convert them to iframes
  expand($('div.embed_analyse a').filter(function() {
    var parsed = parseLink(this);
    if (!parsed) return false;
    this.setAttribute('data-src', parsed.src);
    this.setAttribute('data-type', parsed.type);
    return true;
  }).addClass('embedding_analyse').html(lichess.spinnerHtml).toArray());
});

lichess.startEmbeddedAnalyse = function(opts) {
  opts.socketSend = $.noop
  opts.initialPly = 'url';
  LichessAnalyse(opts);

  var board = opts.element.querySelector('.cg-board-wrap');
  var ground = opts.element.querySelector('.lichess_ground');

  var onResize = function() {
    var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
    var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
    var boardSize = h - 26;
    var gr = 1.618;
    if (boardSize > w / gr) boardSize = w / gr;
    var groundSize = Math.min(500, Math.max(120, w - boardSize));
    board.style.width = boardSize + 'px';
    board.style.height = boardSize + 'px';
    ground.style.width = groundSize + 'px';
    ground.style.maxWidth = groundSize + 'px';
    document.body.dispatchEvent(new Event('chessground.resize'));
  };
  onResize();
  window.addEventListener('resize', onResize);
};
<|endoftext|>


<commit_before>/*
 Map browser based on OpenLayers 5.
 Feature properties editor widget based on snowcode project.

 Copyright (C) 2019-2020 Øyvind Hanssen, LA7ECA, ohanssen@acm.org

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published
 by the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

pol.features = pol.features || {};

pol.features.Properties = class extends pol.core.Widget {

    constructor(dt) {
        super();
        const t = this;
        t.classname = "features.Properties";
        const features = ()=> snow.drawSource.getFeatures();
        t.selected = null; /* Feature whose metadata are edited by user */
        t.drawTool = (dt ? dt : snow.featureEdit);
        t.label = m.stream("");
        t.layerList = getWIDGET("layers.List");
        t.editor = getWIDGET("features.Edit");

        /* Show center and radius of circle (Mithril component) */
        t.circle = {
            view: function() {
                return m("div#circleInfo", [
                    m("span.field", [
                        m("span.sleftlab", "Center: "),
                        (t.center ? m("span.coord", {onclick: apply(gotoPos,t.center)}, formatPos(t.center)) : "-") ]),

                    m("span.field", [
                        m("span.sleftlab", "Radius: "),
                        m("span", t.radius ?
                            (t.radius < 1000 ? Math.round(t.radius*100)/100+" m" :
                            Math.round(t.radius/100)/10+" km") : "-") ])
                ]);
            }
        }

        /* Show list of coordinates (Mithril component) */
        t.coord = {
            view: function() {
                return m("div#colist",
                    t.colist.map( x=> {
                        return [m("span.coord", {onclick: apply(gotoPos,x)}, formatPos(x)), ", "]}));
            }
        }

        t.layers = {
            view: function(vn) {
                return m("select#"+vn.attrs.id, {onchange: ()=>t.changeHandler} , t.layerList.getLayers()
                    .filter( x => x.get("drawing") )
                    .map( x => m("option", {value: x.get("name") }, x.get("name")) ));
            }
        }

        /* Main mithril component */
        t.widget = {
            view: function() {
                let i=0;
                return m("div#features", [
                    m("h1", "Features/properties"),

                    m("table.features",
                      m("caption", "Editor features:"),
                      m("tbody", features().map( x => {
                        return m("tr", {class: (x==t.selected ? "selected" : "")}, [
                            m("td", m(removeEdit,
                                { remove: apply(remove, i), edit: apply(edit, i++) })),
                            m("td", shortType(x.getGeometry().getType())),
                            m("td", (x.label ? x.label : ""))
                        ])
                    }))),

                    ( selectedLayer() != null && selectedLayer().getSource().getFeatures().length > 0 ?
                        m("table.lfeatures", [
                          m("caption", "Layer features:"),
                          m("tbody", selectedLayer().getSource().getFeatures().map( x => {
                            return m("tr",
                                m("td", (x.label ? x.label : "(no label)"))
                            )
                        }))] ) : ""),

                    hr,

                    m("span.field", [
                        m("span.sleftlab", "Type: "),
                        m("span", (t.selected==null? "---" : t.selected.getGeometry().getType()))
                    ]),

                    m("span.field", [
                        m("span.sleftlab", "Label: "),
                        m(textInput, {id:"editLabel", size: 16, maxLength:25, value: t.label, regex: /.*$/i }),
                        m("button", {onclick: set, title: "Update properties"}, "Update")
                    ]),

                    (!t.layerList.isEmpty() ?
                        m("span.field", [
                            m("span.sleftlab", "Layer: "),
                            m(t.layers, {id:"tolayer"}),
                            m("button", {onclick: move, title: "Move feature to layer"}, "Move to"),
                            m("button", {onclick: getFrom, title: "Get features from layer for editing"}, "Get from"),
                        ]) : ""),

                    (t.radius ? m(t.circle) : (t.colist ? m(t.coord) : ""))
                ])
            },
            onupdate: checkHide

        };

        m.redraw();
        setTimeout(changeHandler, 3300);
        snow.drawSource.on("changefeature", changeHandler);

        $(document).on("selectfeature", ()=> {
            _edit(snow.lastSelected);
            changeHandler();
        } );

        snow.addDrawCB(
            e=> setTimeout(()=>changeHandler(), 100)
        );

        CONFIG.mb.map.on("change:view", ()=> setTimeout(()=> changeHandler(), 100) );

        setTimeout(checkHide, 500);

        /* Apply a function to an argument. Returns a new function */
        function apply(f, id) {return function() { f(id); }};

        function shortType(x) {
            if (x=="LineString")
                return "(LStr)";
            else if (x=="Circle")
                return "(Circ)";
            else if (x=="Polygon")
                return "(Poly)";
            else return x;
        }

        function checkHide() {
            const val = $("select#tolayer").val();
            if (val && val != null)
                $("span#tolayer").show();
            else
                $("span#tolayer").hide();
        }

        /* Zoom and show position on map */
        function gotoPos(x) {
            CONFIG.mb.gui.removePopup();
            CONFIG.mb.goto_Pos(x, false);
        }

        /* Format position (longitude, latitude) */
        function formatPos(p) {
            return "["+Math.round(p[0]*1000)/1000 + ", " +
              Math.round(p[1]*1000)/1000+"]";
        }

        /* Handler for edit icon in feature list */
        function edit(i) {
            /* Convert geometry to LatLong */
            const geom = features()[i].getGeometry().clone();
            geom.transform(CONFIG.mb.view.getProjection(), 'EPSG:4326');

            /* Zoom in to feature and allow user to edit it */
            CONFIG.mb.fitExtent(geom.getExtent());
            CONFIG.mb.view.setZoom(CONFIG.mb.view.getZoom()-1)
            _edit(features()[i]);
        }

        /* Edit it - move it into form below feature list */
        function _edit(f) {
            t.selected = f;
            t.label(t.selected.label);
            showGeom(f);
            m.redraw();
        }

        /* Show geometry of feature */
        function showGeom(f) {
            /* Convert geometry to LatLong */
            const g = f.getGeometry().clone();
            const h = g.clone();
            g.transform(CONFIG.mb.view.getProjection(), 'EPSG:4326');

            t.type = g.getType();
            t.center=NaN; t.radius=NaN; t.colist=NaN;

            if (t.type == "Polygon" || t.type == "LineString") {
                t.colist = g.getCoordinates();
                if (t.colist.length == 1)
                    t.colist = t.colist[0];
            }
            else if (t.type=="Circle") {
                t.center=g.getCenter();
                t.radius=h.getRadius();
            }
        }

        /* Remove feature */
        function remove(i) {
            if (confirm("Remove - are you sure?") == false)
                return;
            snow.deleteFeature(features()[i]);
        }

        function set() {
            t.selected.label = t.label();
            t.drawTool.doUpdate(t.selected, "chg");
        }

        function selectedLayer() {
            const name = $("select#tolayer").val();
            let x = null;
            for (x of t.layerList.getLayers())
                if (x.get("name") == name)
                        return x;
            return null;
        }

        /* Move the selected feature to the selected target layer */
        function move() {
            const x = selectedLayer();
            if (t.selected == null)
                console.warn("No feature selected");
            else if (x == null)
                console.warn("No target layer selected");
            else if (snow.drawLayer == x)
                console.warn("Source and target layers is the same")
            else {
                /* Move the feature */
                x.getSource().addFeature(t.selected);
                snow.deleteFeature(t.selected);
                t.selected.layer = x.get("name");
                const s = t.selected;
                setTimeout(()=>t.editor.doUpdate(s, "chg"), 1200);
                t.selected = null;
                t.colist = NaN;
                t.radius = NaN;
            }
        }

        /* Get features from selected target layer */
        function getFrom() {
            const x = selectedLayer();
            if (x == null)
                console.warn("No target layer selected");
            else if (snow.drawLayer == x)
                console.warn("Source and target layers is the same")
            else {
                /* Move the features */
                x.getSource().forEachFeature(
                    (f) => {
                        snow.drawSource.addFeature(f);
                        x.getSource().removeFeature(f);
                        f.layer = "DRAFT";
                        setTimeout(()=>t.editor.doUpdate(f, "chg", x.get("name")), 1200);
                        console.log("Moved feature '"+f.label+"' from '"+f.layer+"'");
                    });
            }
        }

        /* FIXME: Move this to a proper place.
         * use it when we want to show a label on the feature. Do we?
         * Keep text-style when saving/restoring feature.
         */
        function setLabel() {
            let st = (t.originalStyle ? t.originalStyle : t.selected.getStyle());
            st.getText().setText(t.selected.label);
        }

        function changeHandler() {
            console.log("CHANGE HANDLER");
            m.redraw()
        }

    } /* constructor */
} /* class */
<commit_msg>Draw tool fix<commit_after>/*
 Map browser based on OpenLayers 5.
 Feature properties editor widget based on snowcode project.

 Copyright (C) 2019-2020 Øyvind Hanssen, LA7ECA, ohanssen@acm.org

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as published
 by the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

pol.features = pol.features || {};

pol.features.Properties = class extends pol.core.Widget {

    constructor(dt) {
        super();
        const t = this;
        t.classname = "features.Properties";
        const features = ()=> snow.drawSource.getFeatures();
        t.selected = null; /* Feature whose metadata are edited by user */
        t.drawTool = (dt ? dt : snow.featureEdit);
        t.label = m.stream("");
        t.layerList = getWIDGET("layers.List");
        t.editor = getWIDGET("features.Edit");

        /* Show center and radius of circle (Mithril component) */
        t.circle = {
            view: function() {
                return m("div#circleInfo", [
                    m("span.field", [
                        m("span.sleftlab", "Center: "),
                        (t.center ? m("span.coord", {onclick: apply(gotoPos,t.center)}, formatPos(t.center)) : "-") ]),

                    m("span.field", [
                        m("span.sleftlab", "Radius: "),
                        m("span", t.radius ?
                            (t.radius < 1000 ? Math.round(t.radius*100)/100+" m" :
                            Math.round(t.radius/100)/10+" km") : "-") ])
                ]);
            }
        }

        /* Show list of coordinates (Mithril component) */
        t.coord = {
            view: function() {
                if (t.colist.length < 50)
                    return m("div#colist",
                        t.colist.map( x=> {
                            return [m("span.coord", {onclick: apply(gotoPos,x)}, formatPos(x)), ", "]}));
                else
                    return m("div#colist", "(more than 50 points)");
            }
        }

        t.layers = {
            view: function(vn) {
                return m("select#"+vn.attrs.id, {onchange: ()=>t.changeHandler} , t.layerList.getLayers()
                    .filter( x => x.get("drawing") )
                    .map( x => m("option", {value: x.get("name") }, x.get("name")) ));
            }
        }

        /* Main mithril component */
        t.widget = {
            view: function() {
                let i=0;
                return m("div#features", [
                    m("h1", "Features/properties"),

                    m("table.features",
                      m("caption", "Editor features:"),
                      m("tbody", features().map( x => {
                        return m("tr", {class: (x==t.selected ? "selected" : "")}, [
                            m("td", m(removeEdit,
                                { remove: apply(remove, i), edit: apply(edit, i++) })),
                            m("td", shortType(x.getGeometry().getType())),
                            m("td", (x.label ? x.label : ""))
                        ])
                    }))),

                    ( selectedLayer() != null && selectedLayer().getSource().getFeatures().length > 0 ?
                        m("table.lfeatures", [
                          m("caption", "Layer features:"),
                          m("tbody", selectedLayer().getSource().getFeatures().map( x => {
                            return m("tr",
                                m("td", (x.label ? x.label : "(no label)"))
                            )
                        }))] ) : ""),

                    hr,

                    m("span.field", [
                        m("span.sleftlab", "Type: "),
                        m("span", (t.selected==null? "---" : t.selected.getGeometry().getType()))
                    ]),

                    m("span.field", [
                        m("span.sleftlab", "Label: "),
                        m(textInput, {id:"editLabel", size: 16, maxLength:25, value: t.label, regex: /.*$/i }),
                        m("button", {onclick: set, title: "Update properties"}, "Update")
                    ]),

                    (!t.layerList.isEmpty() ?
                        m("span.field", [
                            m("span.sleftlab", "Layer: "),
                            m(t.layers, {id:"tolayer"}),
                            m("button", {onclick: move, title: "Move feature to layer"}, "Move to"),
                            m("button", {onclick: getFrom, title: "Get features from layer for editing"}, "Get from"),
                        ]) : ""),

                    (t.radius ? m(t.circle) : (t.colist ? m(t.coord) : ""))
                ])
            },
            onupdate: checkHide

        };

        m.redraw();
        setTimeout(changeHandler, 3300);
        snow.drawSource.on("changefeature", changeHandler);

        $(document).on("selectfeature", ()=> {
            _edit(snow.lastSelected);
            changeHandler();
        } );

        snow.addDrawCB(
            e=> setTimeout(()=>changeHandler(), 100)
        );

        CONFIG.mb.map.on("change:view", ()=> setTimeout(()=> changeHandler(), 100) );

        setTimeout(checkHide, 500);

        /* Apply a function to an argument. Returns a new function */
        function apply(f, id) {return function() { f(id); }};

        function shortType(x) {
            if (x=="LineString")
                return "(LStr)";
            else if (x=="Circle")
                return "(Circ)";
            else if (x=="Polygon")
                return "(Poly)";
            else return x;
        }

        function checkHide() {
            const val = $("select#tolayer").val();
            if (val && val != null)
                $("span#tolayer").show();
            else
                $("span#tolayer").hide();
        }

        /* Zoom and show position on map */
        function gotoPos(x) {
            CONFIG.mb.gui.removePopup();
            CONFIG.mb.goto_Pos(x, false);
        }

        /* Format position (longitude, latitude) */
        function formatPos(p) {
            return "["+Math.round(p[0]*1000)/1000 + ", " +
              Math.round(p[1]*1000)/1000+"]";
        }

        /* Handler for edit icon in feature list */
        function edit(i) {
            /* Convert geometry to LatLong */
            const geom = features()[i].getGeometry().clone();
            geom.transform(CONFIG.mb.view.getProjection(), 'EPSG:4326');

            /* Zoom in to feature and allow user to edit it */
            CONFIG.mb.fitExtent(geom.getExtent());
            CONFIG.mb.view.setZoom(CONFIG.mb.view.getZoom()-1)
            _edit(features()[i]);
        }

        /* Edit it - move it into form below feature list */
        function _edit(f) {
            t.selected = f;
            t.label(t.selected.label);
            showGeom(f);
            m.redraw();
        }

        /* Show geometry of feature */
        function showGeom(f) {
            /* Convert geometry to LatLong */
            const g = f.getGeometry().clone();
            const h = g.clone();
            g.transform(CONFIG.mb.view.getProjection(), 'EPSG:4326');

            t.type = g.getType();
            t.center=NaN; t.radius=NaN; t.colist=NaN;

            if (t.type == "Polygon" || t.type == "LineString") {
                t.colist = g.getCoordinates();
                if (t.colist.length == 1)
                    t.colist = t.colist[0];
            }
            else if (t.type=="Circle") {
                t.center=g.getCenter();
                t.radius=h.getRadius();
            }
        }

        /* Remove feature */
        function remove(i) {
            if (confirm("Remove - are you sure?") == false)
                return;
            if (t.selected == features()[i])
                clear();
            snow.deleteFeature(features()[i]);
        }

        function clear() {
            t.selected=null;
            t.label("");
            t.colist = null;
        }

        function set() {
            t.selected.label = t.label();
            t.drawTool.doUpdate(t.selected, "chg");
        }

        function selectedLayer() {
            const name = $("select#tolayer").val();
            let x = null;
            for (x of t.layerList.getLayers())
                if (x.get("name") == name)
                        return x;
            return null;
        }

        /* Move the selected feature to the selected target layer */
        function move() {
            const x = selectedLayer();
            if (t.selected == null)
                console.warn("No feature selected");
            else if (x == null)
                console.warn("No target layer selected");
            else if (snow.drawLayer == x)
                console.warn("Source and target layers is the same")
            else {
                /* Move the feature */
                x.getSource().addFeature(t.selected);
                snow.deleteFeature(t.selected);
                t.selected.layer = x.get("name");
                const s = t.selected;
                setTimeout(()=>t.editor.doUpdate(s, "chg"), 1200);
                t.selected = null;
                t.colist = NaN;
                t.radius = NaN;
            }
        }

        /* Get features from selected target layer */
        function getFrom() {
            const x = selectedLayer();
            if (x == null)
                console.warn("No target layer selected");
            else if (snow.drawLayer == x)
                console.warn("Source and target layers is the same")
            else {
                /* Move the features */
                x.getSource().forEachFeature(
                    (f) => {
                        snow.drawSource.addFeature(f);
                        x.getSource().removeFeature(f);
                        f.layer = "DRAFT";
                        setTimeout(()=>t.editor.doUpdate(f, "chg", x.get("name")), 1200);
                        console.log("Moved feature '"+f.label+"' from '"+f.layer+"'");
                    });
            }
        }

        /* FIXME: Move this to a proper place.
         * use it when we want to show a label on the feature. Do we?
         * Keep text-style when saving/restoring feature.
         */
        function setLabel() {
            let st = (t.originalStyle ? t.originalStyle : t.selected.getStyle());
            st.getText().setText(t.selected.label);
        }

        function changeHandler() {
            console.log("CHANGE HANDLER");
            m.redraw()
        }

    } /* constructor */
} /* class */
<|endoftext|>


<commit_before>// kcats - by Jensan
kcats = expand(kcats, {
	version: '0.1',
	ui: kcats.ui || {},
	debugMode: false,
	module: {
		definition: null,		// A function defining the module
		instance: null			// Instantiated module (from definition above)
	},
	keyboard: {
		history: new kcats.types.history(),
		buffer: new kcats.types.stack(),		// Input buffer
		caret: {
			symbol: '░',		// Graphics used for the blinking caret
			delay: 250
		},
		input: {		// Functions for restricting/hindering user input
			restrictTo: null
		}
	}
});

kcats.startup = function (cfg) {
	var cfg = expand(cfg, {
		src: null		// Auto-load this module (external javascript file)
	});
	kcats.bindUI();
	kcats.defineBuiltins();
	if (cfg.src !== null) {
		kcats.loadModule(cfg.src);
	}
};

kcats.bindUI = function () {
	window.addEventListener('keypress', function (ev) { kcats.handleKey(ev.keyCode); }, false);
	window.addEventListener('keydown',  kcats.handleKeyDown, false);

	kcats.ui.keyboardCaret = document.getElementsByClassName('caret')[0];
	kcats.ui.keyboardDisplay = document.getElementById('keyboardDisplay');
	kcats.ui.screen = document.getElementById('screen');

	kcats.ui.keyboardCaret.innerHTML = kcats.keyboard.caret.symbol;
	window.setInterval(kcats.toggleCaret, kcats.keyboard.caret.delay);
};

kcats.toggleCaret = function () {
	if (kcats.ui.keyboardCaret.style.visibility === '') {
		kcats.ui.keyboardCaret.style.visibility = 'hidden';
	} else {
		kcats.ui.keyboardCaret.style.visibility = '';
	}
};

kcats.handleKeyDown = function (ev) {
	// Special case handling for keys not reported by keypress
	switch (ev.keyCode) {
	case 8:
	case 38:	// up
	case 40:	// down
		kcats.handleKey(ev.keyCode);
		ev.preventDefault();
		break;
	default:
		break;
	}
};

kcats.handleKey = function (keyCode) {
	switch (keyCode) {
	case 8:
		if (!kcats.keyboard.buffer.empty()) {
			kcats.keyboard.buffer.pop();
		}
		break;

	case 13:
		kcats.eval(kcats.keyboard.buffer.toString());
		kcats.keyboard.buffer.clear();
		window.scrollBy(0, window.innerHeight);	// todo: always scroll? or detect and scroll then?
		break;

	case 38:
	{
		kcats.keyboard.buffer.clear();
		var s = kcats.keyboard.history.prev();
		for (var i=0; i < s.length; ++i) {
			kcats.keyboard.buffer.push(s.charCodeAt(i));
		}
		break;
	}

	case 40:
	{
		kcats.keyboard.buffer.clear();
		var s = kcats.keyboard.history.next();
		for (var i=0; i < s.length; ++i) {
			kcats.keyboard.buffer.push(s.charCodeAt(i));
		}
		break;
	}

	default:
		if (kcats.keyboard.input.restrictTo === null || kcats.keyboard.input.restrictTo.test(String.fromCharCode(keyCode))) {
			kcats.keyboard.buffer.push(keyCode);
		}
		break;
	}
	kcats.ui.keyboardDisplay.textContent = kcats.keyboard.buffer.toString();
};

/**
 * Prints a text to the screen.
 * @param s What to print
 * @param delay (Optional) If true, will print the characters one after another with a slight delay (default: false)
 * @param callback (Optional) Function to call upon print completion
 */
kcats.print = function (s, delay, callback) {
	if (typeof s === 'undefined') {
		return;
	}
	var delay = delay || false;
	var divNode = document.createElement('div');
	var textNode = document.createTextNode(s);
	var index = 0;
	var slowPrint = function () {
		if (s.charAt(index) === '\n') {
			kcats.print(s.substring(++index), delay, callback);
			return;
		}
		textNode.nodeValue += s.charAt(index);
		++index;
		if (index < s.length) {
			window.setTimeout(slowPrint, Math.ceil(Math.random() * 25));
		} else if (typeof callback !== 'undefined') {
			callback();
		}
	};
	if (delay) {
		textNode.nodeValue = '';
	}
	divNode.appendChild(textNode);
	kcats.ui.screen.appendChild(divNode);
	if (delay) {
		slowPrint();
	}
};

kcats.newLine = function () {
	var divNode = document.createElement('div');
	divNode.appendChild(document.createTextNode('\u00A0'));
	kcats.ui.screen.appendChild(divNode);
};

kcats.debugPrint = function (s) {
	if (kcats.debugMode) {
		kcats.print('??? ' + s);
	}
};

kcats.keyboard.buffer.toString = function () {
	return String.fromCharCode.apply(null, this.toArrayList());
};

kcats.defineModule = function (fn) {
	var instance = new fn();
	kcats.debugPrint('Defining module ' + instance.name);
	// Validate module configuration
	var req = ['name', 'startup', 'eval'];
	for (var k in Object.keys(req)) {
		if (typeof instance[req[k]] === 'undefined') {
			kcats.print('!!! Module error: missing "' + req[k] + '"');
			return false;
		}
	}
	document.getElementsByTagName('head')[0].getElementsByTagName('title')[0].textContent = instance.name;
	kcats.module.definition = fn;
	kcats.module.instance = instance;
	instance.startup();
};

kcats.eval = function (text) {
	kcats.keyboard.history.push(text);
	kcats.print(text);
	if (text.startsWith('_')) {
		// built-in always starts with _
		kcats.evalBuiltin(text);
	} else {
		if (kcats.module.instance !== null) {
			kcats.print(kcats.module.instance.eval(text));
		} else {
			kcats.print('!!!  No module loaded');
		}
	}
};

kcats.evalBuiltin = function (text) {
	// Built-ins are functions meant to examine the "computer", loading modules, etc.
	// They do not belong to any module, and are always present.
	var p = text.split(' ');
	if (kcats.builtin.hasOwnProperty(p[0])) {
		kcats.builtin[p[0]].apply(null, p.splice(1));
	} else {
		kcats.print('!!! Unknown builtin command');
	}
};
<commit_msg>Comment<commit_after>// kcats - by Jensan
kcats = expand(kcats, {
	version: '0.1',
	ui: kcats.ui || {},
	debugMode: false,
	module: {
		definition: null,		// A function defining the module
		instance: null			// Instantiated module (from definition above)
	},
	keyboard: {
		history: new kcats.types.history(),
		buffer: new kcats.types.stack(),		// Input buffer
		caret: {
			symbol: '░',		// Graphics used for the blinking caret
			delay: 250
		},
		input: {		// Functions for restricting/hindering user input
			restrictTo: null		// Expects a regular expression. If null, everything's allowed.
		}
	}
});

kcats.startup = function (cfg) {
	var cfg = expand(cfg, {
		src: null		// Auto-load this module (external javascript file)
	});
	kcats.bindUI();
	kcats.defineBuiltins();
	if (cfg.src !== null) {
		kcats.loadModule(cfg.src);
	}
};

kcats.bindUI = function () {
	window.addEventListener('keypress', function (ev) { kcats.handleKey(ev.keyCode); }, false);
	window.addEventListener('keydown',  kcats.handleKeyDown, false);

	kcats.ui.keyboardCaret = document.getElementsByClassName('caret')[0];
	kcats.ui.keyboardDisplay = document.getElementById('keyboardDisplay');
	kcats.ui.screen = document.getElementById('screen');

	kcats.ui.keyboardCaret.innerHTML = kcats.keyboard.caret.symbol;
	window.setInterval(kcats.toggleCaret, kcats.keyboard.caret.delay);
};

kcats.toggleCaret = function () {
	if (kcats.ui.keyboardCaret.style.visibility === '') {
		kcats.ui.keyboardCaret.style.visibility = 'hidden';
	} else {
		kcats.ui.keyboardCaret.style.visibility = '';
	}
};

kcats.handleKeyDown = function (ev) {
	// Special case handling for keys not reported by keypress
	switch (ev.keyCode) {
	case 8:
	case 38:	// up
	case 40:	// down
		kcats.handleKey(ev.keyCode);
		ev.preventDefault();
		break;
	default:
		break;
	}
};

kcats.handleKey = function (keyCode) {
	switch (keyCode) {
	case 8:
		if (!kcats.keyboard.buffer.empty()) {
			kcats.keyboard.buffer.pop();
		}
		break;

	case 13:
		kcats.eval(kcats.keyboard.buffer.toString());
		kcats.keyboard.buffer.clear();
		window.scrollBy(0, window.innerHeight);	// todo: always scroll? or detect and scroll then?
		break;

	case 38:
	{
		kcats.keyboard.buffer.clear();
		var s = kcats.keyboard.history.prev();
		for (var i=0; i < s.length; ++i) {
			kcats.keyboard.buffer.push(s.charCodeAt(i));
		}
		break;
	}

	case 40:
	{
		kcats.keyboard.buffer.clear();
		var s = kcats.keyboard.history.next();
		for (var i=0; i < s.length; ++i) {
			kcats.keyboard.buffer.push(s.charCodeAt(i));
		}
		break;
	}

	default:
		if (kcats.keyboard.input.restrictTo === null || kcats.keyboard.input.restrictTo.test(String.fromCharCode(keyCode))) {
			kcats.keyboard.buffer.push(keyCode);
		}
		break;
	}
	kcats.ui.keyboardDisplay.textContent = kcats.keyboard.buffer.toString();
};

/**
 * Prints a text to the screen.
 * @param s What to print
 * @param delay (Optional) If true, will print the characters one after another with a slight delay (default: false)
 * @param callback (Optional) Function to call upon print completion
 */
kcats.print = function (s, delay, callback) {
	if (typeof s === 'undefined') {
		return;
	}
	var delay = delay || false;
	var divNode = document.createElement('div');
	var textNode = document.createTextNode(s);
	var index = 0;
	var slowPrint = function () {
		if (s.charAt(index) === '\n') {
			kcats.print(s.substring(++index), delay, callback);
			return;
		}
		textNode.nodeValue += s.charAt(index);
		++index;
		if (index < s.length) {
			window.setTimeout(slowPrint, Math.ceil(Math.random() * 25));
		} else if (typeof callback !== 'undefined') {
			callback();
		}
	};
	if (delay) {
		textNode.nodeValue = '';
	}
	divNode.appendChild(textNode);
	kcats.ui.screen.appendChild(divNode);
	if (delay) {
		slowPrint();
	}
};

kcats.newLine = function () {
	var divNode = document.createElement('div');
	divNode.appendChild(document.createTextNode('\u00A0'));
	kcats.ui.screen.appendChild(divNode);
};

kcats.debugPrint = function (s) {
	if (kcats.debugMode) {
		kcats.print('??? ' + s);
	}
};

kcats.keyboard.buffer.toString = function () {
	return String.fromCharCode.apply(null, this.toArrayList());
};

kcats.defineModule = function (fn) {
	var instance = new fn();
	kcats.debugPrint('Defining module ' + instance.name);
	// Validate module configuration
	var req = ['name', 'startup', 'eval'];
	for (var k in Object.keys(req)) {
		if (typeof instance[req[k]] === 'undefined') {
			kcats.print('!!! Module error: missing "' + req[k] + '"');
			return false;
		}
	}
	document.getElementsByTagName('head')[0].getElementsByTagName('title')[0].textContent = instance.name;
	kcats.module.definition = fn;
	kcats.module.instance = instance;
	instance.startup();
};

kcats.eval = function (text) {
	kcats.keyboard.history.push(text);
	kcats.print(text);
	if (text.startsWith('_')) {
		// built-in always starts with _
		kcats.evalBuiltin(text);
	} else {
		if (kcats.module.instance !== null) {
			kcats.print(kcats.module.instance.eval(text));
		} else {
			kcats.print('!!!  No module loaded');
		}
	}
};

kcats.evalBuiltin = function (text) {
	// Built-ins are functions meant to examine the "computer", loading modules, etc.
	// They do not belong to any module, and are always present.
	var p = text.split(' ');
	if (kcats.builtin.hasOwnProperty(p[0])) {
		kcats.builtin[p[0]].apply(null, p.splice(1));
	} else {
		kcats.print('!!! Unknown builtin command');
	}
};
<|endoftext|>


<commit_before>(function () {
    'use strict';

    var mongoose    = require('mongoose'),
        idsPlugin   = require('./plugins/idsPlugin'),

        PostSchema  = mongoose.Schema({
            // # Content properties
            slug: { type: String, trim: true, lowercase: true },
            title: { type: String, trim: true },
            content: String,
            markdown: String,
            teaser: String,
            labels: { type: [String] },

            author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },

            // # Metadata
            metaDescription: String,

            // # Dates
            createdAt: { type: Date, required: true, default: Date.now },
            updatedAt: { type: Date, required: true, default: Date.now },
            publishedAt: Date,

            // # Additional properties
            geo: { type: [Number] },
            published: { type: Boolean, required: true, default: false },
            page: { type: Boolean, default: false },
            featured: { type: Boolean, default: false },

            commentsCount: { type: Number, default: 0 },

            // # Post edition options
            slugOpt: { type: Boolean, default: false },
            scheduleOpt: { type: Boolean, default: false },

            // # Counters
            counter: {
                view: { type: Number, default: 0 },
                edit: { type: Number, default: 0 }
            }
        });

    PostSchema.plugin(idsPlugin);

    PostSchema.path('slug').index({ unique: true, sparse: true });
    PostSchema.path('publishedAt').index(true);

    module.exports = mongoose.model('Post', PostSchema);

})();<commit_msg>Fields update<commit_after>(function () {
    'use strict';

    var mongoose    = require('mongoose'),
        idsPlugin   = require('./plugins/idsPlugin'),

        PostSchema  = mongoose.Schema({
            // # Content properties
            slug: { type: String, trim: true, lowercase: true },
            title: { type: String, trim: true },
            content: String,
            markdown: String,
            teaser: String,
            labels: { type: [String] },

            author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },

            // # Metadata
            metaDescription: String,

            // # Dates
            createdAt: { type: Date, required: true, default: Date.now },
            updatedAt: { type: Date, required: true, default: Date.now },
            publishedAt: { type: Date, default: null },
            scheduledAt: Date,

            // # Additional properties
            geo: { type: [Number] },
            page: { type: Boolean, default: false },
            featured: { type: Boolean, default: false },

            commentsCount: { type: Number, default: 0 },

            // # Post edition options
            slugOpt: { type: Boolean, default: false },
            scheduleOpt: { type: Boolean, default: false },

            // # Counters
            counter: {
                view: { type: Number, default: 0 },
                edit: { type: Number, default: 0 }
            }
        });

    PostSchema.plugin(idsPlugin);

    PostSchema.path('slug').index({ unique: true, sparse: true });
    PostSchema.path('publishedAt').index(true);

    module.exports = mongoose.model('Post', PostSchema);

})();<|endoftext|>


<commit_before>const React = require('react');
const ReactDOM = require('react-dom');
const classnames = require('classnames');
const types = React.PropTypes;

class Pipeline extends React.Component {
  static propTypes = {
    pipelineName: types.string.isRequired,
    pipelineStatus: types.string.isRequired,
    currentlyRunning: types.bool.isRequired
  };

  render() {
    const {pipelineName, pipelineStatus, currentlyRunning} = this.props;
    const classes = classnames('pipeline', pipelineStatus);
    return (

        <BlinkingLight pipelineStatus={pipelineStatus} currentlyRunning={currentlyRunning} /><FlapRow text={pipelineName} />

    );
  }
}

class FlapRow extends React.Component {
  static propTypes = {
    text: types.string.isRequired
  };

  render() {
    const {text} = this.props;
    return(

      <FlapDigits {...{text}}/>

);
  };
}

class BlinkingLight extends React.Component {
  static propTypes = {
    currentlyRunning: types.string.isRequired,
    pipelineStatus: types.string.isRequired
  };

  render() {
    const {currentlyRunning, pipelineStatus} = this.props;

    const containerClasses = classnames("blinking-light", "ring-container", pipelineStatus);

    var ringClass = "";
    if (currentlyRunning === true) {
      ringClass = "ringring"
    }

    return(

    );
  };
}

class FlapDigits extends React.Component {
  static propTypes = {
    text: types.string.isRequired
  };

  componentDidMount() {
    const node = ReactDOM.findDOMNode(this);
    const flapperOptions = {
      width: 30,
      align: 'left',
      timing: 100
    };
    this.flapper = $(node).flapper(flapperOptions);
  };

  componentWillReceiveProps(newProps) {
    const {text} = newProps;
    this.flapper.val(text).change();
  };

  render() {
    return(
);
  }
}

module.exports = Pipeline;
<commit_msg>Change type of currentlyRunning to bool<commit_after>const React = require('react');
const ReactDOM = require('react-dom');
const classnames = require('classnames');
const types = React.PropTypes;

class Pipeline extends React.Component {
  static propTypes = {
    pipelineName: types.string.isRequired,
    pipelineStatus: types.string.isRequired,
    currentlyRunning: types.bool.isRequired
  };

  render() {
    const {pipelineName, pipelineStatus, currentlyRunning} = this.props;
    const classes = classnames('pipeline', pipelineStatus);
    return (

        <BlinkingLight pipelineStatus={pipelineStatus} currentlyRunning={currentlyRunning} /><FlapRow text={pipelineName} />

    );
  }
}

class FlapRow extends React.Component {
  static propTypes = {
    text: types.string.isRequired
  };

  render() {
    const {text} = this.props;
    return(

      <FlapDigits {...{text}}/>

);
  };
}

class BlinkingLight extends React.Component {
  static propTypes = {
    currentlyRunning: types.bool.isRequired,
    pipelineStatus: types.string.isRequired
  };

  render() {
    const {currentlyRunning, pipelineStatus} = this.props;

    const containerClasses = classnames("blinking-light", "ring-container", pipelineStatus);

    var ringClass = "";
    if (currentlyRunning === true) {
      ringClass = "ringring"
    }

    return(

    );
  };
}

class FlapDigits extends React.Component {
  static propTypes = {
    text: types.string.isRequired
  };

  componentDidMount() {
    const node = ReactDOM.findDOMNode(this);
    const flapperOptions = {
      width: 30,
      align: 'left',
      timing: 100
    };
    this.flapper = $(node).flapper(flapperOptions);
  };

  componentWillReceiveProps(newProps) {
    const {text} = newProps;
    this.flapper.val(text).change();
  };

  render() {
    return(
);
  }
}

module.exports = Pipeline;
<|endoftext|>


<commit_before>var pageVersion = "1.7.0";

// 2016-12-27 V 1.7.0
//  - Manage new crontab disabled state
// 2016-11-04 V 1.6.1
//   - Use cythsI18n.getLanguage() to get language on 2 characters
// 2016-11-01 V 1.6.0
//   - User can now update a crontab configuration
// 2016-10-31 V 1.5.0
//   - Detect crontab user change
// 2016-10-30 V 1.4.0
//   - Enable crontab to be modified without saving modification
// 2016-10-29 V 1.3.3
//   - Use now one line per crontab
// 2016-10-29 V 1.3.2
//   - States are displayed as jqCron
// 2016-10-28 V 1.3.1
//   - Optimize code
// 2016-10-28 V 1.3.0
//   - Add crontab translation
// 2016-10-28 V 1.2.1
//   - Crontab are padded with zero
// 2016-10-27 V 1.2.0
//   - Use cythsBeforeLocalize instead of init
//   - Localize "on" and "off" crontab states
// 2016-10-26 V 1.1.0
//   - Use jqCron library instead of cronwtf
// 2016-10-10 V 1.0.2
//   - Manage cronwtf library
// 2016-10-08 V 1.0.1
//   - Manage new crontab format
// 2016-10-06 V 1.0.0
//   - Initial release

function cythsBeforeLocalize()
{
	// Load jqCron translation
	jQuery.ajax(
	{
	    url: "../../js/jqCron/jqCron." + cythsI18n.getLanguage() + ".js",
	    dataType: 'script',
		async: false
	});

	//
	// Get JSON configuration file
	//
	$.ajax(
	{
	  url: "../../data/config.json",
	  dataType: 'json',
	  async: false,
	  cache: false,
	  success: function( root )
	  {
		var crontabsListToAdd = '';

		//
		// For each switch configured
		//
		$.each( root.switchesList , function( index , switchToDrive )
		{
			// Switch is displayed only if there is a crontab associated
			if( switchToDrive.crontab )
			{
				//
				// Compute piece of HTML to insert
				//
				crontabsListToAdd += '
';
				crontabsListToAdd += '
' + switchToDrive.label + '
';
				crontabsListToAdd += '
';

				$.each( switchToDrive.crontab , function( index , entry )
				{
					crontabsListToAdd += '
';

					// Manage state
					crontabsListToAdd += '   ';
					crontabsListToAdd += '    ';
					crontabsListToAdd += '     ';
					crontabsListToAdd += '      ' + entry.state;
					crontabsListToAdd += '      ';
					crontabsListToAdd += '     ';
					crontabsListToAdd += '
';
					crontabsListToAdd += '
on
';
					crontabsListToAdd += '
off
';
					crontabsListToAdd += '
disabled
';
					crontabsListToAdd += '
';
					crontabsListToAdd += '    ';
					crontabsListToAdd += '    ';

					// Manage jqCron
					crontabsListToAdd += '   ';
					crontabsListToAdd += '    <input value="' + entry.cron + '" class="cyths-crontab-jqcron" type="hidden"></input>';
					crontabsListToAdd += '   ';

					// Manage modified configuration
					crontabsListToAdd += '   ';
					crontabsListToAdd += '    ✔';
					crontabsListToAdd += '   ';

					crontabsListToAdd += '

';
				});

				// End of piece of HTML
				crontabsListToAdd += '
';
				crontabsListToAdd += '
';
	  		}
		});

		// Insert piece of HTML
		$( crontabsListToAdd ).insertAfter( ".row" );

		//
		// Initialize jqCron
		//
		$( '.cyths-crontab-jqcron' ).jqCron(
		{
			enabled_minute: true,
			multiple_dom: true,
			multiple_month: true,
			multiple_mins: true,
			multiple_dow: true,
			multiple_time_hours: true,
			multiple_time_minutes: true,
			default_period: 'week',
			no_reset_button: true,
			disable: false,
			numeric_zero_pad: true,
			lang: cythsI18n.getLanguage(),
			bind_method:
			{
				// User has set a value of jqCron
				set: function( $element , cron )
				{
					// Update hidden input
					$element.val( cron );

					// Get CYTHS crontab tag
					var cythsCrontab = $element.parents( ".cyths-crontab" );

					// Get current state
					var state = cythsCrontab.find( ".cyths-crontab-state span" ).attr( "crontab-state" );

					// Get cron and state configured
					var cythsCrontabConfCron  = cythsCrontab.attr( "conf-cron" );
					var cythsCrontabConfState = cythsCrontab.attr( "conf-state" );

					//
					// Hide/display update CYTHS crontab
					//
					var updateCythsCrontab = cythsCrontab.find( ".update-cyths-crontab" );
					if( cron != cythsCrontabConfCron || state != cythsCrontabConfState )	updateCythsCrontab.show();
					else																	updateCythsCrontab.hide();
				}
			}
		});

		// Display/hide available states
		$( '.cyths-crontab-state' ).click( function()
		{
			$(this).next( ".cyths-crontab-state-list" ).toggle();
		});

		// Manage selected state
		$( '.cyths-crontab-state-list li' ).click( function()
		{
			// Get selected state tag content
			var stateTagSelected = $(this).html();

			// Get selected state
			var state = $(this).children( "span" ).attr( "crontab-state" );

			// Get CYTHS crontab tag
			var cythsCrontab = $(this).parents( ".cyths-crontab" );

			// Get current jqCron
			var jqCron = cythsCrontab.find( ".cyths-crontab-jqcron" );

			// Get current jqCron instance
			var jqCronInstance = jqCron.jqCronGetInstance();

			// Enable/disable jqCron following state selected
			if( state == "disabled" )	jqCronInstance.disable();
			else 						jqCronInstance.enable();

			// Get current cron value
			var cron = jqCron.val();

			// Get cron and state configured
			var cythsCrontabConfCron = cythsCrontab.attr( "conf-cron" );
			var cythsCrontabConfState = cythsCrontab.attr( "conf-state" );

			// Update UI with state selected
			$(this).parent().prev( ".cyths-crontab-state" ).html( stateTagSelected );

			// Hide state list
			$(this).parent().hide();

			//
			// Hide/display update CYTHS crontab
			//
			var updateCythsCrontab = cythsCrontab.find( ".update-cyths-crontab" );
			if( cron != cythsCrontabConfCron || state != cythsCrontabConfState )	updateCythsCrontab.show();
			else																	updateCythsCrontab.hide();
		});

		// Manage CYTHS crontab update
		$( '.update-cyths-crontab' ).click( function()
		{
			// Get reference to current tag
			var updateCythsCrontabTag = $(this);

			// Hide tag to user
			updateCythsCrontabTag.fadeOut( 200 );

			// Get switch tag
			var switchTag = $(this).parents( "ul" ).prev( "h2" );

			// Get switch remote identifier and channel
			var rcId = switchTag.attr( "rcId" );
			var channel = switchTag.attr( "channel" );

			// Get CYTHS crontab tag
			var cythsCrontab = $(this).parents( ".cyths-crontab" );

			// Get configured cron and state
			var cythsCrontabConfCron  = cythsCrontab.attr( "conf-cron" );
			var cythsCrontabConfState = cythsCrontab.attr( "conf-state" );

			// Get user cron and state
			var userCrontabCron  = cythsCrontab.find( ".cyths-crontab-jqcron" ).val();
			var userCrontabState = cythsCrontab.find( ".cyths-crontab-state span" ).attr( "crontab-state" );

			//alert( "Feature not yet implemented.\nRemote identifier: " + rcId + "\nChannel: " + channel + "\nConfigured: " + cythsCrontabConfCron + " " + cythsCrontabConfState + "\nSelected: " + userCrontabCron + " " + userCrontabState );

			// Ask server to change crontab configuration
			$.post( '../../API/set/crontab/' ,
			{
				rcId    		: rcId,
				channel			: channel,
				currentCron		: cythsCrontabConfCron,
				currentState	: cythsCrontabConfState,
				newCron			: userCrontabCron,
				newState		: userCrontabState
			}).done(function( data )
			{
				// Get JSON object
				var response = jQuery.parseJSON( data );

				// Manage error case
				if( response.result == "error")
				{
					var msg = "ERROR\n";
					msg += response.message;

					// Display error to the user
					alert( msg );
				}
				else
				{
					// Update CYTHS crontab configuration
					// It's to detect a new change performed by user on this crontab
					cythsCrontab.attr( "conf-cron" , userCrontabCron );
					cythsCrontabConfState = cythsCrontab.attr( "conf-state" , userCrontabState );
				}

			}).fail(function(jqxhr, textStatus, error)
			{
				// Allow user to try again
				updateCythsCrontabTag.fadeIn( 0 );

				// Alert user
				alert( textStatus + ": " + error );
			});
		});
	  },
	  error: function(xhr, textStatus, error)
	  {
		  alert( textStatus + ": " + error );
	  }
	});
}

<commit_msg>Disabled state is now shown during loading phase<commit_after>var pageVersion = "1.7.1";

// 2016-12-27 V 1.7.1
//  - Disabled state is now shown during loading phase
// 2016-12-27 V 1.7.0
//  - Manage new crontab disabled state
// 2016-11-04 V 1.6.1
//   - Use cythsI18n.getLanguage() to get language on 2 characters
// 2016-11-01 V 1.6.0
//   - User can now update a crontab configuration
// 2016-10-31 V 1.5.0
//   - Detect crontab user change
// 2016-10-30 V 1.4.0
//   - Enable crontab to be modified without saving modification
// 2016-10-29 V 1.3.3
//   - Use now one line per crontab
// 2016-10-29 V 1.3.2
//   - States are displayed as jqCron
// 2016-10-28 V 1.3.1
//   - Optimize code
// 2016-10-28 V 1.3.0
//   - Add crontab translation
// 2016-10-28 V 1.2.1
//   - Crontab are padded with zero
// 2016-10-27 V 1.2.0
//   - Use cythsBeforeLocalize instead of init
//   - Localize "on" and "off" crontab states
// 2016-10-26 V 1.1.0
//   - Use jqCron library instead of cronwtf
// 2016-10-10 V 1.0.2
//   - Manage cronwtf library
// 2016-10-08 V 1.0.1
//   - Manage new crontab format
// 2016-10-06 V 1.0.0
//   - Initial release

function cythsBeforeLocalize()
{
	// Load jqCron translation
	jQuery.ajax(
	{
	    url: "../../js/jqCron/jqCron." + cythsI18n.getLanguage() + ".js",
	    dataType: 'script',
		async: false
	});

	//
	// Get JSON configuration file
	//
	$.ajax(
	{
	  url: "../../data/config.json",
	  dataType: 'json',
	  async: false,
	  cache: false,
	  success: function( root )
	  {
		var crontabsListToAdd = '';

		//
		// For each switch configured
		//
		$.each( root.switchesList , function( index , switchToDrive )
		{
			// Switch is displayed only if there is a crontab associated
			if( switchToDrive.crontab )
			{
				//
				// Compute piece of HTML to insert
				//
				crontabsListToAdd += '
';
				crontabsListToAdd += '
' + switchToDrive.label + '
';
				crontabsListToAdd += '
';

				$.each( switchToDrive.crontab , function( index , entry )
				{
					crontabsListToAdd += '
';

					// Manage state
					crontabsListToAdd += '   ';
					crontabsListToAdd += '    ';
					crontabsListToAdd += '     ';
					crontabsListToAdd += '      ' + entry.state;
					crontabsListToAdd += '      ';
					crontabsListToAdd += '     ';
					crontabsListToAdd += '
';
					crontabsListToAdd += '
on
';
					crontabsListToAdd += '
off
';
					crontabsListToAdd += '
disabled
';
					crontabsListToAdd += '
';
					crontabsListToAdd += '    ';
					crontabsListToAdd += '    ';

					// Manage jqCron
					crontabsListToAdd += '   ';
					crontabsListToAdd += '    <input value="' + entry.cron + '" class="cyths-crontab-jqcron" type="hidden"></input>';
					crontabsListToAdd += '   ';

					// Manage modified configuration
					crontabsListToAdd += '   ';
					crontabsListToAdd += '    ✔';
					crontabsListToAdd += '   ';

					crontabsListToAdd += '

';
				});

				// End of piece of HTML
				crontabsListToAdd += '
';
				crontabsListToAdd += '
';
	  		}
		});

		// Insert piece of HTML
		$( crontabsListToAdd ).insertAfter( ".row" );

		//
		// Initialize all jqCron
		//
		$( '.cyths-crontab-jqcron' ).each( function()
		{
			// Get current jqCron input field
			var jqCronInput = $(this);

			// Setup jqCron
			jqCronInput.jqCron(
			{
				enabled_minute: true,
				multiple_dom: true,
				multiple_month: true,
				multiple_mins: true,
				multiple_dow: true,
				multiple_time_hours: true,
				multiple_time_minutes: true,
				default_period: 'week',
				no_reset_button: true,
				disable: jqCronInput.parent().prev().find( 'span.cyths-crontab-state > span' ).is( '[crontab-state="disabled"]' ),
				numeric_zero_pad: true,
				lang: cythsI18n.getLanguage(),
				bind_method:
				{
					// User has set a value of jqCron
					set: function( $element , cron )
					{
						// Update hidden input
						$element.val( cron );

						// Get CYTHS crontab tag
						var cythsCrontab = $element.parents( ".cyths-crontab" );

						// Get current state
						var state = cythsCrontab.find( ".cyths-crontab-state span" ).attr( "crontab-state" );

						// Get cron and state configured
						var cythsCrontabConfCron  = cythsCrontab.attr( "conf-cron" );
						var cythsCrontabConfState = cythsCrontab.attr( "conf-state" );

						//
						// Hide/display update CYTHS crontab
						//
						var updateCythsCrontab = cythsCrontab.find( ".update-cyths-crontab" );
						if( cron != cythsCrontabConfCron || state != cythsCrontabConfState )	updateCythsCrontab.show();
						else																	updateCythsCrontab.hide();
					}
				}
			});
		});

		// Display/hide available states
		$( '.cyths-crontab-state' ).click( function()
		{
			$(this).next( ".cyths-crontab-state-list" ).toggle();
		});

		// Manage selected state
		$( '.cyths-crontab-state-list li' ).click( function()
		{
			// Get selected state tag content
			var stateTagSelected = $(this).html();

			// Get selected state
			var state = $(this).children( "span" ).attr( "crontab-state" );

			// Get CYTHS crontab tag
			var cythsCrontab = $(this).parents( ".cyths-crontab" );

			// Get current jqCron
			var jqCron = cythsCrontab.find( ".cyths-crontab-jqcron" );

			// Get current jqCron instance
			var jqCronInstance = jqCron.jqCronGetInstance();

			// Enable/disable jqCron following state selected
			if( state == "disabled" )	jqCronInstance.disable();
			else 						jqCronInstance.enable();

			// Get current cron value
			var cron = jqCron.val();

			// Get cron and state configured
			var cythsCrontabConfCron = cythsCrontab.attr( "conf-cron" );
			var cythsCrontabConfState = cythsCrontab.attr( "conf-state" );

			// Update UI with state selected
			$(this).parent().prev( ".cyths-crontab-state" ).html( stateTagSelected );

			// Hide state list
			$(this).parent().hide();

			//
			// Hide/display update CYTHS crontab
			//
			var updateCythsCrontab = cythsCrontab.find( ".update-cyths-crontab" );
			if( cron != cythsCrontabConfCron || state != cythsCrontabConfState )	updateCythsCrontab.show();
			else																	updateCythsCrontab.hide();
		});

		// Manage CYTHS crontab update
		$( '.update-cyths-crontab' ).click( function()
		{
			// Get reference to current tag
			var updateCythsCrontabTag = $(this);

			// Hide tag to user
			updateCythsCrontabTag.fadeOut( 200 );

			// Get switch tag
			var switchTag = $(this).parents( "ul" ).prev( "h2" );

			// Get switch remote identifier and channel
			var rcId = switchTag.attr( "rcId" );
			var channel = switchTag.attr( "channel" );

			// Get CYTHS crontab tag
			var cythsCrontab = $(this).parents( ".cyths-crontab" );

			// Get configured cron and state
			var cythsCrontabConfCron  = cythsCrontab.attr( "conf-cron" );
			var cythsCrontabConfState = cythsCrontab.attr( "conf-state" );

			// Get user cron and state
			var userCrontabCron  = cythsCrontab.find( ".cyths-crontab-jqcron" ).val();
			var userCrontabState = cythsCrontab.find( ".cyths-crontab-state span" ).attr( "crontab-state" );

			//alert( "Feature not yet implemented.\nRemote identifier: " + rcId + "\nChannel: " + channel + "\nConfigured: " + cythsCrontabConfCron + " " + cythsCrontabConfState + "\nSelected: " + userCrontabCron + " " + userCrontabState );

			// Ask server to change crontab configuration
			$.post( '../../API/set/crontab/' ,
			{
				rcId    		: rcId,
				channel			: channel,
				currentCron		: cythsCrontabConfCron,
				currentState	: cythsCrontabConfState,
				newCron			: userCrontabCron,
				newState		: userCrontabState
			}).done(function( data )
			{
				// Get JSON object
				var response = jQuery.parseJSON( data );

				// Manage error case
				if( response.result == "error")
				{
					var msg = "ERROR\n";
					msg += response.message;

					// Display error to the user
					alert( msg );
				}
				else
				{
					// Update CYTHS crontab configuration
					// It's to detect a new change performed by user on this crontab
					cythsCrontab.attr( "conf-cron" , userCrontabCron );
					cythsCrontabConfState = cythsCrontab.attr( "conf-state" , userCrontabState );
				}

			}).fail(function(jqxhr, textStatus, error)
			{
				// Allow user to try again
				updateCythsCrontabTag.fadeIn( 0 );

				// Alert user
				alert( textStatus + ": " + error );
			});
		});
	  },
	  error: function(xhr, textStatus, error)
	  {
		  alert( textStatus + ": " + error );
	  }
	});
}

<|endoftext|>


<commit_before>'use strict';
var server = require('co-request');
var co = require('co');
var images = require('./version.json')

var findLatestFrom = function*(imageName) {
  var image = imageName.split(':');
  var res = yield server.get({
    url: `https://registry.hub.docker.com/v2/repositories/${image[0]}/dockerfile/`,
    json: true
  });
  var contents = res.body.contents.split('\n');
  for(var i = 0; i < contents.length; i++) {
    if(contents[i].startsWith('FROM ')) {
      return yield findLatest(contents[i].split(' ')[1]);
    }
  }
  return null;
};

var findLatest = function*(imageName) {
  var image = imageName.split(':');
  if(image[1] === 'latest') {
    return null;
  }
  var name = image[0];
  if(name.indexOf('/') == -1) {
    name = 'library/' + name;
  }

  var next = `https://registry.hub.docker.com/v2/repositories/${name}/tags/`;
  var results = [];
  while(next) {
    var res = yield server.get({
      url: next,
      json: true
    });
    var body = res.body;
    results = results.concat(body.results);
    next = body.next;
  }
  var maxId = 0;
  var tag;
  for(var i = 0; i < results.length; i++) {
    var result = results[i];
    if(result.name !== 'latest' &&
        (result.name.indexOf('beta') == -1) &&
        (name !== 'library/java' || (result.name.startsWith('openjdk-8u') && result.name.endsWith('-jdk'))) &&
        (name !== 'library/nginx' || (!result.name.startsWith('1.8') && result.name.match(/^[0-9][0-9\.-]*$/))) &&
        result.id > maxId) {
      maxId = result.id;
      tag = result.name;
    }
  }

  var latest = `${name}:${tag}`;
  if(latest !== `${name}:${image[1]}`) {
    return latest;
  } else {
    return null;
  }
};

co(function*() {
  var from = process.argv.length > 2 && process.argv[2] === "from";
  for(var i = 0; i < images.length; i++) {
    var latest;
    if(from) {
      latest = yield findLatestFrom(images[i]);
    } else {
      latest = yield findLatest(images[i]);
    }
    if(latest) {
      console.log(`${images[i]} --> ${latest}`);
    }
  }
}).catch(function(err) {
  console.error(err);
});

<commit_msg>Exclude the alpine version of Jenkins image<commit_after>'use strict';
var server = require('co-request');
var co = require('co');
var images = require('./version.json')

var findLatestFrom = function*(imageName) {
  var image = imageName.split(':');
  var res = yield server.get({
    url: `https://registry.hub.docker.com/v2/repositories/${image[0]}/dockerfile/`,
    json: true
  });
  var contents = res.body.contents.split('\n');
  for(var i = 0; i < contents.length; i++) {
    if(contents[i].startsWith('FROM ')) {
      return yield findLatest(contents[i].split(' ')[1]);
    }
  }
  return null;
};

var findLatest = function*(imageName) {
  var image = imageName.split(':');
  if(image[1] === 'latest') {
    return null;
  }
  var name = image[0];
  if(name.indexOf('/') == -1) {
    name = 'library/' + name;
  }

  var next = `https://registry.hub.docker.com/v2/repositories/${name}/tags/`;
  var results = [];
  while(next) {
    var res = yield server.get({
      url: next,
      json: true
    });
    var body = res.body;
    results = results.concat(body.results);
    next = body.next;
  }
  var maxId = 0;
  var tag;
  for(var i = 0; i < results.length; i++) {
    var result = results[i];
    if(result.name !== 'latest' &&
        (result.name.indexOf('beta') == -1) &&
        (name !== 'library/java' || (result.name.startsWith('openjdk-8u') && result.name.endsWith('-jdk'))) &&
        (name !== 'library/nginx' || (!result.name.startsWith('1.8') && result.name.match(/^[0-9][0-9\.-]*$/))) &&
        (name !== 'library/jenkins' || result.name.match(/^[0-9][0-9\.-]*$/)) &&
        result.id > maxId) {
      maxId = result.id;
      tag = result.name;
    }
  }

  var latest = `${name}:${tag}`;
  if(latest !== `${name}:${image[1]}`) {
    return latest;
  } else {
    return null;
  }
};

co(function*() {
  var from = process.argv.length > 2 && process.argv[2] === "from";
  for(var i = 0; i < images.length; i++) {
    var latest;
    if(from) {
      latest = yield findLatestFrom(images[i]);
    } else {
      latest = yield findLatest(images[i]);
    }
    if(latest) {
      console.log(`${images[i]} --> ${latest}`);
    }
  }
}).catch(function(err) {
  console.error(err);
});

<|endoftext|>


<commit_before>Package.describe({
    summary: "Accounts Templates unstyled.",
    version: "0.9.15",
    name: "splendido:accounts-templates-unstyled",
    git: "https://github.com/splendido/accounts-templates-unstyled.git",
});

Package.on_use(function(api, where) {
    api.versionsFrom("METEOR@0.9.2.2");

    api.use([
        "less",
        "templating",
    ], "client");

    api.use([
        "splendido:accounts-templates-core",
    ], ["client", "server"]);

    api.imply([
        "splendido:accounts-templates-core@0.9.15",
    ], ["client", "server"]);

    api.add_files([
        "lib/at_error.html",
        "lib/at_error.js",
        "lib/at_form.html",
        "lib/at_form.js",
        "lib/at_input.html",
        "lib/at_input.js",
        "lib/at_oauth.html",
        "lib/at_oauth.js",
        "lib/at_pwd_form.html",
        "lib/at_pwd_form.js",
        "lib/at_pwd_form_btn.html",
        "lib/at_pwd_form_btn.js",
        "lib/at_pwd_link.html",
        "lib/at_pwd_link.js",
        "lib/at_result.html",
        "lib/at_result.js",
        "lib/at_sep.html",
        "lib/at_sep.js",
        "lib/at_signin_link.html",
        "lib/at_signin_link.js",
        "lib/at_signup_link.html",
        "lib/at_signup_link.js",
        "lib/at_social.html",
        "lib/at_social.js",
        "lib/at_terms_link.html",
        "lib/at_terms_link.js",
        "lib/at_title.html",
        "lib/at_title.js",
        "lib/full_page_at_form.html",
        "lib/at_unstyled.css"
    ], ["client"]);
});

Package.on_test(function(api) {
    api.use([
        "splendido:accounts-templates-unstyled",
        "splendido:accounts-templates-core@0.9.15",
    ]);

    api.use([
        "accounts-password",
        "tinytest",
        "test-helpers"
    ], ["client", "server"]);

    api.add_files([
        "tests/tests.js"
    ], ["client", "server"]);
});<commit_msg>patch release - Bump to version 0.9.16<commit_after>Package.describe({
    summary: "Accounts Templates unstyled.",
    version: "0.9.16",
    name: "splendido:accounts-templates-unstyled",
    git: "https://github.com/splendido/accounts-templates-unstyled.git",
});

Package.on_use(function(api, where) {
    api.versionsFrom("METEOR@0.9.2.2");

    api.use([
        "less",
        "templating",
    ], "client");

    api.use([
        "splendido:accounts-templates-core",
    ], ["client", "server"]);

    api.imply([
        "splendido:accounts-templates-core@0.9.16",
    ], ["client", "server"]);

    api.add_files([
        "lib/at_error.html",
        "lib/at_error.js",
        "lib/at_form.html",
        "lib/at_form.js",
        "lib/at_input.html",
        "lib/at_input.js",
        "lib/at_oauth.html",
        "lib/at_oauth.js",
        "lib/at_pwd_form.html",
        "lib/at_pwd_form.js",
        "lib/at_pwd_form_btn.html",
        "lib/at_pwd_form_btn.js",
        "lib/at_pwd_link.html",
        "lib/at_pwd_link.js",
        "lib/at_result.html",
        "lib/at_result.js",
        "lib/at_sep.html",
        "lib/at_sep.js",
        "lib/at_signin_link.html",
        "lib/at_signin_link.js",
        "lib/at_signup_link.html",
        "lib/at_signup_link.js",
        "lib/at_social.html",
        "lib/at_social.js",
        "lib/at_terms_link.html",
        "lib/at_terms_link.js",
        "lib/at_title.html",
        "lib/at_title.js",
        "lib/full_page_at_form.html",
        "lib/at_unstyled.css"
    ], ["client"]);
});

Package.on_test(function(api) {
    api.use([
        "splendido:accounts-templates-unstyled",
        "splendido:accounts-templates-core@0.9.16",
    ]);

    api.use([
        "accounts-password",
        "tinytest",
        "test-helpers"
    ], ["client", "server"]);

    api.add_files([
        "tests/tests.js"
    ], ["client", "server"]);
});<|endoftext|>


<commit_before>import atkPlugin from 'plugins/atkPlugin';

export default class jsSearch extends atkPlugin {

  main() {
    this.sortArgs = {};
    this.state = {button: false, filter: false};
    this.textInput = this.$el.find('input[type="text"]');
    this.leftIcon = this.$el.find('.atk-filter-icon').hide();
    this.searchAction = this.$el.find('.atk-search-button');
    this.searchIcon = this.searchAction.find('i.atk-search-icon');
    this.removeIcon  = this.searchAction.find('i.atk-remove-icon').hide();
    this.$el.data('preValue', '');

    this.setInputAction(this);
    this.setSearchAction(this);
  }

  /**
   * Set input field event handler.
   *
   * @param that
   */
  setInputAction(that) {
    this.textInput.on('keyup', function(e) {
      if (e.keyCode === 13 && e.target.value) {
        that.doSearch(that.settings.uri, $.extend({}, that.sortArgs, that.settings.uri_options, {'_q' : e.target.value}), function(){
          that.setButtonState(true);
          that.setFilterState(true);
        });
        that.$el.data('preValue', e.target.value);
      } else if ((e.keyCode === 27 && e.target.value) || (e.keyCode === 13 && e.target.value === '')) {
        that.doSearch(that.settings.uri, $.extend({}, that.sortArgs, that.settings.uri_options), function(){
          that.setButtonState(false);
          that.setFilterState(false);
        });
        that.$el.data('preValue', '');
        that.textInput.val('');
      } else if (that.$el.data('preValue') !== e.target.value) {
        that.setButtonState(false);
      }
    });
  }

  /**
   * Set Search button event handler.
   *
   * @param that
   */
  setSearchAction(that) {
    this.searchAction.on('click', function(e){
      if (that.state.button){
        that.doSearch(that.settings.uri, $.extend({}, that.sortArgs, that.settings.uri_options), function() {
          that.setButtonState(false);
          that.setFilterState(false);
        });
        that.textInput.val('');
      }

      if (!that.state.button && that.textInput.val()) {
        that.doSearch(that.settings.uri,  $.extend({}, that.sortArgs, that.settings.uri_options, {'_q' : that.textInput.val()}), function() {
          that.setButtonState(true);
          that.setFilterState(true);
        });
      }
    });
  }

  /**
   * Add argument to url for sorting purpose.
   *
   * @param name
   * @param sortBy
   */
  setSortArgs(name, sortBy) {
    this.sortArgs[name] = sortBy;
  }

  /**
   * Set Filter icon state.
   *
   * @param isOn
   */
  setFilterState(isOn) {
    if (isOn) {
      this.leftIcon.show();
    } else {
      this.leftIcon.hide();
    }
    this.state.filter = isOn;
  }

  /**
   * Set search button state.
   *
   * @param isOn
   */
  setButtonState(isOn) {
    if (isOn) {
      this.searchIcon.hide();
      this.removeIcon.show();
    } else {
      this.searchIcon.show();
      this.removeIcon.hide();
    }
    this.state.button = isOn;
  }

  /**
   * Send request to server using the search query.
   *
   * @param uri
   * @param options
   */
  doSearch(uri, options, cb = function(){}) {
    this.$el.api({
      on: 'now',
      url: uri,
      data: options,
      method: 'GET',
      obj: this.$el,
      stateContext: this.searchAction,
      onComplete: cb,
    });
  }
}

jsSearch.DEFAULTS = {
  uri: null,
  uri_options: {},
};
<commit_msg>fix for Wordpress integration<commit_after>import atkPlugin from 'plugins/atkPlugin';
import $ from 'jquery';

export default class jsSearch extends atkPlugin {

  main() {
    this.sortArgs = {};
    this.state = {button: false, filter: false};
    this.textInput = this.$el.find('input[type="text"]');
    this.leftIcon = this.$el.find('.atk-filter-icon').hide();
    this.searchAction = this.$el.find('.atk-search-button');
    this.searchIcon = this.searchAction.find('i.atk-search-icon');
    this.removeIcon  = this.searchAction.find('i.atk-remove-icon').hide();
    this.$el.data('preValue', '');

    this.setInputAction(this);
    this.setSearchAction(this);
  }

  /**
   * Set input field event handler.
   *
   * @param that
   */
  setInputAction(that) {
    this.textInput.on('keyup', function(e) {
      if (e.keyCode === 13 && e.target.value) {
        that.doSearch(that.settings.uri, $.extend({}, that.sortArgs, that.settings.uri_options, {'_q' : e.target.value}), function(){
          that.setButtonState(true);
          that.setFilterState(true);
        });
        that.$el.data('preValue', e.target.value);
      } else if ((e.keyCode === 27 && e.target.value) || (e.keyCode === 13 && e.target.value === '')) {
        that.doSearch(that.settings.uri, $.extend({}, that.sortArgs, that.settings.uri_options), function(){
          that.setButtonState(false);
          that.setFilterState(false);
        });
        that.$el.data('preValue', '');
        that.textInput.val('');
      } else if (that.$el.data('preValue') !== e.target.value) {
        that.setButtonState(false);
      }
    });
  }

  /**
   * Set Search button event handler.
   *
   * @param that
   */
  setSearchAction(that) {
    this.searchAction.on('click', function(e){
      if (that.state.button){
        that.doSearch(that.settings.uri, $.extend({}, that.sortArgs, that.settings.uri_options), function() {
          that.setButtonState(false);
          that.setFilterState(false);
        });
        that.textInput.val('');
      }

      if (!that.state.button && that.textInput.val()) {
        that.doSearch(that.settings.uri,  $.extend({}, that.sortArgs, that.settings.uri_options, {'_q' : that.textInput.val()}), function() {
          that.setButtonState(true);
          that.setFilterState(true);
        });
      }
    });
  }

  /**
   * Add argument to url for sorting purpose.
   *
   * @param name
   * @param sortBy
   */
  setSortArgs(name, sortBy) {
    this.sortArgs[name] = sortBy;
  }

  /**
   * Set Filter icon state.
   *
   * @param isOn
   */
  setFilterState(isOn) {
    if (isOn) {
      this.leftIcon.show();
    } else {
      this.leftIcon.hide();
    }
    this.state.filter = isOn;
  }

  /**
   * Set search button state.
   *
   * @param isOn
   */
  setButtonState(isOn) {
    if (isOn) {
      this.searchIcon.hide();
      this.removeIcon.show();
    } else {
      this.searchIcon.show();
      this.removeIcon.hide();
    }
    this.state.button = isOn;
  }

  /**
   * Send request to server using the search query.
   *
   * @param uri
   * @param options
   */
  doSearch(uri, options, cb = function(){}) {
    this.$el.api({
      on: 'now',
      url: uri,
      data: options,
      method: 'GET',
      obj: this.$el,
      stateContext: this.searchAction,
      onComplete: cb,
    });
  }
}

jsSearch.DEFAULTS = {
  uri: null,
  uri_options: {},
};
<|endoftext|>


<commit_before>'use strict';

var helper = {
  concurrency: 2,
  numRetries: 2,
  chunks: []
};

var queue = [];

function guardabosques(url) {
  $(document).ready(function () {
    resourceHandler(url);
  });
}

// Resource fetch from a LB
function resourceHandler(url) {
  $.support.cors = true;
  $.ajax({
    type: 'GET',
    url: url,
    success: function(data) {
      var resource = data;
      console.log(JSON.stringify(resource));
      downloadHandler(resource);
    },
    dataType: 'json',
    async: true
  });
}
// End resource fetch

// Download handler
function downloadHandler(resource) {
  setHelper(resource);
  console.log(JSON.stringify(helper));
  setQueue(helper);
  console.log(queue);

  // TODO gestionar queue (downloadFile(url, index))
  var i = 0;
  queue.forEach(function(url) {
    downloadFile(url, i);
    i++;
  });
}
// End download handler

// Downloads a single file into a blob
function downloadFile(url, index) {
  var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB;
  var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction;
  var dbVersion = 1.0;

  var database;

  var connect = indexedDB.open("guardabosquesDB2", dbVersion);
  var objectStore = 'chunks';

  // IndexedDB connection handlers
  connect.onerror = function(event) {
    console.log("Error creating/accessing IndexedDB database");
  };

  connect.onsuccess = function(event) {
    console.log("Success creating/accessing IndexedDB database");

    database = connect.result;
    database.onerror = function (event) {
      console.log("Error creating/accessing IndexedDB database");
    };

    // Provisional solution for Chrome using objectStore instead. Will be deprecated
    if (database.setVersion) {
      if (database.version != dbVersion) {
        var setVersion = database.setVersion(dbVersion);
        setVersion.onsuccess = function () {
          createObjectStore(database);
          console.log('true');
          getChunkFile(url, index);
        };
      }
      else {
        console.log('true');
        getChunkFile(url, index);
      }
    }
    else {
      console.log('true');
      getChunkFile(url, index);
    }
  };

  // For future use. Currently only in latest Firefox versions
  connect.onupgradeneeded = function (event) {
    createObjectStore(event.target.result);
  };
  // End IndexedDB connection handlers

  // Create/open database
  function createObjectStore (database) {
      // Create an objectStore
      console.log("Creating objectStore")
      database.createObjectStore(objectStore);
  }

  function getChunkFile(url, index) {
    // Create XHR
    var xhr = new XMLHttpRequest();

    xhr.open("GET", url, true);
    // Set the responseType to blob
    xhr.responseType = "blob";

    xhr.addEventListener("load", function () {
      if (xhr.status === 200) {
        console.log("chunk retrieved");

        // Blob as response
        var blob = xhr.response;
        console.log("Blob:" + blob + "size: " + blob.size);

        // Put the received blob into IndexedDB
        putChunkInDB(blob, index);
      }
    }, false);
    // Send XHR
    xhr.send();
  }

  function putChunkInDB(blob, index) {
    console.log("Putting elephants in IndexedDB");

    // Open a transaction to the database
    var readWriteMode = typeof IDBTransaction.READ_WRITE == "undefined" ? "readwrite" : IDBTransaction.READ_WRITE;
    var transaction = database.transaction([objectStore], readWriteMode);

    // Put the blob into the database
    console.log('index: ' + index);
    var put = transaction.objectStore(objectStore).put(blob, index);
  }
}

// Setters
function setHelper(resource) {
  helper.concurrency = resource.concurrency || 2;
  helper.numRetries = resource.numRetries || 2; // TODO

  var chunks = resource.segments;
  chunks.forEach(function (chunk) {
    var file = {
      downloaded: false,
      retries: 0,
      digest: chunk.digest,
      candidates: chunk.candidates
    }
    helper.chunks.push(file);
  });
}

function setQueue(helper) {
  helper.chunks.forEach(function (chunk) {
    queue.push(chunk.candidates[0]);
  });
}
// End setters<commit_msg>Adds file digest as indexedDB id<commit_after>'use strict';

var helper = {
  concurrency: 2,
  maxRetries: 2,
  id: '',
  chunks: []
};

var queue = [];

function guardabosques(url) {
  $(document).ready(function () {
    resourceHandler(url);
  });
}

// Resource fetch from a LB
function resourceHandler(url) {
  $.support.cors = true;
  $.ajax({
    type: 'GET',
    url: url,
    success: function(data) {
      var resource = data;
      console.log('json: ' + JSON.stringify(resource));
      downloadHandler(resource);
    },
    dataType: 'json',
    async: true
  });
}
// End resource fetch

// Download handler
function downloadHandler(resource) {
  setHelper(resource);
  console.log('helper: ' + JSON.stringify(helper));
  setQueue(helper);
  console.log('queue: ' + queue);

  // TODO gestionar queue (downloadFile(url, index))
  var i = 0;
  queue.forEach(function(url) {
    console.log('helper id: ' + helper.id);
    downloadFile(url, helper.id, i);
    i++;
  });
}
// End download handler

// Downloads a single file into a blob
function downloadFile(url, id, index) {
  var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB;
  var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction;
  var dbVersion = 1.0;

  var database;
  var dbName = 'guardabosques';

  var connect = indexedDB.open(dbName, dbVersion);
  var objectStore = id;

  // IndexedDB connection handlers
  connect.onerror = function(event) {
    console.log("Error creating/accessing IndexedDB database");
  };

  connect.onsuccess = function(event) {
    console.log("Success creating/accessing IndexedDB database");

    database = connect.result;
    database.onerror = function (event) {
      console.log("Error creating/accessing IndexedDB database");
    };

    // Provisional solution for Chrome using objectStore instead. Will be deprecated
    if (database.setVersion) {
      if (database.version != dbVersion) {
        var setVersion = database.setVersion(dbVersion);
        setVersion.onsuccess = function () {
          createObjectStore(database);
          getChunkFile(url, index);
        };
      }
      else {
        getChunkFile(url, index);
      }
    }
    else {
      getChunkFile(url, index);
    }
  };

  // For future use. Currently only in latest Firefox versions
  connect.onupgradeneeded = function (event) {
    createObjectStore(event.target.result);
  };
  // End IndexedDB connection handlers

  // Create/open database
  function createObjectStore (database) {
      database.createObjectStore(objectStore);
  }

  function getChunkFile(url, index) {
    // Create XHR
    var xhr = new XMLHttpRequest();

    xhr.open("GET", url, true);
    xhr.responseType = "blob";

    xhr.addEventListener("load", function () {
      if (xhr.status === 200) {
        console.log('chunk retrieved');
        var contentLength = xhr.getResponseHeader('Content-Length')

        // Blob as response
        var blob = xhr.response;
        console.log('Blob: ' + blob);

        var blobSize = blob.size;
        if (Number(blobSize) === Number(contentLength)) {
          console.log('chunk '+url+' retrieved successfully');
          // Put the received blob into IndexedDB
          putChunkInDB(blob, index);
        } else {
          // TODO handle retransmision
          console.log('chunk '+url+' retrieve failed, start retransmision');
        }
      } else {
        // TODO handle retransmision
        console.log('chunk '+url+' retrieve failed, start retransmision');
      }
    }, false);
    // Send XHR
    xhr.send();
  }

  function putChunkInDB(blob, index) {
    console.log("Putting elephants in IndexedDB");

    // Open a transaction to the database
    var readWriteMode = typeof IDBTransaction.READ_WRITE == "undefined" ? "readwrite" : IDBTransaction.READ_WRITE;
    var transaction = database.transaction([objectStore], readWriteMode);

    // Put the blob into the database
    console.log('index: ' + index);
    var put = transaction.objectStore(objectStore).put(blob, index);
  }
}

// Setters
function setHelper(resource) {
  helper.concurrency = resource.concurrency || 2;
  helper.maxRetries = resource.numRetries || 2; // TODO
  helper.id = resource.id;
  var chunks = resource.segments;
  chunks.forEach(function (chunk) {
    var file = {
      downloaded: false,
      retries: 0,
      digest: chunk.digest,
      candidates: chunk.candidates
    }
    helper.chunks.push(file);
  });
}

function setQueue(helper) {
  helper.chunks.forEach(function (chunk) {
    queue.push(chunk.candidates[0]);
  });
}
// End setters<|endoftext|>