<commit_before>/*
 * A simple Node.js application to write to a digital output.
 * Supported Intel IoT development boards are identified in the code.
 *
 * See LICENSE.md for license terms and conditions.
 *
 * https://software.intel.com/en-us/html5/articles/intel-xdk-iot-edition-nodejs-templates
 */

// keep /*jslint and /*jshint lines for proper jshinting and jslinting
// see http://www.jslint.com/help.html and http://jshint.com/docs
/* jslint node:true */
/* jshint unused:true */

"use strict" ;

var APP_NAME = "IoT Digital Write" ;
var cfg = require("./cfg-app-platform.js")() ;          // init and config I/O resources
var test= require("./cfg-app-platform.js")();
console.log("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n") ;   // poor man's clear console
console.log("Initializing " + APP_NAME) ;

// confirm that we have a version of libmraa and Node.js that works
// exit this app if we do not

cfg.identify() ;                // prints some interesting platform details to console

if( !cfg.test() ) {
    process.exitCode = 1 ;
    throw new Error("Call to cfg.test() failed, check console messages for details.") ;
}

if( !cfg.init() ) {
    process.exitCode = 1 ;
    throw new Error("Call to cfg.init() failed, check console messages for details.") ;
}

var blueList = ["Sweet potatoes", "Mac and cheese leftovers", "Orange juice"];
var redList = ["Thai curry", "Ketchup", "Carrots"];

var Color = function(r, g, b) {
    this.red = r;
    this.green = g;
    this.blue = b
}

var blueColor = new Color(0, 0x3E, 0x62);
var redColor = new Color(0x62, 0, 0);

var writeWithPauses = function(list, pauseTime) {
    return new Promise( function (resolve, reject) {
        var iter = iterateList(list);
        var intID = setInterval(iter.next, pauseTime);
        var iterateList = function (list) {
            var i = 0;
            return {
                next: function() {
                    if (i >= list.length) {
                        clearInterval(intID);
                        resolve();
                    } else {
                        clearAndWrite(list[i++]);
                        return;
                    }
                }
            };
        };
    });
};
var clearAndWrite = function(str) {
    display.clear();
    display.home();
    display.write(str);
    //THIS MIGHT WORK
    display.scroll(true);
};
var showList = function (color, list) {
    display.setColor(color.red, color.green, color.blue);
    return writeWithPauses(list, 4000);
};

// configure (initialize) our I/O pins for usage (gives us an I/O object)
// configuration is based on parameters provided by the call to cfg.init()
var lcd = require('jsupm_i2clcd');
var display = new lcd.Jhd1313m1(0, 0x3E, 0x62);
showList(blueColor, blueList).then(function() {showList(redColor, redList)});
test.io = new test.mraa.Gpio(6, true, false);
test.io = new test.mraa.Gpio(6, true, false);
test.io.dir(test.mraa.DIR_OUT);
cfg.io = new cfg.mraa.Gpio(cfg.ioPin, cfg.ioOwner, cfg.ioRaw) ;
cfg.io.dir(cfg.mraa.DIR_OUT) ;                  // configure the gpio pin as an output

var button = new mraa.Gpio(7);
var buttonPressed = function () {console.log.("button!\n");}
button.isr(mraa.EDGE_RISING, buttonPressed);

//var intervalID = setInterval(periodicActivity, 1000) ;  // start the periodic write
cfg.io.write(0);
test.io.write(0);
var testActivity = function () {
    cfg.io.write(0);
    test.io.write(1);
    process.stdout.write('wrote 0 to cfg, 1 to test');
}

var secondTest = function () {
    cfg.io.write(1);
    test.io.write(0);
    process.stdout.write("okay we're done now, switched it");
}

var buttonPressed = function () {
    fakeBlueRequest
}

// type process.exit(0) in debug console to see
// the following message be emitted to the debug console

process.on("exit", function(code) {
    //clearInterval(intervalID) ;
    console.log("\nExiting " + APP_NAME + ", with code:", code) ;
}) ;
<commit_msg>Maya: button doing stuff<commit_after>/*
 * A simple Node.js application to write to a digital output.
 * Supported Intel IoT development boards are identified in the code.
 *
 * See LICENSE.md for license terms and conditions.
 *
 * https://software.intel.com/en-us/html5/articles/intel-xdk-iot-edition-nodejs-templates
 */

// keep /*jslint and /*jshint lines for proper jshinting and jslinting
// see http://www.jslint.com/help.html and http://jshint.com/docs
/* jslint node:true */
/* jshint unused:true */

"use strict" ;

var APP_NAME = "IoT Digital Write" ;
var mraa = require("mraa");
var blue = require("./cfg-app-platform.js")() ;          // init and config I/O resources
var red = require("./cfg-app-platform.js")();
console.log("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n") ;   // poor man's clear console
console.log("Initializing " + APP_NAME) ;

// confirm that we have a version of libmraa and Node.js that works
// exit this app if we do not

blue.identify() ;                // prints some interesting platform details to console

if( !blue.test() ) {
    process.exitCode = 1 ;
    throw new Error("Call to cfg.test() failed, check console messages for details.") ;
}

if( !blue.init() ) {
    process.exitCode = 1 ;
    throw new Error("Call to cfg.init() failed, check console messages for details.") ;
}

var blueList = ["Sweet potatoes", "Mac and cheese leftovers", "Orange juice"];
var redList = ["Thai curry", "Ketchup", "Carrots"];

var Color = function(r, g, b) {
    this.red = r;
    this.green = g;
    this.blue = b;
};

var blueColor = new Color(0, 0x3E, 0x62);
var redColor = new Color(0x62, 0, 0);

var writeWithPauses = function(list, pauseTime) {
    return new Promise( function (resolve, reject) {
        var iterateList = function (list) {
            var i = 0;
            return {
                next: function() {
                    if (i >= list.length) {
                        clearInterval(intID);
                        resolve();
                    } else {
                        clearAndWrite(list[i++]);
                        return;
                    }
                }
            };
        };
        var iter = iterateList(list);
        var intID = setInterval(iter.next, pauseTime);
    });
};
var clearAndWrite = function(str) {
    display.clear();
    display.home();
    display.write(str);
};
var showList = function (color, list) {
    display.setColor(color.red, color.green, color.blue);
    return writeWithPauses(list, 4000);
};

// configure (initialize) our I/O pins for usage (gives us an I/O object)
// configuration is based on parameters provided by the call to cfg.init()

var lcd = require('jsupm_i2clcd');
var display = new lcd.Jhd1313m1(0, 0x3E, 0x62);

red.io = new red.mraa.Gpio(6, true, false);
red.io = new red.mraa.Gpio(6, true, false);
red.io.dir(red.mraa.DIR_OUT);
blue.io = new blue.mraa.Gpio(blue.ioPin, blue.ioOwner, blue.ioRaw) ;
blue.io.dir(blue.mraa.DIR_OUT) ;                  // configure the gpio pin as an output

var button = new mraa.Gpio(7);
var buttonPressed = function () {
    console.log("pressed");
    showList(blueColor, blueList).then(function() {showList(redColor, redList)});
};

console.log("before button\n");
button.isr(mraa.EDGE_BOTH, buttonPressed);
console.log("After button\n");
blue.io.write(0);
red.io.write(1);
(function wait(){
 setTimeout(wait, 1000);
 })();<|endoftext|>


<commit_before>const _ = require('lodash/fp')
const axios = require('axios')

const logger = require('./logger')
const db = require('./db')
const pairing = require('./pairing')
const notifier = require('./notifier')
const dbm = require('./postgresql_interface')
const configManager = require('./new-config-manager')
const settingsLoader = require('./new-settings-loader')

module.exports = {getMachineName, getMachines, getMachineNames, setMachine}

function getMachines () {
  return db.any('select * from devices where display=TRUE order by created')
    .then(rr => rr.map(r => ({
      deviceId: r.device_id,
      cashbox: r.cashbox,
      cassette1: r.cassette1,
      cassette2: r.cassette2,
      version: r.version,
      model: r.model,
      pairedAt: new Date(r.created),
      lastPing: new Date(r.last_online),
      name: r.name,
      // TODO: we shall start using this JSON field at some point
      // location: r.location,
      paired: r.paired
    })))
}

function getConfig (defaultConfig) {
  if (defaultConfig) return Promise.resolve(defaultConfig)

  return settingsLoader.loadLatest().config
}

function getMachineNames (config) {
  const fullyFunctionalStatus = {label: 'Fully functional', type: 'success'}
  const unresponsiveStatus = {label: 'Unresponsive', type: 'error'}
  const stuckStatus = {label: 'Stuck', type: 'error'}

  return Promise.all([getMachines(), getConfig(config)])
    .then(([machines, config]) => Promise.all(
      [machines, notifier.checkPings(machines), dbm.machineEvents(), config]
    ))
    .then(([machines, pings, events, config]) => {
      const getPingStatus = (ping) => {
        if (!ping) return fullyFunctionalStatus

        if (ping.age) return unresponsiveStatus

        return fullyFunctionalStatus
      }

      const getStuckStatus = (stuck) => {
        if (!stuck || !stuck.age) return undefined

        return stuckStatus
      }

      const addName = r => {
        const cashOutConfig = configManager.getCashOut(r.deviceId, config)

        const cashOut = !!cashOutConfig.active

        const ping = getPingStatus(_.first(pings[r.deviceId]))
        const stuck = getStuckStatus(_.first(notifier.checkStuckScreen(events, r.name)))

        const statuses = [ping]

        if (stuck) statuses.push(stuck)

        return _.assign(r, {cashOut, statuses})
      }

      return _.map(addName, machines)
    })
}

/**
 * Given the machine id, get the machine name
 *
 * @name getMachineName
 * @function
 * @async
 *
 * @param {string} machineId machine id
 * @returns {string} machine name
 */
function getMachineName (machineId) {
  const sql = 'select * from devices where device_id=$1'
  return db.oneOrNone(sql, [machineId])
    .then(it => it.name)
}

function resetCashOutBills (rec) {
  const sql = 'update devices set cassette1=$1, cassette2=$2 where device_id=$3'
  return db.none(sql, [rec.cassettes[0], rec.cassettes[1], rec.deviceId])
}

function emptyCashInBills (rec) {
  const sql = 'update devices set cashbox=0 where device_id=$1'
  return db.none(sql, [rec.deviceId])
}

