From a8517f0c9f784c62bccbead5485dd751a8f17d25 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Tue, 4 Feb 2020 18:01:25 +0800 Subject: [PATCH 1/3] beautify web interface, add album picture display, play/pause and play specific file fecture in the web interface. --- interface.py | 19 +++++-- static/css/custom.css | 5 ++ static/image/unknown-album.png | Bin 0 -> 33912 bytes templates/index.html | 97 ++++++++++++++++++++++++--------- 4 files changed, 91 insertions(+), 30 deletions(-) create mode 100644 static/css/custom.css create mode 100644 static/image/unknown-album.png diff --git a/interface.py b/interface.py index e4b01e2..151b70e 100644 --- a/interface.py +++ b/interface.py @@ -71,8 +71,9 @@ def index(): if 'add_file' in request.form and ".." not in request.form['add_file']: item = {'type': 'file', 'path' : request.form['add_file'], + 'title' : 'Unknown', 'user' : 'Web'} - var.playlist.append(item) + var.playlist.append(var.botamusique.get_music_tag_info(item, var.config.get('bot', 'music_folder') + item['path'])) elif ('add_folder' in request.form and ".." not in request.form['add_folder']) or ('add_folder_recursively' in request.form and ".." not in request.form['add_folder_recursively']): try: @@ -106,13 +107,21 @@ def index(): 'user': "Web"}) elif 'delete_music' in request.form: - if len(var.playlist) >= request.form['delete_music']: - var.playlist.pop(request.form['delete_music']) - + if len(var.playlist.playlist) >= int(request.form['delete_music']): + var.playlist.remove(int(request.form['delete_music'])) + + elif 'play_music' in request.form: + if len(var.playlist.playlist) >= int(request.form['play_music']): + var.botamusique.pause() + var.botamusique.launch_music(int(request.form['play_music'])) + elif 'action' in request.form: action = request.form['action'] if action == "randomize": - random.shuffle(var.playlist) + random.shuffle(var.playlist.playlist) + elif action == "stop": + var.botamusique.pause() + return render_template('index.html', all_files=files, diff --git a/static/css/custom.css b/static/css/custom.css new file mode 100644 index 0000000..f2cedf6 --- /dev/null +++ b/static/css/custom.css @@ -0,0 +1,5 @@ +.bs-docs-section{margin-top:4em} +.line{display:flex; margin-bottom:1rem} +.btn-space{margin-right:5px} +.playlist-title{display:inline-block} +.playlist-artwork{display:inline-block; margin-left:5px;} diff --git a/static/image/unknown-album.png b/static/image/unknown-album.png new file mode 100644 index 0000000000000000000000000000000000000000..50455c5d1623a9dd8ed26bed1b8ec2a4bafbdd92 GIT binary patch literal 33912 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 W#XJeuUokK+FnGH9xvXVHq<3 literal 0 HcmV?d00001 diff --git a/templates/index.html b/templates/index.html index 3351c91..2f3062d 100644 --- a/templates/index.html +++ b/templates/index.html @@ -54,13 +54,20 @@ botamusique web interface +
-
+
+ +
+
+
@@ -69,21 +76,28 @@
+
+
+ + +
+
+ + +
-
- - -
@@ -96,16 +110,35 @@ - {% for m in playlist[1:] %} + {% for m in playlist.playlist %} + {% if loop.index0 == playlist.current_index %} + + {% else %} + {% endif %} - + {% endfor %} @@ -128,8 +167,10 @@ + -
+
+
@@ -154,10 +195,12 @@
+
-
+
+
@@ -190,7 +233,10 @@
-
+
+ +
+
@@ -220,6 +266,7 @@
+
From abd5eb8e95d7ffa6406371c3ead13b4e6f65f988 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Tue, 4 Feb 2020 23:30:56 +0800 Subject: [PATCH 2/3] beautify and enhance web interface, debug --- interface.py | 31 +++++++-- media/playlist.py | 9 +++ mumbleBot.py | 17 +++-- static/css/custom.css | 1 - templates/index.html | 142 +++++++++++++++++++++++++----------------- variables.py | 3 +- 6 files changed, 132 insertions(+), 71 deletions(-) diff --git a/interface.py b/interface.py index 151b70e..1d4be14 100644 --- a/interface.py +++ b/interface.py @@ -9,6 +9,7 @@ import random from werkzeug.utils import secure_filename import errno import media +import logging class ReverseProxied(object): @@ -67,14 +68,24 @@ def index(): music_library.add_file(file) if request.method == 'POST': - print(request.form) - if 'add_file' in request.form and ".." not in request.form['add_file']: + logging.debug("Post request: "+ str(request.form)) + if 'add_file_bottom' in request.form and ".." not in request.form['add_file_bottom']: item = {'type': 'file', - 'path' : request.form['add_file'], + 'path' : request.form['add_file_bottom'], 'title' : 'Unknown', 'user' : 'Web'} var.playlist.append(var.botamusique.get_music_tag_info(item, var.config.get('bot', 'music_folder') + item['path'])) + elif 'add_file_next' in request.form and ".." not in request.form['add_file_next']: + item = {'type': 'file', + 'path' : request.form['add_file_next'], + 'title' : 'Unknown', + 'user' : 'Web'} + var.playlist.insert( + var.playlist.current_index + 1, + var.botamusique.get_music_tag_info(item, var.config.get('bot', 'music_folder') + item['path']) + ) + elif ('add_folder' in request.form and ".." not in request.form['add_folder']) or ('add_folder_recursively' in request.form and ".." not in request.form['add_folder_recursively']): try: folder = request.form['add_folder'] @@ -108,7 +119,13 @@ def index(): elif 'delete_music' in request.form: if len(var.playlist.playlist) >= int(request.form['delete_music']): - var.playlist.remove(int(request.form['delete_music'])) + if var.playlist.current_index == int(request.form['delete_music']): + var.botamusique.pause() + var.playlist.remove(int(request.form['delete_music'])) + var.botamusique.launch_music() + else: + var.playlist.remove(int(request.form['delete_music'])) + elif 'play_music' in request.form: if len(var.playlist.playlist) >= int(request.form['play_music']): @@ -121,7 +138,8 @@ def index(): random.shuffle(var.playlist.playlist) elif action == "stop": var.botamusique.pause() - + elif action == "clear": + var.botamusique.stop() return render_template('index.html', all_files=files, @@ -137,7 +155,8 @@ def upload(): if not file: return redirect("./", code=406) - filename = secure_filename(file.filename).strip() + #filename = secure_filename(file.filename).strip() + filename = file.filename if filename == '': return redirect("./", code=406) diff --git a/media/playlist.py b/media/playlist.py index 049999e..b688732 100644 --- a/media/playlist.py +++ b/media/playlist.py @@ -8,6 +8,15 @@ class PlayList: def append(self, item): self.playlist.append(item) + def insert(self, index, item): + if index == -1: + index = self.current_index + + self.playlist.insert(index, item) + + if index <= self.current_index: + self.current_index += 1 + def length(self): return len(self.playlist) diff --git a/mumbleBot.py b/mumbleBot.py index f3e0fe4..32a6084 100644 --- a/mumbleBot.py +++ b/mumbleBot.py @@ -547,7 +547,7 @@ class MumbleBot: # Allow to remove specific music into the queue with a number if parameter is not None and parameter.isdigit() and int(parameter) > 0: if int(parameter) < len(var.playlist.playlist): - removed = var.playlist.pop(int(parameter)) + removed = var.playlist.jump(int(parameter)) # the Title isn't here if the music wasn't downloaded self.send_msg(var.config.get('strings', 'removing_item') % ( @@ -609,7 +609,7 @@ class MumbleBot: uri = "" music = None if index == -1: - music = var.playlist.next() + music = var.playlist.current_item() else: music = var.playlist.jump(index) @@ -636,7 +636,7 @@ class MumbleBot: music['thumbnail'] + '"/>' if var.config.getboolean('bot', 'announce_current_music'): self.send_msg(var.config.get( - 'strings', 'now_playing') % (music['title'], thumbnail_html)) + 'strings', 'now_playing') % (music['artist'] + ' - ' + music['title'], thumbnail_html)) elif music["type"] == "file": uri = var.config.get('bot', 'music_folder') + \ @@ -650,7 +650,7 @@ class MumbleBot: #logging.debug("Thumbnail data " + thumbnail_html) if var.config.getboolean('bot', 'announce_current_music'): self.send_msg(var.config.get( - 'strings', 'now_playing') % (music['title'], thumbnail_html)) + 'strings', 'now_playing') % (music['artist'] + ' - ' + music['title'], thumbnail_html)) elif music["type"] == "radio": uri = music["url"] @@ -671,6 +671,7 @@ class MumbleBot: # The ffmpeg process is a thread self.thread = sp.Popen(command, stdout=sp.PIPE, bufsize=480) self.is_playing = True + self.is_pause = False def download_music(self, index=-1): if index == -1: @@ -781,7 +782,11 @@ class MumbleBot: elif uri[-3:] == "mp3": tags = mutagen.File(uri) if "APIC:" in tags: - music['thumbnail'] = base64.b64encode(tags["APIC:"].data).decode('utf-8') + im = Image.open(BytesIO(tags["APIC:"].data)) + im.thumbnail((100, 100), Image.ANTIALIAS) + buffer = BytesIO() + im.save(buffer, format="JPEG") + music['thumbnail'] = base64.b64encode(buffer.getvalue()).decode('utf-8') return music @@ -789,7 +794,7 @@ class MumbleBot: def async_download_next(self): # Function start if the next music isn't ready # Do nothing in case the next music is already downloaded - logging.info("Async download next asked") + logging.info("Async download next asked ") if len(var.playlist.playlist) > 1 and var.playlist.next_item()['type'] == 'url' and var.playlist.next_item()['ready'] in ["no", "validation"]: th = threading.Thread( target=self.download_music, kwargs={'index': var.playlist.next_index()}) diff --git a/static/css/custom.css b/static/css/custom.css index f2cedf6..c826894 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -1,5 +1,4 @@ .bs-docs-section{margin-top:4em} -.line{display:flex; margin-bottom:1rem} .btn-space{margin-right:5px} .playlist-title{display:inline-block} .playlist-artwork{display:inline-block; margin-left:5px;} diff --git a/templates/index.html b/templates/index.html index 2f3062d..109a5b3 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,24 +4,33 @@ {%- set subdirpath = os.path.relpath(subdirobj.fullpath, music_library.fullpath) %} {%- set subdirid = subdirpath.replace("/","-") %}
  • - {{ subdirpath }}/ 
    -
    - - - -
    - - - +
    + + +
    +
    - + -
    + + {{ subdirpath }}/
  • {{- dirlisting(subdirobj, subdirpath) -}} @@ -33,15 +42,29 @@ {% set filepath = os.path.relpath(os.path.join(dir.fullpath, file), music_library.fullpath) %}
  • -
    - - - +
    + + +
    +
    - + -
     {{ filepath }} +
  •   + {{ filepath }} {% endfor %} {%- endif %} @@ -71,31 +94,18 @@
    -

    Play List

    +

    Play List

    -
    -

    Currently Playing: - {% if playlist.length() > 0 %} - {% if 'url' in playlist.current_item() %} - {{ playlist.current_item()['url'] }} - {% elif 'path' in playlist.current_item() %} - {{ playlist.current_item()['path'] }} - {% endif %} - {% else %} - No music - {% endif %} -

    -
    -
    +
    - +
    - +
    @@ -103,13 +113,17 @@
    - + {% if playlist.length() == 0 %} + + + + {% else %} {% for m in playlist.playlist %} {% if loop.index0 == playlist.current_index %} @@ -117,9 +131,8 @@ {% endif %} - {% endfor %} + {% endif %}
    {{ loop.index }}{{ m['type'] }}{{ m['type'].capitalize() }} - {% if 'title' in m %} - ({{ m['title'] }}) - {% else %} - No title - {% endif %} +
    + {% if 'thumbnail' in m %} + + {% else %} + + {% endif %} +
    +
    + {% if 'title' in m and m['title'].strip() %} + {{ m['title'] }} + {% else %} + {{ m['url'] }} + {% endif %} +
    + {% if 'artist' in m %} + {{ m['artist'] }} + {% else %} + Unknown Artist + {% endif %} +
    {% if 'url' in m %} @@ -115,10 +148,16 @@ {% endif %} -
    - - -
    +
    +
    + + +
    +
    + + +
    +
    #Type Title Url/Path Action
    Play list is empty.
    {{ loop.index }}{{ m['type'].capitalize() }} -
    +
    {% if 'thumbnail' in m %} {% else %} @@ -132,6 +145,7 @@ {% else %} {{ m['url'] }} {% endif %} + {{ m['type'].capitalize() }}
    {% if 'artist' in m %} {{ m['artist'] }} @@ -142,27 +156,35 @@
    {% if 'url' in m %} - {{ m['url'] }} + {{ m['url']|truncate(50) }} {% elif 'path' in m %} - {{ m['path'] }} + {{ m['path']|truncate(50) }} {% endif %} -
    +
    - +
    - +
    + +
    +
    + + +
    +
    @@ -174,19 +196,18 @@
    -

    Music library

    +

    Music Library

    -
    +
    - +
    - +

    @@ -209,14 +230,14 @@
    -
    +
    Upload To - +
    @@ -244,9 +266,11 @@
    - - - + +
    + + +
    @@ -258,9 +282,11 @@
    - - - + +
    + + +
    @@ -271,6 +297,8 @@ + + + if (val === '') return true; + if (val === 'false') return false; + if (val === 'true') return true; + return val; + } + + if (DOCUMENT && typeof DOCUMENT.querySelector === 'function') { + var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']]; + attrs.forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + attr = _ref2[0], + key = _ref2[1]; + + var val = coerce(getAttrConfig(attr)); + + if (val !== undefined && val !== null) { + initial[key] = val; + } + }); + } + + var _default = { + familyPrefix: DEFAULT_FAMILY_PREFIX, + replacementClass: DEFAULT_REPLACEMENT_CLASS, + autoReplaceSvg: true, + autoAddCss: true, + autoA11y: true, + searchPseudoElements: false, + observeMutations: true, + mutateApproach: 'async', + keepOriginalSource: true, + measurePerformance: false, + showMissingIcons: true + }; + + var _config = _objectSpread({}, _default, initial); + + if (!_config.autoReplaceSvg) _config.observeMutations = false; + + var config = _objectSpread({}, _config); + + WINDOW.FontAwesomeConfig = config; + + var w = WINDOW || {}; + if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {}; + if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {}; + if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {}; + if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = []; + var namespace = w[NAMESPACE_IDENTIFIER]; + + var functions = []; + + var listener = function listener() { + DOCUMENT.removeEventListener('DOMContentLoaded', listener); + loaded = 1; + functions.map(function (fn) { + return fn(); + }); + }; + + var loaded = false; + + if (IS_DOM) { + loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState); + if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener); + } + + function domready (fn) { + if (!IS_DOM) return; + loaded ? setTimeout(fn, 0) : functions.push(fn); + } + + var PENDING = 'pending'; + var SETTLED = 'settled'; + var FULFILLED = 'fulfilled'; + var REJECTED = 'rejected'; + + var NOOP = function NOOP() {}; + + var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; + var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; + var asyncQueue = []; + var asyncTimer; + + function asyncFlush() { + // run promise callbacks + for (var i = 0; i < asyncQueue.length; i++) { + asyncQueue[i][0](asyncQueue[i][1]); + } // reset async asyncQueue + + + asyncQueue = []; + asyncTimer = false; + } + + function asyncCall(callback, arg) { + asyncQueue.push([callback, arg]); + + if (!asyncTimer) { + asyncTimer = true; + asyncSetTimer(asyncFlush, 0); + } + } + + function invokeResolver(resolver, promise) { + function resolvePromise(value) { + resolve(promise, value); + } + + function rejectPromise(reason) { + reject(promise, reason); + } + + try { + resolver(resolvePromise, rejectPromise); + } catch (e) { + rejectPromise(e); + } + } + + function invokeCallback(subscriber) { + var owner = subscriber.owner; + var settled = owner._state; + var value = owner._data; + var callback = subscriber[settled]; + var promise = subscriber.then; + + if (typeof callback === 'function') { + settled = FULFILLED; + + try { + value = callback(value); + } catch (e) { + reject(promise, e); + } + } + + if (!handleThenable(promise, value)) { + if (settled === FULFILLED) { + resolve(promise, value); + } + + if (settled === REJECTED) { + reject(promise, value); + } + } + } + + function handleThenable(promise, value) { + var resolved; + + try { + if (promise === value) { + throw new TypeError('A promises callback cannot return that same promise.'); + } + + if (value && (typeof value === 'function' || _typeof(value) === 'object')) { + // then should be retrieved only once + var then = value.then; + + if (typeof then === 'function') { + then.call(value, function (val) { + if (!resolved) { + resolved = true; + + if (value === val) { + fulfill(promise, val); + } else { + resolve(promise, val); + } + } + }, function (reason) { + if (!resolved) { + resolved = true; + reject(promise, reason); + } + }); + return true; + } + } + } catch (e) { + if (!resolved) { + reject(promise, e); + } + + return true; + } + + return false; + } + + function resolve(promise, value) { + if (promise === value || !handleThenable(promise, value)) { + fulfill(promise, value); + } + } + + function fulfill(promise, value) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = value; + asyncCall(publishFulfillment, promise); + } + } + + function reject(promise, reason) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = reason; + asyncCall(publishRejection, promise); + } + } + + function publish(promise) { + promise._then = promise._then.forEach(invokeCallback); + } + + function publishFulfillment(promise) { + promise._state = FULFILLED; + publish(promise); + } + + function publishRejection(promise) { + promise._state = REJECTED; + publish(promise); + + if (!promise._handled && isNode) { + global.process.emit('unhandledRejection', promise._data, promise); + } + } + + function notifyRejectionHandled(promise) { + global.process.emit('rejectionHandled', promise); + } + /** + * @class + */ + + + function P(resolver) { + if (typeof resolver !== 'function') { + throw new TypeError('Promise resolver ' + resolver + ' is not a function'); + } + + if (this instanceof P === false) { + throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); + } + + this._then = []; + invokeResolver(resolver, this); + } + + P.prototype = { + constructor: P, + _state: PENDING, + _then: null, + _data: undefined, + _handled: false, + then: function then(onFulfillment, onRejection) { + var subscriber = { + owner: this, + then: new this.constructor(NOOP), + fulfilled: onFulfillment, + rejected: onRejection + }; + + if ((onRejection || onFulfillment) && !this._handled) { + this._handled = true; + + if (this._state === REJECTED && isNode) { + asyncCall(notifyRejectionHandled, this); + } + } + + if (this._state === FULFILLED || this._state === REJECTED) { + // already resolved, call callback async + asyncCall(invokeCallback, subscriber); + } else { + // subscribe + this._then.push(subscriber); + } + + return subscriber.then; + }, + catch: function _catch(onRejection) { + return this.then(null, onRejection); + } + }; + + P.all = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.all().'); + } + + return new P(function (resolve, reject) { + var results = []; + var remaining = 0; + + function resolver(index) { + remaining++; + return function (value) { + results[index] = value; + + if (! --remaining) { + resolve(results); + } + }; + } + + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; + + if (promise && typeof promise.then === 'function') { + promise.then(resolver(i), reject); + } else { + results[i] = promise; + } + } + + if (!remaining) { + resolve(results); + } + }); + }; + + P.race = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.race().'); + } + + return new P(function (resolve, reject) { + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; + + if (promise && typeof promise.then === 'function') { + promise.then(resolve, reject); + } else { + resolve(promise); + } + } + }); + }; + + P.resolve = function (value) { + if (value && _typeof(value) === 'object' && value.constructor === P) { + return value; + } + + return new P(function (resolve) { + resolve(value); + }); + }; + + P.reject = function (reason) { + return new P(function (resolve, reject) { + reject(reason); + }); + }; + + var picked = typeof Promise === 'function' ? Promise : P; + + var d = UNITS_IN_GRID; + var meaninglessTransform = { + size: 16, + x: 0, + y: 0, + rotate: 0, + flipX: false, + flipY: false + }; + + function isReserved(name) { + return ~RESERVED_CLASSES.indexOf(name); + } + + function bunker(fn) { + try { + fn(); + } catch (e) { + if (!PRODUCTION) { + throw e; + } + } + } + function insertCss(css) { + if (!css || !IS_DOM) { + return; + } + + var style = DOCUMENT.createElement('style'); + style.setAttribute('type', 'text/css'); + style.innerHTML = css; + var headChildren = DOCUMENT.head.childNodes; + var beforeChild = null; + + for (var i = headChildren.length - 1; i > -1; i--) { + var child = headChildren[i]; + var tagName = (child.tagName || '').toUpperCase(); + + if (['STYLE', 'LINK'].indexOf(tagName) > -1) { + beforeChild = child; + } + } + + DOCUMENT.head.insertBefore(style, beforeChild); + return css; + } + var idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + function nextUniqueId() { + var size = 12; + var id = ''; + + while (size-- > 0) { + id += idPool[Math.random() * 62 | 0]; + } + + return id; + } + function toArray(obj) { + var array = []; + + for (var i = (obj || []).length >>> 0; i--;) { + array[i] = obj[i]; + } + + return array; + } + function classArray(node) { + if (node.classList) { + return toArray(node.classList); + } else { + return (node.getAttribute('class') || '').split(' ').filter(function (i) { + return i; + }); + } + } + function getIconName(familyPrefix, cls) { + var parts = cls.split('-'); + var prefix = parts[0]; + var iconName = parts.slice(1).join('-'); + + if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) { + return iconName; + } else { + return null; + } + } + function htmlEscape(str) { + return "".concat(str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(//g, '>'); + } + function joinAttributes(attributes) { + return Object.keys(attributes || {}).reduce(function (acc, attributeName) { + return acc + "".concat(attributeName, "=\"").concat(htmlEscape(attributes[attributeName]), "\" "); + }, '').trim(); + } + function joinStyles(styles) { + return Object.keys(styles || {}).reduce(function (acc, styleName) { + return acc + "".concat(styleName, ": ").concat(styles[styleName], ";"); + }, ''); + } + function transformIsMeaningful(transform) { + return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY; + } + function transformForSvg(_ref) { + var transform = _ref.transform, + containerWidth = _ref.containerWidth, + iconWidth = _ref.iconWidth; + var outer = { + transform: "translate(".concat(containerWidth / 2, " 256)") + }; + var innerTranslate = "translate(".concat(transform.x * 32, ", ").concat(transform.y * 32, ") "); + var innerScale = "scale(".concat(transform.size / 16 * (transform.flipX ? -1 : 1), ", ").concat(transform.size / 16 * (transform.flipY ? -1 : 1), ") "); + var innerRotate = "rotate(".concat(transform.rotate, " 0 0)"); + var inner = { + transform: "".concat(innerTranslate, " ").concat(innerScale, " ").concat(innerRotate) + }; + var path = { + transform: "translate(".concat(iconWidth / 2 * -1, " -256)") + }; + return { + outer: outer, + inner: inner, + path: path + }; + } + function transformForCss(_ref2) { + var transform = _ref2.transform, + _ref2$width = _ref2.width, + width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width, + _ref2$height = _ref2.height, + height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height, + _ref2$startCentered = _ref2.startCentered, + startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered; + var val = ''; + + if (startCentered && IS_IE) { + val += "translate(".concat(transform.x / d - width / 2, "em, ").concat(transform.y / d - height / 2, "em) "); + } else if (startCentered) { + val += "translate(calc(-50% + ".concat(transform.x / d, "em), calc(-50% + ").concat(transform.y / d, "em)) "); + } else { + val += "translate(".concat(transform.x / d, "em, ").concat(transform.y / d, "em) "); + } + + val += "scale(".concat(transform.size / d * (transform.flipX ? -1 : 1), ", ").concat(transform.size / d * (transform.flipY ? -1 : 1), ") "); + val += "rotate(".concat(transform.rotate, "deg) "); + return val; + } + + var ALL_SPACE = { + x: 0, + y: 0, + width: '100%', + height: '100%' + }; + + function fillBlack(abstract) { + var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + if (abstract.attributes && (abstract.attributes.fill || force)) { + abstract.attributes.fill = 'black'; + } + + return abstract; + } + + function deGroup(abstract) { + if (abstract.tag === 'g') { + return abstract.children; + } else { + return [abstract]; + } + } + + function makeIconMasking (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + mask = _ref.mask, + transform = _ref.transform; + var mainWidth = main.width, + mainPath = main.icon; + var maskWidth = mask.width, + maskPath = mask.icon; + var trans = transformForSvg({ + transform: transform, + containerWidth: maskWidth, + iconWidth: mainWidth + }); + var maskRect = { + tag: 'rect', + attributes: _objectSpread({}, ALL_SPACE, { + fill: 'white' + }) + }; + var maskInnerGroupChildrenMixin = mainPath.children ? { + children: mainPath.children.map(fillBlack) + } : {}; + var maskInnerGroup = { + tag: 'g', + attributes: _objectSpread({}, trans.inner), + children: [fillBlack(_objectSpread({ + tag: mainPath.tag, + attributes: _objectSpread({}, mainPath.attributes, trans.path) + }, maskInnerGroupChildrenMixin))] + }; + var maskOuterGroup = { + tag: 'g', + attributes: _objectSpread({}, trans.outer), + children: [maskInnerGroup] + }; + var maskId = "mask-".concat(nextUniqueId()); + var clipId = "clip-".concat(nextUniqueId()); + var maskTag = { + tag: 'mask', + attributes: _objectSpread({}, ALL_SPACE, { + id: maskId, + maskUnits: 'userSpaceOnUse', + maskContentUnits: 'userSpaceOnUse' + }), + children: [maskRect, maskOuterGroup] + }; + var defs = { + tag: 'defs', + children: [{ + tag: 'clipPath', + attributes: { + id: clipId + }, + children: deGroup(maskPath) + }, maskTag] + }; + children.push(defs, { + tag: 'rect', + attributes: _objectSpread({ + fill: 'currentColor', + 'clip-path': "url(#".concat(clipId, ")"), + mask: "url(#".concat(maskId, ")") + }, ALL_SPACE) + }); + return { + children: children, + attributes: attributes + }; + } + + function makeIconStandard (_ref) { + var children = _ref.children, + attributes = _ref.attributes, + main = _ref.main, + transform = _ref.transform, + styles = _ref.styles; + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + if (transformIsMeaningful(transform)) { + var trans = transformForSvg({ + transform: transform, + containerWidth: main.width, + iconWidth: main.width + }); + children.push({ + tag: 'g', + attributes: _objectSpread({}, trans.outer), + children: [{ + tag: 'g', + attributes: _objectSpread({}, trans.inner), + children: [{ + tag: main.icon.tag, + children: main.icon.children, + attributes: _objectSpread({}, main.icon.attributes, trans.path) + }] + }] + }); + } else { + children.push(main.icon); + } + + return { + children: children, + attributes: attributes + }; + } + + function asIcon (_ref) { + var children = _ref.children, + main = _ref.main, + mask = _ref.mask, + attributes = _ref.attributes, + styles = _ref.styles, + transform = _ref.transform; + + if (transformIsMeaningful(transform) && main.found && !mask.found) { + var width = main.width, + height = main.height; + var offset = { + x: width / height / 2, + y: 0.5 + }; + attributes['style'] = joinStyles(_objectSpread({}, styles, { + 'transform-origin': "".concat(offset.x + transform.x / 16, "em ").concat(offset.y + transform.y / 16, "em") + })); + } + + return [{ + tag: 'svg', + attributes: attributes, + children: children + }]; + } + + function asSymbol (_ref) { + var prefix = _ref.prefix, + iconName = _ref.iconName, + children = _ref.children, + attributes = _ref.attributes, + symbol = _ref.symbol; + var id = symbol === true ? "".concat(prefix, "-").concat(config.familyPrefix, "-").concat(iconName) : symbol; + return [{ + tag: 'svg', + attributes: { + style: 'display: none;' + }, + children: [{ + tag: 'symbol', + attributes: _objectSpread({}, attributes, { + id: id + }), + children: children + }] + }]; + } + + function makeInlineSvgAbstract(params) { + var _params$icons = params.icons, + main = _params$icons.main, + mask = _params$icons.mask, + prefix = params.prefix, + iconName = params.iconName, + transform = params.transform, + symbol = params.symbol, + title = params.title, + extra = params.extra, + _params$watchable = params.watchable, + watchable = _params$watchable === void 0 ? false : _params$watchable; + + var _ref = mask.found ? mask : main, + width = _ref.width, + height = _ref.height; + + var widthClass = "fa-w-".concat(Math.ceil(width / height * 16)); + var attrClass = [config.replacementClass, iconName ? "".concat(config.familyPrefix, "-").concat(iconName) : '', widthClass].filter(function (c) { + return extra.classes.indexOf(c) === -1; + }).concat(extra.classes).join(' '); + var content = { + children: [], + attributes: _objectSpread({}, extra.attributes, { + 'data-prefix': prefix, + 'data-icon': iconName, + 'class': attrClass, + 'role': extra.attributes.role || 'img', + 'xmlns': 'http://www.w3.org/2000/svg', + 'viewBox': "0 0 ".concat(width, " ").concat(height) + }) + }; + + if (watchable) { + content.attributes[DATA_FA_I2SVG] = ''; + } + + if (title) content.children.push({ + tag: 'title', + attributes: { + id: content.attributes['aria-labelledby'] || "title-".concat(nextUniqueId()) + }, + children: [title] + }); + + var args = _objectSpread({}, content, { + prefix: prefix, + iconName: iconName, + main: main, + mask: mask, + transform: transform, + symbol: symbol, + styles: extra.styles + }); + + var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args), + children = _ref2.children, + attributes = _ref2.attributes; + + args.children = children; + args.attributes = attributes; + + if (symbol) { + return asSymbol(args); + } else { + return asIcon(args); + } + } + function makeLayersTextAbstract(params) { + var content = params.content, + width = params.width, + height = params.height, + transform = params.transform, + title = params.title, + extra = params.extra, + _params$watchable2 = params.watchable, + watchable = _params$watchable2 === void 0 ? false : _params$watchable2; + + var attributes = _objectSpread({}, extra.attributes, title ? { + 'title': title + } : {}, { + 'class': extra.classes.join(' ') + }); + + if (watchable) { + attributes[DATA_FA_I2SVG] = ''; + } + + var styles = _objectSpread({}, extra.styles); + + if (transformIsMeaningful(transform)) { + styles['transform'] = transformForCss({ + transform: transform, + startCentered: true, + width: width, + height: height + }); + styles['-webkit-transform'] = styles['transform']; + } + + var styleString = joinStyles(styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + var val = []; + val.push({ + tag: 'span', + attributes: attributes, + children: [content] + }); + + if (title) { + val.push({ + tag: 'span', + attributes: { + class: 'sr-only' + }, + children: [title] + }); + } + + return val; + } + function makeLayersCounterAbstract(params) { + var content = params.content, + title = params.title, + extra = params.extra; + + var attributes = _objectSpread({}, extra.attributes, title ? { + 'title': title + } : {}, { + 'class': extra.classes.join(' ') + }); + + var styleString = joinStyles(extra.styles); + + if (styleString.length > 0) { + attributes['style'] = styleString; + } + + var val = []; + val.push({ + tag: 'span', + attributes: attributes, + children: [content] + }); + + if (title) { + val.push({ + tag: 'span', + attributes: { + class: 'sr-only' + }, + children: [title] + }); + } + + return val; + } + + var noop$1 = function noop() {}; + + var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : { + mark: noop$1, + measure: noop$1 + }; + var preamble = "FA \"5.12.0\""; + + var begin = function begin(name) { + p.mark("".concat(preamble, " ").concat(name, " begins")); + return function () { + return end(name); + }; + }; + + var end = function end(name) { + p.mark("".concat(preamble, " ").concat(name, " ends")); + p.measure("".concat(preamble, " ").concat(name), "".concat(preamble, " ").concat(name, " begins"), "".concat(preamble, " ").concat(name, " ends")); + }; + + var perf = { + begin: begin, + end: end + }; + + /** + * Internal helper to bind a function known to have 4 arguments + * to a given context. + */ + + var bindInternal4 = function bindInternal4(func, thisContext) { + return function (a, b, c, d) { + return func.call(thisContext, a, b, c, d); + }; + }; + + /** + * # Reduce + * + * A fast object `.reduce()` implementation. + * + * @param {Object} subject The object to reduce over. + * @param {Function} fn The reducer function. + * @param {mixed} initialValue The initial value for the reducer, defaults to subject[0]. + * @param {Object} thisContext The context for the reducer. + * @return {mixed} The final result. + */ + + + var reduce = function fastReduceObject(subject, fn, initialValue, thisContext) { + var keys = Object.keys(subject), + length = keys.length, + iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn, + i, + key, + result; + + if (initialValue === undefined) { + i = 1; + result = subject[keys[0]]; + } else { + i = 0; + result = initialValue; + } + + for (; i < length; i++) { + key = keys[i]; + result = iterator(result, subject[key], key, subject); + } + + return result; + }; + + function toHex(unicode) { + var result = ''; + + for (var i = 0; i < unicode.length; i++) { + var hex = unicode.charCodeAt(i).toString(16); + result += ('000' + hex).slice(-4); + } + + return result; + } + + function defineIcons(prefix, icons) { + var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _params$skipHooks = params.skipHooks, + skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks; + var normalized = Object.keys(icons).reduce(function (acc, iconName) { + var icon = icons[iconName]; + var expanded = !!icon.icon; + + if (expanded) { + acc[icon.iconName] = icon.icon; + } else { + acc[iconName] = icon; + } + + return acc; + }, {}); + + if (typeof namespace.hooks.addPack === 'function' && !skipHooks) { + namespace.hooks.addPack(prefix, normalized); + } else { + namespace.styles[prefix] = _objectSpread({}, namespace.styles[prefix] || {}, normalized); + } + /** + * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction + * of new styles we needed to differentiate between them. Prefix `fa` is now an alias + * for `fas` so we'll easy the upgrade process for our users by automatically defining + * this as well. + */ + + + if (prefix === 'fas') { + defineIcons('fa', icons); + } + } + + var styles = namespace.styles, + shims = namespace.shims; + var _byUnicode = {}; + var _byLigature = {}; + var _byOldName = {}; + var build = function build() { + var lookup = function lookup(reducer) { + return reduce(styles, function (o, style, prefix) { + o[prefix] = reduce(style, reducer, {}); + return o; + }, {}); + }; + + _byUnicode = lookup(function (acc, icon, iconName) { + if (icon[3]) { + acc[icon[3]] = iconName; + } + + return acc; + }); + _byLigature = lookup(function (acc, icon, iconName) { + var ligatures = icon[2]; + acc[iconName] = iconName; + ligatures.forEach(function (ligature) { + acc[ligature] = iconName; + }); + return acc; + }); + var hasRegular = 'far' in styles; + _byOldName = reduce(shims, function (acc, shim) { + var oldName = shim[0]; + var prefix = shim[1]; + var iconName = shim[2]; + + if (prefix === 'far' && !hasRegular) { + prefix = 'fas'; + } + + acc[oldName] = { + prefix: prefix, + iconName: iconName + }; + return acc; + }, {}); + }; + build(); + function byUnicode(prefix, unicode) { + return (_byUnicode[prefix] || {})[unicode]; + } + function byLigature(prefix, ligature) { + return (_byLigature[prefix] || {})[ligature]; + } + function byOldName(name) { + return _byOldName[name] || { + prefix: null, + iconName: null + }; + } + + var styles$1 = namespace.styles; + var emptyCanonicalIcon = function emptyCanonicalIcon() { + return { + prefix: null, + iconName: null, + rest: [] + }; + }; + function getCanonicalIcon(values) { + return values.reduce(function (acc, cls) { + var iconName = getIconName(config.familyPrefix, cls); + + if (styles$1[cls]) { + acc.prefix = cls; + } else if (config.autoFetchSvg && ['fas', 'far', 'fal', 'fad', 'fab', 'fa'].indexOf(cls) > -1) { + acc.prefix = cls; + } else if (iconName) { + var shim = acc.prefix === 'fa' ? byOldName(iconName) : {}; + acc.iconName = shim.iconName || iconName; + acc.prefix = shim.prefix || acc.prefix; + } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) { + acc.rest.push(cls); + } + + return acc; + }, emptyCanonicalIcon()); + } + function iconFromMapping(mapping, prefix, iconName) { + if (mapping && mapping[prefix] && mapping[prefix][iconName]) { + return { + prefix: prefix, + iconName: iconName, + icon: mapping[prefix][iconName] + }; + } + } + + function toHtml(abstractNodes) { + var tag = abstractNodes.tag, + _abstractNodes$attrib = abstractNodes.attributes, + attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib, + _abstractNodes$childr = abstractNodes.children, + children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr; + + if (typeof abstractNodes === 'string') { + return htmlEscape(abstractNodes); + } else { + return "<".concat(tag, " ").concat(joinAttributes(attributes), ">").concat(children.map(toHtml).join(''), ""); + } + } + + var noop$2 = function noop() {}; + + function isWatched(node) { + var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null; + return typeof i2svg === 'string'; + } + + function getMutator() { + if (config.autoReplaceSvg === true) { + return mutators.replace; + } + + var mutator = mutators[config.autoReplaceSvg]; + return mutator || mutators.replace; + } + + var mutators = { + replace: function replace(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; + var newOuterHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + + if (node.parentNode && node.outerHTML) { + node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? "") : ''); + } else if (node.parentNode) { + var newNode = document.createElement('span'); + node.parentNode.replaceChild(newNode, node); + newNode.outerHTML = newOuterHTML; + } + }, + nest: function nest(mutation) { + var node = mutation[0]; + var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it. + // Short-circuit to the standard replacement + + if (~classArray(node).indexOf(config.replacementClass)) { + return mutators.replace(mutation); + } + + var forSvg = new RegExp("".concat(config.familyPrefix, "-.*")); + delete abstract[0].attributes.style; + delete abstract[0].attributes.id; + var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) { + if (cls === config.replacementClass || cls.match(forSvg)) { + acc.toSvg.push(cls); + } else { + acc.toNode.push(cls); + } + + return acc; + }, { + toNode: [], + toSvg: [] + }); + abstract[0].attributes.class = splitClasses.toSvg.join(' '); + var newInnerHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + node.setAttribute('class', splitClasses.toNode.join(' ')); + node.setAttribute(DATA_FA_I2SVG, ''); + node.innerHTML = newInnerHTML; + } + }; + + function performOperationSync(op) { + op(); + } + + function perform(mutations, callback) { + var callbackFunction = typeof callback === 'function' ? callback : noop$2; + + if (mutations.length === 0) { + callbackFunction(); + } else { + var frame = performOperationSync; + + if (config.mutateApproach === MUTATION_APPROACH_ASYNC) { + frame = WINDOW.requestAnimationFrame || performOperationSync; + } + + frame(function () { + var mutator = getMutator(); + var mark = perf.begin('mutate'); + mutations.map(mutator); + mark(); + callbackFunction(); + }); + } + } + var disabled = false; + function disableObservation() { + disabled = true; + } + function enableObservation() { + disabled = false; + } + var mo = null; + function observe(options) { + if (!MUTATION_OBSERVER) { + return; + } + + if (!config.observeMutations) { + return; + } + + var treeCallback = options.treeCallback, + nodeCallback = options.nodeCallback, + pseudoElementsCallback = options.pseudoElementsCallback, + _options$observeMutat = options.observeMutationsRoot, + observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat; + mo = new MUTATION_OBSERVER(function (objects) { + if (disabled) return; + toArray(objects).forEach(function (mutationRecord) { + if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) { + if (config.searchPseudoElements) { + pseudoElementsCallback(mutationRecord.target); + } + + treeCallback(mutationRecord.target); + } + + if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) { + pseudoElementsCallback(mutationRecord.target.parentNode); + } + + if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) { + if (mutationRecord.attributeName === 'class') { + var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)), + prefix = _getCanonicalIcon.prefix, + iconName = _getCanonicalIcon.iconName; + + if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix); + if (iconName) mutationRecord.target.setAttribute('data-icon', iconName); + } else { + nodeCallback(mutationRecord.target); + } + } + }); + }); + if (!IS_DOM) return; + mo.observe(observeMutationsRoot, { + childList: true, + attributes: true, + characterData: true, + subtree: true + }); + } + function disconnect() { + if (!mo) return; + mo.disconnect(); + } + + function styleParser (node) { + var style = node.getAttribute('style'); + var val = []; + + if (style) { + val = style.split(';').reduce(function (acc, style) { + var styles = style.split(':'); + var prop = styles[0]; + var value = styles.slice(1); + + if (prop && value.length > 0) { + acc[prop] = value.join(':').trim(); + } + + return acc; + }, {}); + } + + return val; + } + + function classParser (node) { + var existingPrefix = node.getAttribute('data-prefix'); + var existingIconName = node.getAttribute('data-icon'); + var innerText = node.innerText !== undefined ? node.innerText.trim() : ''; + var val = getCanonicalIcon(classArray(node)); + + if (existingPrefix && existingIconName) { + val.prefix = existingPrefix; + val.iconName = existingIconName; + } + + if (val.prefix && innerText.length > 1) { + val.iconName = byLigature(val.prefix, node.innerText); + } else if (val.prefix && innerText.length === 1) { + val.iconName = byUnicode(val.prefix, toHex(node.innerText)); + } + + return val; + } + + var parseTransformString = function parseTransformString(transformString) { + var transform = { + size: 16, + x: 0, + y: 0, + flipX: false, + flipY: false, + rotate: 0 + }; + + if (!transformString) { + return transform; + } else { + return transformString.toLowerCase().split(' ').reduce(function (acc, n) { + var parts = n.toLowerCase().split('-'); + var first = parts[0]; + var rest = parts.slice(1).join('-'); + + if (first && rest === 'h') { + acc.flipX = true; + return acc; + } + + if (first && rest === 'v') { + acc.flipY = true; + return acc; + } + + rest = parseFloat(rest); + + if (isNaN(rest)) { + return acc; + } + + switch (first) { + case 'grow': + acc.size = acc.size + rest; + break; + + case 'shrink': + acc.size = acc.size - rest; + break; + + case 'left': + acc.x = acc.x - rest; + break; + + case 'right': + acc.x = acc.x + rest; + break; + + case 'up': + acc.y = acc.y - rest; + break; + + case 'down': + acc.y = acc.y + rest; + break; + + case 'rotate': + acc.rotate = acc.rotate + rest; + break; + } + + return acc; + }, transform); + } + }; + function transformParser (node) { + return parseTransformString(node.getAttribute('data-fa-transform')); + } + + function symbolParser (node) { + var symbol = node.getAttribute('data-fa-symbol'); + return symbol === null ? false : symbol === '' ? true : symbol; + } + + function attributesParser (node) { + var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) { + if (acc.name !== 'class' && acc.name !== 'style') { + acc[attr.name] = attr.value; + } + + return acc; + }, {}); + var title = node.getAttribute('title'); + + if (config.autoA11y) { + if (title) { + extraAttributes['aria-labelledby'] = "".concat(config.replacementClass, "-title-").concat(nextUniqueId()); + } else { + extraAttributes['aria-hidden'] = 'true'; + extraAttributes['focusable'] = 'false'; + } + } + + return extraAttributes; + } + + function maskParser (node) { + var mask = node.getAttribute('data-fa-mask'); + + if (!mask) { + return emptyCanonicalIcon(); + } else { + return getCanonicalIcon(mask.split(' ').map(function (i) { + return i.trim(); + })); + } + } + + function blankMeta() { + return { + iconName: null, + title: null, + prefix: null, + transform: meaninglessTransform, + symbol: false, + mask: null, + extra: { + classes: [], + styles: {}, + attributes: {} + } + }; + } + function parseMeta(node) { + var _classParser = classParser(node), + iconName = _classParser.iconName, + prefix = _classParser.prefix, + extraClasses = _classParser.rest; + + var extraStyles = styleParser(node); + var transform = transformParser(node); + var symbol = symbolParser(node); + var extraAttributes = attributesParser(node); + var mask = maskParser(node); + return { + iconName: iconName, + title: node.getAttribute('title'), + prefix: prefix, + transform: transform, + symbol: symbol, + mask: mask, + extra: { + classes: extraClasses, + styles: extraStyles, + attributes: extraAttributes + } + }; + } + + function MissingIcon(error) { + this.name = 'MissingIcon'; + this.message = error || 'Icon unavailable'; + this.stack = new Error().stack; + } + MissingIcon.prototype = Object.create(Error.prototype); + MissingIcon.prototype.constructor = MissingIcon; + + var FILL = { + fill: 'currentColor' + }; + var ANIMATION_BASE = { + attributeType: 'XML', + repeatCount: 'indefinite', + dur: '2s' + }; + var RING = { + tag: 'path', + attributes: _objectSpread({}, FILL, { + d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z' + }) + }; + + var OPACITY_ANIMATE = _objectSpread({}, ANIMATION_BASE, { + attributeName: 'opacity' + }); + + var DOT = { + tag: 'circle', + attributes: _objectSpread({}, FILL, { + cx: '256', + cy: '364', + r: '28' + }), + children: [{ + tag: 'animate', + attributes: _objectSpread({}, ANIMATION_BASE, { + attributeName: 'r', + values: '28;14;28;28;14;28;' + }) + }, { + tag: 'animate', + attributes: _objectSpread({}, OPACITY_ANIMATE, { + values: '1;0;1;1;0;1;' + }) + }] + }; + var QUESTION = { + tag: 'path', + attributes: _objectSpread({}, FILL, { + opacity: '1', + d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z' + }), + children: [{ + tag: 'animate', + attributes: _objectSpread({}, OPACITY_ANIMATE, { + values: '1;0;0;0;0;1;' + }) + }] + }; + var EXCLAMATION = { + tag: 'path', + attributes: _objectSpread({}, FILL, { + opacity: '0', + d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z' + }), + children: [{ + tag: 'animate', + attributes: _objectSpread({}, OPACITY_ANIMATE, { + values: '0;0;1;1;0;0;' + }) + }] + }; + var missing = { + tag: 'g', + children: [RING, DOT, QUESTION, EXCLAMATION] + }; + + var styles$2 = namespace.styles; + function asFoundIcon(icon) { + var width = icon[0]; + var height = icon[1]; + + var _icon$slice = icon.slice(4), + _icon$slice2 = _slicedToArray(_icon$slice, 1), + vectorData = _icon$slice2[0]; + + var element = null; + + if (Array.isArray(vectorData)) { + element = { + tag: 'g', + attributes: { + class: "".concat(config.familyPrefix, "-").concat(DUOTONE_CLASSES.GROUP) + }, + children: [{ + tag: 'path', + attributes: { + class: "".concat(config.familyPrefix, "-").concat(DUOTONE_CLASSES.SECONDARY), + fill: 'currentColor', + d: vectorData[0] + } + }, { + tag: 'path', + attributes: { + class: "".concat(config.familyPrefix, "-").concat(DUOTONE_CLASSES.PRIMARY), + fill: 'currentColor', + d: vectorData[1] + } + }] + }; + } else { + element = { + tag: 'path', + attributes: { + fill: 'currentColor', + d: vectorData + } + }; + } + + return { + found: true, + width: width, + height: height, + icon: element + }; + } + function findIcon(iconName, prefix) { + return new picked(function (resolve, reject) { + var val = { + found: false, + width: 512, + height: 512, + icon: missing + }; + + if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) { + var icon = styles$2[prefix][iconName]; + return resolve(asFoundIcon(icon)); + } + + var headers = {}; + + if (_typeof(WINDOW.FontAwesomeKitConfig) === 'object' && typeof window.FontAwesomeKitConfig.token === 'string') { + headers['fa-kit-token'] = WINDOW.FontAwesomeKitConfig.token; + } + + if (iconName && prefix && !config.showMissingIcons) { + reject(new MissingIcon("Icon is missing for prefix ".concat(prefix, " with icon name ").concat(iconName))); + } else { + resolve(val); + } + }); + } + + var styles$3 = namespace.styles; + + function generateSvgReplacementMutation(node, nodeMeta) { + var iconName = nodeMeta.iconName, + title = nodeMeta.title, + prefix = nodeMeta.prefix, + transform = nodeMeta.transform, + symbol = nodeMeta.symbol, + mask = nodeMeta.mask, + extra = nodeMeta.extra; + return new picked(function (resolve, reject) { + picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + main = _ref2[0], + mask = _ref2[1]; + + resolve([node, makeInlineSvgAbstract({ + icons: { + main: main, + mask: mask + }, + prefix: prefix, + iconName: iconName, + transform: transform, + symbol: symbol, + mask: mask, + title: title, + extra: extra, + watchable: true + })]); + }); + }); + } + + function generateLayersText(node, nodeMeta) { + var title = nodeMeta.title, + transform = nodeMeta.transform, + extra = nodeMeta.extra; + var width = null; + var height = null; + + if (IS_IE) { + var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10); + var boundingClientRect = node.getBoundingClientRect(); + width = boundingClientRect.width / computedFontSize; + height = boundingClientRect.height / computedFontSize; + } + + if (config.autoA11y && !title) { + extra.attributes['aria-hidden'] = 'true'; + } + + return picked.resolve([node, makeLayersTextAbstract({ + content: node.innerHTML, + width: width, + height: height, + transform: transform, + title: title, + extra: extra, + watchable: true + })]); + } + + function generateMutation(node) { + var nodeMeta = parseMeta(node); + + if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) { + return generateLayersText(node, nodeMeta); + } else { + return generateSvgReplacementMutation(node, nodeMeta); + } + } + + function onTree(root) { + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + if (!IS_DOM) return; + var htmlClassList = DOCUMENT.documentElement.classList; + + var hclAdd = function hclAdd(suffix) { + return htmlClassList.add("".concat(HTML_CLASS_I2SVG_BASE_CLASS, "-").concat(suffix)); + }; + + var hclRemove = function hclRemove(suffix) { + return htmlClassList.remove("".concat(HTML_CLASS_I2SVG_BASE_CLASS, "-").concat(suffix)); + }; + + var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3); + var prefixesDomQuery = [".".concat(LAYERS_TEXT_CLASSNAME, ":not([").concat(DATA_FA_I2SVG, "])")].concat(prefixes.map(function (p) { + return ".".concat(p, ":not([").concat(DATA_FA_I2SVG, "])"); + })).join(', '); + + if (prefixesDomQuery.length === 0) { + return; + } + + var candidates = []; + + try { + candidates = toArray(root.querySelectorAll(prefixesDomQuery)); + } catch (e) {// noop + } + + if (candidates.length > 0) { + hclAdd('pending'); + hclRemove('complete'); + } else { + return; + } + + var mark = perf.begin('onTree'); + var mutations = candidates.reduce(function (acc, node) { + try { + var mutation = generateMutation(node); + + if (mutation) { + acc.push(mutation); + } + } catch (e) { + if (!PRODUCTION) { + if (e instanceof MissingIcon) { + console.error(e); + } + } + } + + return acc; + }, []); + return new picked(function (resolve, reject) { + picked.all(mutations).then(function (resolvedMutations) { + perform(resolvedMutations, function () { + hclAdd('active'); + hclAdd('complete'); + hclRemove('pending'); + if (typeof callback === 'function') callback(); + mark(); + resolve(); + }); + }).catch(function () { + mark(); + reject(); + }); + }); + } + function onNode(node) { + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + generateMutation(node).then(function (mutation) { + if (mutation) { + perform([mutation], callback); + } + }); + } + + function replaceForPosition(node, position) { + var pendingAttribute = "".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-')); + return new picked(function (resolve, reject) { + if (node.getAttribute(pendingAttribute) !== null) { + // This node is already being processed + return resolve(); + } + + var children = toArray(node.children); + var alreadyProcessedPseudoElement = children.filter(function (c) { + return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position; + })[0]; + var styles = WINDOW.getComputedStyle(node, position); + var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN); + var fontWeight = styles.getPropertyValue('font-weight'); + + if (alreadyProcessedPseudoElement && !fontFamily) { + // If we've already processed it but the current computed style does not result in a font-family, + // that probably means that a class name that was previously present to make the icon has been + // removed. So we now should delete the icon. + node.removeChild(alreadyProcessedPseudoElement); + return resolve(); + } else if (fontFamily) { + var content = styles.getPropertyValue('content'); + var prefix = ~['Solid', 'Regular', 'Light', 'Duotone', 'Brands'].indexOf(fontFamily[1]) ? STYLE_TO_PREFIX[fontFamily[1].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight]; + var hexValue = toHex(content.length === 3 ? content.substr(1, 1) : content); + var iconName = byUnicode(prefix, hexValue); + var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't + // already done so with the same prefix and iconName + + if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) { + node.setAttribute(pendingAttribute, iconIdentifier); + + if (alreadyProcessedPseudoElement) { + // Delete the old one, since we're replacing it with a new one + node.removeChild(alreadyProcessedPseudoElement); + } + + var meta = blankMeta(); + var extra = meta.extra; + extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position; + findIcon(iconName, prefix).then(function (main) { + var abstract = makeInlineSvgAbstract(_objectSpread({}, meta, { + icons: { + main: main, + mask: emptyCanonicalIcon() + }, + prefix: prefix, + iconName: iconIdentifier, + extra: extra, + watchable: true + })); + var element = DOCUMENT.createElement('svg'); + + if (position === ':before') { + node.insertBefore(element, node.firstChild); + } else { + node.appendChild(element); + } + + element.outerHTML = abstract.map(function (a) { + return toHtml(a); + }).join('\n'); + node.removeAttribute(pendingAttribute); + resolve(); + }).catch(reject); + } else { + resolve(); + } + } else { + resolve(); + } + }); + } + + function replace(node) { + return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]); + } + + function processable(node) { + return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg'); + } + + function searchPseudoElements (root) { + if (!IS_DOM) return; + return new picked(function (resolve, reject) { + var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace); + var end = perf.begin('searchPseudoElements'); + disableObservation(); + picked.all(operations).then(function () { + end(); + enableObservation(); + resolve(); + }).catch(function () { + end(); + enableObservation(); + reject(); + }); + }); + } + + var baseStyles = "svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fad.fa-inverse{color:#fff}"; + + function css () { + var dfp = DEFAULT_FAMILY_PREFIX; + var drc = DEFAULT_REPLACEMENT_CLASS; + var fp = config.familyPrefix; + var rc = config.replacementClass; + var s = baseStyles; + + if (fp !== dfp || rc !== drc) { + var dPatt = new RegExp("\\.".concat(dfp, "\\-"), 'g'); + var customPropPatt = new RegExp("\\--".concat(dfp, "\\-"), 'g'); + var rPatt = new RegExp("\\.".concat(drc), 'g'); + s = s.replace(dPatt, ".".concat(fp, "-")).replace(customPropPatt, "--".concat(fp, "-")).replace(rPatt, ".".concat(rc)); + } + + return s; + } + + var Library = + /*#__PURE__*/ + function () { + function Library() { + _classCallCheck(this, Library); + + this.definitions = {}; + } + + _createClass(Library, [{ + key: "add", + value: function add() { + var _this = this; + + for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) { + definitions[_key] = arguments[_key]; + } + + var additions = definitions.reduce(this._pullDefinitions, {}); + Object.keys(additions).forEach(function (key) { + _this.definitions[key] = _objectSpread({}, _this.definitions[key] || {}, additions[key]); + defineIcons(key, additions[key]); + build(); + }); + } + }, { + key: "reset", + value: function reset() { + this.definitions = {}; + } + }, { + key: "_pullDefinitions", + value: function _pullDefinitions(additions, definition) { + var normalized = definition.prefix && definition.iconName && definition.icon ? { + 0: definition + } : definition; + Object.keys(normalized).map(function (key) { + var _normalized$key = normalized[key], + prefix = _normalized$key.prefix, + iconName = _normalized$key.iconName, + icon = _normalized$key.icon; + if (!additions[prefix]) additions[prefix] = {}; + additions[prefix][iconName] = icon; + }); + return additions; + } + }]); + + return Library; + }(); + + function ensureCss() { + if (config.autoAddCss && !_cssInserted) { + insertCss(css()); + + _cssInserted = true; + } + } + + function apiObject(val, abstractCreator) { + Object.defineProperty(val, 'abstract', { + get: abstractCreator + }); + Object.defineProperty(val, 'html', { + get: function get() { + return val.abstract.map(function (a) { + return toHtml(a); + }); + } + }); + Object.defineProperty(val, 'node', { + get: function get() { + if (!IS_DOM) return; + var container = DOCUMENT.createElement('div'); + container.innerHTML = val.html; + return container.children; + } + }); + return val; + } + + function findIconDefinition(iconLookup) { + var _iconLookup$prefix = iconLookup.prefix, + prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix, + iconName = iconLookup.iconName; + if (!iconName) return; + return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName); + } + + function resolveIcons(next) { + return function (maybeIconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {}); + var mask = params.mask; + + if (mask) { + mask = (mask || {}).icon ? mask : findIconDefinition(mask || {}); + } + + return next(iconDefinition, _objectSpread({}, params, { + mask: mask + })); + }; + } + + var library = new Library(); + var noAuto = function noAuto() { + config.autoReplaceSvg = false; + config.observeMutations = false; + disconnect(); + }; + var _cssInserted = false; + var dom = { + i2svg: function i2svg() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (IS_DOM) { + ensureCss(); + var _params$node = params.node, + node = _params$node === void 0 ? DOCUMENT : _params$node, + _params$callback = params.callback, + callback = _params$callback === void 0 ? function () {} : _params$callback; + + if (config.searchPseudoElements) { + searchPseudoElements(node); + } + + return onTree(node, callback); + } else { + return picked.reject('Operation requires a DOM of some kind.'); + } + }, + css: css, + insertCss: function insertCss$$1() { + if (!_cssInserted) { + insertCss(css()); + + _cssInserted = true; + } + }, + watch: function watch() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var autoReplaceSvgRoot = params.autoReplaceSvgRoot, + observeMutationsRoot = params.observeMutationsRoot; + + if (config.autoReplaceSvg === false) { + config.autoReplaceSvg = true; + } + + config.observeMutations = true; + domready(function () { + autoReplace({ + autoReplaceSvgRoot: autoReplaceSvgRoot + }); + observe({ + treeCallback: onTree, + nodeCallback: onNode, + pseudoElementsCallback: searchPseudoElements, + observeMutationsRoot: observeMutationsRoot + }); + }); + } + }; + var parse = { + transform: function transform(transformString) { + return parseTransformString(transformString); + } + }; + var icon = resolveIcons(function (iconDefinition) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform = params.transform, + transform = _params$transform === void 0 ? meaninglessTransform : _params$transform, + _params$symbol = params.symbol, + symbol = _params$symbol === void 0 ? false : _params$symbol, + _params$mask = params.mask, + mask = _params$mask === void 0 ? null : _params$mask, + _params$title = params.title, + title = _params$title === void 0 ? null : _params$title, + _params$classes = params.classes, + classes = _params$classes === void 0 ? [] : _params$classes, + _params$attributes = params.attributes, + attributes = _params$attributes === void 0 ? {} : _params$attributes, + _params$styles = params.styles, + styles = _params$styles === void 0 ? {} : _params$styles; + if (!iconDefinition) return; + var prefix = iconDefinition.prefix, + iconName = iconDefinition.iconName, + icon = iconDefinition.icon; + return apiObject(_objectSpread({ + type: 'icon' + }, iconDefinition), function () { + ensureCss(); + + if (config.autoA11y) { + if (title) { + attributes['aria-labelledby'] = "".concat(config.replacementClass, "-title-").concat(nextUniqueId()); + } else { + attributes['aria-hidden'] = 'true'; + attributes['focusable'] = 'false'; + } + } + + return makeInlineSvgAbstract({ + icons: { + main: asFoundIcon(icon), + mask: mask ? asFoundIcon(mask.icon) : { + found: false, + width: null, + height: null, + icon: {} + } + }, + prefix: prefix, + iconName: iconName, + transform: _objectSpread({}, meaninglessTransform, transform), + symbol: symbol, + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: classes + } + }); + }); + }); + var text = function text(content) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$transform2 = params.transform, + transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2, + _params$title2 = params.title, + title = _params$title2 === void 0 ? null : _params$title2, + _params$classes2 = params.classes, + classes = _params$classes2 === void 0 ? [] : _params$classes2, + _params$attributes2 = params.attributes, + attributes = _params$attributes2 === void 0 ? {} : _params$attributes2, + _params$styles2 = params.styles, + styles = _params$styles2 === void 0 ? {} : _params$styles2; + return apiObject({ + type: 'text', + content: content + }, function () { + ensureCss(); + return makeLayersTextAbstract({ + content: content, + transform: _objectSpread({}, meaninglessTransform, transform), + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: ["".concat(config.familyPrefix, "-layers-text")].concat(_toConsumableArray(classes)) + } + }); + }); + }; + var counter = function counter(content) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$title3 = params.title, + title = _params$title3 === void 0 ? null : _params$title3, + _params$classes3 = params.classes, + classes = _params$classes3 === void 0 ? [] : _params$classes3, + _params$attributes3 = params.attributes, + attributes = _params$attributes3 === void 0 ? {} : _params$attributes3, + _params$styles3 = params.styles, + styles = _params$styles3 === void 0 ? {} : _params$styles3; + return apiObject({ + type: 'counter', + content: content + }, function () { + ensureCss(); + return makeLayersCounterAbstract({ + content: content.toString(), + title: title, + extra: { + attributes: attributes, + styles: styles, + classes: ["".concat(config.familyPrefix, "-layers-counter")].concat(_toConsumableArray(classes)) + } + }); + }); + }; + var layer = function layer(assembler) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _params$classes4 = params.classes, + classes = _params$classes4 === void 0 ? [] : _params$classes4; + return apiObject({ + type: 'layer' + }, function () { + ensureCss(); + var children = []; + assembler(function (args) { + Array.isArray(args) ? args.map(function (a) { + children = children.concat(a.abstract); + }) : children = children.concat(args.abstract); + }); + return [{ + tag: 'span', + attributes: { + class: ["".concat(config.familyPrefix, "-layers")].concat(_toConsumableArray(classes)).join(' ') + }, + children: children + }]; + }); + }; + var api = { + noAuto: noAuto, + config: config, + dom: dom, + library: library, + parse: parse, + findIconDefinition: findIconDefinition, + icon: icon, + text: text, + counter: counter, + layer: layer, + toHtml: toHtml + }; + + var autoReplace = function autoReplace() { + var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var _params$autoReplaceSv = params.autoReplaceSvgRoot, + autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv; + if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({ + node: autoReplaceSvgRoot + }); + }; + + function bootstrap() { + if (IS_BROWSER) { + if (!WINDOW.FontAwesome) { + WINDOW.FontAwesome = api; + } + + domready(function () { + autoReplace(); + observe({ + treeCallback: onTree, + nodeCallback: onNode, + pseudoElementsCallback: searchPseudoElements + }); + }); + } + + namespace.hooks = _objectSpread({}, namespace.hooks, { + addPack: function addPack(prefix, icons) { + namespace.styles[prefix] = _objectSpread({}, namespace.styles[prefix] || {}, icons); + build(); + autoReplace(); + }, + addShims: function addShims(shims) { + var _namespace$shims; + + (_namespace$shims = namespace.shims).push.apply(_namespace$shims, _toConsumableArray(shims)); + + build(); + autoReplace(); + } + }); + } + + bunker(bootstrap); + +}());