<commit_before>/*global myCanvas, keyDownHandler,  SCREEN_X, SCREEN_Y, INTERLACE, sound, screen, background, print_small, playfield, player1, ball, requestAnimationFrame*/
/*jslint node: true */
/*jslint bitwise: true*/
'use strict';
document.getElementById(myCanvas);

// Game states
var PAUSED = 1;
var READY = 0;
var PLAYING = 2;
var DONE = 3;

var cursor = [
    'XXXXX   ',
    'X   X   ',
    'X   X   ',
    'X   X   ',
    'XXXXX   ',

    '        ',
    '        ',
    '        ',
    '        ',
    '        '];

var blocky = [
    'XXXX    ',
    'XXXX    ',
    'XXXX    ',
    'XXXX    '];

var nemesis = [
    'XX      ',
    'XX      ',
    'XX      ',
    'X       ',
    'XX      ',
    'XX      ',
    'XX X    ',
    'XXXX    ',
    'XXX     ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XXX     ',
    'X       ',
    'XX      ',

    'XX      ',
    'XX X    ',
    'XX X    ',
    'X  X    ',
    'XX X    ',
    'XXXX    ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX XXX  ',
    'XXXX XX ',
    'XXXX  X ',
    ' XX   XX'];

var plyfd_fill = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
var tree_leavs = [
    'XXXXXXXXXXX  XXXXXXXXXXXXXX  XXXXXXXXXXX',
    'XXXXXXXXXX    XXXXXXXXXXXX    XXXXXXXXXX',
    'XXX  XXXX      XXXX  XXXX      XXXX  XXX',
    'XX    XX        XX    XX        XX    XX'];
var tree_trunk = '.........X.......X....X.......X.........S';

var branch1 = [
    '       X',
    '       X',
    '   XX  X',
    '   XX  X',
    'XX XX XX',
    ' XXXXXX '];

var branch2 = [
    '        ',
    '        ',
    '        ',
    '        ',
    '      XX',
    ' XXXXXX '];

var branch3 = [
    '        ',
    '        ',
    '        ',
    '        ',
    'XX      ',
    ' XXXXXX '];

var branch4 = [
    'X       ',
    'X       ',
    'X  XX   ',
    'X  XX   ',
    'XX XX XX',
    ' XXXXXX '];

var TREE_PANT_COLOR = 105;
var BACKGROUND_COLOR = 107;

var TRUNK_COLOR = 8;
var GROUND_COLOR = 12;

var DIRT_COLOR = 10;
var HAIR_LOG_COLOR = 9;

var FACE_COLOR = 37;
var SHIRT_COLOR = 100;

var BRICK_COLOR = 33;
var MORTAR_COLOR = 3;

var DARKESS_COLOR = 0;
var LETTERING_COLOR = 6;

var nem_color = [
    HAIR_LOG_COLOR,
    FACE_COLOR,
    FACE_COLOR,
    FACE_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR];

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

var thisTime = 0;
var lastTime = Date.now();
var dt = 1;

var game_state = READY;

var animation = 0.0;

var game_number = 0;

var color_p0 = 0;
var color_p1 = 16;
var color_pf = 3 + (8 * 8);
var color_bk1 = 104;
var color_bk2 = 107;

var sound_duration = 0;

var sound_vol = 0.3;
var freq_1 = 110;
var freq_2 = 44;
var type_1 = 'square';
var type_2 = 'square';

var x = 0;
var y = 0;

var i = 0;

document.addEventListener('keydown', keyDownHandler, false);

function onPause() {
    sound_duration = 0;
    sound(1, 0, freq_1, type_1);
    sound(2, 0, freq_2, type_2);
}

function onResume() {
    sound_duration = 0;
}

function onAmazonPlatformReady() {
    document.addEventListener("pause", onPause, false);
    document.addEventListener("resume", onResume, false);
}

document.addEventListener("amazonPlatformReady", onAmazonPlatformReady, false);

function keyDownHandler(event) {
    var key = event.which || event.keyCode;
    if (key === 38) {
        //up arrow
        if (SHIRT_COLOR > 0) {
            SHIRT_COLOR -= 1;
        } else {
            SHIRT_COLOR = 127;
        }
    }
    if (key === 40) {
        //down arrow

        if (SHIRT_COLOR < 127) {
            SHIRT_COLOR += 1;
        } else {
            SHIRT_COLOR = 0;
        }
    }

    if (key === 37) {
        //left arrow
        if (x > 0) {
            x -= 1;
        } else {
            x = 7;
        }
    }
    if (key === 39) {
        //right arrow

        if (x < 7) {
            x += 1;
        } else {
            x = 0;
        }
    }

    if ((key === 13) || (key === 32)) {
        x = 0;
    }
}

function draw() {
    var a,
        p_width = Math.trunc(window.innerWidth / SCREEN_X / INTERLACE),
        p_height = Math.trunc(window.innerHeight / SCREEN_Y);

    thisTime = Date.now();
    dt = thisTime - lastTime;
    lastTime = thisTime;

    dt = dt / 3;

    if (sound_duration > 1) {
        sound_duration -= 1;
    } else {
        sound(1, 0, freq_1, type_1);
        sound(2, 0, freq_2, type_2);
    }

    if (game_state === PLAYING) {
        game_state = READY;
        sound(1, sound_vol, freq_1, type_1);
        sound_duration = 2;
    }

    color_p1 = (color_p1 + 8) & 0x7F;
    animation += dt / 100.0;
    if (animation >= 4.0) {
        animation = 0.0;
        color_p0 = (color_p0 + 8) & 0x78;
    }

    a = Math.trunc(animation);

    screen();
    background(0, SCREEN_Y, DARKESS_COLOR);
    //		background(6, 51, TREE_PANT_COLOR);
    background(57, 60, BACKGROUND_COLOR);
    background(117, 16, GROUND_COLOR);
    background(133, 15, DIRT_COLOR);
    background(180, 6, DIRT_COLOR);

    // draw tree tops
    playfield(6, 51, plyfd_fill, TREE_PANT_COLOR);
    // draw tree leaves
    for (i = 0; i < 4; i += 1) {
        playfield(57 + i * 2, 2, tree_leavs[i], TREE_PANT_COLOR);
    }

    // draw tree trunks
    playfield(65, 52, tree_trunk, TRUNK_COLOR);

    print_small(2, 8, '       2000        ', 2, LETTERING_COLOR);

    for (i = 0; i < 21; i += 1) {
        player1(18, 104 + game_number * 14 + i, nemesis.slice(i, i + 1), 1, nem_color[i]);
    }

    player1(34, 59, branch1, 1, TRUNK_COLOR);
    player1(66, 59, branch2, 1, TRUNK_COLOR);
    player1(86, 59, branch3, 1, TRUNK_COLOR);
    player1(118, 59, branch4, 1, TRUNK_COLOR);

    print_small(12, 190, 'WORK IN PROGRESS ', 1, LETTERING_COLOR);

    ball(0, 0, 8, SCREEN_Y, DARKESS_COLOR);

    requestAnimationFrame(draw);
}

draw();
<commit_msg>Added more detail to screen<commit_after>/*global myCanvas, keyDownHandler, tapDownHandler,  SCREEN_X, SCREEN_Y, INTERLACE, PF, BL, P0, P1, M0, M1, sound, screen, reset_collision, get_collision, background, print_large, print_small, number_large, number_small, playfield, player0, player1, ball, missile0, missile1, requestAnimationFrame*/
/*jslint node: true */
/*jslint bitwise: true*/
'use strict';
document.getElementById(myCanvas);

// Game states
var PAUSED = 1;
var READY = 0;
var PLAYING = 2;
var DONE = 3;

var cursor = [
    'XXXXX   ',
    'X   X   ',
    'X   X   ',
    'X   X   ',
    'XXXXX   ',

    '        ',
    '        ',
    '        ',
    '        ',
    '        '];

var blocky = [
    'XXXX    ',
    'XXXX    ',
    'XXXX    ',
    'XXXX    '];

var harry = [

    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   X    ',
    '   XX   ',
    '   XX   ',
    '   XX X ',
    '   XXXX ',
    '   XXX  ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XXX  ',
    '   X    ',
    '   XX   ',

    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   X    ',
    '   XX   ',
    '   XX   ',
    '  XXX X ',
    '  XXXXX ',
    '  XXXX  ',
    '  XXX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XXX  ',
    '   XXX  ',
    '   X X  ',
    '   X X  ',
    ' XXX X  ',
    ' X    XX',
    ' X    X ',
    '        ',

    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   X    ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XXX  ',
    '   XXX  ',
    '   XX   ',
    '   XX   ',
    '   XXX  ',
    '    XXX ',
    '    X X ',
    '  XXXXX ',
    '  X X   ',
    '  X X   ',
    '    X   ',
    '    XX  ',

    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   X    ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   XXX  ',
    '   XXX  ',
    '   XX   ',
    '   XX   ',
    '   XXX  ',
    '   XXXX ',
    '   X XX ',
    '   X  X ',
    '  XX X  ',
    '  XX X  ',
    '  X   X ',
    '  X     ',
    '   X    ',

    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   X    ',
    '   XX   ',
    '   XX   ',
    '  XXX X ',
    '  XXXXX ',
    '  XXXX  ',
    '  XXX   ',
    '   XX   ',
    '   XX   ',
    '   XXX  ',
    '  XXXXX ',
    '  XX XX ',
    ' XX   X ',
    ' XX   X ',
    'XX    XX',
    'X       ',
    'X       ',
    '        ',

    '   XX   ',
    '   XX   ',
    '   XX   ',
    '   X    ',
    '   XX   ',
    '   XX   ',
    '  XXX X ',
    ' XXXXXX ',
    ' X XXX  ',
    ' X XX   ',
    '   XX   ',
    '   XXX  ',
    '   XXX  ',
    '   XXXX ',
    'XX XX X ',
    ' XXX  X ',
    '  XX  XX',
    '        ',
    '        ',
    '        ',
    '        ',

    'XX      ',
    'XX X    ',
    'XX X    ',
    'X  X    ',
    'XX X    ',
    'XXXX    ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX      ',
    'XX XXX  ',
    'XXXX XX ',
    'XXXX  X ',
    ' XX   XX'];

var plyfd_fill = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
var tree_leavs = [
    'XXXXXXXXXXX  XXXXXXXXXXXXXX  XXXXXXXXXXX',
    'XXXXXXXXXX    XXXXXXXXXXXX    XXXXXXXXXX',
    'XXX  XXXX      XXXX  XXXX      XXXX  XXX',
    'XX    XX        XX    XX        XX    XX'];
var tree_trunk = '.........X.......X....X.......X.........';

var grnd_open =  'XXXXXXXXXXXXXXXXXXX..XXXXXXXXXXXXXXXXXXX';

var branch1 = [
    '       X',
    '       X',
    '   XX  X',
    '   XX  X',
    'XX XX XX',
    ' XXXXXX '];

var branch2 = [
    '        ',
    '        ',
    '        ',
    '        ',
    '      XX',
    ' XXXXXX '];

var branch3 = [
    '        ',
    '        ',
    '        ',
    '        ',
    'XX      ',
    ' XXXXXX '];

var branch4 = [
    'X       ',
    'X       ',
    'X  XX   ',
    'X  XX   ',
    'XX XX XX',
    ' XXXXXX '];