function unpair (rec) {
  return pairing.unpair(rec.deviceId)
}

function reboot (rec) {
  return axios.post(`http://localhost:3030/reboot?device_id=${rec.deviceId}`)
}

function restartServices (rec) {
  return axios.post(`http://localhost:3030/restartServices?device_id=${rec.deviceId}`)
}

function setMachine (rec) {
  switch (rec.action) {
    case 'emptyCashInBills': return emptyCashInBills(rec)
    case 'resetCashOutBills': return resetCashOutBills(rec)
    case 'unpair': return unpair(rec)
    case 'reboot': return reboot(rec)
    case 'restartServices': return restartServices(rec)
    default: throw new Error('No such action: ' + rec.action)
  }
}
<commit_msg>fix: send a single state for the machine status<commit_after>const _ = require('lodash/fp')
const axios = require('axios')

const logger = require('./logger')
const db = require('./db')
const pairing = require('./pairing')
const notifier = require('./notifier')
const dbm = require('./postgresql_interface')
const configManager = require('./new-config-manager')
const settingsLoader = require('./new-settings-loader')

module.exports = {getMachineName, getMachines, getMachineNames, setMachine}

function getMachines () {
  return db.any('select * from devices where display=TRUE order by created')
    .then(rr => rr.map(r => ({
      deviceId: r.device_id,
      cashbox: r.cashbox,
      cassette1: r.cassette1,
      cassette2: r.cassette2,
      version: r.version,
      model: r.model,
      pairedAt: new Date(r.created),
      lastPing: new Date(r.last_online),
      name: r.name,
      // TODO: we shall start using this JSON field at some point
      // location: r.location,
      paired: r.paired
    })))
}

function getConfig (defaultConfig) {
  if (defaultConfig) return Promise.resolve(defaultConfig)

  return settingsLoader.loadLatest().config
}

function getMachineNames (config) {
  const fullyFunctionalStatus = {label: 'Fully functional', type: 'success'}
  const unresponsiveStatus = {label: 'Unresponsive', type: 'error'}
  const stuckStatus = {label: 'Stuck', type: 'error'}

  return Promise.all([getMachines(), getConfig(config)])
    .then(([machines, config]) => Promise.all(
      [machines, notifier.checkPings(machines), dbm.machineEvents(), config]
    ))
    .then(([machines, pings, events, config]) => {
      const getStatus = (ping, stuck) => {
        if (stuck && stuck.age) return stuckStatus

        if (ping && ping.age) return unresponsiveStatus

        return fullyFunctionalStatus
      }

      const addName = r => {
        const cashOutConfig = configManager.getCashOut(r.deviceId, config)

        const cashOut = !!cashOutConfig.active

        const statuses = [
          getStatus(
            _.first(pings[r.deviceId]),
            _.first(notifier.checkStuckScreen(events, r.name))
          )
        ]

        return _.assign(r, {cashOut, statuses})
      }

      return _.map(addName, machines)
    })
}

/**
 * Given the machine id, get the machine name
 *
 * @name getMachineName
 * @function
 * @async
 *
 * @param {string} machineId machine id
 * @returns {string} machine name
 */
function getMachineName (machineId) {
  const sql = 'select * from devices where device_id=$1'
  return db.oneOrNone(sql, [machineId])
    .then(it => it.name)
}

function resetCashOutBills (rec) {
  const sql = 'update devices set cassette1=$1, cassette2=$2 where device_id=$3'
  return db.none(sql, [rec.cassettes[0], rec.cassettes[1], rec.deviceId])
}

function emptyCashInBills (rec) {
  const sql = 'update devices set cashbox=0 where device_id=$1'
  return db.none(sql, [rec.deviceId])
}

function unpair (rec) {
  return pairing.unpair(rec.deviceId)
}

function reboot (rec) {
  return axios.post(`http://localhost:3030/reboot?device_id=${rec.deviceId}`)
}

function restartServices (rec) {
  return axios.post(`http://localhost:3030/restartServices?device_id=${rec.deviceId}`)
}

function setMachine (rec) {
  switch (rec.action) {
    case 'emptyCashInBills': return emptyCashInBills(rec)
    case 'resetCashOutBills': return resetCashOutBills(rec)
    case 'unpair': return unpair(rec)
    case 'reboot': return reboot(rec)
    case 'restartServices': return restartServices(rec)
    default: throw new Error('No such action: ' + rec.action)
  }
}
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');
const url = require('url');
const mapnik = require('@carto/mapnik');
const normalizeURI = require('./uri');
const createMetatileCache = require('./metatile-cache');
const createMapPool = require('./map-pool');
const areValidCoords = require('./utils/coords');
const timeoutDecorator = require('./utils/timeout-decorator');
const headers = require('./utils/headers');
const mime = require('mime');

mapnik.register_default_input_plugins();

function MapnikSource(uri, callback) {
    this.open = false;

    this._uri = normalizeURI(uri);

    if (this._uri.protocol && this._uri.protocol !== 'mapnik:') {
        return callback(new Error('Only the mapnik protocol is supported'));
    }

    if (this._uri.query.limits && this._uri.query.limits.render > 0) {
        this.getTile = timeoutDecorator(this.getTile.bind(this), this._uri.query.limits.render);
        this.getGrid = timeoutDecorator(this.getGrid.bind(this), this._uri.query.limits.render);
    }

    this._open(callback);
}

MapnikSource.mapnik = mapnik;

// Finds all XML files in the filepath and returns their tilesource URI.
MapnikSource.list = function (filepath, callback) {
    filepath = path.resolve(filepath);
    fs.readdir(filepath, (err, files) => {
        if (err) {
            return callback(err);
        }

        const result = {};

        for (i = 0; i < files.length; i++) {
            const name = files[i].match(/^([\w-]+)\.xml$/);

            if (name) {
                result[name[1]] = 'mapnik://' + path.join(filepath, name[0]);
            }
        }

        return callback(null, result);
    });
};

// Finds an XML file with the given ID in the filepath and returns a
// tilesource URI.
MapnikSource.findID = function (filepath, id, callback) {
    filepath = path.resolve(filepath);
    const file = path.join(filepath, id + '.xml');

    fs.stat(file, (err, stats) => {
        if (err) {
            return callback(err);
        }

        return callback(null, 'mapnik://' + file);
    });
};

MapnikSource.registerProtocols = function (tilelive) {
    tilelive.protocols['mapnik:'] = MapnikSource;
};

MapnikSource.prototype.toJSON = function () {
    return url.format(this._uri);
};

MapnikSource.prototype.close = function (callback) {
    if (!this.open) {
        return callback();
    }

    this._metatileCache.clear();

    return this._mapPool.drain()
        .then(() => {
            this._mapPool.clear();
            this.open = false;
            return callback();
        });
};

// Render handler for a given tile request.
MapnikSource.prototype.getTile = function (z, x, y, callback) {
    const format = (this._info && this._info.format) || 'png';
    this._renderTile(format, z, x, y, callback);
};

MapnikSource.prototype.getGrid = function (z, x, y, callback) {
    const format = 'utf';
    this._renderTile('utf', z, x, y, callback);
};

MapnikSource.prototype._renderTile = function (format, z, x, y, callback) {
    z = +z;
    x = +x;
    y = +y;

    try {
        areValidCoords({ z, x, y });
    } catch (err) {
        return callback(err);
    }

    const key = [format, z, x, y].join(',');

    this._metatileCache.get(key, callback);
};

MapnikSource.prototype.getInfo = function(callback) {
    if (!this._info) {
        return callback(new Error('Info is unavailable'));
    }

    return callback(null, this._info);
};

MapnikSource.prototype._open = function (callback) {
    if (this.open) {
        return callback(null, this);
    }

    this._loadXML((err, xml) => {
        if (err) {
            return callback(err);
        }

        this._metatileCache = createMetatileCache(this, this._uri.query.tileSize, this._uri.query.metatile, this._uri.query.metatileCache);
        this._mapPool = createMapPool(this._uri, xml);

        this._populateInfo((err) => {
            if (err) {
                return callback(err);
            }

            this.open = true;

            return callback(null, this);
        });
    });
};

// Loads the XML file from the specified path. Calls `callback` when the mapfile
// can be expected to be in `mapfile`. If this isn't successful, `callback` gets
// an error as its first argument.
MapnikSource.prototype._loadXML = function (callback) {
    if (this._uri.xml) {
        return callback(null, this._uri.xml);
    }

    fs.readFile(path.resolve(this._uri.pathname), 'utf8', callback);
};

MapnikSource.prototype._populateInfo = function (callback) {
    const id = path.basename(this._uri.pathname, path.extname(this._uri.pathname));

    this._mapPool.acquire()
        .then((resource) => {
            if (!(resource instanceof mapnik.Map)) {
                const err = resource;
                this._mapPool.release(resource);

                throw err;
            }

            const map = resource;
            const info = { id: id, name: id, minzoom: 0, maxzoom: 22, autoscale: true };

            const p = map.parameters;
            for (const key in p) {
                info[key] = p[key];
            }

            if (p.bounds) {
                info.bounds = p.bounds.split(',').map(parseFloat);
            }

            if (p.center) {
                info.center = p.center.split(',').map(parseFloat);
            }

            if (p.minzoom) {
                info.minzoom = parseInt(p.minzoom, 10);
            }

            if (p.maxzoom) {
                info.maxzoom = parseInt(p.maxzoom, 10);
            }

            if (p.interactivity_fields) {
                info.interactivity_fields = p.interactivity_fields.split(',');
            }

            if (!info.bounds || info.bounds.length !== 4) {
                info.bounds = [ -180, -85.05112877980659, 180, 85.05112877980659 ];
            }

            if (!info.center || info.center.length !== 3) {
                info.center = [
                    (info.bounds[2] - info.bounds[0]) / 2 + info.bounds[0],
                    (info.bounds[3] - info.bounds[1]) / 2 + info.bounds[1],
                    2
                ];
            }

            this._info = info;
            this._mapPool.release(map);

            return callback(null);
        })
        .catch((err) => {
            return callback(err);
        });
};

