<commit_before>/**
 * Copyright 2014 Shape Security, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {Identifier, LiteralStringExpression, LiteralNumericExpression} from "shift-ast";

// convert Shift AST format to SpiderMonkey AST format

export default function convert(ast) {
  if (ast == null) {
    return null;
  }
  return Convert[ast.type](ast);
}

function convertFunctionBody(node) {
  return node.directives.map(convert).concat(node.statements.map(convert))
}

function convertFunctionDeclaration(node) {
  return {
    type: "FunctionDeclaration",
    id: convert(node.name),
    params: node.parameters.map(convert),
    defaults: [],
    body: {
      type: "BlockStatement",
      body: convert(node.body)
    },
    rest: null,
    generator: false,
    expression: false
  };
}

function convertFunctionExpression(node) {
  return {
    type: "FunctionExpression",
    id: convert(node.name),
    params: node.parameters.map(convert),
    defaults: [],
    body: {
      type: "BlockStatement",
      body: convert(node.body)
    },
    rest: null,
    generator: false,
    expression: false
  };
}

function convertObjectExpression(node) {
  return {
    type: "ObjectExpression",
    properties: node.properties.map(convert)
  };
}

function convertGetter(node) {
  return {
    type: "Property",
    key: convertPropertyName(node.name),
    value: {
      type: "FunctionExpression",
      id: null,
      params: [],
      defaults: [],
      rest: null,
      body: {
        type: "BlockStatement",
        body: convertFunctionBody(node.body)
      },
      generator: false,
      expression: false
    },
    kind: "get"
  };
}

function convertSetter(node) {
  return {
    type: "Property",
    key: convertPropertyName(node.name),
    value: {
      type: "FunctionExpression",
      id: null,
      params: [convert(node.parameter)],
      defaults: [],
      rest: null,
      body: {
        type: "BlockStatement",
        body: convertFunctionBody(node.body)
      },
      generator: false,
      expression: false
    },
    kind: "set"
  };
}

function convertDataProperty(node) {
  return {
    type: "Property",
    key: convertPropertyName(node.name),
    value: convert(node.expression),
    kind: "init"
  };
}

function convertPropertyName(node) {
  switch (node.kind) {
    case "identifier":
      return convert(new Identifier(node.value));
    case "string":
      return convert(new LiteralStringExpression(node.value));
    case "number":
      return convert(new LiteralNumericExpression(+node.value));
  }
}

function convertLiteralBooleanExpression(node) {
  return {
    type: "Literal",
    value: node.value,
  };
}

function convertLiteralNullExpression() {
  return {
    type: "Literal",
    value: null,
  };
}

function convertLiteralNumericExpression(node) {
  return {
    type: "Literal",
    value: node.value,
  };
}

function convertLiteralInfinityExpression(node) {
  return {
    type: "Literal",
    value: 1 / 0,
  };
}

function convertLiteralRegExpExpression(node) {
  let idx = node.value.lastIndexOf('/');
  return {
    type: "Literal",
    value: RegExp(node.value.slice(1, idx), node.value.slice(idx + 1)),
  };
}

function convertLiteralStringExpression(node) {
  return {
    type: "Literal",
    value: node.value,
  };
}

function convertArrayExpression(node) {
  return {
    type: "ArrayExpression",
    elements: node.elements.map(convert)
  };
}

function convertAssignmentExpression(node) {
  return {
    type: "AssignmentExpression",
    operator: node.operator,
    left: convert(node.binding),
    right: convert(node.expression)
  };
}

function convertSequenceExpressionToArray(node) {
  let array = [];
  if (node.left.type === "BinaryExpression" && node.left.operator === ",") {
    array = convertSequenceExpressionToArray(node.left);
  } else {
    array = [convert(node.left)];
  }
  array.push(convert(node.right));
  return array;
}

function convertBinaryExpression(node) {
  if (node.operator === ",") {
    return {
      type: "SequenceExpression",
      expressions: convertSequenceExpressionToArray(node)
    };
  }
  return {
    type: node.operator === "||" || node.operator === "&&" ? "LogicalExpression" : "BinaryExpression",
    operator: node.operator,
    left: convert(node.left),
    right: convert(node.right)
  };
}

function convertCallExpression(node) {
  return {
    type: "CallExpression",
    callee: convert(node.callee),
    arguments: node.arguments.map(convert)
  };
}

function convertComputedMemberExpression(node) {
  return {
    type: "MemberExpression",
    object: convert(node.object),
    property: convert(node.expression),
    computed: true
  };
}

function convertConditionalExpression(node) {
  return {
    type: "ConditionalExpression",
    test: convert(node.test),
    alternate: convert(node.alternate),
    consequent: convert(node.consequent)
  };
}

function convertIdentifierExpression(node) {
  return convert(node.identifier);
}

function convertNewExpression(node) {
  return {
    type: "NewExpression",
    callee: convert(node.callee),
    arguments: node.arguments.map(convert)
  };
}

function convertPostfixExpression(node) {
  return {
    type: "UpdateExpression",
    operator: node.operator,
    argument: convert(node.operand),
    prefix: false
  };
}

function convertPrefixExpression(node) {
  if (node.operator === "++" || node.operator === "--") {
    return {
      type: "UpdateExpression",
      operator: node.operator,
      prefix: true,
      argument: convert(node.operand)
    }
  }
  return {
    type: "UnaryExpression",
    operator: node.operator,
    prefix: true,
    argument: convert(node.operand)
  };
}

function convertStaticMemberExpression(node) {
  return {
    type: "MemberExpression",
    object: convert(node.object),
    property: convert(node.property),
    computed: false
  };
}

function convertThisExpression() {
  return {
    type: "ThisExpression"
  };
}

function convertBlockStatement(node) {
  return convertBlock(node.block);
}

function convertBreakStatement(node) {
  return {
    type: "BreakStatement",
    label: convert(node.label)
  };
}

function convertContinueStatement(node) {
  return {
    type: "ContinueStatement",
    label: convert(node.label)
  };
}

function convertDebuggerStatement() {
  return {
    type: "DebuggerStatement"
  };
}

function convertDoWhileStatement(node) {
  return {
    type: "DoWhileStatement",
    test: convert(node.test),
    body: convert(node.body)
  };
}

function convertEmptyStatement() {
  return {
    type: "EmptyStatement"
  };
}

function convertExpressionStatement(node) {
  return {
    type: "ExpressionStatement",
    expression: convert(node.expression)
  };
}

function convertForInStatement(node) {
  return {
    type: "ForInStatement",
    left: convert(node.left),
    right: convert(node.right),
    body: convert(node.body),
    each: false
  };
}

function convertForStatement(node) {
  return {
    type: "ForStatement",
    init: convert(node.init),
    test: convert(node.test),
    update: convert(node.update),
    body: convert(node.body)
  };
}

function convertIfStatement(node) {
  return {
    type: "IfStatement",
    test: convert(node.test),
    consequent: convert(node.consequent),
    alternate: convert(node.alternate)
  };
}

function convertLabeledStatement(node) {
  return {
    type: "LabeledStatement",
    label: convertIdentifier(node.label),
    body: convert(node.body)
  };
}

function convertReturnStatement(node) {
  return {
    type: "ReturnStatement",
    argument: convert(node.expression)
  };
}

function convertSwitchStatement(node) {
  return {
    type: "SwitchStatement",
    discriminant: convert(node.discriminant),
    cases: node.cases.map(convert)
  };
}

function convertSwitchStatementWithDefault(node) {
  return {
    type: "SwitchStatement",
    discriminant: convert(node.discriminant),
    cases: node.preDefaultCases.map(convert).
        concat(convert(node.defaultCase)).
        concat(node.postDefaultCases.map(convert))
  };
}

function convertThrowStatement(node) {
  return {
    type: "ThrowStatement",
    argument: convert(node.expression)
  };
}

function convertTryCatchStatement(node) {
  return {
    type: "TryStatement",
    block: convertBlock(node.body),
    handlers: [convert(node.catchClause)],
    guardedHandlers: [],
    finalizer: null
  };
}

function convertTryFinallyStatement(node) {
  return {
    type: "TryStatement",
    block: convertBlock(node.body),
    handlers: [convert(node.catchClause)],
    guardedHandlers: [],
    finalizer: convert(node.finalizer)
  };
}

function convertVariableDeclarationStatement(node) {
  return convert(node.declaration);
}

function convertWhileStatement(node) {
  return {
    type: "WhileStatement",
    test: convert(node.test),
    body: convert(node.body)
  };
}

function convertWithStatement(node) {
  return {
    type: "WithStatement",
    object: convert(node.object),
    body: convert(node.body)
  };
}

function convertUnknownDirective(node) {
  return {
    type: "ExpressionStatement",
    expression: {
      type: "Literal",
      value: node.value,
    }
  };
}

function convertUseStrictDirective() {
  return {
    type: "ExpressionStatement",
    expression: {
      type: "Literal",
      value: "use strict",
    }
  };
}

function convertBlock(node) {
  return {
    type: "BlockStatement",
    body: node.statements.map(convert)
  };
}

function convertCatchClause(node) {
  return {
    type: "CatchClause",
    param: convert(node.binding),
    body: convert(node.body)
  };
}

function convertIdentifier(node) {
  return {
    type: "Identifier",
    name: node.name
  };
}

function convertScript(node) {
  return {
    type: "Program",
    body: convertFunctionBody(node.body)
  };
}

function convertSwitchCase(node) {
  return {
    type: "SwitchCase",
    test: convert(node.test),
    consequent: node.consequent.map(convert)
  };
}

function convertSwitchDefault(node) {
  return {
    type: "SwitchCase",
    test: null,
    consequent: node.consequent.map(convert)
  };
}

function convertVariableDeclaration(node) {
  return {
    type: "VariableDeclaration",
    declarations: node.declarators.map(convert),
    kind: node.kind
  };
}

function convertVariableDeclarator(node) {
  return {
    type: "VariableDeclarator",
    id: convert(node.binding),
    init: convert(node.init)
  };
}

const Convert = {
  FunctionBody: convertFunctionBody,
  FunctionDeclaration: convertFunctionDeclaration,
  FunctionExpression: convertFunctionExpression,
  ObjectExpression: convertObjectExpression,
  Getter: convertGetter,
  Setter: convertSetter,
  DataProperty: convertDataProperty,
  PropertyName: convertPropertyName,
  LiteralBooleanExpression: convertLiteralBooleanExpression,
  LiteralNullExpression: convertLiteralNullExpression,
  LiteralNumericExpression: convertLiteralNumericExpression,
  LiteralInfinityExpression: convertLiteralInfinityExpression,
  LiteralRegExpExpression: convertLiteralRegExpExpression,
  LiteralStringExpression: convertLiteralStringExpression,
  ArrayExpression: convertArrayExpression,
  AssignmentExpression: convertAssignmentExpression,
  BinaryExpression: convertBinaryExpression,
  CallExpression: convertCallExpression,
  ComputedMemberExpression: convertComputedMemberExpression,
  ConditionalExpression: convertConditionalExpression,
  IdentifierExpression: convertIdentifierExpression,
  NewExpression: convertNewExpression,
  PostfixExpression: convertPostfixExpression,
  PrefixExpression: convertPrefixExpression,
  StaticMemberExpression: convertStaticMemberExpression,
  ThisExpression: convertThisExpression,
  BlockStatement: convertBlockStatement,
  BreakStatement: convertBreakStatement,
  ContinueStatement: convertContinueStatement,
  DebuggerStatement: convertDebuggerStatement,
  DoWhileStatement: convertDoWhileStatement,
  EmptyStatement: convertEmptyStatement,
  ExpressionStatement: convertExpressionStatement,
  ForInStatement: convertForInStatement,
  ForStatement: convertForStatement,
  IfStatement: convertIfStatement,
  LabeledStatement: convertLabeledStatement,
  ReturnStatement: convertReturnStatement,
  SwitchStatement: convertSwitchStatement,
  SwitchStatementWithDefault: convertSwitchStatementWithDefault,
  ThrowStatement: convertThrowStatement,
  TryCatchStatement: convertTryCatchStatement,
  TryFinallyStatement: convertTryFinallyStatement,
  VariableDeclarationStatement: convertVariableDeclarationStatement,
  WhileStatement: convertWhileStatement,
  WithStatement: convertWithStatement,
  UnknownDirective: convertUnknownDirective,
  UseStrictDirective: convertUseStrictDirective,
  Block: convertBlock,
  CatchClause: convertCatchClause,
  Identifier: convertIdentifier,
  Script: convertScript,
  SwitchCase: convertSwitchCase,
  SwitchDefault: convertSwitchDefault,
  VariableDeclaration: convertVariableDeclaration,
  VariableDeclarator: convertVariableDeclarator
};
<commit_msg>update to current Esprima parse output. add new node types to Convert object<commit_after>/**
 * Copyright 2014 Shape Security, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {Identifier, LiteralStringExpression, LiteralNumericExpression} from "shift-ast";

// convert Shift AST format to SpiderMonkey AST format

export default function convert(ast) {
  if (ast == null) {
    return null;
  }

  if(Convert[ast.type] === convert) throw Error(`convert${ast.type} not implemented.`);

  return Convert[ast.type](ast);
}

function convertFunctionBody(node) {
  return node.directives.map(convert).concat(node.statements.map(convert));
}

function convertFunctionDeclaration(node) {
  return {
    type: "FunctionDeclaration",
    id: convert(node.name),
    params: node.params.map(convert),
    defaults: [],
    body: {
      type: "BlockStatement",
      body: convert(node.body)
    },
    generator: false,
    expression: false
  };
}

function convertFunctionExpression(node) {
  return {
    type: "FunctionExpression",
    id: convert(node.name),
    params: node.params.map(convert),
    defaults: [],
    body: {
      type: "BlockStatement",
      body: convert(node.body)
    },
    generator: false,
    expression: false
  };
}

function convertObjectExpression(node) {
  return {
    type: "ObjectExpression",
    properties: node.properties.map(convert)
  };
}

function convertGetter(node) {
  return {
    type: "Property",
    key: convert(node.name),
    computed: false,
    value: convert(node.body),
    method: false,
    shorthand: false,
    kind: "get"
  };
}

function convertSetter(node) {
  return {
    type: "Property",
    key: convert(node.name),
    computed: false,
    value: convert(node.body),
    method: false,
    shorthand: false,
    kind: "set"
  };
}

function convertDataProperty(node) {
  return {
    type: "Property",
    key: convert(node.name),
    value: convert(node.expression),
    kind: "init",
    computed: node.name.type === "ComputedPropertyName",
    method: false,
    shorthand: false
  };
}

function convertComputedPropertyName(node) {
  return {
  };
}

function convertPropertyName(node) {
  switch (node.type) {
  case "StaticPropertyName":
    return convertStaticPropertyName(node);
  case "ComputedPropertyName":
    return convertComputedPropertyName(node);
  case "ShorthandProperty":
    return convertShorthandProperty(node);
  }
}

function convertLiteralBooleanExpression(node) {
  return {
    type: "Literal",
    value: node.value,
  };
}

function convertLiteralNullExpression() {
  return {
    type: "Literal",
    value: null,
  };
}

function convertLiteralNumericExpression(node) {
  return {
    type: "Literal",
    value: node.value,
  };
}

function convertLiteralInfinityExpression(node) {
  return {
    type: "Literal",
    value: 1 / 0,
  };
}

function convertLiteralRegExpExpression(node) {
  return {
    type: "Literal",
    value: RegExp(node.pattern, node.flags),
    regex: {
      pattern: node.pattern,
      flags: node.flags
    }
  };
}

function convertLiteralStringExpression(node) {
  return {
    type: "Literal",
    value: node.value
  };
}

function convertArrayExpression(node) {
  return {
    type: "ArrayExpression",
    elements: node.elements.map(convert)
  };
}

function convertAssignmentExpression(node) {
  return {
    type: "AssignmentExpression",
    operator: "=",
    left: convert(node.binding),
    right: convert(node.expression)
  };
}

function convertSequenceExpressionToArray(node) {
  let array = [];
  if (node.left.type === "BinaryExpression" && node.left.operator === ",") {
    array = convertSequenceExpressionToArray(node.left);
  } else {
    array = [convert(node.left)];
  }
  array.push(convert(node.right));
  return array;
}

function convertBinaryExpression(node) {
  if (node.operator === ",") {
    return {
      type: "SequenceExpression",
      expressions: convertSequenceExpressionToArray(node)
    };
  }
  return {
    type: node.operator === "||" || node.operator === "&&" ? "LogicalExpression" : "BinaryExpression",
    operator: node.operator,
    left: convert(node.left),
    right: convert(node.right)
  };
}

function convertCallExpression(node) {
  return {
    type: "CallExpression",
    callee: convert(node.callee),
    arguments: node.arguments.map(convert)
  };
}

function convertComputedMemberExpression(node) {
  return {
    type: "MemberExpression",
    object: convert(node.object),
    property: convert(node.expression),
    computed: true
  };
}

function convertConditionalExpression(node) {
  return {
    type: "ConditionalExpression",
    test: convert(node.test),
    alternate: convert(node.alternate),
    consequent: convert(node.consequent)
  };
}

function convertIdentifierExpression(node) {
  return convert(node.name);
}

function convertNewExpression(node) {
  return {
    type: "NewExpression",
    callee: convert(node.callee),
    arguments: node.arguments.map(convert)
  };
}

function convertStaticMemberExpression(node) {
  return {
    type: "MemberExpression",
    object: convert(node.object),
    property: convert(node.property),
    computed: false
  };
}

function convertThisExpression() {
  return {
    type: "ThisExpression"
  };
}

function convertBlockStatement(node) {
  return convertBlock(node.block);
}

function convertBreakStatement(node) {
  return {
    type: "BreakStatement",
    label: convert(node.label)
  };
}

function convertContinueStatement(node) {
  return {
    type: "ContinueStatement",
    label: convert(node.label)
  };
}

function convertDebuggerStatement() {
  return {
    type: "DebuggerStatement"
  };
}

function convertDoWhileStatement(node) {
  return {
    type: "DoWhileStatement",
    test: convert(node.test),
    body: convert(node.body)
  };
}

function convertEmptyStatement() {
  return {
    type: "EmptyStatement"
  };
}

function convertExpressionStatement(node) {
  return {
    type: "ExpressionStatement",
    expression: convert(node.expression)
  };
}

function convertForInStatement(node) {
  return {
    type: "ForInStatement",
    left: convert(node.left),
    right: convert(node.right),
    body: convert(node.body),
    each: false
  };
}

function convertForStatement(node) {
  return {
    type: "ForStatement",
    init: convert(node.init),
    test: convert(node.test),
    update: convert(node.update),
    body: convert(node.body)
  };
}

function convertIfStatement(node) {
  return {
    type: "IfStatement",
    test: convert(node.test),
    consequent: convert(node.consequent),
    alternate: convert(node.alternate)
  };
}

function convertLabeledStatement(node) {
  return {
    type: "LabeledStatement",
    label: convertIdentifier(node.label),
    body: convert(node.body)
  };
}

function convertReturnStatement(node) {
  return {
    type: "ReturnStatement",
    argument: convert(node.expression)
  };
}

function convertSwitchStatement(node) {
  return {
    type: "SwitchStatement",
    discriminant: convert(node.discriminant),
    cases: node.cases.map(convert)
  };
}

function convertSwitchStatementWithDefault(node) {
  return {
    type: "SwitchStatement",
    discriminant: convert(node.discriminant),
    cases: node.preDefaultCases.map(convert).
        concat(convert(node.defaultCase)).
        concat(node.postDefaultCases.map(convert))
  };
}

function convertThrowStatement(node) {
  return {
    type: "ThrowStatement",
    argument: convert(node.expression)
  };
}

function convertTryCatchStatement(node) {
  let catchClause = convert(node.catchClause);
  return {
    type: "TryStatement",
    block: convertBlock(node.body),
    handlers: [catchClause],
    handler: catchClause,
    guardedHandlers: [],
    finalizer: null
  };
}

function convertTryFinallyStatement(node) {
  let catchClause = convert(node.catchClause);
  return {
    type: "TryStatement",
    block: convertBlock(node.body),
    handlers: [catchClause],
    handler: catchClause,
    guardedHandlers: [],
    finalizer: convert(node.finalizer)
  };
}

function convertVariableDeclarationStatement(node) {
  return convert(node.declaration);
}

function convertWhileStatement(node) {
  return {
    type: "WhileStatement",
    test: convert(node.test),
    body: convert(node.body)
  };
}

function convertWithStatement(node) {
  return {
    type: "WithStatement",
    object: convert(node.object),
    body: convert(node.body)
  };
}

function convertBlock(node) {
  return {
    type: "BlockStatement",
    body: node.statements.map(convert)
  };
}

function convertCatchClause(node) {
  return {
    type: "CatchClause",
    param: convert(node.binding),
    body: convert(node.body)
  };
}

function convertIdentifier(node) {
  return {
    type: "Identifier",
    name: node.name
  };
}

function convertScript(node) {
  return {
    type: "Program",
    body: convertFunctionBody(node.statements),
    sourceType: node.scriptType === "module" ? "module" : "script"
  };
}

function convertSwitchCase(node) {
  return {
    type: "SwitchCase",
    test: convert(node.test),
    consequent: node.consequent.map(convert)
  };
}

function convertSwitchDefault(node) {
  return {
    type: "SwitchCase",
    test: null,
    consequent: node.consequent.map(convert)
  };
}

function convertVariableDeclaration(node) {
  return {
    type: "VariableDeclaration",
    declarations: node.declarators.map(convert),
    kind: node.kind
  };
}

function convertVariableDeclarator(node) {
  return {
    type: "VariableDeclarator",
    id: convert(node.binding),
    init: convert(node.init)
  };
}

function convertBindingIdentifier(node) {
  return {
    type: "Identifier",
    name: node.name
  };
}

function convertDirective(node) {
  return {
    type: "ExpressionStatement",
    expression: {
      type: "Literal",
      value: node.rawValue
    }
  };
}

function convertUpdateExpression(node) {
  return {
    type: "UpdateExpression",
    prefix: node.isPrefix,
    operator: node.operator,
    argument: convert(node.operand)
  };
}

function convertUnaryExpression(node) {
  return {
    type: "UnaryExpression",
    operator: node.operator,
    argument: convert(node.operand),
    prefix: true
  };
}

function convertStaticPropertyName(node) {
  let valueType = typeof node.value;
  if(valueType === "string" || valueType === "number") {
    return {
      type: "Literal",
      value: node.value
    };
  } else {
    return {
      type: "Identifier",
      name: node.value
    };
  }
}

const Convert = {
  SourceLocation: convert,
  SourceSpan: convert,
  BindingWithDefault: convert,
  BindingIdentifier: convertBindingIdentifier,
  ArrayBinding: convert,
  ObjectBinding: convert,
  BindingPropertyIdentifier: convert,
  BindingPropertyProperty: convert,
  ClassExpression: convert,
  ClassElement: convert,
  Module: convert,
  Import: convert,
  ImportNamespace: convert,
  ImportSpecifier: convert,
  ExportAllFrom: convert,
  ExportFrom: convert,
  Export: convert,
  ExportDefault: convert,
  ExportSpecifier: convert,
  Method: convert,
  FunctionBody: convertFunctionBody,
  FunctionDeclaration: convertFunctionDeclaration,
  FunctionExpression: convertFunctionExpression,
  ObjectExpression: convertObjectExpression,
  Getter: convertGetter,
  Setter: convertSetter,
  DataProperty: convertDataProperty,
  ShorthandProperty: convert,
  ComputedPropertyName: convert,
  StaticPropertyName: convertStaticPropertyName,
  LiteralBooleanExpression: convertLiteralBooleanExpression,
  LiteralNullExpression: convertLiteralNullExpression,
  LiteralNumericExpression: convertLiteralNumericExpression,
  LiteralInfinityExpression: convertLiteralInfinityExpression,
  LiteralRegExpExpression: convertLiteralRegExpExpression,
  LiteralStringExpression: convertLiteralStringExpression,
  ArrayExpression: convertArrayExpression,
  ArrowExpression: convert,
  AssignmentExpression: convertAssignmentExpression,
  BinaryExpression: convertBinaryExpression,
  CallExpression: convertCallExpression,
  CompoundAssignmentExpression: convert,
  ComputedMemberExpression: convertComputedMemberExpression,
  ConditionalExpression: convertConditionalExpression,
  IdentifierExpression: convertIdentifierExpression,
  NewExpression: convertNewExpression,
  NewTargetExpression: convert,
  UnaryExpression: convertUnaryExpression,
  StaticMemberExpression: convertStaticMemberExpression,
  TemplateExpression: convert,
  ThisExpression: convertThisExpression,
  UpdateExpression: convertUpdateExpression,
  YieldExpression: convert,
  YieldGeneratorExpression: convert,
  BlockStatement: convertBlockStatement,
  BreakStatement: convertBreakStatement,
  ContinueStatement: convertContinueStatement,
  DebuggerStatement: convertDebuggerStatement,
  DoWhileStatement: convertDoWhileStatement,
  EmptyStatement: convertEmptyStatement,
  ExpressionStatement: convertExpressionStatement,
  ForInStatement: convertForInStatement,
  ForOfStatement: convert,
  ForStatement: convertForStatement,
  IfStatement: convertIfStatement,
  LabeledStatement: convertLabeledStatement,
  ReturnStatement: convertReturnStatement,
  SwitchStatement: convertSwitchStatement,
  SwitchStatementWithDefault: convertSwitchStatementWithDefault,
  ThrowStatement: convertThrowStatement,
  TryCatchStatement: convertTryCatchStatement,
  TryFinallyStatement: convertTryFinallyStatement,
  VariableDeclarationStatement: convertVariableDeclarationStatement,
  WhileStatement: convertWhileStatement,
  WithStatement: convertWithStatement,
  Block: convertBlock,
  CatchClause: convertCatchClause,
  Directive: convertDirective,
  FormalParameters: convert,
  Script: convertScript,
  SpreadElement: convert,
  Super: convert,
  SwitchCase: convertSwitchCase,
  SwitchDefault: convertSwitchDefault,
  TemplateElement: convert,
  VariableDeclaration: convertVariableDeclaration,
  VariableDeclarator: convertVariableDeclarator
};
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import _ from 'lodash';

export const PRESENTATION_ATTRIBUTES = {
  alignmentBaseline: PropTypes.string,
  baselineShift: PropTypes.string,
  clip: PropTypes.string,
  clipPath: PropTypes.string,
  clipRule: PropTypes.string,
  color: PropTypes.string,
  colorInterpolation: PropTypes.string,
  colorInterpolationFilters: PropTypes.string,
  colorProfile: PropTypes.string,
  colorRendering: PropTypes.string,
  cursor: PropTypes.string,
  direction: PropTypes.oneOf(['ltr', 'rtl', 'inherit']),
  display: PropTypes.string,
  dominantBaseline: PropTypes.string,
  enableBackground: PropTypes.string,
  fill: PropTypes.string,
  fillOpacity: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  fillRule: PropTypes.oneOf(['nonzero', 'evenodd', 'inherit']),
  filter: PropTypes.string,
  floodColor: PropTypes.string,
  floodOpacity: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  font: PropTypes.string,
  fontFamily: PropTypes.string,
  fontSize: PropTypes.number,
  fontSizeAdjust: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  fontStretch: PropTypes.oneOf([
    'normal', 'wider', 'narrower', 'ultra-condensed', 'extra-condensed',
    'condensed', 'semi-condensed', 'semi-expanded', 'expanded',
    'extra-expanded', 'ultra-expanded', 'inherit',
  ]),
  fontStyle: PropTypes.oneOf(['normal', 'italic', 'oblique', 'inherit']),
  fontVariant: PropTypes.oneOf(['normal', 'small-caps', 'inherit']),
  fontWeight: PropTypes.oneOf([
    'normal', 'bold', 'bolder', 'lighter',
    100, 200, 300, 400, 500, 600, 700, 800, 900, 'inherit',
  ]),
  glyphOrientationHorizontal: PropTypes.string,
  glyphOrientationVertical: PropTypes.string,
  imageRendering: PropTypes.oneOf([
    'auto', 'optimizeSpeed', 'optimizeQuality', 'inherit',
  ]),
  kerning: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  letterSpacing: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  lightingColor: PropTypes.string,
  markerEnd: PropTypes.string,
  markerMid: PropTypes.string,
  markerStart: PropTypes.string,
  mask: PropTypes.string,
  opacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  overflow: PropTypes.oneOf(['visible', 'hidden', 'scroll', 'auto', 'inherit']),
  pointerEvents: PropTypes.oneOf([
    'visiblePainted', 'visibleFill', 'visibleStroke', 'visible', 'painted',
    'fill', 'stroke', 'all', 'none', 'inherit',
  ]),
  shapeRendering: PropTypes.oneOf([
    'auto', 'optimizeSpeed', 'crispEdges', 'geometricPrecision', 'inherit',
  ]),
  stopColor: PropTypes.string,
  stopOpacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  stroke: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  strokeDasharray: PropTypes.string,
  strokeDashoffset: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square', 'inherit']),
  strokeLinejoin: PropTypes.oneOf(['miter', 'round', 'bevel', 'inherit']),
  strokeMiterlimit: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  strokeOpacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  strokeWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  textAnchor: PropTypes.oneOf(['start', 'middle', 'end', 'inherit']),
  textDecoration: PropTypes.oneOf([
    'none', 'underline', 'overline', 'line-through', 'blink', 'inherit',
  ]),
  textRendering: PropTypes.oneOf([
    'auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision',
    'inherit',
  ]),
  unicodeBidi: PropTypes.oneOf(['normal', 'embed', 'bidi-override', 'inherit']),
  visibility: PropTypes.oneOf(['visible', 'hidden', 'collapse', 'inherit']),
  wordSpacing: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  writingMode: PropTypes.oneOf([
    'lr-tb', 'rl-tb', 'tb-rl', 'lr', 'rl', 'tb', 'inherit',
  ]),
  transform: PropTypes.string,
  style: PropTypes.object,

  r: PropTypes.number,
};

const EVENT_ATTRIBUTES = {
  onClick: PropTypes.func,
  onMouseDown: PropTypes.func,
  onMouseUp: PropTypes.func,
  onMouseOver: PropTypes.func,
  onMouseMove: PropTypes.func,
  onMouseOut: PropTypes.func,
  onMouseEnter: PropTypes.func,
  onMouseLeave: PropTypes.func,
};

export const getDisplayName = (Comp) => {
  if (!Comp) { return ''; }
  if (typeof Comp === 'string') {
    return Comp;
  }
  return Comp.displayName || Comp.name || 'Component';
};

/*
 * Find and return all matched children by type. `type` can be a React element class or
 * string
 */