var log_roll = [
    '   XX   ',
    '  XXXX  ',
    ' XXX XX ',
    ' X XXXX ',
    ' XXXXXX ',
    ' XXX XX ',
    ' X XXXX ',
    ' XXXXXX ',
    ' XX  XX ',
    ' X XX X ',
    ' X XX X ',
    ' X XX X ',
    '  X  X  ',
    '   XX   '];

var TREE_PANT_COLOR = 105;
var BACKGROUND_COLOR = 107;

var TRUNK_COLOR = 8;
var GROUND_COLOR = 12;

var DIRT_COLOR = 10;
var HAIR_LOG_COLOR = 9;

var FACE_COLOR = 37;
var SHIRT_COLOR = 100;

var BRICK_COLOR = 33;
var MORTAR_COLOR = 3;

var DARKESS_COLOR = 0;
var LETTERING_COLOR = 6;

var nem_color = [
    HAIR_LOG_COLOR,
    FACE_COLOR,
    FACE_COLOR,
    FACE_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    SHIRT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR,
    TREE_PANT_COLOR];

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

var thisTime = 0;
var lastTime = Date.now();
var dt = 1;

var game_state = READY;

var animation = 0.0;

var game_number = 0;

var color_p0 = 0;
var color_p1 = 16;
var color_pf = 3 + (8 * 8);
var color_bk1 = 104;
var color_bk2 = 107;

var sound_duration = 0;

var sound_vol = 0.3;
var freq_1 = 110;
var freq_2 = 44;
var type_1 = 'square';
var type_2 = 'square';

var x = 100;
var y = 0;

var i = 0;

document.addEventListener('keydown', keyDownHandler, false);

function onPause() {
    sound_duration = 0;
    sound(1, 0, freq_1, type_1);
    sound(2, 0, freq_2, type_2);
}

function onResume() {
    sound_duration = 0;
}

function onAmazonPlatformReady() {
    document.addEventListener("pause", onPause, false);
    document.addEventListener("resume", onResume, false);
}

document.addEventListener("amazonPlatformReady", onAmazonPlatformReady, false);

function keyDownHandler(event) {
    var key = event.which || event.keyCode;
    if (key === 38) {
        //up arrow
        if (SHIRT_COLOR > 0) {
            SHIRT_COLOR -= 1;
        } else {
            SHIRT_COLOR = 127;
        }
    }
    if (key === 40) {
        //down arrow

        if (SHIRT_COLOR < 127) {
            SHIRT_COLOR += 1;
        } else {
            SHIRT_COLOR = 0;
        }
    }

    if (key === 37) {
        //left arrow
        if (x > 0) {
            x -= 1;
        } else {
            x = 160;
        }
    }
    if (key === 39) {
        //right arrow

        if (x < 160) {
            x += 1;
        } else {
            x = 0;
        }
    }

    if ((key === 13) || (key === 32)) {
        x = 0;
    }
}

function draw() {
    var a,
        p_width = Math.trunc(window.innerWidth / SCREEN_X / INTERLACE),
        p_height = Math.trunc(window.innerHeight / SCREEN_Y);

    thisTime = Date.now();
    dt = thisTime - lastTime;
    lastTime = thisTime;

    dt = dt / 3;

    if (sound_duration > 1) {
        sound_duration -= 1;
    } else {
        sound(1, 0, freq_1, type_1);
        sound(2, 0, freq_2, type_2);
    }

    if (game_state === PLAYING) {
        game_state = READY;
        sound(1, sound_vol, freq_1, type_1);
        sound_duration = 2;
    }

    color_p1 = (color_p1 + 8) & 0x7F;
    animation += dt / 30.0;
    if (animation >= 5.0) {
        animation = 0.0;
        color_p0 = (color_p0 + 8) & 0x78;
    }

    a = Math.trunc(animation);

    screen();
    background(0, SCREEN_Y, DARKESS_COLOR);
    background(57, 60, BACKGROUND_COLOR);

    // draw tree tops
    playfield(6, 51, plyfd_fill, TREE_PANT_COLOR);
    // draw tree leaves
    for (i = 0; i < 4; i += 1) {
        playfield(57 + i * 2, 2, tree_leavs[i], TREE_PANT_COLOR);
    }

    // draw tree trunks
    playfield(65, 52, tree_trunk, TRUNK_COLOR);

    playfield(117, 5, plyfd_fill, GROUND_COLOR);
    playfield(122, 6, grnd_open, GROUND_COLOR);
    playfield(128, 5, plyfd_fill, GROUND_COLOR);

    playfield(133, 15, grnd_open, DIRT_COLOR);

    for (i = 0; i < 11; i += 1) {
        ball(78, 136 + i * 4, 4, 2, DIRT_COLOR);
    }
    ball(78, 136, 4, 2, DIRT_COLOR);

    playfield(180, 6, plyfd_fill, DIRT_COLOR);

    print_small(2, 8, '       2000        ', 2, LETTERING_COLOR);

    player0(124, 118, log_roll, 1, HAIR_LOG_COLOR);

    for (i = 0; i < 21; i += 1) {
        player1(16, 104 + i, harry.slice(i, i + 1), 1, nem_color[i]);
    }

    for (i = 0; i < 21; i += 1) {
        player1(9 + x, 159 + i, harry.slice(i + (a + 1) * 21, i + (a + 1) * 21 + 1), 1, nem_color[i]);
    }

    player1(34, 59, branch1, 1, TRUNK_COLOR);
    player1(66, 59, branch2, 1, TRUNK_COLOR);
    player1(86, 59, branch3, 1, TRUNK_COLOR);
    player1(118, 59, branch4, 1, TRUNK_COLOR);

    print_small(12, 190, 'WORK IN PROGRESS ', 1, LETTERING_COLOR);

    ball(0, 0, 8, SCREEN_Y, DARKESS_COLOR);

    requestAnimationFrame(draw);
}

draw();
<|endoftext|>


<commit_before>const Stmt = require("../ast/stmt");

module.exports = class Decl extends Stmt {
    constructor(declaredType, id, exp) {
        super();
        this.declaredType = declaredType;
        this.id = id;
        this.exp = exp;
    }

    analyze(context) {
        this.exp.analyze(context);
        console.log(this.declaredType);
        console.log(this.exp.type);
        console.log(this.declaredType.equals(this.exp.type));
        if (!this.declaredType.equals(this.exp.type)) {
            throw new Error("Declared type does not match the evaluated type.");
        }
        context.checkIfVariableIsAlreadyDeclared(this.id);
        context.addVariable(this.id, this.exp);
    }

    toString() {
        const declString = `(Decl let ${this.type} ${this.id} = ${this.exp})`;
        return declString;
    }
};
<commit_msg>removed unnecessary console.log<commit_after>const Stmt = require("../ast/stmt");

module.exports = class Decl extends Stmt {
    constructor(declaredType, id, exp) {
        super();
        this.declaredType = declaredType;
        this.id = id;
        this.exp = exp;
    }

    analyze(context) {
        this.exp.analyze(context);
        if (!this.declaredType.equals(this.exp.type)) {
            throw new Error("Declared type does not match the evaluated type.");
        }
        context.checkIfVariableIsAlreadyDeclared(this.id);
        context.addVariable(this.id, this.exp);
    }

    toString() {
        const declString = `(Decl let ${this.type} ${this.id} = ${this.exp})`;
        return declString;
    }
};
<|endoftext|>


<commit_before>import warning from '../utils/warning'
import { default as defaultSchema } from '../plugins/schema'

// Maximum recursive calls for normalization
const MAX_CALLS = 50

/**
 * Refresh a reference to a node that have been modified in a transform.
 * @param  {Transform} transform
 * @param  {Node} node
 * @return {Node} newNode
 */

function _refreshNode(transform, node) {
  const { state } = transform
  const { document } = state

  if (node.kind == 'document') {
    return document
  }

  return document.getDescendant(node.key)
}

/**
 * Normalize all children of a node
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Node} node
 * @param  {Node} prevNode
 * @return {Transform} transform
 */

function _normalizeChildrenWith(transform, schema, node, prevNode) {
  if (!node.nodes) {
    return transform
  }

  return node.nodes.reduce(
    (t, child) => {
      const prevChild = prevNode ? prevNode.getChild(child) : null
      return t.normalizeNodeWith(schema, child, prevChild)
    },
    transform
  )
}

/**
 * Normalize a node without its children
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Node} node
 * @return {Transform} transform
 */

function _normalizeNodeWith(transform, schema, node) {
  let recursiveCount = 0

  // Auxiliary function, called recursively, with a maximum calls safety net.
  function _recur(_transform, _node) {
    const failure = schema.__validate(_node)

    // Node is valid?
    if (!failure) {
      return _transform
    }

    const { value, rule } = failure

    // Normalize and get the new state
    _transform = rule.normalize(_transform, _node, value)

    // Search for the updated node in the new state
    const newNode = _refreshNode(_transform, _node)

    // Node no longer exist, go back to normalize parents
    if (!newNode) {
      return _transform
    }

    recursiveCount++
    if (recursiveCount > MAX_CALLS) {
      throw new Error('Unexpected number of successive normalizations. Aborting.')
    }

    return _recur(_transform, newNode)
  }

  return _recur(transform, node)
}

/**
 * Normalize a node (itself and its children) using a schema.
 *
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Node} node
 * @param  {Node} prevNode
 * @return {Transform}
 */

export function normalizeNodeWith(transform, schema, node, prevNode) {
  // Node has not changed
  if (prevNode == node) {
    return transform
  }

  // Iterate over its children
  transform = _normalizeChildrenWith(transform, schema, node, prevNode)

  // Refresh the node reference, and normalize it
  node = _refreshNode(transform, node)
  if (node) {
    transform = _normalizeNodeWith(transform, schema, node)
  }

  return transform
}

/**
 * Normalize a node its parents using a schema.
 *
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Node} node
 * @return {Transform}
 */

export function normalizeParentsWith(transform, schema, node) {
  transform = _normalizeNodeWith(transform, schema, node)

  // Normalize went back up to the document
  if (node.kind == 'document') {
    return transform
  }

  // We search for the new parent
  node = _refreshNode(transform, node)
  if (!node) {
    return transform
  }

  const { state } = transform
  const { document } = state
  const parent = document.getParent(node.key)

  return normalizeParentsWith(transform, schema, parent)
}

/**
 * Normalize state using a schema.
 *
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Document} prevDocument
 * @return {Transform} transform
 */

export function normalizeWith(transform, schema, prevDocument) {
  const { state } = transform
  const { document } = state

  // Schema was not rule to edit the document
  if (!schema.isNormalization) {
    return transform
  }

  return transform.normalizeNodeWith(schema, document, prevDocument)
}

/**
 * Normalize the state using the core schema.
 *
 * @param  {Transform} transform
 * @return {Transform} transform
 */

export function normalize(transform) {
    console.time('normalize')
    transform = transform
        .normalizeDocument()
        .normalizeSelection()
    console.timeEnd('normalize')
    return transform
}

/**
 * Normalize only the document
 *
 * @param  {Transform} transform
 * @return {Transform} transform
 */

export function normalizeDocument(transform) {
  const { state, prevState } = transform
  const { document } = state
  const { document: prevDocument } = prevState || {}

  return transform.normalizeWith(defaultSchema, prevDocument)
}

