<commit_before>import R from "ramda"

//

const warned = {}

const deprecated = message => {
  if (!(message in warned)) {
    warned[message] = message
    console.warn("partial.lenses:", message)
  }
}

//

const empty = {}

const deleteKey = (k, o) => {
  if (o === undefined || !(k in o))
    return o
  let r
  for (const p in o) {
    if (p !== k) {
      if (undefined === r)
        r = {}
      r[p] = o[p]
    }
  }
  return r
}

const setKey = (k, v, o) => {
  if (o === undefined)
    return {[k]: v}
  if (k in o && R.equals(v, o[k]))
    return o
  const r = {[k]: v}
  for (const p in o)
    if (p !== k)
      r[p] = o[p]
  return r
}

//

const dropped = xs => Object.keys(xs).length === 0 ? undefined : xs

//

const toPartial = transform => x => undefined === x ? x : transform(x)

//

const conserve = (c1, c0) => R.equals(c1, c0) ? c0 : c1

const toConserve = f => (y, c0) => conserve(f(y, c0), c0)

//

const snd = (_, c) => c

//

const lift = l => {
  switch (typeof l) {
  case "string": return prop(l)
  case "number": return index(l)
  default:       return l
  }
}

export const compose = (...ls) =>
  ls.length === 0 ? identity :
  ls.length === 1 ? ls[0] :
  R.compose(...ls.map(lift))

export const remove = R.curry((l, s) => R.set(lift(l), undefined, s))

export const removeAll = R.curry((lens, data) => {
  while (get(lens, data) !== undefined)
    data = remove(lens, data)
  return data
})

export const lens = R.lens
export const modify = R.curry((l, x2x, s) => R.over(lift(l), x2x, s))
export const set = R.curry((l, x, s) => R.set(lift(l), x, s))
export const get = R.curry((l, s) => R.view(lift(l), s))

export const choose = x2yL => toFunctor => target => {
  const l = lift(x2yL(target))
  return R.map(focus => R.set(l, focus, target), toFunctor(R.view(l, target)))
}

export const nothing = lens(snd, snd)

export const orElse =
  R.curry((d, l) => choose(x => get(l, x) !== undefined ? l : d))

export const choice = (...ls) => choose(x => {
  const i = ls.findIndex(l => get(l, x) !== undefined)
  return 0 <= i ? ls[i] : nothing
})

export const firstOf = (l, ...ls) =>
  deprecated("`firstOf` has been deprecated --- use `choice` and `orElse`") ||
  orElse(l, choice(l, ...ls))

export const replace = R.curry((inn, out) =>
  R.lens(x => R.equals(x, inn) ? out : x,
         toConserve(y => R.equals(y, out) ? inn : y)))

export const defaults = replace(undefined)
export const required = inn => replace(inn, undefined)
export const define = v => R.compose(required(v), defaults(v))

export const normalize = transform =>
  R.lens(toPartial(transform), toConserve(toPartial(transform)))

export const prop = k =>
  R.lens(o => o && o[k],
         (v, o) => v === undefined ? deleteKey(k, o) : setKey(k, v, o))

export const find = predicate => choose(xs => {
  if (xs === undefined)
    return append
  const i = xs.findIndex(predicate)
  return i < 0 ? append : i
})

export const findWith = (l, ...ls) => {
  const lls = compose(l, ...ls)
  return compose(find(x => R.view(lls, x) !== undefined), lls)
}

export const index = i => R.lens(xs => xs && xs[i], (x, xs) => {
  if (x === undefined) {
    if (xs === undefined)
      return undefined
    if (i < xs.length)
      return dropped(xs.slice(0, i).concat(xs.slice(i+1)))
    return xs
  } else {
    if (xs === undefined)
      return Array(i).concat([x])
    if (xs.length <= i)
      return xs.concat(Array(i - xs.length), [x])
    if (R.equals(x, xs[i]))
      return xs
    return xs.slice(0, i).concat([x], xs.slice(i+1))
  }
})

export const append = R.lens(snd, (x, xs) =>
  x === undefined ? xs : xs === undefined ? [x] : xs.concat([x]))

export const filter = p => R.lens(xs => xs && xs.filter(p), (ys, xs) =>
  conserve(dropped(R.concat(ys || [], (xs || []).filter(R.complement(p)))), xs))

export const augment = template => R.lens(
  toPartial(x => {
    const z = {...x}
    for (const k in template)
      z[k] = template[k](x)
    return z
  }),
  toConserve((y, c) => {
    if (y === undefined)
      return undefined
    let z
    const set = (k, v) => {
      if (undefined === z)
        z = {}
      z[k] = v
    }
    for (const k in y) {
      if (!(k in template))
        set(k, y[k])
      else
        if (k in c)
          set(k, c[k])
    }
    return z
  }))

export const pick = template => R.lens(
  c => {
    let r
    for (const k in template) {
      const v = get(template[k], c)
      if (v !== undefined) {
        if (r === undefined)
          r = {}
        r[k] = v
      }
    }
    return r
  },
  (o = empty, cIn) => {
    let c = cIn
    for (const k in template)
      c = set(template[k], o[k], c)
    return c
  })

export const identity = R.lens(R.identity, conserve)

export const props = (k, ...ks) => {
  const kks = [k, ...ks]
  return pick(R.zipObj(kks, kks))
}

export default compose
<commit_msg>view -> get<commit_after>import R from "ramda"

//

const warned = {}

const deprecated = message => {
  if (!(message in warned)) {
    warned[message] = message
    console.warn("partial.lenses:", message)
  }
}

//

const empty = {}

const deleteKey = (k, o) => {
  if (o === undefined || !(k in o))
    return o
  let r
  for (const p in o) {
    if (p !== k) {
      if (undefined === r)
        r = {}
      r[p] = o[p]
    }
  }
  return r
}

const setKey = (k, v, o) => {
  if (o === undefined)
    return {[k]: v}
  if (k in o && R.equals(v, o[k]))
    return o
  const r = {[k]: v}
  for (const p in o)
    if (p !== k)
      r[p] = o[p]
  return r
}

//

const dropped = xs => Object.keys(xs).length === 0 ? undefined : xs

//

const toPartial = transform => x => undefined === x ? x : transform(x)

//

const conserve = (c1, c0) => R.equals(c1, c0) ? c0 : c1

const toConserve = f => (y, c0) => conserve(f(y, c0), c0)

//

const snd = (_, c) => c

//

const lift = l => {
  switch (typeof l) {
  case "string": return prop(l)
  case "number": return index(l)
  default:       return l
  }
}

export const compose = (...ls) =>
  ls.length === 0 ? identity :
  ls.length === 1 ? ls[0] :
  R.compose(...ls.map(lift))

export const remove = R.curry((l, s) => R.set(lift(l), undefined, s))

export const removeAll = R.curry((lens, data) => {
  while (get(lens, data) !== undefined)
    data = remove(lens, data)
  return data
})

export const lens = R.lens
export const modify = R.curry((l, x2x, s) => R.over(lift(l), x2x, s))
export const set = R.curry((l, x, s) => R.set(lift(l), x, s))
export const get = R.curry((l, s) => R.view(lift(l), s))

export const choose = x2yL => toFunctor => target => {
  const l = lift(x2yL(target))
  return R.map(focus => R.set(l, focus, target), toFunctor(R.view(l, target)))
}

export const nothing = lens(snd, snd)

export const orElse =
  R.curry((d, l) => choose(x => get(l, x) !== undefined ? l : d))

export const choice = (...ls) => choose(x => {
  const i = ls.findIndex(l => get(l, x) !== undefined)
  return 0 <= i ? ls[i] : nothing
})

export const firstOf = (l, ...ls) =>
  deprecated("`firstOf` has been deprecated --- use `choice` and `orElse`") ||
  orElse(l, choice(l, ...ls))

export const replace = R.curry((inn, out) =>
  R.lens(x => R.equals(x, inn) ? out : x,
         toConserve(y => R.equals(y, out) ? inn : y)))

export const defaults = replace(undefined)
export const required = inn => replace(inn, undefined)
export const define = v => R.compose(required(v), defaults(v))

export const normalize = transform =>
  R.lens(toPartial(transform), toConserve(toPartial(transform)))

export const prop = k =>
  R.lens(o => o && o[k],
         (v, o) => v === undefined ? deleteKey(k, o) : setKey(k, v, o))

export const find = predicate => choose(xs => {
  if (xs === undefined)
    return append
  const i = xs.findIndex(predicate)
  return i < 0 ? append : i
})

export const findWith = (l, ...ls) => {
  const lls = lift(compose(l, ...ls))
  return compose(find(x => R.view(lls, x) !== undefined), lls)
}

export const index = i => R.lens(xs => xs && xs[i], (x, xs) => {
  if (x === undefined) {
    if (xs === undefined)
      return undefined
    if (i < xs.length)
      return dropped(xs.slice(0, i).concat(xs.slice(i+1)))
    return xs
  } else {
    if (xs === undefined)
      return Array(i).concat([x])
    if (xs.length <= i)
      return xs.concat(Array(i - xs.length), [x])
    if (R.equals(x, xs[i]))
      return xs
    return xs.slice(0, i).concat([x], xs.slice(i+1))
  }
})

export const append = R.lens(snd, (x, xs) =>
  x === undefined ? xs : xs === undefined ? [x] : xs.concat([x]))

export const filter = p => R.lens(xs => xs && xs.filter(p), (ys, xs) =>
  conserve(dropped(R.concat(ys || [], (xs || []).filter(R.complement(p)))), xs))

export const augment = template => R.lens(
  toPartial(x => {
    const z = {...x}
    for (const k in template)
      z[k] = template[k](x)
    return z
  }),
  toConserve((y, c) => {
    if (y === undefined)
      return undefined
    let z
    const set = (k, v) => {
      if (undefined === z)
        z = {}
      z[k] = v
    }
    for (const k in y) {
      if (!(k in template))
        set(k, y[k])
      else
        if (k in c)
          set(k, c[k])
    }
    return z
  }))

export const pick = template => R.lens(
  c => {
    let r
    for (const k in template) {
      const v = get(template[k], c)
      if (v !== undefined) {
        if (r === undefined)
          r = {}
        r[k] = v
      }
    }
    return r
  },
  (o = empty, cIn) => {
    let c = cIn
    for (const k in template)
      c = set(template[k], o[k], c)
    return c
  })

export const identity = R.lens(R.identity, conserve)

export const props = (k, ...ks) => {
  const kks = [k, ...ks]
  return pick(R.zipObj(kks, kks))
}

export default compose
<|endoftext|>


