<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow

import type { MixedObject } from 'firefox-profiler/types';

/**
 * The "perf script" format is the plain text format that is output by an
 * invocation of `perf script`, where `perf` is the Linux perf command line tool.
 */
export function isPerfScriptFormat(profile: string): boolean {
  // Optimisation: The simplest way to solve this would be using
  // the same logic as parsing: looping over profile.split('\n').
  // But fingerprinting the profile should be fast. So we use a
  // multiline regex to avoid processing the entire profile.

  // This regexp matches the first line that doesn't start with #,
  // and has at least one character.
  const firstLineFinderRe = /^(?!#).+$/m;
  const maybeFirstLine = firstLineFinderRe.exec(profile);
  if (!maybeFirstLine) {
    return false;
  }

  const firstLine = maybeFirstLine[0];
  //          +- process name (anything before the rest of the regexp, can contain spaces)
  //          |        +- PID/ (optional)
  //          |        |      +- TID
  //          |        |      |          +- [CPU] (optional, present in SimplePerf output)
  //          |        |      |          |          +- timestamp
  //       vvvvv   vvvvvvvvv vvv   vvvvvvvvvvvvvv vvvvvv
  return /^\S.+?\s+(?:\d+\/)?\d+\s+(?:\[\d+\]\s+)?[\d.]+:/.test(firstLine);
}

// Don't try and type this more specifically.
type GeckoProfileVersion24 = MixedObject;

const CATEGORIES = [
  { name: 'User', color: 'yellow', subcategories: ['Other'] },
  { name: 'Kernel', color: 'orange', subcategories: ['Other'] },
];
const USER_CATEGORY_INDEX = 0;
const KERNEL_CATEGORY_INDEX = 1;

/**
 * Convert the output from `perf script` into the gecko profile format (version 24).
 */
export function convertPerfScriptProfile(
  profile: string
): GeckoProfileVersion24 {
  function _createThread(name, pid, tid) {
    const markers = {
      schema: {
        name: 0,
        startTime: 1,
        endTime: 2,
        phase: 3,
        category: 4,
        data: 5,
      },
      data: [],
    };
    const samples = {
      schema: {
        stack: 0,
        time: 1,
        responsiveness: 2,
      },
      data: [],
    };
    const frameTable = {
      schema: {
        location: 0,
        relevantForJS: 1,
        innerWindowID: 2,
        implementation: 3,
        optimizations: 4,
        line: 5,
        column: 6,
        category: 7,
        subcategory: 8,
      },
      data: [],
    };
    const stackTable = {
      schema: {
        prefix: 0,
        frame: 1,
      },
      data: [],
    };
    const stringTable = [];

    const stackMap = new Map();
    function getOrCreateStack(frame, prefix) {
      const key = prefix === null ? `${frame}` : `${frame},${prefix}`;
      let stack = stackMap.get(key);
      if (stack === undefined) {
        stack = stackTable.data.length;
        stackTable.data.push([prefix, frame]);
        stackMap.set(key, stack);
      }
      return stack;
    }

    const frameMap = new Map();
    function getOrCreateFrame(frameString: string) {
      let frame = frameMap.get(frameString);
      if (frame === undefined) {
        frame = frameTable.data.length;
        const location = stringTable.length;
        stringTable.push(frameString);
        // Heuristic: 'kallsyms' presence in a frame seems to be a reasonably
        // reliable indicator of a Linux kernel frame, and easier/more portable
        // than checking if the address is in kernel-space (e.g. starting with FF).
        const category = frameString.includes('kallsyms')
          ? KERNEL_CATEGORY_INDEX
          : USER_CATEGORY_INDEX;
        const implementation = null;
        const optimizations = null;
        const line = null;
        const relevantForJS = false;
        const subcategory = null;
        const innerWindowID = 0;
        const column = null;
        frameTable.data.push([
          location,
          relevantForJS,
          innerWindowID,
          implementation,
          optimizations,
          line,
          column,
          category,
          subcategory,
        ]);
        frameMap.set(frameString, frame);
      }
      return frame;
    }

    function addSample(threadName, stackArray, time) {
      // often we create a thread which inherits the name of the parent, and
      // set the thread's name slightly later.  Avoid having the first
      // sample's name stick.
      if (name !== threadName) {
        name = threadName;
      }
      const stack = stackArray.reduce((prefix, stackFrame) => {
        const frame = getOrCreateFrame(stackFrame);
        return getOrCreateStack(frame, prefix);
      }, null);
      // We don't have this information, so simulate that there's no latency at
      // all in processing events.
      const responsiveness = 0;
      samples.data.push([stack, time, responsiveness]);
    }

    return {
      addSample,
      finish: () => {
        return {
          tid,
          pid,
          name,
          markers,
          samples,
          frameTable,
          stackTable,
          stringTable,
          registerTime: 0,
          unregisterTime: null,
          processType: 'default',
        };
      },
    };
  }

  const threadMap = new Map();

  function _addThreadSample(pid, tid, threadName, timeStamp, stack) {
    // Right now this assumes that you can't have two identical tids in
    // different pids, which is true in linux at least.
    let thread = threadMap.get(tid);
    if (thread === undefined) {
      thread = _createThread(threadName, pid, tid);
      threadMap.set(tid, thread);
    }
    thread.addSample(threadName, stack, timeStamp);
  }

  // Parse the format. Some of the regular expressions and comments below were
  // taken from Brendan Gregg's stackcollapse-perf.pl.
  const lines = profile.split('\n');

  let lineIndex = 0;
  let startTime = 0;
  while (lineIndex < lines.length) {
    const line = lines[lineIndex++];
    // perf script --header outputs header lines beginning with #
    if (line === '' || line.startsWith('#')) {
      continue;
    }

    const sampleStartLine = line;
    // default "perf script" output has TID but not PID
    // eg, "java 25607 4794564.109216: cycles:"
    // eg, "java 12688 [002] 6544038.708352: cpu-clock:"
    // eg, "V8 WorkerThread 25607 4794564.109216: cycles:"
    // eg, "java 24636/25607 [000] 4794564.109216: cycles:"
    // eg, "Gecko	25122 [007] 115539.936601:		1000000 task-clock:u:" <-- SimplePerf output; note the tab characters
    // eg, "java 12688/12764 6544038.708352: cpu-clock:"
    // eg, "V8 WorkerThread 24636/25607 [000] 94564.109216: cycles:"
    // other combinations possible
    // pattern: thread-name-with-optional-spaces-and-numbers tid [NNN] time: NNN cycles:XXXX:
    // alternate pattern: thread-name-with-optional-spaces-and-numbers pid/tid [NNN] time: NNN cycles:XXXX:
    // eg, "FS Broker 5858  5791/5860  30171.917889:    4612247 cycles:ppp: "
    // eg, "java 25607/25608 4794564.109216: 33 cycles:uppp"
    //   (generate with "perf script -F +pid")

    // First, get the sample's time stamp and whatever comes before the timestamp:
    const sampleStartMatch = /^(.*)\s+([\d.]+):/.exec(sampleStartLine);
    if (!sampleStartMatch) {
      console.log(
        'Could not parse line as the start of a sample in the "perf script" profile format: "%s"',
        sampleStartLine
      );
      continue;
    }

    const beforeTimeStamp = sampleStartMatch[1];
    const timeStamp = parseFloat(sampleStartMatch[2]) * 1000;

    // Now try to find the tid within `beforeTimeStamp`, possibly with a pid/ in
    // front of it. Treat everything before that as the thread name.
    //                                  +- threadName
    //                                  |          +- pid/ (optional)
    //                                  |          |        +- tid
    //                                  |          |        |   +- end of word (space or end of string)
    //                                 vvvv   vvvvvvvvvvv vvvvv v
    const threadNamePidAndTidMatch = /^(.*)\s+(?:(\d+)\/)?(\d+)\b/.exec(
      beforeTimeStamp
    );

    if (!threadNamePidAndTidMatch) {
      console.log(
        'Could not parse line as the start of a sample in the "perf script" profile format: "%s"',
        sampleStartLine
      );
      continue;
    }

    const threadName = threadNamePidAndTidMatch[1].trim();
    const pid = Number(threadNamePidAndTidMatch[2] || 0);
    const tid = Number(threadNamePidAndTidMatch[3] || 0);

    // Assume start time is the time of the first sample
    if (startTime === 0) {
      startTime = timeStamp;
    }
    // Parse the stack frames of the current sample in a nested loop.
    const stack = [];
    while (lineIndex < lines.length) {
      const stackFrameLine = lines[lineIndex++];
      if (stackFrameLine.trim() === '') {
        // Sample ends.
        break;
      }

      // 	         23fe921 _ZN7mozilla3ipc14MessageChannel11MessageTask3RunEv (/home/mstange/Desktop/firefox/libxul.so)
      const stackFrameMatch = /^\s*(\w+)\s*(.+) \((\S*)\)/.exec(stackFrameLine);
      if (stackFrameMatch) {
        // const pc = stackFrameMatch[1];
        let rawFunc = stackFrameMatch[2];
        const mod = stackFrameMatch[3];

        // Linux 4.8 included symbol offsets in perf script output by default, eg:
        // 7fffb84c9afc cpu_startup_entry+0x800047c022ec ([kernel.kallsyms])
        // strip these off:
        rawFunc = rawFunc.replace(/\+0x[\da-f]+$/, '');

        if (rawFunc.startsWith('(')) {
          continue; // skip process names
        }

        if (mod) {
          // If we have a module name, provide it.
          // The code processing the profile will search for
          // "functionName (in libraryName)" using a regexp,
          // and automatically create the library information.
          rawFunc += ` (in ${mod})`;
        }

        stack.push(rawFunc);
      }
    }

    if (stack.length !== 0) {
      stack.reverse();
      _addThreadSample(pid, tid, threadName, timeStamp, stack);
    }
  }

  const threadArray = Array.from(threadMap.values()).map((thread) =>
    thread.finish()
  );

  for (const thread of threadArray) {
    // The samples are not guaranteed to be in order, sort them so that they are.
    const key = thread.samples.schema.time;
    (thread.samples.data: Array<any>).sort((a, b) => a[key] - b[key]);
  }

  return {
    meta: {
      interval: 1,
      processType: 0,
      product: 'Firefox',
      stackwalk: 1,
      debug: 0,
      gcpoison: 0,
      asyncstack: 1,
      startTime: startTime,
      shutdownTime: null,
      version: 24,
      presymbolicated: true,
      categories: CATEGORIES,
      markerSchema: [],
    },
    libs: [],
    threads: threadArray,
    processes: [],
    pausedRanges: [],
  };
}
<commit_msg>Only sniff linux perf profiles with first 20kB<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow

import type { MixedObject } from 'firefox-profiler/types';

/**
 * The "perf script" format is the plain text format that is output by an
 * invocation of `perf script`, where `perf` is the Linux perf command line tool.
 */
export function isPerfScriptFormat(profile: string): boolean {
  // Slice the input to a reasonable length, because this can
  // also be abused by one very long line.

  // One test showed a header 2KB long:
  // $ cat src/test/fixtures/upgrades/graphviz.perf.gz | gunzip | grep '#' | wc -c
  // 2286
  // 10x margin of error => 20KB should be enough.
  profile = profile.slice(0, 20 * 1024);

  // Optimisation: The simplest way to solve this would be using
  // the same logic as parsing: looping over profile.split('\n').
  // But fingerprinting the profile should be fast. So we use a
  // multiline regex to avoid processing the entire profile.

  // This regexp matches the first line that doesn't start with #,
  // and has at least one character.
  const firstLineFinderRe = /^(?!#).+$/m;
  const maybeFirstLine = firstLineFinderRe.exec(profile);
  if (!maybeFirstLine) {
    return false;
  }

  const firstLine = maybeFirstLine[0];
  //          +- process name (anything before the rest of the regexp, can contain spaces)
  //          |        +- PID/ (optional)
  //          |        |      +- TID
  //          |        |      |          +- [CPU] (optional, present in SimplePerf output)
  //          |        |      |          |          +- timestamp
  //       vvvvv   vvvvvvvvv vvv   vvvvvvvvvvvvvv vvvvvv
  return /^\S.+?\s+(?:\d+\/)?\d+\s+(?:\[\d+\]\s+)?[\d.]+:/.test(firstLine);
}

// Don't try and type this more specifically.
type GeckoProfileVersion24 = MixedObject;

const CATEGORIES = [
  { name: 'User', color: 'yellow', subcategories: ['Other'] },
  { name: 'Kernel', color: 'orange', subcategories: ['Other'] },
];
const USER_CATEGORY_INDEX = 0;
const KERNEL_CATEGORY_INDEX = 1;

/**
 * Convert the output from `perf script` into the gecko profile format (version 24).
 */
export function convertPerfScriptProfile(
  profile: string
): GeckoProfileVersion24 {
  function _createThread(name, pid, tid) {
    const markers = {
      schema: {
        name: 0,
        startTime: 1,
        endTime: 2,
        phase: 3,
        category: 4,
        data: 5,
      },
      data: [],
    };
    const samples = {
      schema: {
        stack: 0,
        time: 1,
        responsiveness: 2,
      },
      data: [],
    };
    const frameTable = {
      schema: {
        location: 0,
        relevantForJS: 1,
        innerWindowID: 2,
        implementation: 3,
        optimizations: 4,
        line: 5,
        column: 6,
        category: 7,
        subcategory: 8,
      },
      data: [],
    };
    const stackTable = {
      schema: {
        prefix: 0,
        frame: 1,
      },
      data: [],
    };
    const stringTable = [];

    const stackMap = new Map();
    function getOrCreateStack(frame, prefix) {
      const key = prefix === null ? `${frame}` : `${frame},${prefix}`;
      let stack = stackMap.get(key);
      if (stack === undefined) {
        stack = stackTable.data.length;
        stackTable.data.push([prefix, frame]);
        stackMap.set(key, stack);
      }
      return stack;
    }

    const frameMap = new Map();
    function getOrCreateFrame(frameString: string) {
      let frame = frameMap.get(frameString);
      if (frame === undefined) {
        frame = frameTable.data.length;
        const location = stringTable.length;
        stringTable.push(frameString);
        // Heuristic: 'kallsyms' presence in a frame seems to be a reasonably
        // reliable indicator of a Linux kernel frame, and easier/more portable
        // than checking if the address is in kernel-space (e.g. starting with FF).
        const category = frameString.includes('kallsyms')
          ? KERNEL_CATEGORY_INDEX
          : USER_CATEGORY_INDEX;
        const implementation = null;
        const optimizations = null;
        const line = null;
        const relevantForJS = false;
        const subcategory = null;
        const innerWindowID = 0;
        const column = null;
        frameTable.data.push([
          location,
          relevantForJS,
          innerWindowID,
          implementation,
          optimizations,
          line,
          column,
          category,
          subcategory,
        ]);
        frameMap.set(frameString, frame);
      }
      return frame;
    }

    function addSample(threadName, stackArray, time) {
      // often we create a thread which inherits the name of the parent, and
      // set the thread's name slightly later.  Avoid having the first
      // sample's name stick.
      if (name !== threadName) {
        name = threadName;
      }
      const stack = stackArray.reduce((prefix, stackFrame) => {
        const frame = getOrCreateFrame(stackFrame);
        return getOrCreateStack(frame, prefix);
      }, null);
      // We don't have this information, so simulate that there's no latency at
      // all in processing events.
      const responsiveness = 0;
      samples.data.push([stack, time, responsiveness]);
    }

    return {
      addSample,
      finish: () => {
        return {
          tid,
          pid,
          name,
          markers,
          samples,
          frameTable,
          stackTable,
          stringTable,
          registerTime: 0,
          unregisterTime: null,
          processType: 'default',
        };
      },
    };
  }

  const threadMap = new Map();

  function _addThreadSample(pid, tid, threadName, timeStamp, stack) {
    // Right now this assumes that you can't have two identical tids in
    // different pids, which is true in linux at least.
    let thread = threadMap.get(tid);
    if (thread === undefined) {
      thread = _createThread(threadName, pid, tid);
      threadMap.set(tid, thread);
    }
    thread.addSample(threadName, stack, timeStamp);
  }

  // Parse the format. Some of the regular expressions and comments below were
  // taken from Brendan Gregg's stackcollapse-perf.pl.
  const lines = profile.split('\n');

  let lineIndex = 0;
  let startTime = 0;
  while (lineIndex < lines.length) {
    const line = lines[lineIndex++];
    // perf script --header outputs header lines beginning with #
    if (line === '' || line.startsWith('#')) {
      continue;
    }

    const sampleStartLine = line;
    // default "perf script" output has TID but not PID
    // eg, "java 25607 4794564.109216: cycles:"
    // eg, "java 12688 [002] 6544038.708352: cpu-clock:"
    // eg, "V8 WorkerThread 25607 4794564.109216: cycles:"
    // eg, "java 24636/25607 [000] 4794564.109216: cycles:"
    // eg, "Gecko	25122 [007] 115539.936601:		1000000 task-clock:u:" <-- SimplePerf output; note the tab characters
    // eg, "java 12688/12764 6544038.708352: cpu-clock:"
    // eg, "V8 WorkerThread 24636/25607 [000] 94564.109216: cycles:"
    // other combinations possible
    // pattern: thread-name-with-optional-spaces-and-numbers tid [NNN] time: NNN cycles:XXXX:
    // alternate pattern: thread-name-with-optional-spaces-and-numbers pid/tid [NNN] time: NNN cycles:XXXX:
    // eg, "FS Broker 5858  5791/5860  30171.917889:    4612247 cycles:ppp: "
    // eg, "java 25607/25608 4794564.109216: 33 cycles:uppp"
    //   (generate with "perf script -F +pid")

    // First, get the sample's time stamp and whatever comes before the timestamp:
    const sampleStartMatch = /^(.*)\s+([\d.]+):/.exec(sampleStartLine);
    if (!sampleStartMatch) {
      console.log(
        'Could not parse line as the start of a sample in the "perf script" profile format: "%s"',
        sampleStartLine
      );
      continue;
    }

    const beforeTimeStamp = sampleStartMatch[1];
    const timeStamp = parseFloat(sampleStartMatch[2]) * 1000;

    // Now try to find the tid within `beforeTimeStamp`, possibly with a pid/ in
    // front of it. Treat everything before that as the thread name.
    //                                  +- threadName
    //                                  |          +- pid/ (optional)
    //                                  |          |        +- tid
    //                                  |          |        |   +- end of word (space or end of string)
    //                                 vvvv   vvvvvvvvvvv vvvvv v
    const threadNamePidAndTidMatch = /^(.*)\s+(?:(\d+)\/)?(\d+)\b/.exec(
      beforeTimeStamp
    );

    if (!threadNamePidAndTidMatch) {
      console.log(
        'Could not parse line as the start of a sample in the "perf script" profile format: "%s"',
        sampleStartLine
      );
      continue;
    }

    const threadName = threadNamePidAndTidMatch[1].trim();
    const pid = Number(threadNamePidAndTidMatch[2] || 0);
    const tid = Number(threadNamePidAndTidMatch[3] || 0);

    // Assume start time is the time of the first sample
    if (startTime === 0) {
      startTime = timeStamp;
    }
    // Parse the stack frames of the current sample in a nested loop.
    const stack = [];
    while (lineIndex < lines.length) {
      const stackFrameLine = lines[lineIndex++];
      if (stackFrameLine.trim() === '') {
        // Sample ends.
        break;
      }

      // 	         23fe921 _ZN7mozilla3ipc14MessageChannel11MessageTask3RunEv (/home/mstange/Desktop/firefox/libxul.so)
      const stackFrameMatch = /^\s*(\w+)\s*(.+) \((\S*)\)/.exec(stackFrameLine);
      if (stackFrameMatch) {
        // const pc = stackFrameMatch[1];
        let rawFunc = stackFrameMatch[2];
        const mod = stackFrameMatch[3];

        // Linux 4.8 included symbol offsets in perf script output by default, eg:
        // 7fffb84c9afc cpu_startup_entry+0x800047c022ec ([kernel.kallsyms])
        // strip these off:
        rawFunc = rawFunc.replace(/\+0x[\da-f]+$/, '');

        if (rawFunc.startsWith('(')) {
          continue; // skip process names
        }

        if (mod) {
          // If we have a module name, provide it.
          // The code processing the profile will search for
          // "functionName (in libraryName)" using a regexp,
          // and automatically create the library information.
          rawFunc += ` (in ${mod})`;
        }

        stack.push(rawFunc);
      }
    }

    if (stack.length !== 0) {
      stack.reverse();
      _addThreadSample(pid, tid, threadName, timeStamp, stack);
    }
  }

  const threadArray = Array.from(threadMap.values()).map((thread) =>
    thread.finish()
  );

  for (const thread of threadArray) {
    // The samples are not guaranteed to be in order, sort them so that they are.
    const key = thread.samples.schema.time;
    (thread.samples.data: Array<any>).sort((a, b) => a[key] - b[key]);
  }

  return {
    meta: {
      interval: 1,
      processType: 0,
      product: 'Firefox',
      stackwalk: 1,
      debug: 0,
      gcpoison: 0,
      asyncstack: 1,
      startTime: startTime,
      shutdownTime: null,
      version: 24,
      presymbolicated: true,
      categories: CATEGORIES,
      markerSchema: [],
    },
    libs: [],
    threads: threadArray,
    processes: [],
    pausedRanges: [],
  };
}
<|endoftext|>


<commit_before>/* eslint max-len:0 */
import {panelists} from '../../resources/panelists'
import {cloneDeep} from 'lodash'
const guests = cloneDeep(panelists)

const guestLinksTipsAndPicks = [
  {
    twitter: 'dan_abramov',
    links: [
      `[React Hot Loader](http://gaearon.github.io/react-hot-loader/)`,
    ],
    picks: [
      `[devtool](https://github.com/Jam3/devtool)`,
      `[React.js pure render performance anti-pattern](https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f#.a6h48jrtg)`,
      `[Fullstack React](https://twitter.com/fullstackreact)`,
      `[Code Cartoons - Relay](https://code-cartoons.com/a-cartoon-intro-to-facebook-s-relay-part-1-3ec1a127bca5)`,
      `[Redux 2 in the works](https://www.reddit.com/r/reactjs/comments/418spy/redux_2_in_the_works_with_dan_and_contra/)`,
    ],
  },
  {
    twitter: 'drboolean',
    links: [
      `[Hardy Jones on lenses + virtual dom](http://joneshf.github.io/programming/2015/12/19/Lenses-and-Virtual-DOM-Support-Open-Closed.html)`,
      `[Lamda Conf vids](https://www.youtube.com/watch?v=JxC1ExlLjgw&list=PLE7tQUdRKcybh21_zOg8_y4f2oMKDHpUS)`,
    ],
    picks: [
      `[Jeff Bridges: The sleeping tapes](http://www.dreamingwithjeff.com)`,
      `[Don Hertzfeldt: World of Tomorrow](https://vimeo.com/ondemand/worldoftomorrow)`,
    ],
  },
  {
    twitter: 'getify',
    links: [
      `[You Don’t Know JS book series](http://youdontknowjs.com)`,
      `[MakerSquare](http://makersquare.com)`,
      `[Frontend Masters](http://frontendmasters.com)`,
      `[ForwardJS Workshops](http://forwardjs.com/workshops)`,
      `[ForwardJS free webinar: “Blocking Across The Wire”](https://attendee.gotowebinar.com/register/7996879282595345666) Tue Jan 25, 12pm CST`,
      `[FluentConf Workshops](http://conferences.oreilly.com/fluent/javascript-html-us/public/schedule/detail/47782)`,
      `[asynquence](http://github.com/getify/asynquence)`,
      `[A Tale Of Three Lists](http://github.com/getify/a-tale-of-three-lists) The “TodoMVC” of async programming`,
    ],
    tips: [
      `Pair program with a friend on a couch.`,
    ],
    picks: [
      `[RTC Everywhere](https://github.com/contra/rtc-everywhere) P2P cross-platform`,
      `[ChakraCore in Node.js](https://blogs.windows.com/msedgedev/2016/01/19/nodejs-chakracore-mainline/)`,
      `[Brave Browser](https://brave.com/) by [@BrendanEich](http://twitter.com/brendaneich)`,
    ],
  },
  {
    twitter: 'kwuchu',
    links: [
      `[IBM Chef Watson](https://www.ibmchefwatson.com/)`,
    ],
    picks: [
      `[Ember-CLI 101](https://leanpub.com/ember-cli-101) - Really good book for getting started with learning Ember!`,
    ],
  },
  {
    twitter: 'linclark',
    links: [
      `[A cartoon guide to Facebook’s Relay, part 1](https://code-cartoons.com/a-cartoon-intro-to-facebook-s-relay-part-1-3ec1a127bca5#.ak19gbh26)`,
    ],
    tips: [
      `Learn keyboard commands for your favorite web apps like Gmail. Flash cards can be really helpful for this. [Brainscape](https://www.brainscape.com/) has a few different decks.`,
    ],
    picks: [
      `[Dvorak keyboard training](http://learn.dvorak.nl/)`,
    ],
  },
  {
    twitter: 'mzabriskie',
    links: [
      `[@zabriskiesbeard](https://twitter.com/zabriskiesbeard)`,
    ],
    tips: [
      `[First Timers Only](https://github.com/search?utf8=%E2%9C%93&q=language%3AJavaScript+state%3Aopen+label%3Afirst-timers-only)`,
    ],
    picks: [
      `[Learning React Native](http://shop.oreilly.com/product/0636920041511.do)`,
    ],
  },
  {
    twitter: 'pamasaur',
    links: [
      `[Choosing a JavaScript Framework](http://bleedingedgepress.com/our-books/choosing-javascript-framework/)`,
      `[When the computing](http://thewebivore.com/when-computing-hurts/)`,
    ],
    picks: [
      `[Pixel Art to CSS](http://pixelart-to-css-react.herokuapp.com/)`,
    ],
  },
  {
    twitter: 'tylermcginnis33',
    picks: [
      `[Headspace](http://headspace.com)`,
      `[Front End Newsletter](http://frontendnewsletter.com)`,
      `[React.run](http://www.react.run/)`,
    ],
  },
]

guestLinksTipsAndPicks.forEach(info => {
  const guestIndex = guests.findIndex(g => g.twitter === info.twitter)
  guests[guestIndex] = {...guests[guestIndex], ...info}
})

export default {
  title: `Introducing the JavaScript Air Panel`,
  guests,
  description: `
    We have some solid developers on the JavaScript Air panel working on some amazing things. This is your chance to get to know them!
  `,
  hangoutId: 'ciduop5sck7su6n8f99nnctigt0',
  youTubeId: 'gxI5m_raAWg',
  podbeanId: '',
  past: true,
  host: {
    links: [
      `[My Talks and Workshops](http://talks.kcd.im)`,
      `[My Egghead lessons](https://egghead.io/instructors/kentcdodds)`,
      `[My Blog](http://blog.kcd.im)`,
      `[My AMA](http://ama.kcd.im) and my answer to [what's your favorite/most-effective learning method?](https://github.com/kentcdodds/ama/issues/41)`,
      `[First Timers Only](https://medium.com/@kentcdodds/first-timers-only-78281ea47455) - My original blogpost about the concept`,
    ],
    tips: [
      `Take chances, make mistakes, and get messy! -Miss Frizzle, Magic School Bus`
    ],
    picks: [
      `[Babel Service](https://github.com/bahmutov/babel-service) by [Gleb Bahmutov](https://twitter.com/bahmutov)`,
      `[The Magic School Bus](http://www.scholastic.com/magicschoolbus/) (warning! Video auto-plays)`,
    ],
  }
}

<commit_msg>Add podbeanId for #4<commit_after>/* eslint max-len:0 */
import {panelists} from '../../resources/panelists'
import {cloneDeep} from 'lodash'
const guests = cloneDeep(panelists)

const guestLinksTipsAndPicks = [
  {
    twitter: 'dan_abramov',
    links: [
      `[React Hot Loader](http://gaearon.github.io/react-hot-loader/)`,
    ],
    picks: [
      `[devtool](https://github.com/Jam3/devtool)`,
      `[React.js pure render performance anti-pattern](https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f#.a6h48jrtg)`,
      `[Fullstack React](https://twitter.com/fullstackreact)`,
      `[Code Cartoons - Relay](https://code-cartoons.com/a-cartoon-intro-to-facebook-s-relay-part-1-3ec1a127bca5)`,
      `[Redux 2 in the works](https://www.reddit.com/r/reactjs/comments/418spy/redux_2_in_the_works_with_dan_and_contra/)`,
    ],
  },
  {
    twitter: 'drboolean',
    links: [
      `[Hardy Jones on lenses + virtual dom](http://joneshf.github.io/programming/2015/12/19/Lenses-and-Virtual-DOM-Support-Open-Closed.html)`,
      `[Lamda Conf vids](https://www.youtube.com/watch?v=JxC1ExlLjgw&list=PLE7tQUdRKcybh21_zOg8_y4f2oMKDHpUS)`,
    ],
    picks: [
      `[Jeff Bridges: The sleeping tapes](http://www.dreamingwithjeff.com)`,
      `[Don Hertzfeldt: World of Tomorrow](https://vimeo.com/ondemand/worldoftomorrow)`,
    ],
  },
  {
    twitter: 'getify',
    links: [
      `[You Don’t Know JS book series](http://youdontknowjs.com)`,
      `[MakerSquare](http://makersquare.com)`,
      `[Frontend Masters](http://frontendmasters.com)`,
      `[ForwardJS Workshops](http://forwardjs.com/workshops)`,
      `[ForwardJS free webinar: “Blocking Across The Wire”](https://attendee.gotowebinar.com/register/7996879282595345666) Tue Jan 25, 12pm CST`,
      `[FluentConf Workshops](http://conferences.oreilly.com/fluent/javascript-html-us/public/schedule/detail/47782)`,
      `[asynquence](http://github.com/getify/asynquence)`,
      `[A Tale Of Three Lists](http://github.com/getify/a-tale-of-three-lists) The “TodoMVC” of async programming`,
    ],
    tips: [
      `Pair program with a friend on a couch.`,
    ],
    picks: [
      `[RTC Everywhere](https://github.com/contra/rtc-everywhere) P2P cross-platform`,
      `[ChakraCore in Node.js](https://blogs.windows.com/msedgedev/2016/01/19/nodejs-chakracore-mainline/)`,
      `[Brave Browser](https://brave.com/) by [@BrendanEich](http://twitter.com/brendaneich)`,
    ],
  },
  {
    twitter: 'kwuchu',
    links: [
      `[IBM Chef Watson](https://www.ibmchefwatson.com/)`,
    ],
    picks: [
      `[Ember-CLI 101](https://leanpub.com/ember-cli-101) - Really good book for getting started with learning Ember!`,
    ],
  },
  {
    twitter: 'linclark',
    links: [
      `[A cartoon guide to Facebook’s Relay, part 1](https://code-cartoons.com/a-cartoon-intro-to-facebook-s-relay-part-1-3ec1a127bca5#.ak19gbh26)`,
    ],
    tips: [
      `Learn keyboard commands for your favorite web apps like Gmail. Flash cards can be really helpful for this. [Brainscape](https://www.brainscape.com/) has a few different decks.`,
    ],
    picks: [
      `[Dvorak keyboard training](http://learn.dvorak.nl/)`,
    ],
  },
  {
    twitter: 'mzabriskie',
    links: [
      `[@zabriskiesbeard](https://twitter.com/zabriskiesbeard)`,
    ],
    tips: [
      `[First Timers Only](https://github.com/search?utf8=%E2%9C%93&q=language%3AJavaScript+state%3Aopen+label%3Afirst-timers-only)`,
    ],
    picks: [
      `[Learning React Native](http://shop.oreilly.com/product/0636920041511.do)`,
    ],
  },
  {
    twitter: 'pamasaur',
    links: [
      `[Choosing a JavaScript Framework](http://bleedingedgepress.com/our-books/choosing-javascript-framework/)`,
      `[When the computing](http://thewebivore.com/when-computing-hurts/)`,
    ],
    picks: [
      `[Pixel Art to CSS](http://pixelart-to-css-react.herokuapp.com/)`,
    ],
  },
  {
    twitter: 'tylermcginnis33',
    picks: [
      `[Headspace](http://headspace.com)`,
      `[Front End Newsletter](http://frontendnewsletter.com)`,
      `[React.run](http://www.react.run/)`,
    ],
  },
]

guestLinksTipsAndPicks.forEach(info => {
  const guestIndex = guests.findIndex(g => g.twitter === info.twitter)
  guests[guestIndex] = {...guests[guestIndex], ...info}
})

export default {
  title: `Introducing the JavaScript Air Panel`,
  guests,
  description: `
    We have some solid developers on the JavaScript Air panel working on some amazing things. This is your chance to get to know them!
  `,
  hangoutId: 'ciduop5sck7su6n8f99nnctigt0',
  youTubeId: 'gxI5m_raAWg',
  podbeanId: 'mu5vn-5bebfd',
  past: true,
  host: {
    links: [
      `[My Talks and Workshops](http://talks.kcd.im)`,
      `[My Egghead lessons](https://egghead.io/instructors/kentcdodds)`,
      `[My Blog](http://blog.kcd.im)`,
      `[My AMA](http://ama.kcd.im) and my answer to [what's your favorite/most-effective learning method?](https://github.com/kentcdodds/ama/issues/41)`,
      `[First Timers Only](https://medium.com/@kentcdodds/first-timers-only-78281ea47455) - My original blogpost about the concept`,
    ],
    tips: [
      `Take chances, make mistakes, and get messy! -Miss Frizzle, Magic School Bus`
    ],
    picks: [
      `[Babel Service](https://github.com/bahmutov/babel-service) by [Gleb Bahmutov](https://twitter.com/bahmutov)`,
      `[The Magic School Bus](http://www.scholastic.com/magicschoolbus/) (warning! Video auto-plays)`,
    ],
  }
}

<|endoftext|>


<commit_before>var request = require('request');
var qs = require('querystring');

angular.module('bullhorn')
  .service('Spotify', function($q) {

    var initialized = $q.defer();

    var startPort = 4370;
    var endPort = 4379;

    var charset = 'abcdefghijklmnopqrstuvwxyz1234567890';

    var generateRandomString = function(length) {
      var result = '';

      for (var i = length; i > 0; --i) {
        result += charset[Math.round(Math.random() * (charset.length - 1))];
      }

      return result;
    };

    var buildLocalUrl = function(port) {
      return 'https://' + svc.subDomain + '.spotilocal.com:' + port;
    };

    // Service
    var svc = {};

    svc.play = function(id) {
      initialized.promise.then(function() {
        svc.get('/remote/play.json', {
          'uri': id
        });
      });
    };

    svc.pause = function(pause) {
      initialized.promise.then(function() {
        svc.get('/remote/pause.json', {
          'pause': angular.isDefined(pause) ? pause : true
        });
      });
    };

    svc.determineLocalUrl = function() {
      var deferred = $q.defer();

      for (var port = startPort; port <= endPort; port++) {

        request(buildLocalUrl(port) + '/remote/status.json', function(error, response, body) {
          if (response && response.statusCode === 200) {
              deferred.resolve(response.request.port);
          }
        });
      }

      return deferred.promise;
    };

    svc.getOAuthToken = function() {
      var deferred = $q.defer();

      request('http://open.spotify.com/token', function(error, response, body) {
        var obj = JSON.parse(body);
        deferred.resolve(obj.t);
      });

      return deferred.promise;
    };

    svc.getCsrfToken = function() {
      var deferred = $q.defer();

      var path = '/simplecsrf/token.json?ref=&cors=';

      var options = {
        url: svc.localUrl + path,
        headers: {
          'Origin': 'https://open.spotify.com'
        }
      };

      request(options, function(error, response, body) {
        var obj = JSON.parse(body);
        deferred.resolve(obj.token);
      });

      return deferred.promise;
    };

    svc.get = function(path, params) {
      var deferred = $q.defer();

      if (/^\//.test(path)) {
        path = svc.localUrl + path;
      }

      var parameters = {
        'oauth': svc.oAuthToken,
        'csrf': svc.csrfToken,
        'ref': '',
        'cors': ''
      }

      if (angular.isDefined(params)) {
        angular.forEach(params, function(value, key) {
          parameters[key] = value;
        });
      }

      path += '?' + qs.stringify(parameters);

      request(path, function(error, response, body) {
        deferred.resolve();
      })

      return deferred.promise;
    };

    svc.initialize = function() {
      svc.subDomain = generateRandomString(5);

      svc.determineLocalUrl().then(function(port) {
        svc.localUrl = buildLocalUrl(port);

        $q.all([
          svc.getOAuthToken(),
          svc.getCsrfToken()
        ]).then(function(data) {

          svc.oAuthToken = data[0];
          svc.csrfToken = data[1];

          initialized.resolve();
        });
      });

      return initialized.promise;
    };

    svc.initialize();

    return svc;
  });
<commit_msg>Added Origin header to all requests<commit_after>var request = require('request');
var qs = require('querystring');

angular.module('bullhorn')
  .service('Spotify', function($q) {

    var initialized = $q.defer();

    var startPort = 4370;
    var endPort = 4379;

    var originHeader = 'https://open.spotify.com';

    var charset = 'abcdefghijklmnopqrstuvwxyz1234567890';

    var generateRandomString = function(length) {
      var result = '';

      for (var i = length; i > 0; --i) {
        result += charset[Math.round(Math.random() * (charset.length - 1))];
      }

      return result;
    };

    var buildLocalUrl = function(port) {
      return 'https://' + svc.subDomain + '.spotilocal.com:' + port;
    };

    // Service
    var svc = {};

    svc.play = function(id) {
      initialized.promise.then(function() {
        svc.get('/remote/play.json', {
          'uri': id
        });
      });
    };

    svc.pause = function(pause) {
      initialized.promise.then(function() {
        svc.get('/remote/pause.json', {
          'pause': angular.isDefined(pause) ? pause : true
        });
      });
    };

    svc.determineLocalUrl = function() {
      var deferred = $q.defer();

      for (var port = startPort; port <= endPort; port++) {

        var options = {
          url: buildLocalUrl(port) + '/remote/status.json',
          headers: {
            'Origin': originHeader
          }
        };

        request(options, function(error, response, body) {
          if (response && response.statusCode === 200) {
              deferred.resolve(response.request.port);
          }
        });
      }

      return deferred.promise;
    };

    svc.getOAuthToken = function() {
      var deferred = $q.defer();

      request('http://open.spotify.com/token', function(error, response, body) {
        var obj = JSON.parse(body);
        deferred.resolve(obj.t);
      });

      return deferred.promise;
    };

    svc.getCsrfToken = function() {
      var deferred = $q.defer();

      var path = '/simplecsrf/token.json?ref=&cors=';

      var options = {
        url: svc.localUrl + path,
        headers: {
          'Origin': originHeader
        }
      };

      request(options, function(error, response, body) {
        var obj = JSON.parse(body);
        deferred.resolve(obj.token);
      });

      return deferred.promise;
    };

    svc.get = function(path, params) {
      var deferred = $q.defer();

      if (/^\//.test(path)) {
        path = svc.localUrl + path;
      }

      var parameters = {
        'oauth': svc.oAuthToken,
        'csrf': svc.csrfToken,
        'ref': '',
        'cors': ''
      };

      if (angular.isDefined(params)) {
        angular.forEach(params, function(value, key) {
          parameters[key] = value;
        });
      }

      var options = {
        url: path += '?' + qs.stringify(parameters),
        headers: {
          'Origin': originHeader
        }
      };

      request(options, function(error, response, body) {
        deferred.resolve();
      });

      return deferred.promise;
    };

    svc.initialize = function() {
      svc.subDomain = generateRandomString(5);

      svc.determineLocalUrl().then(function(port) {
        svc.localUrl = buildLocalUrl(port);

        $q.all([
          svc.getOAuthToken(),
          svc.getCsrfToken()
        ]).then(function(data) {

          svc.oAuthToken = data[0];
          svc.csrfToken = data[1];

          initialized.resolve();
        });
      });

      return initialized.promise;
    };

    svc.initialize();

    return svc;
  });
<|endoftext|>


<commit_before>function initTypeProtoI(a, b, c){} //IGNORE
function initTypeProto(a,b,c,d){}//IGNORE
function initType(a,b){}//IGNORE
function IdentifiableObject(x){}//IGNORE
function ArraySequence(x){}//IGNORE
function Comprehension(x){}//IGNORE
function Exception(x){}//IGNORE
function String$(x){}//IGNORE
var Container,$finished,$empty,larger,smaller,exports;//IGNORE

function Iterator(wat) {
    return wat;
}
initType(Iterator, 'ceylon.language.Iterator');
exports.Iterator=Iterator;

function Iterable(wat) {
    return wat;
}
initTypeProtoI(Iterable, 'ceylon.language.Iterable', ContainerWithFirstElement);
var Iterable$proto=Iterable.$$.prototype;
Iterable$proto.getEmpty = function() {
    return this.getIterator().next() === $finished;
}
Iterable$proto.getFirst = function() {
    var e = this.getIterator().next();
    return e === $finished ? null : e;
}
Iterable$proto.getRest = function() {
    return this.skipping(Integer(1));
}
Iterable$proto.getSequence = function() {
    var a = [];
    var iter = this.getIterator();
    var next;
    while ((next = iter.next()) !== $finished) {
        a.push(next);
    }
    return ArraySequence(a);
}
Iterable$proto.map = function(mapper) {
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        return function() {
            var e = it.next();
            if(e !== $finished) {return mapper(e);}
            return $finished;
        }
    });
}
Iterable$proto.filter = function(select) {
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        return function() {
            do {
                var e = it.next();
            } while ((e !== $finished) && !select(e));
            return e;
        }
    });
}
Iterable$proto.fold = function(ini, accum) {
    var r = ini;
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        r = accum(r, e);
    }
    return r;
}
Iterable$proto.find = function(select) {
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        if (select(e)) {
            return e;
        }
    }
    return null;
}
Iterable$proto.findLast = function(select) {
    var iter = this.getIterator();
    var last = null;
    var e; while ((e = iter.next()) !== $finished) {
        if (select(e)) {
            last = e;
        }
    }
    return last;
}
Iterable$proto.sort = function(/*Callable<Comparison?,Element,Element>*/comparing) {
    var a = [];
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        a.push(e);
    }
    a.sort(function(x,y) {
        var r = comparing(x,y);
        if (r === larger) return 1;
        if (r === smaller) return -1;
        return 0;
    });
    return ArraySequence(a);
}
Iterable$proto.any = function(/*Callable<Boolean,Element>*/selecting) {
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        if (selecting(e)) {
            return true;
        }
    }
    return false;
}
Iterable$proto.every = function(/*Callable<Boolean,Element>*/selecting) {
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        if (!selecting(e)) {
            return false;
        }
    }
    return true;
}
Iterable$proto.skipping = function(skip) {
    function skip$iter(iter,skip){
        var $cmp$=new skip$iter.$$;
        IdentifiableObject($cmp$);
        $cmp$.iter=iter;
        $cmp$.skip=skip;
        $cmp$.getIterator=function(){
            var iter = this.iter.getIterator();
            for (var i=0; i < this.skip; i++) {
                iter.next();
            }
            return iter;
        };
        return $cmp$;
    }
    initTypeProto(skip$iter, 'ceylon.language.SkipIterable', IdentifiableObject, Iterable);
    return skip$iter(this,skip.value);
}
Iterable$proto.taking = function(take) {
    if (take.value <= 0) return $empty;
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        var i = 0;
        return function() {
            if (i >= take.value) {return $finished;}
            ++i;
            return it.next();
        }
    });
}
Iterable$proto.by = function(step) {
    if (step.value == 1) return this;
    if (step.value < 1) throw Exception(String$("Step must be positive"));
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        return function() {
            var e = it.next();
            for (var i=1; i<step.value && (it.next()!==$finished); i++);
            return e;
        }
    });
}
Iterable$proto.count = function(sel) {
    var c = 0;
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        if (sel(e)) c++;
    }
    return Integer(c);
}
Iterable$proto.getCoalesced = function() {
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        return function() {
            var e;
            while ((e = it.next()) === null);
            return e;
        }
    });
}
Iterable$proto.getIndexed = function() {
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        var idx = 0;
        return function() {
            var e;
            while ((e = it.next()) === null);
            return e === $finished ? e : Entry(Integer(idx++), e);
        }
    });
}
Iterable$proto.getLast = function() {
    var iter = this.getIterator();
    var l=null;
    var e; while ((e = iter.next()) !== $finished) {
        l=e;
    }
    return l;
}