/**
 * Normalize a node and its children using core schema
 *
 * @param  {Transform} transform
 * @param  {Node or String} key
 * @return {Transform} transform
 */

export function normalizeNodeByKey(transform, key) {
  const { state, prevState } = transform
  const { document } = state
  const { document: prevDocument } = prevState || {}

  const node = document.key == key ? document : document.assertDescendant(key)
  const prevNode = document.key == key ? prevDocument : prevDocument.getDescendant(key)

  console.time('normalizeNodeByKey')
  transform = transform.normalizeNodeWith(defaultSchema, node, prevNode)
  console.timeEnd('normalizeNodeByKey')
  return transform
}

/**
 * Normalize a node and its parent using core schema
 *
 * @param  {Transform} transform
 * @param  {Node or String} key
 * @return {Transform} transform
 */

export function normalizeParentsByKey(transform, key) {
  const { state, prevState } = transform
  const { document } = state
  const { document: prevDocument } = prevState || {}
  const node = document.key == key ? document : document.assertDescendant(key)
  const prevNode = document.key == key ? prevDocument : prevDocument.getDescendant(key)
  console.time('normalizeParentsByKey')
  transform = transform.normalizeParentsWith(defaultSchema, node, prevNode)
  console.timeEnd('normalizeParentsByKey')
  return transform
}

/**
 * Normalize only the selection.
 *
 * @param  {Transform} transform
 * @return {Transform} transform
 */

export function normalizeSelection(transform) {
  console.time('normalizeSelection')
  let { state } = transform
  let { document, selection } = state
  selection = selection.normalize(document)

  // If the selection is nulled (not normal)
  if (
    selection.isUnset ||
    !document.hasDescendant(selection.anchorKey) ||
    !document.hasDescendant(selection.focusKey)
  ) {
      warning('Selection was invalid and reset to start of the document')
      const firstText = document.getTexts().first()
      selection = selection.merge({
        anchorKey: firstText.key,
        anchorOffset: 0,
        focusKey: firstText.key,
        focusOffset: 0,
        isBackward: false
      })
  }

  state = state.merge({ selection })
  transform.state = state
  console.timeEnd('normalizeSelection')
  return transform
}
<commit_msg>Small optimization for normalize<commit_after>import warning from '../utils/warning'
import { default as defaultSchema } from '../plugins/schema'

// Maximum recursive calls for normalization
const MAX_CALLS = 50

/**
 * Refresh a reference to a node that have been modified in a transform.
 * @param  {Transform} transform
 * @param  {Node} node
 * @return {Node} newNode
 */

function _refreshNode(transform, node) {
  const { state } = transform
  const { document } = state

  if (node.kind == 'document') {
    return document
  }

  return document.getDescendant(node.key)
}

/**
 * Normalize all children of a node
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Node} node
 * @param  {Node} prevNode
 * @return {Transform} transform
 */

function _normalizeChildrenWith(transform, schema, node, prevNode) {
  if (!node.nodes) {
    return transform
  }

  return node.nodes.reduce(
    (t, child) => {
      const prevChild = prevNode ? prevNode.getChild(child) : null
      return t.normalizeNodeWith(schema, child, prevChild)
    },
    transform
  )
}

/**
 * Normalize a node without its children
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Node} node
 * @return {Transform} transform
 */

function _normalizeNodeWith(transform, schema, node) {
  let recursiveCount = 0

  // Auxiliary function, called recursively, with a maximum calls safety net.
  function _recur(_transform, _node) {
    const failure = schema.__validate(_node)

    // Node is valid?
    if (!failure) {
      return _transform
    }

    const { value, rule } = failure

    // Normalize and get the new state
    _transform = rule.normalize(_transform, _node, value)

    // Search for the updated node in the new state
    const newNode = _refreshNode(_transform, _node)

    // Node no longer exist, go back to normalize parents
    if (!newNode) {
      return _transform
    }

    recursiveCount++
    if (recursiveCount > MAX_CALLS) {
      throw new Error('Unexpected number of successive normalizations. Aborting.')
    }

    return _recur(_transform, newNode)
  }

  return _recur(transform, node)
}

/**
 * Normalize a node (itself and its children) using a schema.
 *
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Node} node
 * @param  {Node} prevNode
 * @return {Transform}
 */

export function normalizeNodeWith(transform, schema, node, prevNode) {
  // Node has not changed
  if (prevNode == node) {
    return transform
  }

  // For performance considerations, we will check if the transform was changed
  const opCount = transform.operations.length

  // Iterate over its children
  transform = _normalizeChildrenWith(transform, schema, node, prevNode)

  const hasChanged = transform.operations.length != opCount
  if (hasChanged) {
    // Refresh the node reference
    node = _refreshNode(transform, node)
  }

  // Now normalize the node itself if it still exist
  if (node) {
    transform = _normalizeNodeWith(transform, schema, node)
  }

  return transform
}

/**
 * Normalize a node its parents using a schema.
 *
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Node} node
 * @return {Transform}
 */

export function normalizeParentsWith(transform, schema, node) {
  transform = _normalizeNodeWith(transform, schema, node)

  // Normalize went back up to the document
  if (node.kind == 'document') {
    return transform
  }

  // We search for the new parent
  node = _refreshNode(transform, node)
  if (!node) {
    return transform
  }

  const { state } = transform
  const { document } = state
  const parent = document.getParent(node.key)

  return normalizeParentsWith(transform, schema, parent)
}

/**
 * Normalize state using a schema.
 *
 * @param  {Transform} transform
 * @param  {Schema} schema
 * @param  {Document} prevDocument
 * @return {Transform} transform
 */

export function normalizeWith(transform, schema, prevDocument) {
  const { state } = transform
  const { document } = state

  if (!schema.isNormalization) {
    // Schema has no normalization rules
    return transform
  }

  return transform.normalizeNodeWith(schema, document, prevDocument)
}

/**
 * Normalize the state using the core schema.
 *
 * @param  {Transform} transform
 * @return {Transform} transform
 */

export function normalize(transform) {
    console.time('normalize')
    transform = transform
        .normalizeDocument()
        .normalizeSelection()
    console.timeEnd('normalize')
    return transform
}

/**
 * Normalize only the document
 *
 * @param  {Transform} transform
 * @return {Transform} transform
 */

export function normalizeDocument(transform) {
  const { state, prevState } = transform
  const { document } = state
  const { document: prevDocument } = prevState || {}

  return transform.normalizeWith(defaultSchema, prevDocument)
}

/**
 * Normalize a node and its children using core schema
 *
 * @param  {Transform} transform
 * @param  {Node or String} key
 * @return {Transform} transform
 */

export function normalizeNodeByKey(transform, key) {
  const { state, prevState } = transform
  const { document } = state
  const { document: prevDocument } = prevState || {}

  const node = document.key == key ? document : document.assertDescendant(key)
  const prevNode = document.key == key ? prevDocument : prevDocument.getDescendant(key)

  console.time('normalizeNodeByKey')
  transform = transform.normalizeNodeWith(defaultSchema, node, prevNode)
  console.timeEnd('normalizeNodeByKey')
  return transform
}

/**
 * Normalize a node and its parent using core schema
 *
 * @param  {Transform} transform
 * @param  {Node or String} key
 * @return {Transform} transform
 */

export function normalizeParentsByKey(transform, key) {
  const { state, prevState } = transform
  const { document } = state
  const { document: prevDocument } = prevState || {}
  const node = document.key == key ? document : document.assertDescendant(key)
  const prevNode = document.key == key ? prevDocument : prevDocument.getDescendant(key)
  console.time('normalizeParentsByKey')
  transform = transform.normalizeParentsWith(defaultSchema, node, prevNode)
  console.timeEnd('normalizeParentsByKey')
  return transform
}

/**
 * Normalize only the selection.
 *
 * @param  {Transform} transform
 * @return {Transform} transform
 */

export function normalizeSelection(transform) {
  console.time('normalizeSelection')
  let { state } = transform
  let { document, selection } = state
  selection = selection.normalize(document)

  // If the selection is nulled (not normal)
  if (
    selection.isUnset ||
    !document.hasDescendant(selection.anchorKey) ||
    !document.hasDescendant(selection.focusKey)
  ) {
      warning('Selection was invalid and reset to start of the document')
      const firstText = document.getTexts().first()
      selection = selection.merge({
        anchorKey: firstText.key,
        anchorOffset: 0,
        focusKey: firstText.key,
        focusOffset: 0,
        isBackward: false
      })
  }

  state = state.merge({ selection })
  transform.state = state
  console.timeEnd('normalizeSelection')
  return transform
}
<|endoftext|>


<commit_before>/** Namespace */
mw.libs.autoFillFormFields = {};

/**
 * Usage:
 * Field that contains the final calculated name: "class": "smw_autotitle smw_url_?strasse?plz?ort?land?adressZusatz",
 * Source Fields: "class": "smw_autotitle_source attr_plz"
 */
mw.libs.autoFillFormFields.initInstance = function(element) {

    var $el = $(element);
    var titleEl = $el.find('.smw_autotitle');

    // If MultipleInstances has a smw_autotitle field:
    if (titleEl.length > 0) {

        var title = $('link[rel="ExportRDF"]').attr('title');
        var classes = titleEl.attr('class').split(' ');
        var path = false;

        // Set as readonly field, so it can be submitted but not manipulated by the user
        titleEl.prop('readonly', true);

        // Calculate Naming Path
        for (var j = 0; j < classes.length; j++) {

            var className = classes[j];

            if (className.indexOf("smw_url_") > -1) {
               path = className.replace('smw_url_', '');
               path = path.replace('CURRENT', title);
               path = path.replace('__', '/');
            }

        }

        // If path could be found / set
        if (path) {

            var variables = path.split('?');

            var sources = $el.find('.smw_autotitle_source');
            var variablesMap = {};

            for (var k = 1; k < variables.length; k++) {

                var varName = variables[k];
                var $elName = $el.find('.attr_' + varName);

                variablesMap[varName] = $elName;

            }

            // Initial calculation of the automatic field value
            mw.libs.autoFillFormFields.updateInstance($el, titleEl, variables, variablesMap);

            // Listen on KeyUp Event on every field that is a source
            sources.on("keyup", function() {
                mw.libs.autoFillFormFields.updateInstance($el, titleEl, variables, variablesMap);
            });

            // Listen on KeyUp Event on every field that is a source
            sources.on("change", function() {
                mw.libs.autoFillFormFields.updateInstance($el, titleEl, variables, variablesMap);
            });
        }

    }

}

/**
 * Updates the title on init and keypress
 * Uses a hard coded separator
 */
mw.libs.autoFillFormFields.updateInstance = function($el, titleEl, variables, variablesMap) {

    console.info(variables);
    console.info(variablesMap);

    var separator = ', ';
    var calculatedTitle = variables[0];

    for (var i = 0; i < variables.length; i++) {

        var varName = variables[i]

        if (variablesMap[varName]) {
            var value = variablesMap[varName].val();

            if (value && value !== '') {
                value = value.trim();
                calculatedTitle += variablesMap[varName].val();
                calculatedTitle +=  separator;
            }
        }
    };

    calculatedTitle = calculatedTitle.slice(0, -separator.length);
    titleEl.val(calculatedTitle);
};