<commit_before>define([
    "jquery",
    "./inject",
    "../core/parser",
    "../registry"
], function($, inject, Parser, registry) {
    var parser = new Parser("expandable");

    parser.add_argument("load-content");

    var _ = {
        name: "expandable",
        trigger: "ul.pat-expandable",
        jquery_plugin: true,
        init: function($el) {
            // make sure inject folders have a ul
            $el.find(".folder[data-pat-expandable]:not(:has(ul))")
                .append("
");

            // find all folders that contain a ul
            var $folders = $el.find("li.folder:has(ul)");

            // inject span.toggle as first child of each folder
            $folders.prepend("");

            // all folders are implicitly closed
            $folders.filter(":not(.open,.closed)").addClass("closed");

            // trigger open event for open folders
            $folders.filter(".open").trigger("patterns-folder-open");

            // wire spans as control elements
            var $ctrls = $el.find("span.toggle");
            $ctrls.each(function() {
                var $ctrl = $(this),
                    $folder = $ctrl.parent();
                $ctrl.on("click.pat-expandable", function() {
                    $folder.toggleClass("open closed")
                        .filter(".open[data-pat-expandable]")
                        .patExpandable("loadContent");
                });
            });
            return $el;
        },
        loadContent: function($el) {
            return $el.each(function() {
                var $el = $(this),
                    url = parser.parse($el).loadContent,
                    components = url.split("#"),
                    base_url = components[0],
                    id = components[1] ? "#" + components[1] : "body",
                    opts = [{
                        url: base_url,
                        source: id,
                        $target: $el,
                        dataType: "html"
                    }];
                inject.execute(opts, $el);
            });
        }

    };
    registry.register(_);
    return _;
});

// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<commit_msg>fix expandable injection target<commit_after>define([
    "jquery",
    "./inject",
    "../core/parser",
    "../registry"
], function($, inject, Parser, registry) {
    var parser = new Parser("expandable");

    parser.add_argument("load-content");

    var _ = {
        name: "expandable",
        trigger: "ul.pat-expandable",
        jquery_plugin: true,
        init: function($el) {
            // make sure inject folders have a ul
            $el.find(".folder[data-pat-expandable]:not(:has(ul))")
                .append("
");

            // find all folders that contain a ul
            var $folders = $el.find("li.folder:has(ul)");

            // inject span.toggle as first child of each folder
            $folders.prepend("");

            // all folders are implicitly closed
            $folders.filter(":not(.open,.closed)").addClass("closed");

            // trigger open event for open folders
            $folders.filter(".open").trigger("patterns-folder-open");

            // wire spans as control elements
            var $ctrls = $el.find("span.toggle");
            $ctrls.each(function() {
                var $ctrl = $(this),
                    $folder = $ctrl.parent();
                $ctrl.on("click.pat-expandable", function() {
                    $folder.toggleClass("open closed")
                        .filter(".open[data-pat-expandable]")
                        .patExpandable("loadContent");
                });
            });
            return $el;
        },
        loadContent: function($el) {
            return $el.each(function() {
                var $el = $(this),
                    url = parser.parse($el).loadContent,
                    components = url.split("#"),
                    base_url = components[0],
                    id = components[1] ? "#" + components[1] : "body",
                    opts = [{
                        url: base_url,
                        source: id,
                        $target: $el.find('ul'),
                        dataType: "html"
                    }];
                inject.execute(opts, $el);
            });
        }

    };
    registry.register(_);
    return _;
});

// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<|endoftext|>


<commit_before>/**
 * @depends Pattern.js
 */

var PProxy = new Class({
    Extends: Pattern,
    initialize: function(pattern) {
        Pattern.prototype.initialize(this);
        if (pattern) {
            this.pattern = pattern;
        }
    },

    next: function() {
        var returnValue;
        if (this.pattern) {
            var returnValue = pattern.next();
        }
        else {
            returnValue = null;
        }
        return returnValue;
    }
});
var Pp = PProxy;

<commit_msg>Fix missing this<commit_after>/**
 * @depends Pattern.js
 */

var PProxy = new Class({
    Extends: Pattern,
    initialize: function(pattern) {
        Pattern.prototype.initialize(this);
        if (pattern) {
            this.pattern = pattern;
        }
    },

    next: function() {
        var returnValue;
        if (this.pattern) {
            var returnValue = this.pattern.next();
        }
        else {
            returnValue = null;
        }
        return returnValue;
    }
});
var Pp = PProxy;

<|endoftext|>