export const findAllByType = (children, type) => {
  const result = [];
  let types = [];

  if (_.isArray(type)) {
    types = type.map(t => getDisplayName(t));
  } else {
    types = [getDisplayName(type)];
  }

  React.Children.forEach(children, child => {
    const childType = child && child.type && (child.type.displayName || child.type.name);
    if (types.indexOf(childType) !== -1) {
      result.push(child);
    }
  });

  return result;
};
/*
 * Return the first matched child by type, return null otherwise.
 * `type` can be a React element class or string.
 */
export const findChildByType = (children, type) => {
  const result = findAllByType(children, type);

  return result && result[0];
};

/*
 * Create a new array of children excluding the ones matched the type
 */
export const withoutType = (children, type) => {
  const newChildren = [];
  let types;

  if (_.isArray(type)) {
    types = type.map(t => getDisplayName(t));
  } else {
    types = [getDisplayName(type)];
  }

  React.Children.forEach(children, child => {
    if (child && child.type && child.type.displayName
      && types.indexOf(child.type.displayName) !== -1) {
      return;
    }
    newChildren.push(child);
  });

  return newChildren;
};

/**
 * get all the presentation attribute of svg element
 * @param  {Object} el A react element or the props of a react element
 * @return {Object}    attributes or null
 */
export const getPresentationAttributes = (el) => {
  if (!el || _.isFunction(el)) { return null; }

  const props = React.isValidElement(el) ? el.props : el;
  const keys = Object.keys(props).filter(k => PRESENTATION_ATTRIBUTES[k]);

  return (keys && keys.length) ?
    keys.reduce((result, k) => ({ ...result, [k]: props[k] }), {}) :
    null;
};