// Register JavaScript Hook on DOM ready
jQuery(document).ready(function() {

    /**
     * Uses sf.initializeJSElements Hook that is triggered everytime a new form instance is added
     */
    mw.hook('sf.initializeJSElements').add(function($elements, partOfMultiple) {
        console.log('initializeJSElements Hook');
        if (partOfMultiple) {
            $elements.each(function(i, element) {
                mw.libs.autoFillFormFields.initInstance(element);
            });
        }
    });
});
<commit_msg>Support for the new 'sf.addTemplateInstance' Hook<commit_after>/** Namespace */
mw.libs.autoFillFormFields = {};

/**
 * Usage:
 * Field that contains the final calculated name: "class": "smw_autotitle smw_url_?strasse?plz?ort?land?adressZusatz",
 * Source Fields: "class": "smw_autotitle_source attr_plz"
 */
mw.libs.autoFillFormFields.initInstance = function(element) {

    var $el = $(element);
    var autoTitleElement = $el.find('.smw_autotitle');

    // If MultipleInstances has a smw_autotitle field:
    if (autoTitleElement.length === 1) {

        var title = $('link[rel="ExportRDF"]').attr('title');
        var classes = autoTitleElement.attr('class').split(' ');
        var path = false;

        // Set as readonly field, so it can be submitted but not manipulated by the user
        autoTitleElement.prop('readonly', true);

        // Calculate Naming Path
        for (var j = 0; j < classes.length; j++) {

            var className = classes[j];

            if (className.indexOf("smw_url_") > -1) {
               path = className.replace('smw_url_', '');
               path = path.replace('CURRENT', title);
               path = path.replace('__', '/');
            }

        }

        // If path could be found / set
        if (path) {

            var variables = path.split('?');

            var sources = $el.find('.smw_autotitle_source');
            var variablesMap = {};

            for (var k = 1; k < variables.length; k++) {

                var varName = variables[k];
                var $elName = $el.find('.attr_' + varName);

                variablesMap[varName] = $elName;

            }

            // Initial calculation of the automatic field value
            mw.libs.autoFillFormFields.updateInstance($el, autoTitleElement, variables, variablesMap);

            // Listen on KeyUp Event on every field that is a source
            sources.on("keyup", function() {
                mw.libs.autoFillFormFields.updateInstance($el, autoTitleElement, variables, variablesMap);
            });

            // Listen on KeyUp Event on every field that is a source
            sources.on("change", function() {
                mw.libs.autoFillFormFields.updateInstance($el, autoTitleElement, variables, variablesMap);
            });
        }

    }

}

/**
 * Updates the title on init and keypress
 * Uses a hard coded separator
 */
mw.libs.autoFillFormFields.updateInstance = function($el, autoTitleElement, variables, variablesMap) {

    var separator = ', ';
    var calculatedTitle = variables[0];

    for (var i = 0; i < variables.length; i++) {

        var varName = variables[i]

        if (variablesMap[varName]) {
            var value = variablesMap[varName].val();

            if (value && value !== '') {
                value = value.trim();
                calculatedTitle += variablesMap[varName].val();
                calculatedTitle +=  separator;
            }
        }
    };

    calculatedTitle = calculatedTitle.slice(0, -separator.length);
    autoTitleElement.val(calculatedTitle);
};

// Register JavaScript Hook on DOM ready
jQuery(document).ready(function() {

    // Registrate all current instances
    $('.multipleTemplateInstance, .formtable ').each(function() {
        mw.libs.autoFillFormFields.initInstance($(this));
    });

    // registrate future instances
    // Uses sf.addTemplateInstance Hook that is triggered everytime a new form instance is added
    mw.hook('sf.addTemplateInstance').add(function($instance) {
        mw.libs.autoFillFormFields.initInstance($instance);
    });
});
<|endoftext|>


<commit_before>var request = require('superagent');
var bingUtils = require('./bingUtils');
var commonUtils = require('./commonUtils');
var dbUtils = require('./dbUtils');
var weibo = require('../configs/config').weibo;
var mailUtils = require('./mailUtils');
var cookie = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36' };
var update_url_text = 'https://api.weibo.com/2/statuses/upload_url_text.json';
module.exports = {
    /**
     * 发送微博
     * @callback
     * @isAuto 是否自动发送(true,false)
     */
    update: function(callback, isAuto) {
        var date = new Date();
        var y = date.getFullYear();
        var m = Number(date.getMonth()) + 1 < 10 ? '0' + (Number(date.getMonth()) + 1) : Number(date.getMonth()) + 1;
        var d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
        var full = y + '-' + m + '-' + d;
        // 查询数据库中是否存在今天的新数据
        dbUtils.get('bing', {
            enddate: full.replace(/\-/g, '')
        }, function(rows) {
            if (rows.length === 0) {
                // 如果不存在则抓取
                bingUtils.fetchPicture({}, function(data) {
                    dbUtils.set('bing', data, function(rows) {
                        data.id = rows.insertId || 0;
                        module.exports.commonSend(data, callback, isAuto);
                    })
                });
            } else {
                // 如果存在，但没有发送微博
                var data = rows[0];
                if (data.weibo == 0) {
                    // 如果少了某个字段
                    if (!data.title || !data.attribute || !data.description || !data.thumbnail_pic) {
                        bingUtils.fetchStory({
                            enddate: data.enddate
                        }, function(body) {
                            data['title'] = body.title;
                            data['attribute'] = body.attribute;
                            data['description'] = body.description;
                            data['country'] = body.country;
                            data['city'] = body.city;
                            data['longitude'] = body.longitude;
                            data['latitude'] = body.latitude;
                            data['continent'] = body.continent;
                            module.exports.commonSend(data, callback, isAuto);
                        });
                    } else {
                        module.exports.commonSend(data, callback, isAuto);
                    }
                } else {
                    // 如果已发送则查询上一条是否已发送
                    dbUtils.get('bing', {
                        weibo: 0
                    }, function(rs) {
                        if (rs.length > 0) {
                            var d = rs[0];
                            // 如果少了某个字段
                            if (!d.title || !d.attribute || !d.description || !d.thumbnail_pic) {
                                bingUtils.fetchStory({
                                    d: d.enddate
                                }, function(body) {
                                    d['url'] = !!d.qiniu_url && 'http://7xilig.com1.z0.glb.clouddn.com/bing/' + d.qiniu_url + '_1920x1080.jpg' || d.url;
                                    d['title'] = body.title;
                                    d['attribute'] = body.attribute;
                                    d['description'] = body.description;
                                    d['country'] = body.country;
                                    d['city'] = body.city;
                                    d['longitude'] = body.longitude;
                                    d['latitude'] = body.latitude;
                                    d['continent'] = body.continent;
                                    module.exports.commonSend(d, callback, isAuto);
                                });
                            } else {
                                module.exports.commonSend(d, callback, isAuto);
                            }
                        }
                    })

                }
            }
        });

    },
    /**
     * 获取短链
     */
    shorten: function(url, callback) {
        module.exports.checkOauth(function(token) {
            request
                .post('https://api.weibo.com/2/short_url/shorten.json')
                .type('form')
                .set(cookie)
                .send({
                    access_token: token,
                    url_long: url
                })
                .end(function(err, res) {
                    commonUtils.convert(err, res, callback);
                });
        });
    },
    /**
     * 公共发送微博方法
     */
    commonSend: function(data, callback) {
        module.exports.checkOauth(function(token) {
            var date = data.enddate;
            var y = date.substr(0, 4);
            var m = date.substr(4, 2);
            var d = date.substr(6, 2);
            var full = y + '-' + m + '-' + d;
            var status = ('#必应壁纸# ' + full + ' / ' + data.description).slice(0, 138) + '... http://bing.ioliu.cn?id=' + data.id;
            var post = {
                access_token: token,
                status: status,
                url: data.url,
                lat: data.Latitude,
                long: data.Longitude,
                annotations: {
                    place: {
                        title: data.attribute,
                        url: data.copyright,
                        locality: data.city,
                        country_name: data.country,
                        region: data.country,
                        latitude: data.catitude,
                        longitude: data.congitude
                    }
                }
            };
            request
                .post(update_url_text)
                .type('form')
                .set(cookie)
                .send(post)
                .end(function(err, response) {
                    commonUtils.convert(err, response, function(body) {
                        data['weibo'] = 1;
                        data['thumbnail_pic'] = body.thumbnail_pic;
                        data['bmiddle_pic'] = body.bmiddle_pic;
                        data['original_pic'] = body.original_pic;
                        dbUtils.update('bing', {
                            body: {
                                title: data.title,
                                description: data.description,
                                attribute: data.attribute,
                                country: data.country,
                                city: data.city,
                                longitude: data.longitude,
                                latitude: data.latitude,
                                continent: data.continent,
                                weibo: 1,
                                thumbnail_pic: data.thumbnail_pic,
                                bmiddle_pic: data.bmiddle_pic,
                                original_pic: data.original_pic
                            },
                            condition: {
                                id: data.id
                            }
                        }, function(rows) {
                            callback && callback(body);
                        });
                    });
                });
        });

    },
    /**
     * 检查授权
     * @callback
     * @isAuto 是否自动发送(true/false)
     */
    checkOauth: function(callback, isAuto) {
        var uid = !!weibo.USER_UID ? weibo.USER_UID : weibo.MASTER_UID;
        if (isAuto) {
            uid = weibo.MASTER_UID;
        }
        dbUtils.get('bing_session', {
            body: {
                uid: uid
            }
        }, function(rows) {
            if (rows.length === 0) {
                callback && callback(-1);
            } else {
                callback && callback(rows[0].token);
            }
        })
    }
}<commit_msg>fix send weibo error<commit_after>var request = require('superagent');
var bingUtils = require('./bingUtils');
var commonUtils = require('./commonUtils');
var dbUtils = require('./dbUtils');
var weibo = require('../configs/config').weibo;
var mailUtils = require('./mailUtils');
var cookie = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36' };
var update_url_text = 'https://api.weibo.com/2/statuses/upload_url_text.json';
module.exports = {
    /**
     * 发送微博
     * @callback
     * @isAuto 是否自动发送(true,false)
     */
    update: function(callback, isAuto) {
        var date = new Date();
        var y = date.getFullYear();
        var m = Number(date.getMonth()) + 1 < 10 ? '0' + (Number(date.getMonth()) + 1) : Number(date.getMonth()) + 1;
        var d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
        var full = y + '-' + m + '-' + d;
        // 查询数据库中是否存在今天的新数据
        dbUtils.get('bing', {
            enddate: full.replace(/\-/g, '')
        }, function(rows) {
            if (rows.length === 0) {
                // 如果不存在则抓取
                bingUtils.fetchPicture({}, function(data) {
                    dbUtils.set('bing', data, function(rows) {
                        data.id = rows.insertId || 0;
                        module.exports.commonSend(data, callback, isAuto);
                    })
                });
            } else {
                // 如果存在，但没有发送微博
                var data = rows[0];
                if (data.weibo == 0) {
                    // 如果少了某个字段
                    if (!data.title || !data.attribute || !data.description || !data.thumbnail_pic) {
                        bingUtils.fetchStory({
                            enddate: data.enddate
                        }, function(body) {
                            data['title'] = body.title;
                            data['attribute'] = body.attribute;
                            data['description'] = body.description;
                            data['country'] = body.country;
                            data['city'] = body.city;
                            data['longitude'] = body.longitude;
                            data['latitude'] = body.latitude;
                            data['continent'] = body.continent;
                            module.exports.commonSend(data, callback, isAuto);
                        });
                    } else {
                        module.exports.commonSend(data, callback, isAuto);
                    }
                } else {
                    // 如果已发送则查询上一条是否已发送
                    dbUtils.get('bing', {
                        weibo: 0
                    }, function(rs) {
                        if (rs.length > 0) {
                            var d = rs[0];
                            // 如果少了某个字段
                            if (!d.title || !d.attribute || !d.description || !d.thumbnail_pic) {
                                bingUtils.fetchStory({
                                    d: d.enddate
                                }, function(body) {
                                    d['url'] = !!d.qiniu_url && 'http://7xilig.com1.z0.glb.clouddn.com/bing/' + d.qiniu_url + '_1920x1080.jpg' || d.url;
                                    d['title'] = body.title;
                                    d['attribute'] = body.attribute;
                                    d['description'] = body.description;
                                    d['country'] = body.country;
                                    d['city'] = body.city;
                                    d['longitude'] = body.longitude;
                                    d['latitude'] = body.latitude;
                                    d['continent'] = body.continent;
                                    module.exports.commonSend(d, callback, isAuto);
                                });
                            } else {
                                module.exports.commonSend(d, callback, isAuto);
                            }
                        }
                    })

                }
            }
        });

    },
    /**
     * 获取短链
     */
    shorten: function(url, callback) {
        module.exports.checkOauth(function(token) {
            request
                .post('https://api.weibo.com/2/short_url/shorten.json')
                .type('form')
                .set(cookie)
                .send({
                    access_token: token,
                    url_long: url
                })
                .end(function(err, res) {
                    commonUtils.convert(err, res, callback);
                });
        });
    },
    /**
     * 公共发送微博方法
     */
    commonSend: function(data, callback) {
        module.exports.checkOauth(function(token) {
            var date = data.enddate;
            var y = date.substr(0, 4);
            var m = date.substr(4, 2);
            var d = date.substr(6, 2);
            var full = y + '-' + m + '-' + d;
            var status = ('#必应壁纸# ' + full + ' / ' + data.description).slice(0, 138) + '... http://bing.ioliu.cn?id=' + data.id;
            var post = {
                access_token: token,
                status: status,
                url: data.url,
                lat: data.Latitude,
                long: data.Longitude,
                annotations: {
                    place: {
                        title: data.attribute,
                        url: data.copyright,
                        locality: data.city,
                        country_name: data.country,
                        region: data.country,
                        latitude: data.catitude,
                        longitude: data.congitude
                    }
                }
            };
            console.log(post);
            request
                .post(update_url_text)
                .type('form')
                .set(cookie)
                .send(post)
                .end(function(err, response) {
                    commonUtils.convert(err, response, function(body) {
                        data['weibo'] = 1;
                        data['thumbnail_pic'] = body.thumbnail_pic;
                        data['bmiddle_pic'] = body.bmiddle_pic;
                        data['original_pic'] = body.original_pic;
                        dbUtils.update('bing', {
                            body: {
                                title: data.title,
                                description: data.description,
                                attribute: data.attribute,
                                country: data.country,
                                city: data.city,
                                longitude: data.longitude,
                                latitude: data.latitude,
                                continent: data.continent,
                                weibo: 1,
                                thumbnail_pic: data.thumbnail_pic,
                                bmiddle_pic: data.bmiddle_pic,
                                original_pic: data.original_pic
                            },
                            condition: {
                                id: data.id
                            }
                        }, function(rows) {
                            callback && callback(body);
                        });
                    });
                });
        });

    },
    /**
     * 检查授权
     * @callback
     * @isAuto 是否自动发送(true/false)
     */
    checkOauth: function(callback, isAuto) {
        var uid = !!weibo.USER_UID ? weibo.USER_UID : weibo.MASTER_UID;
        if (isAuto) {
            uid = weibo.MASTER_UID;
        }
        dbUtils.get('bing_session', {
            body: {
                uid: uid
            }
        }, function(rows) {
            if (rows.length === 0) {
                callback && callback(-1);
            } else {
                callback && callback(rows[0].token);
            }
        })
    }
}<|endoftext|>