exports.Iterable=Iterable;

function ChainedIterator(i1, i2) {
	var that = new ChainedIterator.$$;
	that.i1=i1;
	that.i2=i2;
	that.more=true;
	return that;
}
initTypeProto(ChainedIterator, 'ceylon.language.ChainedIterator', IdentifiableObject, Iterator);
ChainedIterator.$$.prototype.next = function() {
	if (this.iter === undefined) {
		this.iter = this.i1.getIterator();
	}
	var e = this.iter.next();
	if (e === $finished && this.more) {
		this.more=false;
		this.iter=this.i2.getIterator();
		e=this.iter.next();
	}
	return e;
}
exports.ChainedIterator=ChainedIterator;
Iterable$proto.chain = function(other) {
    return ChainedIterable(this, other);
}
exports.Iterable=Iterable;

function ChainedIterable(first, second, chained) {
    if (chained===undefined) {chained = new ChainedIterable.$$;}
    IdentifiableObject(chained);
    chained.first = first;
    chained.second = second;
    return chained;
}
initTypeProto(ChainedIterable, "ceylon.language.ChainedIterable",
        IdentifiableObject, Iterable);
var ChainedIterable$proto = ChainedIterable.$$.prototype;
ChainedIterable$proto.getIterator = function() {
    return ChainedIterator(this.first, this.second);
}
<commit_msg>implement collect and select<commit_after>function initTypeProtoI(a, b, c){} //IGNORE
function initTypeProto(a,b,c,d){}//IGNORE
function initType(a,b){}//IGNORE
function IdentifiableObject(x){}//IGNORE
function ArraySequence(x){}//IGNORE
function Comprehension(x){}//IGNORE
function Exception(x){}//IGNORE
function String$(x){}//IGNORE
var Container,$finished,$empty,larger,smaller,exports;//IGNORE