/**
 * get all the event attribute of svg element
 * @param  {Object} el A react element or the props of a react element
 * @return {Object}    attributes or null
 */
export const filterEventAttributes = (el) => {
  if (!el || _.isFunction(el)) { return null; }

  const props = React.isValidElement(el) ? el.props : el;

  const keys = Object.keys(props).filter(k => EVENT_ATTRIBUTES[k]);

  return (keys && keys.length) ?
      keys.map((result, k) => ({ ...result, [k]: props[k] }), {}) :
      null;
};

/**
 * validate the width and height props of a chart element
 * @param  {Object} el A chart element
 * @return {Boolean}   true If the props width and height are number, and greater than 0
 */
export const validateWidthHeight = (el) => {
  if (!el || !el.props) { return false; }
  const { width, height } = el.props;

  if (!_.isNumber(width) || width <= 0 ||
    !_.isNumber(height) || height <= 0) {
    return false;
  }

  return true;
};

export const isSsr = () => (typeof document === 'undefined');

<commit_msg>fix: fix the bug of filterEventAttributes<commit_after>import React, { PropTypes } from 'react';
import _ from 'lodash';

export const PRESENTATION_ATTRIBUTES = {
  alignmentBaseline: PropTypes.string,
  baselineShift: PropTypes.string,
  clip: PropTypes.string,
  clipPath: PropTypes.string,
  clipRule: PropTypes.string,
  color: PropTypes.string,
  colorInterpolation: PropTypes.string,
  colorInterpolationFilters: PropTypes.string,
  colorProfile: PropTypes.string,
  colorRendering: PropTypes.string,
  cursor: PropTypes.string,
  direction: PropTypes.oneOf(['ltr', 'rtl', 'inherit']),
  display: PropTypes.string,
  dominantBaseline: PropTypes.string,
  enableBackground: PropTypes.string,
  fill: PropTypes.string,
  fillOpacity: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  fillRule: PropTypes.oneOf(['nonzero', 'evenodd', 'inherit']),
  filter: PropTypes.string,
  floodColor: PropTypes.string,
  floodOpacity: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  font: PropTypes.string,
  fontFamily: PropTypes.string,
  fontSize: PropTypes.number,
  fontSizeAdjust: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  fontStretch: PropTypes.oneOf([
    'normal', 'wider', 'narrower', 'ultra-condensed', 'extra-condensed',
    'condensed', 'semi-condensed', 'semi-expanded', 'expanded',
    'extra-expanded', 'ultra-expanded', 'inherit',
  ]),
  fontStyle: PropTypes.oneOf(['normal', 'italic', 'oblique', 'inherit']),
  fontVariant: PropTypes.oneOf(['normal', 'small-caps', 'inherit']),
  fontWeight: PropTypes.oneOf([
    'normal', 'bold', 'bolder', 'lighter',
    100, 200, 300, 400, 500, 600, 700, 800, 900, 'inherit',
  ]),
  glyphOrientationHorizontal: PropTypes.string,
  glyphOrientationVertical: PropTypes.string,
  imageRendering: PropTypes.oneOf([
    'auto', 'optimizeSpeed', 'optimizeQuality', 'inherit',
  ]),
  kerning: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  letterSpacing: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  lightingColor: PropTypes.string,
  markerEnd: PropTypes.string,
  markerMid: PropTypes.string,
  markerStart: PropTypes.string,
  mask: PropTypes.string,
  opacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  overflow: PropTypes.oneOf(['visible', 'hidden', 'scroll', 'auto', 'inherit']),
  pointerEvents: PropTypes.oneOf([
    'visiblePainted', 'visibleFill', 'visibleStroke', 'visible', 'painted',
    'fill', 'stroke', 'all', 'none', 'inherit',
  ]),
  shapeRendering: PropTypes.oneOf([
    'auto', 'optimizeSpeed', 'crispEdges', 'geometricPrecision', 'inherit',
  ]),
  stopColor: PropTypes.string,
  stopOpacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  stroke: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  strokeDasharray: PropTypes.string,
  strokeDashoffset: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square', 'inherit']),
  strokeLinejoin: PropTypes.oneOf(['miter', 'round', 'bevel', 'inherit']),
  strokeMiterlimit: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  strokeOpacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  strokeWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  textAnchor: PropTypes.oneOf(['start', 'middle', 'end', 'inherit']),
  textDecoration: PropTypes.oneOf([
    'none', 'underline', 'overline', 'line-through', 'blink', 'inherit',
  ]),
  textRendering: PropTypes.oneOf([
    'auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision',
    'inherit',
  ]),
  unicodeBidi: PropTypes.oneOf(['normal', 'embed', 'bidi-override', 'inherit']),
  visibility: PropTypes.oneOf(['visible', 'hidden', 'collapse', 'inherit']),
  wordSpacing: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  writingMode: PropTypes.oneOf([
    'lr-tb', 'rl-tb', 'tb-rl', 'lr', 'rl', 'tb', 'inherit',
  ]),
  transform: PropTypes.string,
  style: PropTypes.object,

  r: PropTypes.number,
};