<commit_before>Util.Modules["defaultEdit"] = new function() {
	this.init = function(div) {

		div._item_id = u.cv(div, "item_id");

		// primary form
		var form = u.qs("form", div);
		form.div = div;

		form.h2_name = u.qs("#content .scene > h2.name");
		form.p_sindex = u.qs("#content .scene div.sindex p.sindex");

		var autosave_setting = u.cv(div, "autosave");
		if(autosave_setting == "off") {
			page.autosave_disabled = true;
		}

		u.f.init(form);
		// form.actions["cancel"].clicked = function(event) {
		// 	location.href = this.url;
		// }
		form.submitted = function(iN) {

			// stop autosave (this could be a manual save)
			u.t.resetTimer(page.t_autosave);

			this.response = function(response) {
				// restart autosave
//				page.t_autosave = u.t.setTimer(this, "autosave", page._autosave_interval);

				// notifier will kill autosave if necessary (if login is required)
				// could happen if user logs off in other tab
				page.notify(response);

				// Update any potential filelists
				u.f.updateFilelistStatus(this, response);

				// Update values typically shown in edit page
				if(response && response.cms_object) {

					if(response.cms_object.name && this.h2_name) {
						this.h2_name.innerHTML = response.cms_object.name;
					}

					if(response.cms_object.sindex && this.p_sindex) {
						this.p_sindex.innerHTML = response.cms_object.sindex;
					}

				}

			}
			u.request(this, this.action, {"method":"post", "data" : this.getData()});

		}

		form.updated = function() {
//			u.bug("form has been updated")

			this.change_state = true;
			u.t.resetTimer(page.t_autosave);

			if(!page.autosave_disabled) {

//				u.bug("start autosave loop after update")
				page.t_autosave = u.t.setTimer(this, "autosave", page._autosave_interval);

			}
		}

		// enable autosaving for testing
		form.autosave = function() {
//			u.bug("autosaving:" + this.change_state)

			// is autosave on?
			if(!page.autosave_disabled && this.change_state) {

//				u.bug("autosave execute")

				for(name in this.inputs) {
					if(this.inputs[name].field) {

						// field has not been used yet
						if(!this.inputs[name].used) {

							// check for required and value
							if(u.hc(this.inputs[name].field, "required") && !this.inputs[name].val()) {

								// cannot save due to missing values - keep trying
//								page.t_autosave = u.t.setTimer(this, "autosave", page._autosave_interval);
								return false;
							}

						}
						// do actual validation
						else {
							u.f.validate(this.inputs[name]);
						}
					}
				}

				// if no error is found after validation
				if(!u.qs(".field.error", this)) {
					this.change_state = false;
					this.submitted();
				}
				// keep auto save going
				// else {
				// 	page.t_autosave = u.t.setTimer(this, "autosave", page._autosave_interval);
				// }

			}

			// autosave is turned off
			else {

			}

		}

		form.change_state = false;

		page._autosave_node = form;
		page._autosave_interval = 3000;
		page.t_autosave = u.t.setTimer(form, "autosave", page._autosave_interval);

		// kill backspace to avoid leaving page unintended (backspace is history.back)
		form.cancelBackspace = function(event) {
//			u.bug("ss:" + u.qsa(".field.focus", this).length);
			if(event.keyCode == 8 && !u.qsa(".field.focus").length) {
				u.e.kill(event);
			}
		}
		u.e.addEvent(document.body, "keydown", form.cancelBackspace);

	}
}

Util.Modules["newSystemMessage"] = new function() {
	this.init = function(div) {

		// primary form
		var form = u.qs("form", div);
		form.div = div;

		form.ul_actions = u.qs("ul.actions", form);
		var fieldset = u.qs("fieldset.values", form);
		fieldset.h3_span = u.qs("h3 span.recipient", fieldset);
		fieldset.h3_span.innerHTML = "?";

		u.f.init(form);

		form.inputs["recipients"].keyup = function(event) {

			var recipients = this.val().replace(/,/g, ";").split(";");
			var fieldsets = u.qsa("fieldset.values", this._form);
			var i, recipient, inputs, input, labels, label, fieldset;

			// if these keys, update number of fieldsets
			if(event.key == "," || event.key == "," || event.key == "Delete" || event.key == "Backspace") {
				if(recipients.length < fieldsets.length && fieldsets.length > 1) {
					fieldsets[0].parentNode.removeChild(fieldsets[fieldsets.length-1]);
					fieldsets = u.qsa("fieldset.values", this._form);
				}
				else if(recipients.length > fieldsets.length) {

					// duplicate fieldset
					fieldset = fieldsets[0].parentNode.insertBefore(fieldsets[0].cloneNode(true), this._form.ul_actions);

					// make reference to header span
					fieldset.h3_span = u.qs("h3 span.recipient", fieldset);
					fieldsets = u.qsa("fieldset.values", this._form);

					// update input and label attributes
					inputs = u.qsa("input[type=text]", fieldset);
					for(i = 0; i < inputs.length; i++) {
						input = inputs[i];
						input.value = "";
						input.name = input.name.replace(/values\[[\d]+\]/, "values["+(fieldsets.length-1)+"]");
						input.id = input.id.replace(/values\[[\d]+\]/, "values["+(fieldsets.length-1)+"]");

					}
					labels = u.qsa("label", fieldset);
					for(i = 0; i < labels.length; i++) {
						label = labels[i];
						label.setAttribute("for", label.getAttribute("for").replace(/values\[[\d]+\]/, "values["+(fieldsets.length-1)+"]"));
					}

					// reinitialize form
					u.f.init(this._form);

				}

			}

			// update recipients text in all value fieldsets
			for(i = 0; i < recipients.length; i++) {
				recipient = recipients[i];
				fieldsets[i].h3_span.innerHTML = recipient;
			}

		}
		u.e.addEvent(form.inputs["recipients"], "keyup", form.inputs["recipients"].keyup);

		form.submitted = function(iN) {

			u.ac(this, "submitting");
			this.response = function(response) {
				u.rc(this, "submitting");

				if(response.cms_status == "success") {

					var div_receipt = u.ae(this.div, "div", {class:"receipt"});
					u.ae(div_receipt, "p", {html:"Mail(s) was successfully sent to:"});
					var ul_receipt = u.ae(div_receipt, "ul", {class:"receipt"});

					var i;
					for(i = 0; i < response.cms_object.length; i++) {
						u.ae(ul_receipt, "li", {html:response.cms_object[i]})
					}
					this.parentNode.replaceChild(div_receipt, this);
//					console.log(response.cms_object);

				}
				// error could happen if user log off in other tab
				page.notify(response);

			}
			u.request(this, this.action, {"method":"post", "data" : this.getData({"format":"formdata"})});

		}

	}
}