function Iterator(wat) {
    return wat;
}
initType(Iterator, 'ceylon.language.Iterator');
exports.Iterator=Iterator;

function Iterable(wat) {
    return wat;
}
initTypeProtoI(Iterable, 'ceylon.language.Iterable', ContainerWithFirstElement);
var Iterable$proto=Iterable.$$.prototype;
Iterable$proto.getEmpty = function() {
    return this.getIterator().next() === $finished;
}
Iterable$proto.getFirst = function() {
    var e = this.getIterator().next();
    return e === $finished ? null : e;
}
Iterable$proto.getRest = function() {
    return this.skipping(Integer(1));
}
Iterable$proto.getSequence = function() {
    var a = [];
    var iter = this.getIterator();
    var next;
    while ((next = iter.next()) !== $finished) {
        a.push(next);
    }
    return ArraySequence(a);
}
Iterable$proto.map = function(mapper) {
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        return function() {
            var e = it.next();
            if(e !== $finished) {return mapper(e);}
            return $finished;
        }
    });
}
Iterable$proto.filter = function(select) {
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        return function() {
            do {
                var e = it.next();
            } while ((e !== $finished) && !select(e));
            return e;
        }
    });
}
Iterable$proto.fold = function(ini, accum) {
    var r = ini;
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        r = accum(r, e);
    }
    return r;
}
Iterable$proto.find = function(select) {
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        if (select(e)) {
            return e;
        }
    }
    return null;
}
Iterable$proto.findLast = function(select) {
    var iter = this.getIterator();
    var last = null;
    var e; while ((e = iter.next()) !== $finished) {
        if (select(e)) {
            last = e;
        }
    }
    return last;
}
Iterable$proto.sort = function(/*Callable<Comparison?,Element,Element>*/comparing) {
    var a = [];
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        a.push(e);
    }
    a.sort(function(x,y) {
        var r = comparing(x,y);
        if (r === larger) return 1;
        if (r === smaller) return -1;
        return 0;
    });
    return ArraySequence(a);
}
Iterable$proto.any = function(/*Callable<Boolean,Element>*/selecting) {
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        if (selecting(e)) {
            return true;
        }
    }
    return false;
}
Iterable$proto.every = function(/*Callable<Boolean,Element>*/selecting) {
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        if (!selecting(e)) {
            return false;
        }
    }
    return true;
}
Iterable$proto.skipping = function(skip) {
    function skip$iter(iter,skip){
        var $cmp$=new skip$iter.$$;
        IdentifiableObject($cmp$);
        $cmp$.iter=iter;
        $cmp$.skip=skip;
        $cmp$.getIterator=function(){
            var iter = this.iter.getIterator();
            for (var i=0; i < this.skip; i++) {
                iter.next();
            }
            return iter;
        };
        return $cmp$;
    }
    initTypeProto(skip$iter, 'ceylon.language.SkipIterable', IdentifiableObject, Iterable);
    return skip$iter(this,skip.value);
}
Iterable$proto.taking = function(take) {
    if (take.value <= 0) return $empty;
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        var i = 0;
        return function() {
            if (i >= take.value) {return $finished;}
            ++i;
            return it.next();
        }
    });
}
Iterable$proto.by = function(step) {
    if (step.value == 1) return this;
    if (step.value < 1) throw Exception(String$("Step must be positive"));
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        return function() {
            var e = it.next();
            for (var i=1; i<step.value && (it.next()!==$finished); i++);
            return e;
        }
    });
}
Iterable$proto.count = function(sel) {
    var c = 0;
    var iter = this.getIterator();
    var e; while ((e = iter.next()) !== $finished) {
        if (sel(e)) c++;
    }
    return Integer(c);
}
Iterable$proto.getCoalesced = function() {
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        return function() {
            var e;
            while ((e = it.next()) === null);
            return e;
        }
    });
}
Iterable$proto.getIndexed = function() {
    var iter = this;
    return Comprehension(function() {
        var it = iter.getIterator();
        var idx = 0;
        return function() {
            var e;
            while ((e = it.next()) === null);
            return e === $finished ? e : Entry(Integer(idx++), e);
        }
    });
}
Iterable$proto.getLast = function() {
    var iter = this.getIterator();
    var l=null;
    var e; while ((e = iter.next()) !== $finished) {
        l=e;
    }
    return l;
}
Iterable$proto.collect = function(collecting) {
    return this.map(collecting).getSequence();
}
Iterable$proto.select = function(selecting) {
    return this.filter(selecting).getSequence();
}