const EVENT_ATTRIBUTES = {
  onClick: PropTypes.func,
  onMouseDown: PropTypes.func,
  onMouseUp: PropTypes.func,
  onMouseOver: PropTypes.func,
  onMouseMove: PropTypes.func,
  onMouseOut: PropTypes.func,
  onMouseEnter: PropTypes.func,
  onMouseLeave: PropTypes.func,
};

export const getDisplayName = (Comp) => {
  if (!Comp) { return ''; }
  if (typeof Comp === 'string') {
    return Comp;
  }
  return Comp.displayName || Comp.name || 'Component';
};

/*
 * Find and return all matched children by type. `type` can be a React element class or
 * string
 */
export const findAllByType = (children, type) => {
  const result = [];
  let types = [];

  if (_.isArray(type)) {
    types = type.map(t => getDisplayName(t));
  } else {
    types = [getDisplayName(type)];
  }

  React.Children.forEach(children, child => {
    const childType = child && child.type && (child.type.displayName || child.type.name);
    if (types.indexOf(childType) !== -1) {
      result.push(child);
    }
  });

  return result;
};
/*
 * Return the first matched child by type, return null otherwise.
 * `type` can be a React element class or string.
 */
export const findChildByType = (children, type) => {
  const result = findAllByType(children, type);

  return result && result[0];
};

/*
 * Create a new array of children excluding the ones matched the type
 */
export const withoutType = (children, type) => {
  const newChildren = [];
  let types;

  if (_.isArray(type)) {
    types = type.map(t => getDisplayName(t));
  } else {
    types = [getDisplayName(type)];
  }

  React.Children.forEach(children, child => {
    if (child && child.type && child.type.displayName
      && types.indexOf(child.type.displayName) !== -1) {
      return;
    }
    newChildren.push(child);
  });

  return newChildren;
};

/**
 * get all the presentation attribute of svg element
 * @param  {Object} el A react element or the props of a react element
 * @return {Object}    attributes or null
 */
export const getPresentationAttributes = (el) => {
  if (!el || _.isFunction(el)) { return null; }

  const props = React.isValidElement(el) ? el.props : el;
  const keys = Object.keys(props).filter(k => PRESENTATION_ATTRIBUTES[k]);

  return (keys && keys.length) ?
    keys.reduce((result, k) => ({ ...result, [k]: props[k] }), {}) :
    null;
};

/**
 * get all the event attribute of svg element
 * @param  {Object} el A react element or the props of a react element
 * @return {Object}    attributes or null
 */
export const filterEventAttributes = (el) => {
  if (!el || _.isFunction(el)) { return null; }

  const props = React.isValidElement(el) ? el.props : el;
  const keys = Object.keys(props).filter(k => EVENT_ATTRIBUTES[k]);

  return (keys && keys.length) ?
      keys.reduce((result, k) => ({ ...result, [k]: props[k] }), {}) :
      null;
};

/**
 * validate the width and height props of a chart element
 * @param  {Object} el A chart element
 * @return {Boolean}   true If the props width and height are number, and greater than 0
 */
export const validateWidthHeight = (el) => {
  if (!el || !el.props) { return false; }
  const { width, height } = el.props;

  if (!_.isNumber(width) || width <= 0 ||
    !_.isNumber(height) || height <= 0) {
    return false;
  }

  return true;
};

export const isSsr = () => (typeof document === 'undefined');

<|endoftext|>


<commit_before>var models  = require('../../models'),
    async = require('async'),
    numeral = require('numeral'),
    parser = require('fec-parse'),
    _ = require('lodash'),
    brake = require('brake');

var payload = 200; // how many rows get processed by cargo at a time

var formModels = [
    models.fec_filing,
    models.fec_presidential_summary,
    models.fec_pac_summary,
    models.fec_group_summary,
    models.fec_lobbyist_bundler,
    models.fec_contribution,
    models.fec_expenditure,
    models.fec_debt,
    models.fec_loan,
    models.fec_ie
];

function importFiling(task,callback) {
    var transaction = null;

    var processed = 0,
        queued = 0,
        finished = false;

    function error(err) {
        cargo.kill();

        if (!finished) {
            finished = true;

            notify('fecImportFailed',{ filing_id: filing_id });

            console.error(err);

            if (transaction !== null) {
                console.error('rolling back transaction');

                transaction.rollback()
                    .then(callback.bind(this,err))
                    .catch(function () {
                        console.error('error rolling back transaction');

                        callback(err);
                    });
            }
            else {
                callback(err);
            }
        }
        else {
            throw new Error('error called for ' + filing_id + ', but already finished');
        }
    }

    function done() {
        if (processed == queued && !finished) {
            finished = true;

            console.log('inserted ' + processed + ' rows from ' + task.name);
            console.log('commiting transaction');

            transaction.commit()
                .then(function (result) {
                    notify('fecImportComplete',{ filing_id: filing_id });

                    callback(null,result);
                })
                .catch(error);
        }
        else if (finished) {
            throw new Error('done called for ' + filing_id + ', but already finished');
        }
        else if (processed !== queued) {
            throw new Error('done called for ' + filing_id + ', but processed is ' + processed + ' and queued is ' + queued);
        }
    }

    function startTransaction(cb) {
        models.sequelize.transaction()
                .then(cb)
                .catch(error);
    }

    function processRows(task,cb) {
        if (finished) {
            cb();
            return;
        }

        rows = task.rows;

        if (rows[0].report_id === '') {
            rows[0].report_id = null;
        }
        if (rows[0].report_number === '') {
            rows[0].report_number = null;
        }

        console.log('processing ' + numeral(processed).format() + ' - ' + numeral(processed+task.rows.length).format() + ' of ' + numeral(queued).format());

        rows[0].model
            .bulkCreate(rows,{
                transaction: transaction
            })
            .then(function () {
                processed += task.rows.length;

                cb();
            })
            .catch(function (err) {
                if (err.name == 'SequelizeUniqueConstraintError') {
                    console.log('already inserted ' + rows[0].filing_id);
                }
                else {
                    console.error('error inserting ' + rows[0].filing_id + ':');
                    console.log(err);
                }

                cb(err);
            });
    }

    function queueRows(rows,cb) {
        if (finished) {
            cb();
            return;
        }

        var modelGroups = _(rows)
                    .groupBy(function (row) {
                        return row.model.name;
                    })
                    .toArray()
                    .map(function (rows) {
                        return {
                            rows: rows
                        };
                    })
                    .value();

        var q = async.queue(processRows,1);

        q.push(modelGroups,function (err) {
            if (err) {
                q.kill();

                cb(err);
            }
        });

        q.drain = cb;
    }

    function notify(channel,data) {
        if (models.sequelize.getDialect() == 'postgres') {
            if (data.coverage_from_date) {
                data = _.pick(data,[
                    'filing_id',
                    'form_type',
                    'committee_name',
                    'organization_name',
                    'filer_committee_id_number',
                    'coverage_from_date',
                    'coverage_through_date']);
            }

            return models.sequelize.query('NOTIFY ' + channel + ', \'' + models.sequelize.escape(JSON.stringify(data)) + '\';');
        }
    }

    function processFiling(openStream, cb) {
        console.log('== importing ' + filing_id + ' ==');

        var parse = parser();

        openStream(function (err,stream) {
            if (err) {
                error(err);
                return;
            }

            stream
                .pipe(brake(45164*3))
                .pipe(parse)
                .on('data',function (row) {
                    row.filing_id = filing_id;
                    row.model = formModels.find(function (model) {
                        return model.match(row);
                    });

                    if (typeof row.model !== 'undefined' && !finished) {
                        queued++;

                        if (queued == 2 && row.coverage_from_date) {
                            notify('fecImportStart',row);
                        }

                        cargo.push(row,function (err) {
                            if (err) {
                                error();
                            }
                        });
                    }

                })
                .on('end',function () {
                    cargo.drain = done;

                    if (processed === queued) {
                        done();
                    }
                })
                .on('error',error);
        });
    }

    function checkForFiling(id,cb) {
        models.fec_filing.findById(id)
            .then(function (result) {
                if (result) {
                    //console.log('already inserted ' + filing_id);

                    callback();
                }
                else {
                    cb();
                }
            })
            .catch(error);
    }

    var filing_id = task.name.replace(/[^0-9]+/g,''); // assume the filing number is just the numeric portion of the file name

    var cargo = async.cargo(queueRows,payload);

    checkForFiling(filing_id,function () {
        startTransaction(function (t) {
            transaction = t;

            processFiling(task.openStream,done);
        });
    });

}