<commit_before>define([
    'jquery',
    '../logging',
    "../core/parser",
    "../registry",
    "./inject"
], function($, logging, Parser, registry, inject) {
    var log = logging.getLogger('modal'),
        parser = new Parser("modal");

    parser.add_argument("class");

    var modal = {
        // div's are turned into modals
        // links and forms inject modals
        trigger: "div.pat-modal, a.pat-modal, form.pat-modal",
        init: function($el, opts) {
            return $el.each(function() {
                var $el = $(this),
                    cfg = parser.parse($el, opts);

                if ($el.is('div'))
                    modal._init_div1($el, cfg);
                else
                    modal._init_inject1($el, cfg);
            });
        },
        _init_inject1: function($el, cfg) {
            var opts = {
                target: '#modal',
                "class": "pat-modal" + (cfg["class"] ? " " + cfg["class"] : "")
            };
            $('#modal').detach();
            inject.init($el, opts);
        },
        _init_div1: function($el, cfg) {
            var $header = $('
'),
                $button = $(
                    '<button type="button" class="close-panel">Close</button>'
                ).appendTo($header);

            $el.children(':last, :not(:first)').wrapAll('
');
            $('.body', $el).before($header);
            $el.children(':first:not(.header)').prependTo($header);

            // event handlers remove modal - first arg to bind is ``this``
            $(document).on('click.pat-modal', '.close-panel',
                           modal.destroy.bind($el, $el));
            // remove on ESC
            $(document).on('keyup.pat-modal',
                           modal.destroy.bind($el, $el));
        },
        destroy: function($el, ev) {
            if (ev && ev.type === "keyup" && ev.which !== 27)
                return;
            $(document).off('.pat-modal');
            $el.remove();
        }
    };
    registry.register(modal);
    return modal;
});

// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<commit_msg>prefix modal id: #pat-modal<commit_after>define([
    'jquery',
    '../logging',
    "../core/parser",
    "../registry",
    "./inject"
], function($, logging, Parser, registry, inject) {
    var log = logging.getLogger('modal'),
        parser = new Parser("modal");

    parser.add_argument("class");

    var modal = {
        // div's are turned into modals
        // links and forms inject modals
        trigger: "div.pat-modal, a.pat-modal, form.pat-modal",
        init: function($el, opts) {
            return $el.each(function() {
                var $el = $(this),
                    cfg = parser.parse($el, opts);

                if ($el.is('div'))
                    modal._init_div1($el, cfg);
                else
                    modal._init_inject1($el, cfg);
            });
        },
        _init_inject1: function($el, cfg) {
            var opts = {
                target: '#pat-modal',
                "class": "pat-modal" + (cfg["class"] ? " " + cfg["class"] : "")
            };
            $('#pat-modal').detach();
            inject.init($el, opts);
        },
        _init_div1: function($el, cfg) {
            var $header = $('
'),
                $button = $(
                    '<button type="button" class="close-panel">Close</button>'
                ).appendTo($header);

            $el.children(':last, :not(:first)').wrapAll('
');
            $('.body', $el).before($header);
            $el.children(':first:not(.header)').prependTo($header);

            // event handlers remove modal - first arg to bind is ``this``
            $(document).on('click.pat-modal', '.close-panel',
                           modal.destroy.bind($el, $el));
            // remove on ESC
            $(document).on('keyup.pat-modal',
                           modal.destroy.bind($el, $el));
        },
        destroy: function($el, ev) {
            if (ev && ev.type === "keyup" && ev.which !== 27)
                return;
            $(document).off('.pat-modal');
            $el.remove();
        }
    };
    registry.register(modal);
    return modal;
});

// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<|endoftext|>


<commit_before>goog.provide('ol.reproj.Tile');

goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.math');
goog.require('goog.object');
goog.require('ol.Tile');
goog.require('ol.TileState');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.proj');
goog.require('ol.reproj');
goog.require('ol.reproj.Triangulation');

/**
 * @constructor
 * @extends {ol.Tile}
 * @param {ol.proj.Projection} sourceProj
 * @param {ol.tilegrid.TileGrid} sourceTileGrid
 * @param {ol.proj.Projection} targetProj
 * @param {ol.tilegrid.TileGrid} targetTileGrid
 * @param {number} z
 * @param {number} x
 * @param {number} y
 * @param {number} pixelRatio
 * @param {function(number, number, number, number) : ol.Tile} getTileFunction
 * @param {boolean=} opt_renderEdges
 */
ol.reproj.Tile = function(sourceProj, sourceTileGrid,
    targetProj, targetTileGrid, z, x, y, pixelRatio, getTileFunction,
    opt_renderEdges) {
  goog.base(this, [z, x, y], ol.TileState.IDLE);

  /**
   * @private
   * @type {boolean}
   */
  this.renderEdges_ = goog.isDef(opt_renderEdges) ? opt_renderEdges : false;

  /**
   * @private
   * @type {HTMLCanvasElement}
   */
  this.canvas_ = null;

  /**
   * @private
   * @type {Object.<number, HTMLCanvasElement>}
   */
  this.canvasByContext_ = {};

  /**
   * @private
   * @type {ol.tilegrid.TileGrid}
   */
  this.sourceTileGrid_ = sourceTileGrid;

  /**
   * @private
   * @type {ol.tilegrid.TileGrid}
   */
  this.targetTileGrid_ = targetTileGrid;

  /**
   * @private
   * @type {!Array.<ol.Tile>}
   */
  this.srcTiles_ = [];

  /**
   * @private
   * @type {Array.<goog.events.Key>}
   */
  this.sourcesListenerKeys_ = null;

  /**
   * @private
   * @type {number}
   */
  this.srcZ_ = 0;

  var targetExtent = targetTileGrid.getTileCoordExtent(this.getTileCoord());
  var maxTargetExtent = this.targetTileGrid_.getExtent();
  var maxSourceExtent = this.sourceTileGrid_.getExtent();

  var limitedTargetExtent = goog.isNull(maxTargetExtent) ?
      targetExtent : ol.extent.getIntersection(targetExtent, maxTargetExtent);

  if (ol.extent.getArea(limitedTargetExtent) === 0) {
    // Tile is completely outside range -> EMPTY
    // TODO: is it actually correct that the source even creates the tile ?
    this.state = ol.TileState.EMPTY;
    return;
  }

  var targetResolution = targetTileGrid.getResolution(z);

  var errorThresholdInPixels = ol.DEFAULT_RASTER_REPROJ_ERROR_THRESHOLD;

  // in source units
  var errorThreshold = targetResolution * errorThresholdInPixels *
      targetProj.getMetersPerUnit() / sourceProj.getMetersPerUnit();

  /**
   * @private
   * @type {!ol.reproj.Triangulation}
   */
  this.triangulation_ = new ol.reproj.Triangulation(
      sourceProj, targetProj, limitedTargetExtent, maxSourceExtent,
      errorThreshold);

  if (this.triangulation_.getTriangles().length === 0) {
    // no valid triangles -> EMPTY
    this.state = ol.TileState.EMPTY;
    return;
  }

  var targetCenter = ol.extent.getCenter(limitedTargetExtent);
  var sourceResolution = ol.reproj.calculateSourceResolution(
      sourceProj, targetProj, targetCenter, targetResolution);

  if (!goog.math.isFiniteNumber(sourceResolution) || sourceResolution <= 0) {
    // invalid sourceResolution -> EMPTY
    // probably edges of the projections when no extent is defined
    this.state = ol.TileState.EMPTY;
    return;
  }

  this.srcZ_ = sourceTileGrid.getZForResolution(sourceResolution);
  var srcExtent = this.triangulation_.calculateSourceExtent();

  var sourceProjExtent = sourceProj.getExtent();
  if (!sourceProj.isGlobal() && sourceProjExtent) {
    srcExtent = ol.extent.getIntersection(srcExtent, sourceProjExtent);
  }

  if (!goog.isNull(maxSourceExtent) &&
      !ol.extent.intersects(maxSourceExtent, srcExtent)) {
    this.state = ol.TileState.EMPTY;
  } else {
    var srcRange = sourceTileGrid.getTileRangeForExtentAndZ(
        srcExtent, this.srcZ_);

    var xRange;
    var srcFullRange = sourceTileGrid.getFullTileRange(this.srcZ_);
    if (!goog.isNull(srcFullRange)) {
      srcRange.minY = Math.max(srcRange.minY, srcFullRange.minY);
      srcRange.maxY = Math.min(srcRange.maxY, srcFullRange.maxY);

      if (srcRange.minX > srcRange.maxX) {
        xRange = goog.array.concat(
            goog.array.range(srcRange.minX, srcFullRange.maxX + 1),
            goog.array.range(srcFullRange.minX, srcRange.maxX + 1)
            );
      } else {
        xRange = goog.array.range(
            Math.max(srcRange.minX, srcFullRange.minX),
            Math.min(srcRange.maxX, srcFullRange.maxX) + 1
            );
      }
    } else {
      xRange = goog.array.range(srcRange.minX, srcRange.maxX + 1);
    }

    var tilesRequired = xRange.length * srcRange.getHeight();
    goog.asserts.assert(tilesRequired < ol.RASTER_REPROJ_MAX_SOURCE_TILES,
        'reasonable number of tiles is required');

    if (tilesRequired > ol.RASTER_REPROJ_MAX_SOURCE_TILES) {
      this.state = ol.TileState.ERROR;
      return;
    }
    goog.array.forEach(xRange, function(srcX, i, arr) {
      for (var srcY = srcRange.minY; srcY <= srcRange.maxY; srcY++) {
        var tile = getTileFunction(this.srcZ_, srcX, srcY, pixelRatio);
        if (tile) {
          this.srcTiles_.push(tile);
        }
      }
    }, this);

    if (this.srcTiles_.length === 0) {
      this.state = ol.TileState.EMPTY;
    }
  }
};
goog.inherits(ol.reproj.Tile, ol.Tile);

/**
 * @inheritDoc
 */
ol.reproj.Tile.prototype.disposeInternal = function() {
  if (this.state == ol.TileState.LOADING) {
    this.unlistenSources_();
  }
  goog.base(this, 'disposeInternal');
};

/**
 * @inheritDoc
 */
ol.reproj.Tile.prototype.getImage = function(opt_context) {
  if (goog.isDef(opt_context)) {
    var image;
    var key = goog.getUid(opt_context);
    if (key in this.canvasByContext_) {
      return this.canvasByContext_[key];
    } else if (goog.object.isEmpty(this.canvasByContext_)) {
      image = this.canvas_;
    } else {
      image = /** @type {HTMLCanvasElement} */ (this.canvas_.cloneNode(false));
    }
    this.canvasByContext_[key] = image;
    return image;
  } else {
    return this.canvas_;
  }
};

/**
 * @private
 */
ol.reproj.Tile.prototype.reproject_ = function() {
  var sources = [];
  goog.array.forEach(this.srcTiles_, function(tile, i, arr) {
    if (tile && tile.getState() == ol.TileState.LOADED) {
      sources.push({
        extent: this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord),
        image: tile.getImage()
      });
    }
  }, this);

  // create the canvas
  var tileCoord = this.getTileCoord();
  var z = tileCoord[0];
  var size = this.targetTileGrid_.getTileSize(z);
  var targetResolution = this.targetTileGrid_.getResolution(z);
  var srcResolution = this.sourceTileGrid_.getResolution(this.srcZ_);

  var width = goog.isNumber(size) ? size : size[0];
  var height = goog.isNumber(size) ? size : size[1];
  var context = ol.dom.createCanvasContext2D(width, height);
  context.imageSmoothingEnabled = true;

  if (sources.length > 0) {
    var targetExtent = this.targetTileGrid_.getTileCoordExtent(tileCoord);
    ol.reproj.renderTriangles(context,
        srcResolution, this.sourceTileGrid_.getExtent(),
        targetResolution, targetExtent, this.triangulation_, sources,
        this.renderEdges_);
  }

  this.canvas_ = context.canvas;
  this.state = ol.TileState.LOADED;
  this.changed();
};

/**
 * @inheritDoc
 */
ol.reproj.Tile.prototype.load = function() {
  if (this.state == ol.TileState.IDLE) {
    this.state = ol.TileState.LOADING;
    this.changed();

    var leftToLoad = 0;
    var onSingleSourceLoaded = goog.bind(function() {
      leftToLoad--;
      goog.asserts.assert(leftToLoad >= 0, 'leftToLoad should not be negative');
      if (leftToLoad <= 0) {
        this.unlistenSources_();
        this.reproject_();
      }
    }, this);

    goog.asserts.assert(goog.isNull(this.sourcesListenerKeys_),
        'this.sourcesListenerKeys_ should be null');

    this.sourcesListenerKeys_ = [];
    goog.array.forEach(this.srcTiles_, function(tile, i, arr) {
      var state = tile.getState();
      if (state == ol.TileState.IDLE || state == ol.TileState.LOADING) {
        leftToLoad++;

        var sourceListenKey;
        sourceListenKey = tile.listen(goog.events.EventType.CHANGE,
            function(e) {
              var state = tile.getState();
              if (state == ol.TileState.LOADED ||
                  state == ol.TileState.ERROR ||
                  state == ol.TileState.EMPTY) {
                onSingleSourceLoaded();
                goog.events.unlistenByKey(sourceListenKey);
              }
            });
        this.sourcesListenerKeys_.push(sourceListenKey);
      }
    }, this);

    goog.array.forEach(this.srcTiles_, function(tile, i, arr) {
      var state = tile.getState();
      if (state == ol.TileState.IDLE) {
        tile.load();
      }
    });

    if (leftToLoad === 0) {
      this.reproject_();
    }
  }
};

/**
 * @private
 */
ol.reproj.Tile.prototype.unlistenSources_ = function() {
  goog.asserts.assert(!goog.isNull(this.sourcesListenerKeys_),
      'this.sourcesListenerKeys_ should not be null');
  goog.array.forEach(this.sourcesListenerKeys_, goog.events.unlistenByKey);
  this.sourcesListenerKeys_ = null;
};
<commit_msg>Better handling of tilegrids without extent during reprojection<commit_after>goog.provide('ol.reproj.Tile');

goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.math');
goog.require('goog.object');
goog.require('ol.Tile');
goog.require('ol.TileState');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.proj');
goog.require('ol.reproj');
goog.require('ol.reproj.Triangulation');

/**
 * @constructor
 * @extends {ol.Tile}
 * @param {ol.proj.Projection} sourceProj
 * @param {ol.tilegrid.TileGrid} sourceTileGrid
 * @param {ol.proj.Projection} targetProj
 * @param {ol.tilegrid.TileGrid} targetTileGrid
 * @param {number} z
 * @param {number} x
 * @param {number} y
 * @param {number} pixelRatio
 * @param {function(number, number, number, number) : ol.Tile} getTileFunction
 * @param {boolean=} opt_renderEdges
 */
ol.reproj.Tile = function(sourceProj, sourceTileGrid,
    targetProj, targetTileGrid, z, x, y, pixelRatio, getTileFunction,
    opt_renderEdges) {
  goog.base(this, [z, x, y], ol.TileState.IDLE);

  /**
   * @private
   * @type {boolean}
   */
  this.renderEdges_ = goog.isDef(opt_renderEdges) ? opt_renderEdges : false;

  /**
   * @private
   * @type {HTMLCanvasElement}
   */
  this.canvas_ = null;

  /**
   * @private
   * @type {Object.<number, HTMLCanvasElement>}
   */
  this.canvasByContext_ = {};

  /**
   * @private
   * @type {ol.tilegrid.TileGrid}
   */
  this.sourceTileGrid_ = sourceTileGrid;

  /**
   * @private
   * @type {ol.tilegrid.TileGrid}
   */
  this.targetTileGrid_ = targetTileGrid;

  /**
   * @private
   * @type {!Array.<ol.Tile>}
   */
  this.srcTiles_ = [];

  /**
   * @private
   * @type {Array.<goog.events.Key>}
   */
  this.sourcesListenerKeys_ = null;

  /**
   * @private
   * @type {number}
   */
  this.srcZ_ = 0;

  var targetExtent = targetTileGrid.getTileCoordExtent(this.getTileCoord());
  var maxTargetExtent = this.targetTileGrid_.getExtent();
  var maxSourceExtent = this.sourceTileGrid_.getExtent();

  var limitedTargetExtent = goog.isNull(maxTargetExtent) ?
      targetExtent : ol.extent.getIntersection(targetExtent, maxTargetExtent);

  if (ol.extent.getArea(limitedTargetExtent) === 0) {
    // Tile is completely outside range -> EMPTY
    // TODO: is it actually correct that the source even creates the tile ?
    this.state = ol.TileState.EMPTY;
    return;
  }

  if (!sourceProj.isGlobal()) {
    var sourceProjExtent = sourceProj.getExtent();
    if (!goog.isNull(sourceProjExtent)) {
      if (goog.isNull(maxSourceExtent)) {
        maxSourceExtent = sourceProjExtent;
      } else {
        maxSourceExtent = ol.extent.getIntersection(
            maxSourceExtent, sourceProjExtent);
      }
    }
  }

  var targetResolution = targetTileGrid.getResolution(z);

  var errorThresholdInPixels = ol.DEFAULT_RASTER_REPROJ_ERROR_THRESHOLD;

  // in source units
  var errorThreshold = targetResolution * errorThresholdInPixels *
      targetProj.getMetersPerUnit() / sourceProj.getMetersPerUnit();

  /**
   * @private
   * @type {!ol.reproj.Triangulation}
   */
  this.triangulation_ = new ol.reproj.Triangulation(
      sourceProj, targetProj, limitedTargetExtent, maxSourceExtent,
      errorThreshold);

  if (this.triangulation_.getTriangles().length === 0) {
    // no valid triangles -> EMPTY
    this.state = ol.TileState.EMPTY;
    return;
  }

  var targetCenter = ol.extent.getCenter(limitedTargetExtent);
  var sourceResolution = ol.reproj.calculateSourceResolution(
      sourceProj, targetProj, targetCenter, targetResolution);

  if (!goog.math.isFiniteNumber(sourceResolution) || sourceResolution <= 0) {
    // invalid sourceResolution -> EMPTY
    // probably edges of the projections when no extent is defined
    this.state = ol.TileState.EMPTY;
    return;
  }

  this.srcZ_ = sourceTileGrid.getZForResolution(sourceResolution);
  var srcExtent = this.triangulation_.calculateSourceExtent();

  if (!goog.isNull(maxSourceExtent) &&
      !ol.extent.intersects(maxSourceExtent, srcExtent)) {
    this.state = ol.TileState.EMPTY;
  } else {
    var srcRange = sourceTileGrid.getTileRangeForExtentAndZ(
        srcExtent, this.srcZ_);

    var xRange;
    var srcFullRange = sourceTileGrid.getFullTileRange(this.srcZ_);
    if (!goog.isNull(srcFullRange)) {
      srcRange.minY = Math.max(srcRange.minY, srcFullRange.minY);
      srcRange.maxY = Math.min(srcRange.maxY, srcFullRange.maxY);

      if (srcRange.minX > srcRange.maxX) {
        xRange = goog.array.concat(
            goog.array.range(srcRange.minX, srcFullRange.maxX + 1),
            goog.array.range(srcFullRange.minX, srcRange.maxX + 1)
            );
      } else {
        xRange = goog.array.range(
            Math.max(srcRange.minX, srcFullRange.minX),
            Math.min(srcRange.maxX, srcFullRange.maxX) + 1
            );
      }
    } else {
      xRange = goog.array.range(srcRange.minX, srcRange.maxX + 1);
    }

    var tilesRequired = xRange.length * srcRange.getHeight();
    if (!goog.asserts.assert(tilesRequired < ol.RASTER_REPROJ_MAX_SOURCE_TILES,
        'reasonable number of tiles is required')) {
      this.state = ol.TileState.ERROR;
      return;
    }
    goog.array.forEach(xRange, function(srcX, i, arr) {
      for (var srcY = srcRange.minY; srcY <= srcRange.maxY; srcY++) {
        var tile = getTileFunction(this.srcZ_, srcX, srcY, pixelRatio);
        if (tile) {
          this.srcTiles_.push(tile);
        }
      }
    }, this);

    if (this.srcTiles_.length === 0) {
      this.state = ol.TileState.EMPTY;
    }
  }
};
goog.inherits(ol.reproj.Tile, ol.Tile);

/**
 * @inheritDoc
 */
ol.reproj.Tile.prototype.disposeInternal = function() {
  if (this.state == ol.TileState.LOADING) {
    this.unlistenSources_();
  }
  goog.base(this, 'disposeInternal');
};

/**
 * @inheritDoc
 */
ol.reproj.Tile.prototype.getImage = function(opt_context) {
  if (goog.isDef(opt_context)) {
    var image;
    var key = goog.getUid(opt_context);
    if (key in this.canvasByContext_) {
      return this.canvasByContext_[key];
    } else if (goog.object.isEmpty(this.canvasByContext_)) {
      image = this.canvas_;
    } else {
      image = /** @type {HTMLCanvasElement} */ (this.canvas_.cloneNode(false));
    }
    this.canvasByContext_[key] = image;
    return image;
  } else {
    return this.canvas_;
  }
};

/**
 * @private
 */
ol.reproj.Tile.prototype.reproject_ = function() {
  var sources = [];
  goog.array.forEach(this.srcTiles_, function(tile, i, arr) {
    if (tile && tile.getState() == ol.TileState.LOADED) {
      sources.push({
        extent: this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord),
        image: tile.getImage()
      });
    }
  }, this);

  // create the canvas
  var tileCoord = this.getTileCoord();
  var z = tileCoord[0];
  var size = this.targetTileGrid_.getTileSize(z);
  var targetResolution = this.targetTileGrid_.getResolution(z);
  var srcResolution = this.sourceTileGrid_.getResolution(this.srcZ_);

  var width = goog.isNumber(size) ? size : size[0];
  var height = goog.isNumber(size) ? size : size[1];
  var context = ol.dom.createCanvasContext2D(width, height);
  context.imageSmoothingEnabled = true;

  if (sources.length > 0) {
    var targetExtent = this.targetTileGrid_.getTileCoordExtent(tileCoord);
    ol.reproj.renderTriangles(context,
        srcResolution, this.sourceTileGrid_.getExtent(),
        targetResolution, targetExtent, this.triangulation_, sources,
        this.renderEdges_);
  }

  this.canvas_ = context.canvas;
  this.state = ol.TileState.LOADED;
  this.changed();
};