Util.Modules["sendMessage"] = new function() {
	this.init = function(div) {

		// primary form
		var form = u.qs("form", div);
		form.div = div;

		u.f.init(form);

		form.div_message_form = u.qs("div.item.message form");

		form.submitted = function(iN) {

			// recipients or maillist_id must be filled out
			if(this.inputs["recipients"].val() || this.inputs["maillist_id"].val() || this.inputs["user_id"].val()) {

				// save message before sending mail
				this.div_message_form.submit();

				u.ac(this, "submitting");
				this.response = function(response) {
					u.rc(this, "submitting");

					page.notify(response);

					// successful send
					if(response.cms_status == "success") {
						u.ass(this, {
							display:"none",
						});

						this.div_receipt = u.ae(this.div, "div", {class:"receipt"});
						u.ae(this.div_receipt, "p", {html:"Mail(s) was successfully sent to:"});
						var ul_receipt = u.ae(this.div_receipt, "ul", {class:"receipt"});

						var i;
						for(i = 0; i < response.cms_object.length; i++) {
							u.ae(ul_receipt, "li", {html:response.cms_object[i]})
						}

						// enable easy sending another
						var ul_actions = u.ae(this.div_receipt, "ul", {class:"actions"});
						var action = u.f.addAction(ul_actions, {name:"send_another", value:"Send another", type:"button", class:"button"});
						action._form = this
						u.ce(action);
						action.clicked = function() {
							this._form.div_receipt.parentNode.removeChild(this._form.div_receipt);
							u.ass(this._form, {
								display: "block",
							});
						}

					}

				}
				u.request(this, this.action, {"method":"post", "data" : this.getData({"format":"formdata"})});

			}
			else {

				u.f.inputHasError(this.inputs["recipients"]);
				u.f.inputHasError(this.inputs["maillist_id"]);

			}

		}

	}

}
<commit_msg>Scroll to error<commit_after>Util.Modules["defaultEdit"] = new function() {
	this.init = function(div) {

		div._item_id = u.cv(div, "item_id");

		// primary form
		var form = u.qs("form", div);
		form.div = div;

		form.h2_name = u.qs("#content .scene > h2.name");
		form.p_sindex = u.qs("#content .scene div.sindex p.sindex");

		var autosave_setting = u.cv(div, "autosave");
		if(autosave_setting == "off") {
			page.autosave_disabled = true;
		}

		u.f.init(form);
		// form.actions["cancel"].clicked = function(event) {
		// 	location.href = this.url;
		// }
		form.submitFailed = function(iN) {

			u.bug("submit failed", iN);

			var first_error = Object.keys(this._error_inputs)[0];
			if(this.inputs[first_error]) {
				u.scrollTo(window, {node: this.inputs[first_error].field, offset_y: 170});
			}

		}

		form.submitted = function(iN) {

			// stop autosave (this could be a manual save)
			u.t.resetTimer(page.t_autosave);

			this.response = function(response) {
				// restart autosave
//				page.t_autosave = u.t.setTimer(this, "autosave", page._autosave_interval);

				// notifier will kill autosave if necessary (if login is required)
				// could happen if user logs off in other tab
				page.notify(response);

				// Update any potential filelists
				u.f.updateFilelistStatus(this, response);

				// Update values typically shown in edit page
				if(response && response.cms_object) {

					if(response.cms_object.name && this.h2_name) {
						this.h2_name.innerHTML = response.cms_object.name;
					}

					if(response.cms_object.sindex && this.p_sindex) {
						this.p_sindex.innerHTML = response.cms_object.sindex;
					}

				}

			}
			u.request(this, this.action, {"method":"post", "data" : this.getData()});

		}

		form.updated = function() {
//			u.bug("form has been updated")

			this.change_state = true;
			u.t.resetTimer(page.t_autosave);

			if(!page.autosave_disabled) {

//				u.bug("start autosave loop after update")
				page.t_autosave = u.t.setTimer(this, "autosave", page._autosave_interval);

			}
		}

		// enable autosaving for testing
		form.autosave = function() {
//			u.bug("autosaving:" + this.change_state)

			// is autosave on?
			if(!page.autosave_disabled && this.change_state) {

//				u.bug("autosave execute")

				for(name in this.inputs) {
					if(this.inputs[name].field) {

						// field has not been used yet
						if(!this.inputs[name].used) {

							// check for required and value
							if(u.hc(this.inputs[name].field, "required") && !this.inputs[name].val()) {

								// cannot save due to missing values - keep trying
//								page.t_autosave = u.t.setTimer(this, "autosave", page._autosave_interval);
								return false;
							}

						}
						// do actual validation
						else {
							u.f.validate(this.inputs[name]);
						}
					}
				}

				// if no error is found after validation
				if(!u.qs(".field.error", this)) {
					this.change_state = false;
					this.submitted();
				}
				// keep auto save going
				// else {
				// 	page.t_autosave = u.t.setTimer(this, "autosave", page._autosave_interval);
				// }

			}

			// autosave is turned off
			else {

			}

		}

		form.change_state = false;

		page._autosave_node = form;
		page._autosave_interval = 3000;
		page.t_autosave = u.t.setTimer(form, "autosave", page._autosave_interval);

		// kill backspace to avoid leaving page unintended (backspace is history.back)
		form.cancelBackspace = function(event) {
//			u.bug("ss:" + u.qsa(".field.focus", this).length);
			if(event.keyCode == 8 && !u.qsa(".field.focus").length) {
				u.e.kill(event);
			}
		}
		u.e.addEvent(document.body, "keydown", form.cancelBackspace);

	}
}

Util.Modules["newSystemMessage"] = new function() {
	this.init = function(div) {

		// primary form
		var form = u.qs("form", div);
		form.div = div;

		form.ul_actions = u.qs("ul.actions", form);
		var fieldset = u.qs("fieldset.values", form);
		fieldset.h3_span = u.qs("h3 span.recipient", fieldset);
		fieldset.h3_span.innerHTML = "?";

		u.f.init(form);

		form.inputs["recipients"].keyup = function(event) {

			var recipients = this.val().replace(/,/g, ";").split(";");
			var fieldsets = u.qsa("fieldset.values", this._form);
			var i, recipient, inputs, input, labels, label, fieldset;

			// if these keys, update number of fieldsets
			if(event.key == "," || event.key == "," || event.key == "Delete" || event.key == "Backspace") {
				if(recipients.length < fieldsets.length && fieldsets.length > 1) {
					fieldsets[0].parentNode.removeChild(fieldsets[fieldsets.length-1]);
					fieldsets = u.qsa("fieldset.values", this._form);
				}
				else if(recipients.length > fieldsets.length) {

					// duplicate fieldset
					fieldset = fieldsets[0].parentNode.insertBefore(fieldsets[0].cloneNode(true), this._form.ul_actions);

					// make reference to header span
					fieldset.h3_span = u.qs("h3 span.recipient", fieldset);
					fieldsets = u.qsa("fieldset.values", this._form);

					// update input and label attributes
					inputs = u.qsa("input[type=text]", fieldset);
					for(i = 0; i < inputs.length; i++) {
						input = inputs[i];
						input.value = "";
						input.name = input.name.replace(/values\[[\d]+\]/, "values["+(fieldsets.length-1)+"]");
						input.id = input.id.replace(/values\[[\d]+\]/, "values["+(fieldsets.length-1)+"]");

					}
					labels = u.qsa("label", fieldset);
					for(i = 0; i < labels.length; i++) {
						label = labels[i];
						label.setAttribute("for", label.getAttribute("for").replace(/values\[[\d]+\]/, "values["+(fieldsets.length-1)+"]"));
					}

					// reinitialize form
					u.f.init(this._form);

				}

			}

			// update recipients text in all value fieldsets
			for(i = 0; i < recipients.length; i++) {
				recipient = recipients[i];
				fieldsets[i].h3_span.innerHTML = recipient;
			}

		}
		u.e.addEvent(form.inputs["recipients"], "keyup", form.inputs["recipients"].keyup);

		form.submitted = function(iN) {

			u.ac(this, "submitting");
			this.response = function(response) {
				u.rc(this, "submitting");

				if(response.cms_status == "success") {

					var div_receipt = u.ae(this.div, "div", {class:"receipt"});
					u.ae(div_receipt, "p", {html:"Mail(s) was successfully sent to:"});
					var ul_receipt = u.ae(div_receipt, "ul", {class:"receipt"});

					var i;
					for(i = 0; i < response.cms_object.length; i++) {
						u.ae(ul_receipt, "li", {html:response.cms_object[i]})
					}
					this.parentNode.replaceChild(div_receipt, this);
//					console.log(response.cms_object);

				}
				// error could happen if user log off in other tab
				page.notify(response);

			}
			u.request(this, this.action, {"method":"post", "data" : this.getData({"format":"formdata"})});

		}

	}
}

Util.Modules["sendMessage"] = new function() {
	this.init = function(div) {

		// primary form
		var form = u.qs("form", div);
		form.div = div;

		u.f.init(form);

		form.div_message_form = u.qs("div.item.message form");

		form.submitted = function(iN) {

			// recipients or maillist_id must be filled out
			if(this.inputs["recipients"].val() || this.inputs["maillist_id"].val() || this.inputs["user_id"].val()) {

				// save message before sending mail
				this.div_message_form.submit();

				u.ac(this, "submitting");
				this.response = function(response) {
					u.rc(this, "submitting");

					page.notify(response);

					// successful send
					if(response.cms_status == "success") {
						u.ass(this, {
							display:"none",
						});

						this.div_receipt = u.ae(this.div, "div", {class:"receipt"});
						u.ae(this.div_receipt, "p", {html:"Mail(s) was successfully sent to:"});
						var ul_receipt = u.ae(this.div_receipt, "ul", {class:"receipt"});

						var i;
						for(i = 0; i < response.cms_object.length; i++) {
							u.ae(ul_receipt, "li", {html:response.cms_object[i]})
						}

						// enable easy sending another
						var ul_actions = u.ae(this.div_receipt, "ul", {class:"actions"});
						var action = u.f.addAction(ul_actions, {name:"send_another", value:"Send another", type:"button", class:"button"});
						action._form = this
						u.ce(action);
						action.clicked = function() {
							this._form.div_receipt.parentNode.removeChild(this._form.div_receipt);
							u.ass(this._form, {
								display: "block",
							});
						}

					}

				}
				u.request(this, this.action, {"method":"post", "data" : this.getData({"format":"formdata"})});

			}
			else {

				u.f.inputHasError(this.inputs["recipients"]);
				u.f.inputHasError(this.inputs["maillist_id"]);

			}

		}

	}

}
<|endoftext|>


<commit_before>var CldrPluralRule = require('./CldrPluralRule'),
    cldrPluralRuleTermFunctionByName = require('./cldrPluralRuleTermFunctionByName'),
    uglifyJs = require('uglify-js');

function CldrPluralRuleSet() {
    this.cldrPluralRuleByCount = {};
}