function FilingQueue() {
    var q = async.queue(importFiling, 1);

    return q;
}

module.exports = new FilingQueue();
<commit_msg>Fix string escaping in notify<commit_after>var models  = require('../../models'),
    async = require('async'),
    numeral = require('numeral'),
    parser = require('fec-parse'),
    _ = require('lodash'),
    brake = require('brake');

var payload = 200; // how many rows get processed by cargo at a time

var formModels = [
    models.fec_filing,
    models.fec_presidential_summary,
    models.fec_pac_summary,
    models.fec_group_summary,
    models.fec_lobbyist_bundler,
    models.fec_contribution,
    models.fec_expenditure,
    models.fec_debt,
    models.fec_loan,
    models.fec_ie
];

function importFiling(task,callback) {
    var transaction = null;

    var processed = 0,
        queued = 0,
        finished = false;

    function error(err) {
        cargo.kill();

        if (!finished) {
            finished = true;

            notify('fecImportFailed',{ filing_id: filing_id });

            console.error(err);

            if (transaction !== null) {
                console.error('rolling back transaction');

                transaction.rollback()
                    .then(callback.bind(this,err))
                    .catch(function () {
                        console.error('error rolling back transaction');

                        callback(err);
                    });
            }
            else {
                callback(err);
            }
        }
        else {
            throw new Error('error called for ' + filing_id + ', but already finished');
        }
    }

    function done() {
        if (processed == queued && !finished) {
            finished = true;

            console.log('inserted ' + processed + ' rows from ' + task.name);
            console.log('commiting transaction');

            transaction.commit()
                .then(function (result) {
                    notify('fecImportComplete',{ filing_id: filing_id });

                    callback(null,result);
                })
                .catch(error);
        }
        else if (finished) {
            throw new Error('done called for ' + filing_id + ', but already finished');
        }
        else if (processed !== queued) {
            throw new Error('done called for ' + filing_id + ', but processed is ' + processed + ' and queued is ' + queued);
        }
    }

    function startTransaction(cb) {
        models.sequelize.transaction()
                .then(cb)
                .catch(error);
    }

    function processRows(task,cb) {
        if (finished) {
            cb();
            return;
        }

        rows = task.rows;

        if (rows[0].report_id === '') {
            rows[0].report_id = null;
        }
        if (rows[0].report_number === '') {
            rows[0].report_number = null;
        }

        console.log('processing ' + numeral(processed).format() + ' - ' + numeral(processed+task.rows.length).format() + ' of ' + numeral(queued).format());

        rows[0].model
            .bulkCreate(rows,{
                transaction: transaction
            })
            .then(function () {
                processed += task.rows.length;

                cb();
            })
            .catch(function (err) {
                if (err.name == 'SequelizeUniqueConstraintError') {
                    console.log('already inserted ' + rows[0].filing_id);
                }
                else {
                    console.error('error inserting ' + rows[0].filing_id + ':');
                    console.log(err);
                }

                cb(err);
            });
    }

    function queueRows(rows,cb) {
        if (finished) {
            cb();
            return;
        }

        var modelGroups = _(rows)
                    .groupBy(function (row) {
                        return row.model.name;
                    })
                    .toArray()
                    .map(function (rows) {
                        return {
                            rows: rows
                        };
                    })
                    .value();

        var q = async.queue(processRows,1);

        q.push(modelGroups,function (err) {
            if (err) {
                q.kill();

                cb(err);
            }
        });

        q.drain = cb;
    }

    function notify(channel,data) {
        if (models.sequelize.getDialect() == 'postgres') {
            if (data.coverage_from_date) {
                data = _.pick(data,[
                    'filing_id',
                    'form_type',
                    'committee_name',
                    'organization_name',
                    'filer_committee_id_number',
                    'coverage_from_date',
                    'coverage_through_date']);
            }

            return models.sequelize.query('NOTIFY ' + channel + ',  ' +
                    models.sequelize.escape(JSON.stringify(data)) + ';');
        }
    }

    function processFiling(openStream, cb) {
        console.log('== importing ' + filing_id + ' ==');

        var parse = parser();

        openStream(function (err,stream) {
            if (err) {
                error(err);
                return;
            }

            stream
                .pipe(brake(45164*3))
                .pipe(parse)
                .on('data',function (row) {
                    row.filing_id = filing_id;
                    row.model = formModels.find(function (model) {
                        return model.match(row);
                    });

                    if (typeof row.model !== 'undefined' && !finished) {
                        queued++;

                        if (queued == 2 && row.coverage_from_date) {
                            notify('fecImportStart',row);
                        }

                        cargo.push(row,function (err) {
                            if (err) {
                                error();
                            }
                        });
                    }

                })
                .on('end',function () {
                    cargo.drain = done;

                    if (processed === queued) {
                        done();
                    }
                })
                .on('error',error);
        });
    }

    function checkForFiling(id,cb) {
        models.fec_filing.findById(id)
            .then(function (result) {
                if (result) {
                    //console.log('already inserted ' + filing_id);

                    callback();
                }
                else {
                    cb();
                }
            })
            .catch(error);
    }

    var filing_id = task.name.replace(/[^0-9]+/g,''); // assume the filing number is just the numeric portion of the file name

    var cargo = async.cargo(queueRows,payload);

    checkForFiling(filing_id,function () {
        startTransaction(function (t) {
            transaction = t;

            processFiling(task.openStream,done);
        });
    });

}

function FilingQueue() {
    var q = async.queue(importFiling, 1);

    return q;
}

module.exports = new FilingQueue();
<|endoftext|>


<commit_before>const gochan = require('gochan');

const simpleGit = require('simple-git'),
getRepoFiles = require('./gitGetRepoFiles.js'),
logger = require('./logger.js').get();

let getHotspots = function (repoDir, callback, amount = 10) {
    let getFileLogs = function(files) {
        const git = simpleGit(repoDir);
        const exec = require('child_process').exec;
        const tokens = gochan();

        for (var i = 0; i < 250; i++) {
            tokens.put(i)
        }

        files = files.map(function(file, index) {
            return new Promise((resolve, reject) => {
                tokens.get((err, token) => {
                    logger.verbose(token, ' started reading file: ', file)

                    exec('git --git-dir ' + repoDir + '/.git log --follow --oneline -- ' + file,
                    (err, stdout, stderr) => {
                        if (err == null && stderr == "") {
                            let count = stdout.trim().split(/\r?\n/).length;

                            logger.verbose(`finished reading file: ${count} ${file}`)
                            logger.verbose(`index: ${index}, token: ${token}\n`)

                            tokens.put(token)

                            resolve({
                                file,
                                count
                            });
                        }
                        else {
                            logger.error(err)
                            logger.error(stderr)

                            tokens.put(token)

                            if (err == null) {
                                reject(stderr)
                            }
                            else {
                                reject(err);
                            }
                        }
                    });
                })
            })
        });

        logger.verbose('total files count: ', files.length)
        return files;
    }

    let resolveFiles = async function(filesPromises) {
        return Promise.all(filesPromises)
    }

    let sortFiles = function(filesCount) {
        filesCount.sort(function (a, b) {
            a = a.count;
            b = b.count;

            return a > b ? -1 : (a < b ? 1 : 0);
        });

        return filesCount;
    }

    let runCallbacks = function(filesCount) {
        if (amount !== null) {
            filesCount.splice(amount - 1, filesCount.length - amount - 1);
        }

        callback(filesCount);
    }

    getRepoFiles(repoDir)
    .then((files) => getFileLogs(files))
    .then((filesPromises) => resolveFiles(filesPromises))
    .then((filesCount) => sortFiles(filesCount))
    .then((filesCount) => runCallbacks(filesCount))
};

module.exports = getHotspots;<commit_msg>fixed amount of shown files bug<commit_after>const gochan = require('gochan');

const simpleGit = require('simple-git'),
getRepoFiles = require('./gitGetRepoFiles.js'),
logger = require('./logger.js').get();

let getHotspots = function (repoDir, callback, amount = 10) {
    let getFileLogs = function(files) {
        const git = simpleGit(repoDir);
        const exec = require('child_process').exec;
        const tokens = gochan();

        for (var i = 0; i < 250; i++) {
            tokens.put(i)
        }

        files = files.map(function(file, index) {
            return new Promise((resolve, reject) => {
                tokens.get((err, token) => {
                    logger.verbose(token, ' started reading file: ', file)

                    exec('git --git-dir ' + repoDir + '/.git log --follow --oneline -- ' + file,
                    (err, stdout, stderr) => {
                        if (err == null && stderr == "") {
                            let count = stdout.trim().split(/\r?\n/).length;

                            logger.verbose(`finished reading file: ${count} ${file}`)
                            logger.verbose(`index: ${index}, token: ${token}\n`)

                            tokens.put(token)

                            resolve({
                                file,
                                count
                            });
                        }
                        else {
                            logger.error(err)
                            logger.error(stderr)

                            tokens.put(token)

                            if (err == null) {
                                reject(stderr)
                            }
                            else {
                                reject(err);
                            }
                        }
                    });
                })
            })
        });

        logger.verbose('total files count: ', files.length)
        return files;
    }

    let resolveFiles = async function(filesPromises) {
        return Promise.all(filesPromises)
    }

    let sortFiles = function(filesCount) {
        filesCount.sort(function (a, b) {
            a = a.count;
            b = b.count;

            return a > b ? -1 : (a < b ? 1 : 0);
        });

        return filesCount;
    }

    let runCallbacks = function(filesCount) {
        if (amount !== null) {
            filesCount.splice(amount, filesCount.length - amount);
        }

        callback(filesCount);
    }

    getRepoFiles(repoDir)
    .then((files) => getFileLogs(files))
    .then((filesPromises) => resolveFiles(filesPromises))
    .then((filesCount) => sortFiles(filesCount))
    .then((filesCount) => runCallbacks(filesCount))
};