/**
 * @inheritDoc
 */
ol.reproj.Tile.prototype.load = function() {
  if (this.state == ol.TileState.IDLE) {
    this.state = ol.TileState.LOADING;
    this.changed();

    var leftToLoad = 0;
    var onSingleSourceLoaded = goog.bind(function() {
      leftToLoad--;
      goog.asserts.assert(leftToLoad >= 0, 'leftToLoad should not be negative');
      if (leftToLoad <= 0) {
        this.unlistenSources_();
        this.reproject_();
      }
    }, this);

    goog.asserts.assert(goog.isNull(this.sourcesListenerKeys_),
        'this.sourcesListenerKeys_ should be null');

    this.sourcesListenerKeys_ = [];
    goog.array.forEach(this.srcTiles_, function(tile, i, arr) {
      var state = tile.getState();
      if (state == ol.TileState.IDLE || state == ol.TileState.LOADING) {
        leftToLoad++;

        var sourceListenKey;
        sourceListenKey = tile.listen(goog.events.EventType.CHANGE,
            function(e) {
              var state = tile.getState();
              if (state == ol.TileState.LOADED ||
                  state == ol.TileState.ERROR ||
                  state == ol.TileState.EMPTY) {
                onSingleSourceLoaded();
                goog.events.unlistenByKey(sourceListenKey);
              }
            });
        this.sourcesListenerKeys_.push(sourceListenKey);
      }
    }, this);

    goog.array.forEach(this.srcTiles_, function(tile, i, arr) {
      var state = tile.getState();
      if (state == ol.TileState.IDLE) {
        tile.load();
      }
    });

    if (leftToLoad === 0) {
      this.reproject_();
    }
  }
};

/**
 * @private
 */
ol.reproj.Tile.prototype.unlistenSources_ = function() {
  goog.asserts.assert(!goog.isNull(this.sourcesListenerKeys_),
      'this.sourcesListenerKeys_ should not be null');
  goog.array.forEach(this.sourcesListenerKeys_, goog.events.unlistenByKey);
  this.sourcesListenerKeys_ = null;
};
<|endoftext|>


<commit_before>define(["pex/core/Context", "pex/sys/IO", "pex/util/GLUtils"], function(Context, IO, GLUtils) {
  var kShaderPrefix         = "#ifdef GL_ES\nprecision highp float;\n#endif\n";
  var kVertexShaderPrefix   = kShaderPrefix + "#define VERT\n";
  var kFragmentShaderPrefix = kShaderPrefix + "#define FRAG\n";

  function Program(vertSrc, fragSrc) {
    this.gl = Context.currentContext.gl;

    this.handle = this.gl.createProgram();
    this.uniforms  = {};
    this.attributes = {};
    this.addSources(vertSrc, fragSrc);
    this.ready = false;
    if (this.vertShader && this.fragShader) this.link();
  }

  Program.prototype.addSources = function(vertSrc, fragSrc) {
    vertSrc = vertSrc ? vertSrc : null;
    fragSrc = fragSrc ? fragSrc : vertSrc;

    if (vertSrc) this.addVertexSource(vertSrc);
    if (fragSrc) this.addFragmentSource(fragSrc);
  };

  Program.prototype.addVertexSource = function(vertSrc) {
    var gl = this.gl;
    var vert = this.vertShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vert, kVertexShaderPrefix + vertSrc);
    gl.compileShader(vert);
    if (gl.getShaderParameter(vert, gl.COMPILE_STATUS) !== true) {
      console.log(vertSrc);
      throw gl.getShaderInfoLog(vert);
    }
  };

  Program.prototype.addFragmentSource = function(fragSrc) {
    var gl = this.gl;
    var frag = this.fragShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(frag, kFragmentShaderPrefix + fragSrc);
    gl.compileShader(frag);
    if (gl.getShaderParameter(frag, gl.COMPILE_STATUS) !== true) {
      console.log(fragSrc);
      throw gl.getShaderInfoLog(frag);
    }
  };

  Program.prototype.link = function(){
    var gl = this.gl;
    var handle = this.handle;

    gl.attachShader(handle, this.vertShader);
    gl.attachShader(handle, this.fragShader);
    gl.linkProgram(handle);

    if (gl.getProgramParameter(handle, gl.LINK_STATUS) !== true)
        throw gl.getProgramInfoLog(handle);

    var numUniforms = gl.getProgramParameter(handle, gl.ACTIVE_UNIFORMS);

    for(var i = 0; i < numUniforms; ++i){
      var info     = gl.getActiveUniform(handle, i);
      var location = gl.getUniformLocation(handle, info.name);
      this.uniforms[info.name] = makeUniformSetter(gl, info.type, location);
    }

    var numAttributes = gl.getProgramParameter(handle, gl.ACTIVE_ATTRIBUTES);
    for(var i = 0; i < numAttributes; ++i){
      var info     = gl.getActiveAttrib(handle, i);
      var location = gl.getAttribLocation(handle, info.name);
      this.attributes[info.name] = location;
    }

    this.ready = true;
    return this;
  };

  Program.prototype.use = function(){
    this.gl.useProgram(this.handle);
  };

  Program.prototype.dispose = function(){
    this.gl.deleteShader(this.vertShader);
    this.gl.deleteShader(this.fragShader);
    this.gl.deleteProgram(this.handle);
  };

  Program.load = function(url, callback) {
    var program = new Program();
    IO.loadTextFile(url, function(source) {
      console.log("Program.Compiling " + url);
      program.addSources(source);
      program.link();
      if (callback) callback();
    });
    return program;
  }

  function makeUniformSetter(gl, type, location){
    var setterFun = null;
    switch(type){
      case gl.BOOL:
      case gl.INT:
      case gl.SAMPLER_2D:
      case gl.SAMPLER_CUBE:
        setterFun = function(value){
          if (isNaN(value)) {
            gl.uniform1i(location, value.handle);
          }
          else {
            gl.uniform1i(location, value);
          }
        };
        break;
      case gl.FLOAT:
        setterFun = function(value){
          gl.uniform1f(location, value);
        };
        break;
      case gl.FLOAT_VEC2:
        setterFun = function(v){
          gl.uniform2fv(location, v);
        };
        break;
      case gl.FLOAT_VEC3:
        setterFun = function(v) {
          gl.uniform3fv(location, v);
        };
        break;
      case gl.FLOAT_VEC4:
        setterFun = function(v){
          gl.uniform4fv(location, v);
        };
        break;
      case gl.FLOAT_MAT4:
        setterFun = (function(mv) {
          gl.uniformMatrix4fv(location, false, mv);
        };
        break;
    }

    if (setterFun) {
      setterFun.type = type;
      return setterFun;
    }
    return function(){
      throw "Unknown uniform type: " + type;
    };
  }

  return Program;
});<commit_msg>Typo fixes and removed unused code<commit_after>define(["pex/gl/Context", "pex/sys/IO"], function(Context, IO) {
  var kShaderPrefix         = "#ifdef GL_ES\nprecision highp float;\n#endif\n";
  var kVertexShaderPrefix   = kShaderPrefix + "#define VERT\n";
  var kFragmentShaderPrefix = kShaderPrefix + "#define FRAG\n";

  function Program(vertSrc, fragSrc) {
    this.gl = Context.currentContext.gl;

    this.handle = this.gl.createProgram();
    this.uniforms  = {};
    this.attributes = {};
    this.addSources(vertSrc, fragSrc);
    this.ready = false;
    if (this.vertShader && this.fragShader) this.link();
  }

  Program.prototype.addSources = function(vertSrc, fragSrc) {
    vertSrc = vertSrc ? vertSrc : null;
    fragSrc = fragSrc ? fragSrc : vertSrc;

    if (vertSrc) this.addVertexSource(vertSrc);
    if (fragSrc) this.addFragmentSource(fragSrc);
  };

  Program.prototype.addVertexSource = function(vertSrc) {
    var gl = this.gl;
    var vert = this.vertShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vert, kVertexShaderPrefix + vertSrc);
    gl.compileShader(vert);
    if (gl.getShaderParameter(vert, gl.COMPILE_STATUS) !== true) {
      console.log(vertSrc);
      throw gl.getShaderInfoLog(vert);
    }
  };

  Program.prototype.addFragmentSource = function(fragSrc) {
    var gl = this.gl;
    var frag = this.fragShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(frag, kFragmentShaderPrefix + fragSrc);
    gl.compileShader(frag);
    if (gl.getShaderParameter(frag, gl.COMPILE_STATUS) !== true) {
      console.log(fragSrc);
      throw gl.getShaderInfoLog(frag);
    }
  };

  Program.prototype.link = function(){
    var gl = this.gl;
    var handle = this.handle;

    gl.attachShader(handle, this.vertShader);
    gl.attachShader(handle, this.fragShader);
    gl.linkProgram(handle);

    if (gl.getProgramParameter(handle, gl.LINK_STATUS) !== true)
        throw gl.getProgramInfoLog(handle);

    var numUniforms = gl.getProgramParameter(handle, gl.ACTIVE_UNIFORMS);

    for(var i = 0; i < numUniforms; ++i){
      var info     = gl.getActiveUniform(handle, i);
      var location = gl.getUniformLocation(handle, info.name);
      this.uniforms[info.name] = makeUniformSetter(gl, info.type, location);
    }

    var numAttributes = gl.getProgramParameter(handle, gl.ACTIVE_ATTRIBUTES);
    for(var i = 0; i < numAttributes; ++i){
      var info     = gl.getActiveAttrib(handle, i);
      var location = gl.getAttribLocation(handle, info.name);
      this.attributes[info.name] = location;
    }

    this.ready = true;
    return this;
  };

  Program.prototype.use = function(){
    this.gl.useProgram(this.handle);
  };

  Program.prototype.dispose = function(){
    this.gl.deleteShader(this.vertShader);
    this.gl.deleteShader(this.fragShader);
    this.gl.deleteProgram(this.handle);
  };

  Program.load = function(url, callback) {
    var program = new Program();
    IO.loadTextFile(url, function(source) {
      console.log("Program.Compiling " + url);
      program.addSources(source);
      program.link();
      if (callback) callback();
    });
    return program;
  }

  function makeUniformSetter(gl, type, location){
    var setterFun = null;
    switch(type){
      case gl.BOOL:
      case gl.INT:
      case gl.SAMPLER_2D:
      case gl.SAMPLER_CUBE:
        setterFun = function(value){
          if (isNaN(value)) {
            gl.uniform1i(location, value.handle);
          }
          else {
            gl.uniform1i(location, value);
          }
        };
        break;
      case gl.FLOAT:
        setterFun = function(value){
          gl.uniform1f(location, value);
        };
        break;
      case gl.FLOAT_VEC2:
        setterFun = function(v){
          gl.uniform2fv(location, v);
        };
        break;
      case gl.FLOAT_VEC3:
        setterFun = function(v) {
          gl.uniform3fv(location, v);
        };
        break;
      case gl.FLOAT_VEC4:
        setterFun = function(v){
          gl.uniform4fv(location, v);
        };
        break;
      case gl.FLOAT_MAT4:
        setterFun = function(mv) {
          gl.uniformMatrix4fv(location, false, mv);
        };
        break;
    }

    if (setterFun) {
      setterFun.type = type;
      return setterFun;
    }
    return function(){
      throw "Unknown uniform type: " + type;
    };
  }

  return Program;
});<|endoftext|>