CldrPluralRuleSet.prototype = {
    addRule: function (cldrPluralRule, count) {
        if (typeof cldrPluralRule === 'string') {
            cldrPluralRule = cldrPluralRule.replace(/\s*@(?:decimal|integer).*$/, '');
            // Some count="other" nodes in CLDR 24+ consist purely of sample text.
            // Don't add those.
            if (cldrPluralRule.length === 0) {
                return;
            }
            cldrPluralRule = new CldrPluralRule(cldrPluralRule);
        }
        this.cldrPluralRuleByCount[count] = cldrPluralRule;
    },

    toJavaScriptFunctionBodyAst: function () {
        var statementAsts = [],
            isUsedByTerm = {};
        Object.keys(this.cldrPluralRuleByCount).forEach(function (count) {
            var cldrPluralRule = this.cldrPluralRuleByCount[count];
            cldrPluralRule.updateIsUsedByTerm(isUsedByTerm);
            statementAsts.push(
                [
                    'if',
                    cldrPluralRule.toJavaScriptAst(),
                    ['return', ['string', count]]
                ]
            );
        }, this);
        statementAsts.push(['return', ['string', 'other']]);
        var varAsts = [];

        ['i', 'v', 'w', 'f', 't'].forEach(function (term) {
            if (isUsedByTerm[term]) {
                varAsts.push([term, uglifyJs.parser.parse(cldrPluralRuleTermFunctionByName[term].toString())[1][0][3][0][1]]);
            }
        });

        if (Object.keys(isUsedByTerm).length !== 0) {
            statementAsts.unshift(
                // if (typeof n === 'string') n = parseInt(n, 10);
                [ 'if',
                    [ 'binary',
                        '===',
                        [ 'unary-prefix', 'typeof', [ 'name', 'n' ] ],
                        [ 'string', 'string' ] ],
                    [ 'stat',
                        [ 'assign',
                            true,
                            [ 'name', 'n' ],
                            [ 'call',
                                [ 'name', 'parseInt' ],
                                [ [ 'name', 'n' ], [ 'num', 10 ] ] ] ] ],
                    undefined ]
            );
        }

        if (varAsts.length > 0) {
            statementAsts.unshift(['var', varAsts]);
        }
        return statementAsts;
    }
};

module.exports = CldrPluralRuleSet;
<commit_msg>add method to list included plural rule classes<commit_after>var CldrPluralRule = require('./CldrPluralRule'),
    cldrPluralRuleTermFunctionByName = require('./cldrPluralRuleTermFunctionByName'),
    uglifyJs = require('uglify-js');

function CldrPluralRuleSet() {
    this.cldrPluralRuleByCount = {};
}

CldrPluralRuleSet.prototype = {
    addRule: function (cldrPluralRule, count) {
        if (typeof cldrPluralRule === 'string') {
            cldrPluralRule = cldrPluralRule.replace(/\s*@(?:decimal|integer).*$/, '');
            // Some count="other" nodes in CLDR 24+ consist purely of sample text.
            // Don't add those.
            if (cldrPluralRule.length === 0) {
                return;
            }
            cldrPluralRule = new CldrPluralRule(cldrPluralRule);
        }
        this.cldrPluralRuleByCount[count] = cldrPluralRule;
    },

    /**
     * @returns {Array} of all plural classes including "other" in set.
     */
    availablePluralClasses: function() {
      let pluralClasses = Object.keys(this.cldrPluralRuleByCount);
      pluralClasses.push('other');
      return pluralClasses;
    },

    toJavaScriptFunctionBodyAst: function () {
        var statementAsts = [],
            isUsedByTerm = {};
        Object.keys(this.cldrPluralRuleByCount).forEach(function (count) {
            var cldrPluralRule = this.cldrPluralRuleByCount[count];
            cldrPluralRule.updateIsUsedByTerm(isUsedByTerm);
            statementAsts.push(
                [
                    'if',
                    cldrPluralRule.toJavaScriptAst(),
                    ['return', ['string', count]]
                ]
            );
        }, this);
        statementAsts.push(['return', ['string', 'other']]);
        var varAsts = [];

        ['i', 'v', 'w', 'f', 't'].forEach(function (term) {
            if (isUsedByTerm[term]) {
                varAsts.push([term, uglifyJs.parser.parse(cldrPluralRuleTermFunctionByName[term].toString())[1][0][3][0][1]]);
            }
        });

        if (Object.keys(isUsedByTerm).length !== 0) {
            statementAsts.unshift(
                // if (typeof n === 'string') n = parseInt(n, 10);
                [ 'if',
                    [ 'binary',
                        '===',
                        [ 'unary-prefix', 'typeof', [ 'name', 'n' ] ],
                        [ 'string', 'string' ] ],
                    [ 'stat',
                        [ 'assign',
                            true,
                            [ 'name', 'n' ],
                            [ 'call',
                                [ 'name', 'parseInt' ],
                                [ [ 'name', 'n' ], [ 'num', 10 ] ] ] ] ],
                    undefined ]
            );
        }

        if (varAsts.length > 0) {
            statementAsts.unshift(['var', varAsts]);
        }
        return statementAsts;
    }
};

module.exports = CldrPluralRuleSet;
<|endoftext|>


<commit_before>// Copyright (c) 2007-2009 gocept gmbh & co. kg
// See also LICENSE.txt
// $Id$

zeit.cms.PanelHandler = Class.extend({

    construct: function(base_url) {
        this.url = base_url + '/panel_handlers';
    },

    registerPanelHandlers: function() {
        var panels = getElementsByTagAndClassName('div', 'panel');
        this.resizePanels(panels);
        this.registerFoldHandlers(panels);
        connect('sidebar', 'panel-content-changed', this, 'resizeAllPanels');
        addElementClass('sidebar', 'sized');
    },

    resizeAllPanels: function() {
        signal('sidebar', 'zeit.cms.RememberScrollStateEvent');
        var panels = getElementsByTagAndClassName('div', 'panel');
        // Reset
        forEach(panels, function(panel) {
            var content_element = getFirstElementByTagAndClassName(
                'div', 'PanelContent', panel);
            setStyle(content_element, {'height': ''});
        });
        this.resizePanels(panels);
        signal('sidebar', 'zeit.cms.RestoreScrollStateEvent');
    },

    resizePanels: function(panels) {
        var max_height = MochiKit.Style.getElementDimensions(
            'sidebar', true).h;
        var fixed_space = 0;
        var flex_sum = 0;

        // Compute flex_sum and fixed_space
        forEach(panels, function(panel) {
            var content_element = getFirstElementByTagAndClassName(
                'div', 'PanelContent', panel);
            // XXX: getAttributeNS doesn't work :(
            var flex = panel.getAttribute('panel:flex');
            var fixed;
            if (flex) {
                panel._flex = new Number(flex);
                flex_sum += panel._flex;
                fixed = panel.clientHeight - content_element.clientHeight;
            } else {
                // A non flexible panel will not be shrunk
                fixed = panel.clientHeight;
            }
            log(panel.id, 'fixed =', fixed, 'flex =', flex);
            fixed_space += fixed;
        });

        // Fix up flex / fixed_space for not making panels larger than they'd
        // need to be
        var continue_ = true;
        while (continue_) {
            continue_ = false;
            log("Max height", max_height);
            log("Fixed space", fixed_space);
            var available_space = max_height - fixed_space;
            var space_per_flex = available_space / flex_sum;
            log("space per flex", space_per_flex);

            forEach(panels, function(panel) {
                var content_element = getFirstElementByTagAndClassName(
                    'div', 'PanelContent', panel);
                if (panel._flex) {
                    var new_height = panel._flex * space_per_flex;
                    if (new_height >= content_element.clientHeight) {
                        flex_sum -= panel._flex;
                        fixed_space += content_element.clientHeight;
                        panel._flex = null;
                        continue_ = true;
                        throw MochiKit.Iter.StopIteration;
                    }
                }
            });
        }

        // Finally set the sizes
        forEach(panels, function(panel) {
            var content_element = getFirstElementByTagAndClassName(
                'div', 'PanelContent', panel);
            if (panel._flex) {
                // compute padding and remove px from padding;
                // NOTE: this is quite expensive, maybe we can work around
                // calling getStyle somehow?
                var padding_top = getStyle(
                    content_element, 'padding-top').slice(0, -2);
                var padding_bottom = getStyle(
                    content_element, 'padding-bottom').slice(0, -2);
                var padding = (
                    new Number(padding_top) + new Number(padding_bottom));

                var height = panel._flex * space_per_flex - padding;
                log("Sizing", panel.id, "at", height, "flex =", panel._flex);
                setStyle(content_element, {'height': height + 'px'});
            }
        });
    },

    registerFoldHandlers: function(panels) {
        var self = this;
        forEach(panels, function(panel) {
            var foldmarker = panel.getElementsByTagName('h1')[0];
            connect(foldmarker, "onclick", function(event) {
                if (event.target() != foldmarker) return;
                var new_state;
                if (hasElementClass(panel, 'folded')) {
                    removeElementClass(panel, 'folded');
                    addElementClass(panel, 'unfolded');
                } else {
                    removeElementClass(panel, 'unfolded');
                    addElementClass(panel, 'folded');
                }
                self.resizeAllPanels();
                self.storeState(panel.id);
            });
            var content_element = getFirstElementByTagAndClassName(
                'div', 'PanelContent', panel);
            var scroll_state = new zeit.cms.ScrollStateRestorer(
                content_element);
            scroll_state.connectWindowHandlers();
            connect(
                'sidebar', 'zeit.cms.RememberScrollStateEvent',
                scroll_state, 'rememberScrollState');
            connect(
                'sidebar', 'zeit.cms.RestoreScrollStateEvent',
                scroll_state, 'restoreScrollState');

        });

    },

    storeState: function(panel_id) {
        doSimpleXMLHttpRequest(this.url, {toggle_folding: panel_id});
    },

});

// Handler to close and open the sidebar making more space for the actual
// content area.

function SidebarDragger(base_url) {
    this.url = base_url + '/@@sidebar_folded';
    this.observe_ids = new Array('sidebar', 'sidebar-dragger',
        'visualContentSeparator', 'visualContentWrapper', 'header');
}

SidebarDragger.prototype = {

    classes: ['sidebar-folded', 'sidebar-expanded'],

    toggle: function(event) {
        var self = this;
        var folded = ! hasElementClass('sidebar', 'sidebar-folded');
        var d = doSimpleXMLHttpRequest(this.url, {folded: folded});
        d.addCallback(function(result) {
            var css_class = result.responseText;
            self.setClass(css_class);
        });
    },

    hide: function() {
        var self = this;
        self.setClass('sidebar-folded');
    },

    setClass: function(css_class) {
        var self = this;
        forEach(this.observe_ids,
            function(element_id) {
              forEach(self.classes, function(cls) {
                  var element = getElement(element_id);
                  removeElementClass(element, cls);
                  });
        var element = getElement(element_id);
        addElementClass(element, css_class);
        });
    },
}
<commit_msg>change panel handlers so it is possible to add other things to the sidebar (besides panels)<commit_after>// Copyright (c) 2007-2009 gocept gmbh & co. kg
// See also LICENSE.txt
// $Id$