module.exports = getHotspots;<|endoftext|>


<commit_before>import Util from '../../core/util.js';
export class Grid extends Util {
  constructor(SL, config) {
    super(SL, config);
    this.name = 'Grid';
    this.configure();
  }
  reset() {
    super.reset();
    this.unregisterSnappers();
  }

  configure(config) {
    config = super.configure(config);

    // base definition
    this.definition = {
      offset: { x: 0, y: 0 },
      width: '100%',
      height: '100%',
      cell: {},
      cols: '+',
      rows: '+'
    };

    // use config to customize the definition
    if (config.offset) {
      this.definition.offset.x = config.offset.x || this.definition.offset.x;
      this.definition.offset.y = config.offset.y || this.definition.offset.y;
    }
    this.definition.width = config.width || this.definition.width;
    this.definition.height = config.height || this.definition.height;

    this.definition.cell.width = (config.cell && config.cell.width) || (config.cell && config.cell.size) || config.size || this.definition.cell.width;
    this.definition.cell.height = (config.cell && config.cell.height) || (config.cell && config.cell.size) || config.size || this.definition.cell.height;

    this.definition.cols = config.cols || this.definition.cols;
    this.definition.rows = config.rows || this.definition.rows;

    // set things up
    this.registerSnappers();
    this.renderGrid();

    return this.config;
  }

  getCurrentDefinition() {
    let currentDef = {};
    let Parser = this.SL.Utils.gets('ConfigParser');
    let View = this.SL.Paper.view;
    let Def = this.definition;
    let parsed;

    // parse grid offset
    currentDef.offset = { x: 0, y: 0 };
    parsed = Parser.parseNumber(Def.offset.x);
    currentDef.offset.x = parsed.value;
    if (parsed.percent) {
      currentDef.offset.x *= View.size.width;
    }
    parsed = Parser.parseNumber(Def.offset.y);
    currentDef.offset.y = parsed.value;
    if (parsed.percent) {
      currentDef.offset.y *= View.size.height;
    }

    // parse grid width
    currentDef.width = View.size.width;
    parsed = Parser.parseNumber(Def.width);
    if (!parsed.value) {
      parsed.value = 1.0;
      parsed.percent = true;
    }
    if (parsed.percent) {
      currentDef.width *= parsed.value;
    }
    else if (parsed.value) {
      currentDef.width = parsed.value;
    }

    // parse grid height
    currentDef.height = View.size.height;
    parsed = Parser.parseNumber(Def.height);
    if (!parsed.value) {
      parsed.value = 1.0;
      parsed.percent = true;
    }
    if (parsed.percent) {
      currentDef.height *= parsed.value;
    }
    else if (parsed.value) {
      currentDef.height = parsed.value;
    }

    // read row and col preferences
    let cols = Parser.parseNumber(Def.cols);
    let rows = Parser.parseNumber(Def.rows);
    currentDef.cell = {};

    // calculate cell width + cols
    parsed = Parser.parseNumber(Def.cell.width);
    currentDef.cell.width = parsed.value;
    if (!parsed.value) {
      if (cols.value) {
        currentDef.cell.width = currentDef.width / cols.value;
      }
    }
    else if (parsed.percent) {
      currentDef.cell.width = currentDef.width * parsed.value;
    }
    currentDef.cell.width = Parser.unparseNumber(currentDef.cell.width, parsed);

    // calculate cell height + rows
    parsed = Parser.parseNumber(Def.cell.height);
    currentDef.cell.height = parsed.value;
    if (!parsed.value) {
      if (rows.value) {
        currentDef.cell.height = currentDef.height / rows.value;
      }
    }
    else if (parsed.percent) {
      currentDef.cell.height = currentDef.height * parsed.value;
    }
    currentDef.cell.height = Parser.unparseNumber(currentDef.cell.height, parsed);

    // if width or height is missing, try to use the other
    currentDef.cell.width = currentDef.cell.width || currentDef.cell.height;
    currentDef.cell.height = currentDef.cell.height || currentDef.cell.width;

    // finalize number of cols
    currentDef.cols = currentDef.width / currentDef.cell.width;
    currentDef.cols = Parser.unparseNumber(currentDef.cols, cols);
    // finalize number of rows
    currentDef.rows = currentDef.height / currentDef.cell.height;
    currentDef.rows = Parser.unparseNumber(currentDef.rows, rows);

    return currentDef;
  }

  registerSnappers() {
    let Snap = this.SL.Utils.get('Snap');
    if (Snap) {
      if (!this.Snappers) {
        this.Snappers = {};
      }
      this.Snappers.point = Snap.addSnapper('point', {
        priority: 75,
        callback: (point, config) => {
          return this.snapPoint(point, config);
        }
      });
      this.Snappers.rectangle = Snap.addSnapper('rectangle', {
        priority: 75,
        callback: (rectangle, config) => {
          return this.snapRectangle(rectangle, config);
        }
      });
      this.Snappers.item = Snap.addSnapper('item', {
        priority: 57,
        callback: (item, config) => {
          return this.snapItem(item, config);
        }
      });
    }
  }
  unregisterSnappers() {
    let Snap = this.SL.Utils.get('Snap');
    if (!Snap || !this.Snappers) {
      return;
    }
    if (this.Snappers.point) {
      Snap.dropSnapper('point', this.Snappers.point.id);
      this.Snappers.point = undefined;
    }
    if (Snap && this.Snappers.rectangle) {
      Snap.dropSnapper('rectangle', this.Snappers.rectangle.id);
      this.Snappers.rectangle = undefined;
    }
    if (Snap && this.Snappers.item) {
      Snap.dropSnapper('item', this.Snappers.item.id);
      this.Snappers.item = undefined;
    }
  }
  snapPoint(point, config={}) {
    if (config && config.interactive) {
      return point;
    }
    let def = this.getCurrentDefinition();
    let min = { Col: -1, Row: -1 };
    let max = { Col: -1, Row: -1 };
    let Snap = this.SL.Utils.get('Snap');
    if (Snap) {
      let pointMin = Snap.PointMin(new paper.Point);
      min.Col = Math.ceil(pointMin.x / def.cell.width);
      min.Row = Math.ceil(pointMin.y / def.cell.height);

      let pointMax = Snap.PointMax(new paper.Point);
      max.Col = Math.floor(pointMax.x / def.cell.width);
      max.Row = Math.floor(pointMax.y / def.cell.height);
    }
    let newPoint = new paper.Point(def.offset).add(point);
    let target = {
      Col: Math.round(newPoint.x / def.cell.width),
      Row: Math.round(newPoint.y / def.cell.height)
    };
    if (min.Col >= 0 && target.Col < min.Col) {
      target.Col = min.Col;
    }
    else if (max.Col >= 0 && target.Col > max.Col) {
      target.Col = max.Col;
    }
    if (min.Row >= 0 && target.Row < min.Row) {
      target.Row = min.Row;
    }
    else if (max.Row >= 0 && target.Row > max.Row) {
      target.Row = max.Row;
    }
    newPoint.set({
      x: (target.Col * def.cell.width) - def.offset.x,
      y: (target.Row * def.cell.height) - def.offset.y
    });
    point.set(newPoint);
    return point;
  }
  snapRectangle(rectangle, config={}) {
    if (config && config.interactive && config.size === false) {
      return rectangle;
    }
    let interactive = !!(config && config.interactive);
    let Geo = this.SL.Utils.get('Geo');
    let anchor = config.anchor || rectangle.center;
    if (config.anchorEdge && Geo) {
      anchor = Geo.Direction.edgePoint(config.anchorEdge, rectangle);
    }
    let rectangleWidth = rectangle.width;
    let rectangleHeight = rectangle.height;
    let topLeft = new paper.Point({x: rectangle.left, y: rectangle.top});
    let bottomRight = new paper.Point({x: rectangle.right, y: rectangle.bottom});
    let pointMin, pointMax;
    let Snap = this.SL.Utils.get('Snap');
    if (Snap) {
      pointMin = Snap.PointMin(new paper.Point);
      pointMax = Snap.PointMax(new paper.Point);
    }
    let snapped = {
      left: undefined,
      top: undefined,
      right: undefined,
      bottom: undefined
    };

    // horizontal snapping
    if (anchor.x > rectangle.center.x) {
      // anchored at right, snap right edge first
      snapped.right = this.snapPoint(new paper.Point(bottomRight));
      if (!interactive) {
        snapped.left = this.snapPoint(new paper.Point(snapped.right.x-rectangleWidth, topLeft.y));
      }
      else {
        snapped.left = topLeft.clone();
      }
      if (pointMin != undefined && (snapped.left.x) < pointMin.x) {
        // if horizontal snapping by Right would exceed pointMin, re-snap horizontally based on Left
        snapped.left = this.snapPoint(new paper.Point(topLeft));
        if (!interactive) {
          snapped.right = this.snapPoint(new paper.Point(snapped.left.x+rectangleWidth, bottomRight.y));
        }
        else {
          snapped.right = bottomRight.clone();
        }
      }
    }
    else {
      // otherwise, snap left edge first
      // first try horizontal snapping based on Left
      snapped.left = this.snapPoint(new paper.Point(topLeft));
      if (!interactive) {
        snapped.right = this.snapPoint(new paper.Point(snapped.left.x+rectangleWidth, bottomRight.y));
      }
      else {
        snapped.right = bottomRight.clone();
      }
      if (pointMax != undefined && (snapped.left.x+rectangleWidth) > pointMax.x) {
        // if horizontal snapping by Left would exceed pointMax, re-snap horizontally based on Right
        snapped.right = this.snapPoint(new paper.Point(bottomRight));
        if (!interactive) {
          snapped.left = this.snapPoint(new paper.Point(snapped.right.x-rectangleWidth, topLeft.y));
        }
        else {
          snapped.left = topLeft.clone();
        }
      }
    }

    // vertical snapping
    if (anchor.y > rectangle.center.y) {
      // anchored at bottom, snap bottom edge first
      snapped.bottom = this.snapPoint(new paper.Point(bottomRight));
      if (!interactive) {
        snapped.top = this.snapPoint(new paper.Point(topLeft.x, snapped.bottom.y-rectangleHeight));
      }
      else {
        snapped.top = topLeft.clone();
      }
      if (pointMin != undefined && (snapped.top.y) < pointMin.y) {
        // if vertical snapping by Bottom would exceed pointMin, re-snap vertically based on Top
        snapped.top = this.snapPoint(new paper.Point(topLeft));
        if (!interactive) {
          snapped.bottom = this.snapPoint(new paper.Point(bottomRight.x, snapped.top.y+rectangleHeight));
        }
        else {
          snapped.bottom = bottomRight.clone();
        }
      }
    }
    else {
      // otherwise, snap top edge first
      // first try vertical snapping based on Top
      snapped.top = this.snapPoint(new paper.Point(topLeft));
      if (!interactive) {
        snapped.bottom = this.snapPoint(new paper.Point(bottomRight.x, snapped.top.y+rectangleHeight));
      }
      else {
        snapped.bottom = bottomRight.clone();
      }
      if (pointMax != undefined && (snapped.top.y+rectangleHeight) > pointMax.y) {
        // if vertical snapping by Top would exceed pointMax, re-snap vertically based on Bottom
        snapped.bottom = this.snapPoint(new paper.Point(bottomRight));
        if (!interactive) {
          snapped.top = this.snapPoint(new paper.Point(topLeft.x, snapped.bottom.y-rectangleHeight));
        }
        else {
          snapped.top = topLeft.clone();
        }
      }
    }

    // apply the snapped sides
    rectangle.set({
      top: snapped.top.y,
      left: snapped.left.x,
      bottom: snapped.bottom.y,
      right: snapped.right.x
    });
    return rectangle;
  }
  snapItem(item, config={}) {
    if (config && config.interactive) {
      return item;
    }
    let rotation = item.rotation;
    if (rotation) {
      item.rotate(-rotation);
    }

    // @TODO: support for the data.type == 'Line' segments

    let snapped = this.snapRectangle(item.bounds.clone(), config);
    item.bounds.set(snapped);

    if (rotation) {
      item.rotate(rotation);
    }
    return item;
  }

