(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

var _index = require(9);

(0, _index.showImageGallery)(true);

},{"9":9}],2:[function(require,module,exports){
"use strict";

exports.defineProperty = function (obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });
  } else {
    obj[key] = value;
  }return obj;
};exports.inherits = function (subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
  }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};exports.possibleConstructorReturn = function (self, call) {
  if (!self) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }return call && (typeof call === "object" || typeof call === "function") ? call : self;
};exports.createClass = function () {
  function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
    }
  }return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
  };
}();exports.classCallCheck = function (instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
};exports.slicedToArray = function () {
  function sliceIterator(arr, i) {
    var _arr = [];var _n = true;var _d = false;var _e = undefined;try {
      for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
        _arr.push(_s.value);if (i && _arr.length === i) break;
      }
    } catch (err) {
      _d = true;_e = err;
    } finally {
      try {
        if (!_n && _i["return"]) _i["return"]();
      } finally {
        if (_d) throw _e;
      }
    }return _arr;
  }return function (arr, i) {
    if (Array.isArray(arr)) {
      return arr;
    } else if (Symbol.iterator in Object(arr)) {
      return sliceIterator(arr, i);
    } else {
      throw new TypeError("Invalid attempt to destructure non-iterable instance");
    }
  };
}();exports.get = function get(object, property, receiver) {
  if (object === null) object = Function.prototype;var desc = Object.getOwnPropertyDescriptor(object, property);if (desc === undefined) {
    var parent = Object.getPrototypeOf(object);if (parent === null) {
      return undefined;
    } else {
      return get(parent, property, receiver);
    }
  } else if ("value" in desc) {
    return desc.value;
  } else {
    var getter = desc.get;if (getter === undefined) {
      return undefined;
    }return getter.call(receiver);
  }
};

},{}],3:[function(require,module,exports){
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (factory((global.preact = global.preact || {})));
}(this, function (exports) {
    function VNode(nodeName, attributes, children) {
      /** @type {string|function} */
      this.nodeName = nodeName;

      /** @type {object<string>|undefined} */
      this.attributes = attributes;

      /** @type {array<VNode>|undefined} */
      this.children = children;

      /** Reference to the given key. */
      this.key = attributes && attributes.key;
    }

    var options = {

      /** If `true`, `prop` changes trigger synchronous component updates.
      *	@name syncComponentUpdates
      *	@type Boolean
      *	@default true
      */
      //syncComponentUpdates: true,

      /** Processes all created VNodes.
      *	@param {VNode} vnode	A newly-created VNode to normalize/process
      */
      //vnode(vnode) { }

      /** Hook invoked after a component is mounted. */
      // afterMount(component) { }

      /** Hook invoked after the DOM is updated with a component's latest render. */
      // afterUpdate(component) { }

      /** Hook invoked immediately before a component is unmounted. */
      // beforeUnmount(component) { }
    };

    var stack = [];

    /** JSX/hyperscript reviver
    *	Benchmarks: https://esbench.com/bench/57ee8f8e330ab09900a1a1a0
     *	@see http://jasonformat.com/wtf-is-jsx
     *	@public
     *  @example
     *  /** @jsx h *\/
     *  import { render, h } from 'preact';
     *  render(<span>foo</span>, document.body);
     */

    function h(nodeName, attributes) {
      var children = [],
          lastSimple,
          child,
          simple,
          i;
      for (i = arguments.length; i-- > 2;) {
          stack.push(arguments[i]);
      }
      if (attributes && attributes.children) {
          if (!stack.length) stack.push(attributes.children);
          delete attributes.children;
      }
      while (stack.length) {
          if ((child = stack.pop()) instanceof Array) {
              for (i = child.length; i--;) stack.push(child[i]);
          } else if (child != null && child !== false) {
              if (typeof child == 'number' || child === true) child = String(child);
              simple = typeof child == 'string';
              if (simple && lastSimple) {
                  children[children.length - 1] += child;
              } else {
                  children.push(child);
                  lastSimple = simple;
              }
          }
      }

      var p = new VNode(nodeName, attributes || undefined, children);

      // if a "vnode hook" is defined, pass every created VNode to it
      if (options.vnode) options.vnode(p);

      return p;
    }

    function extend(obj, props) {
      if (props) {
          for (var i in props) {
              obj[i] = props[i];
          }
      }
      return obj;
    }

    /** Fast clone. Note: does not filter out non-own properties.
     *	@see https://esbench.com/bench/56baa34f45df6895002e03b6
     */

    function clone(obj) {
      return extend({}, obj);
    }

    /** Get a deep property value from the given object, expressed in dot-notation.
     *	@private
     */

    function delve(obj, key) {
      for (var p = key.split('.'), i = 0; i < p.length && obj; i++) {
          obj = obj[p[i]];
      }
      return obj;
    }

    /** @private is the given object a Function? */

    function isFunction(obj) {
      return 'function' === typeof obj;
    }

    /** @private is the given object a String? */

    function isString(obj) {
      return 'string' === typeof obj;
    }

    /** Convert a hashmap of CSS classes to a space-delimited className string
     *	@private
     */

    function hashToClassName(c) {
      var str = '';
      for (var prop in c) {
          if (c[prop]) {
              if (str) str += ' ';
              str += prop;
          }
      }
      return str;
    }

    /** Just a memoized String#toLowerCase */
    var lcCache = {};
    var toLowerCase = function toLowerCase(s) {
      return lcCache[s] || (lcCache[s] = s.toLowerCase());
    };

    /** Call a function asynchronously, as soon as possible.
     *	@param {Function} callback
     */
    var resolved = typeof Promise !== 'undefined' && Promise.resolve();
    var defer = resolved ? function (f) {
      resolved.then(f);
    } : setTimeout;

    function cloneElement(vnode, props) {
      return h(vnode.nodeName, extend(clone(vnode.attributes), props), arguments.length > 2 ? [].slice.call(arguments, 2) : vnode.children);
    }

    var EMPTY = {};

    var ATTR_KEY = typeof Symbol !== 'undefined' ? Symbol['for']('preactattr') : '__preactattr_';

    // DOM properties that should NOT have "px" added when numeric
    var NON_DIMENSION_PROPS = {
      boxFlex: 1, boxFlexGroup: 1, columnCount: 1, fillOpacity: 1, flex: 1, flexGrow: 1,
      flexPositive: 1, flexShrink: 1, flexNegative: 1, fontWeight: 1, lineClamp: 1, lineHeight: 1,
      opacity: 1, order: 1, orphans: 1, strokeOpacity: 1, widows: 1, zIndex: 1, zoom: 1
    };

    // DOM event types that do not bubble and should be attached via useCapture
    var NON_BUBBLING_EVENTS = { blur: 1, error: 1, focus: 1, load: 1, resize: 1, scroll: 1 };

    /** Create an Event handler function that sets a given state property.
     *	@param {Component} component	The component whose state should be updated
     *	@param {string} key				A dot-notated key path to update in the component's state
     *	@param {string} eventPath		A dot-notated key path to the value that should be retrieved from the Event or component
     *	@returns {function} linkedStateHandler
     *	@private
     */

    function createLinkedState(component, key, eventPath) {
      var path = key.split('.');
      return function (e) {
          var t = e && e.target || this,
              state = {},
              obj = state,
              v = isString(eventPath) ? delve(e, eventPath) : t.nodeName ? t.type.match(/^che|rad/) ? t.checked : t.value : e,
              i = 0;
          for (; i < path.length - 1; i++) {
              obj = obj[path[i]] || (obj[path[i]] = !i && component.state[path[i]] || {});
          }
          obj[path[i]] = v;
          component.setState(state);
      };
    }

    /** Managed queue of dirty components to be re-rendered */

    // items/itemsOffline swap on each rerender() call (just a simple pool technique)
    var items = [];

    function enqueueRender(component) {
      if (!component._dirty && (component._dirty = true) && items.push(component) == 1) {
          (options.debounceRendering || defer)(rerender);
      }
    }

    function rerender() {
      var p,
          list = items;
      items = [];
      while (p = list.pop()) {
          if (p._dirty) renderComponent(p);
      }
    }

    /** Check if a VNode is a reference to a stateless functional component.
     *	A function component is represented as a VNode whose `nodeName` property is a reference to a function.
     *	If that function is not a Component (ie, has no `.render()` method on a prototype), it is considered a stateless functional component.
     *	@param {VNode} vnode	A VNode
     *	@private
     */

    function isFunctionalComponent(vnode) {
      var nodeName = vnode && vnode.nodeName;
      return nodeName && isFunction(nodeName) && !(nodeName.prototype && nodeName.prototype.render);
    }

    /** Construct a resultant VNode from a VNode referencing a stateless functional component.
     *	@param {VNode} vnode	A VNode with a `nodeName` property that is a reference to a function.
     *	@private
     */

    function buildFunctionalComponent(vnode, context) {
      return vnode.nodeName(getNodeProps(vnode), context || EMPTY);
    }

    /** Check if two nodes are equivalent.
     *	@param {Element} node
     *	@param {VNode} vnode
     *	@private
     */

    function isSameNodeType(node, vnode) {
      if (isString(vnode)) {
          return node instanceof Text;
      }
      if (isString(vnode.nodeName)) {
          return !node._componentConstructor && isNamedNode(node, vnode.nodeName);
      }
      if (isFunction(vnode.nodeName)) {
          return (node._componentConstructor ? node._componentConstructor === vnode.nodeName : true) || isFunctionalComponent(vnode);
      }
    }

    function isNamedNode(node, nodeName) {
      return node.normalizedNodeName === nodeName || toLowerCase(node.nodeName) === toLowerCase(nodeName);
    }

    /**
     * Reconstruct Component-style `props` from a VNode.
     * Ensures default/fallback values from `defaultProps`:
     * Own-properties of `defaultProps` not present in `vnode.attributes` are added.
     * @param {VNode} vnode
     * @returns {Object} props
     */

    function getNodeProps(vnode) {
      var props = clone(vnode.attributes);
      props.children = vnode.children;

      var defaultProps = vnode.nodeName.defaultProps;
      if (defaultProps) {
          for (var i in defaultProps) {
              if (props[i] === undefined) {
                  props[i] = defaultProps[i];
              }
          }
      }

      return props;
    }

    /** Removes a given DOM Node from its parent. */

    function removeNode(node) {
      var p = node.parentNode;
      if (p) p.removeChild(node);
    }

    /** Set a named attribute on the given Node, with special behavior for some names and event handlers.
     *	If `value` is `null`, the attribute/handler will be removed.
     *	@param {Element} node	An element to mutate
     *	@param {string} name	The name/key to set, such as an event or attribute name
     *	@param {any} value		An attribute value, such as a function to be used as an event handler
     *	@param {any} previousValue	The last value that was set for this name/node pair
     *	@private
     */

    function setAccessor(node, name, old, value, isSvg) {

      if (name === 'className') name = 'class';

      if (name === 'class' && value && typeof value === 'object') {
          value = hashToClassName(value);
      }

      if (name === 'key') {
          // ignore
      } else if (name === 'class' && !isSvg) {
              node.className = value || '';
          } else if (name === 'style') {
              if (!value || isString(value) || isString(old)) {
                  node.style.cssText = value || '';
              }
              if (value && typeof value === 'object') {
                  if (!isString(old)) {
                      for (var i in old) {
                          if (!(i in value)) node.style[i] = '';
                      }
                  }
                  for (var i in value) {
                      node.style[i] = typeof value[i] === 'number' && !NON_DIMENSION_PROPS[i] ? value[i] + 'px' : value[i];
                  }
              }
          } else if (name === 'dangerouslySetInnerHTML') {
              node.innerHTML = value && value.__html || '';
          } else if (name[0] == 'o' && name[1] == 'n') {
              var l = node._listeners || (node._listeners = {});
              name = toLowerCase(name.substring(2));
              // @TODO: this might be worth it later, un-breaks focus/blur bubbling in IE9:
              // if (node.attachEvent) name = name=='focus'?'focusin':name=='blur'?'focusout':name;
              if (value) {
                  if (!l[name]) node.addEventListener(name, eventProxy, !!NON_BUBBLING_EVENTS[name]);
              } else if (l[name]) {
                  node.removeEventListener(name, eventProxy, !!NON_BUBBLING_EVENTS[name]);
              }
              l[name] = value;
          } else if (name !== 'list' && name !== 'type' && !isSvg && name in node) {
              setProperty(node, name, value == null ? '' : value);
              if (value == null || value === false) node.removeAttribute(name);
          } else {
              var ns = isSvg && name.match(/^xlink\:?(.+)/);
              if (value == null || value === false) {
                  if (ns) node.removeAttributeNS('http://www.w3.org/1999/xlink', toLowerCase(ns[1]));else node.removeAttribute(name);
              } else if (typeof value !== 'object' && !isFunction(value)) {
                  if (ns) node.setAttributeNS('http://www.w3.org/1999/xlink', toLowerCase(ns[1]), value);else node.setAttribute(name, value);
              }
          }
    }

    /** Attempt to set a DOM property to the given value.
     *	IE & FF throw for certain property-value combinations.
     */
    function setProperty(node, name, value) {
      try {
          node[name] = value;
      } catch (e) {}
    }

    /** Proxy an event to hooked event handlers
     *	@private
     */
    function eventProxy(e) {
      return this._listeners[e.type](options.event && options.event(e) || e);
    }

    /** DOM node pool, keyed on nodeName. */

    var nodes = {};

    function collectNode(node) {
      removeNode(node);

      if (node instanceof Element) {
          node._component = node._componentConstructor = null;

          var _name = node.normalizedNodeName || toLowerCase(node.nodeName);
          (nodes[_name] || (nodes[_name] = [])).push(node);
      }
    }

    function createNode(nodeName, isSvg) {
      var name = toLowerCase(nodeName),
          node = nodes[name] && nodes[name].pop() || (isSvg ? document.createElementNS('http://www.w3.org/2000/svg', nodeName) : document.createElement(nodeName));
      node.normalizedNodeName = name;
      return node;
    }

    /** Queue of components that have been mounted and are awaiting componentDidMount */
    var mounts = [];

    /** Diff recursion count, used to track the end of the diff cycle. */
    var diffLevel = 0;

    /** Global flag indicating if the diff is currently within an SVG */
    var isSvgMode = false;

    /** Global flag indicating if the diff is performing hydration */
    var hydrating = false;

    /** Invoke queued componentDidMount lifecycle methods */

    function flushMounts() {
      var c;
      while (c = mounts.pop()) {
          if (options.afterMount) options.afterMount(c);
          if (c.componentDidMount) c.componentDidMount();
      }
    }

    /** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
     *	@param {Element} [dom=null]		A DOM node to mutate into the shape of the `vnode`
     *	@param {VNode} vnode			A VNode (with descendants forming a tree) representing the desired DOM structure
     *	@returns {Element} dom			The created/mutated element
     *	@private
     */

    function diff(dom, vnode, context, mountAll, parent, componentRoot) {
      // diffLevel having been 0 here indicates initial entry into the diff (not a subdiff)
      if (! diffLevel++) {
          // when first starting the diff, check if we're diffing an SVG or within an SVG
          isSvgMode = parent instanceof SVGElement;

          // hydration is inidicated by the existing element to be diffed not having a prop cache
          hydrating = dom && !(ATTR_KEY in dom);
      }

      var ret = idiff(dom, vnode, context, mountAll);

      // append the element if its a new parent
      if (parent && ret.parentNode !== parent) parent.appendChild(ret);

      // diffLevel being reduced to 0 means we're exiting the diff
      if (! --diffLevel) {
          hydrating = false;
          // invoke queued componentDidMount lifecycle methods
          if (!componentRoot) flushMounts();
      }

      return ret;
    }

    function idiff(dom, vnode, context, mountAll) {
      var originalAttributes = vnode && vnode.attributes;

      // Resolve ephemeral Pure Functional Components
      while (isFunctionalComponent(vnode)) {
          vnode = buildFunctionalComponent(vnode, context);
      }

      // empty values (null & undefined) render as empty Text nodes
      if (vnode == null) vnode = '';

      // Fast case: Strings create/update Text nodes.
      if (isString(vnode)) {
          // update if it's already a Text node
          if (dom && dom instanceof Text) {
              if (dom.nodeValue != vnode) {
                  dom.nodeValue = vnode;
              }
          } else {
              // it wasn't a Text node: replace it with one and recycle the old Element
              if (dom) recollectNodeTree(dom);
              dom = document.createTextNode(vnode);
          }

          // Mark for non-hydration updates
          dom[ATTR_KEY] = true;
          return dom;
      }

      // If the VNode represents a Component, perform a component diff.
      if (isFunction(vnode.nodeName)) {
          return buildComponentFromVNode(dom, vnode, context, mountAll);
      }

      var out = dom,
          nodeName = String(vnode.nodeName),
          // @TODO this masks undefined component errors as `<undefined>`
      prevSvgMode = isSvgMode,
          vchildren = vnode.children;

      // SVGs have special namespace stuff.
      // This tracks entering and exiting that namespace when descending through the tree.
      isSvgMode = nodeName === 'svg' ? true : nodeName === 'foreignObject' ? false : isSvgMode;

      if (!dom) {
          // case: we had no element to begin with
          // - create an element to with the nodeName from VNode
          out = createNode(nodeName, isSvgMode);
      } else if (!isNamedNode(dom, nodeName)) {
          // case: Element and VNode had different nodeNames
          // - need to create the correct Element to match VNode
          // - then migrate children from old to new

          out = createNode(nodeName, isSvgMode);

          // move children into the replacement node
          while (dom.firstChild) out.appendChild(dom.firstChild);

          // if the previous Element was mounted into the DOM, replace it inline
          if (dom.parentNode) dom.parentNode.replaceChild(out, dom);

          // recycle the old element (skips non-Element node types)
          recollectNodeTree(dom);
      }

      var fc = out.firstChild,
          props = out[ATTR_KEY];

      // Attribute Hydration: if there is no prop cache on the element,
      // ...create it and populate it with the element's attributes.
      if (!props) {
          out[ATTR_KEY] = props = {};
          for (var a = out.attributes, i = a.length; i--;) {
              props[a[i].name] = a[i].value;
          }
      }

      // Apply attributes/props from VNode to the DOM Element:
      diffAttributes(out, vnode.attributes, props);

      // Optimization: fast-path for elements containing a single TextNode:
      if (!hydrating && vchildren && vchildren.length === 1 && typeof vchildren[0] === 'string' && fc && fc instanceof Text && !fc.nextSibling) {
          if (fc.nodeValue != vchildren[0]) {
              fc.nodeValue = vchildren[0];
          }
      }
      // otherwise, if there are existing or new children, diff them:
      else if (vchildren && vchildren.length || fc) {
              innerDiffNode(out, vchildren, context, mountAll);
          }

      // invoke original ref (from before resolving Pure Functional Components):
      if (originalAttributes && typeof originalAttributes.ref === 'function') {
          (props.ref = originalAttributes.ref)(out);
      }

      isSvgMode = prevSvgMode;

      return out;
    }

    /** Apply child and attribute changes between a VNode and a DOM Node to the DOM.
     *	@param {Element} dom		Element whose children should be compared & mutated
     *	@param {Array} vchildren	Array of VNodes to compare to `dom.childNodes`
     *	@param {Object} context		Implicitly descendant context object (from most recent `getChildContext()`)
     *	@param {Boolean} moutAll
     */
    function innerDiffNode(dom, vchildren, context, mountAll) {
      var originalChildren = dom.childNodes,
          children = [],
          keyed = {},
          keyedLen = 0,
          min = 0,
          len = originalChildren.length,
          childrenLen = 0,
          vlen = vchildren && vchildren.length,
          j,
          c,
          vchild,
          child;

      if (len) {
          for (var i = 0; i < len; i++) {
              var _child = originalChildren[i],
                  props = _child[ATTR_KEY],
                  key = vlen ? (c = _child._component) ? c.__key : props ? props.key : null : null;
              if (key != null) {
                  keyedLen++;
                  keyed[key] = _child;
              } else if (hydrating || props) {
                  children[childrenLen++] = _child;
              }
          }
      }

      if (vlen) {
          for (var i = 0; i < vlen; i++) {
              vchild = vchildren[i];
              child = null;

              // if (isFunctionalComponent(vchild)) {
              // 	vchild = buildFunctionalComponent(vchild);
              // }

              // attempt to find a node based on key matching
              var key = vchild.key;
              if (key != null) {
                  if (keyedLen && key in keyed) {
                      child = keyed[key];
                      keyed[key] = undefined;
                      keyedLen--;
                  }
              }
              // attempt to pluck a node of the same type from the existing children
              else if (!child && min < childrenLen) {
                      for (j = min; j < childrenLen; j++) {
                          c = children[j];
                          if (c && isSameNodeType(c, vchild)) {
                              child = c;
                              children[j] = undefined;
                              if (j === childrenLen - 1) childrenLen--;
                              if (j === min) min++;
                              break;
                          }
                      }
                  }

              // morph the matched/found/created DOM child to match vchild (deep)
              child = idiff(child, vchild, context, mountAll);

              if (child && child !== dom) {
                  if (i >= len) {
                      dom.appendChild(child);
                  } else if (child !== originalChildren[i]) {
                      if (child === originalChildren[i + 1]) {
                          removeNode(originalChildren[i]);
                      }
                      dom.insertBefore(child, originalChildren[i] || null);
                  }
              }
          }
      }

      if (keyedLen) {
          for (var i in keyed) {
              if (keyed[i]) recollectNodeTree(keyed[i]);
          }
      }

      // remove orphaned children
      while (min <= childrenLen) {
          child = children[childrenLen--];
          if (child) recollectNodeTree(child);
      }
    }

    /** Recursively recycle (or just unmount) a node an its descendants.
     *	@param {Node} node						DOM node to start unmount/removal from
     *	@param {Boolean} [unmountOnly=false]	If `true`, only triggers unmount lifecycle, skips removal
     */

    function recollectNodeTree(node, unmountOnly) {
      var component = node._component;
      if (component) {
          // if node is owned by a Component, unmount that component (ends up recursing back here)
          unmountComponent(component, !unmountOnly);
      } else {
          // If the node's VNode had a ref function, invoke it with null here.
          // (this is part of the React spec, and smart for unsetting references)
          if (node[ATTR_KEY] && node[ATTR_KEY].ref) node[ATTR_KEY].ref(null);

          if (!unmountOnly) {
              collectNode(node);
          }

          // Recollect/unmount all children.
          // - we use .lastChild here because it causes less reflow than .firstChild
          // - it's also cheaper than accessing the .childNodes Live NodeList
          var c;
          while (c = node.lastChild) recollectNodeTree(c, unmountOnly);
      }
    }

    /** Apply differences in attributes from a VNode to the given DOM Element.
     *	@param {Element} dom		Element with attributes to diff `attrs` against
     *	@param {Object} attrs		The desired end-state key-value attribute pairs
     *	@param {Object} old			Current/previous attributes (from previous VNode or element's prop cache)
     */
    function diffAttributes(dom, attrs, old) {
      // remove attributes no longer present on the vnode by setting them to undefined
      for (var _name in old) {
          if (!(attrs && _name in attrs) && old[_name] != null) {
              setAccessor(dom, _name, old[_name], old[_name] = undefined, isSvgMode);
          }
      }

      // add new & update changed attributes
      if (attrs) {
          for (var _name2 in attrs) {
              if (_name2 !== 'children' && _name2 !== 'innerHTML' && (!(_name2 in old) || attrs[_name2] !== (_name2 === 'value' || _name2 === 'checked' ? dom[_name2] : old[_name2]))) {
                  setAccessor(dom, _name2, old[_name2], old[_name2] = attrs[_name2], isSvgMode);
              }
          }
      }
    }

    /** Retains a pool of Components for re-use, keyed on component name.
     *	Note: since component names are not unique or even necessarily available, these are primarily a form of sharding.
     *	@private
     */
    var components = {};

    function collectComponent(component) {
      var name = component.constructor.name,
          list = components[name];
      if (list) list.push(component);else components[name] = [component];
    }

    function createComponent(Ctor, props, context) {
      var inst = new Ctor(props, context),
          list = components[Ctor.name];
      Component.call(inst, props, context);
      if (list) {
          for (var i = list.length; i--;) {
              if (list[i].constructor === Ctor) {
                  inst.nextBase = list[i].nextBase;
                  list.splice(i, 1);
                  break;
              }
          }
      }
      return inst;
    }

    /** Set a component's `props` (generally derived from JSX attributes).
     *	@param {Object} props
     *	@param {Object} [opts]
     *	@param {boolean} [opts.renderSync=false]	If `true` and {@link options.syncComponentUpdates} is `true`, triggers synchronous rendering.
     *	@param {boolean} [opts.render=true]			If `false`, no render will be triggered.
     */

    function setComponentProps(component, props, opts, context, mountAll) {
      if (component._disable) return;
      component._disable = true;

      if (component.__ref = props.ref) delete props.ref;
      if (component.__key = props.key) delete props.key;

      if (!component.base || mountAll) {
          if (component.componentWillMount) component.componentWillMount();
      } else if (component.componentWillReceiveProps) {
          component.componentWillReceiveProps(props, context);
      }

      if (context && context !== component.context) {
          if (!component.prevContext) component.prevContext = component.context;
          component.context = context;
      }

      if (!component.prevProps) component.prevProps = component.props;
      component.props = props;

      component._disable = false;

      if (opts !== 0) {
          if (opts === 1 || options.syncComponentUpdates !== false || !component.base) {
              renderComponent(component, 1, mountAll);
          } else {
              enqueueRender(component);
          }
      }

      if (component.__ref) component.__ref(component);
    }

    /** Render a Component, triggering necessary lifecycle events and taking High-Order Components into account.
     *	@param {Component} component
     *	@param {Object} [opts]
     *	@param {boolean} [opts.build=false]		If `true`, component will build and store a DOM node if not already associated with one.
     *	@private
     */

    function renderComponent(component, opts, mountAll, isChild) {
      if (component._disable) return;

      var skip,
          rendered,
          props = component.props,
          state = component.state,
          context = component.context,
          previousProps = component.prevProps || props,
          previousState = component.prevState || state,
          previousContext = component.prevContext || context,
          isUpdate = component.base,
          nextBase = component.nextBase,
          initialBase = isUpdate || nextBase,
          initialChildComponent = component._component,
          inst,
          cbase;

      // if updating
      if (isUpdate) {
          component.props = previousProps;
          component.state = previousState;
          component.context = previousContext;
          if (opts !== 2 && component.shouldComponentUpdate && component.shouldComponentUpdate(props, state, context) === false) {
              skip = true;
          } else if (component.componentWillUpdate) {
              component.componentWillUpdate(props, state, context);
          }
          component.props = props;
          component.state = state;
          component.context = context;
      }

      component.prevProps = component.prevState = component.prevContext = component.nextBase = null;
      component._dirty = false;

      if (!skip) {
          if (component.render) rendered = component.render(props, state, context);

          // context to pass to the child, can be updated via (grand-)parent component
          if (component.getChildContext) {
              context = extend(clone(context), component.getChildContext());
          }

          while (isFunctionalComponent(rendered)) {
              rendered = buildFunctionalComponent(rendered, context);
          }

          var childComponent = rendered && rendered.nodeName,
              toUnmount,
              base;

          if (isFunction(childComponent)) {
              // set up high order component link

              var childProps = getNodeProps(rendered);
              inst = initialChildComponent;

              if (inst && inst.constructor === childComponent && childProps.key == inst.__key) {
                  setComponentProps(inst, childProps, 1, context);
              } else {
                  toUnmount = inst;

                  inst = createComponent(childComponent, childProps, context);
                  inst.nextBase = inst.nextBase || nextBase;
                  inst._parentComponent = component;
                  component._component = inst;
                  setComponentProps(inst, childProps, 0, context);
                  renderComponent(inst, 1, mountAll, true);
              }

              base = inst.base;
          } else {
              cbase = initialBase;

              // destroy high order component link
              toUnmount = initialChildComponent;
              if (toUnmount) {
                  cbase = component._component = null;
              }

              if (initialBase || opts === 1) {
                  if (cbase) cbase._component = null;
                  base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true);
              }
          }

          if (initialBase && base !== initialBase && inst !== initialChildComponent) {
              var baseParent = initialBase.parentNode;
              if (baseParent && base !== baseParent) {
                  baseParent.replaceChild(base, initialBase);

                  if (!toUnmount) {
                      initialBase._component = null;
                      recollectNodeTree(initialBase);
                  }
              }
          }

          if (toUnmount) {
              unmountComponent(toUnmount, base !== initialBase);
          }

          component.base = base;
          if (base && !isChild) {
              var componentRef = component,
                  t = component;
              while (t = t._parentComponent) {
                  (componentRef = t).base = base;
              }
              base._component = componentRef;
              base._componentConstructor = componentRef.constructor;
          }
      }

      if (!isUpdate || mountAll) {
          mounts.unshift(component);
      } else if (!skip) {
          if (component.componentDidUpdate) {
              component.componentDidUpdate(previousProps, previousState, previousContext);
          }
          if (options.afterUpdate) options.afterUpdate(component);
      }

      var cb = component._renderCallbacks,
          fn;
      if (cb) while (fn = cb.pop()) fn.call(component);

      if (!diffLevel && !isChild) flushMounts();
    }

    /** Apply the Component referenced by a VNode to the DOM.
     *	@param {Element} dom	The DOM node to mutate
     *	@param {VNode} vnode	A Component-referencing VNode
     *	@returns {Element} dom	The created/mutated element
     *	@private
     */

    function buildComponentFromVNode(dom, vnode, context, mountAll) {
      var c = dom && dom._component,
          oldDom = dom,
          isDirectOwner = c && dom._componentConstructor === vnode.nodeName,
          isOwner = isDirectOwner,
          props = getNodeProps(vnode);
      while (c && !isOwner && (c = c._parentComponent)) {
          isOwner = c.constructor === vnode.nodeName;
      }

      if (c && isOwner && (!mountAll || c._component)) {
          setComponentProps(c, props, 3, context, mountAll);
          dom = c.base;
      } else {
          if (c && !isDirectOwner) {
              unmountComponent(c, true);
              dom = oldDom = null;
          }

          c = createComponent(vnode.nodeName, props, context);
          if (dom && !c.nextBase) {
              c.nextBase = dom;
              // passing dom/oldDom as nextBase will recycle it if unused, so bypass recycling on L241:
              oldDom = null;
          }
          setComponentProps(c, props, 1, context, mountAll);
          dom = c.base;

          if (oldDom && dom !== oldDom) {
              oldDom._component = null;
              recollectNodeTree(oldDom);
          }
      }

      return dom;
    }

    /** Remove a component from the DOM and recycle it.
     *	@param {Element} dom			A DOM node from which to unmount the given Component
     *	@param {Component} component	The Component instance to unmount
     *	@private
     */

    function unmountComponent(component, remove) {
      if (options.beforeUnmount) options.beforeUnmount(component);

      // console.log(`${remove?'Removing':'Unmounting'} component: ${component.constructor.name}`);
      var base = component.base;

      component._disable = true;

      if (component.componentWillUnmount) component.componentWillUnmount();

      component.base = null;

      // recursively tear down & recollect high-order component children:
      var inner = component._component;
      if (inner) {
          unmountComponent(inner, remove);
      } else if (base) {
          if (base[ATTR_KEY] && base[ATTR_KEY].ref) base[ATTR_KEY].ref(null);

          component.nextBase = base;

          if (remove) {
              removeNode(base);
              collectComponent(component);
          }
          var c;
          while (c = base.lastChild) recollectNodeTree(c, !remove);
          // removeOrphanedChildren(base.childNodes, true);
      }

      if (component.__ref) component.__ref(null);
      if (component.componentDidUnmount) component.componentDidUnmount();
    }

    /** Base Component class, for he ES6 Class method of creating Components
     *	@public
     *
     *	@example
     *	class MyFoo extends Component {
     *		render(props, state) {
     *			return <div />;
     *		}
     *	}
     */

    function Component(props, context) {
      /** @private */
      this._dirty = true;
      // /** @public */
      // this._disableRendering = false;
      // /** @public */
      // this.prevState = this.prevProps = this.prevContext = this.base = this.nextBase = this._parentComponent = this._component = this.__ref = this.__key = this._linkedStates = this._renderCallbacks = null;
      /** @public */
      this.context = context;
      /** @type {object} */
      this.props = props;
      /** @type {object} */
      if (!this.state) this.state = {};
    }

    extend(Component.prototype, {

      /** Returns a `boolean` value indicating if the component should re-render when receiving the given `props` and `state`.
      *	@param {object} nextProps
      *	@param {object} nextState
      *	@param {object} nextContext
      *	@returns {Boolean} should the component re-render
      *	@name shouldComponentUpdate
      *	@function
      */
      // shouldComponentUpdate() {
      // 	return true;
      // },

      /** Returns a function that sets a state property when called.
      *	Calling linkState() repeatedly with the same arguments returns a cached link function.
      *
      *	Provides some built-in special cases:
      *		- Checkboxes and radio buttons link their boolean `checked` value
      *		- Inputs automatically link their `value` property
      *		- Event paths fall back to any associated Component if not found on an element
      *		- If linked value is a function, will invoke it and use the result
      *
      *	@param {string} key				The path to set - can be a dot-notated deep key
      *	@param {string} [eventPath]		If set, attempts to find the new state value at a given dot-notated path within the object passed to the linkedState setter.
      *	@returns {function} linkStateSetter(e)
      *
      *	@example Update a "text" state value when an input changes:
      *		<input onChange={ this.linkState('text') } />
      *
      *	@example Set a deep state value on click
      *		<button onClick={ this.linkState('touch.coords', 'touches.0') }>Tap</button
      */
      linkState: function linkState(key, eventPath) {
          var c = this._linkedStates || (this._linkedStates = {});
          return c[key + eventPath] || (c[key + eventPath] = createLinkedState(this, key, eventPath));
      },

      /** Update component state by copying properties from `state` to `this.state`.
      *	@param {object} state		A hash of state properties to update with new values
      */
      setState: function setState(state, callback) {
          var s = this.state;
          if (!this.prevState) this.prevState = clone(s);
          extend(s, isFunction(state) ? state(s, this.props) : state);
          if (callback) (this._renderCallbacks = this._renderCallbacks || []).push(callback);
          enqueueRender(this);
      },

      /** Immediately perform a synchronous re-render of the component.
      *	@private
      */
      forceUpdate: function forceUpdate() {
          renderComponent(this, 2);
      },

      /** Accepts `props` and `state`, and returns a new Virtual DOM tree to build.
      *	Virtual DOM is generally constructed via [JSX](http://jasonformat.com/wtf-is-jsx).
      *	@param {object} props		Props (eg: JSX attributes) received from parent element/component
      *	@param {object} state		The component's current state
      *	@param {object} context		Context object (if a parent component has provided context)
      *	@returns VNode
      */
      render: function render() {}

    });

    /** Render JSX into a `parent` Element.
     *	@param {VNode} vnode		A (JSX) VNode to render
     *	@param {Element} parent		DOM element to render into
     *	@param {Element} [merge]	Attempt to re-use an existing DOM tree rooted at `merge`
     *	@public
     *
     *	@example
     *	// render a div into <body>:
     *	render(<div id="hello">hello!</div>, document.body);
     *
     *	@example
     *	// render a "Thing" component into #foo:
     *	const Thing = ({ name }) => <span>{ name }</span>;
     *	render(<Thing name="one" />, document.querySelector('#foo'));
     */

    function render(vnode, parent, merge) {
      return diff(merge, vnode, {}, false, parent);
    }

    exports.h = h;
    exports.cloneElement = cloneElement;
    exports.Component = Component;
    exports.render = render;
    exports.rerender = rerender;
    exports.options = options;

    Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=preact.dev.js.map

},{}],4:[function(require,module,exports){
"use strict";

exports.$m = $m;
function $m(key) {
  return chrome.i18n.getMessage(key);
}

},{}],5:[function(require,module,exports){
'use strict';

exports.CLOSE_SVG = exports.GalleryComponent = undefined;

var _preact = require(11);

var _api = require(8);

var _utils = require(17);

var _imageGalleryPage = require(23);

var _i18n = require(4);

let GalleryComponent = exports.GalleryComponent = function (_React$Component) {
  require(2).inherits(GalleryComponent, _React$Component);

  function GalleryComponent(pros) {
    require(2).classCallCheck(this, GalleryComponent);

    var _this = require(2).possibleConstructorReturn(this, Object.getPrototypeOf(GalleryComponent).call(this, pros));

    let currentIndex = pros.currentIndex || 0;
    let rowCount = pros.rowCount || 6;
    _this.state = {
      currentIndex,
      rowCount,
      rowIndex: getRowIndex(currentIndex, rowCount),
      items: pros.dataSource.getFilteredImageData(),
      selectedImages: []
    };
    return _this;
  }

  require(2).createClass(GalleryComponent, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      this._unwatch = this.props.dataSource.addChangeHandler(dataSource => {
        let items = dataSource.getFilteredImageData().map(data => data.src);
        let state = { items };
        this.setState(state);
        if (this.state.currentIndex >= items.length) {
          this.setCurrentIndex(items.length - 1);
        }
      });
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      if (this._unwatch) {
        this._unwatch();
      }
    }
  }, {
    key: 'setCurrentIndex',
    value: function setCurrentIndex(index) {
      let currentIndex = this.state.currentIndex;
      if (index != currentIndex) {
        this.changeCurrentIndex(index - currentIndex);
      }
    }
  }, {
    key: 'changeCurrentIndex',
    value: function changeCurrentIndex(dec) {
      let state = this.state;
      let index = state.currentIndex;
      let nextIndex = dec + index;
      if (nextIndex >= 0 && nextIndex < state.items.length) {
        this.setState({
          currentIndex: nextIndex,
          rowIndex: getRowIndex(nextIndex, state.rowCount)
        });
      }
    }
  }, {
    key: 'changeRowIndex',
    value: function changeRowIndex(dec) {
      let rowIndex = this.state.rowIndex + dec;
      if (rowIndex >= 0 && rowIndex * this.state.rowCount < this.state.items.length) {
        this.setState({ rowIndex });
      }
    }
  }, {
    key: 'getDisplayRowUrls',
    value: function getDisplayRowUrls() {
      let state = this.state;
      let start = state.rowIndex * state.rowCount;
      return state.items.slice(start, start + state.rowCount).map((src, index) => ({ src, index: index + start }));
    }
  }, {
    key: 'downloadAllImages',
    value: function downloadAllImages() {
      (0, _api.downloadImages)(this.state.items);
      (0, _imageGalleryPage.saveAllImages)(location.hostname);
    }
  }, {
    key: 'downloadCurrentImage',
    value: function downloadCurrentImage() {
      let state = this.state;
      if (state.selectedImages.length) {
        (0, _api.downloadImages)(state.selectedImages);
      } else {
        let url = state.items[state.currentIndex];
        (0, _api.downloadImages)([url]);
      }
      (0, _imageGalleryPage.saveImages)(location.hostname);
    }
  }, {
    key: 'toggleSelectImage',
    value: function toggleSelectImage(src) {
      let selectedImages = this.state.selectedImages;
      let changed;
      if (this.isSelected(src)) {
        changed = (0, _utils.arrRemove)(selectedImages, src);
      } else {
        changed = (0, _utils.arrAdd)(selectedImages, src);
      }
      if (changed) {
        this.setState({ selectedImages });
      }
    }
  }, {
    key: 'isSelected',
    value: function isSelected(src) {
      return this.state.selectedImages.indexOf(src) > -1;
    }
  }, {
    key: 'render',
    value: function render() {
      let state = this.state;
      let currentIndex = state.currentIndex;
      let currentImgSrc = state.items[currentIndex];
      let indicator = state.items.length ? `${ +currentIndex + 1 } / ${ state.items.length }` : '加载中...';
      let leftArrowClass = state.currentIndex == 0 ? 'disabled' : '';
      let rightArrowClass = state.currentIndex == state.items.length - 1 ? 'disabled' : '';
      let leftPageClass = state.rowIndex == 0 ? 'disabled' : '';
      let rightPageClass = (state.rowIndex + 1) * state.rowCount >= state.items.length ? 'disabled' : '';
      return _preact.createElement(
        'div',
        null,
        _preact.createElement('div', { className: 'close', onClick: this.props.onClickClose, dangerouslySetInnerHTML: { __html: CLOSE_SVG } }),
        _preact.createElement(
          'div',
          { className: 'main' },
          _preact.createElement('button', { className: `arrow left ${ leftArrowClass }`, onClick: () => this.changeCurrentIndex(-1),
            dangerouslySetInnerHTML: { __html: LEFT_CIRCLE_ARROW } }),
          _preact.createElement('div', { className: 'img', style: `background-image:url('${ currentImgSrc }')` }),
          _preact.createElement('button', { className: `arrow right ${ rightArrowClass }`, onClick: () => this.changeCurrentIndex(1),
            dangerouslySetInnerHTML: { __html: RIGHT_CIRCLE_ARROW } }),
          _preact.createElement(
            'div',
            { className: 'page-indicator' },
            indicator
          )
        ),
        _preact.createElement(
          'div',
          { className: 'save-tool' },
          _preact.createElement(
            'button',
            { className: 'btn', onClick: () => this.downloadCurrentImage() },
            _preact.createElement('span', { className: 'icon', dangerouslySetInnerHTML: { __html: IMG_SVG } }),
            _preact.createElement(
              'span',
              null,
              (0, _i18n.$m)('image_gallery_save_image'),
              ' ',
              state.selectedImages.length || ''
            )
          ),
          _preact.createElement(
            'button',
            { className: 'btn', onClick: () => this.downloadAllImages() },
            _preact.createElement('span', { className: 'icon', dangerouslySetInnerHTML: { __html: IMGS_SVG } }),
            _preact.createElement(
              'span',
              null,
              (0, _i18n.$m)('image_gallery_save_all')
            )
          )
        ),
        _preact.createElement(
          'div',
          { className: 'nav' },
          _preact.createElement(
            'div',
            { className: 'items' },
            _preact.createElement('div', { className: `left arrow ${ leftPageClass }`, onClick: () => this.changeRowIndex(-1),
              dangerouslySetInnerHTML: { __html: LEFT_ARROW } }),
            this.getDisplayRowUrls().map(_ref => {
              let src = _ref.src;
              let index = _ref.index;
              return _preact.createElement(
                'div',
                { className: `thumbnail ${ src == currentImgSrc ? 'active' : '' }` },
                _preact.createElement('img', { src: src, onError: onError, onClick: () => this.setCurrentIndex(index) }),
                _preact.createElement('div', { className: `select ${ this.isSelected(src) ? 'active' : '' }`,
                  dangerouslySetInnerHTML: { __html: SELECT_SVG },
                  onClick: () => this.toggleSelectImage(src)
                })
              );
            }),
            _preact.createElement('div', { className: `right arrow ${ rightPageClass }`, onClick: () => this.changeRowIndex(1),
              dangerouslySetInnerHTML: { __html: RIGHT_ARROW } })
          )
        )
      );
    }
  }]);

  return GalleryComponent;
}(_preact.Component);