// Render png/jpg/tif image or a utf grid and return an encoded buffer
MapnikSource.prototype._renderMetatile = function (format, z, x, y, metatile, callback) {
    this._mapPool.acquire()
        .then((resource) => {
            if (!(resource instanceof mapnik.Map)) {
                const err = resource;
                this._mapPool.release(resource)

                throw err;
            }

            const map = resource;

            try {
                const options = {
                    tileSize: this._uri.query.tileSize,
                    buffer_size: this._uri.query.bufferSize,
                    format: format,
                    z: z,
                    x: metatile.x,
                    y: metatile.y,
                    metrics: this._uri.query.metrics,
                    variables: this._uri.query.variables || {},
                    scale: this._uri.query.scale
                };

                // Set x, y, z based on the metatile boundary
                options.variables.zoom = options.z;

                // Set default options.
                if (options.format === 'utf') {
                    if (!map.parameters.interactivity_layer || !map.parameters.interactivity_fields) {
                        return callback(new Error('Tileset has no interactivity'));
                    }

                    options.layer = map.parameters.interactivity_layer;
                    options.fields = map.parameters.interactivity_fields.split(',');
                    options.resolution = this._uri.query.resolution;
                }

                const renderStartTime = Date.now();

                const image = new mapnik[format === 'utf' ? 'Grid' : 'Image'](metatile.width, metatile.height);

                image.metrics_enabled = options.metrics;

                map.resize(metatile.width, metatile.height);
                map.extent = metatile.bbox;

                map.render(image, options, (err, image) => {
                    this._mapPool.release(map);

                    if (err) {
                        return callback(err);
                    }

                    const renderStats = {
                        render: Math.round((Date.now() - renderStartTime) / metatile.tiles.length)
                    };

                    return this._sliceMetatile(image, options, metatile, renderStats, callback);
                });
            } catch(err) {
                this._mapPool.release(map);
                return callback(err);
            }
        })
        .catch((err) => {
            return callback(err);
        });
};

MapnikSource.prototype._sliceMetatile = function (image, options, metatile, stats, callback) {
    if (metatile.tiles.length === 0) {
        return callback(null, {});
    }

    Promise.all(metatile.tiles.map((coords) => {
        return new Promise((resolve, reject) => {
            const key = [ options.format, coords[0], coords[1], coords[2] ].join(',');
            const encodeStartTime = Date.now();
            const x = (coords[1] - metatile.x) * options.tileSize;
            const y = (coords[2] - metatile.y) * options.tileSize;

            try {
                const view = image.view(x, y, options.tileSize, options.tileSize);

                const params = options.format === 'utf' ? [ options ] : [ options.format, options ];
                view.encode(...params, (err, encodedImage) => {
                    if (err) {
                        return reject(err);
                    }

                    resolve({
                        [key]: {
                            image: encodedImage,
                            headers: headers(options.format),
                            stats: Object.assign(stats, { encode: Date.now() - encodeStartTime }, image.get_metrics())
                        }
                    });
                });
            } catch (err) {
                return callback(err);
            }
        });
    }))
    .then((tiles) => callback(null, Object.assign({}, ...tiles)))
    .catch((err) => callback(err));
};

module.exports = MapnikSource;
<commit_msg>Don't use callback inside of a Promise constructor<commit_after>'use strict';

const fs = require('fs');
const path = require('path');
const url = require('url');
const mapnik = require('@carto/mapnik');
const normalizeURI = require('./uri');
const createMetatileCache = require('./metatile-cache');
const createMapPool = require('./map-pool');
const areValidCoords = require('./utils/coords');
const timeoutDecorator = require('./utils/timeout-decorator');
const headers = require('./utils/headers');
const mime = require('mime');

mapnik.register_default_input_plugins();

function MapnikSource(uri, callback) {
    this.open = false;

    this._uri = normalizeURI(uri);

    if (this._uri.protocol && this._uri.protocol !== 'mapnik:') {
        return callback(new Error('Only the mapnik protocol is supported'));
    }

    if (this._uri.query.limits && this._uri.query.limits.render > 0) {
        this.getTile = timeoutDecorator(this.getTile.bind(this), this._uri.query.limits.render);
        this.getGrid = timeoutDecorator(this.getGrid.bind(this), this._uri.query.limits.render);
    }

    this._open(callback);
}

MapnikSource.mapnik = mapnik;

// Finds all XML files in the filepath and returns their tilesource URI.
MapnikSource.list = function (filepath, callback) {
    filepath = path.resolve(filepath);
    fs.readdir(filepath, (err, files) => {
        if (err) {
            return callback(err);
        }

        const result = {};

        for (i = 0; i < files.length; i++) {
            const name = files[i].match(/^([\w-]+)\.xml$/);

            if (name) {
                result[name[1]] = 'mapnik://' + path.join(filepath, name[0]);
            }
        }

        return callback(null, result);
    });
};

// Finds an XML file with the given ID in the filepath and returns a
// tilesource URI.
MapnikSource.findID = function (filepath, id, callback) {
    filepath = path.resolve(filepath);
    const file = path.join(filepath, id + '.xml');

    fs.stat(file, (err, stats) => {
        if (err) {
            return callback(err);
        }

        return callback(null, 'mapnik://' + file);
    });
};

MapnikSource.registerProtocols = function (tilelive) {
    tilelive.protocols['mapnik:'] = MapnikSource;
};

MapnikSource.prototype.toJSON = function () {
    return url.format(this._uri);
};

MapnikSource.prototype.close = function (callback) {
    if (!this.open) {
        return callback();
    }

    this._metatileCache.clear();

    return this._mapPool.drain()
        .then(() => {
            this._mapPool.clear();
            this.open = false;
            return callback();
        });
};

// Render handler for a given tile request.
MapnikSource.prototype.getTile = function (z, x, y, callback) {
    const format = (this._info && this._info.format) || 'png';
    this._renderTile(format, z, x, y, callback);
};

MapnikSource.prototype.getGrid = function (z, x, y, callback) {
    const format = 'utf';
    this._renderTile('utf', z, x, y, callback);
};

MapnikSource.prototype._renderTile = function (format, z, x, y, callback) {
    z = +z;
    x = +x;
    y = +y;

    try {
        areValidCoords({ z, x, y });
    } catch (err) {
        return callback(err);
    }

    const key = [format, z, x, y].join(',');

    this._metatileCache.get(key, callback);
};

MapnikSource.prototype.getInfo = function(callback) {
    if (!this._info) {
        return callback(new Error('Info is unavailable'));
    }

    return callback(null, this._info);
};

MapnikSource.prototype._open = function (callback) {
    if (this.open) {
        return callback(null, this);
    }

    this._loadXML((err, xml) => {
        if (err) {
            return callback(err);
        }

        this._metatileCache = createMetatileCache(this, this._uri.query.tileSize, this._uri.query.metatile, this._uri.query.metatileCache);
        this._mapPool = createMapPool(this._uri, xml);

        this._populateInfo((err) => {
            if (err) {
                return callback(err);
            }

            this.open = true;

            return callback(null, this);
        });
    });
};

// Loads the XML file from the specified path. Calls `callback` when the mapfile
// can be expected to be in `mapfile`. If this isn't successful, `callback` gets
// an error as its first argument.
MapnikSource.prototype._loadXML = function (callback) {
    if (this._uri.xml) {
        return callback(null, this._uri.xml);
    }

    fs.readFile(path.resolve(this._uri.pathname), 'utf8', callback);
};

MapnikSource.prototype._populateInfo = function (callback) {
    const id = path.basename(this._uri.pathname, path.extname(this._uri.pathname));

    this._mapPool.acquire()
        .then((resource) => {
            if (!(resource instanceof mapnik.Map)) {
                const err = resource;
                this._mapPool.release(resource);

                throw err;
            }

            const map = resource;
            const info = { id: id, name: id, minzoom: 0, maxzoom: 22, autoscale: true };

            const p = map.parameters;
            for (const key in p) {
                info[key] = p[key];
            }

            if (p.bounds) {
                info.bounds = p.bounds.split(',').map(parseFloat);
            }

            if (p.center) {
                info.center = p.center.split(',').map(parseFloat);
            }

            if (p.minzoom) {
                info.minzoom = parseInt(p.minzoom, 10);
            }

            if (p.maxzoom) {
                info.maxzoom = parseInt(p.maxzoom, 10);
            }

            if (p.interactivity_fields) {
                info.interactivity_fields = p.interactivity_fields.split(',');
            }

            if (!info.bounds || info.bounds.length !== 4) {
                info.bounds = [ -180, -85.05112877980659, 180, 85.05112877980659 ];
            }

            if (!info.center || info.center.length !== 3) {
                info.center = [
                    (info.bounds[2] - info.bounds[0]) / 2 + info.bounds[0],
                    (info.bounds[3] - info.bounds[1]) / 2 + info.bounds[1],
                    2
                ];
            }

            this._info = info;
            this._mapPool.release(map);

            return callback(null);
        })
        .catch((err) => {
            return callback(err);
        });
};

// Render png/jpg/tif image or a utf grid and return an encoded buffer
MapnikSource.prototype._renderMetatile = function (format, z, x, y, metatile, callback) {
    this._mapPool.acquire()
        .then((resource) => {
            if (!(resource instanceof mapnik.Map)) {
                const err = resource;
                this._mapPool.release(resource)

                throw err;
            }

            const map = resource;

            try {
                const options = {
                    tileSize: this._uri.query.tileSize,
                    buffer_size: this._uri.query.bufferSize,
                    format: format,
                    z: z,
                    x: metatile.x,
                    y: metatile.y,
                    metrics: this._uri.query.metrics,
                    variables: this._uri.query.variables || {},
                    scale: this._uri.query.scale
                };

                // Set x, y, z based on the metatile boundary
                options.variables.zoom = options.z;

                // Set default options.
                if (options.format === 'utf') {
                    if (!map.parameters.interactivity_layer || !map.parameters.interactivity_fields) {
                        return callback(new Error('Tileset has no interactivity'));
                    }

                    options.layer = map.parameters.interactivity_layer;
                    options.fields = map.parameters.interactivity_fields.split(',');
                    options.resolution = this._uri.query.resolution;
                }

                const renderStartTime = Date.now();

                const image = new mapnik[format === 'utf' ? 'Grid' : 'Image'](metatile.width, metatile.height);

                image.metrics_enabled = options.metrics;

                map.resize(metatile.width, metatile.height);
                map.extent = metatile.bbox;

                map.render(image, options, (err, image) => {
                    this._mapPool.release(map);

                    if (err) {
                        return callback(err);
                    }

                    const renderStats = {
                        render: Math.round((Date.now() - renderStartTime) / metatile.tiles.length)
                    };

                    return this._sliceMetatile(image, options, metatile, renderStats, callback);
                });
            } catch(err) {
                this._mapPool.release(map);
                return callback(err);
            }
        })
        .catch((err) => {
            return callback(err);
        });
};