zeit.cms.PanelHandler = Class.extend({

    construct: function(base_url) {
        this.url = base_url + '/panel_handlers';
    },

    registerPanelHandlers: function() {
        var panels = MochiKit.DOM.getElementsByTagAndClassName(
            'div', 'panel', 'sidebar');
        this.resizePanels(panels);
        this.registerFoldHandlers(panels);
        MochiKit.Signal.connect(
            'sidebar', 'panel-content-changed', this, this.resizeAllPanels);
        MochiKit.DOM.addElementClass('sidebar', 'sized');
    },

    resizeAllPanels: function() {
        MochiKit.Signal.signal('sidebar', 'zeit.cms.RememberScrollStateEvent');
        var panels = MochiKit.DOM.getElementsByTagAndClassName(
            'div', 'panel', 'sidebar');
        // Reset
        forEach(panels, function(panel) {
            var content_element = MochiKit.DOM.getFirstElementByTagAndClassName(
                'div', 'PanelContent', panel);
            if (!isNull(content_element)) {
                MochiKit.Style.setStyle(content_element, {'height': ''});
            }
        });
        this.resizePanels(panels);
        MochiKit.Signal.signal('sidebar', 'zeit.cms.RestoreScrollStateEvent');
    },

    resizePanels: function(panels) {
        var max_height = MochiKit.Style.getElementDimensions(
            'sidebar', true).h;
        var fixed_space = 0;
        var flex_sum = 0;

        // Compute flex_sum and fixed_space
        forEach(panels, function(panel) {
            // XXX: getAttributeNS doesn't work :(
            var flex = panel.getAttribute('panel:flex');
            var fixed;
            if (flex) {
                var content_element = getFirstElementByTagAndClassName(
                    'div', 'PanelContent', panel);
                panel._flex = new Number(flex);
                flex_sum += panel._flex;
                fixed = panel.clientHeight - content_element.clientHeight;
            } else {
                // A non flexible panel will not be shrunk
                fixed = panel.clientHeight;
            }
            log(panel.id, 'fixed =', fixed, 'flex =', flex);
            fixed_space += fixed;
        });

        // Fix up flex / fixed_space for not making panels larger than they'd
        // need to be
        var continue_ = true;
        while (continue_) {
            continue_ = false;
            log("Max height", max_height);
            log("Fixed space", fixed_space);
            var available_space = max_height - fixed_space;
            log("Available space", available_space);
            var space_per_flex = available_space / flex_sum;
            log("space per flex", space_per_flex, available_space, flex_sum);

            forEach(panels, function(panel) {
                if (panel._flex) {
                    var content_element = getFirstElementByTagAndClassName(
                        'div', 'PanelContent', panel);
                    var new_height = panel._flex * space_per_flex;
                    if (new_height >= content_element.clientHeight) {
                        flex_sum -= panel._flex;
                        fixed_space += content_element.clientHeight;
                        panel._flex = null;
                        continue_ = true;
                        log('Panel does not exceed flex size:', panel.id,
                            new_height);
                        throw MochiKit.Iter.StopIteration;
                    }
                }
            });
        }

        // Finally set the sizes
        forEach(panels, function(panel) {
            if (panel._flex) {
                var content_element = getFirstElementByTagAndClassName(
                    'div', 'PanelContent', panel);
                // compute padding and remove px from padding;
                // NOTE: this is quite expensive, maybe we can work around
                // calling getStyle somehow?
                var padding_top = MochiKit.Style.getStyle(
                    content_element, 'padding-top').slice(0, -2);
                var padding_bottom = MochiKit.Style.getStyle(
                    content_element, 'padding-bottom').slice(0, -2);
                var padding = (
                    new Number(padding_top) + new Number(padding_bottom));

                var height = panel._flex * space_per_flex - padding;
                log("Sizing", panel.id, "at", height, "flex =", panel._flex);
                MochiKit.Style.setStyle(
                    content_element, {'height': height + 'px'});
            }
        });
    },

    registerFoldHandlers: function(panels) {
        var self = this;
        forEach(panels, function(panel) {
            var foldmarker = MochiKit.DOM.getFirstElementByTagAndClassName(
                'h1', null, panel)
            if (isNull(foldmarker)) {
                return; // continue
            }
            MochiKit.Signal.connect(foldmarker, "onclick", function(event) {
                if (event.target() != foldmarker) {
                    return;
                }
                var new_state;
                if (hasElementClass(panel, 'folded')) {
                    removeElementClass(panel, 'folded');
                    addElementClass(panel, 'unfolded');
                } else {
                    removeElementClass(panel, 'unfolded');
                    addElementClass(panel, 'folded');
                }
                self.resizeAllPanels();
                self.storeState(panel.id);
            });
            var content_element = getFirstElementByTagAndClassName(
                'div', 'PanelContent', panel);
            var scroll_state = new zeit.cms.ScrollStateRestorer(
                content_element);
            scroll_state.connectWindowHandlers();
            connect(
                'sidebar', 'zeit.cms.RememberScrollStateEvent',
                scroll_state, 'rememberScrollState');
            connect(
                'sidebar', 'zeit.cms.RestoreScrollStateEvent',
                scroll_state, 'restoreScrollState');

        });

    },

    storeState: function(panel_id) {
        doSimpleXMLHttpRequest(this.url, {toggle_folding: panel_id});
    },

});

// Handler to close and open the sidebar making more space for the actual
// content area.

function SidebarDragger(base_url) {
    this.url = base_url + '/@@sidebar_folded';
    this.observe_ids = new Array('sidebar', 'sidebar-dragger',
        'visualContentSeparator', 'visualContentWrapper', 'header');
}

SidebarDragger.prototype = {

    classes: ['sidebar-folded', 'sidebar-expanded'],

    toggle: function(event) {
        var self = this;
        var folded = ! hasElementClass('sidebar', 'sidebar-folded');
        var d = doSimpleXMLHttpRequest(this.url, {folded: folded});
        d.addCallback(function(result) {
            var css_class = result.responseText;
            self.setClass(css_class);
        });
    },

    hide: function() {
        var self = this;
        self.setClass('sidebar-folded');
    },

    setClass: function(css_class) {
        var self = this;
        forEach(this.observe_ids,
            function(element_id) {
              forEach(self.classes, function(cls) {
                  var element = getElement(element_id);
                  removeElementClass(element, cls);
                  });
        var element = getElement(element_id);
        addElementClass(element, css_class);
        });
    },
}
<|endoftext|>


<commit_before>const url = require('url')
const {Disposable} = require('event-kit')

// Public: Associates listener functions with URLs from outside the application.
//
// The global URL handler registry maps URLs to listener functions. URLs are mapped
// based on the hostname of the URL; the format is atom://package/command?args.
// The "core" package name is reserved for URLs handled by Atom core (it is not possible
// to register a package with the name "core").
//
// Because URL handling can be triggered from outside the application (e.g. from
// the user's browser), package authors should take great care to ensure that malicious
// activities cannot be performed by an attacker. A good rule to follow is that
// **URL handlers should not take action on behalf of the user**. For example, clicking
// a link to open a pane item that prompts the user to install a package is okay;
// automatically installing the package right away is not.
//
// Packages can register their desire to handle URLs via a special key in their
// `package.json` called "urlHandlers". The value of this key should be an object
// that contains, at minimum, a key named "method". This is the name of the method
// on your package object that Atom will call when it receives a URL your package
// is responsible for handling. It will pass the full URL as the only argument, and you
// are free to do your own URL parsing to handle it.
//
// If your package can defer activation until a URL it needs to handle is triggered,
// you can additionally specify the `"defer": true` option in your "urlHandlers" object.
// When Atom receives a request for a URL in your package's namespace, it will activate your
// pacakge and then call `methodName` on it as before.
//
// If your package specifies a deprecated `urlMain` property, you cannot register URL handlers
// via the `urlHandlers` key.
//
// ## Example
//
// Here is a message that could open a specific panel in a package's view:
//
// `package.json`:
//
// ```javascript
// {
//   "name": "my-package",
//   "main": "./lib/my-package.js",
//   "urlHandlers": {
//     "method": "handleUrl",
//     "deferActivation": true,
//   }
// }
// ```
//
// `lib/my-package.json`
//
// ```javascript
// module.exports = {
//   activate: function() {
//     // code to activate your package
//   }
//
//   handleUrl(url) {
//     // parse and handle url
//   }
// }
// ```
//
// In this example, when Atom handles `atom://my-package/something`, it will activate your
// package and then call `handleUrl` passing in the string `"atom://my-package/something"`
module.exports =
class UrlHandlerRegistry {
  constructor () {
    this.registrations = new Map()
  }

  registerHostHandler (host, callback) {
    if (typeof callback !== 'function') {
      throw new Error('Cannot register a URL host handler with a non-function callback')
    }

    if (this.registrations.has(host)) {
      throw new Error(`There is already a URL host handler for the host ${host}`)
    } else {
      this.registrations.set(host, callback)
    }

    return new Disposable(() => {
      this.registrations.delete(host)
    })
  }

  handleUrl (uri) {
    const {protocol, slashes, auth, port, host} = url.parse(uri)
    if (protocol !== 'atom:' || slashes !== true || auth || port) {
      throw new Error(`UrlHandlerRegistry#handleUrl asked to handle an invalid URL: ${uri}`)
    }

    const registration = this.registrations.get(host)
    if (registration) {
      registration(uri)
    }
  }
}
<commit_msg>Make it private<commit_after>const url = require('url')
const {Disposable} = require('event-kit')

// Private: Associates listener functions with URLs from outside the application.
//
// The global URL handler registry maps URLs to listener functions. URLs are mapped
// based on the hostname of the URL; the format is atom://package/command?args.
// The "core" package name is reserved for URLs handled by Atom core (it is not possible
// to register a package with the name "core").
//
// Because URL handling can be triggered from outside the application (e.g. from
// the user's browser), package authors should take great care to ensure that malicious
// activities cannot be performed by an attacker. A good rule to follow is that
// **URL handlers should not take action on behalf of the user**. For example, clicking
// a link to open a pane item that prompts the user to install a package is okay;
// automatically installing the package right away is not.
//
// Packages can register their desire to handle URLs via a special key in their
// `package.json` called "urlHandlers". The value of this key should be an object
// that contains, at minimum, a key named "method". This is the name of the method
// on your package object that Atom will call when it receives a URL your package
// is responsible for handling. It will pass the full URL as the only argument, and you
// are free to do your own URL parsing to handle it.
//
// If your package can defer activation until a URL it needs to handle is triggered,
// you can additionally specify the `"defer": true` option in your "urlHandlers" object.
// When Atom receives a request for a URL in your package's namespace, it will activate your
// pacakge and then call `methodName` on it as before.
//
// If your package specifies a deprecated `urlMain` property, you cannot register URL handlers
// via the `urlHandlers` key.
//
// ## Example
//
// Here is a message that could open a specific panel in a package's view:
//
// `package.json`:
//
// ```javascript
// {
//   "name": "my-package",
//   "main": "./lib/my-package.js",
//   "urlHandlers": {
//     "method": "handleUrl",
//     "deferActivation": true,
//   }
// }
// ```
//
// `lib/my-package.json`
//
// ```javascript
// module.exports = {
//   activate: function() {
//     // code to activate your package
//   }
//
//   handleUrl(url) {
//     // parse and handle url
//   }
// }
// ```
//
// In this example, when Atom handles `atom://my-package/something`, it will activate your
// package and then call `handleUrl` passing in the string `"atom://my-package/something"`
module.exports =
class UrlHandlerRegistry {
  constructor () {
    this.registrations = new Map()
  }

  registerHostHandler (host, callback) {
    if (typeof callback !== 'function') {
      throw new Error('Cannot register a URL host handler with a non-function callback')
    }

    if (this.registrations.has(host)) {
      throw new Error(`There is already a URL host handler for the host ${host}`)
    } else {
      this.registrations.set(host, callback)
    }

    return new Disposable(() => {
      this.registrations.delete(host)
    })
  }

  handleUrl (uri) {
    const {protocol, slashes, auth, port, host} = url.parse(uri)
    if (protocol !== 'atom:' || slashes !== true || auth || port) {
      throw new Error(`UrlHandlerRegistry#handleUrl asked to handle an invalid URL: ${uri}`)
    }

    const registration = this.registrations.get(host)
    if (registration) {
      registration(uri)
    }
  }
}
<|endoftext|>