exports.Iterable=Iterable;

function ChainedIterator(i1, i2) {
	var that = new ChainedIterator.$$;
	that.i1=i1;
	that.i2=i2;
	that.more=true;
	return that;
}
initTypeProto(ChainedIterator, 'ceylon.language.ChainedIterator', IdentifiableObject, Iterator);
ChainedIterator.$$.prototype.next = function() {
	if (this.iter === undefined) {
		this.iter = this.i1.getIterator();
	}
	var e = this.iter.next();
	if (e === $finished && this.more) {
		this.more=false;
		this.iter=this.i2.getIterator();
		e=this.iter.next();
	}
	return e;
}
exports.ChainedIterator=ChainedIterator;
Iterable$proto.chain = function(other) {
    return ChainedIterable(this, other);
}
exports.Iterable=Iterable;

function ChainedIterable(first, second, chained) {
    if (chained===undefined) {chained = new ChainedIterable.$$;}
    IdentifiableObject(chained);
    chained.first = first;
    chained.second = second;
    return chained;
}
initTypeProto(ChainedIterable, "ceylon.language.ChainedIterable",
        IdentifiableObject, Iterable);
var ChainedIterable$proto = ChainedIterable.$$.prototype;
ChainedIterable$proto.getIterator = function() {
    return ChainedIterator(this.first, this.second);
}
<|endoftext|>