MapnikSource.prototype._sliceMetatile = function (image, options, metatile, stats, callback) {
    if (metatile.tiles.length === 0) {
        return callback(null, {});
    }

    Promise.all(metatile.tiles.map((coords) => {
        return new Promise((resolve, reject) => {
            const key = [ options.format, coords[0], coords[1], coords[2] ].join(',');
            const encodeStartTime = Date.now();
            const x = (coords[1] - metatile.x) * options.tileSize;
            const y = (coords[2] - metatile.y) * options.tileSize;

            try {
                const view = image.view(x, y, options.tileSize, options.tileSize);

                const params = options.format === 'utf' ? [ options ] : [ options.format, options ];
                view.encode(...params, (err, encodedImage) => {
                    if (err) {
                        return reject(err);
                    }

                    resolve({
                        [key]: {
                            image: encodedImage,
                            headers: headers(options.format),
                            stats: Object.assign(stats, { encode: Date.now() - encodeStartTime }, image.get_metrics())
                        }
                    });
                });
            } catch (err) {
                return reject(err);
            }
        });
    }))
    .then((tiles) => callback(null, Object.assign({}, ...tiles)))
    .catch((err) => callback(err));
};

module.exports = MapnikSource;
<|endoftext|>


<commit_before>export default class SDFShader {
  static Voxel() {
    return `
      struct Voxel
      {
        vec4 coord;
        vec4 material;
      };
    `
  }

  static sdfBox() {
    return `
      Voxel sdfBox(vec3 position, vec3 box, vec4 material) {
        return Voxel(vec4(position, length(max(abs(position) - box, 0.0))), material);
      }
    `;
  }

  static sdfEllipsoid() {
    return `
      Voxel sdfEllipsoid(vec3 position, vec3 box, vec4 material) {
        return Voxel(vec4(position, (length(position / box) - 1.0) * min(min(box.x, box.y), box.z)), material);
      }
    `;
  }

  static sdfSphere() {
    return `
      Voxel sdfSphere(vec3 position, float radius, vec4 material) {
        return Voxel(vec4(position, length(position) - radius), material);
      }
    `;
  }

  static smoothMin() {
    return `
      Voxel smoothMin(Voxel voxel1, Voxel voxel2, float blendRatio) {
        float ratio = clamp(.5 + .5 * (voxel2.coord.w - voxel1.coord.w) / blendRatio, 0., 1.);

        vec4 coord = mix(voxel2.coord, voxel1.coord, ratio) - blendRatio * ratio * (1. - ratio);
        vec4 material = mix(voxel2.material, voxel1.material, ratio);

        return Voxel(coord, material);
      }
    `;
  }

  static min() {
    return `
    Voxel min(Voxel voxel1, Voxel voxel2) {
      if(voxel1.coord.w < voxel2.coord.w) {
        return voxel1;
      }
      else {
        return voxel2;
      }
    }
    `;
  }

  static substraction() {
    return `
      Voxel substraction(Voxel voxel1, Voxel voxel2)
      {
        voxel1.coord.w = max(-voxel2.coord.w, voxel1.coord.w);
        return voxel1;
      }
    `
  }

  static repeat() {
    return `
      float repeat(float p, float c) {
        return mod(p,c) - 0.5 * c;
      }

      vec2 repeat(vec2 p, vec2 c) {
        return mod(p,c) - 0.5 * c;
      }

      vec3 repeat(vec3 p, vec3 c) {
        return mod(p,c) - 0.5 * c;
      }
    `;
  }

  static rayMarch({
    map = `
      Voxel voxel = Voxel(0., vec4(0.));
      return voxel;
    `,
    maxSteps = 128
  } = {}) {
    return `
      Voxel map(vec3 position) {
        ${map}
      }

      vec3 normalFromPosition(vec3 position, float step) {
        vec2 e = vec2(step, 0.0);
        return normalize(vec3(
          map(position + e.xyy).coord.w - map(position - e.xyy).coord.w,
          map(position + e.yxy).coord.w - map(position - e.yxy).coord.w,
          map(position + e.yyx).coord.w - map(position - e.yyx).coord.w
        ));
      }

      Voxel rayMarch(Ray ray, float near, float far, int steps)
      {
        Voxel voxel;

        float rayMarchingStep = far;
        float distance = near;

        for(int i = 0; i < ${maxSteps}; i++) {
          if (i == steps || rayMarchingStep < 0.0001 || distance > far) break;
          voxel = map(ray.origin + ray.direction * distance);
          rayMarchingStep = voxel.coord.w;
          distance += rayMarchingStep;
        }

        voxel.coord.w = distance;
        voxel = min(voxel, Voxel(vec4(0., 0., 0., far), vec4(0.)));

        return voxel;
      }

      Voxel rayMarchFromCamera(vec2 position, Camera camera, int steps) {
        Ray ray = rayFromCamera(position, camera);
        Voxel voxel = rayMarch(ray, camera.near, camera.far, steps);
        return voxel;
      }
    `;
  }
}

// Voxel rayMarchTerrain(vec3 rayOrigin, vec3 rayDirection)
// {
//   Voxel voxel = Voxel(uCamera.far, vec4(0.0));
//
//   float lastHeight = 0.;
//   float lastY = 0.;
//
//   float distance = 0.;
//
//   float steps = 200.;
//   float step = pow(steps, 1./steps);
//   // const float step = 1.0789723114;
//
//   float distanceToPlane = -dot(rayOrigin, vec3(0., 1., 0.)) / dot(rayDirection, vec3(0., 1., 0.));
//
//
//   for(float i = 0.; i < 200.; i++) {
//     distance = distanceToPlane - steps + i;
//     // distance = pow(step, i);
//     vec3 p = rayOrigin + rayDirection * distance;
//     float height = height(p);
//
//     if(p.y < height) {
//         // interpolate the intersection distanceance
//         // resT = t - dt + dt * (lastHeight - lastY) / (p.y - lastY - h + lastHeight);
//         voxel.material = vec4(vec3(p.y / scale), 1.0);
//         break;
//     }
//
//     // step = 0.01 * distance;
//     lastHeight = height;
//     lastY = p.y;
//
//     // rayMarchingStep = voxel.coord.w;
//     // distance += rayMarchingStep;
//     // voxel.coord.w = distance;
//   }
//
//   // vec3 normal = calcNormal(rayOrigin + rayDirection * distance);
//   // voxel.material *= 1. + dot(normal, normalize(vec3(cos(uTime * 100.), cos(uTime * 100.), sin(uTime * 100.))));
//
//   return voxel;
// }<commit_msg>prefix sdfShader methods for WebGL2<commit_after>export default class SDFShader {
  static Voxel() {
    return `
      struct Voxel
      {
        vec4 coord;
        vec4 material;
      };
    `
  }

  static sdfBox() {
    return `
      Voxel sdfBox(vec3 position, vec3 box, vec4 material) {
        return Voxel(vec4(position, length(max(abs(position) - box, 0.0))), material);
      }
    `;
  }

  static sdfEllipsoid() {
    return `
      Voxel sdfEllipsoid(vec3 position, vec3 box, vec4 material) {
        return Voxel(vec4(position, (length(position / box) - 1.0) * min(min(box.x, box.y), box.z)), material);
      }
    `;
  }

  static sdfSphere() {
    return `
      Voxel sdfSphere(vec3 position, float radius, vec4 material) {
        return Voxel(vec4(position, length(position) - radius), material);
      }
    `;
  }

  static sdfSmoothMin() {
    return `
      Voxel sdfSmoothMin(Voxel voxel1, Voxel voxel2, float blendRatio) {
        float ratio = clamp(.5 + .5 * (voxel2.coord.w - voxel1.coord.w) / blendRatio, 0., 1.);

        vec4 coord = mix(voxel2.coord, voxel1.coord, ratio) - blendRatio * ratio * (1. - ratio);
        vec4 material = mix(voxel2.material, voxel1.material, ratio);

        return Voxel(coord, material);
      }
    `;
  }

  static sdfMin() {
    return `
    Voxel sdfMin(Voxel voxel1, Voxel voxel2) {
      if(voxel1.coord.w < voxel2.coord.w) {
        return voxel1;
      }
      else {
        return voxel2;
      }
    }
    `;
  }

  static sdfTransform() {
    return `
    vec3 sdfTransform(vec3 position, mat4 transform) {
      position = inverse(transform) * position;
      return position;
    }
    `;
  }

  static sdfSubstraction() {
    return `
      Voxel sdfSubstraction(Voxel voxel1, Voxel voxel2)
      {
        voxel1.coord.w = max(-voxel2.coord.w, voxel1.coord.w);
        return voxel1;
      }
    `
  }

  static sdfRepeat() {
    return `
      float sdfRepeat(float p, float c) {
        return mod(p,c) - 0.5 * c;
      }

      vec2 sdfRepeat(vec2 p, vec2 c) {
        return mod(p,c) - 0.5 * c;
      }

      vec3 sdfRepeat(vec3 p, vec3 c) {
        return mod(p,c) - 0.5 * c;
      }
    `;
  }

  static rayMarch({
    map = `
      Voxel voxel = Voxel(0., vec4(0.));
      return voxel;
    `,
    maxSteps = 128
  } = {}) {
    return `
      Voxel map(vec3 position) {
        ${map}
      }

      vec3 normalFromPosition(vec3 position, float step) {
        vec2 e = vec2(step, 0.0);
        return normalize(vec3(
          map(position + e.xyy).coord.w - map(position - e.xyy).coord.w,
          map(position + e.yxy).coord.w - map(position - e.yxy).coord.w,
          map(position + e.yyx).coord.w - map(position - e.yyx).coord.w
        ));
      }

      Voxel rayMarch(Ray ray, float near, float far, int steps)
      {
        Voxel voxel;

        float rayMarchingStep = far;
        float distance = near;

        for(int i = 0; i < ${maxSteps}; i++) {
          if (i == steps || rayMarchingStep < 0.0001 || distance > far) break;
          voxel = map(ray.origin + ray.direction * distance);
          rayMarchingStep = voxel.coord.w;
          distance += rayMarchingStep;
        }

        voxel.coord.w = distance;
        voxel = sdfMin(voxel, Voxel(vec4(0., 0., 0., far), vec4(0.)));

        return voxel;
      }

      Voxel rayMarchFromCamera(vec2 position, Camera camera, int steps) {
        Ray ray = rayFromCamera(position, camera);
        Voxel voxel = rayMarch(ray, camera.near, camera.far, steps);
        return voxel;
      }
    `;
  }
}