<commit_before>var mongoose = require('mongoose');

var CatModel;

var DogSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        trim: true,
        unique: true
    },

    breed: {
        type: String,
        trim:true,
        required: true
    },
    age:{
        type:Number,
        trim:true,
    },

    createdDate: {
        type: Date,
        default: Date.now
    }

});

DogSchema.statics.findByName = function(name, callback) {

    var search = {
        name: name
    };

    return DogModel.findOne(search, callback);
};

DogModel = mongoose.model('Dog', DogSchema);

module.exports.DogModel = DogModel;
module.exports.DogSchema = DogSchema;
<commit_msg>fixed error in Dog.js<commit_after>var mongoose = require('mongoose');

var DogModel;

var DogSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        trim: true,
        unique: true
    },

    breed: {
        type: String,
        trim:true,
        required: true
    },
    age:{
        type:Number,
        trim:true,
    },

    createdDate: {
        type: Date,
        default: Date.now
    }

});

DogSchema.statics.findByName = function(name, callback) {

    var search = {
        name: name
    };

    return DogModel.findOne(search, callback);
};

DogModel = mongoose.model('Dog', DogSchema);

module.exports.DogModel = DogModel;
module.exports.DogSchema = DogSchema;
<|endoftext|>


<commit_before>import * as Sajari from 'sajari'

import './polyfill' // for .startsWith

const TRACKING_RESET = 'TRACKING_RESET';
const RESULT_CLICKED = 'RESULT_CLICKED';
const RESULTS_CHANGED = 'RESULTS_CHANGED';
const VALUES_CHANGED = 'VALUES_CHANGED';

// beforeSearch is run before a search is started (i.e. sent to the server).
// If it returns false, then we bail.
const websiteBeforeSearch = state => {
  // If q == "" then clear the results immediately and don't run a search.
  if (state.getValues()["q"] === "") {
    state.reset()
    delete state.getValues()["filter"];
    delete state.getValues()["page"];
    return false;
  }
  return true
};

const websiteConstructTracking = state => {
  const tracking = new Sajari.Tracking()

  if (state.pipeline === 'website') {
    tracking.clickTokens('url') // NOTE: this will not be cleared if the pipeline is changed
  }

  // tracking.data is merged into tracking.data (to avoid clearing existing values unless
  // another explicitly replaces it).
  if (state.tracking.data) {
    for (let k in state.tracking.data) {
      tracking.data[k] = state.tracking.data[k];
    }
  }

  // Record the QID and the sequence
  if (state.tracking.qid && state.tracking.seq >= 0) {
    tracking.i = state.tracking.qid;
    tracking.s = state.tracking.seq+1;
  }
  state.tracking.qid = tracking.i;
  state.tracking.seq = tracking.s;

  return tracking;
}

class state {
  constructor(namespace) {
    this.namespace = namespace;
    this.values = {};
    this.responseValues = {};
    this.tracking = {};

    this.listeners = [];
    this.beforeSearch = websiteBeforeSearch;
    this.constructTracking = websiteConstructTracking;
  }

  getPipeline() {
    return this.pipeline;
  }

  getNamespace() {
    return this.namespace;
  }

  setPipeline(pipeline) {
    this.pipeline = pipeline;
  }

  setProject(project) {
    this.project = project;
  }

  setCollection(collection) {
    this.collection = collection;
  }

  setTrackingData(data) {
    this.tracking.data = data;
  }

  setBeforeSearch(f) {
    this.beforeSearch = f;
  }

  setConstructTracking(f) {
    this.constructTracking = f;
  }

  resetTracking() {
    this.tracking.seq = null;
    this.tracking.qid = null;
    this.notify(TRACKING_RESET);
  }

  reset() {
    this.results = undefined;
    this.error = undefined;
    this.values = {};
    this.responseValues = {};
    this.notify(RESULTS_CHANGED);
    this.resetTracking();
  }

  _runSearch() {
    if (!this.beforeSearch(this)) {
      return
    }

    const client = new Sajari.Client(this.project, this.collection);
    const tracking = this.constructTracking(this);

    client.searchPipeline(this.pipeline, this.values, tracking, (err, res) => {
      // Discard this result if another (more recent query) has been sent through
      // with a different qid.
      if (this.tracking.qid !== tracking.i) {
        return;
      }

      // Discard this result if another (more recent query) has been sent.
      if (this.tracking.seq >= tracking.s) {
        return;
      }

      if (!res) {
        this.error = err || "No response.";
        if (console && console.error) {
          console.error("got error during search", this.error);
        }
        this.notify(RESULTS_CHANGED);
        return;
      }
      this.error = null;

      this.responseValues = res.values;
      this.results = res.searchResponse;
      this.notify(RESULTS_CHANGED);
    })
  }

  registerListener(type, listener) {
    this.listeners.push({ type, listener })
  }

  unregisterListener(type, listener) {
    this.listeners = this.listeners.filter(l => {
      if (l.type === type && l.listener === listener) {
        return false;
      }
      return true;
    });
  }

  notify(type, ...x) {
    this.listeners.forEach(l => {
      if (l.type === type) {
        l.listener(...x);
      }
    });
  }

  getError() {
    return this.error;
  }

  getResults() {
    return this.results;
  }

  getValues() {
    return this.values;
  }

  getResponseValues() {
    return this.responseValues;
  }

  beforeMergingValues(values) {
    // Only if values["q"] is set do we check if the value has changed.
    if (values["q"] !== undefined) {
      let prevQ = this.values["q"] || "";
      let currQ = values["q"];

      // Reset the tracking if the new query differs in prefix to the old.
      if (!currQ.startsWith(prevQ.substr(0, Math.min(currQ.length, 3)))) {
        this.resetTracking();
      }

      // If the query has changed then reset the page, but only if
      // we're not already trying to set it.
      if (currQ !== prevQ && values["page"] === undefined) {
        this.values["page"] = "1";
      }

      // Clear q.used when setting q to be "", but only if we're
      // not also setting q.used.
      if (currQ === "" && values["q.used"] === undefined) {
        delete this.responseValues["q.used"];
      }
    }

    // Only if values["filter"] is set do we check if the value has changed.
    if (values["filter"] !== undefined) {
      let prevFilter = this.values["filter"] || "";
      // Reset the page, but only if we're not already trying
      // to set it.
      if (prevFilter !== values["filter"] && values["page"] === undefined) {
        this.values["page"] = "1";
      }
    }
  }

  setValues(values, runSearch = false) {
    this.beforeMergingValues(values);

    // Merge values into this.values.
    for (let k in values) {
      this.values[k] = values[k]
    }

    if (runSearch) {
      this._runSearch();
    }
    this.notify(VALUES_CHANGED);
  }
}

class State {
  constructor() {
    this._ns = {}

    this.ns = this.ns.bind(this);
  }

  default() {
    return this.ns("default");
  }

  ns(namespace) {
    let n = this._ns[namespace]
    if (!n) {
      n = new state(namespace);
      this._ns[namespace] = n
    }
    return n;
  }
}

const _state = new State();

export { _state as State, TRACKING_RESET, RESULT_CLICKED, RESULTS_CHANGED, VALUES_CHANGED }
<commit_msg>pipeline: clear null or undefined values from the map<commit_after>import * as Sajari from 'sajari'

import './polyfill' // for .startsWith

const TRACKING_RESET = 'TRACKING_RESET';
const RESULT_CLICKED = 'RESULT_CLICKED';
const RESULTS_CHANGED = 'RESULTS_CHANGED';
const VALUES_CHANGED = 'VALUES_CHANGED';

// beforeSearch is run before a search is started (i.e. sent to the server).
// If it returns false, then we bail.
const websiteBeforeSearch = state => {
  // If q == "" then clear the results immediately and don't run a search.
  if (state.getValues()["q"] === "") {
    state.reset()
    delete state.getValues()["filter"];
    delete state.getValues()["page"];
    return false;
  }
  return true
};

const websiteConstructTracking = state => {
  const tracking = new Sajari.Tracking()

  if (state.pipeline === 'website') {
    tracking.clickTokens('url') // NOTE: this will not be cleared if the pipeline is changed
  }

  // tracking.data is merged into tracking.data (to avoid clearing existing values unless
  // another explicitly replaces it).
  if (state.tracking.data) {
    for (let k in state.tracking.data) {
      tracking.data[k] = state.tracking.data[k];
    }
  }

  // Record the QID and the sequence
  if (state.tracking.qid && state.tracking.seq >= 0) {
    tracking.i = state.tracking.qid;
    tracking.s = state.tracking.seq+1;
  }
  state.tracking.qid = tracking.i;
  state.tracking.seq = tracking.s;

  return tracking;
}

class state {
  constructor(namespace) {
    this.namespace = namespace;
    this.values = {};
    this.responseValues = {};
    this.tracking = {};

    this.listeners = [];
    this.beforeSearch = websiteBeforeSearch;
    this.constructTracking = websiteConstructTracking;
  }

  getPipeline() {
    return this.pipeline;
  }

  getNamespace() {
    return this.namespace;
  }

  setPipeline(pipeline) {
    this.pipeline = pipeline;
  }

  setProject(project) {
    this.project = project;
  }

  setCollection(collection) {
    this.collection = collection;
  }

  setTrackingData(data) {
    this.tracking.data = data;
  }

  setBeforeSearch(f) {
    this.beforeSearch = f;
  }

  setConstructTracking(f) {
    this.constructTracking = f;
  }

  resetTracking() {
    this.tracking.seq = null;
    this.tracking.qid = null;
    this.notify(TRACKING_RESET);
  }

  reset() {
    this.results = undefined;
    this.error = undefined;
    this.values = {};
    this.responseValues = {};
    this.notify(RESULTS_CHANGED);
    this.resetTracking();
  }

  _runSearch() {
    if (!this.beforeSearch(this)) {
      return
    }

    const client = new Sajari.Client(this.project, this.collection);
    const tracking = this.constructTracking(this);

    client.searchPipeline(this.pipeline, this.values, tracking, (err, res) => {
      // Discard this result if another (more recent query) has been sent through
      // with a different qid.
      if (this.tracking.qid !== tracking.i) {
        return;
      }

      // Discard this result if another (more recent query) has been sent.
      if (this.tracking.seq >= tracking.s) {
        return;
      }

      if (!res) {
        this.error = err || "No response.";
        if (console && console.error) {
          console.error("got error during search", this.error);
        }
        this.notify(RESULTS_CHANGED);
        return;
      }
      this.error = null;

      this.responseValues = res.values;
      this.results = res.searchResponse;
      this.notify(RESULTS_CHANGED);
    })
  }

  registerListener(type, listener) {
    this.listeners.push({ type, listener })
  }