<commit_before>/**
 * Last update: 2016/06/26
 * https://translate.google.com/translate/releases/twsfe_w_20160620_RC00/r/js/desktop_module_main.js
 *
 * Everything between 'BEGIN' and 'END' was copied from the url above.
 */

import settings from 'electron-settings'
import axios from 'axios'

/* eslint-disable */
// BEGIN

function sM(a) {
    var b;
    if (null !== yr)
        b = yr;
    else {
        b = wr(String.fromCharCode(84));
        var c = wr(String.fromCharCode(75));
        b = [b(), b()];
        b[1] = c();
        b = (yr = window[b.join(c())] || "") || ""
    }
    var d = wr(String.fromCharCode(116))
        , c = wr(String.fromCharCode(107))
        , d = [d(), d()];
    d[1] = c();
    c = "&" + d.join("") + "=";
    d = b.split(".");
    b = Number(d[0]) || 0;
    for (var e = [], f = 0, g = 0; g < a.length; g++) {
        var l = a.charCodeAt(g);
        128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023),
            e[f++] = l >> 18 | 240,
            e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224,
            e[f++] = l >> 6 & 63 | 128),
            e[f++] = l & 63 | 128)
    }
    a = b;
    for (f = 0; f < e.length; f++)
        a += e[f],
            a = xr(a, "+-a^+6");
    a = xr(a, "+-3^+b+-f");
    a ^= Number(d[1]) || 0;
    0 > a && (a = (a & 2147483647) + 2147483648);
    a %= 1E6;
    return c + (a.toString() + "." + (a ^ b))
}

var yr = null;
var wr = function(a) {
    return function() {
        return a
    }
}
    , xr = function(a, b) {
    for (var c = 0; c < b.length - 2; c += 3) {
        var d = b.charAt(c + 2)
            , d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d)
            , d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
        a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
    }
    return a
};

// END
/* eslint-enable */

var window = {
    TKK: settings.get('TKK') || '0'
};

async function updateTKK() {
    return new Promise(async function (resolve, reject) {
        var now = Math.floor(Date.now() / 3600000)

        if (Number(window.TKK.split('.')[0]) === now) {
            resolve()
        } else {
            try {
                const res = await axios({
                    method: 'get',
                    url: 'https://translate.google.com'
                })
                var code = res.data.match(/(TKK=').*?(?=;)/g)
                var TKK
                if (code) {
                    TKK = code[0].slice(5, -1)
                    window.TKK = TKK;
                    settings.set('TKK', TKK)
                }
                resolve()
            } catch (err) {
                console.error(`updateTKK:\n${err}`)
                reject(err)
            }
        }
    });
}

export default function getToken(text) {
    return updateTKK().then(function () {
        var tk = sM(text);
        tk = tk.replace('&tk=', '');
        return { name: 'tk', value: tk };
    }).catch(function (err) {
        throw err;
    });
}
<commit_msg>get token<commit_after>/**
 * Last update: 2016/06/26
 * https://translate.google.com/translate/releases/twsfe_w_20160620_RC00/r/js/desktop_module_main.js
 *
 * Everything between 'BEGIN' and 'END' was copied from the url above.
 */

import settings from 'electron-settings'
import axios from 'axios'

/* eslint-disable */
// BEGIN

function sM(a) {
    var b;
    if (null !== yr)
        b = yr;
    else {
        b = wr(String.fromCharCode(84));
        var c = wr(String.fromCharCode(75));
        b = [b(), b()];
        b[1] = c();
        b = (yr = window[b.join(c())] || "") || ""
    }
    var d = wr(String.fromCharCode(116))
        , c = wr(String.fromCharCode(107))
        , d = [d(), d()];
    d[1] = c();
    c = "&" + d.join("") + "=";
    d = b.split(".");
    b = Number(d[0]) || 0;
    for (var e = [], f = 0, g = 0; g < a.length; g++) {
        var l = a.charCodeAt(g);
        128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023),
            e[f++] = l >> 18 | 240,
            e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224,
            e[f++] = l >> 6 & 63 | 128),
            e[f++] = l & 63 | 128)
    }
    a = b;
    for (f = 0; f < e.length; f++)
        a += e[f],
            a = xr(a, "+-a^+6");
    a = xr(a, "+-3^+b+-f");
    a ^= Number(d[1]) || 0;
    0 > a && (a = (a & 2147483647) + 2147483648);
    a %= 1E6;
    return c + (a.toString() + "." + (a ^ b))
}

var yr = null;
var wr = function(a) {
    return function() {
        return a
    }
}
    , xr = function(a, b) {
    for (var c = 0; c < b.length - 2; c += 3) {
        var d = b.charAt(c + 2)
            , d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d)
            , d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
        a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
    }
    return a
};

// END
/* eslint-enable */

var window = {
    TKK: settings.get('TKK') || '0'
};