  renderGrid(style) {
    style = style || this.config.style || Grid.DEFAULT.style;
    let def = this.getCurrentDefinition();
    let grid = this.SL.Paper.generatePaperItem({Class:'UI', Layer:'BG', Grid:'GRID', Source: this}, paper.Group);
    let n, pt1, pt2;
    let strong = this.config.strong;
    let strongStyle = $.extend({}, style,
      { strokeWidth: (style.strokeWidth ? style.strokeWidth*2.0 : 2.0) },
      this.config.strongStyle);

    // render vertical lines
    n = 0;
    pt1 = new paper.Point(def.offset.x, def.offset.y);
    pt2 = new paper.Point(def.offset.x, def.offset.y+def.height);
    while (n <= def.cols) {
      pt2.x = pt1.x;
      let gridLine = this.SL.Paper.generatePaperItem({Class:'UI.Grid', Layer:'GROUPED', Grid:'COL-'+n}, paper.Path.Line, pt1, pt2);
      let applyStyle = style;
      if (strong && n % strong == 0) {
        applyStyle = strongStyle;
      }
      this.SL.Paper.applyStyle(gridLine, applyStyle);
      grid.addChild(gridLine);
      pt1.x += def.cell.width;
      n++;
    }

    // render horizontal lines
    n = 0;
    pt1 = new paper.Point(def.offset.x, def.offset.y);
    pt2 = new paper.Point(def.offset.x+def.width, def.offset.y);
    while (n <= def.rows) {
      pt2.y = pt1.y;
      let gridLine = this.SL.Paper.generatePaperItem({Class:'UI.Grid', Layer:'GROUPED', Grid:'ROW-'+n}, paper.Path.Line, pt1, pt2);
      let applyStyle = style;
      if (strong && n % strong == 0) {
        applyStyle = strongStyle;
      }
      this.SL.Paper.applyStyle(gridLine, applyStyle);
      grid.addChild(gridLine);
      pt1.y += def.cell.height;
      n++;
    }

    return grid;
  }
}
Grid.DEFAULT = {
  style: { strokeWidth: 1.5, strokeColor: (2.0/3.0), opacity: 0.25 }
};
<commit_msg>Utils.Grid snapping for item.segments<commit_after>import Util from '../../core/util.js';
export class Grid extends Util {
  constructor(SL, config) {
    super(SL, config);
    this.name = 'Grid';
    this.configure();
  }
  reset() {
    super.reset();
    this.unregisterSnappers();
  }

  configure(config) {
    config = super.configure(config);

    // base definition
    this.definition = {
      offset: { x: 0, y: 0 },
      width: '100%',
      height: '100%',
      cell: {},
      cols: '+',
      rows: '+'
    };

    // use config to customize the definition
    if (config.offset) {
      this.definition.offset.x = config.offset.x || this.definition.offset.x;
      this.definition.offset.y = config.offset.y || this.definition.offset.y;
    }
    this.definition.width = config.width || this.definition.width;
    this.definition.height = config.height || this.definition.height;

    this.definition.cell.width = (config.cell && config.cell.width) || (config.cell && config.cell.size) || config.size || this.definition.cell.width;
    this.definition.cell.height = (config.cell && config.cell.height) || (config.cell && config.cell.size) || config.size || this.definition.cell.height;

    this.definition.cols = config.cols || this.definition.cols;
    this.definition.rows = config.rows || this.definition.rows;

    // set things up
    this.registerSnappers();
    this.renderGrid();

    return this.config;
  }

  getCurrentDefinition() {
    let currentDef = {};
    let Parser = this.SL.Utils.gets('ConfigParser');
    let View = this.SL.Paper.view;
    let Def = this.definition;
    let parsed;

    // parse grid offset
    currentDef.offset = { x: 0, y: 0 };
    parsed = Parser.parseNumber(Def.offset.x);
    currentDef.offset.x = parsed.value;
    if (parsed.percent) {
      currentDef.offset.x *= View.size.width;
    }
    parsed = Parser.parseNumber(Def.offset.y);
    currentDef.offset.y = parsed.value;
    if (parsed.percent) {
      currentDef.offset.y *= View.size.height;
    }

    // parse grid width
    currentDef.width = View.size.width;
    parsed = Parser.parseNumber(Def.width);
    if (!parsed.value) {
      parsed.value = 1.0;
      parsed.percent = true;
    }
    if (parsed.percent) {
      currentDef.width *= parsed.value;
    }
    else if (parsed.value) {
      currentDef.width = parsed.value;
    }

    // parse grid height
    currentDef.height = View.size.height;
    parsed = Parser.parseNumber(Def.height);
    if (!parsed.value) {
      parsed.value = 1.0;
      parsed.percent = true;
    }
    if (parsed.percent) {
      currentDef.height *= parsed.value;
    }
    else if (parsed.value) {
      currentDef.height = parsed.value;
    }

    // read row and col preferences
    let cols = Parser.parseNumber(Def.cols);
    let rows = Parser.parseNumber(Def.rows);
    currentDef.cell = {};

    // calculate cell width + cols
    parsed = Parser.parseNumber(Def.cell.width);
    currentDef.cell.width = parsed.value;
    if (!parsed.value) {
      if (cols.value) {
        currentDef.cell.width = currentDef.width / cols.value;
      }
    }
    else if (parsed.percent) {
      currentDef.cell.width = currentDef.width * parsed.value;
    }
    currentDef.cell.width = Parser.unparseNumber(currentDef.cell.width, parsed);

    // calculate cell height + rows
    parsed = Parser.parseNumber(Def.cell.height);
    currentDef.cell.height = parsed.value;
    if (!parsed.value) {
      if (rows.value) {
        currentDef.cell.height = currentDef.height / rows.value;
      }
    }
    else if (parsed.percent) {
      currentDef.cell.height = currentDef.height * parsed.value;
    }
    currentDef.cell.height = Parser.unparseNumber(currentDef.cell.height, parsed);

    // if width or height is missing, try to use the other
    currentDef.cell.width = currentDef.cell.width || currentDef.cell.height;
    currentDef.cell.height = currentDef.cell.height || currentDef.cell.width;

    // finalize number of cols
    currentDef.cols = currentDef.width / currentDef.cell.width;
    currentDef.cols = Parser.unparseNumber(currentDef.cols, cols);
    // finalize number of rows
    currentDef.rows = currentDef.height / currentDef.cell.height;
    currentDef.rows = Parser.unparseNumber(currentDef.rows, rows);

    return currentDef;
  }