  unregisterListener(type, listener) {
    this.listeners = this.listeners.filter(l => {
      if (l.type === type && l.listener === listener) {
        return false;
      }
      return true;
    });
  }

  notify(type, ...x) {
    this.listeners.forEach(l => {
      if (l.type === type) {
        l.listener(...x);
      }
    });
  }

  getError() {
    return this.error;
  }

  getResults() {
    return this.results;
  }

  getValues() {
    return this.values;
  }

  getResponseValues() {
    return this.responseValues;
  }

  beforeMergingValues(values) {
    // Only if values["q"] is set do we check if the value has changed.
    if (values["q"] !== undefined) {
      let prevQ = this.values["q"] || "";
      let currQ = values["q"];

      // Reset the tracking if the new query differs in prefix to the old.
      if (!currQ.startsWith(prevQ.substr(0, Math.min(currQ.length, 3)))) {
        this.resetTracking();
      }

      // If the query has changed then reset the page, but only if
      // we're not already trying to set it.
      if (currQ !== prevQ && values["page"] === undefined) {
        this.values["page"] = "1";
      }

      // Clear q.used when setting q to be "", but only if we're
      // not also setting q.used.
      if (currQ === "" && values["q.used"] === undefined) {
        delete this.responseValues["q.used"];
      }
    }

    // Only if values["filter"] is set do we check if the value has changed.
    if (values["filter"] !== undefined) {
      let prevFilter = this.values["filter"] || "";
      // Reset the page, but only if we're not already trying
      // to set it.
      if (prevFilter !== values["filter"] && values["page"] === undefined) {
        this.values["page"] = "1";
      }
    }
  }

  setValues(values, runSearch = false) {
    this.beforeMergingValues(values);

    // Merge values into this.values.
    for (let k in values) {
      if (values[k] === undefined || values[k] === null) {
        delete this.values[k];
      } else {
        this.values[k] = values[k];
      }
    }

    if (runSearch) {
      this._runSearch();
    }
    this.notify(VALUES_CHANGED);
  }
}

class State {
  constructor() {
    this._ns = {}

    this.ns = this.ns.bind(this);
  }

  default() {
    return this.ns("default");
  }

  ns(namespace) {
    let n = this._ns[namespace]
    if (!n) {
      n = new state(namespace);
      this._ns[namespace] = n
    }
    return n;
  }
}

const _state = new State();

export { _state as State, TRACKING_RESET, RESULT_CLICKED, RESULTS_CHANGED, VALUES_CHANGED }
<|endoftext|>


<commit_before>$.define("store", top.JSON && JSON.parse ? "support" :"support,json2", function(){
    var store = {
        //一些接口(空实现)
        disabled: false,
        set : function(key, value) {},
        get: function(key) {},
        remove : function(key) {},
        clear : function() {},
        transact : function(key, defaultVal, transactionFn) {
            var val = store.get(key)
            if (transactionFn == null) {
                transactionFn = defaultVal
                defaultVal = null
            }
            if (typeof val == 'undefined') {
                val = defaultVal || {}
            }
            transactionFn(val)
            store.set(key, val)
        },
        getAll : function() {},
        serialize : function(value) {
            return JSON.stringify(value)
        },
        deserialize : function(value) {
            if (typeof value != 'string') {
                return undefined
            }
            return JSON.parse(value)
        }
    }
    //http://wojodesign.com/full-browser-support-for-localstorage-without-cookies/
    //http://mathiasbynens.be/notes/localstorage-pattern
    var name = "test"+ (new Date-0), win = window, localStorageName = "localStorage",storage
    var supportLocalStorage = $.support.localStorage = false;
    try {
        localStorage.setItem(name,"mass");
        localStorage.removeItem(name);
        supportLocalStorage = true;
    }catch(e){}

    var supportGlobalStorage = $.support.globalStorage = false;
    try {
        supportGlobalStorage = win["globalStorage"][win.location.hostname]
    }catch(e){}

    if (supportLocalStorage) {
        storage = localStorage;
        $.mix(store,{//重写
            set: function(key, val) {
                if (val === undefined) {
                    return store.remove(key)
                }
                storage.setItem(key, store.serialize(val))
            },
            get:  function(key) {
                return store.deserialize(storage.getItem(key))
            },
            remove: function(key) {
                storage.removeItem(key)
            },
            clear: function() {
                storage.clear()
            },
            getAll: function() {
                var ret = {}
                for (var i=0; i<storage.length; ++i) {
                    var key = storage.key(i)
                    ret[key] = store.get(key)
                }
                return ret
            }
        })

    }else if(supportGlobalStorage){
        storage = supportGlobalStorage
        $.mix(store,{//重写
            set: function(key, val) {
                if (val === undefined) {
                    return store.remove(key)
                }
                storage[key] = store.serialize(val)
            },
            get:  function(key) {
                return store.deserialize(storage[key] && storage[key].value)
            },
            remove: function(key) {
                delete storage[key]
            },
            clear:  function() {
                for (var key in storage ) {
                    delete storage[key]
                }
            },
            getAll: function() {
                var ret = {}
                for (var i=0; i<storage.length; ++i) {
                    var key = storage.key(i)
                    ret[key] = store.get(key)
                }
                return ret
            }
        })

    }else if ( $.html.addBehavior) {
        var storageOwner,
        storageContainer
        //由于＃userData的存储仅适用于特定的路径，
        //我们需要以某种方式关联我们的数据到一个特定的路径。我们选择/favicon.ico作为一个非常安全的目标，
        //因为所有的浏览器都发出这个URL请求，而且这个请求即使是404也不会有危险。
        //我们可以通过一个ActiveXObject(htmlfle)对象的文档来干这事。
        //(参见:http://msdn.microsoft.com/en-us/library/aa752574(v = VS.85). aspx)
        //因为iframe的访问规则允许直接访问和操纵文档中的元素，即使是404。
        //这文档可以用来代替当前文档（这被限制在当前路径）执行＃userData的存储。
        try {
            storageContainer = new ActiveXObject('htmlfile')
            storageContainer.open()
            storageContainer.write('<s' + 'cript>document.w=window</s' + 'cript><iframe src="/favicon.ico"></frame>')
            storageContainer.close()
            storageOwner = storageContainer.w.frames[0].document
            storage = storageOwner.createElement('div')
        } catch(e) {
            storage = document.createElement('div')
            storageOwner = document.body
        }
        function withIEStorage(storeFunction) {
            return function() {
                var args = Array.apply([],arguments);
                args.unshift(storage)
                //  http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
                //  http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
                storageOwner.appendChild(storage)
                storage.addBehavior('#default#userData')
                storage.load(localStorageName)
                var result = storeFunction.apply(store, args)
                storageOwner.removeChild(storage)
                return result
            }
        }
        function ieKeyFix(key) {
            // 不能以数字开头
            // See https://github.com/marcuswestin/store.js/issues/40#issuecomment-4617842
            return '_'+key
        }
        $.mix(store,{//重写
            set:  withIEStorage(function(storage, key, val) {
                key = ieKeyFix(key)
                if (val === undefined) {
                    return store.remove(key)
                }
                storage.setAttribute(key, store.serialize(val))
                storage.save(localStorageName)
            }),
            get:  withIEStorage(function(storage, key) {
                key = ieKeyFix(key)
                return store.deserialize(storage.getAttribute(key))
            }),
            remove: withIEStorage(function(storage, key) {
                key = ieKeyFix(key)
                storage.removeAttribute(key)
                storage.save(localStorageName)
            }),
            clear:  withIEStorage(function(storage) {
                var attributes = storage.XMLDocument.documentElement.attributes
                storage.load(localStorageName)
                for (var i=0, attr; attr=attributes[i]; i++) {
                    storage.removeAttribute(attr.name)
                }
                storage.save(localStorageName)
            }),
            getAll: withIEStorage(function(storage) {
                var attributes = storage.XMLDocument.documentElement.attributes
                storage.load(localStorageName)
                var ret = {}
                for (var i=0, attr; attr=attributes[i]; ++i) {
                    ret[attr] = store.get(attr)
                }
                return ret
            })
        })
    }
    try {
        store.set(localStorageName, localStorageName)
        if (store.get(localStorageName) != localStorageName) {
            store.disabled = true
        }
        store.remove(localStorageName);
    } catch(e) {
        store.disabled = true
    }

    return store;
})
//这里提供了一个用cookie实现本地储存的方案 https://developer.mozilla.org/en/DOM/Storage
//http://www.cnblogs.com/NNUF/archive/2012/06/01/2531436.html<commit_msg>添加更多有用的资料<commit_after>$.define("store", top.JSON && JSON.parse ? "support" :"support,json2", function(){
    var store = {
        //一些接口(空实现)
        disabled: false,
        set : function(key, value) {},
        get: function(key) {},
        remove : function(key) {},
        clear : function() {},
        transact : function(key, defaultVal, transactionFn) {
            var val = store.get(key)
            if (transactionFn == null) {
                transactionFn = defaultVal
                defaultVal = null
            }
            if (typeof val == 'undefined') {
                val = defaultVal || {}
            }
            transactionFn(val)
            store.set(key, val)
        },
        getAll : function() {},
        serialize : function(value) {
            return JSON.stringify(value)
        },
        deserialize : function(value) {
            if (typeof value != 'string') {
                return undefined
            }
            return JSON.parse(value)
        }
    }
    //http://wojodesign.com/full-browser-support-for-localstorage-without-cookies/
    //http://mathiasbynens.be/notes/localstorage-pattern
    var name = "test"+ (new Date-0), win = window, localStorageName = "localStorage",storage
    var supportLocalStorage = $.support.localStorage = false;
    try {
        localStorage.setItem(name,"mass");
        localStorage.removeItem(name);
        supportLocalStorage = true;
    }catch(e){}

    var supportGlobalStorage = $.support.globalStorage = false;
    try {
        supportGlobalStorage = win["globalStorage"][win.location.hostname]
    }catch(e){}

    if (supportLocalStorage) {
        storage = localStorage;
        $.mix(store,{//重写
            set: function(key, val) {
                if (val === undefined) {
                    return store.remove(key)
                }
                storage.setItem(key, store.serialize(val))
            },
            get:  function(key) {
                return store.deserialize(storage.getItem(key))
            },
            remove: function(key) {
                storage.removeItem(key)
            },
            clear: function() {
                storage.clear()
            },
            getAll: function() {
                var ret = {}
                for (var i=0; i<storage.length; ++i) {
                    var key = storage.key(i)
                    ret[key] = store.get(key)
                }
                return ret
            }
        })

    }else if(supportGlobalStorage){
        storage = supportGlobalStorage
        $.mix(store,{//重写
            set: function(key, val) {
                if (val === undefined) {
                    return store.remove(key)
                }
                storage[key] = store.serialize(val)
            },
            get:  function(key) {
                return store.deserialize(storage[key] && storage[key].value)
            },
            remove: function(key) {
                delete storage[key]
            },
            clear:  function() {
                for (var key in storage ) {
                    delete storage[key]
                }
            },
            getAll: function() {
                var ret = {}
                for (var i=0; i<storage.length; ++i) {
                    var key = storage.key(i)
                    ret[key] = store.get(key)
                }
                return ret
            }
        })

    }else if ( $.html.addBehavior) {
        var storageOwner,
        storageContainer
        //由于＃userData的存储仅适用于特定的路径，
        //我们需要以某种方式关联我们的数据到一个特定的路径。我们选择/favicon.ico作为一个非常安全的目标，
        //因为所有的浏览器都发出这个URL请求，而且这个请求即使是404也不会有危险。
        //我们可以通过一个ActiveXObject(htmlfle)对象的文档来干这事。
        //(参见:http://msdn.microsoft.com/en-us/library/aa752574(v = VS.85). aspx)
        //因为iframe的访问规则允许直接访问和操纵文档中的元素，即使是404。
        //这文档可以用来代替当前文档（这被限制在当前路径）执行＃userData的存储。
        try {
            storageContainer = new ActiveXObject('htmlfile')
            storageContainer.open()
            storageContainer.write('<s' + 'cript>document.w=window</s' + 'cript><iframe src="/favicon.ico"></frame>')
            storageContainer.close()
            storageOwner = storageContainer.w.frames[0].document
            storage = storageOwner.createElement('div')
        } catch(e) {
            storage = document.createElement('div')
            storageOwner = document.body
        }
        function withIEStorage(storeFunction) {
            return function() {
                var args = Array.apply([],arguments);
                args.unshift(storage)
                //  http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
                //  http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
                storageOwner.appendChild(storage)
                storage.addBehavior('#default#userData')
                storage.load(localStorageName)
                var result = storeFunction.apply(store, args)
                storageOwner.removeChild(storage)
                return result
            }
        }
        function ieKeyFix(key) {
            // 不能以数字开头
            // See https://github.com/marcuswestin/store.js/issues/40#issuecomment-4617842
            return '_'+key
        }
        $.mix(store,{//重写
            set:  withIEStorage(function(storage, key, val) {
                key = ieKeyFix(key)
                if (val === undefined) {
                    return store.remove(key)
                }
                storage.setAttribute(key, store.serialize(val))
                storage.save(localStorageName)
            }),
            get:  withIEStorage(function(storage, key) {
                key = ieKeyFix(key)
                return store.deserialize(storage.getAttribute(key))
            }),
            remove: withIEStorage(function(storage, key) {
                key = ieKeyFix(key)
                storage.removeAttribute(key)
                storage.save(localStorageName)
            }),
            clear:  withIEStorage(function(storage) {
                var attributes = storage.XMLDocument.documentElement.attributes
                storage.load(localStorageName)
                for (var i=0, attr; attr=attributes[i]; i++) {
                    storage.removeAttribute(attr.name)
                }
                storage.save(localStorageName)
            }),
            getAll: withIEStorage(function(storage) {
                var attributes = storage.XMLDocument.documentElement.attributes
                storage.load(localStorageName)
                var ret = {}
                for (var i=0, attr; attr=attributes[i]; ++i) {
                    ret[attr] = store.get(attr)
                }
                return ret
            })
        })
    }
    try {
        store.set(localStorageName, localStorageName)
        if (store.get(localStorageName) != localStorageName) {
            store.disabled = true
        }
        store.remove(localStorageName);
    } catch(e) {
        store.disabled = true
    }

    return store;
})
//这里提供了一个用cookie实现本地储存的方案 https://developer.mozilla.org/en/DOM/Storage
//其他有用的资料
//http://www.cnblogs.com/NNUF/archive/2012/06/01/2531436.html
//http://www.cnblogs.com/zjcn/archive/2012/07/03/2575026.html<|endoftext|>


