/*!
 * ZeroClipboard
 * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
 * Copyright (c) 2014 Jon Rohan, James M. Greene
 * Licensed MIT
 * http://zeroclipboard.org/
 * v2.0.0-beta.5
 */
;(function (window) {
  'use strict'
  var _currentElement
  var _flashState = {
    bridge: null,
    version: '0.0.0',
    pluginType: 'unknown',
    disabled: null,
    outdated: null,
    unavailable: null,
    deactivated: null,
    overdue: null,
    ready: null
  }
  var _clipData = {}
  var _clipDataFormatMap = null
  var _clientIdCounter = 0
  var _clientMeta = {}
  var _elementIdCounter = 0
  var _elementMeta = {}
  var _swfPath = (function () {
    var i,
      jsDir,
      tmpJsPath,
      jsPath,
      swfPath = 'ZeroClipboard.swf'
    if (!(document.currentScript && (jsPath = document.currentScript.src))) {
      var scripts = document.getElementsByTagName('script')
      if ('readyState' in scripts[0]) {
        for (i = scripts.length; i--; ) {
          if (scripts[i].readyState === 'interactive' && (jsPath = scripts[i].src)) {
            break
          }
        }
      } else if (document.readyState === 'loading') {
        jsPath = scripts[scripts.length - 1].src
      } else {
        for (i = scripts.length; i--; ) {
          tmpJsPath = scripts[i].src
          if (!tmpJsPath) {
            jsDir = null
            break
          }
          tmpJsPath = tmpJsPath.split('#')[0].split('?')[0]
          tmpJsPath = tmpJsPath.slice(0, tmpJsPath.lastIndexOf('/') + 1)
          if (jsDir == null) {
            jsDir = tmpJsPath
          } else if (jsDir !== tmpJsPath) {
            jsDir = null
            break
          }
        }
        if (jsDir !== null) {
          jsPath = jsDir
        }
      }
    }
    if (jsPath) {
      jsPath = jsPath.split('#')[0].split('?')[0]
      swfPath = jsPath.slice(0, jsPath.lastIndexOf('/') + 1) + swfPath
    }
    return swfPath
  })()
  var _camelizeCssPropName = (function () {
    var matcherRegex = /\-([a-z])/g,
      replacerFn = function (match, group) {
        return group.toUpperCase()
      }
    return function (prop) {
      return prop.replace(matcherRegex, replacerFn)
    }
  })()
  var _getStyle = function (el, prop) {
    var value, camelProp, tagName
    if (window.getComputedStyle) {
      value = window.getComputedStyle(el, null).getPropertyValue(prop)
    } else {
      camelProp = _camelizeCssPropName(prop)
      if (el.currentStyle) {
        value = el.currentStyle[camelProp]
      } else {
        value = el.style[camelProp]
      }
    }
    if (prop === 'cursor') {
      if (!value || value === 'auto') {
        tagName = el.tagName.toLowerCase()
        if (tagName === 'a') {
          return 'pointer'
        }
      }
    }
    return value
  }
  var _elementMouseOver = function (event) {
    if (!event) {
      event = window.event
    }
    var target
    if (this !== window) {
      target = this
    } else if (event.target) {
      target = event.target
    } else if (event.srcElement) {
      target = event.srcElement
    }
    ZeroClipboard.activate(target)
  }
  var _addEventHandler = function (element, method, func) {
    if (!element || element.nodeType !== 1) {
      return
    }
    if (element.addEventListener) {
      element.addEventListener(method, func, false)
    } else if (element.attachEvent) {
      element.attachEvent('on' + method, func)
    }
  }
  var _removeEventHandler = function (element, method, func) {
    if (!element || element.nodeType !== 1) {
      return
    }
    if (element && element.removeEventListener) {
      element.removeEventListener(method, func, false)
    } else if (element.detachEvent) {
      element.detachEvent('on' + method, func)
    }
  }
  var _addClass = function (element, value) {
    if (!element || element.nodeType !== 1) {
      return element
    }
    if (element.classList) {
      if (!element.classList.contains(value)) {
        element.classList.add(value)
      }
      return element
    }
    if (value && typeof value === 'string') {
      var classNames = (value || '').split(/\s+/)
      if (element.nodeType === 1) {
        if (!element.className) {
          element.className = value
        } else {
          var className = ' ' + element.className + ' ',
            setClass = element.className
          for (var c = 0, cl = classNames.length; c < cl; c++) {
            if (className.indexOf(' ' + classNames[c] + ' ') < 0) {
              setClass += ' ' + classNames[c]
            }
          }
          element.className = setClass.replace(/^\s+|\s+$/g, '')
        }
      }
    }
    return element
  }
  var _removeClass = function (element, value) {
    if (!element || element.nodeType !== 1) {
      return element
    }
    if (element.classList) {
      if (element.classList.contains(value)) {
        element.classList.remove(value)
      }
      return element
    }
    if ((value && typeof value === 'string') || value === undefined) {
      var classNames = (value || '').split(/\s+/)
      if (element.nodeType === 1 && element.className) {
        if (value) {
          var className = (' ' + element.className + ' ').replace(/[\n\t]/g, ' ')
          for (var c = 0, cl = classNames.length; c < cl; c++) {
            className = className.replace(' ' + classNames[c] + ' ', ' ')
          }
          element.className = className.replace(/^\s+|\s+$/g, '')
        } else {
          element.className = ''
        }
      }
    }
    return element
  }
  var _getZoomFactor = function () {
    var rect,
      physicalWidth,
      logicalWidth,
      zoomFactor = 1
    if (typeof document.body.getBoundingClientRect === 'function') {
      rect = document.body.getBoundingClientRect()
      physicalWidth = rect.right - rect.left
      logicalWidth = document.body.offsetWidth
      zoomFactor = Math.round((physicalWidth / logicalWidth) * 100) / 100
    }
    return zoomFactor
  }
  var _getDOMObjectPosition = function (obj, defaultZIndex) {
    var info = {
      left: 0,
      top: 0,
      width: 0,
      height: 0,
      zIndex: _getSafeZIndex(defaultZIndex) - 1
    }
    if (obj.getBoundingClientRect) {
      var rect = obj.getBoundingClientRect()
      var pageXOffset, pageYOffset, zoomFactor
      if ('pageXOffset' in window && 'pageYOffset' in window) {
        pageXOffset = window.pageXOffset
        pageYOffset = window.pageYOffset
      } else {
        zoomFactor = _getZoomFactor()
        pageXOffset = Math.round(document.documentElement.scrollLeft / zoomFactor)
        pageYOffset = Math.round(document.documentElement.scrollTop / zoomFactor)
      }
      var leftBorderWidth = document.documentElement.clientLeft || 0
      var topBorderWidth = document.documentElement.clientTop || 0
      info.left = rect.left + pageXOffset - leftBorderWidth
      info.top = rect.top + pageYOffset - topBorderWidth
      info.width = 'width' in rect ? rect.width : rect.right - rect.left
      info.height = 'height' in rect ? rect.height : rect.bottom - rect.top
    }
    return info
  }
  var _cacheBust = function (path, options) {
    var cacheBust = options == null || (options && options.cacheBust === true)
    if (cacheBust) {
      return (path.indexOf('?') === -1 ? '?' : '&') + 'noCache=' + new Date().getTime()
    } else {
      return ''
    }
  }
  var _vars = function (options) {
    var i,
      len,
      domain,
      domains,
      str = '',
      trustedOriginsExpanded = []
    if (options.trustedDomains) {
      if (typeof options.trustedDomains === 'string') {
        domains = [options.trustedDomains]
      } else if (typeof options.trustedDomains === 'object' && 'length' in options.trustedDomains) {
        domains = options.trustedDomains
      }
    }
    if (domains && domains.length) {
      for (i = 0, len = domains.length; i < len; i++) {
        if (domains.hasOwnProperty(i) && domains[i] && typeof domains[i] === 'string') {
          domain = _extractDomain(domains[i])
          if (!domain) {
            continue
          }
          if (domain === '*') {
            trustedOriginsExpanded = [domain]
            break
          }
          trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [
            domain,
            '//' + domain,
            window.location.protocol + '//' + domain
          ])
        }
      }
    }
    if (trustedOriginsExpanded.length) {
      str += 'trustedOrigins=' + encodeURIComponent(trustedOriginsExpanded.join(','))
    }
    if (options.forceEnhancedClipboard === true) {
      str += (str ? '&' : '') + 'forceEnhancedClipboard=true'
    }
    return str
  }
  var _inArray = function (elem, array, fromIndex) {
    if (typeof array.indexOf === 'function') {
      return array.indexOf(elem, fromIndex)
    }
    var i,
      len = array.length
    if (typeof fromIndex === 'undefined') {
      fromIndex = 0
    } else if (fromIndex < 0) {
      fromIndex = len + fromIndex
    }
    for (i = fromIndex; i < len; i++) {
      if (array.hasOwnProperty(i) && array[i] === elem) {
        return i
      }
    }
    return -1
  }
  var _prepClip = function (elements) {
    if (typeof elements === 'string') {
      throw new TypeError("ZeroClipboard doesn't accept query strings.")
    }
    return typeof elements.length !== 'number' ? [elements] : elements
  }
  var _dispatchCallback = function (func, context, args, async) {
    if (async) {
      window.setTimeout(function () {
        func.apply(context, args)
      }, 0)
    } else {
      func.apply(context, args)
    }
  }
  var _getSafeZIndex = function (val) {
    var zIndex, tmp
    if (val) {
      if (typeof val === 'number' && val > 0) {
        zIndex = val
      } else if (typeof val === 'string' && (tmp = parseInt(val, 10)) && !isNaN(tmp) && tmp > 0) {
        zIndex = tmp
      }
    }
    if (!zIndex) {
      if (typeof _globalConfig.zIndex === 'number' && _globalConfig.zIndex > 0) {
        zIndex = _globalConfig.zIndex
      } else if (
        typeof _globalConfig.zIndex === 'string' &&
        (tmp = parseInt(_globalConfig.zIndex, 10)) &&
        !isNaN(tmp) &&
        tmp > 0
      ) {
        zIndex = tmp
      }
    }
    return zIndex || 0
  }
  var _extend = function () {
    var i,
      len,
      arg,
      prop,
      src,
      copy,
      target = arguments[0] || {}
    for (i = 1, len = arguments.length; i < len; i++) {
      if ((arg = arguments[i]) != null) {
        for (prop in arg) {
          if (arg.hasOwnProperty(prop)) {
            src = target[prop]
            copy = arg[prop]
            if (target === copy) {
              continue
            }
            if (copy !== undefined) {
              target[prop] = copy
            }
          }
        }
      }
    }
    return target
  }
  var _extractDomain = function (originOrUrl) {
    if (originOrUrl == null || originOrUrl === '') {
      return null
    }
    originOrUrl = originOrUrl.replace(/^\s+|\s+$/g, '')
    if (originOrUrl === '') {
      return null
    }
    var protocolIndex = originOrUrl.indexOf('//')
    originOrUrl = protocolIndex === -1 ? originOrUrl : originOrUrl.slice(protocolIndex + 2)
    var pathIndex = originOrUrl.indexOf('/')
    originOrUrl =
      pathIndex === -1
        ? originOrUrl
        : protocolIndex === -1 || pathIndex === 0
        ? null
        : originOrUrl.slice(0, pathIndex)
    if (originOrUrl && originOrUrl.slice(-4).toLowerCase() === '.swf') {
      return null
    }
    return originOrUrl || null
  }
  var _determineScriptAccess = (function () {
    var _extractAllDomains = function (origins, resultsArray) {
      var i, len, tmp
      if (origins == null || resultsArray[0] === '*') {
        return
      }
      if (typeof origins === 'string') {
        origins = [origins]
      }
      if (!(typeof origins === 'object' && typeof origins.length === 'number')) {
        return
      }
      for (i = 0, len = origins.length; i < len; i++) {
        if (origins.hasOwnProperty(i) && (tmp = _extractDomain(origins[i]))) {
          if (tmp === '*') {
            resultsArray.length = 0
            resultsArray.push('*')
            break
          }
          if (_inArray(tmp, resultsArray) === -1) {
            resultsArray.push(tmp)
          }
        }
      }
    }
    return function (currentDomain, configOptions) {
      var swfDomain = _extractDomain(configOptions.swfPath)
      if (swfDomain === null) {
        swfDomain = currentDomain
      }
      var trustedDomains = []
      _extractAllDomains(configOptions.trustedOrigins, trustedDomains)
      _extractAllDomains(configOptions.trustedDomains, trustedDomains)
      var len = trustedDomains.length
      if (len > 0) {
        if (len === 1 && trustedDomains[0] === '*') {
          return 'always'
        }
        if (_inArray(currentDomain, trustedDomains) !== -1) {
          if (len === 1 && currentDomain === swfDomain) {
            return 'sameDomain'
          }
          return 'always'
        }
      }
      return 'never'
    }
  })()
  var _objectKeys = function (obj) {
    if (obj == null) {
      return []
    }
    if (Object.keys) {
      return Object.keys(obj)
    }
    var keys = []
    for (var prop in obj) {
      if (obj.hasOwnProperty(prop)) {
        keys.push(prop)
      }
    }
    return keys
  }
  var _deleteOwnProperties = function (obj) {
    if (obj) {
      for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
          delete obj[prop]
        }
      }
    }
    return obj
  }
  var _safeActiveElement = function () {
    try {
      return document.activeElement
    } catch (err) {}
    return null
  }
  var _pick = function (obj, keys) {
    var newObj = {}
    for (var i = 0, len = keys.length; i < len; i++) {
      if (keys[i] in obj) {
        newObj[keys[i]] = obj[keys[i]]
      }
    }
    return newObj
  }
  var _omit = function (obj, keys) {
    var newObj = {}
    for (var prop in obj) {
      if (_inArray(prop, keys) === -1) {
        newObj[prop] = obj[prop]
      }
    }
    return newObj
  }
  var _mapClipDataToFlash = function (clipData) {
    var newClipData = {},
      formatMap = {}
    if (!(typeof clipData === 'object' && clipData)) {
      return
    }
    for (var dataFormat in clipData) {
      if (
        dataFormat &&
        clipData.hasOwnProperty(dataFormat) &&
        typeof clipData[dataFormat] === 'string' &&
        clipData[dataFormat]
      ) {
        switch (dataFormat.toLowerCase()) {
          case 'text/plain':
          case 'text':
          case 'air:text':
          case 'flash:text':
            newClipData.text = clipData[dataFormat]
            formatMap.text = dataFormat
            break

          case 'text/html':
          case 'html':
          case 'air:html':
          case 'flash:html':
            newClipData.html = clipData[dataFormat]
            formatMap.html = dataFormat
            break

          case 'application/rtf':
          case 'text/rtf':
          case 'rtf':
          case 'richtext':
          case 'air:rtf':
          case 'flash:rtf':
            newClipData.rtf = clipData[dataFormat]
            formatMap.rtf = dataFormat
            break

          default:
            break
        }
      }
    }
    return {
      data: newClipData,
      formatMap: formatMap
    }
  }
  var _mapClipResultsFromFlash = function (clipResults, formatMap) {
    if (
      !(
        typeof clipResults === 'object' &&
        clipResults &&
        typeof formatMap === 'object' &&
        formatMap
      )
    ) {
      return clipResults
    }
    var newResults = {}
    for (var prop in clipResults) {
      if (clipResults.hasOwnProperty(prop)) {
        if (prop !== 'success' && prop !== 'data') {
          newResults[prop] = clipResults[prop]
          continue
        }
        newResults[prop] = {}
        var tmpHash = clipResults[prop]
        for (var dataFormat in tmpHash) {
          if (
            dataFormat &&
            tmpHash.hasOwnProperty(dataFormat) &&
            formatMap.hasOwnProperty(dataFormat)
          ) {
            newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat]
          }
        }
      }
    }
    return newResults
  }
  var _args = (function (arraySlice) {
    return function (args) {
      return arraySlice.call(args, 0)
    }
  })(window.Array.prototype.slice)
  var _detectFlashSupport = function () {
    var plugin,
      ax,
      mimeType,
      hasFlash = false,
      isActiveX = false,
      isPPAPI = false,
      flashVersion = ''
    function parseFlashVersion(desc) {
      var matches = desc.match(/[\d]+/g)
      matches.length = 3
      return matches.join('.')
    }
    function isPepperFlash(flashPlayerFileName) {
      return (
        !!flashPlayerFileName &&
        (flashPlayerFileName = flashPlayerFileName.toLowerCase()) &&
        (/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(
          flashPlayerFileName
        ) ||
          flashPlayerFileName.slice(-13) === 'chrome.plugin')
      )
    }
    function inspectPlugin(plugin) {
      if (plugin) {
        hasFlash = true
        if (plugin.version) {
          flashVersion = parseFlashVersion(plugin.version)
        }
        if (!flashVersion && plugin.description) {
          flashVersion = parseFlashVersion(plugin.description)
        }
        if (plugin.filename) {
          isPPAPI = isPepperFlash(plugin.filename)
        }
      }
    }
    if (navigator.plugins && navigator.plugins.length) {
      plugin = navigator.plugins['Shockwave Flash']
      inspectPlugin(plugin)
      if (navigator.plugins['Shockwave Flash 2.0']) {
        hasFlash = true
        flashVersion = '2.0.0.11'
      }
    } else if (navigator.mimeTypes && navigator.mimeTypes.length) {
      mimeType = navigator.mimeTypes['application/x-shockwave-flash']
      plugin = mimeType && mimeType.enabledPlugin
      inspectPlugin(plugin)
    } else if (typeof ActiveXObject !== 'undefined') {
      isActiveX = true
      try {
        ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.7')
        hasFlash = true
        flashVersion = parseFlashVersion(ax.GetVariable('$version'))
      } catch (e1) {
        try {
          ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6')
          hasFlash = true
          flashVersion = '6.0.21'
        } catch (e2) {
          try {
            ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')
            hasFlash = true
            flashVersion = parseFlashVersion(ax.GetVariable('$version'))
          } catch (e3) {
            isActiveX = false
          }
        }
      }
    }
    _flashState.disabled = hasFlash !== true
    _flashState.outdated = flashVersion && parseFloat(flashVersion) < 11
    _flashState.version = flashVersion || '0.0.0'
    _flashState.pluginType = isPPAPI
      ? 'pepper'
      : isActiveX
      ? 'activex'
      : hasFlash
      ? 'netscape'
      : 'unknown'
  }
  _detectFlashSupport()
  var ZeroClipboard = function (elements) {
    if (!(this instanceof ZeroClipboard)) {
      return new ZeroClipboard(elements)
    }
    this.id = '' + _clientIdCounter++
    _clientMeta[this.id] = {
      instance: this,
      elements: [],
      handlers: {}
    }
    if (elements) {
      this.clip(elements)
    }
    if (typeof _flashState.ready !== 'boolean') {
      _flashState.ready = false
    }
    if (!ZeroClipboard.isFlashUnusable() && _flashState.bridge === null) {
      var _client = this
      var maxWait = _globalConfig.flashLoadTimeout
      if (typeof maxWait === 'number' && maxWait >= 0) {
        setTimeout(function () {
          if (typeof _flashState.deactivated !== 'boolean') {
            _flashState.deactivated = true
          }
          if (_flashState.deactivated === true) {
            ZeroClipboard.emit({
              type: 'error',
              name: 'flash-deactivated',
              client: _client
            })
          }
        }, maxWait)
      }
      _flashState.overdue = false
      _bridge()
    }
  }
  ZeroClipboard.prototype.setText = function (text) {
    ZeroClipboard.setData('text/plain', text)
    return this
  }
  ZeroClipboard.prototype.setHtml = function (html) {
    ZeroClipboard.setData('text/html', html)
    return this
  }
  ZeroClipboard.prototype.setRichText = function (richText) {
    ZeroClipboard.setData('application/rtf', richText)
    return this
  }
  ZeroClipboard.prototype.setData = function () {
    ZeroClipboard.setData.apply(ZeroClipboard, _args(arguments))
    return this
  }
  ZeroClipboard.prototype.clearData = function () {
    ZeroClipboard.clearData.apply(ZeroClipboard, _args(arguments))
    return this
  }
  ZeroClipboard.prototype.setSize = function (width, height) {
    _setSize(width, height)
    return this
  }
  var _setHandCursor = function (enabled) {
    if (
      _flashState.ready === true &&
      _flashState.bridge &&
      typeof _flashState.bridge.setHandCursor === 'function'
    ) {
      _flashState.bridge.setHandCursor(enabled)
    } else {
      _flashState.ready = false
    }
  }
  ZeroClipboard.prototype.destroy = function () {
    this.unclip()
    this.off()
    delete _clientMeta[this.id]
  }
  var _getAllClients = function () {
    var i,
      len,
      client,
      clients = [],
      clientIds = _objectKeys(_clientMeta)
    for (i = 0, len = clientIds.length; i < len; i++) {
      client = _clientMeta[clientIds[i]].instance
      if (client && client instanceof ZeroClipboard) {
        clients.push(client)
      }
    }
    return clients
  }
  ZeroClipboard.version = '2.0.0-beta.5'
  var _globalConfig = {
    swfPath: _swfPath,
    trustedDomains: window.location.host ? [window.location.host] : [],
    cacheBust: true,
    forceHandCursor: false,
    forceEnhancedClipboard: false,
    zIndex: 999999999,
    debug: false,
    title: null,
    autoActivate: true,
    flashLoadTimeout: 3e4
  }
  ZeroClipboard.isFlashUnusable = function () {
    return !!(
      _flashState.disabled ||
      _flashState.outdated ||
      _flashState.unavailable ||
      _flashState.deactivated
    )
  }
  ZeroClipboard.config = function (options) {
    if (typeof options === 'object' && options !== null) {
      _extend(_globalConfig, options)
    }
    if (typeof options === 'string' && options) {
      if (_globalConfig.hasOwnProperty(options)) {
        return _globalConfig[options]
      }
      return
    }
    var copy = {}
    for (var prop in _globalConfig) {
      if (_globalConfig.hasOwnProperty(prop)) {
        if (typeof _globalConfig[prop] === 'object' && _globalConfig[prop] !== null) {
          if ('length' in _globalConfig[prop]) {
            copy[prop] = _globalConfig[prop].slice(0)
          } else {
            copy[prop] = _extend({}, _globalConfig[prop])
          }
        } else {
          copy[prop] = _globalConfig[prop]
        }
      }
    }
    return copy
  }
  ZeroClipboard.destroy = function () {
    ZeroClipboard.deactivate()
    for (var clientId in _clientMeta) {
      if (_clientMeta.hasOwnProperty(clientId) && _clientMeta[clientId]) {
        var client = _clientMeta[clientId].instance
        if (client && typeof client.destroy === 'function') {
          client.destroy()
        }
      }
    }
    var flashBridge = _flashState.bridge
    if (flashBridge) {
      var htmlBridge = _getHtmlBridge(flashBridge)
      if (htmlBridge) {
        if (_flashState.pluginType === 'activex' && 'readyState' in flashBridge) {
          flashBridge.style.display = 'none'
          ;(function removeSwfFromIE() {
            if (flashBridge.readyState === 4) {
              for (var prop in flashBridge) {
                if (typeof flashBridge[prop] === 'function') {
                  flashBridge[prop] = null
                }
              }
              flashBridge.parentNode.removeChild(flashBridge)
              if (htmlBridge.parentNode) {
                htmlBridge.parentNode.removeChild(htmlBridge)
              }
            } else {
              setTimeout(removeSwfFromIE, 10)
            }
          })()
        } else {
          flashBridge.parentNode.removeChild(flashBridge)
          if (htmlBridge.parentNode) {
            htmlBridge.parentNode.removeChild(htmlBridge)
          }
        }
      }
      _flashState.ready = null
      _flashState.bridge = null
      _flashState.deactivated = null
    }
    ZeroClipboard.clearData()
  }
  ZeroClipboard.activate = function (element) {
    if (_currentElement) {
      _removeClass(_currentElement, _globalConfig.hoverClass)
      _removeClass(_currentElement, _globalConfig.activeClass)
    }
    _currentElement = element
    _addClass(element, _globalConfig.hoverClass)
    _reposition()
    var newTitle = _globalConfig.title || element.getAttribute('title')
    if (newTitle) {
      var htmlBridge = _getHtmlBridge(_flashState.bridge)
      if (htmlBridge) {
        htmlBridge.setAttribute('title', newTitle)
      }
    }
    var useHandCursor =
      _globalConfig.forceHandCursor === true || _getStyle(element, 'cursor') === 'pointer'
    _setHandCursor(useHandCursor)
  }
  ZeroClipboard.deactivate = function () {
    var htmlBridge = _getHtmlBridge(_flashState.bridge)
    if (htmlBridge) {
      htmlBridge.removeAttribute('title')
      htmlBridge.style.left = '0px'
      htmlBridge.style.top = '-9999px'
      _setSize(1, 1)
    }
    if (_currentElement) {
      _removeClass(_currentElement, _globalConfig.hoverClass)
      _removeClass(_currentElement, _globalConfig.activeClass)
      _currentElement = null
    }
  }
  ZeroClipboard.state = function () {
    return {
      browser: _pick(window.navigator, ['userAgent', 'platform', 'appName']),
      flash: _omit(_flashState, ['bridge']),
      zeroclipboard: {
        version: ZeroClipboard.version,
        config: ZeroClipboard.config()
      }
    }
  }
  ZeroClipboard.setData = function (format, data) {
    var dataObj
    if (typeof format === 'object' && format && typeof data === 'undefined') {
      dataObj = format
      ZeroClipboard.clearData()
    } else if (typeof format === 'string' && format) {
      dataObj = {}
      dataObj[format] = data
    } else {
      return
    }
    for (var dataFormat in dataObj) {
      if (
        dataFormat &&
        dataObj.hasOwnProperty(dataFormat) &&
        typeof dataObj[dataFormat] === 'string' &&
        dataObj[dataFormat]
      ) {
        _clipData[dataFormat] = dataObj[dataFormat]
      }
    }
  }
  ZeroClipboard.clearData = function (format) {
    if (typeof format === 'undefined') {
      _deleteOwnProperties(_clipData)
      _clipDataFormatMap = null
    } else if (typeof format === 'string' && _clipData.hasOwnProperty(format)) {
      delete _clipData[format]
    }
  }
  var _bridge = function () {
    var flashBridge, len
    var container = document.getElementById('global-zeroclipboard-html-bridge')
    if (!container) {
      var allowScriptAccess = _determineScriptAccess(window.location.host, _globalConfig)
      var allowNetworking = allowScriptAccess === 'never' ? 'none' : 'all'
      var flashvars = _vars(_globalConfig)
      var swfUrl = _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig)
      container = _createHtmlBridge()
      var divToBeReplaced = document.createElement('div')
      container.appendChild(divToBeReplaced)
      document.body.appendChild(container)
      var tmpDiv = document.createElement('div')
      var oldIE = _flashState.pluginType === 'activex'
      tmpDiv.innerHTML =
        '<object id="global-zeroclipboard-flash-bridge" name="global-zeroclipboard-flash-bridge" ' +
        'width="100%" height="100%" ' +
        (oldIE
          ? 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'
          : 'type="application/x-shockwave-flash" data="' + swfUrl + '"') +
        '>' +
        (oldIE ? '<param name="movie" value="' + swfUrl + '"/>' : '') +
        '<param name="allowScriptAccess" value="' +
        allowScriptAccess +
        '"/>' +
        '<param name="allowNetworking" value="' +
        allowNetworking +
        '"/>' +
        '<param name="menu" value="false"/>' +
        '<param name="wmode" value="transparent"/>' +
        '<param name="flashvars" value="' +
        flashvars +
        '"/>' +
        '</object>'
      flashBridge = tmpDiv.firstChild
      tmpDiv = null
      flashBridge.ZeroClipboard = ZeroClipboard
      container.replaceChild(flashBridge, divToBeReplaced)
    }
    if (!flashBridge) {
      flashBridge = document['global-zeroclipboard-flash-bridge']
      if (flashBridge && (len = flashBridge.length)) {
        flashBridge = flashBridge[len - 1]
      }
      if (!flashBridge) {
        flashBridge = container.firstChild
      }
    }
    _flashState.bridge = flashBridge || null
  }
  var _createHtmlBridge = function () {
    var container = document.createElement('div')
    container.id = 'global-zeroclipboard-html-bridge'
    container.className = 'global-zeroclipboard-container'
    container.style.position = 'absolute'
    container.style.left = '0px'
    container.style.top = '-9999px'
    container.style.width = '1px'
    container.style.height = '1px'
    container.style.zIndex = '' + _getSafeZIndex(_globalConfig.zIndex)
    return container
  }
  var _getHtmlBridge = function (flashBridge) {
    var htmlBridge = flashBridge && flashBridge.parentNode
    while (htmlBridge && htmlBridge.nodeName === 'OBJECT' && htmlBridge.parentNode) {
      htmlBridge = htmlBridge.parentNode
    }
    return htmlBridge || null
  }
  var _reposition = function () {
    if (_currentElement) {
      var pos = _getDOMObjectPosition(_currentElement, _globalConfig.zIndex)
      var htmlBridge = _getHtmlBridge(_flashState.bridge)
      if (htmlBridge) {
        htmlBridge.style.top = pos.top + 'px'
        htmlBridge.style.left = pos.left + 'px'
        htmlBridge.style.width = pos.width + 'px'
        htmlBridge.style.height = pos.height + 'px'
        htmlBridge.style.zIndex = pos.zIndex + 1
      }
      _setSize(pos.width, pos.height)
    }
  }
  var _setSize = function (width, height) {
    var htmlBridge = _getHtmlBridge(_flashState.bridge)
    if (htmlBridge) {
      htmlBridge.style.width = width + 'px'
      htmlBridge.style.height = height + 'px'
    }
  }
  ZeroClipboard.emit = function (event) {
    var eventType, eventObj, performCallbackAsync, clients, i, len, eventCopy, returnVal, tmp
    if (typeof event === 'string' && event) {
      eventType = event
    }
    if (typeof event === 'object' && event && typeof event.type === 'string' && event.type) {
      eventType = event.type
      eventObj = event
    }
    if (!eventType) {
      return
    }
    event = _createEvent(eventType, eventObj)
    _preprocessEvent(event)
    if (event.type === 'ready' && _flashState.overdue === true) {
      return ZeroClipboard.emit({
        type: 'error',
        name: 'flash-overdue'
      })
    }
    performCallbackAsync = !/^(before)?copy$/.test(event.type)
    if (event.client) {
      _dispatchClientCallbacks.call(event.client, event, performCallbackAsync)
    } else {
      clients =
        event.target && event.target !== window && _globalConfig.autoActivate === true
          ? _getAllClientsClippedToElement(event.target)
          : _getAllClients()
      for (i = 0, len = clients.length; i < len; i++) {
        eventCopy = _extend({}, event, {
          client: clients[i]
        })
        _dispatchClientCallbacks.call(clients[i], eventCopy, performCallbackAsync)
      }
    }
    if (event.type === 'copy') {
      tmp = _mapClipDataToFlash(_clipData)
      returnVal = tmp.data
      _clipDataFormatMap = tmp.formatMap
    }
    return returnVal
  }
  var _dispatchClientCallbacks = function (event, async) {
    var handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers[event.type]
    if (handlers && handlers.length) {
      var i,
        len,
        func,
        context,
        originalContext = this
      for (i = 0, len = handlers.length; i < len; i++) {
        func = handlers[i]
        context = originalContext
        if (typeof func === 'string' && typeof window[func] === 'function') {
          func = window[func]
        }
        if (typeof func === 'object' && func && typeof func.handleEvent === 'function') {
          context = func
          func = func.handleEvent
        }
        if (typeof func === 'function') {
          _dispatchCallback(func, context, [event], async)
        }
      }
    }
    return this
  }
  var _eventMessages = {
    ready: 'Flash communication is established',
    error: {
      'flash-disabled': 'Flash is disabled or not installed',
      'flash-outdated': 'Flash is too outdated to support ZeroClipboard',
      'flash-unavailable': 'Flash is unable to communicate bidirectionally with JavaScript',
      'flash-deactivated':
        'Flash is too outdated for your browser and/or is configured as click-to-activate',
      'flash-overdue':
        'Flash communication was established but NOT within the acceptable time limit'
    }
  }
  var _createEvent = function (eventType, event) {
    if (!(eventType || (event && event.type))) {
      return
    }
    event = event || {}
    eventType = (eventType || event.type).toLowerCase()
    _extend(event, {
      type: eventType,
      target: event.target || _currentElement || null,
      relatedTarget: event.relatedTarget || null,
      currentTarget: (_flashState && _flashState.bridge) || null
    })
    var msg = _eventMessages[event.type]
    if (event.type === 'error' && event.name && msg) {
      msg = msg[event.name]
    }
    if (msg) {
      event.message = msg
    }
    if (event.type === 'ready') {
      _extend(event, {
        target: null,
        version: _flashState.version
      })
    }
    if (event.type === 'error') {
      event.target = null
      if (/^flash-(outdated|unavailable|deactivated|overdue)$/.test(event.name)) {
        _extend(event, {
          version: _flashState.version,
          minimumVersion: '11.0.0'
        })
      }
    }
    if (event.type === 'copy') {
      event.clipboardData = {
        setData: ZeroClipboard.setData,
        clearData: ZeroClipboard.clearData
      }
    }
    if (event.type === 'aftercopy') {
      event = _mapClipResultsFromFlash(event, _clipDataFormatMap)
    }
    if (event.target && !event.relatedTarget) {
      event.relatedTarget = _getRelatedTarget(event.target)
    }
    return event
  }
  var _getRelatedTarget = function (targetEl) {
    var relatedTargetId =
      targetEl && targetEl.getAttribute && targetEl.getAttribute('data-clipboard-target')
    return relatedTargetId ? document.getElementById(relatedTargetId) : null
  }
  var _preprocessEvent = function (event) {
    var element = event.target || _currentElement
    switch (event.type) {
      case 'error':
        if (
          _inArray(event.name, [
            'flash-disabled',
            'flash-outdated',
            'flash-deactivated',
            'flash-overdue'
          ])
        ) {
          _extend(_flashState, {
            disabled: event.name === 'flash-disabled',
            outdated: event.name === 'flash-outdated',
            unavailable: event.name === 'flash-unavailable',
            deactivated: event.name === 'flash-deactivated',
            overdue: event.name === 'flash-overdue',
            ready: false
          })
        }
        break

      case 'ready':
        var wasDeactivated = _flashState.deactivated === true
        _extend(_flashState, {
          disabled: false,
          outdated: false,
          unavailable: false,
          deactivated: false,
          overdue: wasDeactivated,
          ready: !wasDeactivated
        })
        break

      case 'copy':
        var textContent,
          htmlContent,
          targetEl = event.relatedTarget
        if (
          !(_clipData['text/html'] || _clipData['text/plain']) &&
          targetEl &&
          (htmlContent = targetEl.value || targetEl.outerHTML || targetEl.innerHTML) &&
          (textContent = targetEl.value || targetEl.textContent || targetEl.innerText)
        ) {
          event.clipboardData.clearData()
          event.clipboardData.setData('text/plain', textContent)
          if (htmlContent !== textContent) {
            event.clipboardData.setData('text/html', htmlContent)
          }
        } else if (
          !_clipData['text/plain'] &&
          event.target &&
          (textContent = event.target.getAttribute('data-clipboard-text'))
        ) {
          event.clipboardData.clearData()
          event.clipboardData.setData('text/plain', textContent)
        }
        break

      case 'aftercopy':
        ZeroClipboard.clearData()
        if (element && element !== _safeActiveElement() && element.focus) {
          element.focus()
        }
        break

      case 'mouseover':
        _addClass(element, _globalConfig.hoverClass)
        break

      case 'mouseout':
        if (_globalConfig.autoActivate === true) {
          ZeroClipboard.deactivate()
        }
        break

      case 'mousedown':
        _addClass(element, _globalConfig.activeClass)
        break

      case 'mouseup':
        _removeClass(element, _globalConfig.activeClass)
        break
    }
  }
  ZeroClipboard.prototype.on = function (eventName, func) {
    var i,
      len,
      events,
      added = {},
      handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers
    if (typeof eventName === 'string' && eventName) {
      events = eventName.toLowerCase().split(/\s+/)
    } else if (typeof eventName === 'object' && eventName && typeof func === 'undefined') {
      for (i in eventName) {
        if (
          eventName.hasOwnProperty(i) &&
          typeof i === 'string' &&
          i &&
          typeof eventName[i] === 'function'
        ) {
          this.on(i, eventName[i])
        }
      }
    }
    if (events && events.length) {
      for (i = 0, len = events.length; i < len; i++) {
        eventName = events[i].replace(/^on/, '')
        added[eventName] = true
        if (!handlers[eventName]) {
          handlers[eventName] = []
        }
        handlers[eventName].push(func)
      }
      if (added.ready && _flashState.ready) {
        ZeroClipboard.emit({
          type: 'ready',
          client: this
        })
      }
      if (added.error) {
        var errorTypes = ['disabled', 'outdated', 'unavailable', 'deactivated', 'overdue']
        for (i = 0, len = errorTypes.length; i < len; i++) {
          if (_flashState[errorTypes[i]]) {
            ZeroClipboard.emit({
              type: 'error',
              name: 'flash-' + errorTypes[i],
              client: this
            })
            break
          }
        }
      }
    }
    return this
  }
  ZeroClipboard.prototype.off = function (eventName, func) {
    var i,
      len,
      foundIndex,
      events,
      perEventHandlers,
      handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers
    if (arguments.length === 0) {
      events = _objectKeys(handlers)
    } else if (typeof eventName === 'string' && eventName) {
      events = eventName.split(/\s+/)
    } else if (typeof eventName === 'object' && eventName && typeof func === 'undefined') {
      for (i in eventName) {
        if (
          eventName.hasOwnProperty(i) &&
          typeof i === 'string' &&
          i &&
          typeof eventName[i] === 'function'
        ) {
          this.off(i, eventName[i])
        }
      }
    }
    if (events && events.length) {
      for (i = 0, len = events.length; i < len; i++) {
        eventName = events[i].toLowerCase().replace(/^on/, '')
        perEventHandlers = handlers[eventName]
        if (perEventHandlers && perEventHandlers.length) {
          if (func) {
            foundIndex = _inArray(func, perEventHandlers)
            while (foundIndex !== -1) {
              perEventHandlers.splice(foundIndex, 1)
              foundIndex = _inArray(func, perEventHandlers, foundIndex)
            }
          } else {
            handlers[eventName].length = 0
          }
        }
      }
    }
    return this
  }
  ZeroClipboard.prototype.handlers = function (eventName) {
    var prop,
      copy = null,
      handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers
    if (handlers) {
      if (typeof eventName === 'string' && eventName) {
        return handlers[eventName] ? handlers[eventName].slice(0) : null
      }
      copy = {}
      for (prop in handlers) {
        if (handlers.hasOwnProperty(prop) && handlers[prop]) {
          copy[prop] = handlers[prop].slice(0)
        }
      }
    }
    return copy
  }
  ZeroClipboard.prototype.clip = function (elements) {
    elements = _prepClip(elements)
    for (var i = 0; i < elements.length; i++) {
      if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {
        if (!elements[i].zcClippingId) {
          elements[i].zcClippingId = 'zcClippingId_' + _elementIdCounter++
          _elementMeta[elements[i].zcClippingId] = [this.id]
          if (_globalConfig.autoActivate === true) {
            _addEventHandler(elements[i], 'mouseover', _elementMouseOver)
          }
        } else if (_inArray(this.id, _elementMeta[elements[i].zcClippingId]) === -1) {
          _elementMeta[elements[i].zcClippingId].push(this.id)
        }
        var clippedElements = _clientMeta[this.id].elements
        if (_inArray(elements[i], clippedElements) === -1) {
          clippedElements.push(elements[i])
        }
      }
    }
    return this
  }
  ZeroClipboard.prototype.unclip = function (elements) {
    var meta = _clientMeta[this.id]
    if (!meta) {
      return this
    }
    var clippedElements = meta.elements
    var arrayIndex
    if (typeof elements === 'undefined') {
      elements = clippedElements.slice(0)
    } else {
      elements = _prepClip(elements)
    }
    for (var i = elements.length; i--; ) {
      if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {
        arrayIndex = 0
        while ((arrayIndex = _inArray(elements[i], clippedElements, arrayIndex)) !== -1) {
          clippedElements.splice(arrayIndex, 1)
        }
        var clientIds = _elementMeta[elements[i].zcClippingId]
        if (clientIds) {
          arrayIndex = 0
          while ((arrayIndex = _inArray(this.id, clientIds, arrayIndex)) !== -1) {
            clientIds.splice(arrayIndex, 1)
          }
          if (clientIds.length === 0) {
            if (_globalConfig.autoActivate === true) {
              _removeEventHandler(elements[i], 'mouseover', _elementMouseOver)
            }
            delete elements[i].zcClippingId
          }
        }
      }
    }
    return this
  }
  ZeroClipboard.prototype.elements = function () {
    var meta = _clientMeta[this.id]
    return meta && meta.elements ? meta.elements.slice(0) : []
  }
  var _getAllClientsClippedToElement = function (element) {
    var elementMetaId,
      clientIds,
      i,
      len,
      client,
      clients = []
    if (
      element &&
      element.nodeType === 1 &&
      (elementMetaId = element.zcClippingId) &&
      _elementMeta.hasOwnProperty(elementMetaId)
    ) {
      clientIds = _elementMeta[elementMetaId]
      if (clientIds && clientIds.length) {
        for (i = 0, len = clientIds.length; i < len; i++) {
          client = _clientMeta[clientIds[i]].instance
          if (client && client instanceof ZeroClipboard) {
            clients.push(client)
          }
        }
      }
    }
    return clients
  }
  _globalConfig.hoverClass = 'zeroclipboard-is-hover'
  _globalConfig.activeClass = 'zeroclipboard-is-active'
  if (typeof define === 'function' && define.amd) {
    define(function () {
      return ZeroClipboard
    })
  } else if (
    typeof module === 'object' &&
    module &&
    typeof module.exports === 'object' &&
    module.exports
  ) {
    module.exports = ZeroClipboard
  } else {
    window.ZeroClipboard = ZeroClipboard
  }
})(
  (function () {
    return this
  })()
)