// Voxel rayMarchTerrain(vec3 rayOrigin, vec3 rayDirection)
// {
//   Voxel voxel = Voxel(uCamera.far, vec4(0.0));
//
//   float lastHeight = 0.;
//   float lastY = 0.;
//
//   float distance = 0.;
//
//   float steps = 200.;
//   float step = pow(steps, 1./steps);
//   // const float step = 1.0789723114;
//
//   float distanceToPlane = -dot(rayOrigin, vec3(0., 1., 0.)) / dot(rayDirection, vec3(0., 1., 0.));
//
//
//   for(float i = 0.; i < 200.; i++) {
//     distance = distanceToPlane - steps + i;
//     // distance = pow(step, i);
//     vec3 p = rayOrigin + rayDirection * distance;
//     float height = height(p);
//
//     if(p.y < height) {
//         // interpolate the intersection distanceance
//         // resT = t - dt + dt * (lastHeight - lastY) / (p.y - lastY - h + lastHeight);
//         voxel.material = vec4(vec3(p.y / scale), 1.0);
//         break;
//     }
//
//     // step = 0.01 * distance;
//     lastHeight = height;
//     lastY = p.y;
//
//     // rayMarchingStep = voxel.coord.w;
//     // distance += rayMarchingStep;
//     // voxel.coord.w = distance;
//   }
//
//   // vec3 normal = calcNormal(rayOrigin + rayDirection * distance);
//   // voxel.material *= 1. + dot(normal, normalize(vec3(cos(uTime * 100.), cos(uTime * 100.), sin(uTime * 100.))));
//
//   return voxel;
// }<|endoftext|>


<commit_before>Minionette.CollectionView = Minionette.View.extend({
    constructor: function(options) {
        Minionette.View.apply(this, arguments);

        // Listen to the default events
        this._listenEvents();
    },

    render: function() {
        this.$el.html(this.template(this.collection));
        var ModelView = this._getModelView();

        this.collection.each(function(model) {
            this._addModelView(model, ModelView);
        }, this);

        return this;
    },

    addOne: function(model) {
        var ModelView = this._getModelView();
        this._addModelView(model, ModelView);
    },

    removeOne: function(model) {
        var view = this._findSubViewByModel(model);
        this._removeModelView(view);
    },

    _addModelView: function(model, ModelView) {
        var modelView = new ModelView({model: model});
        this._subViews[modelView.cid] = modelView;
        this.$el.append(modelView.render().el);
    },

    _getModelView: function() {
        var ModelView = this.ModelView;
        if (this.options && this.options.ModelView) {
            ModelView = this.option.ModelView;
        }
        return ModelView;
    },

    _listenEvents: function() {
        if (this.collection){
            this.listenTo(this.collection, "add", this.addOne, this);
            this.listenTo(this.collection, "remove", this.removeOne, this);
            this.listenTo(this.collection, "reset", this.render, this);
        }
    },

    _removeModelView: function(view) {
        if (view) {
            view.close();
            delete this._subViews[view.cid];
        }
    },

    _findSubViewByModel: function(model) {
        return _.findWhere(this._subViews, {model: model});
    }
});
<commit_msg>Use collectionEvents to bind CollectionView's events<commit_after>Minionette.CollectionView = Minionette.View.extend({

    // Listen to the default events
    collectionEvents: {
        'add': 'addOne',
        'remove': 'removeOne',
        'reset': 'render'
    },

    render: function() {
        this.$el.html(this.template(this.collection));
        var ModelView = this._getModelView();

        this.collection.each(function(model) {
            this._addModelView(model, ModelView);
        }, this);

        return this;
    },

    addOne: function(model) {
        var ModelView = this._getModelView();
        this._addModelView(model, ModelView);
    },

    removeOne: function(model) {
        var view = this._findSubViewByModel(model);
        this._removeModelView(view);
    },

    _addModelView: function(model, ModelView) {
        var modelView = new ModelView({model: model});
        this._subViews[modelView.cid] = modelView;
        this.$el.append(modelView.render().el);
    },

    _getModelView: function() {
        var ModelView = this.ModelView;
        if (this.options && this.options.ModelView) {
            ModelView = this.option.ModelView;
        }
        return ModelView;
    },

    _removeModelView: function(view) {
        if (view) {
            view.close();
            delete this._subViews[view.cid];
        }
    },

    _findSubViewByModel: function(model) {
        return _.findWhere(this._subViews, {model: model});
    }
});
<|endoftext|>


<commit_before>'use strict';

let connect = require('connect'),
    http = require('http'),
    serveStatic = require('serve-static'),
    serveIndex = require('serve-index'),
    moment = require('moment'),
    webpackDevMiddleware = require("webpack-dev-middleware");

let Manager = require('../modules/manager.js');

exports.usage = "开发服务";

exports.setOptions = (optimist) => {
    optimist.alias('h', 'hot');
    optimist.describe('h', '热加载');
    optimist.alias('s', 'https');
    optimist.describe('s', '使用https协议');
    optimist.alias('p', 'port');
    optimist.describe('p', '端口');
    optimist.alias('m', 'middlewares');
    optimist.describe('m', '加载项目中间件');
};

exports.run = (options) => {
    let app = connect(),
        cwd = options.cwd,
        hot = options.h || options.hot,
        middlewares = options.m || options.middlewares,
        https = options.s || options.https,
        port = options.p || options.port || 80;

    let middlewareCache = {};

    if (middlewares) {
        middlewares.split('|').forEach((proName) => {
            let pro = Manager.getProject(sysPath.join(cwd, proName)).readConfig({
                server: true
            });
            if (pro.check() && Array.isArray(pro.middlewares)) {
                pro.middlewares.forEach((mw) => app.use(mw));
            }
        })
    }

    // logger
    app.use(function() {
        const dateFormat = 'YY.MM.DD HH:mm:ss';
        const parse = function(req, res, format) {
            const status = (function() {
        		switch (true) {
        			case 500 <= res.statusCode:
        				return '\x1b[31m';
        			case 400 <= res.statusCode:
        				return '\x1b[33m';
        			case 300 <= res.statusCode:
        				return '\x1b[36m';
        			case 200 <= res.statusCode:
        				return '\x1b[32m';
        		}
        	})();

            let contentLength = res._contentLength || '';
            if(contentLength){
                contentLength = contentLength > 1024
                                ? (contentLength / 1024).toFixed(2) + 'kb '
                                : contentLength + 'b ';
            }

        	format = format.replace(/%date/g, "\x1b[90m" + '[' + (moment().format(dateFormat)) + ']' + "\x1b[0m");
        	format = format.replace(/%method/g, "\x1b[35m" + (req.method.toUpperCase()) + "\x1b[0m");
        	format = format.replace(/%url/g, "\x1b[90m" + options.cwd + decodeURI(req.originalUrl) + "\x1b[0m");
        	format = format.replace(/%status/g, "" + status + res.statusCode + "\x1b[0m");
            format = format.replace(/%route/g, "\x1b[90m" + (req.route ? req.route.path + ' ' : '\x1b[31m') + "\x1b[0m");
        	format = format.replace(/%contentLength/g, "\x1b[90m" + contentLength + '\x1b[31m' + "\x1b[0m");
        	format = format.replace(/%(date|time)/g, "\x1b[90m" + (new Date - req._startTime) + "ms\x1b[0m");
        	return format;
        };

        return function(req, res, next) {
            const end = res.end;
        	req._startTime = new Date;

        	res.end = function(chunk, encoding) {
        		res.end = end;
        		res.end(chunk, encoding);
                const format = '%date %status %method %url (%route%contentLength%time)'
        		const message = parse(req, res, format);
        		return process.nextTick(function() {
        			return info(message);
        		});
        	};
        	return next();
        };
    }());

    app.use(function(req, res, next) {
        let url = req.url,
            keys = url.split('/');

        if (keys[2] == 'prd') {
            let projectName = keys[1],
                projectCwd = sysPath.join(cwd, projectName),
                middleware = middlewareCache[projectName];

            if (!middleware) {
                let project = Manager.getProject(projectCwd).readConfig({
                    server: true
                });
                if (project.check()) {
                    let compiler = project.getCompiler();
                    middleware = middlewareCache[projectName] = webpackDevMiddleware(compiler, {
                        noInfo: true
                        // hot: hot TODO
                    });
                } else {
                    next();
                    return;
                }
            }
            req.url = '/' + keys.slice(3).join('/').replace(/(\@[\d\w]+)?\.(js|css)/, '.$2');
            middleware(req, res, next);
        } else {
            next();
        }
    });

    app.use(serveStatic(cwd, {
        redirect: false,
        index: false
    }));

    app.use(serveIndex(cwd));

    http.createServer(app).listen(port);
    info('Listening on port ' + port)
};
<commit_msg>fix(server): logger url改用相对路径（考虑一些工程相对路径已经很长了...所以不用绝对路径）<commit_after>'use strict';

let connect = require('connect'),
    http = require('http'),
    serveStatic = require('serve-static'),
    serveIndex = require('serve-index'),
    moment = require('moment'),
    webpackDevMiddleware = require("webpack-dev-middleware");

let Manager = require('../modules/manager.js');

exports.usage = "开发服务";

exports.setOptions = (optimist) => {
    optimist.alias('h', 'hot');
    optimist.describe('h', '热加载');
    optimist.alias('s', 'https');
    optimist.describe('s', '使用https协议');
    optimist.alias('p', 'port');
    optimist.describe('p', '端口');
    optimist.alias('m', 'middlewares');
    optimist.describe('m', '加载项目中间件');
};