<commit_before>/**
 * 配置界面
 */
$(function(){
  var domBtnSettings = [
    '
',
      '',
        '',
        'iZhihu',
      '',
    '
'
  ].join('');

  var cbemptyimg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRFAAAAAAAApWe5zwAAAAF0Uk5TAEDm2GYAAAAMSURBVHjaYmAACDAAAAIAAU9tWeEAAAAASUVORK5CYII=';
    var domDlgSettings = [
      '
',
        '
',
          '配置选项',
          '',
        '
',
        '
',
          '
',
            '
',
            '
',
            	'
',
            		'
功能开关（更改后设置将立刻保存，但只有当页面再次打开时才会生效)
',
            	'
',
            	'
',
                '
在首页直接浏览常去话题		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setHomeTopics" name="HomeTopics" />
',
                '
改变网页样式外观		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setHomeLayout" name="HomeLayout" />
',
                '
调整首页「新动态」提醒按钮		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setHomeNoti" name="HomeNoti" />
',
                '
开启「首页分栏」		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setHomeFeedsColumns" name="HomeFeedsColumns" />
',
                '
将用户信息挪到回答下方		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setAuthorRear" name="AuthorRear" />
',
                '
开启「右舷评论」		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setRightComment" name="ShowComment" />	',
                '关闭时自动卷屏至对应条目		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setRightComment_AutoScrollPageWhenClosing" name="RightComment_AutoScrollPageWhenClosing" />
',
                '
开启「快速屏蔽」（加入黑名单/取消关注）功能		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setQuickBlock" name="QuickBlock" />
',
                '
开启「快速收藏」菜单		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setQuickFavo" name="QuickFavo" />
',
                '
开启「回答目录」		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setAuthorList" name="AuthorList" />
',
            	'
',
            '
',
            '
',
              '
',
                '当前版本：'+version+'；',
                '最后更新：'+updateDate,
                '
制作：',
                '@钢盅郭子，',
                '@天猪(刘勇)，',
                '@yukirock，',
                '@墨磊',
                '
感谢：',
                '@邓文博，@水云逸',
              '
',
              '
',
              '刷新网页',
            '
',
          '
',
        '
',
      '
'
    ].join('');

  $(domBtnSettings).insertBefore($('ul#top-nav-profile-dropdown li:last'))
  .click(function(){
    console.log(this);
    $('.modal-dialog-bg').show();
    $('input.t_rtjdchk','#izh-dlg-settings').each(function(i,e){
        if(utils.getCfg($(e).attr('name')))
            $(e).attr('checked','checked');
    });
    $('#izh-dlg-settings').css({'z-index':'123','position':'fixed','top': ($win.height() - $('#izh-dlg-settings').height()) / 2, 'left': ($win.width() - $('#izh-dlg-settings').width()) / 2}).fadeIn('slow');
  });
  var $dlg=$(domDlgSettings).appendTo(_doc.body);
  $dlg.drags({handler:'.modal-dialog-title-draggable'});
  $('.modal-dialog-title-close',$dlg).click(function(){
      $('.modal-dialog-bg').hide();
      $('#izh-dlg-settings').first().hide();
  });
  $('input.t_rtjdchk',$dlg).checkbox({cls:'t_jchkbox',empty:cbemptyimg});
  $('input.t_rtjdchk',$dlg).click(function(){
      var key=$(this).attr('name')
        , value=!this.checked;
      console.log(key+' = '+value);
      utils.setCfg(key,value);
  });
  $('#izhRefresh').click(function(){
    location.reload()
  })
})
<commit_msg>- Fixed tool-tips in settings<commit_after>/**
 * 配置界面
 */
$(function(){
  var domBtnSettings = [
    '
',
      '',
        '',
        'iZhihu',
      '',
    '
'
  ].join('');

  var cbemptyimg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRFAAAAAAAApWe5zwAAAAF0Uk5TAEDm2GYAAAAMSURBVHjaYmAACDAAAAIAAU9tWeEAAAAASUVORK5CYII=';
    var domDlgSettings = [
      '
',
        '
',
          '配置选项',
          '',
        '
',
        '
',
          '
',
            '
',
            '
',
            	'
',
            		'
功能开关（更改后设置将立刻保存，但只有当页面再次打开时才会生效)
',
            	'
',
            	'
',
                '
在首页直接浏览常去话题		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setHomeTopics" name="HomeTopics" />
',
                '
改变网页样式外观		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setHomeLayout" name="HomeLayout" />
',
                '
调整首页「新动态」提醒按钮		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setHomeNoti" name="HomeNoti" />
',
                '
开启「首页分栏」		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setHomeFeedsColumns" name="HomeFeedsColumns" />
',
                '
将用户信息挪到回答下方		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setAuthorRear" name="AuthorRear" />
',
                '
开启「右舷评论」		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setRightComment" name="ShowComment" />	',
                '关闭时自动卷屏至对应条目		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setRightComment_AutoScrollPageWhenClosing" name="RightComment_AutoScrollPageWhenClosing" />
',
                '
开启「快速屏蔽」（加入黑名单/取消关注）功能		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setQuickBlock" name="QuickBlock" />
',
                '
开启「快速收藏」菜单		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setQuickFavo" name="QuickFavo" />
',
                '
开启「回答目录」		<input type="checkbox" class="t_rtjdchk" id="iZhihu_setAuthorList" name="AuthorList" />
',
            	'
',
            '
',
            '
',
              '
',
                '当前版本：'+version+'；',
                '最后更新：'+updateDate,
                '
制作：',
                '@钢盅郭子，',
                '@天猪(刘勇)，',
                '@yukirock，',
                '@墨磊',
                '
感谢：',
                '@邓文博，@水云逸',
              '
',
              '
',
              '刷新网页',
            '
',
          '
',
        '
',
      '
'
    ].join('');

  $(domBtnSettings).insertBefore($('ul#top-nav-profile-dropdown li:last'))
  .click(function(){
    console.log(this);
    $('.modal-dialog-bg').show();
    $('input.t_rtjdchk','#izh-dlg-settings').each(function(i,e){
        if(utils.getCfg($(e).attr('name')))
            $(e).attr('checked','checked');
    });
    $('#izh-dlg-settings').css({'z-index':'99','position':'fixed','top': ($win.height() - $('#izh-dlg-settings').height()) / 2, 'left': ($win.width() - $('#izh-dlg-settings').width()) / 2}).fadeIn('slow');
  });
  var $dlg=$(domDlgSettings).appendTo(_doc.body);
  $dlg.drags({handler:'.modal-dialog-title-draggable'});
  $('.modal-dialog-title-close',$dlg).click(function(){
      $('.modal-dialog-bg').hide();
      $('#izh-dlg-settings').first().hide();
  });
  $('input.t_rtjdchk',$dlg).checkbox({cls:'t_jchkbox',empty:cbemptyimg});
  $('input.t_rtjdchk',$dlg).click(function(){
      var key=$(this).attr('name')
        , value=!this.checked;
      console.log(key+' = '+value);
      utils.setCfg(key,value);
  });
  $('#izhRefresh').click(function(){
    location.reload()
  })
})
<|endoftext|>


<commit_before><commit_msg>Jeyashree: index: Fill missing numbers (tbd)<commit_after>var inputStr = '1,2,3...6,7,8...11,12...15';
var arr = [];
var outputArr = [];
var intermediate = [];
var interStr = '';

/**
 * Convert to array
 */
var strToArr = function () {
  arr = inputStr.split('');

 console.log(arr);
  for (var i = 0; i < arr.length; i++) {
    if (typeof (arr[i]) === 'number' && typeof (arr[i+1]) === 'number') {
      intermediate.push(arr[i]);
      intermediate.push(arr[i+1]);
      interStr = intermediate.join();
      intermediate = [];
    }

  }
};

/**
 * Process to fill missing numbers
 */

var onProcess = function () {
  while (arr.length > 0) {
    var pointIdx = arr.indexOf('.');

    for (var i = 0; i < pointIdx; i++) {
      outputArr.push(arr[i]);
    }

    var startNum = parseInt(arr[pointIdx - 1]);
    var endNum = parseInt(arr[pointIdx + 3]);

    for (var i = startNum + 1; i <= endNum; i++) {
      outputArr.push(i);
    }

    for (var i = 0; i < endNum + 3; i++) {
      arr.shift();
    }

    // console.log(arr);

    console.log(outputArr);
  }

};

strToArr();
// onProcess();
<|endoftext|>


<commit_before>import Server from './server';

console.log('app');
console.log(Server);

let i = 0;

console.log(i);

const test = () => { '123' };

test();
test();
<commit_msg>update<commit_after>import Server from './server';

console.log(Server);
<|endoftext|>


<commit_before>"use strict";

// Load required modules
var express       = require('express');
var debug         = require('debug')('coinbox');
var cookieParser  = require('cookie-parser');
var session       = require('express-session');
var crypto        = require('crypto');
var bodyParser    = require('body-parser');
var models        = require('./models');
var config        = require(__dirname + '/config/security.json');

// Create an Express app
var app = express();