function onError(e) {
  e.target.style.display = 'none';
}
function getRowIndex(index, rowCount) {
  return Math.floor(index / rowCount);
}
const RIGHT_ARROW = `<svg  viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1517"><path d="M298.8288 1023.7952l-94.5664-93.056L629.76 512 204.2624 93.2608 298.8288 0.2048 818.9952 512z" p-id="1518"></path></svg>`;
const LEFT_ARROW = `<svg  viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1372"><path d="M724.48 1023.7952l94.4384-93.056L393.9072 512 818.944 93.2608 724.48 0.2048 205.0048 512z" p-id="1373"></path></svg>`;
const RIGHT_CIRCLE_ARROW = `<svg  viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1488"><path d="M512 1024A512 512 0 1 0 0 512a512 512 0 0 0 512 512z m-87.3984-682.4192L460.8 305.3824 667.4176 512l-36.1984 36.1984L460.8 718.6176l-36.1984-36.1984L595.0208 512z" p-id="1489"></path></svg>`;
const LEFT_CIRCLE_ARROW = `<svg  viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1401"><path d="M512 1024a512 512 0 1 1 512-512 512 512 0 0 1-512 512z m87.3984-682.4192L563.2 305.3824 356.5824 512l36.1984 36.1984L563.2 718.6176l36.1984-36.1984L428.9792 512z" p-id="1402"></path></svg>`;
const SELECT_SVG = `<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1202"><path d="M958.947315 205.952c-26.273616-27.622141-69.348848-28.141899-96.206869-1.172687l-463.601778 465.36404L159.704972 423.996768c-24.864323-25.585778-66.550949-24.166141-93.137455 3.141818-26.585212 27.313131-27.968646 70.181495-3.074586 95.762101l292.676525 300.873697c24.857859 25.550869 66.549657 24.131232 93.13099-3.176727 6.09099-6.256485 10.651152-13.348202 14.070949-20.848485 2.631111-1.969131 5.257051-3.837414 7.641212-6.256485l486.798222-488.631596c26.894222-26.995071 27.379071-71.253333 1.141657-98.909091L958.947315 205.952 958.947315 205.952zM958.947315 205.952" p-id="1203"></path></svg>`;
const IMGS_SVG = `<svg  viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="806"><path d="M960 1024H256v-64h704V256h64v768h-64z m-192-128H128a128 128 0 0 1-128-128V128a128 128 0 0 1 128-128h640a128 128 0 0 1 128 128v640a128 128 0 0 1-128 128zM224 128A96 96 0 1 0 320 224 96 96 0 0 0 224 128zM320 576c-106.048 0-271.616 123.072-256 192 0 78.72 42.432 64 256 64 106.048 0 108.288-1.28 320 0 0-70.4-213.952-256-320-256z m512 0c0-70.4-28.672-128-64-128s-193.92 57.6-192 128c21.952 163.968 231.104 198.784 256 192-1.92-57.6 0-121.6 0-192z" p-id="807"></path></svg>`;
const IMG_SVG = `<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="922"><path d="M832 960H192a128 128 0 0 1-128-128V192a128 128 0 0 1 128-128h640a128 128 0 0 1 128 128v640a128 128 0 0 1-128 128zM288 192A96 96 0 1 0 384 288 96 96 0 0 0 288 192zM384 640c-106.048 0-271.616 123.072-256 192 0 78.72 42.432 64 256 64 106.048 0 108.288-1.28 320 0 0-70.4-213.952-256-320-256z m512 0c0-70.4-28.672-128-64-128s-193.92 57.6-192 128c21.952 163.968 231.104 198.784 256 192-1.92-57.6 0-121.6 0-192z" p-id="923"></path></svg>`;
const CLOSE_SVG = exports.CLOSE_SVG = `<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1550"><path d="M854.534865 259.712043c11.280928-11.280928 11.280928-29.740348 0-41.022299l-49.226145-49.227168c-11.280928-11.280928-29.740348-11.280928-41.022299 0L532.509614 401.23836c-11.279904 11.280928-29.740348 11.280928-41.021276 0L259.712555 169.4636c-11.280928-11.280928-29.740348-11.280928-41.022299 0l-49.226145 49.228191c-11.280928 11.280928-11.280928 29.740348 0 41.022299l231.774761 231.773737c11.280928 11.280928 11.280928 29.740348 0 41.022299L169.463088 764.283864c-11.280928 11.280928-11.280928 29.740348 0 41.022299l49.226145 49.228191c11.280928 11.280928 29.741371 11.280928 41.022299 0L491.487316 622.759593c11.280928-11.280928 29.741371-11.280928 41.021276 0L764.286422 854.535377c11.280928 11.280928 29.740348 11.280928 41.022299 0l49.226145-49.227168c11.280928-11.280928 11.280928-29.740348 0-41.022299L622.759081 532.510126c-11.280928-11.280928-11.280928-29.741371 0-41.022299L854.534865 259.712043z" p-id="1551"></path></svg>`;

},{"11":11,"17":17,"2":2,"23":23,"4":4,"8":8}],6:[function(require,module,exports){
'use strict';

exports.GalleryDataSource = exports.EVENT_CHANGE = undefined;

var _imageGallery = require(18);

var _progressingMessage = require(22);

var _storage = require(12);

var _EventEmitter2 = require(14);

const EVENT_CHANGE = exports.EVENT_CHANGE = 'change';

let GalleryDataSource = exports.GalleryDataSource = function (_EventEmitter) {
  require(2).inherits(GalleryDataSource, _EventEmitter);

  require(2).createClass(GalleryDataSource, [{
    key: 'addChangeHandler',
    value: function addChangeHandler(handler, once) {
      this.on(EVENT_CHANGE, handler, once);
      return () => this.off(EVENT_CHANGE, handler);
    }
  }]);

  function GalleryDataSource() {
    require(2).classCallCheck(this, GalleryDataSource);

    var _this = require(2).possibleConstructorReturn(this, Object.getPrototypeOf(GalleryDataSource).call(this));

    _this._imageMap = new Map();
    _this.filter = { width: _imageGallery.DEF_IMAGE_FILTER_WIDTH, height: _imageGallery.DEF_IMAGE_FILTER_HEIGHT };
    _this.loadFilterFromChromeStorage();
    return _this;
  }

  require(2).createClass(GalleryDataSource, [{
    key: 'requestImageUrlsAsync',
    value: function requestImageUrlsAsync() {
      if (!this._pending) {
        let process = urls => this.addImageUrls(urls);
        this._pending = (0, _progressingMessage.sendMessageWithProgressHandlerAsync)(_imageGallery.MSG_EVENT_IMAGE_GALLERY_COLLECT_IMAGE, null, process).then(process, noop).then(() => this._pending = null);
      }
      return this._pending;
    }
  }, {
    key: 'addImageUrls',
    value: function addImageUrls(urls) {
      let map = this._imageMap;
      let onLoad = e => {
        let img = e.target;
        let data;
        map.set(img.src, data = {
          src: img.src,
          complete: true,
          height: img.height,
          width: img.width,
          size: img.width * img.height
        });
        if (filterImageData(data, this.filter)) {
          this.emit(EVENT_CHANGE, [this]);
        }
      };
      for (let i = 0; i < urls.length; i++) {
        let src = urls[i];
        if (!map.has(src)) {
          let image = new Image();
          src = image.src = src;
          image.onload = onLoad;
          map.set(src, { src, complete: false });
        }
      }
    }
  }, {
    key: 'getFilteredImageData',
    value: function getFilteredImageData() {
      let ret = [];
      this._imageMap.forEach(data => filterImageData(data, this.filter) && ret.push(data));
      return ret.sort((a, b) => b.size - a.size);
    }
  }, {
    key: 'loadFilterFromChromeStorage',
    value: function loadFilterFromChromeStorage() {
      let getFilter = size => {
        this.filter = parseFilter(size);
        this.emit(EVENT_CHANGE, [this]);
      };
      (0, _storage.getByKeyAsync)(_storage.STORAGE_TYPE_SYNC, _imageGallery.STORAGE_KEY_IMAGE_GALLERY_SIZE_FILTER).then(getFilter);
      (0, _storage.watchStorageChange)(_storage.STORAGE_TYPE_SYNC, change => {
        getFilter(change.newValue);
      }, _imageGallery.STORAGE_KEY_IMAGE_GALLERY_SIZE_FILTER);
    }
  }]);

  return GalleryDataSource;
}(_EventEmitter2.EventEmitter);

function parseFilter(size) {
  let math = /(\d+)x(\d+)/i.exec(size);
  return math ? { width: +math[1], height: +math[2] } : {
    width: _imageGallery.DEF_IMAGE_FILTER_WIDTH,
    height: _imageGallery.DEF_IMAGE_FILTER_HEIGHT
  };
}
function filterImageData(data, filter) {
  return data.complete && data.width > filter.width && data.height > filter.height;
}
function noop() {}

},{"12":12,"14":14,"18":18,"2":2,"22":22}],7:[function(require,module,exports){
'use strict';

exports.ImageGallery = undefined;
exports.openImageGallery = openImageGallery;

var _GalleryComponent = require(5);

var _GalleryDataSource = require(6);

var _preact = require(11);

var _AsyncRender2 = require(13);

var _dom = require(16);

var _rule = require(10);

var _imageGalleryPage = require(23);

const STYLE = require(25);
const IMAGE_GALLERY_APPEND = 'image-gallery-append';
const IMAGE_GALLERY_CLASS_NAME = 'uc-image-gallery';
const IMAGE_GALLERY_OPEN_ATTRIBUTE = 'open';

let ImageGallery = exports.ImageGallery = function (_AsyncRender) {
  require(2).inherits(ImageGallery, _AsyncRender);

  function ImageGallery() {
    require(2).classCallCheck(this, ImageGallery);

    var _this = require(2).possibleConstructorReturn(this, Object.getPrototypeOf(ImageGallery).call(this));

    _this.dataSource = new _GalleryDataSource.GalleryDataSource();
    _this.createDOM();
    return _this;
  }

  require(2).createClass(ImageGallery, [{
    key: 'watchDOM',
    value: function watchDOM() {
      let response = () => this.layout();
      window.addEventListener('scroll', response);
      this._cancelHandler = () => window.removeEventListener('scroll', response);
    }
  }, {
    key: 'createDOM',
    value: function createDOM() {
      let element = this.element = document.createElement('div');
      let shadow = element.createShadowRoot();
      element.className = IMAGE_GALLERY_CLASS_NAME;
      shadow.innerHTML = `<style>${ STYLE }</style><div class="toolbar">${ LOGO_SVG }<span>全屏看图</span><span class="close-toolbar">
${ CLOSE_SVG }</span></div><dialog class="root hide"></dialog>`;
      let root = this.root = (0, _dom.$)('.root', shadow);
      let toolbar = this.toolbar = (0, _dom.$)('.toolbar', shadow);
      (0, _dom.$)('.close-toolbar', shadow).addEventListener('click', () => {
        this.dispose();
        (0, _rule.closeToolbar)();
      });
      _preact.render(_preact.createElement(_GalleryComponent.GalleryComponent, { dataSource: this.dataSource,
        onClickClose: () => this.renderState.toolbarAnchor ? this.close() : this.dispose() }), root);
      toolbar.addEventListener('click', e => {
        this.show();
        this.dataSource.requestImageUrlsAsync();
      });

      this.dataSource.requestImageUrlsAsync();
      let observer = new MutationObserver(changes => {
        let change = changes.find(c => c.attributeName == IMAGE_GALLERY_OPEN_ATTRIBUTE);
        if (change) {
          let show = !!change.target.getAttribute(IMAGE_GALLERY_OPEN_ATTRIBUTE);
          if (this.renderState.show !== show) {
            this.setRenderState({ show });
          }
        }
      });
      observer.observe(element, { attributes: true, attributeFilter: [IMAGE_GALLERY_OPEN_ATTRIBUTE] });
    }
  }, {
    key: 'close',
    value: function close() {
      this.setRenderState({ show: false });
    }
  }, {
    key: 'show',
    value: function show() {
      this.setRenderState({ show: true });
      (0, _imageGalleryPage.enterImageGalleryFromToolbar)(location.hostname);
    }
  }, {
    key: 'appendTo',
    value: function appendTo(element) {
      if (!element.hasAttribute(IMAGE_GALLERY_APPEND)) {
        element.appendChild(this.element);
        element.setAttribute(IMAGE_GALLERY_APPEND, '1');
        return true;
      }
    }
  }, {
    key: 'dispose',
    value: function dispose() {
      _preact.render(_preact.createElement('div', null), this.root);
      let parent = this.element.parentNode;
      if (parent) {
        parent.removeChild(this.element);
        parent.removeAttribute(IMAGE_GALLERY_APPEND);
      }
      if (this._cancelHandler) {
        this._cancelHandler();
      }
      this.dataSource.off();
    }
  }, {
    key: 'layout',
    value: function layout() {
      if (!this._layoutDispatched) {
        this._layoutDispatched = requestAnimationFrame(() => {
          this._layout();
          this._layoutDispatched = 0;
        });
      }
    }
  }, {
    key: '_layout',
    value: function _layout() {
      let toolbar = this.toolbar;
      let anchor = this.renderState.toolbarAnchor;
      if (anchor) {
        let anchorBound = anchor.getBoundingClientRect();
        let toolbarBound = toolbar.getBoundingClientRect();
        toolbar.style.left = anchorBound.left + anchorBound.width - toolbarBound.width + 'px';
        toolbar.style.top = anchorBound.top - toolbarBound.height + this.element.parentElement.scrollTop + 'px';
      }
    }
  }, {
    key: 'syncRenderState',
    value: function syncRenderState(state) {
      let show = state.show;
      let root = this.root;
      let toolbar = this.toolbar;
      this.element.setAttribute(IMAGE_GALLERY_OPEN_ATTRIBUTE, show || '');
      (0, _dom.toggleClass)(root, 'hide', !show);
      (0, _dom.toggleClass)(toolbar, 'hide', show);
      toggleDialog(root, show);
      this._layout();
    }
  }]);

  return ImageGallery;
}(_AsyncRender2.AsyncRender);

function openImageGallery() {
  let ele = (0, _dom.$)(`.${ IMAGE_GALLERY_CLASS_NAME }`);
  if (ele) {
    ele.setAttribute(IMAGE_GALLERY_OPEN_ATTRIBUTE, true);
  }
}
function toggleDialog(dialog, show) {
  if (show && !dialog.hasAttribute('open')) {
    try {
      dialog.showModal();
    } catch (ex) {}
  } else if (!show && dialog.hasAttribute('open')) {
    dialog.close();
  }
}
const CLOSE_SVG = `<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1548"><path d="M708.493 339.273l-23.763-23.731-172.727 172.727-172.727-172.727-23.763 23.731 172.762 172.727-172.762 172.727 23.763 23.763 172.727-172.727 172.727 172.727 23.763-23.763-172.762-172.727z" p-id="1549"></path></svg>`;
const LOGO_SVG = `<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1579"><path d="M291.2 819.2c-19.2-25.6-60.8-108.8-16-201.6 60.8-128 214.4-118.4 259.2-268.8 19.2-67.2 3.2-150.4-83.2-198.4C380.8 112 297.6 128 243.2 156.8 150.4 208 128 275.2 128 275.2s38.4-41.6 96-28.8c35.2 6.4 80 48 60.8 115.2-25.6 92.8-179.2 147.2-153.6 336 6.4 57.6 48 112 83.2 144 80 67.2 198.4 54.4 198.4 54.4S345.6 896 291.2 819.2zM828.8 588.8c-112-9.6-115.2-57.6-214.4-86.4-131.2-38.4-188.8 3.2-188.8 3.2 192-19.2 265.6 150.4 265.6 150.4s41.6 25.6 105.6-9.6c54.4-28.8 96-6.4 96-6.4S899.2 595.2 828.8 588.8zM540.8 742.4c0-60.8-51.2-112-112-112-60.8 0-112 51.2-112 112 0 60.8 51.2 112 112 112C489.6 854.4 540.8 806.4 540.8 742.4zM425.6 793.6c-28.8 0-51.2-22.4-51.2-51.2s22.4-51.2 51.2-51.2c28.8 0 51.2 22.4 51.2 51.2S454.4 793.6 425.6 793.6zM707.2 841.6c-25.6-9.6-60.8-12.8-60.8-12.8s35.2-76.8-3.2-169.6c-28.8-70.4-112-121.6-182.4-118.4-124.8 0-150.4 102.4-150.4 102.4s48-67.2 137.6-57.6c169.6 19.2 198.4 256 16 310.4 0 0 76.8 0 147.2-3.2 86.4-3.2 140.8-9.6 140.8-9.6S745.6 857.6 707.2 841.6zM675.2 486.4c80 32 92.8 64 169.6 60.8 35.2-3.2 48-12.8 48-12.8s9.6-64-32-128c-38.4-54.4-102.4-70.4-102.4-70.4S755.2 310.4 742.4 288c-9.6-16-19.2-28.8-19.2-28.8s-16 12.8-25.6 41.6c-9.6 32-9.6 64-9.6 64s-9.6 12.8-51.2 38.4c-38.4 22.4-108.8 51.2-108.8 51.2S582.4 448 675.2 486.4z" p-id="1580"></path></svg> `;

},{"10":10,"11":11,"13":13,"16":16,"2":2,"23":23,"25":25,"5":5,"6":6}],8:[function(require,module,exports){
'use strict';

exports.downloadImages = downloadImages;
exports.downloadImage = downloadImage;
exports.lastFileComponent = lastFileComponent;

var _videoDownload = require(20);

var _message = require(21);

function downloadImages(urls) {
  (0, _message.sendMessageAsync)(_videoDownload.MSG_EVENT_WOW_DOWNLOAD_IMAGES, { urls, title: document.title }, { noReply: true });
}
function downloadImage(url, filename) {
  (0, _message.sendMessageAsync)(_videoDownload.MSG_EVENT_VIDEO_DOWNLOAD_CHROME_DOWNLOAD, { url, filename }, { noReply: true });
}
function lastFileComponent(url) {
  let i = url.lastIndexOf('?');
  if (i != -1) {
    url = url.substring(0, i);
  }
  return url.substring(url.lastIndexOf('/') + 1);
}

},{"20":20,"21":21}],9:[function(require,module,exports){
'use strict';

exports.showImageGallery = showImageGallery;

var _ImageGallery = require(7);

var _rule = require(10);

function showImageGallery(force) {
  let toolbarAnchor = (0, _rule.findAnchorElement)();
  if (toolbarAnchor && (0, _rule.shouldAutoShowToolbar)() || force) {
    let imageGallery = new _ImageGallery.ImageGallery();
    if (imageGallery.appendTo(document.body)) {
      if (toolbarAnchor) {
        imageGallery.setRenderState({ toolbarAnchor });
        imageGallery.close();
      } else if (force) {
        imageGallery.show();
      }
      imageGallery.watchDOM();
    } else {
      imageGallery.dispose();
      (0, _ImageGallery.openImageGallery)();
    }
  }
}

},{"10":10,"7":7}],10:[function(require,module,exports){
'use strict';

exports.findAnchorElement = findAnchorElement;
exports.closeToolbar = closeToolbar;
exports.shouldAutoShowToolbar = shouldAutoShowToolbar;

var _dom = require(16);

const STORAGE_KEY_SHOULD_HIDE_TOOL_BAR = 'uc-nexus-hide-image-gallery-toolbar';
function findAnchorElement() {
  let hostname = location.hostname;
  let path = location.pathname;
  if ((hostname == 'detail.tmall.com' || hostname === 'item.taobao.com' || hostname == 'chaoshi.detail.tmall.com') && /^\/item/.test(path)) {
    return (0, _dom.$)('#J_ImgBooth');
  } else if (hostname == 'detail.tmall.hk' && path.includes('/item.htm')) {
    return (0, _dom.$)('#J_ImgBooth');
  } else if (hostname == 'item.jd.com') {
    return (0, _dom.$)('#spec-n1');
  } else if (hostname == 'product.suning.com') {
    return (0, _dom.$)('#imgZoom');
  } else if (hostname == 's.yhd.com' && /^\/item\//.test(path)) {
    return (0, _dom.$)('#layout_warp');
  } else if (hostname === 'item.yhd.com' && /^\/item\//.test(path)) {
    return (0, _dom.$)('#jsModDetailPreview');
  } else if (hostname == 'detail.ju.taobao.com' && path == '/home.htm') {
    return (0, _dom.$)('.main-pic');
  } else {
    return (0, _dom.$)('.image-gallery-anchor');
  }
}
function closeToolbar() {
  localStorage.setItem(STORAGE_KEY_SHOULD_HIDE_TOOL_BAR, '1');
}
function shouldAutoShowToolbar() {
  return !localStorage.getItem(STORAGE_KEY_SHOULD_HIDE_TOOL_BAR);
}

},{"16":16}],11:[function(require,module,exports){
'use strict';

let React;

React = require(3);


React.options.syncComponentUpdates = false;
React.options.debounceRendering = window.requestAnimationFrame;
React.createElement = React.h;

module.exports = React;

},{"3":3}],12:[function(require,module,exports){
'use strict';

exports.watchStorageChange = watchStorageChange;
exports.setAsync = setAsync;
exports.getAsync = getAsync;
exports.removeAsync = removeAsync;
exports.getByKeyAsync = getByKeyAsync;
const STORAGE_TYPE_SYNC = exports.STORAGE_TYPE_SYNC = 'sync',
      STORAGE_TYPE_LOCAL = exports.STORAGE_TYPE_LOCAL = 'local';
let watchHandlers = {
  local: [],
  sync: [],
  managed: []
};
function onChange(change, target) {
  let handlers = watchHandlers[target];
  if (handlers) {
    handlers.slice().forEach(handle => handle(change));
  }
}
let watched;
function watchStorageChange(target, handler, key) {
  if (!watched) {
    chrome.storage.onChanged.addListener(onChange);
    window.addEventListener('unload', () => chrome.storage.onChanged.removeListener(onChange));
    watched = true;
  }
  let handlers = watchHandlers[target];
  if (handlers && handlers.indexOf(handler == -1) && typeof handler === "function") {
    let func = handler;
    if (typeof key === "string") {
      func = change => change[key] && handler(change[key]);
    }
    handlers.push(func);
    return function () {
      let index = handlers.indexOf(func);
      if (index !== -1) {
        handlers.splice(index, 1);
      }
      func = null;
    };
  }
  return noop;
}
function setAsync(target, items) {
  let area = getStorageTarget(target);
  if (area) {
    return new Promise((res, rej) => area.set(items, () => {
      let error = chrome.runtime.lastError;
      error ? rej(error) : res();
    }));
  }
  return rejectInvalidStorageArea();
}
function getAsync(target, keys) {
  let area = getStorageTarget(target);
  if (area) {
    return new Promise((res, rej) => {
      area.get(keys, function (obj) {
        if (obj) {
          res(obj);
        } else {
          rej(chrome.runtime.lastError);
        }
      });
    });
  }
  return rejectInvalidStorageArea();
}
function removeAsync(target, key) {
  let area = getStorageTarget(target);
  if (area) {
    return new Promise(function (res, rej) {
      area.remove(key, function () {
        let error = chrome.runtime.lastError;
        error ? rej(error) : res();
      });
    });
  }
  return rejectInvalidStorageArea();
}
function getByKeyAsync(target, key) {
  let area = getStorageTarget(target);
  if (area) {
    return new Promise((res, rej) => {
      area.get(key, function (obj) {
        if (obj) {
          res(obj[key]);
        } else {
          rej(chrome.runtime.lastError);
        }
      });
    });
  }
  return rejectInvalidStorageArea();
}
function rejectInvalidStorageArea() {
  return Promise.reject(new Error('invalid storage target'));
}
function getStorageTarget(type) {
  let target;
  if (chrome && chrome.storage) {
    target = chrome.storage[type];
  }
  if (!target) {
    console.error('invalid storage target:' + type);
  }
  return target;
}
function noop() {}

},{}],13:[function(require,module,exports){
"use strict";

let AsyncRender = exports.AsyncRender = function () {
  function AsyncRender(renderState) {
    require(2).classCallCheck(this, AsyncRender);

    this.renderState = Object.assign({}, renderState);
    this.__lasyRenderState = {};
    this.needSync();
  }

  require(2).createClass(AsyncRender, [{
    key: "syncRenderState",
    value: function syncRenderState(renderState) {}
  }, {
    key: "setRenderState",
    value: function setRenderState(renderState) {
      let invalid,
          originalState = this.renderState;
      if (renderState) {
        Object.getOwnPropertyNames(renderState).forEach(function (key) {
          let val = renderState[key];
          if (val !== originalState[key]) {
            originalState[key] = val;
            invalid = true;
          }
        });
      }
      invalid && this.needSync();
    }
  }, {
    key: "shouldUpdate",
    value: function shouldUpdate(nextRenderState, lastRenderState) {
      return true;
    }
  }, {
    key: "needSync",
    value: function needSync() {
      if (!this._syncDispatched) {
        this._syncDispatched = true;
        requestAnimationFrame(() => {
          let renderState = this.renderState;
          if (this.shouldUpdate(renderState, this.__lastRenderState)) {
            this.syncRenderState(renderState);
          }
          this.__lastRenderState = this.renderState;
          this._syncDispatched = false;
        });
      }
    }
  }]);

  return AsyncRender;
}();

},{"2":2}],14:[function(require,module,exports){
'use strict';

exports.EventEmitter = undefined;
exports.addEventListener = addEventListener;
exports.emitEvent = emitEvent;
exports.removeEventListener = removeEventListener;

var _utils = require(17);

let EventEmitter = exports.EventEmitter = function () {
  require(2).createClass(EventEmitter, [{
    key: 'on',
    value: function on(eventName, handler) {
      let once = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];

      addEventListener(this, eventName, handler, once);
      return this;
    }
  }, {
    key: 'once',
    value: function once(eventName, handler) {
      return this.on(eventName, handler, true);
    }
  }, {
    key: 'off',
    value: function off(eventName, handler) {
      removeEventListener(this, eventName, handler);
      return this;
    }
  }, {
    key: 'emit',
    value: function emit(eventName, args, thisObj) {
      emitEvent(this, eventName, args, thisObj);
      return this;
    }
  }]);

  function EventEmitter() {
    require(2).classCallCheck(this, EventEmitter);
  }

  return EventEmitter;
}();

function addEventListener(obj, evtName, handler, once) {
  if (typeof evtName == "string" && evtName && (0, _utils.isFunc)(handler)) {
    var cbs, hs;
    if (!obj.hasOwnProperty('$$callbacks')) {
      obj.$$callbacks = {};
    }
    cbs = obj.$$callbacks;
    if (!(hs = cbs[evtName])) {
      hs = cbs[evtName] = [];
    }
    return arrAdd(hs, once ? warpOnceFunc(handler) : handler);
  }
  return false;
}
function arrAdd(array, item, first) {
  if (array.indexOf(item) == -1) {
    array[first ? 'unshift' : 'push'](item);
    return true;
  }
}
function emitEvent(obj, evtName, argArray, thisObj) {
  var callbacks, handlers;
  if (!obj.hasOwnProperty('$$callbacks') || !(handlers = (callbacks = obj.$$callbacks)[evtName])) {
    return false;
  }
  if (!argArray) {
    argArray = [];
  } else if (!(argArray instanceof Array)) {
    argArray = [argArray];
  }
  if (thisObj === undefined) {
    thisObj = obj;
  }
  return callbacks[evtName] = handlers.reduce(function (next, call) {
    if ((0, _utils.isFunc)(call) && call.apply(thisObj, argArray) !== -1) {
      next.push(call);
    }
    return next;
  }, []);
}
function removeEventListener(obj, evtName, handler) {
  var cbs, hs, i;
  if (evtName === undefined) {
    obj.$$callbacks = {};
  } else if ((cbs = obj.$$callbacks) && (hs = cbs[evtName]) && hs) {
    if (handler) {
      if ((i = hs.indexOf(handler)) > -1) {
        hs[i] = null;
      }
    } else {
      cbs[evtName] = [];
    }
  }
  return obj;
}
function warpOnceFunc(func) {
  return function () {
    func.apply(this, arguments);
    return -1;
  };
}

},{"17":17,"2":2}],15:[function(require,module,exports){
"use strict";

exports.defer = defer;
function defer() {
  let _resolve,
      _reject,
      promise = new Promise((_res, _rej) => {
    _resolve = _res;
    _reject = _rej;
  });
  return {
    resolve: function resolve(arg) {
      _resolve(arg);
    },
    reject: function reject(arg) {
      _reject(arg);
    },
    promise
  };
}

},{}],16:[function(require,module,exports){
'use strict';

exports.$ = $;
exports._$ = _$;
exports._$$ = _$$;
exports.$$ = $$;
exports.toggleClass = toggleClass;
exports.removeNodeFromParent = removeNodeFromParent;
let slice = Array.prototype.slice;
function $(slt, ele) {
  if (slt instanceof HTMLElement) {
    return slt;
  }
  return (ele || document).querySelector(slt);
}

function _$(slt, ele) {
  return (ele || document).shadowRoot.querySelector(slt);
}
function _$$(slt, ele) {
  return slice.call((ele || document).shadowRoot.querySelectorAll(slt));
}
function $$(slt, ele) {
  return slice.call((ele || document).querySelectorAll(slt));
}
function toggleClass(ele, className, showClass) {
  let hasClass = arguments.length == 2 ? ele.classList.contains(className) : !showClass;
  ele.classList[hasClass ? 'remove' : 'add'](className);
}
function removeNodeFromParent(node) {
  if (node && node.parentNode) {
    node.parentNode.removeChild(node);
    return true;
  }
  return false;
}

},{}],17:[function(require,module,exports){
'use strict';

exports.forEach = forEach;
exports.arrAdd = arrAdd;
exports.arrFind = arrFind;
exports.arrFirst = arrFirst;
exports.arrRemove = arrRemove;
exports.arrFilterMappedResult = arrFilterMappedResult;
exports.isFunc = isFunc;
exports.isObj = isObj;
exports.isStr = isStr;
exports.noop = noop;
function forEach(object, callback, thisObj) {
  if (isObj(object)) {
    if (thisObj === void 0) {
      thisObj = object;
    }
    if (object instanceof Array || object.hasOwnProperty('length')) {
      for (let i = 0, len = object.length; i < len; i++) {
        callback.call(thisObj, object[i], i);
      }
    } else {
      for (let name in object) {
        if (object.hasOwnProperty(name)) {
          callback.call(thisObj, object[name], name);
        }
      }
    }
  }
  return object;
}
function arrAdd(array, item, first) {
  if (array.indexOf(item) == -1) {
    array[first ? 'unshift' : 'push'](item);
    return true;
  }
}
function arrFind(arr, test) {
  let index = 0;
  for (let item of arr) {
    if (test(item, index++)) {
      return item;
    }
  }
}
function arrFirst(arr, map) {
  let index = 0;
  for (let item of arr) {
    let val = map(item, index++);
    if (val) {
      return val;
    }
  }
}
function arrRemove(arr, item) {
  let index = arr.indexOf(item);
  if (index > -1) {
    arr.splice(index, 1);
  }
  return index != -1;
}
function arrFilterMappedResult(arr, mapFunc, thisObj) {
  let ret = [],
      item;
  forEach(arr, function (val, key) {
    if (item = mapFunc.call(this, val, key)) {
      ret.push(item);
    }
  }, thisObj);
  return ret;
}
function isFunc(any) {
  return typeof any === 'function';
}
function isObj(any) {
  return any && typeof any === 'object';
}
function isStr(any) {
  return typeof any === "string";
}
function noop() {}

},{}],18:[function(require,module,exports){
'use strict';

const MSG_EVENT_IMAGE_GALLERY_COLLECT_IMAGE = exports.MSG_EVENT_IMAGE_GALLERY_COLLECT_IMAGE = 'image-gallery-collect-img',
      MSG_EVENT_IMAGE_GALLERY_IMAGE_SIZE_FILTER = exports.MSG_EVENT_IMAGE_GALLERY_IMAGE_SIZE_FILTER = 'image-gallery-image-size-filter',
      STORAGE_KEY_IMAGE_GALLERY_SIZE_FILTER = exports.STORAGE_KEY_IMAGE_GALLERY_SIZE_FILTER = 'image-gallery-size-filter',
      MSG_EVENT_IMAGE_GALLERY_ENTER_GALLERY = exports.MSG_EVENT_IMAGE_GALLERY_ENTER_GALLERY = 'enter-image-gallery',
      DEF_IMAGE_FILTER_WIDTH = exports.DEF_IMAGE_FILTER_WIDTH = 200,
      DEF_IMAGE_FILTER_HEIGHT = exports.DEF_IMAGE_FILTER_HEIGHT = 150;

},{}],19:[function(require,module,exports){
'use strict';

const MSG_EVENT_STATISTIC_RECORD = exports.MSG_EVENT_STATISTIC_RECORD = 'statistic-record';

},{}],20:[function(require,module,exports){
'use strict';

const MSG_EVENT_VIDEO_DOWNLOAD_CRAWL_URL = exports.MSG_EVENT_VIDEO_DOWNLOAD_CRAWL_URL = 'VD-crawl-url',
      MSG_EVENT_VIDEO_DOWNLOAD_CHROME_DOWNLOAD = exports.MSG_EVENT_VIDEO_DOWNLOAD_CHROME_DOWNLOAD = 'VD-chrome-download',
      MSG_EVENT_VIDEO_DOWNLOAD_EXTERNAL_CRAWL_URL = exports.MSG_EVENT_VIDEO_DOWNLOAD_EXTERNAL_CRAWL_URL = 'VD-external-crawl-url',
      MSG_EVENT_PAGE_INJECTION_ENABLED = exports.MSG_EVENT_PAGE_INJECTION_ENABLED = 'page-injection-enabled',
      MSG_EVENT_WOW_DOWNLOAD_IMAGES = exports.MSG_EVENT_WOW_DOWNLOAD_IMAGES = 'wow-download-images',
      MSG_EVENT_WOW_IMAGE_DOWNLOAD_FORMAT = exports.MSG_EVENT_WOW_IMAGE_DOWNLOAD_FORMAT = 'wow-download-image-format';

},{}],21:[function(require,module,exports){
'use strict';

exports.sendMessageAsync = sendMessageAsync;
exports.registerMsgHandler = registerMsgHandler;

var _defer = require(15);

let deferCache,
    bkMsgHandlers = Object.create(null),
    extPort;
if (typeof chrome == "object" && chrome.runtime && chrome.runtime.onMessage) {
  chrome.runtime.onMessage.addListener(onMsg);
}
window.addEventListener('unload', () => {
  extPort.disconnect();
  disposePort();
});
function sendMessageAsync(type, data) {
  var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

  let noReply = _ref.noReply;
  let extId = _ref.extId;

  let msg = { type, data, sync: false, noReply, d: 'req' };

  if (noReply) {
    sendMsg(extId, msg);
    return Promise.resolve();
  } else {
    let uid = guid(),
        deferred = (0, _defer.defer)();
    msg.guid = uid;
    deferCache[uid] = deferred;
    sendMsg(extId, msg);

    return deferred.promise;
  }
}
initPort();
function initPort() {
  deferCache = Object.create(null);
  try {
    extPort = chrome.runtime.connect({ name: 'page:connect' });
    extPort.onMessage.addListener(onMsg);
    extPort.onDisconnect.addListener(function () {
      disposePort();
      setTimeout(initPort, 0);
    });
  } catch (ex) {
    console.log(ex);
  }
}
function disposePort() {
  for (let uid in deferCache) {
    let deferred = deferCache[uid];
    if (deferred && deferred.reject) {
      deferred.reject('disconnect');
    }
  }
  deferCache = Object.create(null);
  extPort = null;
}
function onMsg(response) {
  let guid = response.guid;
  let d = response.d;let deferred = deferCache[guid];
  if (d === 'postTab') {
    let handler = bkMsgHandlers[response.type];
    handler && handler(response.data);
  } else if (deferred) {
    if (d === 'res') {
      response.success ? deferred.resolve(response.data) : deferred.reject(response.error);
      delete deferCache[guid];
    }
  } else {
    console.warn('response with:' + guid + ' not found');
  }
}
function registerMsgHandler(event, handler) {
  if (typeof handler === "function") {
    bkMsgHandlers[event] = handler;
  }
}
function sendMsg(extId, msg) {
  if (extId && msg) {
    throw Error('not support external');
  } else if (msg) {
    if (extPort) {
      extPort.postMessage(msg);
    } else {
      chrome.runtime.sendMessage(msg);
    }
  }
}
function noop() {}
function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
  }

  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + Date.now();
}

},{"15":15}],22:[function(require,module,exports){
'use strict';

exports.sendMessageWithProgressHandlerAsync = sendMessageWithProgressHandlerAsync;

var _utils = require(17);

let IN_BROWSER = window.chrome && chrome.runtime;

function sendMessageWithProgressHandlerAsync(type, data, onProgress) {
  if (IN_BROWSER) {
    return new Promise((res, rej) => {
      let port = chrome.runtime.connect({ name: 'page:dedicate' });
      port.onMessage.addListener(function (msg) {
        if (msg.type !== type && true) {
          throw Error('invalid message of type:' + msg.type);
        }
        if (msg.progressing && (0, _utils.isFunc)(onProgress)) {
          onProgress(msg.data);
        } else {
          msg.success ? res(msg.data) : rej(msg.error);
        }
      });
      port.postMessage({
        type, data
      });
    });
  }
  return Promise.reject('not in browser');
}

},{"17":17}],23:[function(require,module,exports){
'use strict';

exports.saveImages = saveImages;
exports.saveAllImages = saveAllImages;
exports.enterImageGalleryFromToolbar = enterImageGalleryFromToolbar;

var _wowPage = require(24);

function saveImages(domain) {
  (0, _wowPage.wowLog)('1.39.3.4.3', { domain });
}
function saveAllImages(domain) {
  (0, _wowPage.wowLog)('1.39.3.4.4', { domain });
}
function enterImageGalleryFromToolbar(domain) {
  (0, _wowPage.wowLog)('1.39.3.4.1', { domain });
}

},{"24":24}],24:[function(require,module,exports){
'use strict';

exports.wowLog = wowLog;

var _message = require(21);

var _statistic = require(19);

function wowLog(statsId, param) {
  (0, _message.sendMessageAsync)(_statistic.MSG_EVENT_STATISTIC_RECORD, {
    id: statsId,
    param
  }, { noReply: false });
}

},{"19":19,"21":21}],25:[function(require,module,exports){
module.exports = "*{box-sizing:border-box}.toolbar{position:absolute;z-index:99999999;width:120px;height:30px;line-height:30px;background:#3e99ff;color:#fff;cursor:pointer}.toolbar span{vertical-align:top}.toolbar svg{fill:#fff;height:100%}.btn{min-width:120px;height:42px;border:1px solid #4b5565;color:#4b5565;border-radius:21px;font-size:14px;outline:0!important;padding:12px 18px;margin:0 17px;background:0 0;cursor:pointer}.btn:hover{border-color:#5e7091;color:#5e7091}.btn:hover svg{fill:#5e7091}.btn span{vertical-align:top}.btn .icon{margin-right:10px}.btn svg{fill:#4b5565}.hide{display:none!important}.root{position:fixed;left:0;padding:2% 0 0;right:0;top:0;bottom:0;width:100%;height:100%;background:#202225;user-select:none}.save-tool{text-align:center;margin-bottom:20px}.close{fill:#4b5565;position:fixed;top:30px;right:30px;width:20px;height:20px;cursor:pointer}.close:hover{fill:#5e7091}svg{height:100%}.main{height:100%;top:0;text-align:center;margin:20px auto 30px;min-width:1000px}.main .arrow{display:inline-block;position:relative;outline:0;background:0 0;border:none;width:50px;height:50px;border-radius:50%;vertical-align:top;margin:230px 50px auto}.main .img{display:inline-block;width:660px;height:460px;background-size:contain;background-repeat:no-repeat;background-position:center}.main .page-indicator{margin-top:20px;font-size:20px;color:#4b5565}.nav{bottom:10px;height:120px}.nav .items{text-align:center;margin:0 auto;min-width:1200px}.nav .thumbnail{display:inline-block;width:160px;height:120px;margin:0 10px;overflow:hidden;position:relative}.nav .thumbnail .select{width:20px;height:20px;border-radius:50%;position:absolute;right:10px;bottom:10px;background:#536483;cursor:pointer;opacity:.6}.nav .thumbnail .select svg{width:80%}.nav .thumbnail .select.active{background:#228b22}.nav .thumbnail .select.active svg{fill:#fff}.nav .thumbnail.active img{opacity:1}.nav .thumbnail img{width:100%;height:100%;cursor:pointer;opacity:.6}.items .arrow:hover:before{border-color:#5e7091}.items .arrow.disabled:before{border-color:#272b31}.arrow{display:inline-block;vertical-align:top;margin:40px 0 0;cursor:pointer;height:40px}.arrow svg{fill:#536483}.arrow svg:active{fill:#2d394d}.arrow:hover svg{fill:#5e7091}.arrow:active svg{fill:#2d394d}.arrow.disabled svg,.arrow.disabled:hover svg{fill:#272b31}.arrow.left{margin-right:30px}.arrow.right{margin-left:30px}.arrow.left:before{transform:rotate(45deg)}.arrow.right:before{transform:rotate(-135deg)}@media all and (max-height:720px){.main{margin:5px auto}.main .page-indicator{margin-top:5px}.root{padding-top:0}}@media all and (max-width:1300px){.arrow.left{margin-right:20px}.arrow.right{margin-left:20px}}";
},{}]},{},[1]);