exports.run = (options) => {
    let app = connect(),
        cwd = options.cwd,
        hot = options.h || options.hot,
        middlewares = options.m || options.middlewares,
        https = options.s || options.https,
        port = options.p || options.port || 80;

    let middlewareCache = {};

    if (middlewares) {
        middlewares.split('|').forEach((proName) => {
            let pro = Manager.getProject(sysPath.join(cwd, proName)).readConfig({
                server: true
            });
            if (pro.check() && Array.isArray(pro.middlewares)) {
                pro.middlewares.forEach((mw) => app.use(mw));
            }
        })
    }

    // logger
    app.use(function() {
        const dateFormat = 'YY.MM.DD HH:mm:ss';
        const parse = function(req, res, format) {
            const status = (function() {
        		switch (true) {
        			case 500 <= res.statusCode:
        				return '\x1b[31m';
        			case 400 <= res.statusCode:
        				return '\x1b[33m';
        			case 300 <= res.statusCode:
        				return '\x1b[36m';
        			case 200 <= res.statusCode:
        				return '\x1b[32m';
        		}
        	})();

            let contentLength = res._contentLength || '';
            if(contentLength){
                contentLength = contentLength > 1024
                                ? (contentLength / 1024).toFixed(2) + 'kb '
                                : contentLength + 'b ';
            }

        	format = format.replace(/%date/g, "\x1b[90m" + '[' + (moment().format(dateFormat)) + ']' + "\x1b[0m");
        	format = format.replace(/%method/g, "\x1b[35m" + (req.method.toUpperCase()) + "\x1b[0m");
        	format = format.replace(/%url/g, "\x1b[90m" + decodeURI(req.originalUrl) + "\x1b[0m");
        	format = format.replace(/%status/g, "" + status + res.statusCode + "\x1b[0m");
            format = format.replace(/%route/g, "\x1b[90m" + (req.route ? req.route.path + ' ' : '\x1b[31m') + "\x1b[0m");
        	format = format.replace(/%contentLength/g, "\x1b[90m" + contentLength + '\x1b[31m' + "\x1b[0m");
        	format = format.replace(/%(date|time)/g, "\x1b[90m" + (new Date - req._startTime) + "ms\x1b[0m");
        	return format;
        };

        return function(req, res, next) {
            const end = res.end;
        	req._startTime = new Date;

        	res.end = function(chunk, encoding) {
        		res.end = end;
        		res.end(chunk, encoding);
                const format = '%date %status %method %url (%route%contentLength%time)'
        		const message = parse(req, res, format);
        		return process.nextTick(function() {
        			return info(message);
        		});
        	};
        	return next();
        };
    }());

    app.use(function(req, res, next) {
        let url = req.url,
            keys = url.split('/');

        if (keys[2] == 'prd') {
            let projectName = keys[1],
                projectCwd = sysPath.join(cwd, projectName),
                middleware = middlewareCache[projectName];

            if (!middleware) {
                let project = Manager.getProject(projectCwd).readConfig({
                    server: true
                });
                if (project.check()) {
                    let compiler = project.getCompiler();
                    middleware = middlewareCache[projectName] = webpackDevMiddleware(compiler, {
                        noInfo: true
                        // hot: hot TODO
                    });
                } else {
                    next();
                    return;
                }
            }
            req.url = '/' + keys.slice(3).join('/').replace(/(\@[\d\w]+)?\.(js|css)/, '.$2');
            middleware(req, res, next);
        } else {
            next();
        }
    });

    app.use(serveStatic(cwd, {
        redirect: false,
        index: false
    }));

    app.use(serveIndex(cwd));

    http.createServer(app).listen(port);
    info('Listening on port ' + port)
};
<|endoftext|>


<commit_before>/* @flow */
import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';

import type { ChildrenArray, Context, Style } from '../types';

const componentStyles = StyleSheet.create({
  centerer: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
  },
  inner: {
    width: '100%',
    maxWidth: 480,
  },
});

type Props = {
  style?: Style,
  children: ChildrenArray<*>,
  padding: boolean,
};

export default class Centerer extends PureComponent<Props> {
  context: Context;
  props: Props;

  static contextTypes = {
    styles: () => null,
  };

  static defaultProps = {
    padding: false,
  };

  render() {
    const { styles } = this.context;
    const { children, padding, style } = this.props;

    return (
      <View style={[componentStyles.centerer, padding && styles.padding, style]}>
        <View style={componentStyles.inner}>{children}</View>
      </View>
    );
  }
}
<commit_msg>jsdoc: Document Centerer component.<commit_after>/* @flow */
import React, { PureComponent } from 'react';
import { StyleSheet, View } from 'react-native';

import type { ChildrenArray, Context, Style } from '../types';

const componentStyles = StyleSheet.create({
  centerer: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
  },
  inner: {
    width: '100%',
    maxWidth: 480,
  },
});

type Props = {
  style?: Style,
  children: ChildrenArray<*>,
  padding: boolean,
};

/**
 * A layout component that centers wrapped components
 * horizontally and vertically.
 *
 * @prop [style] - Apply styles to wrapper component.
 * @prop children - Components to be centered.
 * @prop [padding] - Specifies if the components should be padded.
 */
export default class Centerer extends PureComponent<Props> {
  context: Context;
  props: Props;

  static contextTypes = {
    styles: () => null,
  };

  static defaultProps = {
    padding: false,
  };

  render() {
    const { styles } = this.context;
    const { children, padding, style } = this.props;

    return (
      <View style={[componentStyles.centerer, padding && styles.padding, style]}>
        <View style={componentStyles.inner}>{children}</View>
      </View>
    );
  }
}
<|endoftext|>