// Specify basic route middleware
app.use(express.static(__dirname + '/public'));
app.use(session({
  secret: config.session.secret,
  resave: false,
  saveUninitialized: true
}));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// Handle CSRF token management for all routes
app.use ('/', function (req, res, next) {
  debug(req.path);
  if (req.method === 'POST' || req.method === 'PUT') {
    if(req.get('X-XSRF-TOKEN') == req.session.XSRFToken){
      debug('Token match.')
      next();
    } else {
      debug('Token mismatch.')
      res.send({success: false, error: "XSRF Token mismatch."})
    }
  } else if (req.method === 'GET' && (!req.cookies['XSRF-TOKEN']
      || req.get('X-XSRF-TOKEN') != req.session.XSRFToken)) {
    debug('Get request missing CSRF token. Generating and saving...');
    var csrf = crypto.randomBytes(20).toString('hex');
    res.cookie('XSRF-TOKEN', csrf);
    req.session.XSRFToken = csrf;
    next();
  } else {
    next();
  }
});

// Pre-fetch the currently logged-in user for API requests
app.use ('/api', function (req, res, next) {
  if(req.session.userID){
    models.User.find(req.session.userId).then(function(user) {
      req.user = user;
      user.getInfo().then(function(info){
        req.userinfo = info;
        next();
      });
    });
  } else {
    next();
  }
});

// Define the modules that will handle various API routes
app.use('/api/users', require('./api/user'));

// Send all other routes to the single page front-end application
app.route('/*').get(function(req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

// Ensure the database model is sync'd with the db, then start the app
models.sequelize.sync().then(function () {
  var port   = process.env['PORT'] || 3000;
  var server = app.listen(port, function() {
    debug('Express server listening on port ' + server.address().port);
  });
});
<commit_msg>Set up route middleware needed to validate user tokens<commit_after>"use strict";

// Load required modules
var express       = require('express');
var debug         = require('debug')('coinbox');
var cookieParser  = require('cookie-parser');
var session       = require('express-session');
var crypto        = require('crypto');
var bodyParser    = require('body-parser');
var models        = require('./models');
var passport      = require('passport');
var BearerStrategy= require('passport-http-bearer').Strategy;
var config        = require(__dirname + '/config/security.json');

// Create an Express app
var app = express();

// Specify basic route middleware
app.use(express.static(__dirname + '/public'));
app.use(session({
  secret: config.session.secret,
  resave: false,
  saveUninitialized: true
}));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// Initialize authentication library
app.use(passport.initialize());

// Handle CSRF token management for all routes
app.use ('/', function (req, res, next) {
  debug(req.path);
  if (req.method === 'POST' || req.method === 'PUT') {
    if(req.get('X-XSRF-TOKEN') == req.session.XSRFToken){
      debug('Token match.')
      next();
    } else {
      debug('Token mismatch.')
      res.send({success: false, error: "XSRF Token mismatch."})
    }
  } else if (req.method === 'GET' && (!req.cookies['XSRF-TOKEN']
      || req.get('X-XSRF-TOKEN') != req.session.XSRFToken)) {
    debug('Get request missing CSRF token. Generating and saving...');
    var csrf = crypto.randomBytes(20).toString('hex');
    res.cookie('XSRF-TOKEN', csrf);
    req.session.XSRFToken = csrf;
    next();
  } else {
    next();
  }
});

// Pre-fetch the currently logged-in user for API requests
app.use ('/api', function (req, res, next) {
  if(req.session.userID){
    models.User.find(req.session.userId).then(function(user) {
      req.user = user;
      user.getInfo().then(function(info){
        req.userinfo = info;
        next();
      });
    });
  } else {
    next();
  }
});

// Define the modules that will handle various API routes
app.use('/api/users', require('./api/user'));

// Set up OAuth Authentication Strategy
passport.use(new BearerStrategy(function (token, done) {
  models.User.find({ where: {token: token}}).then(function(user) {
    if (!user) return done(null, false);
    return done(null, user);
  });
}));

// Send all other routes to the single page front-end application
app.route('/*').get(function(req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

// Ensure the database model is sync'd with the db, then start the app
models.sequelize.sync().then(function () {
  var port   = process.env['PORT'] || 3000;
  var server = app.listen(port, function() {
    debug('Express server listening on port ' + server.address().port);
  });
});
<|endoftext|>


<commit_before>import koa from 'koa'
import mount from 'koa-mount'
import helmet from 'koa-helmet'
import logger from 'koa-logger'
import responseTime from 'koa-response-time'
import session from 'koa-generic-session'
import level from 'levelup'
import store from 'koa-level'
import staticCache from 'koa-static-cache'
import cors from 'koa-cors'
import basicAuth from './passport/basic'
import jwtAuth from './passport/local-jwt'
import facebookAuth from './passport/facebook'
import googleAuth from './passport/google'
import localAuth from './passport/local'
import router from './routes'
import path from 'path'
import co from 'co'
import favicon from 'koa-favicon'
import services from 'src/server/services'
import adminServices from 'src/server/services/admin'
import models from 'src/server/db/models'
import locale from 'koa-locale'
import bodyParser from 'koa-bodyparser'
import noCache from 'koa-no-cache'

const debug = require('debug')
const leveldb = level('./storage/leveldb')

const app = koa()
// ES7 async
// app.experimental = true

const env = process.env.NODE_ENV || 'development'

co(function *() {
  if (env === 'development') {
    const webpack = require('webpack')
    const config = require('config/webpack/'+ env +'.config')
    const compiler = webpack(config.webpack)
    app.use(require('koa-webpack-dev-middleware')(compiler, config.server.options))
    app.use(require('koa-webpack-hot-middleware')(compiler))
  }
})

locale(app, 'lang')
app.use(responseTime())
app.use(logger())
app.use(helmet())

if (env === 'production') {
  app.use(require('koa-conditional-get')())
  app.use(require('koa-etag')())
  app.use(require('koa-compressor')())

  // Cache pages
  const cache = require('lru-cache')({ maxAge: 3000 })
  app.use(require('koa-cash')({
    get: function* (key) {
      return cache.get(key)
    },
    set: function* (key, value) {
      cache.set(key, value)
    }
  }))
}

if (env === 'development') {
  debug.enable('dev,koa')
  require('blocked')((ms) => debug('koa')(`blocked for ${ms}ms`))
}

const cacheOpts = { maxAge: 86400000, gzip: true }

if (env === 'development') {
  app.use(
    mount(
      '/assets',
      require('koa-proxy')({ host: 'http://0.0.0.0:3000' })
    )
  )
} else {
  app.use(
    mount('/assets',
      staticCache(
        path.join(__dirname, '../../public/assets'),
        cacheOpts
      )
    )
  )
}

app.use(mount('/images',
  staticCache(
    path.join(__dirname, '../../images'),
    cacheOpts
  )
))

app.use(mount('/uploads',
  staticCache(
    path.join(__dirname, '../../uploads'),
    cacheOpts
  )
))

app.use(favicon(path.join(__dirname, '../../images/app/v2.3-t/favicon.ico')))

app.keys = require('config').app.SESSION_KEYS
app.use(
  session(
    {
	  proxy : true,
	  cookie: {
      path: '/',
      httpOnly: true,
      maxAge: 24 * 60 * 60 * 1000,
      overwrite: true,
      signed: true,
      secure: true,
      sameSite: 'lax'
    }, store: store({ db: leveldb }) }
  )
)

app.use(noCache({
  paths: ['/api/v1/(.*)'],
  types: ['application/json']
}))

app.use(mount('/api/v1', cors()))
app.use(mount('/api/v1', services.v1))
app.use(mount('/api/v1', basicAuth.initialize()))
app.use(mount('/api/v1', jwtAuth.initialize()))

app.use(bodyParser())
app.use(localAuth.initialize())
app.use(facebookAuth.initialize())
app.use(googleAuth.initialize())
app.use(router.routes())

app.use(mount('/api/admin/v1', adminServices.v1))

import adminView from './adminView'
adminView(app)

import appView from './appView'
appView(app)

const port = process.env.PORT || 3000

co(function *() {
  const connection = yield models.sequelize.sync()
  if (connection) {
    app.listen(port)
    debug('koa')(`App started listening on port ${port}`)
  }
})

module.exports = app
<commit_msg>Update server side settings<commit_after>import koa from 'koa'
import mount from 'koa-mount'
import helmet from 'koa-helmet'
import logger from 'koa-logger'
import responseTime from 'koa-response-time'
import session from 'koa-generic-session'
import level from 'levelup'
import store from 'koa-level'
import staticCache from 'koa-static-cache'
import cors from 'koa-cors'
import basicAuth from './passport/basic'
import jwtAuth from './passport/local-jwt'
import facebookAuth from './passport/facebook'
import googleAuth from './passport/google'
import localAuth from './passport/local'
import router from './routes'
import path from 'path'
import co from 'co'
import favicon from 'koa-favicon'
import services from 'src/server/services'
import adminServices from 'src/server/services/admin'
import models from 'src/server/db/models'
import locale from 'koa-locale'
import bodyParser from 'koa-bodyparser'
import noCache from 'koa-no-cache'

const debug = require('debug')
const leveldb = level('./storage/leveldb')

const app = koa()
// ES7 async
// app.experimental = true

const env = process.env.NODE_ENV || 'development'

co(function *() {
  if (env === 'development') {
    const webpack = require('webpack')
    const config = require('config/webpack/'+ env +'.config')
    const compiler = webpack(config.webpack)
    app.use(require('koa-webpack-dev-middleware')(compiler, config.server.options))
    app.use(require('koa-webpack-hot-middleware')(compiler))
  }
})

locale(app, 'lang')
app.use(responseTime())
app.use(logger())
app.use(helmet())

if (env === 'production') {
  app.use(require('koa-conditional-get')())
  app.use(require('koa-etag')())
  app.use(require('koa-compressor')())

  // Cache pages
  const cache = require('lru-cache')({ maxAge: 3000 })
  app.use(require('koa-cash')({
    get: function* (key) {
      return cache.get(key)
    },
    set: function* (key, value) {
      cache.set(key, value)
    }
  }))
}

if (env === 'development') {
  debug.enable('dev,koa')
  require('blocked')((ms) => debug('koa')(`blocked for ${ms}ms`))
}

const cacheOpts = { maxAge: 86400000, gzip: true }

if (env === 'development') {
  app.use(
    mount(
      '/assets',
      require('koa-proxy')({ host: 'http://0.0.0.0:3000' })
    )
  )
} else {
  app.use(
    mount('/assets',
      staticCache(
        path.join(__dirname, '../../public/assets'),
        cacheOpts
      )
    )
  )
}

app.use(mount('/images',
  staticCache(
    path.join(__dirname, '../../images'),
    cacheOpts
  )
))

app.use(mount('/uploads',
  staticCache(
    path.join(__dirname, '../../uploads'),
    cacheOpts
  )
))

app.use(favicon(path.join(__dirname, '../../images/app/v2.3-t/favicon.ico')))

app.keys = require('config').app.SESSION_KEYS
app.use(
  session(
    {
	  proxy : true,
	  cookie: {
      path: '/',
      httpOnly: true,
      maxAge: 24 * 60 * 60 * 1000,
      overwrite: true,
      signed: true,
      secure: true,
      sameSite: 'strict'
    }, store: store({ db: leveldb }) }
  )
)

app.use(noCache({
  paths: ['/api/v1/(.*)'],
  types: ['application/json']
}))

app.use(mount('/api/v1', cors()))
app.use(mount('/api/v1', services.v1))
app.use(mount('/api/v1', basicAuth.initialize()))
app.use(mount('/api/v1', jwtAuth.initialize()))

app.use(bodyParser())
app.use(localAuth.initialize())
app.use(facebookAuth.initialize())
app.use(googleAuth.initialize())
app.use(router.routes())

app.use(mount('/api/admin/v1', adminServices.v1))

import adminView from './adminView'
adminView(app)

import appView from './appView'
appView(app)

const port = process.env.PORT || 3000

co(function *() {
  const connection = yield models.sequelize.sync()
  if (connection) {
    app.listen(port)
    debug('koa')(`App started listening on port ${port}`)
  }
})

module.exports = app
<|endoftext|>