  registerSnappers() {
    let Snap = this.SL.Utils.get('Snap');
    if (Snap) {
      if (!this.Snappers) {
        this.Snappers = {};
      }
      this.Snappers.point = Snap.addSnapper('point', {
        priority: 75,
        callback: (point, config) => {
          return this.snapPoint(point, config);
        }
      });
      this.Snappers.rectangle = Snap.addSnapper('rectangle', {
        priority: 75,
        callback: (rectangle, config) => {
          return this.snapRectangle(rectangle, config);
        }
      });
      this.Snappers.item = Snap.addSnapper('item', {
        priority: 57,
        callback: (item, config) => {
          return this.snapItem(item, config);
        }
      });
    }
  }
  unregisterSnappers() {
    let Snap = this.SL.Utils.get('Snap');
    if (!Snap || !this.Snappers) {
      return;
    }
    if (this.Snappers.point) {
      Snap.dropSnapper('point', this.Snappers.point.id);
      this.Snappers.point = undefined;
    }
    if (Snap && this.Snappers.rectangle) {
      Snap.dropSnapper('rectangle', this.Snappers.rectangle.id);
      this.Snappers.rectangle = undefined;
    }
    if (Snap && this.Snappers.item) {
      Snap.dropSnapper('item', this.Snappers.item.id);
      this.Snappers.item = undefined;
    }
  }
  snapPoint(point, config={}) {
    if (config && config.interactive) {
      return point;
    }
    let def = this.getCurrentDefinition();
    let min = { Col: -1, Row: -1 };
    let max = { Col: -1, Row: -1 };
    let Snap = this.SL.Utils.get('Snap');
    if (Snap) {
      let pointMin = Snap.PointMin(new paper.Point);
      min.Col = Math.ceil(pointMin.x / def.cell.width);
      min.Row = Math.ceil(pointMin.y / def.cell.height);

      let pointMax = Snap.PointMax(new paper.Point);
      max.Col = Math.floor(pointMax.x / def.cell.width);
      max.Row = Math.floor(pointMax.y / def.cell.height);
    }
    let newPoint = new paper.Point(def.offset).add(point);
    let target = {
      Col: Math.round(newPoint.x / def.cell.width),
      Row: Math.round(newPoint.y / def.cell.height)
    };
    if (min.Col >= 0 && target.Col < min.Col) {
      target.Col = min.Col;
    }
    else if (max.Col >= 0 && target.Col > max.Col) {
      target.Col = max.Col;
    }
    if (min.Row >= 0 && target.Row < min.Row) {
      target.Row = min.Row;
    }
    else if (max.Row >= 0 && target.Row > max.Row) {
      target.Row = max.Row;
    }
    newPoint.set({
      x: (target.Col * def.cell.width) - def.offset.x,
      y: (target.Row * def.cell.height) - def.offset.y
    });
    point.set(newPoint);
    return point;
  }
  snapRectangle(rectangle, config={}) {
    if (config && config.interactive && config.size === false) {
      return rectangle;
    }
    let interactive = !!(config && config.interactive);
    let Geo = this.SL.Utils.get('Geo');
    let anchor = config.anchor || rectangle.center;
    if (config.anchorEdge && Geo) {
      anchor = Geo.Direction.edgePoint(config.anchorEdge, rectangle);
    }
    let rectangleWidth = rectangle.width;
    let rectangleHeight = rectangle.height;
    let topLeft = new paper.Point({x: rectangle.left, y: rectangle.top});
    let bottomRight = new paper.Point({x: rectangle.right, y: rectangle.bottom});
    let pointMin, pointMax;
    let Snap = this.SL.Utils.get('Snap');
    if (Snap) {
      pointMin = Snap.PointMin(new paper.Point);
      pointMax = Snap.PointMax(new paper.Point);
    }
    let snapped = {
      left: undefined,
      top: undefined,
      right: undefined,
      bottom: undefined
    };

    // horizontal snapping
    if (anchor.x > rectangle.center.x) {
      // anchored at right, snap right edge first
      snapped.right = this.snapPoint(new paper.Point(bottomRight));
      if (!interactive) {
        snapped.left = this.snapPoint(new paper.Point(snapped.right.x-rectangleWidth, topLeft.y));
      }
      else {
        snapped.left = topLeft.clone();
      }
      if (pointMin != undefined && (snapped.left.x) < pointMin.x) {
        // if horizontal snapping by Right would exceed pointMin, re-snap horizontally based on Left
        snapped.left = this.snapPoint(new paper.Point(topLeft));
        if (!interactive) {
          snapped.right = this.snapPoint(new paper.Point(snapped.left.x+rectangleWidth, bottomRight.y));
        }
        else {
          snapped.right = bottomRight.clone();
        }
      }
    }
    else {
      // otherwise, snap left edge first
      // first try horizontal snapping based on Left
      snapped.left = this.snapPoint(new paper.Point(topLeft));
      if (!interactive) {
        snapped.right = this.snapPoint(new paper.Point(snapped.left.x+rectangleWidth, bottomRight.y));
      }
      else {
        snapped.right = bottomRight.clone();
      }
      if (pointMax != undefined && (snapped.left.x+rectangleWidth) > pointMax.x) {
        // if horizontal snapping by Left would exceed pointMax, re-snap horizontally based on Right
        snapped.right = this.snapPoint(new paper.Point(bottomRight));
        if (!interactive) {
          snapped.left = this.snapPoint(new paper.Point(snapped.right.x-rectangleWidth, topLeft.y));
        }
        else {
          snapped.left = topLeft.clone();
        }
      }
    }

    // vertical snapping
    if (anchor.y > rectangle.center.y) {
      // anchored at bottom, snap bottom edge first
      snapped.bottom = this.snapPoint(new paper.Point(bottomRight));
      if (!interactive) {
        snapped.top = this.snapPoint(new paper.Point(topLeft.x, snapped.bottom.y-rectangleHeight));
      }
      else {
        snapped.top = topLeft.clone();
      }
      if (pointMin != undefined && (snapped.top.y) < pointMin.y) {
        // if vertical snapping by Bottom would exceed pointMin, re-snap vertically based on Top
        snapped.top = this.snapPoint(new paper.Point(topLeft));
        if (!interactive) {
          snapped.bottom = this.snapPoint(new paper.Point(bottomRight.x, snapped.top.y+rectangleHeight));
        }
        else {
          snapped.bottom = bottomRight.clone();
        }
      }
    }
    else {
      // otherwise, snap top edge first
      // first try vertical snapping based on Top
      snapped.top = this.snapPoint(new paper.Point(topLeft));
      if (!interactive) {
        snapped.bottom = this.snapPoint(new paper.Point(bottomRight.x, snapped.top.y+rectangleHeight));
      }
      else {
        snapped.bottom = bottomRight.clone();
      }
      if (pointMax != undefined && (snapped.top.y+rectangleHeight) > pointMax.y) {
        // if vertical snapping by Top would exceed pointMax, re-snap vertically based on Bottom
        snapped.bottom = this.snapPoint(new paper.Point(bottomRight));
        if (!interactive) {
          snapped.top = this.snapPoint(new paper.Point(topLeft.x, snapped.bottom.y-rectangleHeight));
        }
        else {
          snapped.top = topLeft.clone();
        }
      }
    }

    // apply the snapped sides
    rectangle.set({
      top: snapped.top.y,
      left: snapped.left.x,
      bottom: snapped.bottom.y,
      right: snapped.right.x
    });
    return rectangle;
  }
  snapItem(item, config={}) {
    if (config && config.interactive) {
      return item;
    }
    let rotation = item.rotation;
    if (rotation) {
      item.rotate(-rotation);
    }

    if (item.segments) {
      for (let segment of item.segments) {
        let snapped = this.snapPoint(segment.point.clone(), config);
        segment.point.set(snapped);
      }
    }
    else if (item.bounds) {
      let snapped = this.snapRectangle(item.bounds.clone(), config);
      item.bounds.set(snapped);
    }

    if (rotation) {
      item.rotate(rotation);
    }
    return item;
  }

  renderGrid(style) {
    style = style || this.config.style || Grid.DEFAULT.style;
    let def = this.getCurrentDefinition();
    let grid = this.SL.Paper.generatePaperItem({Class:'UI', Layer:'BG', Grid:'GRID', Source: this}, paper.Group);
    let n, pt1, pt2;
    let strong = this.config.strong;
    let strongStyle = $.extend({}, style,
      { strokeWidth: (style.strokeWidth ? style.strokeWidth*2.0 : 2.0) },
      this.config.strongStyle);

    // render vertical lines
    n = 0;
    pt1 = new paper.Point(def.offset.x, def.offset.y);
    pt2 = new paper.Point(def.offset.x, def.offset.y+def.height);
    while (n <= def.cols) {
      pt2.x = pt1.x;
      let gridLine = this.SL.Paper.generatePaperItem({Class:'UI.Grid', Layer:'GROUPED', Grid:'COL-'+n}, paper.Path.Line, pt1, pt2);
      let applyStyle = style;
      if (strong && n % strong == 0) {
        applyStyle = strongStyle;
      }
      this.SL.Paper.applyStyle(gridLine, applyStyle);
      grid.addChild(gridLine);
      pt1.x += def.cell.width;
      n++;
    }

    // render horizontal lines
    n = 0;
    pt1 = new paper.Point(def.offset.x, def.offset.y);
    pt2 = new paper.Point(def.offset.x+def.width, def.offset.y);
    while (n <= def.rows) {
      pt2.y = pt1.y;
      let gridLine = this.SL.Paper.generatePaperItem({Class:'UI.Grid', Layer:'GROUPED', Grid:'ROW-'+n}, paper.Path.Line, pt1, pt2);
      let applyStyle = style;
      if (strong && n % strong == 0) {
        applyStyle = strongStyle;
      }
      this.SL.Paper.applyStyle(gridLine, applyStyle);
      grid.addChild(gridLine);
      pt1.y += def.cell.height;
      n++;
    }

    return grid;
  }
}
Grid.DEFAULT = {
  style: { strokeWidth: 1.5, strokeColor: (2.0/3.0), opacity: 0.25 }
};
<|endoftext|>


<commit_before>export const templatePrefixes = [
  '<REPLACE>',
  '<REPLACE_FOR_EACH_TYPE>'
]
<commit_msg>fixup prefix for REPLACE_FOR_EACH_TYPE<commit_after>export const templatePrefixes = [
  '<REPLACE>',
  '<REPLACE_FOR_EACH_TYPE>_'
]
<|endoftext|>


<commit_before>const highlight = require('highlight.js/lib/highlight')

const languages = [
	'php',
	'python',
	'css',
	'coffeescript',
	'reasonml',
	'xml',
	'json',
	'javascript',
	'markdown',
	'django',
	'elm',
	'htmlbars',
	'haml',
	'handlebars',
	'less',
	'scss',
	'stylus',
	'twig',
	'typescript',
	'yaml',
	'plaintext'
]

languages.forEach((language) => {
	highlight.registerLanguage(language, require(`highlight.js/lib/languages/${ language }`))
})

module.exports = highlight<commit_msg>Dynamic require ain't working<commit_after>const highlight = require('highlight.js/lib/highlight')

highlight.registerLanguage('php', require('highlight.js/lib/languages/php'))
highlight.registerLanguage('python', require('highlight.js/lib/languages/python'))
highlight.registerLanguage('css', require('highlight.js/lib/languages/css'))
highlight.registerLanguage('coffeescript', require('highlight.js/lib/languages/coffeescript'))
highlight.registerLanguage('reasonml', require('highlight.js/lib/languages/reasonml'))
highlight.registerLanguage('xml', require('highlight.js/lib/languages/xml'))
highlight.registerLanguage('json', require('highlight.js/lib/languages/json'))
highlight.registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
highlight.registerLanguage('markdown', require('highlight.js/lib/languages/markdown'))
highlight.registerLanguage('django', require('highlight.js/lib/languages/django'))
highlight.registerLanguage('elm', require('highlight.js/lib/languages/elm'))
highlight.registerLanguage('htmlbars', require('highlight.js/lib/languages/htmlbars'))
highlight.registerLanguage('haml', require('highlight.js/lib/languages/haml'))
highlight.registerLanguage('handlebars', require('highlight.js/lib/languages/handlebars'))
highlight.registerLanguage('less', require('highlight.js/lib/languages/less'))
highlight.registerLanguage('scss', require('highlight.js/lib/languages/scss'))
highlight.registerLanguage('stylus', require('highlight.js/lib/languages/stylus'))
highlight.registerLanguage('twig', require('highlight.js/lib/languages/twig'))
highlight.registerLanguage('typescript', require('highlight.js/lib/languages/typescript'))
highlight.registerLanguage('yaml', require('highlight.js/lib/languages/yaml'))
highlight.registerLanguage('plaintext', require('highlight.js/lib/languages/plaintext'))

module.exports = highlight<|endoftext|>


<commit_before>// Promises polyfill
import 'core-js/es6/promise';

// Object.assign polyfill
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
if (typeof Object.assign !== 'function') {
    (function () {
        Object.assign = function (target) {
            'use strict';
            // We must check against these specific cases.
            if (target === undefined || target === null) {
                throw new TypeError('Cannot convert undefined or null to object');
            }

            var output = Object(target);
            for (var index = 1; index < arguments.length; index++) {
                var source = arguments[index];
                if (source !== undefined && source !== null) {
                    for (var nextKey in source) {
                        if (source.hasOwnProperty(nextKey)) {
                            output[nextKey] = source[nextKey];
                        }
                    }
                }
            }
            return output;
        };
    })();
}
<commit_msg>polyfill Math.hypot()<commit_after>// Promises polyfill
import 'core-js/es6/promise';

// Object.assign polyfill
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
if (typeof Object.assign !== 'function') {
    (function () {
        Object.assign = function (target) {
            'use strict';
            // We must check against these specific cases.
            if (target === undefined || target === null) {
                throw new TypeError('Cannot convert undefined or null to object');
            }

            var output = Object(target);
            for (var index = 1; index < arguments.length; index++) {
                var source = arguments[index];
                if (source !== undefined && source !== null) {
                    for (var nextKey in source) {
                        if (source.hasOwnProperty(nextKey)) {
                            output[nextKey] = source[nextKey];
                        }
                    }
                }
            }
            return output;
        };
    })();
}

// Math.hypot polyfill
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot
Math.hypot = Math.hypot || function() {
    var y = 0;
    var length = arguments.length;

    for (var i = 0; i < length; i++) {
        if (arguments[i] === Infinity || arguments[i] === -Infinity) {
            return Infinity;
        }
        y += arguments[i] * arguments[i];
    }
    return Math.sqrt(y);
};
<|endoftext|>