async function updateTKK() {
    return new Promise(async function (resolve, reject) {
        var now = Math.floor(Date.now() / 3600000)

        if (Number(window.TKK.split('.')[0]) === now) {
            resolve()
        } else {
            try {
                const res = await axios({
                    method: 'get',
                    url: 'https://translate.google.com'
                })
                var code = res.data.match(/(tkk:').*?(?=,)/g)
                var TKK
                if (code) {
                    TKK = code[0].slice(5, -1)
                    window.TKK = TKK;
                    settings.set('TKK', TKK)
                }
                resolve()
            } catch (err) {
                console.error(`updateTKK:\n${err}`)
                reject(err)
            }
        }
    });
}

export default function getToken(text) {
    return updateTKK().then(function () {
        var tk = sM(text);
        tk = tk.replace('&tk=', '');
        return { name: 'tk', value: tk };
    }).catch(function (err) {
        throw err;
    });
}
<|endoftext|>


<commit_before>/**
 * abstract base class for dynform fields
 *
 * @param {object} field_descriptor field specific part of the form schema
 * @param {object} field_data initial value for the field
 * @constructor
 **/
schnipp.dynforms.abstract_field = function(field_descriptor, field_data, parent_dynform) {
    var self = {}
    self.default_value = '' /* override this in subclass */
    self.field_descriptor = field_descriptor
    self.initial_data = field_data
    self.events = schnipp.events.event_support()

    self.templates = {
        main: _.template('\
            <div class="schnippforms-field-holder schnippforms-field-<%=name%> schnippforms-<%=type%> <%=extra_classes%>" >\

\
        '),
        errorlist: '

'
    }
    self.dom = {main:null}

    /**
     * renders a field in a container with the field label
     *
     * @param {object} field_descriptor the field`s schema
     * @param {object} rendered_field jquery nodelist of the rendered field view
     * @returns {object} jquery nodelist containing rendered field view
     * @name schnipp.dynforms.abstract_field#render_container
     **/
    self.render_container = function(field_descriptor, rendered_field) {

        if (field_descriptor.extra_classes == undefined)
            field_descriptor.extra_classes = ''

        var main = $(self.templates.main({
            name: field_descriptor.name,
            type: field_descriptor.type,
            extra_classes: field_descriptor.extra_classes
        }))

        if (field_descriptor.classes !== undefined)
            $.each(field_descriptor.classes, function(i, cls) {main.addClass(cls)})

        // label
        if (field_descriptor.label !== undefined) {
            var label = $('').text(field_descriptor.label)
            main.append(label)
            if (field_descriptor.required)
               label.addClass('schnippforms-required')
        }

        // field
        main.append(rendered_field)

        // dsc
        if (field_descriptor.description !== undefined)
            main.append($('

').text(field_descriptor.description))

        return main
    }

    /**
     * render the input portion of the field
     *
     * @returns {object} jquery nodelist containing input portion of rendered field view
     *
     * must be implemented by subclass
     *
     * @name schnipp.dynforms.abstract_field#render_input
     **/
    self.render_input = function() {
        throw {
            message: "get_data not implemented by abstract base class!"
        }
    }

    self.hide = function() {
        self.dom.main.hide()
    }

    self.show = function() {
        self.dom.main.show()
    }

    /**
     * render the form
     * @returns {object} jquery nodelist containing rendered field
     * @name schnipp.dynforms.abstract_field#render
     **/
    self.render = function() {
        self.dom.main = self.render_container(
            self.field_descriptor,
            self.render_input()
        )
        return self.dom.main
    }

    /**
     * get current field data
     * @returns {?} field data - the format of the data depends on the
     * field type
     *
     * must be implemented by subclass
     *
     * @name schnipp.dynforms.abstract_field#get_data
     **/
    self.get_data = function() {
        throw {
            message: "get_data not implemented by abstract base class!"
        }
    }

    /**
     * reset field`s data to the default value
     * @name schnipp.dynforms.abstract_field#clear
     **/
    self.clear = function() {
        self.set_data(self.get_default_data())
    }

    /**
     * Returns the field's default data
     *
     * Default data is the value of 'default_value' in the field`s schema.
     * If it is not set, field.default_value is used.
     * @name schnipp.dynforms.abstract_field#get_default_data
     **/
    self.get_default_data = function() {
        if (self.field_descriptor.default_value !== undefined) {
            return self.field_descriptor.default_value
        } else {
            return self.default_value
        }
    }

    /**
     * Returns the field's initial data or the default data if no initial data has been given.
     * @name schnipp.dynforms.abstract_field#get_initial_data
     **/
    self.get_initial_data = function() {
        if (self.initial_data !== undefined) {
            return self.initial_data
        } else {
            return self.get_default_data()
        }
    }

    /**
     * set data of the field
     * used internally by set_data to actually set the field
     *
     * must be implemented in subclass
     *
     * @param {?} field data - format depends on the field type
     * @name schnipp.dynforms.abstract_field#_set
     **/
    self._set = function(value) {
        throw {
            message: "_set not implemented by abstract base class!"
        }
    }

    /**
     * set data of the field
     * @param {?} field data - format depends on the field type
     * @name schnipp.dynforms.abstract_field#set_data
     **/
    self.set_data = function(value) {
        var old_value = self.get_data()
        self._set(value)
        self.events.fire('change', {
            src: self,
            value: value,
            old_value: old_value
        })
    }

    /**
     * validates the field. Override this method in subclasses to add
     * specific validation to fields. This implementation checks
     * that required fields contain a value.
     * @returns {object} validation result
     * @name schnipp.dynforms.abstract_field#validate
     **/
    self.validate = function() {
        if (self.field_descriptor.required) {
            if ($.trim(self.get_data()) == '') {
                return {
                    valid: false,
                    errors: {
                        required: 'This field is required'
                    }
                }
            }
        }
        return {valid: true}
    }

    /**
    *   Removes the errorlist from dom and all error classes.
    */
    self.render_valid = function() {
        if (self.dom.errorlist)
            self.dom.errorlist.remove()
        self.dom.main.removeClass('schnippforms-error')
    }

    self.render_errors = function(errors) {
        if (self.dom.errorlist)
            self.dom.errorlist.remove()
        if (self.dom.main) {
            self.dom.errorlist = $(self.templates.errorlist)
            self.dom.main.append(self.dom.errorlist)
            self.dom.errorlist.empty()
            $.each(errors, function(index, value) {
                self.dom.errorlist.append($(
                    '

'
                ).text(value))
            })
            self.dom.main.addClass('schnippforms-error')
            self.dom.main.animate({opacity: 0.5}, 500).animate({opacity: 1}, 500)
        }
    }

    /**
     * triggers field validation
     * @returns {object} validation result
     * @name schnipp.dynforms.abstract_field#do_validate
     **/
    self.do_validate = function() {
        var validation_result = self.validate()
        if (validation_result.valid) {
            self.render_valid()
        } else {
            self.render_errors(validation_result.errors)
        }
        return validation_result
    }

    /**
     * Must be implemented by the concrete subclass and trigger the (dom) focus event.
     * Make sure in this context, initialize alsp triggers self.events.fire('focus', {field: self})
     * @name schnipp.dynforms.abstract_field#focus
     **/
    self.set_focus = function(bool) {

    }

    /**
    *   Returns the root form, which is in case of nested form structures
    *   the most outer form.
    */
    self.get_root_form = function() {
        if (parent_dynform.get_root_form != undefined) {
            return parent_dynform.get_root_form()
        } else {
            return parent_dynform
        }
    }

    /**
     * initialize the field - must be called after the field has been rendered
     * and placed into the DOM of the page.
     * @name schnipp.dynforms.abstract_field#initialize
     **/
    self.initialize = function() {

    }

    return self
}
<commit_msg>introduced help text rendering<commit_after>/**
 * abstract base class for dynform fields
 *
 * @param {object} field_descriptor field specific part of the form schema
 * @param {object} field_data initial value for the field
 * @constructor
 **/
schnipp.dynforms.abstract_field = function(field_descriptor, field_data, parent_dynform) {
    var self = {}
    self.default_value = '' /* override this in subclass */
    self.field_descriptor = field_descriptor
    self.initial_data = field_data
    self.events = schnipp.events.event_support()

    self.templates = {
        main: _.template('\
            <div class="schnippforms-field-holder schnippforms-field-<%=name%> schnippforms-<%=type%> <%=extra_classes%>" >\

\
        '),
        errorlist: '

'
    }
    self.dom = {main:null}

    /**
     * renders a field in a container with the field label
     *
     * @param {object} field_descriptor the field`s schema
     * @param {object} rendered_field jquery nodelist of the rendered field view
     * @returns {object} jquery nodelist containing rendered field view
     * @name schnipp.dynforms.abstract_field#render_container
     **/
    self.render_container = function(field_descriptor, rendered_field) {

        if (field_descriptor.extra_classes == undefined)
            field_descriptor.extra_classes = ''

        var main = $(self.templates.main(field_descriptor))

        if (field_descriptor.classes !== undefined)
            $.each(field_descriptor.classes, function(i, cls) {main.addClass(cls)})

        // label
        if (field_descriptor.label !== undefined) {
            var label = $('').text(field_descriptor.label)
            main.append(label)
            if (field_descriptor.required)
               label.addClass('schnippforms-required')
        }

        // dsc
        if (field_descriptor.help_text !== undefined)
            main.append($('

').text(field_descriptor.help_text))

        // field
        main.append(rendered_field)

        // dsc
        if (field_descriptor.description !== undefined)
            main.append($('

').text(field_descriptor.description))

        return main
    }

    /**
     * render the input portion of the field
     *
     * @returns {object} jquery nodelist containing input portion of rendered field view
     *
     * must be implemented by subclass
     *
     * @name schnipp.dynforms.abstract_field#render_input
     **/
    self.render_input = function() {
        throw {
            message: "get_data not implemented by abstract base class!"
        }
    }

    self.hide = function() {
        self.dom.main.hide()
    }

    self.show = function() {
        self.dom.main.show()
    }

    /**
     * render the form
     * @returns {object} jquery nodelist containing rendered field
     * @name schnipp.dynforms.abstract_field#render
     **/
    self.render = function() {
        self.dom.main = self.render_container(
            self.field_descriptor,
            self.render_input()
        )
        return self.dom.main
    }

    /**
     * get current field data
     * @returns {?} field data - the format of the data depends on the
     * field type
     *
     * must be implemented by subclass
     *
     * @name schnipp.dynforms.abstract_field#get_data
     **/
    self.get_data = function() {
        throw {
            message: "get_data not implemented by abstract base class!"
        }
    }

    /**
     * reset field`s data to the default value
     * @name schnipp.dynforms.abstract_field#clear
     **/
    self.clear = function() {
        self.set_data(self.get_default_data())
    }

    /**
     * Returns the field's default data
     *
     * Default data is the value of 'default_value' in the field`s schema.
     * If it is not set, field.default_value is used.
     * @name schnipp.dynforms.abstract_field#get_default_data
     **/
    self.get_default_data = function() {
        if (self.field_descriptor.default_value !== undefined) {
            return self.field_descriptor.default_value
        } else {
            return self.default_value
        }
    }

    /**
     * Returns the field's initial data or the default data if no initial data has been given.
     * @name schnipp.dynforms.abstract_field#get_initial_data
     **/
    self.get_initial_data = function() {
        if (self.initial_data !== undefined) {
            return self.initial_data
        } else {
            return self.get_default_data()
        }
    }

    /**
     * set data of the field
     * used internally by set_data to actually set the field
     *
     * must be implemented in subclass
     *
     * @param {?} field data - format depends on the field type
     * @name schnipp.dynforms.abstract_field#_set
     **/
    self._set = function(value) {
        throw {
            message: "_set not implemented by abstract base class!"
        }
    }

    /**
     * set data of the field
     * @param {?} field data - format depends on the field type
     * @name schnipp.dynforms.abstract_field#set_data
     **/
    self.set_data = function(value) {
        var old_value = self.get_data()
        self._set(value)
        self.events.fire('change', {
            src: self,
            value: value,
            old_value: old_value
        })

        if ( field_descriptor.fetch_further ) {
            var root_form = self.get_root_form()
            $.each( field_descriptor.fetch_further, function(idx, fieldname) {
                root_form.fields[fieldname].call_remote()
            } )
        }
    }

    /**
     * validates the field. Override this method in subclasses to add
     * specific validation to fields. This implementation checks
     * that required fields contain a value.
     * @returns {object} validation result
     * @name schnipp.dynforms.abstract_field#validate
     **/
    self.validate = function() {
        if (self.field_descriptor.required) {
            if ($.trim(self.get_data()) == '') {
                return {
                    valid: false,
                    errors: {
                        required: 'This field is required'
                    }
                }
            }
        }
        return {valid: true}
    }

    /**
    *   Removes the errorlist from dom and all error classes.
    */
    self.render_valid = function() {
        if (self.dom.errorlist)
            self.dom.errorlist.remove()
        self.dom.main.removeClass('schnippforms-error')
    }

    self.render_errors = function(errors) {
        if (self.dom.errorlist)
            self.dom.errorlist.remove()
        if (self.dom.main) {
            self.dom.errorlist = $(self.templates.errorlist)
            self.dom.main.append(self.dom.errorlist)
            self.dom.errorlist.empty()
            $.each(errors, function(index, value) {
                self.dom.errorlist.append($(
                    '

'
                ).text(value))
            })
            self.dom.main.addClass('schnippforms-error')
            self.dom.main.animate({opacity: 0.5}, 500).animate({opacity: 1}, 500)
        }
    }

    /**
     * triggers field validation
     * @returns {object} validation result
     * @name schnipp.dynforms.abstract_field#do_validate
     **/
    self.do_validate = function() {
        var validation_result = self.validate()
        if (validation_result.valid) {
            self.render_valid()
        } else {
            self.render_errors(validation_result.errors)
        }
        return validation_result
    }

    /**
     * Must be implemented by the concrete subclass and trigger the (dom) focus event.
     * Make sure in this context, initialize alsp triggers self.events.fire('focus', {field: self})
     * @name schnipp.dynforms.abstract_field#focus
     **/
    self.set_focus = function(bool) {

    }

    /**
    *   Returns the root form, which is in case of nested form structures
    *   the most outer form.
    */
    self.get_root_form = function() {
        if (parent_dynform.get_root_form != undefined) {
            return parent_dynform.get_root_form()
        } else {
            return parent_dynform
        }
    }

    /**
     * initialize the field - must be called after the field has been rendered
     * and placed into the DOM of the page.
     * @name schnipp.dynforms.abstract_field#initialize
     **/
    self.initialize = function() {

    }

    return self
}
<|endoftext|>


<commit_before>'use strict';

var _ = require('underscore');

var auth = require('app/util/auth');
var user_config = require('app/config/user');
var logger_module = require('app/util/logger');
var logger = logger_module.get('app/api/session/router_impl');

//var keys_required_for_login = [user_config.local_auth.username_field, user_config.local_auth.password_field];
var keys_required_for_login = [user_config.local_auth.username_field, user_config.local_auth.password_field];
var keys_required_for_signup = keys_required_for_login.concat(
  _.map(keys_required_for_login, function(field) { return field + '_check'; })
);

module.exports = {
  /**
   * Returns user description - assumes that the requester must be logged in to access this API endpoint
   */
  get_user: function get_user(pr, req, res, next) {
    var result = {
      local_email: req.user.local_email,
      signup_date: req.user.sq_created_at,
      facebook_email: req.user.facebook_email,
      facebook_name: req.user.facebook_name,
      twitter_username: req.user.twitter_username,
      twitter_name: req.user.twitter_name,
      google_name: req.user.google_name,
      google_email: req.user.google_email
    };
    res.status(200).send(result);
  },

  /**
   * Logs user out and destroys session (the logic for this: if they're logging out then in user's mind this session
   * is over)
   */
  logout: function logout(req, res, next) {
    req.logout();
    res.clearCookie(user_config.logged_in_cookie_name);
    req.session.destroy(function() {
      // No req.flash message because we just destroyed the session: req.flash('message', 'Logged out');
      res.redirect('/api/util/success');
    });
  },

  /**
   * Initiates requests for Google authentication, using passport to redirect to Google - this API endpoint should
   * be access directly by the browser, not via AJAX
   * @type {Function}
   */
  access_google_auth: function access_google_auth(req, res, next) {
    logger.debug('exports.access_google_auth -- redir request to FB (display mode: ' + req.query.diplay + ')');
    (auth.passport.authenticate('google-auth', {
      scope: ['profile', 'email'],
      display: req.query.display
    }))(req, res, next);
  },

  /**
   * Completes requests for Google authentication
   * @type {Function}
   */
  access_google_callback: auth.passport.authenticate('google-auth', {
    successRedirect: '/profile',
    failureRedirect: '/access?reason=google_declined',
    failureFlash: true
  }),

  /**
   * Initiates requests for Facebook authentication, using passport to redirect to Facebook - this API endpoint should
   * be access directly by the browser, not via AJAX
   * @type {Function}
   */
  access_facebook_auth: function access_facebook_auth(req, res, next) {
    logger.debug('exports.access_facebook_auth -- redir request to FB (display mode: ' + req.query.display + ')');
    (auth.passport.authenticate('facebook-auth', {
      scope: ['public_profile', 'email'],
      display: req.query.display
    }))(req, res, next);
  },

  /**
   * Completes requests for Facebook authentication
   * @type {Function}
   */
  access_facebook_callback: auth.passport.authenticate('facebook-auth', {
    successRedirect: '/profile',
    failureRedirect: '/access?reason=fb_declined',
    failureFlash: true
  }),

  /**
   * Passport.js redirects without explanation on failure, this middleware should be run first to check that the
   * fields expected by the authentication strategy for local login are present - log if not
   */
  access_local_check_login_post: auth.mw_gen.check_post_has_req_fields(keys_required_for_login),

  /**
   * Passport.js redirects without explanation on failure, this middleware should be run first to check that the
   * fields expected by the authentication strategy for local signup are present - log if not
   */
  access_local_check_login_signup: auth.mw_gen.check_post_has_req_fields(keys_required_for_signup),

  /**
   * Handles requests for local access account login
   * @type {Function}
   */
  access_local_login: auth.passport.authenticate('local-login', {
    successRedirect: '/api/util/success',
    failureRedirect: '/api/util/failure',
    failureFlash: true
  }),

  /**
   * Handles requests for local access account signup
   * @type {Function}
   */
  access_local_signup: auth.passport.authenticate('local-signup', {
    successRedirect: '/api/util/success',
    failureRedirect: '/api/util/failure',
    failureFlash: true
  }),

  /**
   * Initiates requests for Twitter authentication, using passport to redirect to Twitter - this API endpoint should
   * be access directly by the browser, not via AJAX
   * @type {Function}
   */
  access_twitter_auth: auth.passport.authenticate('twitter-auth'),

  /**
   * Completes request for Twitter authentication
   * @type {Function}
   */
  access_twitter_callback: auth.passport.authenticate('twitter-auth', {
    successRedirect: '/profile',
    failureRedirect: '/access?reason=twitter_declined',
    failureFlash: true
  })
};
<commit_msg>server/app/api/user/router_impl.js - comment typo bug fix<commit_after>'use strict';

var _ = require('underscore');

var auth = require('app/util/auth');
var user_config = require('app/config/user');
var logger_module = require('app/util/logger');
var logger = logger_module.get('app/api/session/router_impl');

//var keys_required_for_login = [user_config.local_auth.username_field, user_config.local_auth.password_field];
var keys_required_for_login = [user_config.local_auth.username_field, user_config.local_auth.password_field];
var keys_required_for_signup = keys_required_for_login.concat(
  _.map(keys_required_for_login, function(field) { return field + '_check'; })
);

module.exports = {
  /**
   * Returns user description - assumes that the requester must be logged in to access this API endpoint
   */
  get_user: function get_user(pr, req, res, next) {
    var result = {
      local_email: req.user.local_email,
      signup_date: req.user.sq_created_at,
      facebook_email: req.user.facebook_email,
      facebook_name: req.user.facebook_name,
      twitter_username: req.user.twitter_username,
      twitter_name: req.user.twitter_name,
      google_name: req.user.google_name,
      google_email: req.user.google_email
    };
    res.status(200).send(result);
  },

  /**
   * Logs user out and destroys session (the logic for this: if they're logging out then in user's mind this session
   * is over)
   */
  logout: function logout(req, res, next) {
    req.logout();
    res.clearCookie(user_config.logged_in_cookie_name);
    req.session.destroy(function() {
      // No req.flash message because we just destroyed the session: req.flash('message', 'Logged out');
      res.redirect('/api/util/success');
    });
  },

  /**
   * Initiates requests for Google authentication, using passport to redirect to Google - this API endpoint should
   * be access directly by the browser, not via AJAX
   * @type {Function}
   */
  access_google_auth: function access_google_auth(req, res, next) {
    logger.debug('exports.access_google_auth -- redir request to Google (display mode: ' + req.query.diplay + ')');
    (auth.passport.authenticate('google-auth', {
      scope: ['profile', 'email'],
      display: req.query.display
    }))(req, res, next);
  },

  /**
   * Completes requests for Google authentication
   * @type {Function}
   */
  access_google_callback: auth.passport.authenticate('google-auth', {
    successRedirect: '/profile',
    failureRedirect: '/access?reason=google_declined',
    failureFlash: true
  }),

  /**
   * Initiates requests for Facebook authentication, using passport to redirect to Facebook - this API endpoint should
   * be access directly by the browser, not via AJAX
   * @type {Function}
   */
  access_facebook_auth: function access_facebook_auth(req, res, next) {
    logger.debug('exports.access_facebook_auth -- redir request to FB (display mode: ' + req.query.display + ')');
    (auth.passport.authenticate('facebook-auth', {
      scope: ['public_profile', 'email'],
      display: req.query.display
    }))(req, res, next);
  },

  /**
   * Completes requests for Facebook authentication
   * @type {Function}
   */
  access_facebook_callback: auth.passport.authenticate('facebook-auth', {
    successRedirect: '/profile',
    failureRedirect: '/access?reason=fb_declined',
    failureFlash: true
  }),

  /**
   * Passport.js redirects without explanation on failure, this middleware should be run first to check that the
   * fields expected by the authentication strategy for local login are present - log if not
   */
  access_local_check_login_post: auth.mw_gen.check_post_has_req_fields(keys_required_for_login),

  /**
   * Passport.js redirects without explanation on failure, this middleware should be run first to check that the
   * fields expected by the authentication strategy for local signup are present - log if not
   */
  access_local_check_login_signup: auth.mw_gen.check_post_has_req_fields(keys_required_for_signup),

  /**
   * Handles requests for local access account login
   * @type {Function}
   */
  access_local_login: auth.passport.authenticate('local-login', {
    successRedirect: '/api/util/success',
    failureRedirect: '/api/util/failure',
    failureFlash: true
  }),

  /**
   * Handles requests for local access account signup
   * @type {Function}
   */
  access_local_signup: auth.passport.authenticate('local-signup', {
    successRedirect: '/api/util/success',
    failureRedirect: '/api/util/failure',
    failureFlash: true
  }),

  /**
   * Initiates requests for Twitter authentication, using passport to redirect to Twitter - this API endpoint should
   * be access directly by the browser, not via AJAX
   * @type {Function}
   */
  access_twitter_auth: auth.passport.authenticate('twitter-auth'),

  /**
   * Completes request for Twitter authentication
   * @type {Function}
   */
  access_twitter_callback: auth.passport.authenticate('twitter-auth', {
    successRedirect: '/profile',
    failureRedirect: '/access?reason=twitter_declined',
    failureFlash: true
  })
};
<|endoftext|>


<commit_before>var events = require('events');
var net = require('net');

var listener = module.exports = function listener(port){

    var _this = this;

    var emitLog = function(text){
        _this.emit('log', text);
    };

    this.start = function(){
        net.createServer(function(c) {

            var data = '';
            try {
                c.on('data', function (d) {
                    data += d;
                    if (data.slice(-1) === '\n') {
                        var message = JSON.parse(data);
                        _this.emit('command', message.command, message.params, message.options, function(message){
                            c.end(message);
                        });
                    }
                });
                c.on('end', function () {

                });
            }
            catch(e){
                emitLog('CLI listener failed to parse message ' + data);
            }

        }).listen(port, '127.0.0.1', function() {
            emitLog('CLI listening on port ' + port)
        });
    }

};

listener.prototype.__proto__ = events.EventEmitter.prototype;
<commit_msg>Update cliListener.js<commit_after>var events = require('events');
var net = require('net');

var listener = module.exports = function listener(port){

    var _this = this;

    var emitLog = function(text){
        _this.emit('log', text);
    };

    this.start = function(){
        net.createServer(function(c) {

            var data = '';
            try {
                c.on('data', function (d) {
                    data += d;
                    if (data.slice(-1) === '\n') {
                        var message = JSON.parse(data);
                        _this.emit('command', message.command, message.params, message.options, function(message){
                            c.end(message);
                        });
                    }
                });
                c.on('end', function () {

                });
                c.on('error', function () {

                });
            }
            catch(e){
                emitLog('CLI listener failed to parse message ' + data);
            }

        }).listen(port, '127.0.0.1', function() {
            emitLog('CLI listening on port ' + port)
        });
    }

};

listener.prototype.__proto__ = events.EventEmitter.prototype;
<|endoftext|>


<commit_before>import fetch from 'node-fetch'
import FormData from 'form-data'
import { URL } from 'url'
import NodeVaultClient from 'cozy-keys-lib/transpiled/NodeVaultClient'
import CozyClient from 'cozy-client'
import logger from 'cozy-logger'

import updateAccountsPassword from 'cozy-harvest-lib/dist/services/updateAccountsPassword'

const log = logger.namespace('updateAccounts')

global.fetch = fetch
global.Headers = fetch.Headers
global.Response = fetch.Response
global.Request = fetch.Request
global.FormData = FormData
global.URL = URL

const main = async () => {
  const vaultClient = new NodeVaultClient(process.env.COZY_URL)

  const cozyClient = CozyClient.fromEnv()

  try {
    await updateAccountsPassword(
      cozyClient,
      vaultClient,
      JSON.parse(process.env.COZY_COUCH_DOC)
    )
  } catch (err) {
    if (err.message === 'DECRYPT_FAILED') {
      log(
        'warning',
        'Login/password decrypt failed. The cipher may not be shared with the Cozy organization'
      )
    } else {
      throw err
    }
  }
}
;(async () => {
  try {
    await main()
  } catch (error) {
    log('critical', error.message)
  }
})()
<commit_msg>refactor(updateAccounts): Override globals only if needed<commit_after>import fetch from 'node-fetch'
import FormData from 'form-data'
import { URL } from 'url'
import NodeVaultClient from 'cozy-keys-lib/transpiled/NodeVaultClient'
import CozyClient from 'cozy-client'
import logger from 'cozy-logger'

import updateAccountsPassword from 'cozy-harvest-lib/dist/services/updateAccountsPassword'

const log = logger.namespace('updateAccounts')

if (global) {
  global.fetch = global.fetch || fetch
  global.Headers = global.Headers || fetch.Headers
  global.Response = global.Response || fetch.Response
  global.Request = global.Request || fetch.Request
  global.FormData = global.FormData || FormData
  global.URL = global.URL || URL
}

const main = async () => {
  const vaultClient = new NodeVaultClient(process.env.COZY_URL)

  const cozyClient = CozyClient.fromEnv()

  try {
    await updateAccountsPassword(
      cozyClient,
      vaultClient,
      JSON.parse(process.env.COZY_COUCH_DOC)
    )
  } catch (err) {
    if (err.message === 'DECRYPT_FAILED') {
      log(
        'warning',
        'Login/password decrypt failed. The cipher may not be shared with the Cozy organization'
      )
    } else {
      throw err
    }
  }
}
;(async () => {
  try {
    await main()
  } catch (error) {
    log('critical', error.message)
  }
})()
<|endoftext|>


<commit_before>import assert from 'assert';
import { shuffle } from 'lodash';

import { ARMY_COLORS, PARAMETERS } from '../consts';
import NamingMixin from '../mixins/NamingMixin';
import Model from './Model';
import { unitResourceDict, unitTypeIds } from './units';

class PrototypeArmyModel extends Model {}
Object.assign(PrototypeArmyModel.prototype, NamingMixin);

export default class ArmyModel extends PrototypeArmyModel {

  /*
   * @param {Array<string>} unitDeck - A list of UnitModel's typeId
   */
  constructor({ name = null, color, unitDeck }) {
    super();

    this._name = name || 'No Name';
    this._color = color;
    this._battlers = this._createBattlers(unitDeck);
  }

  get color() { return this._color; }

  _createBattlers(unitDeck) {
    unitDeck.forEach(typeId => assert(unitTypeIds.indexOf(typeId) !== -1, `${ typeId } is not a unitTypeId`));

    return shuffle(unitDeck)
      .map(typeId => unitResourceDict[typeId].beBornAsBattler({ belongingArmy: this }))
    ;
  }

  _findUnplacedBattlers() {
    return this._battlers.filter(battler => !battler.isPlaced());
  }

  _getVisibleBattlers() {
    return this._findUnplacedBattlers().slice(0, PARAMETERS.MAX_VISIBLE_BATTLER_COUNT);
  }

  getNextBattler() {
    return this._findUnplacedBattlers()[0] || null;
  }

  presentProps() {
    return {
      name: this.getName(),
      score: 99,  // TODO
      visibleBattlers: this._getVisibleBattlers().map(battler => battler.presentProps()),
    };
  }
}
<commit_msg>Make to calculate score<commit_after>import assert from 'assert';
import { shuffle } from 'lodash';

import { ARMY_COLORS, PARAMETERS } from '../consts';
import NamingMixin from '../mixins/NamingMixin';
import Model from './Model';
import { unitResourceDict, unitTypeIds } from './units';

class PrototypeArmyModel extends Model {}
Object.assign(PrototypeArmyModel.prototype, NamingMixin);

export default class ArmyModel extends PrototypeArmyModel {

  /*
   * @param {Array<string>} unitDeck - A list of UnitModel's typeId
   */
  constructor({ name = null, color, unitDeck }) {
    super();

    this._name = name || 'No Name';
    this._color = color;
    this._battlers = this._createBattlers(unitDeck);
  }

  get color() { return this._color; }

  _createBattlers(unitDeck) {
    unitDeck.forEach(typeId => assert(unitTypeIds.indexOf(typeId) !== -1, `${ typeId } is not a unitTypeId`));

    return shuffle(unitDeck)
      .map(typeId => unitResourceDict[typeId].beBornAsBattler({ belongingArmy: this }))
    ;
  }

  _findPlacedBattlers() {
    return this._battlers.filter(battler => battler.isPlaced());
  }

  _findUnplacedBattlers() {
    return this._battlers.filter(battler => !battler.isPlaced());
  }

  _getVisibleBattlers() {
    return this._findUnplacedBattlers().slice(0, PARAMETERS.MAX_VISIBLE_BATTLER_COUNT);
  }

  getNextBattler() {
    return this._findUnplacedBattlers()[0] || null;
  }

  _calculateScore() {
    return this._findPlacedBattlers().filter(battler => battler.isAlive()).length;
  }

  presentProps() {
    return {
      name: this.getName(),
      score: this._calculateScore(),
      visibleBattlers: this._getVisibleBattlers().map(battler => battler.presentProps()),
    };
  }
}
<|endoftext|>


<commit_before>"use strict";

const log = require("libnpm/log");
const runScript = require("libnpm/run-script");
const npmConf = require("@lerna/npm-conf");

module.exports = runLifecycle;
module.exports.createRunner = createRunner;

function runLifecycle(pkg, stage, opts) {
  log.silly("run-lifecycle", stage, pkg.name);

  const config = {};
  const dir = pkg.location;

  // https://github.com/isaacs/proto-list/blob/27764cd/proto-list.js#L29
  for (const key of opts.keys) {
    const val = opts.get(key);

    if (val != null) {
      config[key] = val;
    }
  }

  // env.npm_config_prefix should be the package directory
  config.prefix = dir;

  // TODO: remove pkg._id when npm-lifecycle no longer relies on it
  pkg._id = `${pkg.name}@${pkg.version}`; // eslint-disable-line

  return runScript(pkg, stage, dir, {
    config,
    dir,
    failOk: false,
    log,
    unsafePerm: true,
  }).then(
    () => pkg,
    err => {
      // propagate the exit code
      const exitCode = err.errno || 1;

      // error logging has already occurred on stderr, but we need to stop the chain
      log.error("lifecycle", "%j errored in %j, exiting %d", stage, pkg.name, exitCode);

      // ensure clean logging, avoiding spurious log dump
      err.name = "ValidationError";

      // our yargs.fail() handler expects a numeric .code, not .errno
      err.code = exitCode;
      process.exitCode = exitCode;

      // stop the chain
      throw err;
    }
  );
}

function createRunner(commandOptions) {
  const cfg = npmConf(commandOptions);

  return (pkg, stage) => {
    if (pkg.scripts && pkg.scripts[stage]) {
      return runLifecycle(pkg, stage, cfg);
    }

    return Promise.resolve(pkg);
  };
}
<commit_msg>fix(run-lifecycle): Omit circular options from config<commit_after>"use strict";

const log = require("libnpm/log");
const runScript = require("libnpm/run-script");
const npmConf = require("@lerna/npm-conf");

module.exports = runLifecycle;
module.exports.createRunner = createRunner;

function runLifecycle(pkg, stage, opts) {
  log.silly("run-lifecycle", stage, pkg.name);

  const config = {};
  const dir = pkg.location;

  // https://github.com/isaacs/proto-list/blob/27764cd/proto-list.js#L29
  for (const key of opts.keys) {
    const val = opts.get(key);

    // omit falsy and Stream-based (circular) values
    if (val != null && key !== "logstream" && key !== "log") {
      config[key] = val;
    }
  }

  // env.npm_config_prefix should be the package directory
  config.prefix = dir;

  // TODO: remove pkg._id when npm-lifecycle no longer relies on it
  pkg._id = `${pkg.name}@${pkg.version}`; // eslint-disable-line

  return runScript(pkg, stage, dir, {
    config,
    dir,
    failOk: false,
    log,
    unsafePerm: true,
  }).then(
    () => pkg,
    err => {
      // propagate the exit code
      const exitCode = err.errno || 1;

      // error logging has already occurred on stderr, but we need to stop the chain
      log.error("lifecycle", "%j errored in %j, exiting %d", stage, pkg.name, exitCode);

      // ensure clean logging, avoiding spurious log dump
      err.name = "ValidationError";

      // our yargs.fail() handler expects a numeric .code, not .errno
      err.code = exitCode;
      process.exitCode = exitCode;

      // stop the chain
      throw err;
    }
  );
}

function createRunner(commandOptions) {
  const cfg = npmConf(commandOptions);

  return (pkg, stage) => {
    if (pkg.scripts && pkg.scripts[stage]) {
      return runLifecycle(pkg, stage, cfg);
    }

    return Promise.resolve(pkg);
  };
}
<|endoftext|>