<commit_before>
// Sets up default options and initializes blockly
startTiming('Puzzle', script_path, '');
var baseOptions = {
  containerId: 'blocklyApp',
  Dialog: Dialog,
  cdoSounds: CDOSounds,
  position: { blockYCoordinateInterval: 25 },
  onInitialize: function() {
    this.createCallouts();
    if (window.wrapExistingClipPaths && window.handleClipPathChanges) {
      wrapExistingClipPaths();
      handleClipPathChanges();
    }
    $(document).trigger('appInitialized');
  },
  createCallouts: function() {
    $.fn.qtip.zindex = 500;
    this.callouts && this.callouts.every(function(callout) {
      var selector = callout.element_id; // jquery selector.
      if ($(selector).length === 0 && !callout.on) {
        return true;
      }

      var defaultConfig = {
        content: {
          text: callout.localized_text,
          title: {
            button: $('
')
          }
        },
        style: {
          classes: "",
          tip: {
            width: 20,
            height: 20
          }
        },
        position: {
          my: "bottom left",
          at: "top right"
        },
        hide: {
          event: 'click mousedown touchstart'
        },
        show: false // don't show on mouseover
      };

      var customConfig = $.parseJSON(callout.qtip_config);
      var config = $.extend(true, {}, defaultConfig, customConfig);
      config.style.classes = config.style.classes.concat(" cdo-qtips");

      // Reverse callouts in RTL mode
      if (Blockly.RTL) {
        config.position.my = reverseCallout(config.position.my);
        config.position.at = reverseCallout(config.position.at);
        if (config.position.adjust) {
          config.position.adjust.x *= -1;
        }
      }

      if (callout.on) {
        window.addEventListener(callout.on, function() {
          if (!callout.seen && $(selector).length > 0) {
            callout.seen = true;
            $(selector).qtip(config).qtip('show');
          }
        });
      } else {
        $(selector).qtip(config).qtip('show');
      }

      return true;
    });
  },
  onAttempt: function(report) {
    if (appOptions.level.isProjectLevel) {
      return;
    }
    report.fallbackResponse = appOptions.report.fallback_response;
    report.callback = appOptions.report.callback;
    // Track puzzle attempt event
    trackEvent('Puzzle', 'Attempt', script_path, report.pass ? 1 : 0);
    if (report.pass) {
      trackEvent('Puzzle', 'Success', script_path, report.attempt);
      stopTiming('Puzzle', script_path, '');
    }
    trackEvent('Activity', 'Lines of Code', script_path, report.lines);
    sendReport(report);
  },
  onResetPressed: function() {
    cancelReport();
  },
  onContinue: function() {
    if (lastServerResponse.videoInfo) {
      showVideoDialog(lastServerResponse.videoInfo);
    } else if (lastServerResponse.nextRedirect) {
      window.location.href = lastServerResponse.nextRedirect;
    }
  },
  backToPreviousLevel: function() {
    if (lastServerResponse.previousLevelRedirect) {
      window.location.href = lastServerResponse.previousLevelRedirect;
    }
  },
  showInstructionsWrapper: function(showInstructions) {
    var hasInstructions = appOptions.level.instructions || appOptions.level.aniGifURL;
    if (!hasInstructions || this.share || appOptions.level.skipInstructionsPopup) {
      return;
    }

    if (appOptions.autoplayVideo) {
      showVideoDialog(appOptions.autoplayVideo);
      $('.video-modal').on('hidden.bs.modal', function () {
        showInstructions();
      });
    } else {
      showInstructions();
    }
  }
};
$.extend(appOptions, baseOptions);

function reverseDirection(token) {
  if (/left/i.test(token)) {
    token = 'right';
  } else if (/right/i.test(token)) {
    token = 'left';
  }
  return token;
}
function reverseCallout(position) {
  position = position.split(/\s+/);
  var a = position[0];
  var b = position[1];
  return reverseDirection(a) + reverseDirection(b);
}
// Hide callouts when the function editor is closed (otherwise they jump to the top left corner)
$(window).on('function_editor_closed', function() {
  $('.cdo-qtips').qtip('hide');
});
// Turn string values into functions for keys that begin with 'fn_' (JSON can't contain function definitions)
// E.g. { fn_example: 'function () { return; }' } becomes { example: function () { return; } }
(function fixUpFunctions(node) {
  if (typeof node !== 'object') return;
  for (var i in node) {
    if (/^fn_/.test(i)) {
      try {
        node[i.replace(/^fn_/, '')] = eval('(' + node[i] + ')');
      } catch (e) { }
    } else {
      fixUpFunctions(node[i]);
    }
  }
})(appOptions.level);

/**
 * Only execute the given argument if it is a function.
 * @param callback
 */
function callbackSafe(callback, data) {
  if (typeof callback === 'function') {
    callback(data);
  }
}

dashboard.updateTimestamp = function() {
  if (dashboard.currentApp.updatedAt) {
    // TODO i18n
    $('.project_updated_at').empty().append("Saved ")  // TODO i18n
        .append($('').attr('title', dashboard.currentApp.updatedAt)).show();
    $('.project_updated_at span.timestamp').timeago();
  } else {
    $('.project_updated_at').text("Click 'Run' to save"); // TODO i18n
  }
}

dashboard.saveProject = function(callback) {
  $('.project_updated_at').text('Saving...');  // TODO (Josh) i18n
  var app_id = dashboard.currentApp.id;
  dashboard.currentApp.levelSource = window.Blockly
      ? Blockly.Xml.domToText(Blockly.Xml.blockSpaceToDom(Blockly.mainBlockSpace))
      : Applab.getCode();
  dashboard.currentApp.level = window.location.pathname;
  if (app_id) {
    storageApps().update(app_id, dashboard.currentApp, function(data) {
      dashboard.currentApp = data;
      dashboard.updateTimestamp();
      callbackSafe(callback, data);
    });
  } else {
    storageApps().create(dashboard.currentApp, function(data) {
      dashboard.currentApp = data;
      location.hash = dashboard.currentApp.id + '/edit';
      dashboard.updateTimestamp();
      callbackSafe(callback, data);
    });
  }
};

dashboard.deleteProject = function(callback) {
  var app_id = dashboard.currentApp.id;
  if (app_id) {
    storageApps().delete(app_id, function(data) {
      callbackSafe(callback, data);
    });
  } else {
    callbackSafe(callback, false);
  }
};

dashboard.loadEmbeddedProject = function(projectTemplateLevelName) {
  var deferred = new $.Deferred();
  // get all projects (TODO: filter on server side?)
  storageApps().all(function(data) {
    if (data) {
      // find the one that matches this level
      var projects = $.grep(data, function(app) {
        return (app.projectTemplateLevelName &&
                app.projectTemplateLevelName === projectTemplateLevelName);
      });
      if (projects.length == 0) {
        // create a new project
        var options = {
          projectTemplateLevelName: projectTemplateLevelName,
          name: projectTemplateLevelName,
          hidden: true
        };
        storageApps().create(options, function(app) {
          if (app) {
            dashboard.currentApp = app;
            deferred.resolve();
          } else {
            deferred.reject(); // failed to create project
          }
        });
      } else {
        // use the existing project
        dashboard.currentApp = projects[0];
        deferred.resolve();
      }
    } else {
      deferred.reject(); // failed to list projects
    }
  });
  return deferred;
};

function initApp() {
  if (appOptions.level.isProjectLevel || dashboard.currentApp) {
    if (dashboard.isEditingProject) {
      if (dashboard.currentApp) {
        if (dashboard.currentApp.levelSource) {
          appOptions.level.startBlocks = dashboard.currentApp.levelSource;
        }
      } else {
        dashboard.currentApp = {
          name: 'My Project'
        };
      }

      $(window).on('run_button_pressed', dashboard.saveProject);

      if (!dashboard.currentApp.hidden) {
        dashboard.showProjectHeader();
      }
    } else if (dashboard.currentApp && dashboard.currentApp.levelSource) {
      appOptions.level.startBlocks = dashboard.currentApp.levelSource;
      appOptions.hideSource = true;
      appOptions.callouts = [];
    }
  }
  window[appOptions.app + 'Main'](appOptions);
}

// Returns a function which returns a $.Deferred instance. When executed, the
// function loads the given app script.
function loadSource(name) {
  return function () {
    var deferred = new $.Deferred();
    document.body.appendChild($('


<commit_before>var barcodescanner = require("./barcodescanner-common");
var frame = require("ui/frame");
var utils = require("utils/utils");

barcodescanner.available = function () {
  return new Promise(function (resolve) {
    resolve(QRCodeReader.isAvailable());
  });
};

// TODO consider giving camera PERMISSION beforehand: https://github.com/yannickl/QRCodeReaderViewController/issues/4,
// would fit well with the Android 6 implementation.
barcodescanner.scan = function (arg) {
  return new Promise(function (resolve, reject) {
    try {
      arg = arg || {};
      var closeButtonLabel = arg.cancelLabel || "Close";

      var types = [];
      if (arg.formats) {
        var formats = arg.formats.split(",");
        for (var f in formats) {
          var format = formats[f].trim();
          console.log("---- format: " + format);
          if (format === "QR_CODE") types.push(AVMetadataObjectTypeQRCode);
          else if (format === "PDF_417") types.push(AVMetadataObjectTypePDF417Code);
          else if (format === "AZTEC") types.push(AVMetadataObjectTypeAztecCode);
          else if (format === "UPC_E") types.push(AVMetadataObjectTypeUPCECode);
          else if (format === "CODE_39") types.push(AVMetadataObjectTypeCode39Code);
          else if (format === "CODE_39_MOD_43") types.push(AVMetadataObjectTypeCode39Mod43Code);
          else if (format === "CODE_93") types.push(AVMetadataObjectTypeCode93Code);
          else if (format === "CODE_128") types.push(AVMetadataObjectTypeCode128Code);
          else if (format === "EAN_8") types.push(AVMetadataObjectTypeEAN8Code);
          else if (format === "EAN_13") types.push(AVMetadataObjectTypeEAN13Code);
        }
      } else {
        types = [AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code,
          AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code,
          AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];
      }

      var bs = QRCodeReaderViewController.readerWithCancelButtonTitleMetadataObjectTypes(closeButtonLabel, types);
      bs.modalPresentationStyle = UIModalPresentationFormSheet;

      // Assign first to local variable, otherwise it will be garbage collected since delegate is weak reference.
      var delegate = QRCodeReaderDelegateImpl.new().initWithCallback(function (reader, text, type) {
        // invoke the callback / promise
        if (text === undefined) {
          reject("Scan aborted");
        } else {
          resolve({
            format : type,
            text : text
          });
        }
        // Remove the local variable for the delegate.
        delegate = undefined;
      });
      bs.delegate = delegate;

      var topMostFrame = frame.topmost();
      if (topMostFrame) {
        var vc = topMostFrame.currentPage && topMostFrame.currentPage.ios;
        if (vc) {
          vc.presentViewControllerAnimatedCompletion(bs, true, null);
        }
      }
    } catch (ex) {
      console.log("Error in barcodescanner.scan: " + ex);
      reject(ex);
    }
  });
};

var QRCodeReaderDelegateImpl = (function (_super) {
  __extends(QRCodeReaderDelegateImpl, _super);
  function QRCodeReaderDelegateImpl() {
    _super.apply(this, arguments);
  }

  QRCodeReaderDelegateImpl.new = function () {
    return _super.new.call(this);
  };
  QRCodeReaderDelegateImpl.prototype.initWithCallback = function (callback) {
    this._callback = callback;
    return this;
  };
  QRCodeReaderDelegateImpl.prototype.readerDidCancel = function (reader) {
    var app = utils.ios.getter(UIApplication, UIApplication.sharedApplication);
    app.keyWindow.rootViewController.dismissViewControllerAnimatedCompletion(true, null);
    this._callback(reader);
  };
  QRCodeReaderDelegateImpl.prototype.readerDidScanResultForType = function (reader, text, type) {
    var app = utils.ios.getter(UIApplication, UIApplication.sharedApplication);
    app.keyWindow.rootViewController.dismissViewControllerAnimatedCompletion(true, null);
    this._callback(reader, text, type);
  };
  QRCodeReaderDelegateImpl.ObjCProtocols = [QRCodeReaderDelegate];
  return QRCodeReaderDelegateImpl;
})(NSObject);

module.exports = barcodescanner;<commit_msg>UIApplication.sharedApplication is not a function #33<commit_after>var barcodescanner = require("./barcodescanner-common");
var frame = require("ui/frame");
var utils = require("utils/utils");

barcodescanner.available = function () {
  return new Promise(function (resolve) {
    // since this would also request permission...
    //   resolve(QRCodeReader.isAvailable());
    // ... and it's extremely likely to be 'true' anyway, I decided to hardcode this:
    resolve(true);
  });
};

// TODO consider asking camera PERMISSION beforehand: https://github.com/yannickl/QRCodeReaderViewController/issues/4,
// would fit well with the Android 6 implementation.
barcodescanner.scan = function (arg) {
  return new Promise(function (resolve, reject) {
    try {
      arg = arg || {};
      var closeButtonLabel = arg.cancelLabel || "Close";

      var types = [];
      if (arg.formats) {
        var formats = arg.formats.split(",");
        for (var f in formats) {
          var format = formats[f].trim();
          if (format === "QR_CODE") types.push(AVMetadataObjectTypeQRCode);
          else if (format === "PDF_417") types.push(AVMetadataObjectTypePDF417Code);
          else if (format === "AZTEC") types.push(AVMetadataObjectTypeAztecCode);
          else if (format === "UPC_E") types.push(AVMetadataObjectTypeUPCECode);
          else if (format === "CODE_39") types.push(AVMetadataObjectTypeCode39Code);
          else if (format === "CODE_39_MOD_43") types.push(AVMetadataObjectTypeCode39Mod43Code);
          else if (format === "CODE_93") types.push(AVMetadataObjectTypeCode93Code);
          else if (format === "CODE_128") types.push(AVMetadataObjectTypeCode128Code);
          else if (format === "EAN_8") types.push(AVMetadataObjectTypeEAN8Code);
          else if (format === "EAN_13") types.push(AVMetadataObjectTypeEAN13Code);
        }
      } else {
        types = [AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code,
          AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code,
          AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];
      }

      var bs = QRCodeReaderViewController.readerWithCancelButtonTitleMetadataObjectTypes(closeButtonLabel, types);
      bs.modalPresentationStyle = UIModalPresentationFormSheet;

      // Assign first to local variable, otherwise it will be garbage collected since delegate is weak reference.
      var delegate = QRCodeReaderDelegateImpl.new().initWithCallback(function (reader, text, type) {
        // invoke the callback / promise
        if (text === undefined) {
          reject("Scan aborted");
        } else {
          resolve({
            format : type,
            text : text
          });
        }
        // Remove the local variable for the delegate.
        delegate = undefined;
      });
      bs.delegate = delegate;

      var topMostFrame = frame.topmost();
      if (topMostFrame) {
        var vc = topMostFrame.currentPage && topMostFrame.currentPage.ios;
        if (vc) {
          vc.presentViewControllerAnimatedCompletion(bs, true, null);
        }
      }
    } catch (ex) {
      console.log("Error in barcodescanner.scan: " + ex);
      reject(ex);
    }
  });
};

var QRCodeReaderDelegateImpl = (function (_super) {
  __extends(QRCodeReaderDelegateImpl, _super);
  function QRCodeReaderDelegateImpl() {
    _super.apply(this, arguments);
  }

  QRCodeReaderDelegateImpl.new = function () {
    return _super.new.call(this);
  };
  QRCodeReaderDelegateImpl.prototype.initWithCallback = function (callback) {
    this._callback = callback;
    return this;
  };
  QRCodeReaderDelegateImpl.prototype.readerDidCancel = function (reader) {
    var app = utils.ios.getter(UIApplication, UIApplication.sharedApplication);
    app.keyWindow.rootViewController.dismissViewControllerAnimatedCompletion(true, null);
    this._callback(reader);
  };
  QRCodeReaderDelegateImpl.prototype.readerDidScanResultForType = function (reader, text, type) {
    var app = utils.ios.getter(UIApplication, UIApplication.sharedApplication);
    app.keyWindow.rootViewController.dismissViewControllerAnimatedCompletion(true, null);
    this._callback(reader, text, type);
  };
  QRCodeReaderDelegateImpl.ObjCProtocols = [QRCodeReaderDelegate];
  return QRCodeReaderDelegateImpl;
})(NSObject);

module.exports = barcodescanner;<|endoftext|>


<commit_before>'use strict';

const St = imports.gi.St;
const Main = imports.ui.main;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Util = imports.misc.util;

const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;

let text, button, label;
let clock, clock_signal_id;
let settings;

const format_with_seconds = new Intl.DateTimeFormat(
    'default',
    {
        hour: 'numeric',
        minute: 'numeric',
        second: 'numeric',
        hour12: false
    }
);
const format_without_seconds = new Intl.DateTimeFormat(
    'default',
    {
        hour: 'numeric',
        minute: 'numeric',
        hour12: false
    }
);
let seconds_displayed_format = format_without_seconds;

let time_text = 'UTC';

function init() {
    settings = Convenience.getSettings();
    settings.connect('changed::show-seconds', Lang.bind(this, setSecondsDisplayed));
    settings.connect('changed::time-text', Lang.bind(this, setTimeText));

    clock = new GnomeDesktop.WallClock();
    button = new St.Bin({
        style_class: 'panel-button',
        reactive: true,
        can_focus: false,
        x_fill: true,
        y_fill: false,
        y_align: St.Align.MIDDLE,
        track_hover: true
    });
    label = new St.Label({
        text: '00:00 ' + time_text,
        opacity: 200
    });

    button.set_child(label);
    button.connect('button-press-event', showMenu);
    setSecondsDisplayed();
    setTimeText();
}

function enable() {
    log(`enabling ${Me.metadata.name} version ${Me.metadata.version}`);
    update_time();
    clock_signal_id = clock.connect('notify::clock', Lang.bind(this, this.update_time));
    Main.panel._centerBox.insert_child_at_index(button, 1);
    log(`${Me.metadata.name} enabled.`);
}

function disable() {
    log(`disabling ${Me.metadata.name} version ${Me.metadata.version}`);
    Main.panel._centerBox.remove_child(button);
    clock.disconnect(clock_signal_id);
    log(`${Me.metadata.name} disabled.`);
}

function update_time() {
    var now = new Date();
    now.setHours(now.getUTCHours());
    now.setMinutes(now.getUTCMinutes());
    label.set_text(seconds_displayed_format.format(now) + ' ' + time_text);
}

function setSecondsDisplayed() {
    let secondsDisplayed = settings.get_boolean('show-seconds');
    seconds_displayed_format = secondsDisplayed ? format_with_seconds : format_without_seconds;
    update_time();
}

function setTimeText() {
    let text = settings.get_string('time-text');
    time_text = text;
    update_time();
}

function showMenu() {
    Util.spawn([
        "gnome-shell-extension-prefs",
        Me.uuid
    ]);
}<commit_msg>Better logging<commit_after>'use strict';

const St = imports.gi.St;
const Main = imports.ui.main;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Util = imports.misc.util;

const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;

let text, button, label;
let clock, clock_signal_id;
let settings;

const format_with_seconds = new Intl.DateTimeFormat(
    'default',
    {
        hour: 'numeric',
        minute: 'numeric',
        second: 'numeric',
        hour12: false
    }
);
const format_without_seconds = new Intl.DateTimeFormat(
    'default',
    {
        hour: 'numeric',
        minute: 'numeric',
        hour12: false
    }
);
let seconds_displayed_format = format_without_seconds;

let time_text = 'UTC';

function init() {
    settings = Convenience.getSettings();
    settings.connect('changed::show-seconds', Lang.bind(this, setSecondsDisplayed));
    settings.connect('changed::time-text', Lang.bind(this, setTimeText));

    clock = new GnomeDesktop.WallClock();
    button = new St.Bin({
        style_class: 'panel-button',
        reactive: true,
        can_focus: false,
        x_fill: true,
        y_fill: false,
        y_align: St.Align.MIDDLE,
        track_hover: true
    });
    label = new St.Label({
        text: '00:00 ' + time_text,
        opacity: 200
    });

    button.set_child(label);
    button.connect('button-press-event', showMenu);
    setSecondsDisplayed();
    setTimeText();
}

function enable() {
    log_this(`enabling...`);
    update_time();
    clock_signal_id = clock.connect('notify::clock', Lang.bind(this, this.update_time));
    Main.panel._centerBox.insert_child_at_index(button, 1);
    log_this(`enabled.`);
}

function disable() {
    log_this(`disabling...`);
    Main.panel._centerBox.remove_child(button);
    clock.disconnect(clock_signal_id);
    log_this(`disabled.`);
}

function update_time() {
    var now = new Date();
    now.setHours(now.getUTCHours());
    now.setMinutes(now.getUTCMinutes());
    label.set_text(seconds_displayed_format.format(now) + ' ' + time_text);
}

function setSecondsDisplayed() {
    let secondsDisplayed = settings.get_boolean('show-seconds');
    seconds_displayed_format = secondsDisplayed ? format_with_seconds : format_without_seconds;
    update_time();
}

function setTimeText() {
    let text = settings.get_string('time-text');
    time_text = text;
    update_time();
}

function showMenu() {
    Util.spawn([
        "gnome-shell-extension-prefs",
        Me.uuid
    ]);
}

function log_this(string) {
    log(`[${Me.metadata.name}-${Me.metadata.version}] ${string}`)
}<|endoftext|>


<commit_before>// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require("vscode");

const MermaidDocumentContentProvider = require("./content-provider");

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
function activate(context) {
  const registerCommand = vscode.commands.registerCommand;
  let previewUri = vscode.Uri.parse(
    "mermaid-preview://authority/mermaid-preview"
  );

  let provider = new MermaidDocumentContentProvider(context);
  let registration = vscode.workspace.registerTextDocumentContentProvider(
    "mermaid-preview",
    provider
  );

  // Use the console to output diagnostic information (console.log) and errors (console.error)
  // This line of code will only be executed once when your extension is activated
  // console.log('Congratulations, your extension "mermaid-preview" is now active!');

  // The command has been defined in the package.json file
  // Now provide the implementation of the command with  registerCommand
  // The commandId parameter must match the command field in package.json
  let disposable = registerCommand("extension.previewMermaidDiagram", () => {
    return vscode.commands
      .executeCommand(
        "vscode.previewHtml",
        previewUri,
        vscode.ViewColumn.Two,
        "Mermaid Preview"
      )
      .then(
        success => {},
        reason => {
          vscode.window.showErrorMessage(reason);
        }
      );
  });

  vscode.workspace.onDidChangeTextDocument(e => {
    if (e.document === vscode.window.activeTextEditor.document) {
      provider.update(previewUri);
    }
  });

  vscode.window.onDidChangeTextEditorSelection(e => {
    if (e.textEditor === vscode.window.activeTextEditor) {
      provider.update(previewUri);
    }
  });

  context.subscriptions.push(disposable, registration);

  return {
    extendMarkdownIt(md) {
      const highlight = md.options.highlight;
      md.options.highlight = (code, lang) => {
        if (lang && lang.toLowerCase() === "mermaid") {
          return `<div class="mermaid">${code}</div>`;
        }
        return highlight(code, lang);
      };
      return md;
    }
  };
}
exports.activate = activate;

// this method is called when your extension is deactivated
function deactivate() {}
exports.deactivate = deactivate;
<commit_msg>transitioned to webview<commit_after>// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require('vscode');
const findDiagram = require('./lib/find-diagram');

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
function activate(context) {
  const registerCommand = vscode.commands.registerCommand;

  let command = registerCommand('mermaidPreview.start', () => {
    const panel = vscode.window.createWebviewPanel(
      'mermaidPreview',
      'Mermaid Preview',
      vscode.ViewColumn.Two,
      {
        enableScripts: true
      }
    );

    const getContent = () => {
      const mermaidPath = 'node_modules/mermaid/dist/mermaid.min.js';
      const mermaidUrl = vscode.Uri.file(context.asAbsolutePath(mermaidPath)).with({
        scheme: 'vscode-resource'
      });

      const fsStylesheetPath = 'node_modules/font-awesome/css/font-awesome.min.css';
      const faBase = vscode.Uri.file(context.asAbsolutePath(fsStylesheetPath)).with({
        scheme: 'vscode-resource'
      });

      return `<!DOCTYPE html>

    <base href="">
    <link rel="stylesheet" href="${faBase}">

`;
    };

    const previewHandler = () => {
      const editor = vscode.window.activeTextEditor;
      const text = editor.document.getText();
      const cursor = editor.document.offsetAt(editor.selection.anchor);

      const diagram = findDiagram(text, cursor);

      panel.webview.postMessage({
        diagram
      });
    }

    vscode.workspace.onDidChangeTextDocument(e => {
      if (e.document === vscode.window.activeTextEditor.document) {
        previewHandler();
      }
    });

    vscode.window.onDidChangeTextEditorSelection(e => {
      if (e.textEditor === vscode.window.activeTextEditor) {
        previewHandler();
      }
    });

    panel.onDidDispose(() => {
      console.log('panel closed');
      clearInterval(interval);
    }, null, context.subscriptions);

    panel.webview.html = getContent();
  });

  context.subscriptions.push(command);

  return {
    extendMarkdownIt(md) {
      const highlight = md.options.highlight;
      md.options.highlight = (code, lang) => {
        if (lang && lang.toLowerCase() === "mermaid") {
          return `<div class="mermaid">${code}</div>`;
        }
        return highlight(code, lang);
      };
      return md;
    }
  };
}
exports.activate = activate;

// this method is called when your extension is deactivated
function deactivate() {}
exports.deactivate = deactivate;
<|endoftext|>