diff --git a/front/dist/css-polyfills.js b/front/dist/css-polyfills.js new file mode 100644 index 0000000..77b3ea6 --- /dev/null +++ b/front/dist/css-polyfills.js @@ -0,0 +1,13690 @@ +(function() { + if (this.__polyfills_originalGlobals == null) { + this.__polyfills_originalGlobals = { + define: this.define, + underscore: this._, + less: this.less, + eventemitter2: this.EventEmitter2, + SelectorSet: this.SelectorSet + }; + } + + this.define = void 0; + +}).call(this); + +// Underscore.js 1.5.2 +// http://underscorejs.org +// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + concat = ArrayProto.concat, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object via a string identifier, + // for Closure Compiler "advanced" mode. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.5.2'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects with the built-in `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, length = obj.length; i < length; i++) { + if (iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; + } + } + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = _.collect = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results.push(iterator.call(context, value, index, list)); + }); + return results; + }; + + var reduceError = 'Reduce of empty array with no initial value'; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var length = obj.length; + if (length !== +length) { + var keys = _.keys(obj); + length = keys.length; + } + each(obj, function(value, index, list) { + index = keys ? keys[--length] : --length; + if (!initial) { + memo = obj[index]; + initial = true; + } else { + memo = iterator.call(context, memo, obj[index], index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, iterator, context) { + return _.filter(obj, function(value, index, list) { + return !iterator.call(context, value, index, list); + }, context); + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result || (result = iterator.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if the array or object contains a given value (using `===`). + // Aliased as `include`. + _.contains = _.include = function(obj, target) { + if (obj == null) return false; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + return any(obj, function(value) { + return value === target; + }); + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + return (isFunc ? method : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs, first) { + if (_.isEmpty(attrs)) return first ? void 0 : []; + return _[first ? 'find' : 'filter'](obj, function(value) { + for (var key in attrs) { + if (attrs[key] !== value[key]) return false; + } + return true; + }); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.where(obj, attrs, true); + }; + + // Return the maximum element or (element-based computation). + // Can't optimize arrays of integers longer than 65,535 elements. + // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797) + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.max.apply(Math, obj); + } + if (!iterator && _.isEmpty(obj)) return -Infinity; + var result = {computed : -Infinity, value: -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed > result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.min.apply(Math, obj); + } + if (!iterator && _.isEmpty(obj)) return Infinity; + var result = {computed : Infinity, value: Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Shuffle an array, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var rand; + var index = 0; + var shuffled = []; + each(obj, function(value) { + rand = _.random(index++); + shuffled[index - 1] = shuffled[rand]; + shuffled[rand] = value; + }); + return shuffled; + }; + + // Sample **n** random values from an array. + // If **n** is not specified, returns a single random element from the array. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (arguments.length < 2 || guard) { + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // An internal function to generate lookup iterators. + var lookupIterator = function(value) { + return _.isFunction(value) ? value : function(obj){ return obj[value]; }; + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, value, context) { + var iterator = lookupIterator(value); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, value, context) { + var result = {}; + var iterator = value == null ? _.identity : lookupIterator(value); + each(obj, function(value, index) { + var key = iterator.call(context, value, index, obj); + behavior(result, key, value); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, key, value) { + (_.has(result, key) ? result[key] : (result[key] = [])).push(value); + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, key, value) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, key) { + _.has(result, key) ? result[key]++ : result[key] = 1; + }); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator, context) { + iterator = iterator == null ? _.identity : lookupIterator(iterator); + var value = iterator.call(context, obj); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >>> 1; + iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (obj.length === +obj.length) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + return (n == null) || guard ? array[0] : slice.call(array, 0, n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. The **guard** check allows it to work with + // `_.map`. + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. The **guard** check allows it to work with `_.map`. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if ((n == null) || guard) { + return array[array.length - 1]; + } else { + return slice.call(array, Math.max(array.length - n, 0)); + } + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, (n == null) || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, output) { + if (shallow && _.every(input, _.isArray)) { + return concat.apply(output, input); + } + each(input, function(value) { + if (_.isArray(value) || _.isArguments(value)) { + shallow ? push.apply(output, value) : flatten(value, shallow, output); + } else { + output.push(value); + } + }); + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iterator, context) { + if (_.isFunction(isSorted)) { + context = iterator; + iterator = isSorted; + isSorted = false; + } + var initial = iterator ? _.map(array, iterator, context) : array; + var results = []; + var seen = []; + each(initial, function(value, index) { + if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { + seen.push(value); + results.push(array[index]); + } + }); + return results; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.contains(rest, value); }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var length = _.max(_.pluck(arguments, "length").concat(0)); + var results = new Array(length); + for (var i = 0; i < length; i++) { + results[i] = _.pluck(arguments, '' + i); + } + return results; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + if (list == null) return {}; + var result = {}; + for (var i = 0, length = list.length; i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i = 0, length = array.length; + if (isSorted) { + if (typeof isSorted == 'number') { + i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted); + } else { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); + for (; i < length; i++) if (array[i] === item) return i; + return -1; + }; + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item, from) { + if (array == null) return -1; + var hasIndex = from != null; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { + return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); + } + var i = (hasIndex ? from : array.length); + while (i--) if (array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(length); + + while(idx < length) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Reusable constructor function for prototype setting. + var ctor = function(){}; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + var args, bound; + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError; + args = slice.call(arguments, 2); + return bound = function() { + if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); + ctor.prototype = func.prototype; + var self = new ctor; + ctor.prototype = null; + var result = func.apply(self, args.concat(slice.call(arguments))); + if (Object(result) === result) return result; + return self; + }; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. + _.partial = function(func) { + var args = slice.call(arguments, 1); + return function() { + return func.apply(this, args.concat(slice.call(arguments))); + }; + }; + + // Bind all of an object's methods to that object. Useful for ensuring that + // all callbacks defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length === 0) throw new Error("bindAll must be passed function names"); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(null, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + options || (options = {}); + var later = function() { + previous = options.leading === false ? 0 : new Date; + timeout = null; + result = func.apply(context, args); + }; + return function() { + var now = new Date; + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + return function() { + context = this; + args = arguments; + timestamp = new Date(); + var later = function() { + var last = (new Date()) - timestamp; + if (last < wait) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) result = func.apply(context, args); + } + }; + var callNow = immediate && !timeout; + if (!timeout) { + timeout = setTimeout(later, wait); + } + if (callNow) result = func.apply(context, args); + return result; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + memo = func.apply(this, arguments); + func = null; + return memo; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return function() { + var args = [func]; + push.apply(args, arguments); + return wrapper.apply(this, args); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = new Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = new Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + } + }); + return obj; + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + each(keys, function(key) { + if (key in obj) copy[key] = obj[key]; + }); + return copy; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + for (var key in obj) { + if (!_.contains(keys, key)) copy[key] = obj[key]; + } + return copy; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + if (obj[prop] === void 0) obj[prop] = source[prop]; + } + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a == 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) return bStack[length] == b; + } + // Objects with different constructors are not equivalent, but `Object`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && + _.isFunction(bCtor) && (bCtor instanceof bCtor))) { + return false; + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0, result = true; + // Recursively compare objects and arrays. + if (className == '[object Array]') { + // Compare array lengths to determine if a deep comparison is necessary. + size = a.length; + result = size == b.length; + if (result) { + // Deep compare the contents, ignoring non-numeric properties. + while (size--) { + if (!(result = eq(a[size], b[size], aStack, bStack))) break; + } + } + } else { + // Deep compare objects. + for (var key in a) { + if (_.has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return result; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b, [], []); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. + each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) == '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; + } + + // Optimize `isFunction` if appropriate. + if (typeof (/./) !== 'function') { + _.isFunction = function(obj) { + return typeof obj === 'function'; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj != +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + // Run a function **n** times. + _.times = function(n, iterator, context) { + var accum = Array(Math.max(0, n)); + for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // List of HTML entities for escaping. + var entityMap = { + escape: { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + } + }; + entityMap.unescape = _.invert(entityMap.escape); + + // Regexes containing the keys and values listed immediately above. + var entityRegexes = { + escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), + unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') + }; + + // Functions for escaping and unescaping strings to/from HTML interpolation. + _.each(['escape', 'unescape'], function(method) { + _[method] = function(string) { + if (string == null) return ''; + return ('' + string).replace(entityRegexes[method], function(match) { + return entityMap[method][match]; + }); + }; + }); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property) { + if (object == null) return void 0; + var value = object[property]; + return _.isFunction(value) ? value.call(object) : value; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result.call(this, func.apply(_, args)); + }; + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(text, data, settings) { + var render; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = new RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset) + .replace(escaper, function(match) { return '\\' + escapes[match]; }); + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } + if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } + if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + index = offset + match.length; + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + "return __p;\n"; + + try { + render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + if (data) return render(data, _); + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled function source as a convenience for precompilation. + template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function, which will delegate to the wrapper. + _.chain = function(obj) { + return _(obj).chain(); + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(obj) { + return this._chain ? _(obj).chain() : obj; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; + return result.call(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result.call(this, method.apply(this._wrapped, arguments)); + }; + }); + + _.extend(_.prototype, { + + // Start chaining a wrapped Underscore object. + chain: function() { + this._chain = true; + return this; + }, + + // Extracts the result from a wrapped and chained object. + value: function() { + return this._wrapped; + } + + }); + +}).call(this); + +/*! + * Sizzle CSS Selector Engine v1.10.19 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-04-18 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = "
"; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowclip^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +// EXPOSE +if ( typeof define === "function" && define.amd ) { + define(function() { return Sizzle; }); +// Sizzle requires that there be a global window in Common-JS like environments +} else if ( typeof module !== "undefined" && module.exports ) { + module.exports = Sizzle; +} else { + window.Sizzle = Sizzle; +} +// EXPOSE + +})( window ); + +/*! + * LESS - Leaner CSS v1.6.0 + * http://lesscss.org + * + * Copyright (c) 2009-2014, Alexis Sellier + * Licensed under the Apache v2 License. + * + */ + + /** * @license Apache v2 + */ + + + +(function (window, undefined) {// +// Stub out `require` in the browser +// +function require(arg) { + return window.less[arg.split('/')[1]]; +}; + + +if (typeof(window.less) === 'undefined' || typeof(window.less.nodeType) !== 'undefined') { window.less = {}; } +less = window.less; +tree = window.less.tree = {}; +less.mode = 'browser'; + +var less, tree; + +// Node.js does not have a header file added which defines less +if (less === undefined) { + less = exports; + tree = require('./tree'); + less.mode = 'node'; +} +// +// less.js - parser +// +// A relatively straight-forward predictive parser. +// There is no tokenization/lexing stage, the input is parsed +// in one sweep. +// +// To make the parser fast enough to run in the browser, several +// optimization had to be made: +// +// - Matching and slicing on a huge input is often cause of slowdowns. +// The solution is to chunkify the input into smaller strings. +// The chunks are stored in the `chunks` var, +// `j` holds the current chunk index, and `currentPos` holds +// the index of the current chunk in relation to `input`. +// This gives us an almost 4x speed-up. +// +// - In many cases, we don't need to match individual tokens; +// for example, if a value doesn't hold any variables, operations +// or dynamic references, the parser can effectively 'skip' it, +// treating it as a literal. +// An example would be '1px solid #000' - which evaluates to itself, +// we don't need to know what the individual components are. +// The drawback, of course is that you don't get the benefits of +// syntax-checking on the CSS. This gives us a 50% speed-up in the parser, +// and a smaller speed-up in the code-gen. +// +// +// Token matching is done with the `$` function, which either takes +// a terminal string or regexp, or a non-terminal function to call. +// It also takes care of moving all the indices forwards. +// +// +less.Parser = function Parser(env) { + var input, // LeSS input string + i, // current index in `input` + j, // current chunk + temp, // temporarily holds a chunk's state, for backtracking + memo, // temporarily holds `i`, when backtracking + furthest, // furthest index the parser has gone to + chunks, // chunkified input + current, // current chunk + currentPos, // index of current chunk, in `input` + parser, + parsers, + rootFilename = env && env.filename; + + // Top parser on an import tree must be sure there is one "env" + // which will then be passed around by reference. + if (!(env instanceof tree.parseEnv)) { + env = new tree.parseEnv(env); + } + + var imports = this.imports = { + paths: env.paths || [], // Search paths, when importing + queue: [], // Files which haven't been imported yet + files: env.files, // Holds the imported parse trees + contents: env.contents, // Holds the imported file contents + contentsIgnoredChars: env.contentsIgnoredChars, // lines inserted, not in the original less + mime: env.mime, // MIME type of .less files + error: null, // Error in parsing/evaluating an import + push: function (path, currentFileInfo, importOptions, callback) { + var parserImports = this; + this.queue.push(path); + + var fileParsedFunc = function (e, root, fullPath) { + parserImports.queue.splice(parserImports.queue.indexOf(path), 1); // Remove the path from the queue + + var importedPreviously = fullPath in parserImports.files || fullPath === rootFilename; + + parserImports.files[fullPath] = root; // Store the root + + if (e && !parserImports.error) { parserImports.error = e; } + + callback(e, root, importedPreviously, fullPath); + }; + + if (less.Parser.importer) { + less.Parser.importer(path, currentFileInfo, fileParsedFunc, env); + } else { + less.Parser.fileLoader(path, currentFileInfo, function(e, contents, fullPath, newFileInfo) { + if (e) {fileParsedFunc(e); return;} + + var newEnv = new tree.parseEnv(env); + + newEnv.currentFileInfo = newFileInfo; + newEnv.processImports = false; + newEnv.contents[fullPath] = contents; + + if (currentFileInfo.reference || importOptions.reference) { + newFileInfo.reference = true; + } + + if (importOptions.inline) { + fileParsedFunc(null, contents, fullPath); + } else { + new(less.Parser)(newEnv).parse(contents, function (e, root) { + fileParsedFunc(e, root, fullPath); + }); + } + }, env); + } + } + }; + + function save() { temp = current; memo = currentPos = i; } + function restore() { current = temp; currentPos = i = memo; } + + function sync() { + if (i > currentPos) { + current = current.slice(i - currentPos); + currentPos = i; + } + } + function isWhitespace(str, pos) { + var code = str.charCodeAt(pos | 0); + return (code <= 32) && (code === 32 || code === 10 || code === 9); + } + // + // Parse from a token, regexp or string, and move forward if match + // + function $(tok) { + var tokType = typeof tok, + match, length; + + // Either match a single character in the input, + // or match a regexp in the current chunk (`current`). + // + if (tokType === "string") { + if (input.charAt(i) !== tok) { + return null; + } + skipWhitespace(1); + return tok; + } + + // regexp + sync (); + if (! (match = tok.exec(current))) { + return null; + } + + length = match[0].length; + + // The match is confirmed, add the match length to `i`, + // and consume any extra white-space characters (' ' || '\n') + // which come after that. The reason for this is that LeSS's + // grammar is mostly white-space insensitive. + // + skipWhitespace(length); + + if(typeof(match) === 'string') { + return match; + } else { + return match.length === 1 ? match[0] : match; + } + } + + // Specialization of $(tok) + function $re(tok) { + if (i > currentPos) { + current = current.slice(i - currentPos); + currentPos = i; + } + var m = tok.exec(current); + if (!m) { + return null; + } + + skipWhitespace(m[0].length); + if(typeof m === "string") { + return m; + } + + return m.length === 1 ? m[0] : m; + } + + var _$re = $re; + + // Specialization of $(tok) + function $char(tok) { + if (input.charAt(i) !== tok) { + return null; + } + skipWhitespace(1); + return tok; + } + + function skipWhitespace(length) { + var oldi = i, oldj = j, + curr = i - currentPos, + endIndex = i + current.length - curr, + mem = (i += length), + inp = input, + c; + + for (; i < endIndex; i++) { + c = inp.charCodeAt(i); + if (c > 32) { + break; + } + + if ((c !== 32) && (c !== 10) && (c !== 9) && (c !== 13)) { + break; + } + } + + current = current.slice(length + i - mem + curr); + currentPos = i; + + if (!current.length && (j < chunks.length - 1)) { + current = chunks[++j]; + } + + return oldi !== i || oldj !== j; + } + + function expect(arg, msg) { + var result = (typeof arg === "function") ? arg.call(parsers) : $(arg); + if (result) { + return result; + } + error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'" + : "unexpected token")); + } + + // Specialization of expect() + function expectChar(arg, msg) { + if (input.charAt(i) === arg) { + skipWhitespace(1); + return arg; + } + error(msg || "expected '" + arg + "' got '" + input.charAt(i) + "'"); + } + + function error(msg, type) { + var e = new Error(msg); + e.index = i; + e.type = type || 'Syntax'; + throw e; + } + + // Same as $(), but don't change the state of the parser, + // just return the match. + function peek(tok) { + if (typeof(tok) === 'string') { + return input.charAt(i) === tok; + } else { + return tok.test(current); + } + } + + // Specialization of peek() + function peekChar(tok) { + return input.charAt(i) === tok; + } + + + function getInput(e, env) { + if (e.filename && env.currentFileInfo.filename && (e.filename !== env.currentFileInfo.filename)) { + return parser.imports.contents[e.filename]; + } else { + return input; + } + } + + function getLocation(index, inputStream) { + var n = index + 1, + line = null, + column = -1; + + while (--n >= 0 && inputStream.charAt(n) !== '\n') { + column++; + } + + if (typeof index === 'number') { + line = (inputStream.slice(0, index).match(/\n/g) || "").length; + } + + return { + line: line, + column: column + }; + } + + function getDebugInfo(index, inputStream, env) { + var filename = env.currentFileInfo.filename; + if(less.mode !== 'browser' && less.mode !== 'rhino') { + filename = require('path').resolve(filename); + } + + return { + lineNumber: getLocation(index, inputStream).line + 1, + fileName: filename + }; + } + + function LessError(e, env) { + var input = getInput(e, env), + loc = getLocation(e.index, input), + line = loc.line, + col = loc.column, + callLine = e.call && getLocation(e.call, input).line, + lines = input.split('\n'); + + this.type = e.type || 'Syntax'; + this.message = e.message; + this.filename = e.filename || env.currentFileInfo.filename; + this.index = e.index; + this.line = typeof(line) === 'number' ? line + 1 : null; + this.callLine = callLine + 1; + this.callExtract = lines[callLine]; + this.stack = e.stack; + this.column = col; + this.extract = [ + lines[line - 1], + lines[line], + lines[line + 1] + ]; + } + + LessError.prototype = new Error(); + LessError.prototype.constructor = LessError; + + this.env = env = env || {}; + + // The optimization level dictates the thoroughness of the parser, + // the lower the number, the less nodes it will create in the tree. + // This could matter for debugging, or if you want to access + // the individual nodes in the tree. + this.optimization = ('optimization' in this.env) ? this.env.optimization : 1; + + // + // The Parser + // + parser = { + + imports: imports, + // + // Parse an input string into an abstract syntax tree, + // @param str A string containing 'less' markup + // @param callback call `callback` when done. + // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply + // + parse: function (str, callback, additionalData) { + var root, line, lines, error = null, globalVars, modifyVars, preText = ""; + + i = j = currentPos = furthest = 0; + + globalVars = (additionalData && additionalData.globalVars) ? less.Parser.serializeVars(additionalData.globalVars) + '\n' : ''; + modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + less.Parser.serializeVars(additionalData.modifyVars) : ''; + + if (globalVars || (additionalData && additionalData.banner)) { + preText = ((additionalData && additionalData.banner) ? additionalData.banner : "") + globalVars; + parser.imports.contentsIgnoredChars[env.currentFileInfo.filename] = preText.length; + } + + str = str.replace(/\r\n/g, '\n'); + // Remove potential UTF Byte Order Mark + input = str = preText + str.replace(/^\uFEFF/, '') + modifyVars; + parser.imports.contents[env.currentFileInfo.filename] = str; + + // Split the input into chunks. + chunks = (function (input) { + var len = input.length, level = 0, parenLevel = 0, + lastOpening, lastClosing, lastMultiComment, lastMultiCommentEndBrace, + chunks = [], emitFrom = 0, + parserCurrentIndex, currentChunkStartIndex, cc, cc2, matched; + + function fail(msg, index) { + error = new(LessError)({ + index: index || parserCurrentIndex, + type: 'Parse', + message: msg, + filename: env.currentFileInfo.filename + }, env); + } + + function emitChunk(force) { + var len = parserCurrentIndex - emitFrom; + if (((len < 512) && !force) || !len) { + return; + } + chunks.push(input.slice(emitFrom, parserCurrentIndex + 1)); + emitFrom = parserCurrentIndex + 1; + } + + for (parserCurrentIndex = 0; parserCurrentIndex < len; parserCurrentIndex++) { + cc = input.charCodeAt(parserCurrentIndex); + if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { + // a-z or whitespace + continue; + } + + switch (cc) { + case 40: // ( + parenLevel++; continue; + case 41: // ) + parenLevel--; continue; + case 59: // ; + if (!parenLevel) { emitChunk(); } + continue; + case 123: // { + level++; lastOpening = parserCurrentIndex; continue; + case 125: // } + level--; lastClosing = parserCurrentIndex; + if (!level) { emitChunk(); } + continue; + case 92: // \ + if (parserCurrentIndex < len - 1) { parserCurrentIndex++; continue; } + return fail("unescaped `\\`"); + case 34: + case 39: + case 96: // ", ' and ` + matched = 0; + currentChunkStartIndex = parserCurrentIndex; + for (parserCurrentIndex = parserCurrentIndex + 1; parserCurrentIndex < len; parserCurrentIndex++) { + cc2 = input.charCodeAt(parserCurrentIndex); + if (cc2 > 96) { continue; } + if (cc2 == cc) { matched = 1; break; } + if (cc2 == 92) { // \ + if (parserCurrentIndex == len - 1) { + return fail("unescaped `\\`"); + } + parserCurrentIndex++; + } + } + if (matched) { continue; } + return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); + case 47: // /, check for comment + if (parenLevel || (parserCurrentIndex == len - 1)) { continue; } + cc2 = input.charCodeAt(parserCurrentIndex + 1); + if (cc2 == 47) { + // //, find lnfeed + for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len; parserCurrentIndex++) { + cc2 = input.charCodeAt(parserCurrentIndex); + if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; } + } + } else if (cc2 == 42) { + // /*, find */ + lastMultiComment = currentChunkStartIndex = parserCurrentIndex; + for (parserCurrentIndex = parserCurrentIndex + 2; parserCurrentIndex < len - 1; parserCurrentIndex++) { + cc2 = input.charCodeAt(parserCurrentIndex); + if (cc2 == 125) { lastMultiCommentEndBrace = parserCurrentIndex; } + if (cc2 != 42) { continue; } + if (input.charCodeAt(parserCurrentIndex + 1) == 47) { break; } + } + if (parserCurrentIndex == len - 1) { + return fail("missing closing `*/`", currentChunkStartIndex); + } + } + continue; + case 42: // *, check for unmatched */ + if ((parserCurrentIndex < len - 1) && (input.charCodeAt(parserCurrentIndex + 1) == 47)) { + return fail("unmatched `/*`"); + } + continue; + } + } + + if (level !== 0) { + if (level > 0) { + if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { + return fail("missing closing `}` or `*/`", lastOpening); + } else { + return fail("missing closing `}`", lastOpening); + } + } + return fail("missing opening `{`", lastClosing); + } else if (parenLevel !== 0) { + return fail((parenLevel > 0) ? "missing closing `)`" : "missing opening `(`"); + } + + emitChunk(true); + return chunks; + })(str); + + if (error) { + return callback(new(LessError)(error, env)); + } + + current = chunks[0]; + + // Start with the primary rule. + // The whole syntax tree is held under a Ruleset node, + // with the `root` property set to true, so no `{}` are + // output. The callback is called when the input is parsed. + try { + root = new(tree.Ruleset)(null, this.parsers.primary()); + root.root = true; + root.firstRoot = true; + } catch (e) { + return callback(new(LessError)(e, env)); + } + + root.toCSS = (function (evaluate) { + return function (options, variables) { + options = options || {}; + var evaldRoot, + css, + evalEnv = new tree.evalEnv(options); + + // + // Allows setting variables with a hash, so: + // + // `{ color: new(tree.Color)('#f01') }` will become: + // + // new(tree.Rule)('@color', + // new(tree.Value)([ + // new(tree.Expression)([ + // new(tree.Color)('#f01') + // ]) + // ]) + // ) + // + if (typeof(variables) === 'object' && !Array.isArray(variables)) { + variables = Object.keys(variables).map(function (k) { + var value = variables[k]; + + if (! (value instanceof tree.Value)) { + if (! (value instanceof tree.Expression)) { + value = new(tree.Expression)([value]); + } + value = new(tree.Value)([value]); + } + return new(tree.Rule)('@' + k, value, false, null, 0); + }); + evalEnv.frames = [new(tree.Ruleset)(null, variables)]; + } + + try { + var preEvalVisitors = [], + visitors = [ + new(tree.joinSelectorVisitor)(), + new(tree.processExtendsVisitor)(), + new(tree.toCSSVisitor)({compress: Boolean(options.compress)}) + ], i, root = this; + + if (options.plugins) { + for(i =0; i < options.plugins.length; i++) { + if (options.plugins[i].isPreEvalVisitor) { + preEvalVisitors.push(options.plugins[i]); + } else { + if (options.plugins[i].isPreVisitor) { + visitors.splice(0, 0, options.plugins[i]); + } else { + visitors.push(options.plugins[i]); + } + } + } + } + + for(i = 0; i < preEvalVisitors.length; i++) { + preEvalVisitors[i].run(root); + } + + evaldRoot = evaluate.call(root, evalEnv); + + for(i = 0; i < visitors.length; i++) { + visitors[i].run(evaldRoot); + } + + if (options.sourceMap) { + evaldRoot = new tree.sourceMapOutput( + { + contentsIgnoredCharsMap: parser.imports.contentsIgnoredChars, + writeSourceMap: options.writeSourceMap, + rootNode: evaldRoot, + contentsMap: parser.imports.contents, + sourceMapFilename: options.sourceMapFilename, + sourceMapURL: options.sourceMapURL, + outputFilename: options.sourceMapOutputFilename, + sourceMapBasepath: options.sourceMapBasepath, + sourceMapRootpath: options.sourceMapRootpath, + outputSourceFiles: options.outputSourceFiles, + sourceMapGenerator: options.sourceMapGenerator + }); + } + + css = evaldRoot.toCSS({ + compress: Boolean(options.compress), + dumpLineNumbers: env.dumpLineNumbers, + strictUnits: Boolean(options.strictUnits)}); + } catch (e) { + throw new(LessError)(e, env); + } + + if (options.cleancss && less.mode === 'node') { + var CleanCSS = require('clean-css'), + cleancssOptions = options.cleancssOptions || {}; + + if (cleancssOptions.keepSpecialComments === undefined) { + cleancssOptions.keepSpecialComments = "*"; + } + cleancssOptions.processImport = false; + cleancssOptions.noRebase = true; + if (cleancssOptions.noAdvanced === undefined) { + cleancssOptions.noAdvanced = true; + } + + return new CleanCSS(cleancssOptions).minify(css); + } else if (options.compress) { + return css.replace(/(^(\s)+)|((\s)+$)/g, ""); + } else { + return css; + } + }; + })(root.eval); + + // If `i` is smaller than the `input.length - 1`, + // it means the parser wasn't able to parse the whole + // string, so we've got a parsing error. + // + // We try to extract a \n delimited string, + // showing the line where the parse error occured. + // We split it up into two parts (the part which parsed, + // and the part which didn't), so we can color them differently. + if (i < input.length - 1) { + i = furthest; + var loc = getLocation(i, input); + lines = input.split('\n'); + line = loc.line + 1; + + error = { + type: "Parse", + message: "Unrecognised input", + index: i, + filename: env.currentFileInfo.filename, + line: line, + column: loc.column, + extract: [ + lines[line - 2], + lines[line - 1], + lines[line] + ] + }; + } + + var finish = function (e) { + e = error || e || parser.imports.error; + + if (e) { + if (!(e instanceof LessError)) { + e = new(LessError)(e, env); + } + + return callback(e); + } + else { + return callback(null, root); + } + }; + + if (env.processImports !== false) { + new tree.importVisitor(this.imports, finish) + .run(root); + } else { + return finish(); + } + }, + + // + // Here in, the parsing rules/functions + // + // The basic structure of the syntax tree generated is as follows: + // + // Ruleset -> Rule -> Value -> Expression -> Entity + // + // Here's some LESS code: + // + // .class { + // color: #fff; + // border: 1px solid #000; + // width: @w + 4px; + // > .child {...} + // } + // + // And here's what the parse tree might look like: + // + // Ruleset (Selector '.class', [ + // Rule ("color", Value ([Expression [Color #fff]])) + // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) + // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) + // Ruleset (Selector [Element '>', '.child'], [...]) + // ]) + // + // In general, most rules will try to parse a token with the `$()` function, and if the return + // value is truly, will return a new node, of the relevant type. Sometimes, we need to check + // first, before parsing, that's when we use `peek()`. + // + parsers: parsers = { + // + // The `primary` rule is the *entry* and *exit* point of the parser. + // The rules here can appear at any level of the parse tree. + // + // The recursive nature of the grammar is an interplay between the `block` + // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, + // as represented by this simplified grammar: + // + // primary → (ruleset | rule)+ + // ruleset → selector+ block + // block → '{' primary '}' + // + // Only at one point is the primary rule not called from the + // block rule: at the root level. + // + primary: function () { + var mixin = this.mixin, $re = _$re, root = [], node; + + while (true) + { + node = this.extendRule() || mixin.definition() || this.rule() || this.ruleset() || + mixin.call() || this.comment() || this.directive(); + if (node) { + root.push(node); + } else { + if (!($re(/^[\s\n]+/) || $re(/^;+/))) { + break; + } + } + } + + return root; + }, + + // We create a Comment node for CSS comments `/* */`, + // but keep the LeSS comments `//` silent, by just skipping + // over them. + comment: function () { + var comment; + + if (input.charAt(i) !== '/') { return; } + + if (input.charAt(i + 1) === '/') { + return new(tree.Comment)($re(/^\/\/.*/), true, i, env.currentFileInfo); + } + comment = $re(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/); + if (comment) { + return new(tree.Comment)(comment, false, i, env.currentFileInfo); + } + }, + + comments: function () { + var comment, comments = []; + + while(true) { + comment = this.comment(); + if (!comment) { + break; + } + comments.push(comment); + } + + return comments; + }, + + // + // Entities are tokens which can be found inside an Expression + // + entities: { + // + // A string, which supports escaping " and ' + // + // "milky way" 'he\'s the one!' + // + quoted: function () { + var str, j = i, e, index = i; + + if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings + if (input.charAt(j) !== '"' && input.charAt(j) !== "'") { return; } + + if (e) { $char('~'); } + + str = $re(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/); + if (str) { + return new(tree.Quoted)(str[0], str[1] || str[2], e, index, env.currentFileInfo); + } + }, + + // + // A catch-all word, such as: + // + // black border-collapse + // + keyword: function () { + var k; + + k = $re(/^[_A-Za-z-][_A-Za-z0-9-]*/); + if (k) { + var color = tree.Color.fromKeyword(k); + if (color) { + return color; + } + return new(tree.Keyword)(k); + } + }, + + // + // A function call + // + // rgb(255, 0, 255) + // + // We also try to catch IE's `alpha()`, but let the `alpha` parser + // deal with the details. + // + // The arguments are parsed with the `entities.arguments` parser. + // + call: function () { + var name, nameLC, args, alpha_ret, index = i; + + name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(current); + if (!name) { return; } + + name = name[1]; + nameLC = name.toLowerCase(); + if (nameLC === 'url') { + return null; + } + + i += name.length; + + if (nameLC === 'alpha') { + alpha_ret = parsers.alpha(); + if(typeof alpha_ret !== 'undefined') { + return alpha_ret; + } + } + + $char('('); // Parse the '(' and consume whitespace. + + args = this.arguments(); + + if (! $char(')')) { + return; + } + + if (name) { return new(tree.Call)(name, args, index, env.currentFileInfo); } + }, + arguments: function () { + var args = [], arg; + + while (true) { + arg = this.assignment() || parsers.expression(); + if (!arg) { + break; + } + args.push(arg); + if (! $char(',')) { + break; + } + } + return args; + }, + literal: function () { + return this.dimension() || + this.color() || + this.quoted() || + this.unicodeDescriptor(); + }, + + // Assignments are argument entities for calls. + // They are present in ie filter properties as shown below. + // + // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) + // + + assignment: function () { + var key, value; + key = $re(/^\w+(?=\s?=)/i); + if (!key) { + return; + } + if (!$char('=')) { + return; + } + value = parsers.entity(); + if (value) { + return new(tree.Assignment)(key, value); + } + }, + + // + // Parse url() tokens + // + // We use a specific rule for urls, because they don't really behave like + // standard function calls. The difference is that the argument doesn't have + // to be enclosed within a string, so it can't be parsed as an Expression. + // + url: function () { + var value; + + if (input.charAt(i) !== 'u' || !$re(/^url\(/)) { + return; + } + + value = this.quoted() || this.variable() || + $re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ""; + + expectChar(')'); + + return new(tree.URL)((value.value != null || value instanceof tree.Variable) + ? value : new(tree.Anonymous)(value), env.currentFileInfo); + }, + + // + // A Variable entity, such as `@fink`, in + // + // width: @fink + 2px + // + // We use a different parser for variable definitions, + // see `parsers.variable`. + // + variable: function () { + var name, index = i; + + if (input.charAt(i) === '@' && (name = $re(/^@@?[\w-]+/))) { + return new(tree.Variable)(name, index, env.currentFileInfo); + } + }, + + // A variable entity useing the protective {} e.g. @{var} + variableCurly: function () { + var curly, index = i; + + if (input.charAt(i) === '@' && (curly = $re(/^@\{([\w-]+)\}/))) { + return new(tree.Variable)("@" + curly[1], index, env.currentFileInfo); + } + }, + + // + // A Hexadecimal color + // + // #4F3C2F + // + // `rgb` and `hsl` colors are parsed through the `entities.call` parser. + // + color: function () { + var rgb; + + if (input.charAt(i) === '#' && (rgb = $re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) { + return new(tree.Color)(rgb[1]); + } + }, + + // + // A Dimension, that is, a number and a unit + // + // 0.5em 95% + // + dimension: function () { + var value, c = input.charCodeAt(i); + //Is the first char of the dimension 0-9, '.', '+' or '-' + if ((c > 57 || c < 43) || c === 47 || c == 44) { + return; + } + + value = $re(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/); + if (value) { + return new(tree.Dimension)(value[1], value[2]); + } + }, + + // + // A unicode descriptor, as is used in unicode-range + // + // U+0?? or U+00A1-00A9 + // + unicodeDescriptor: function () { + var ud; + + ud = $re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); + if (ud) { + return new(tree.UnicodeDescriptor)(ud[0]); + } + }, + + // + // JavaScript code to be evaluated + // + // `window.location.href` + // + javascript: function () { + var str, j = i, e; + + if (input.charAt(j) === '~') { j++; e = true; } // Escaped strings + if (input.charAt(j) !== '`') { return; } + if (env.javascriptEnabled !== undefined && !env.javascriptEnabled) { + error("You are using JavaScript, which has been disabled."); + } + + if (e) { $char('~'); } + + str = $re(/^`([^`]*)`/); + if (str) { + return new(tree.JavaScript)(str[1], i, e); + } + } + }, + + // + // The variable part of a variable definition. Used in the `rule` parser + // + // @fink: + // + variable: function () { + var name; + + if (input.charAt(i) === '@' && (name = $re(/^(@[\w-]+)\s*:/))) { return name[1]; } + }, + + // + // extend syntax - used to extend selectors + // + extend: function(isRule) { + var elements, e, index = i, option, extendList, extend; + + if (!(isRule ? $re(/^&:extend\(/) : $re(/^:extend\(/))) { return; } + + do { + option = null; + elements = null; + while (! (option = $re(/^(all)(?=\s*(\)|,))/))) { + e = this.element(); + if (!e) { break; } + if (elements) { elements.push(e); } else { elements = [ e ]; } + } + + option = option && option[1]; + + extend = new(tree.Extend)(new(tree.Selector)(elements), option, index); + if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } + + } while($char(",")); + + expect(/^\)/); + + if (isRule) { + expect(/^;/); + } + + return extendList; + }, + + // + // extendRule - used in a rule to extend all the parent selectors + // + extendRule: function() { + return this.extend(true); + }, + + // + // Mixins + // + mixin: { + // + // A Mixin call, with an optional argument list + // + // #mixins > .square(#fff); + // .rounded(4px, black); + // .button; + // + // The `while` loop is there because mixins can be + // namespaced, but we only support the child and descendant + // selector for now. + // + call: function () { + var s = input.charAt(i), important = false, index = i, + elements, elem, e, c, args; + + if (s !== '.' && s !== '#') { return; } + + save(); // stop us absorbing part of an invalid selector + + while (true) { + e = $re(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/); + if (!e) { + break; + } + elem = new(tree.Element)(c, e, i, env.currentFileInfo); + if (elements) { elements.push(elem); } else { elements = [ elem ]; } + c = $char('>'); + } + if ($char('(')) { + args = this.args(true).args; + expectChar(')'); + } + + if (parsers.important()) { + important = true; + } + + if (elements && ($char(';') || peekChar('}'))) { + return new(tree.mixin.Call)(elements, args, index, env.currentFileInfo, important); + } + + restore(); + }, + args: function (isCall) { + var parsers = parser.parsers, entities = parsers.entities, + returner = { args:null, variadic: false }, + expressions = [], argsSemiColon = [], argsComma = [], + isSemiColonSeperated, expressionContainsNamed, name, nameLoop, value, arg; + + while (true) { + if (isCall) { + arg = parsers.expression(); + } else { + parsers.comments(); + if (input.charAt(i) === '.' && $re(/^\.{3}/)) { + returner.variadic = true; + if ($char(";") && !isSemiColonSeperated) { + isSemiColonSeperated = true; + } + (isSemiColonSeperated ? argsSemiColon : argsComma) + .push({ variadic: true }); + break; + } + arg = entities.variable() || entities.literal() || entities.keyword(); + } + + if (!arg) { + break; + } + + nameLoop = null; + if (arg.throwAwayComments) { + arg.throwAwayComments(); + } + value = arg; + var val = null; + + if (isCall) { + // Variable + if (arg.value.length == 1) { + val = arg.value[0]; + } + } else { + val = arg; + } + + if (val && val instanceof tree.Variable) { + if ($char(':')) { + if (expressions.length > 0) { + if (isSemiColonSeperated) { + error("Cannot mix ; and , as delimiter types"); + } + expressionContainsNamed = true; + } + value = expect(parsers.expression); + nameLoop = (name = val.name); + } else if (!isCall && $re(/^\.{3}/)) { + returner.variadic = true; + if ($char(";") && !isSemiColonSeperated) { + isSemiColonSeperated = true; + } + (isSemiColonSeperated ? argsSemiColon : argsComma) + .push({ name: arg.name, variadic: true }); + break; + } else if (!isCall) { + name = nameLoop = val.name; + value = null; + } + } + + if (value) { + expressions.push(value); + } + + argsComma.push({ name:nameLoop, value:value }); + + if ($char(',')) { + continue; + } + + if ($char(';') || isSemiColonSeperated) { + + if (expressionContainsNamed) { + error("Cannot mix ; and , as delimiter types"); + } + + isSemiColonSeperated = true; + + if (expressions.length > 1) { + value = new(tree.Value)(expressions); + } + argsSemiColon.push({ name:name, value:value }); + + name = null; + expressions = []; + expressionContainsNamed = false; + } + } + + returner.args = isSemiColonSeperated ? argsSemiColon : argsComma; + return returner; + }, + // + // A Mixin definition, with a list of parameters + // + // .rounded (@radius: 2px, @color) { + // ... + // } + // + // Until we have a finer grained state-machine, we have to + // do a look-ahead, to make sure we don't have a mixin call. + // See the `rule` function for more information. + // + // We start by matching `.rounded (`, and then proceed on to + // the argument list, which has optional default values. + // We store the parameters in `params`, with a `value` key, + // if there is a value, such as in the case of `@radius`. + // + // Once we've got our params list, and a closing `)`, we parse + // the `{...}` block. + // + definition: function () { + var name, params = [], match, ruleset, cond, variadic = false; + if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') || + peek(/^[^{]*\}/)) { + return; + } + + save(); + + match = $re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); + if (match) { + name = match[1]; + + var argInfo = this.args(false); + params = argInfo.args; + variadic = argInfo.variadic; + + // .mixincall("@{a}"); + // looks a bit like a mixin definition.. so we have to be nice and restore + if (!$char(')')) { + furthest = i; + restore(); + } + + parsers.comments(); + + if ($re(/^when/)) { // Guard + cond = expect(parsers.conditions, 'expected condition'); + } + + ruleset = parsers.block(); + + if (ruleset) { + return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic); + } else { + restore(); + } + } + } + }, + + // + // Entities are the smallest recognized token, + // and can be found inside a rule's value. + // + entity: function () { + var entities = this.entities; + + return entities.literal() || entities.variable() || entities.url() || + entities.call() || entities.keyword() || entities.javascript() || + this.comment(); + }, + + // + // A Rule terminator. Note that we use `peek()` to check for '}', + // because the `block` rule will be expecting it, but we still need to make sure + // it's there, if ';' was ommitted. + // + end: function () { + return $char(';') || peekChar('}'); + }, + + // + // IE's alpha function + // + // alpha(opacity=88) + // + alpha: function () { + var value; + + if (! $re(/^\(opacity=/i)) { return; } + value = $re(/^\d+/) || this.entities.variable(); + if (value) { + expectChar(')'); + return new(tree.Alpha)(value); + } + }, + + // + // A Selector Element + // + // div + // + h1 + // #socks + // input[type="text"] + // + // Elements are the building blocks for Selectors, + // they are made out of a `Combinator` (see combinator rule), + // and an element name, such as a tag a class, or `*`. + // + element: function () { + var e, c, v; + + c = this.combinator(); + + e = $re(/^(?:\d+\.\d+|\d+)%/) || $re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || + $char('*') || $char('&') || this.attribute() || $re(/^\([^()@]+\)/) || $re(/^[\.#](?=@)/) || + this.entities.variableCurly(); + + if (! e) { + if ($char('(')) { + if ((v = this.selector()) && $char(')')) { + e = new(tree.Paren)(v); + } + } + } + + if (e) { return new(tree.Element)(c, e, i, env.currentFileInfo); } + }, + + // + // Combinators combine elements together, in a Selector. + // + // Because our parser isn't white-space sensitive, special care + // has to be taken, when parsing the descendant combinator, ` `, + // as it's an empty space. We have to check the previous character + // in the input, to see if it's a ` ` character. More info on how + // we deal with this in *combinator.js*. + // + combinator: function () { + var c = input.charAt(i); + + if (c === '>' || c === '+' || c === '~' || c === '|') { + i++; + while (isWhitespace(input, i)) { i++; } + return new(tree.Combinator)(c); + } else if (isWhitespace(input, i - 1)) { + return new(tree.Combinator)(" "); + } else { + return new(tree.Combinator)(null); + } + }, + // + // A CSS selector (see selector below) + // with less extensions e.g. the ability to extend and guard + // + lessSelector: function () { + return this.selector(true); + }, + // + // A CSS Selector + // + // .class > div + h1 + // li a:hover + // + // Selectors are made out of one or more Elements, see above. + // + selector: function (isLess) { + var $re = _$re, elements, extendList, c, e, extend, when, condition; + + while ((isLess && (extend = this.extend())) || (isLess && (when = $re(/^when/))) || (e = this.element())) { + if (when) { + condition = expect(this.conditions, 'expected condition'); + } else if (condition) { + error("CSS guard can only be used at the end of selector"); + } else if (extend) { + if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } + } else { + if (extendList) { error("Extend can only be used at the end of selector"); } + c = input.charAt(i); + if (elements) { elements.push(e); } else { elements = [ e ]; } + e = null; + } + if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { + break; + } + } + + if (elements) { return new(tree.Selector)(elements, extendList, condition, i, env.currentFileInfo); } + if (extendList) { error("Extend must be used to extend a selector, it cannot be used on its own"); } + }, + attribute: function () { + if (! $char('[')) { return; } + + var entities = this.entities, + key, val, op; + + if (!(key = entities.variableCurly())) { + key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); + } + + op = $re(/^[|~*$^]?=/); + if (op) { + val = entities.quoted() || $re(/^[0-9]+%/) || $re(/^[\w-]+/) || entities.variableCurly(); + } + + expectChar(']'); + + return new(tree.Attribute)(key, op, val); + }, + + // + // The `block` rule is used by `ruleset` and `mixin.definition`. + // It's a wrapper around the `primary` rule, with added `{}`. + // + block: function () { + var content; + if ($char('{') && (content = this.primary()) && $char('}')) { + return content; + } + }, + + // + // div, .class, body > p {...} + // + ruleset: function () { + var selectors, s, rules, debugInfo; + + save(); + + if (env.dumpLineNumbers) { + debugInfo = getDebugInfo(i, input, env); + } + + while (true) { + s = this.lessSelector(); + if (!s) { + break; + } + if (selectors) { selectors.push(s); } else { selectors = [ s ]; } + this.comments(); + if (! $char(',')) { break; } + if (s.condition) { + error("Guards are only currently allowed on a single selector."); + } + this.comments(); + } + + if (selectors && (rules = this.block())) { + var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports); + if (env.dumpLineNumbers) { + ruleset.debugInfo = debugInfo; + } + return ruleset; + } else { + // Backtrack + furthest = i; + restore(); + } + }, + rule: function (tryAnonymous) { + var name, value, c = input.charAt(i), important, merge = false; + save(); + + if (c === '.' || c === '#' || c === '&') { return; } + + name = this.variable() || this.ruleProperty(); + if (name) { + // prefer to try to parse first if its a variable or we are compressing + // but always fallback on the other one + value = !tryAnonymous && (env.compress || (name.charAt && (name.charAt(0) === '@'))) ? + (this.value() || this.anonymousValue()) : + (this.anonymousValue() || this.value()); + + important = this.important(); + + // a name returned by this.ruleProperty() is always an array of the form: + // ["", "string-1", ..., "string-n", ""] or ["", "string-1", ..., "string-n", "+"] + merge = name.pop && (name.pop() === "+"); + + if (value && this.end()) { + return new (tree.Rule)(name, value, important, merge, memo, env.currentFileInfo); + } else { + furthest = i; + restore(); + if (value && !tryAnonymous) { + return this.rule(true); + } + } + } + }, + anonymousValue: function () { + var match; + match = /^([^@+\/'"*`(;{}-]*);/.exec(current); + if (match) { + i += match[0].length - 1; + return new(tree.Anonymous)(match[1]); + } + }, + + // + // An @import directive + // + // @import "lib"; + // + // Depending on our environemnt, importing is done differently: + // In the browser, it's an XHR request, in Node, it would be a + // file-system operation. The function used for importing is + // stored in `import`, which we pass to the Import constructor. + // + "import": function () { + var path, features, index = i; + + save(); + + var dir = $re(/^@import?\s+/); + + var options = (dir ? this.importOptions() : null) || {}; + + if (dir && (path = this.entities.quoted() || this.entities.url())) { + features = this.mediaFeatures(); + if ($char(';')) { + features = features && new(tree.Value)(features); + return new(tree.Import)(path, features, options, index, env.currentFileInfo); + } + } + + restore(); + }, + + importOptions: function() { + var o, options = {}, optionName, value; + + // list of options, surrounded by parens + if (! $char('(')) { return null; } + do { + o = this.importOption(); + if (o) { + optionName = o; + value = true; + switch(optionName) { + case "css": + optionName = "less"; + value = false; + break; + case "once": + optionName = "multiple"; + value = false; + break; + } + options[optionName] = value; + if (! $char(',')) { break; } + } + } while (o); + expectChar(')'); + return options; + }, + + importOption: function() { + var opt = $re(/^(less|css|multiple|once|inline|reference)/); + if (opt) { + return opt[1]; + } + }, + + mediaFeature: function () { + var entities = this.entities, nodes = [], e, p; + do { + e = entities.keyword() || entities.variable(); + if (e) { + nodes.push(e); + } else if ($char('(')) { + p = this.property(); + e = this.value(); + if ($char(')')) { + if (p && e) { + nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, i, env.currentFileInfo, true))); + } else if (e) { + nodes.push(new(tree.Paren)(e)); + } else { + return null; + } + } else { return null; } + } + } while (e); + + if (nodes.length > 0) { + return new(tree.Expression)(nodes); + } + }, + + mediaFeatures: function () { + var entities = this.entities, features = [], e; + do { + e = this.mediaFeature(); + if (e) { + features.push(e); + if (! $char(',')) { break; } + } else { + e = entities.variable(); + if (e) { + features.push(e); + if (! $char(',')) { break; } + } + } + } while (e); + + return features.length > 0 ? features : null; + }, + + media: function () { + var features, rules, media, debugInfo; + + if (env.dumpLineNumbers) { + debugInfo = getDebugInfo(i, input, env); + } + + if ($re(/^@media/)) { + features = this.mediaFeatures(); + + rules = this.block(); + if (rules) { + media = new(tree.Media)(rules, features, i, env.currentFileInfo); + if (env.dumpLineNumbers) { + media.debugInfo = debugInfo; + } + return media; + } + } + }, + + // + // A CSS Directive + // + // @charset "utf-8"; + // + directive: function () { + var name, value, rules, nonVendorSpecificName, + hasBlock, hasIdentifier, hasExpression, identifier; + + if (input.charAt(i) !== '@') { return; } + + value = this['import']() || this.media(); + if (value) { + return value; + } + + save(); + + name = $re(/^@[a-z-]+/); + + if (!name) { return; } + + nonVendorSpecificName = name; + if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { + nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); + } + + switch(nonVendorSpecificName) { + case "@font-face": + hasBlock = true; + break; + case "@viewport": + case "@top-left": + case "@top-left-corner": + case "@top-center": + case "@top-right": + case "@top-right-corner": + case "@bottom-left": + case "@bottom-left-corner": + case "@bottom-center": + case "@bottom-right": + case "@bottom-right-corner": + case "@left-top": + case "@left-middle": + case "@left-bottom": + case "@right-top": + case "@right-middle": + case "@right-bottom": + hasBlock = true; + break; + case "@host": + case "@page": + case "@document": + case "@supports": + case "@keyframes": + hasBlock = true; + hasIdentifier = true; + break; + case "@namespace": + hasExpression = true; + break; + } + + if (hasIdentifier) { + identifier = ($re(/^[^{]+/) || '').trim(); + if (identifier) { + name += " " + identifier; + } + } + + if (hasBlock) { + rules = this.block(); + if (rules) { + return new(tree.Directive)(name, rules, i, env.currentFileInfo); + } + } else { + value = hasExpression ? this.expression() : this.entity(); + if (value && $char(';')) { + var directive = new(tree.Directive)(name, value, i, env.currentFileInfo); + if (env.dumpLineNumbers) { + directive.debugInfo = getDebugInfo(i, input, env); + } + return directive; + } + } + + restore(); + }, + + // + // A Value is a comma-delimited list of Expressions + // + // font-family: Baskerville, Georgia, serif; + // + // In a Rule, a Value represents everything after the `:`, + // and before the `;`. + // + value: function () { + var e, expressions = []; + + do { + e = this.expression(); + if (e) { + expressions.push(e); + if (! $char(',')) { break; } + } + } while(e); + + if (expressions.length > 0) { + return new(tree.Value)(expressions); + } + }, + important: function () { + if (input.charAt(i) === '!') { + return $re(/^! *important/); + } + }, + sub: function () { + var a, e; + + if ($char('(')) { + a = this.addition(); + if (a) { + e = new(tree.Expression)([a]); + expectChar(')'); + e.parens = true; + return e; + } + } + }, + multiplication: function () { + var m, a, op, operation, isSpaced; + m = this.operand(); + if (m) { + isSpaced = isWhitespace(input, i - 1); + while (true) { + if (peek(/^\/[*\/]/)) { + break; + } + op = $char('/') || $char('*'); + + if (!op) { break; } + + a = this.operand(); + + if (!a) { break; } + + m.parensInOp = true; + a.parensInOp = true; + operation = new(tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = isWhitespace(input, i - 1); + } + return operation || m; + } + }, + addition: function () { + var m, a, op, operation, isSpaced; + m = this.multiplication(); + if (m) { + isSpaced = isWhitespace(input, i - 1); + while (true) { + op = $re(/^[-+]\s+/) || (!isSpaced && ($char('+') || $char('-'))); + if (!op) { + break; + } + a = this.multiplication(); + if (!a) { + break; + } + + m.parensInOp = true; + a.parensInOp = true; + operation = new(tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = isWhitespace(input, i - 1); + } + return operation || m; + } + }, + conditions: function () { + var a, b, index = i, condition; + + a = this.condition(); + if (a) { + while (true) { + if (!peek(/^,\s*(not\s*)?\(/) || !$char(',')) { + break; + } + b = this.condition(); + if (!b) { + break; + } + condition = new(tree.Condition)('or', condition || a, b, index); + } + return condition || a; + } + }, + condition: function () { + var entities = this.entities, index = i, negate = false, + a, b, c, op; + + if ($re(/^not/)) { negate = true; } + expectChar('('); + a = this.addition() || entities.keyword() || entities.quoted(); + if (a) { + op = $re(/^(?:>=|<=|=<|[<=>])/); + if (op) { + b = this.addition() || entities.keyword() || entities.quoted(); + if (b) { + c = new(tree.Condition)(op, a, b, index, negate); + } else { + error('expected expression'); + } + } else { + c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate); + } + expectChar(')'); + return $re(/^and/) ? new(tree.Condition)('and', c, this.condition()) : c; + } + }, + + // + // An operand is anything that can be part of an operation, + // such as a Color, or a Variable + // + operand: function () { + var entities = this.entities, + p = input.charAt(i + 1), negate; + + if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $char('-'); } + var o = this.sub() || entities.dimension() || + entities.color() || entities.variable() || + entities.call(); + + if (negate) { + o.parensInOp = true; + o = new(tree.Negative)(o); + } + + return o; + }, + + // + // Expressions either represent mathematical operations, + // or white-space delimited Entities. + // + // 1px solid black + // @var * 2 + // + expression: function () { + var entities = [], e, delim; + + do { + e = this.addition() || this.entity(); + if (e) { + entities.push(e); + // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here + if (!peek(/^\/[\/*]/)) { + delim = $char('/'); + if (delim) { + entities.push(new(tree.Anonymous)(delim)); + } + } + } + } while (e); + if (entities.length > 0) { + return new(tree.Expression)(entities); + } + }, + property: function () { + var name = $re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); + if (name) { + return name[1]; + } + }, + ruleProperty: function () { + var c = current, name = [], index = [], length = 0; + + function match(re) { + var a = re.exec(c); + if (a) { + index.push(i + length); + length += a[0].length; + c = c.slice(a[1].length); + return name.push(a[1]); + } + } + + match(/^(\*?)/); + while (match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)); // ! + if ((name.length > 1) && match(/^\s*(\+?)\s*:/)) { + // at last, we have the complete match now. move forward, + // convert @{var}s to tree.Variable(s) and return: + skipWhitespace(length); + for (var k in name) { + if (name[k].charAt(0) === '@') { + name[k] = new tree.Variable('@' + name[k].slice(2, -1), + index[k], env.currentFileInfo); + } + } + return name; + } + } + } + }; + return parser; +}; +less.Parser.serializeVars = function(vars) { + var s = ''; + + for (var name in vars) { + if (Object.hasOwnProperty.call(vars, name)) { + var value = vars[name]; + s += ((name[0] === '@') ? '' : '@') + name +': '+ value + + ((('' + value).slice(-1) === ';') ? '' : ';'); + } + } + + return s; +}; +(function (tree) { + +tree.functions = { + rgb: function (r, g, b) { + return this.rgba(r, g, b, 1.0); + }, + rgba: function (r, g, b, a) { + var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); + a = number(a); + return new(tree.Color)(rgb, a); + }, + hsl: function (h, s, l) { + return this.hsla(h, s, l, 1.0); + }, + hsla: function (h, s, l, a) { + function hue(h) { + h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); + if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } + else if (h * 2 < 1) { return m2; } + else if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; } + else { return m1; } + } + + h = (number(h) % 360) / 360; + s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a)); + + var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; + var m1 = l * 2 - m2; + + return this.rgba(hue(h + 1/3) * 255, + hue(h) * 255, + hue(h - 1/3) * 255, + a); + }, + + hsv: function(h, s, v) { + return this.hsva(h, s, v, 1.0); + }, + + hsva: function(h, s, v, a) { + h = ((number(h) % 360) / 360) * 360; + s = number(s); v = number(v); a = number(a); + + var i, f; + i = Math.floor((h / 60) % 6); + f = (h / 60) - i; + + var vs = [v, + v * (1 - s), + v * (1 - f * s), + v * (1 - (1 - f) * s)]; + var perm = [[0, 3, 1], + [2, 0, 1], + [1, 0, 3], + [1, 2, 0], + [3, 1, 0], + [0, 1, 2]]; + + return this.rgba(vs[perm[i][0]] * 255, + vs[perm[i][1]] * 255, + vs[perm[i][2]] * 255, + a); + }, + + hue: function (color) { + return new(tree.Dimension)(Math.round(color.toHSL().h)); + }, + saturation: function (color) { + return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%'); + }, + lightness: function (color) { + return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%'); + }, + hsvhue: function(color) { + return new(tree.Dimension)(Math.round(color.toHSV().h)); + }, + hsvsaturation: function (color) { + return new(tree.Dimension)(Math.round(color.toHSV().s * 100), '%'); + }, + hsvvalue: function (color) { + return new(tree.Dimension)(Math.round(color.toHSV().v * 100), '%'); + }, + red: function (color) { + return new(tree.Dimension)(color.rgb[0]); + }, + green: function (color) { + return new(tree.Dimension)(color.rgb[1]); + }, + blue: function (color) { + return new(tree.Dimension)(color.rgb[2]); + }, + alpha: function (color) { + return new(tree.Dimension)(color.toHSL().a); + }, + luma: function (color) { + return new(tree.Dimension)(Math.round(color.luma() * color.alpha * 100), '%'); + }, + saturate: function (color, amount) { + // filter: saturate(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + var hsl = color.toHSL(); + + hsl.s += amount.value / 100; + hsl.s = clamp(hsl.s); + return hsla(hsl); + }, + desaturate: function (color, amount) { + var hsl = color.toHSL(); + + hsl.s -= amount.value / 100; + hsl.s = clamp(hsl.s); + return hsla(hsl); + }, + lighten: function (color, amount) { + var hsl = color.toHSL(); + + hsl.l += amount.value / 100; + hsl.l = clamp(hsl.l); + return hsla(hsl); + }, + darken: function (color, amount) { + var hsl = color.toHSL(); + + hsl.l -= amount.value / 100; + hsl.l = clamp(hsl.l); + return hsla(hsl); + }, + fadein: function (color, amount) { + var hsl = color.toHSL(); + + hsl.a += amount.value / 100; + hsl.a = clamp(hsl.a); + return hsla(hsl); + }, + fadeout: function (color, amount) { + var hsl = color.toHSL(); + + hsl.a -= amount.value / 100; + hsl.a = clamp(hsl.a); + return hsla(hsl); + }, + fade: function (color, amount) { + var hsl = color.toHSL(); + + hsl.a = amount.value / 100; + hsl.a = clamp(hsl.a); + return hsla(hsl); + }, + spin: function (color, amount) { + var hsl = color.toHSL(); + var hue = (hsl.h + amount.value) % 360; + + hsl.h = hue < 0 ? 360 + hue : hue; + + return hsla(hsl); + }, + // + // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein + // http://sass-lang.com + // + mix: function (color1, color2, weight) { + if (!weight) { + weight = new(tree.Dimension)(50); + } + var p = weight.value / 100.0; + var w = p * 2 - 1; + var a = color1.toHSL().a - color2.toHSL().a; + + var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + + var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, + color1.rgb[1] * w1 + color2.rgb[1] * w2, + color1.rgb[2] * w1 + color2.rgb[2] * w2]; + + var alpha = color1.alpha * p + color2.alpha * (1 - p); + + return new(tree.Color)(rgb, alpha); + }, + greyscale: function (color) { + return this.desaturate(color, new(tree.Dimension)(100)); + }, + contrast: function (color, dark, light, threshold) { + // filter: contrast(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + if (typeof light === 'undefined') { + light = this.rgba(255, 255, 255, 1.0); + } + if (typeof dark === 'undefined') { + dark = this.rgba(0, 0, 0, 1.0); + } + //Figure out which is actually light and dark! + if (dark.luma() > light.luma()) { + var t = light; + light = dark; + dark = t; + } + if (typeof threshold === 'undefined') { + threshold = 0.43; + } else { + threshold = number(threshold); + } + if (color.luma() < threshold) { + return light; + } else { + return dark; + } + }, + e: function (str) { + return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str); + }, + escape: function (str) { + return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29")); + }, + '%': function (quoted /* arg, arg, ...*/) { + var args = Array.prototype.slice.call(arguments, 1), + str = quoted.value; + + for (var i = 0; i < args.length; i++) { + /*jshint loopfunc:true */ + str = str.replace(/%[sda]/i, function(token) { + var value = token.match(/s/i) ? args[i].value : args[i].toCSS(); + return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; + }); + } + str = str.replace(/%%/g, '%'); + return new(tree.Quoted)('"' + str + '"', str); + }, + unit: function (val, unit) { + if(!(val instanceof tree.Dimension)) { + throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") }; + } + return new(tree.Dimension)(val.value, unit ? unit.toCSS() : ""); + }, + convert: function (val, unit) { + return val.convertTo(unit.value); + }, + round: function (n, f) { + var fraction = typeof(f) === "undefined" ? 0 : f.value; + return _math(function(num) { return num.toFixed(fraction); }, null, n); + }, + pi: function () { + return new(tree.Dimension)(Math.PI); + }, + mod: function(a, b) { + return new(tree.Dimension)(a.value % b.value, a.unit); + }, + pow: function(x, y) { + if (typeof x === "number" && typeof y === "number") { + x = new(tree.Dimension)(x); + y = new(tree.Dimension)(y); + } else if (!(x instanceof tree.Dimension) || !(y instanceof tree.Dimension)) { + throw { type: "Argument", message: "arguments must be numbers" }; + } + + return new(tree.Dimension)(Math.pow(x.value, y.value), x.unit); + }, + _minmax: function (isMin, args) { + args = Array.prototype.slice.call(args); + switch(args.length) { + case 0: throw { type: "Argument", message: "one or more arguments required" }; + case 1: return args[0]; + } + var i, j, current, currentUnified, referenceUnified, unit, + order = [], // elems only contains original argument values. + values = {}; // key is the unit.toString() for unified tree.Dimension values, + // value is the index into the order array. + for (i = 0; i < args.length; i++) { + current = args[i]; + if (!(current instanceof tree.Dimension)) { + order.push(current); + continue; + } + currentUnified = current.unify(); + unit = currentUnified.unit.toString(); + j = values[unit]; + if (j === undefined) { + values[unit] = order.length; + order.push(current); + continue; + } + referenceUnified = order[j].unify(); + if ( isMin && currentUnified.value < referenceUnified.value || + !isMin && currentUnified.value > referenceUnified.value) { + order[j] = current; + } + } + if (order.length == 1) { + return order[0]; + } + args = order.map(function (a) { return a.toCSS(this.env); }) + .join(this.env.compress ? "," : ", "); + return new(tree.Anonymous)((isMin ? "min" : "max") + "(" + args + ")"); + }, + min: function () { + return this._minmax(true, arguments); + }, + max: function () { + return this._minmax(false, arguments); + }, + argb: function (color) { + return new(tree.Anonymous)(color.toARGB()); + }, + percentage: function (n) { + return new(tree.Dimension)(n.value * 100, '%'); + }, + color: function (n) { + if (n instanceof tree.Quoted) { + var colorCandidate = n.value, + returnColor; + returnColor = tree.Color.fromKeyword(colorCandidate); + if (returnColor) { + return returnColor; + } + if (/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(colorCandidate)) { + return new(tree.Color)(colorCandidate.slice(1)); + } + throw { type: "Argument", message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF" }; + } else { + throw { type: "Argument", message: "argument must be a string" }; + } + }, + iscolor: function (n) { + return this._isa(n, tree.Color); + }, + isnumber: function (n) { + return this._isa(n, tree.Dimension); + }, + isstring: function (n) { + return this._isa(n, tree.Quoted); + }, + iskeyword: function (n) { + return this._isa(n, tree.Keyword); + }, + isurl: function (n) { + return this._isa(n, tree.URL); + }, + ispixel: function (n) { + return this.isunit(n, 'px'); + }, + ispercentage: function (n) { + return this.isunit(n, '%'); + }, + isem: function (n) { + return this.isunit(n, 'em'); + }, + isunit: function (n, unit) { + return (n instanceof tree.Dimension) && n.unit.is(unit.value || unit) ? tree.True : tree.False; + }, + _isa: function (n, Type) { + return (n instanceof Type) ? tree.True : tree.False; + }, + tint: function(color, amount) { + return this.mix(this.rgb(255,255,255), color, amount); + }, + shade: function(color, amount) { + return this.mix(this.rgb(0, 0, 0), color, amount); + }, + extract: function(values, index) { + index = index.value - 1; // (1-based index) + // handle non-array values as an array of length 1 + // return 'undefined' if index is invalid + return Array.isArray(values.value) + ? values.value[index] : Array(values)[index]; + }, + length: function(values) { + var n = Array.isArray(values.value) ? values.value.length : 1; + return new tree.Dimension(n); + }, + + "data-uri": function(mimetypeNode, filePathNode) { + + if (typeof window !== 'undefined') { + return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); + } + + var mimetype = mimetypeNode.value; + var filePath = (filePathNode && filePathNode.value); + + var fs = require("fs"), + path = require("path"), + useBase64 = false; + + if (arguments.length < 2) { + filePath = mimetype; + } + + if (this.env.isPathRelative(filePath)) { + if (this.currentFileInfo.relativeUrls) { + filePath = path.join(this.currentFileInfo.currentDirectory, filePath); + } else { + filePath = path.join(this.currentFileInfo.entryPath, filePath); + } + } + + // detect the mimetype if not given + if (arguments.length < 2) { + var mime; + try { + mime = require('mime'); + } catch (ex) { + mime = tree._mime; + } + + mimetype = mime.lookup(filePath); + + // use base 64 unless it's an ASCII or UTF-8 format + var charset = mime.charsets.lookup(mimetype); + useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; + if (useBase64) { mimetype += ';base64'; } + } + else { + useBase64 = /;base64$/.test(mimetype); + } + + var buf = fs.readFileSync(filePath); + + // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded + // and the --ieCompat flag is enabled, return a normal url() instead. + var DATA_URI_MAX_KB = 32, + fileSizeInKB = parseInt((buf.length / 1024), 10); + if (fileSizeInKB >= DATA_URI_MAX_KB) { + + if (this.env.ieCompat !== false) { + if (!this.env.silent) { + console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB); + } + + return new tree.URL(filePathNode || mimetypeNode, this.currentFileInfo).eval(this.env); + } + } + + buf = useBase64 ? buf.toString('base64') + : encodeURIComponent(buf); + + var uri = "'data:" + mimetype + ',' + buf + "'"; + return new(tree.URL)(new(tree.Anonymous)(uri)); + }, + + "svg-gradient": function(direction) { + + function throwArgumentDescriptor() { + throw { type: "Argument", message: "svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]" }; + } + + if (arguments.length < 3) { + throwArgumentDescriptor(); + } + var stops = Array.prototype.slice.call(arguments, 1), + gradientDirectionSvg, + gradientType = "linear", + rectangleDimension = 'x="0" y="0" width="1" height="1"', + useBase64 = true, + renderEnv = {compress: false}, + returner, + directionValue = direction.toCSS(renderEnv), + i, color, position, positionValue, alpha; + + switch (directionValue) { + case "to bottom": + gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; + break; + case "to right": + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; + break; + case "to bottom right": + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; + break; + case "to top right": + gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; + break; + case "ellipse": + case "ellipse at center": + gradientType = "radial"; + gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; + rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; + break; + default: + throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" }; + } + returner = '' + + '' + + '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>'; + + for (i = 0; i < stops.length; i+= 1) { + if (stops[i].value) { + color = stops[i].value[0]; + position = stops[i].value[1]; + } else { + color = stops[i]; + position = undefined; + } + + if (!(color instanceof tree.Color) || (!((i === 0 || i+1 === stops.length) && position === undefined) && !(position instanceof tree.Dimension))) { + throwArgumentDescriptor(); + } + positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%"; + alpha = color.alpha; + returner += ''; + } + returner += '' + + ''; + + if (useBase64) { + // only works in node, needs interface to what is supported in environment + try { + returner = new Buffer(returner).toString('base64'); + } catch(e) { + useBase64 = false; + } + } + + returner = "'data:image/svg+xml" + (useBase64 ? ";base64" : "") + "," + returner + "'"; + return new(tree.URL)(new(tree.Anonymous)(returner)); + } +}; + +// these static methods are used as a fallback when the optional 'mime' dependency is missing +tree._mime = { + // this map is intentionally incomplete + // if you want more, install 'mime' dep + _types: { + '.htm' : 'text/html', + '.html': 'text/html', + '.gif' : 'image/gif', + '.jpg' : 'image/jpeg', + '.jpeg': 'image/jpeg', + '.png' : 'image/png' + }, + lookup: function (filepath) { + var ext = require('path').extname(filepath), + type = tree._mime._types[ext]; + if (type === undefined) { + throw new Error('Optional dependency "mime" is required for ' + ext); + } + return type; + }, + charsets: { + lookup: function (type) { + // assumes all text types are UTF-8 + return type && (/^text\//).test(type) ? 'UTF-8' : ''; + } + } +}; + +// Math + +var mathFunctions = { + // name, unit + ceil: null, + floor: null, + sqrt: null, + abs: null, + tan: "", + sin: "", + cos: "", + atan: "rad", + asin: "rad", + acos: "rad" +}; + +function _math(fn, unit, n) { + if (!(n instanceof tree.Dimension)) { + throw { type: "Argument", message: "argument must be a number" }; + } + if (unit == null) { + unit = n.unit; + } else { + n = n.unify(); + } + return new(tree.Dimension)(fn(parseFloat(n.value)), unit); +} + +// ~ End of Math + +// Color Blending +// ref: http://www.w3.org/TR/compositing-1 + +function colorBlend(mode, color1, color2) { + var ab = color1.alpha, cb, // backdrop + as = color2.alpha, cs, // source + ar, cr, r = []; // result + + ar = as + ab * (1 - as); + for (var i = 0; i < 3; i++) { + cb = color1.rgb[i] / 255; + cs = color2.rgb[i] / 255; + cr = mode(cb, cs); + if (ar) { + cr = (as * cs + ab * (cb + - as * (cb + cs - cr))) / ar; + } + r[i] = cr * 255; + } + + return new(tree.Color)(r, ar); +} + +var colorBlendMode = { + multiply: function(cb, cs) { + return cb * cs; + }, + screen: function(cb, cs) { + return cb + cs - cb * cs; + }, + overlay: function(cb, cs) { + cb *= 2; + return (cb <= 1) + ? colorBlendMode.multiply(cb, cs) + : colorBlendMode.screen(cb - 1, cs); + }, + softlight: function(cb, cs) { + var d = 1, e = cb; + if (cs > 0.5) { + e = 1; + d = (cb > 0.25) ? Math.sqrt(cb) + : ((16 * cb - 12) * cb + 4) * cb; + } + return cb - (1 - 2 * cs) * e * (d - cb); + }, + hardlight: function(cb, cs) { + return colorBlendMode.overlay(cs, cb); + }, + difference: function(cb, cs) { + return Math.abs(cb - cs); + }, + exclusion: function(cb, cs) { + return cb + cs - 2 * cb * cs; + }, + + // non-w3c functions: + average: function(cb, cs) { + return (cb + cs) / 2; + }, + negation: function(cb, cs) { + return 1 - Math.abs(cb + cs - 1); + } +}; + +// ~ End of Color Blending + +tree.defaultFunc = { + eval: function () { + var v = this.value_, e = this.error_; + if (e) { + throw e; + } + if (v != null) { + return v ? tree.True : tree.False; + } + }, + value: function (v) { + this.value_ = v; + }, + error: function (e) { + this.error_ = e; + }, + reset: function () { + this.value_ = this.error_ = null; + } +}; + +function initFunctions() { + var f, tf = tree.functions; + + // math + for (f in mathFunctions) { + tf[f] = _math.bind(null, Math[f], mathFunctions[f]); + } + + // color blending + for (f in colorBlendMode) { + tf[f] = colorBlend.bind(null, colorBlendMode[f]); + } + + // default + f = tree.defaultFunc; + tf.default = f.eval.bind(f); + +} initFunctions(); + +function hsla(color) { + return tree.functions.hsla(color.h, color.s, color.l, color.a); +} + +function scaled(n, size) { + if (n instanceof tree.Dimension && n.unit.is('%')) { + return parseFloat(n.value * size / 100); + } else { + return number(n); + } +} + +function number(n) { + if (n instanceof tree.Dimension) { + return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); + } else if (typeof(n) === 'number') { + return n; + } else { + throw { + error: "RuntimeError", + message: "color functions take numbers as parameters" + }; + } +} + +function clamp(val) { + return Math.min(1, Math.max(0, val)); +} + +tree.functionCall = function(env, currentFileInfo) { + this.env = env; + this.currentFileInfo = currentFileInfo; +}; + +tree.functionCall.prototype = tree.functions; + +})(require('./tree')); + +(function (tree) { + tree.colors = { + 'aliceblue':'#f0f8ff', + 'antiquewhite':'#faebd7', + 'aqua':'#00ffff', + 'aquamarine':'#7fffd4', + 'azure':'#f0ffff', + 'beige':'#f5f5dc', + 'bisque':'#ffe4c4', + 'black':'#000000', + 'blanchedalmond':'#ffebcd', + 'blue':'#0000ff', + 'blueviolet':'#8a2be2', + 'brown':'#a52a2a', + 'burlywood':'#deb887', + 'cadetblue':'#5f9ea0', + 'chartreuse':'#7fff00', + 'chocolate':'#d2691e', + 'coral':'#ff7f50', + 'cornflowerblue':'#6495ed', + 'cornsilk':'#fff8dc', + 'crimson':'#dc143c', + 'cyan':'#00ffff', + 'darkblue':'#00008b', + 'darkcyan':'#008b8b', + 'darkgoldenrod':'#b8860b', + 'darkgray':'#a9a9a9', + 'darkgrey':'#a9a9a9', + 'darkgreen':'#006400', + 'darkkhaki':'#bdb76b', + 'darkmagenta':'#8b008b', + 'darkolivegreen':'#556b2f', + 'darkorange':'#ff8c00', + 'darkorchid':'#9932cc', + 'darkred':'#8b0000', + 'darksalmon':'#e9967a', + 'darkseagreen':'#8fbc8f', + 'darkslateblue':'#483d8b', + 'darkslategray':'#2f4f4f', + 'darkslategrey':'#2f4f4f', + 'darkturquoise':'#00ced1', + 'darkviolet':'#9400d3', + 'deeppink':'#ff1493', + 'deepskyblue':'#00bfff', + 'dimgray':'#696969', + 'dimgrey':'#696969', + 'dodgerblue':'#1e90ff', + 'firebrick':'#b22222', + 'floralwhite':'#fffaf0', + 'forestgreen':'#228b22', + 'fuchsia':'#ff00ff', + 'gainsboro':'#dcdcdc', + 'ghostwhite':'#f8f8ff', + 'gold':'#ffd700', + 'goldenrod':'#daa520', + 'gray':'#808080', + 'grey':'#808080', + 'green':'#008000', + 'greenyellow':'#adff2f', + 'honeydew':'#f0fff0', + 'hotpink':'#ff69b4', + 'indianred':'#cd5c5c', + 'indigo':'#4b0082', + 'ivory':'#fffff0', + 'khaki':'#f0e68c', + 'lavender':'#e6e6fa', + 'lavenderblush':'#fff0f5', + 'lawngreen':'#7cfc00', + 'lemonchiffon':'#fffacd', + 'lightblue':'#add8e6', + 'lightcoral':'#f08080', + 'lightcyan':'#e0ffff', + 'lightgoldenrodyellow':'#fafad2', + 'lightgray':'#d3d3d3', + 'lightgrey':'#d3d3d3', + 'lightgreen':'#90ee90', + 'lightpink':'#ffb6c1', + 'lightsalmon':'#ffa07a', + 'lightseagreen':'#20b2aa', + 'lightskyblue':'#87cefa', + 'lightslategray':'#778899', + 'lightslategrey':'#778899', + 'lightsteelblue':'#b0c4de', + 'lightyellow':'#ffffe0', + 'lime':'#00ff00', + 'limegreen':'#32cd32', + 'linen':'#faf0e6', + 'magenta':'#ff00ff', + 'maroon':'#800000', + 'mediumaquamarine':'#66cdaa', + 'mediumblue':'#0000cd', + 'mediumorchid':'#ba55d3', + 'mediumpurple':'#9370d8', + 'mediumseagreen':'#3cb371', + 'mediumslateblue':'#7b68ee', + 'mediumspringgreen':'#00fa9a', + 'mediumturquoise':'#48d1cc', + 'mediumvioletred':'#c71585', + 'midnightblue':'#191970', + 'mintcream':'#f5fffa', + 'mistyrose':'#ffe4e1', + 'moccasin':'#ffe4b5', + 'navajowhite':'#ffdead', + 'navy':'#000080', + 'oldlace':'#fdf5e6', + 'olive':'#808000', + 'olivedrab':'#6b8e23', + 'orange':'#ffa500', + 'orangered':'#ff4500', + 'orchid':'#da70d6', + 'palegoldenrod':'#eee8aa', + 'palegreen':'#98fb98', + 'paleturquoise':'#afeeee', + 'palevioletred':'#d87093', + 'papayawhip':'#ffefd5', + 'peachpuff':'#ffdab9', + 'peru':'#cd853f', + 'pink':'#ffc0cb', + 'plum':'#dda0dd', + 'powderblue':'#b0e0e6', + 'purple':'#800080', + 'red':'#ff0000', + 'rosybrown':'#bc8f8f', + 'royalblue':'#4169e1', + 'saddlebrown':'#8b4513', + 'salmon':'#fa8072', + 'sandybrown':'#f4a460', + 'seagreen':'#2e8b57', + 'seashell':'#fff5ee', + 'sienna':'#a0522d', + 'silver':'#c0c0c0', + 'skyblue':'#87ceeb', + 'slateblue':'#6a5acd', + 'slategray':'#708090', + 'slategrey':'#708090', + 'snow':'#fffafa', + 'springgreen':'#00ff7f', + 'steelblue':'#4682b4', + 'tan':'#d2b48c', + 'teal':'#008080', + 'thistle':'#d8bfd8', + 'tomato':'#ff6347', + 'turquoise':'#40e0d0', + 'violet':'#ee82ee', + 'wheat':'#f5deb3', + 'white':'#ffffff', + 'whitesmoke':'#f5f5f5', + 'yellow':'#ffff00', + 'yellowgreen':'#9acd32' + }; +})(require('./tree')); + +(function (tree) { + +tree.debugInfo = function(env, ctx, lineSeperator) { + var result=""; + if (env.dumpLineNumbers && !env.compress) { + switch(env.dumpLineNumbers) { + case 'comments': + result = tree.debugInfo.asComment(ctx); + break; + case 'mediaquery': + result = tree.debugInfo.asMediaQuery(ctx); + break; + case 'all': + result = tree.debugInfo.asComment(ctx) + (lineSeperator || "") + tree.debugInfo.asMediaQuery(ctx); + break; + } + } + return result; +}; + +tree.debugInfo.asComment = function(ctx) { + return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n'; +}; + +tree.debugInfo.asMediaQuery = function(ctx) { + return '@media -sass-debug-info{filename{font-family:' + + ('file://' + ctx.debugInfo.fileName).replace(/([.:/\\])/g, function (a) { + if (a == '\\') { + a = '\/'; + } + return '\\' + a; + }) + + '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n'; +}; + +tree.find = function (obj, fun) { + for (var i = 0, r; i < obj.length; i++) { + r = fun.call(obj, obj[i]); + if (r) { return r; } + } + return null; +}; + +tree.jsify = function (obj) { + if (Array.isArray(obj.value) && (obj.value.length > 1)) { + return '[' + obj.value.map(function (v) { return v.toCSS(false); }).join(', ') + ']'; + } else { + return obj.toCSS(false); + } +}; + +tree.toCSS = function (env) { + var strs = []; + this.genCSS(env, { + add: function(chunk, fileInfo, index) { + strs.push(chunk); + }, + isEmpty: function () { + return strs.length === 0; + } + }); + return strs.join(''); +}; + +tree.outputRuleset = function (env, output, rules) { + var ruleCnt = rules.length, i; + env.tabLevel = (env.tabLevel | 0) + 1; + + // Compressed + if (env.compress) { + output.add('{'); + for (i = 0; i < ruleCnt; i++) { + rules[i].genCSS(env, output); + } + output.add('}'); + env.tabLevel--; + return; + } + + // Non-compressed + var tabSetStr = '\n' + Array(env.tabLevel).join(" "), tabRuleStr = tabSetStr + " "; + if (!ruleCnt) { + output.add(" {" + tabSetStr + '}'); + } else { + output.add(" {" + tabRuleStr); + rules[0].genCSS(env, output); + for (i = 1; i < ruleCnt; i++) { + output.add(tabRuleStr); + rules[i].genCSS(env, output); + } + output.add(tabSetStr + '}'); + } + + env.tabLevel--; +}; + +})(require('./tree')); + +(function (tree) { + +tree.Alpha = function (val) { + this.value = val; +}; +tree.Alpha.prototype = { + type: "Alpha", + accept: function (visitor) { + this.value = visitor.visit(this.value); + }, + eval: function (env) { + if (this.value.eval) { return new tree.Alpha(this.value.eval(env)); } + return this; + }, + genCSS: function (env, output) { + output.add("alpha(opacity="); + + if (this.value.genCSS) { + this.value.genCSS(env, output); + } else { + output.add(this.value); + } + + output.add(")"); + }, + toCSS: tree.toCSS +}; + +})(require('../tree')); + +(function (tree) { + +tree.Anonymous = function (string, index, currentFileInfo, mapLines) { + this.value = string.value || string; + this.index = index; + this.mapLines = mapLines; + this.currentFileInfo = currentFileInfo; +}; +tree.Anonymous.prototype = { + type: "Anonymous", + eval: function () { + return new tree.Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines); + }, + compare: function (x) { + if (!x.toCSS) { + return -1; + } + + var left = this.toCSS(), + right = x.toCSS(); + + if (left === right) { + return 0; + } + + return left < right ? -1 : 1; + }, + genCSS: function (env, output) { + output.add(this.value, this.currentFileInfo, this.index, this.mapLines); + }, + toCSS: tree.toCSS +}; + +})(require('../tree')); + +(function (tree) { + +tree.Assignment = function (key, val) { + this.key = key; + this.value = val; +}; +tree.Assignment.prototype = { + type: "Assignment", + accept: function (visitor) { + this.value = visitor.visit(this.value); + }, + eval: function (env) { + if (this.value.eval) { + return new(tree.Assignment)(this.key, this.value.eval(env)); + } + return this; + }, + genCSS: function (env, output) { + output.add(this.key + '='); + if (this.value.genCSS) { + this.value.genCSS(env, output); + } else { + output.add(this.value); + } + }, + toCSS: tree.toCSS +}; + +})(require('../tree')); + +(function (tree) { + +// +// A function call node. +// +tree.Call = function (name, args, index, currentFileInfo) { + this.name = name; + this.args = args; + this.index = index; + this.currentFileInfo = currentFileInfo; +}; +tree.Call.prototype = { + type: "Call", + accept: function (visitor) { + if (this.args) { + this.args = visitor.visitArray(this.args); + } + }, + // + // When evaluating a function call, + // we either find the function in `tree.functions` [1], + // in which case we call it, passing the evaluated arguments, + // if this returns null or we cannot find the function, we + // simply print it out as it appeared originally [2]. + // + // The *functions.js* file contains the built-in functions. + // + // The reason why we evaluate the arguments, is in the case where + // we try to pass a variable to a function, like: `saturate(@color)`. + // The function should receive the value, not the variable. + // + eval: function (env) { + var args = this.args.map(function (a) { return a.eval(env); }), + nameLC = this.name.toLowerCase(), + result, func; + + if (nameLC in tree.functions) { // 1. + try { + func = new tree.functionCall(env, this.currentFileInfo); + result = func[nameLC].apply(func, args); + if (result != null) { + return result; + } + } catch (e) { + throw { type: e.type || "Runtime", + message: "error evaluating function `" + this.name + "`" + + (e.message ? ': ' + e.message : ''), + index: this.index, filename: this.currentFileInfo.filename }; + } + } + + return new tree.Call(this.name, args, this.index, this.currentFileInfo); + }, + + genCSS: function (env, output) { + output.add(this.name + "(", this.currentFileInfo, this.index); + + for(var i = 0; i < this.args.length; i++) { + this.args[i].genCSS(env, output); + if (i + 1 < this.args.length) { + output.add(", "); + } + } + + output.add(")"); + }, + + toCSS: tree.toCSS +}; + +})(require('../tree')); + +(function (tree) { +// +// RGB Colors - #ff0014, #eee +// +tree.Color = function (rgb, a) { + // + // The end goal here, is to parse the arguments + // into an integer triplet, such as `128, 255, 0` + // + // This facilitates operations and conversions. + // + if (Array.isArray(rgb)) { + this.rgb = rgb; + } else if (rgb.length == 6) { + this.rgb = rgb.match(/.{2}/g).map(function (c) { + return parseInt(c, 16); + }); + } else { + this.rgb = rgb.split('').map(function (c) { + return parseInt(c + c, 16); + }); + } + this.alpha = typeof(a) === 'number' ? a : 1; +}; + +var transparentKeyword = "transparent"; + +tree.Color.prototype = { + type: "Color", + eval: function () { return this; }, + luma: function () { return (0.2126 * this.rgb[0] / 255) + (0.7152 * this.rgb[1] / 255) + (0.0722 * this.rgb[2] / 255); }, + + genCSS: function (env, output) { + output.add(this.toCSS(env)); + }, + toCSS: function (env, doNotCompress) { + var compress = env && env.compress && !doNotCompress; + + // If we have some transparency, the only way to represent it + // is via `rgba`. Otherwise, we use the hex representation, + // which has better compatibility with older browsers. + // Values are capped between `0` and `255`, rounded and zero-padded. + if (this.alpha < 1) { + if (this.alpha === 0 && this.isTransparentKeyword) { + return transparentKeyword; + } + return "rgba(" + this.rgb.map(function (c) { + return clamp(Math.round(c), 255); + }).concat(clamp(this.alpha, 1)) + .join(',' + (compress ? '' : ' ')) + ")"; + } else { + var color = this.toRGB(); + + if (compress) { + var splitcolor = color.split(''); + + // Convert color to short format + if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { + color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5]; + } + } + + return color; + } + }, + + // + // Operations have to be done per-channel, if not, + // channels will spill onto each other. Once we have + // our result, in the form of an integer triplet, + // we create a new Color node to hold the result. + // + operate: function (env, op, other) { + var rgb = []; + var alpha = this.alpha * (1 - other.alpha) + other.alpha; + for (var c = 0; c < 3; c++) { + rgb[c] = tree.operate(env, op, this.rgb[c], other.rgb[c]); + } + return new(tree.Color)(rgb, alpha); + }, + + toRGB: function () { + return toHex(this.rgb); + }, + + toHSL: function () { + var r = this.rgb[0] / 255, + g = this.rgb[1] / 255, + b = this.rgb[2] / 255, + a = this.alpha; + + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, l = (max + min) / 2, d = max - min; + + if (max === min) { + h = s = 0; + } else { + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + return { h: h * 360, s: s, l: l, a: a }; + }, + //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + toHSV: function () { + var r = this.rgb[0] / 255, + g = this.rgb[1] / 255, + b = this.rgb[2] / 255, + a = this.alpha; + + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, v = max; + + var d = max - min; + if (max === 0) { + s = 0; + } else { + s = d / max; + } + + if (max === min) { + h = 0; + } else { + switch(max){ + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + return { h: h * 360, s: s, v: v, a: a }; + }, + toARGB: function () { + return toHex([this.alpha * 255].concat(this.rgb)); + }, + compare: function (x) { + if (!x.rgb) { + return -1; + } + + return (x.rgb[0] === this.rgb[0] && + x.rgb[1] === this.rgb[1] && + x.rgb[2] === this.rgb[2] && + x.alpha === this.alpha) ? 0 : -1; + } +}; + +tree.Color.fromKeyword = function(keyword) { + if (tree.colors.hasOwnProperty(keyword)) { + // detect named color + return new(tree.Color)(tree.colors[keyword].slice(1)); + } + if (keyword === transparentKeyword) { + var transparent = new(tree.Color)([0, 0, 0], 0); + transparent.isTransparentKeyword = true; + return transparent; + } +}; + +function toHex(v) { + return '#' + v.map(function (c) { + c = clamp(Math.round(c), 255); + return (c < 16 ? '0' : '') + c.toString(16); + }).join(''); +} + +function clamp(v, max) { + return Math.min(Math.max(v, 0), max); +} + +})(require('../tree')); + +(function (tree) { + +tree.Comment = function (value, silent, index, currentFileInfo) { + this.value = value; + this.silent = !!silent; + this.currentFileInfo = currentFileInfo; +}; +tree.Comment.prototype = { + type: "Comment", + genCSS: function (env, output) { + if (this.debugInfo) { + output.add(tree.debugInfo(env, this), this.currentFileInfo, this.index); + } + output.add(this.value.trim()); //TODO shouldn't need to trim, we shouldn't grab the \n + }, + toCSS: tree.toCSS, + isSilent: function(env) { + var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced), + isCompressed = env.compress && !this.value.match(/^\/\*!/); + return this.silent || isReference || isCompressed; + }, + eval: function () { return this; }, + markReferenced: function () { + this.isReferenced = true; + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Condition = function (op, l, r, i, negate) { + this.op = op.trim(); + this.lvalue = l; + this.rvalue = r; + this.index = i; + this.negate = negate; +}; +tree.Condition.prototype = { + type: "Condition", + accept: function (visitor) { + this.lvalue = visitor.visit(this.lvalue); + this.rvalue = visitor.visit(this.rvalue); + }, + eval: function (env) { + var a = this.lvalue.eval(env), + b = this.rvalue.eval(env); + + var i = this.index, result; + + result = (function (op) { + switch (op) { + case 'and': + return a && b; + case 'or': + return a || b; + default: + if (a.compare) { + result = a.compare(b); + } else if (b.compare) { + result = b.compare(a); + } else { + throw { type: "Type", + message: "Unable to perform comparison", + index: i }; + } + switch (result) { + case -1: return op === '<' || op === '=<' || op === '<='; + case 0: return op === '=' || op === '>=' || op === '=<' || op === '<='; + case 1: return op === '>' || op === '>='; + } + } + })(this.op); + return this.negate ? !result : result; + } +}; + +})(require('../tree')); + +(function (tree) { + +// +// A number with a unit +// +tree.Dimension = function (value, unit) { + this.value = parseFloat(value); + this.unit = (unit && unit instanceof tree.Unit) ? unit : + new(tree.Unit)(unit ? [unit] : undefined); +}; + +tree.Dimension.prototype = { + type: "Dimension", + accept: function (visitor) { + this.unit = visitor.visit(this.unit); + }, + eval: function (env) { + return this; + }, + toColor: function () { + return new(tree.Color)([this.value, this.value, this.value]); + }, + genCSS: function (env, output) { + if ((env && env.strictUnits) && !this.unit.isSingular()) { + throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString()); + } + + var value = this.value, + strValue = String(value); + + if (value !== 0 && value < 0.000001 && value > -0.000001) { + // would be output 1e-6 etc. + strValue = value.toFixed(20).replace(/0+$/, ""); + } + + if (env && env.compress) { + // Zero values doesn't need a unit + if (value === 0 && this.unit.isLength()) { + output.add(strValue); + return; + } + + // Float values doesn't need a leading zero + if (value > 0 && value < 1) { + strValue = (strValue).substr(1); + } + } + + output.add(strValue); + this.unit.genCSS(env, output); + }, + toCSS: tree.toCSS, + + // In an operation between two Dimensions, + // we default to the first Dimension's unit, + // so `1px + 2` will yield `3px`. + operate: function (env, op, other) { + /*jshint noempty:false */ + var value = tree.operate(env, op, this.value, other.value), + unit = this.unit.clone(); + + if (op === '+' || op === '-') { + if (unit.numerator.length === 0 && unit.denominator.length === 0) { + unit.numerator = other.unit.numerator.slice(0); + unit.denominator = other.unit.denominator.slice(0); + } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) { + // do nothing + } else { + other = other.convertTo(this.unit.usedUnits()); + + if(env.strictUnits && other.unit.toString() !== unit.toString()) { + throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() + + "' and '" + other.unit.toString() + "'."); + } + + value = tree.operate(env, op, this.value, other.value); + } + } else if (op === '*') { + unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); + unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); + unit.cancel(); + } else if (op === '/') { + unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); + unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); + unit.cancel(); + } + return new(tree.Dimension)(value, unit); + }, + + compare: function (other) { + if (other instanceof tree.Dimension) { + var a = this.unify(), b = other.unify(), + aValue = a.value, bValue = b.value; + + if (bValue > aValue) { + return -1; + } else if (bValue < aValue) { + return 1; + } else { + if (!b.unit.isEmpty() && a.unit.compare(b.unit) !== 0) { + return -1; + } + return 0; + } + } else { + return -1; + } + }, + + unify: function () { + return this.convertTo({ length: 'm', duration: 's', angle: 'rad' }); + }, + + convertTo: function (conversions) { + var value = this.value, unit = this.unit.clone(), + i, groupName, group, targetUnit, derivedConversions = {}, applyUnit; + + if (typeof conversions === 'string') { + for(i in tree.UnitConversions) { + if (tree.UnitConversions[i].hasOwnProperty(conversions)) { + derivedConversions = {}; + derivedConversions[i] = conversions; + } + } + conversions = derivedConversions; + } + applyUnit = function (atomicUnit, denominator) { + /*jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit)) { + if (denominator) { + value = value / (group[atomicUnit] / group[targetUnit]); + } else { + value = value * (group[atomicUnit] / group[targetUnit]); + } + + return targetUnit; + } + + return atomicUnit; + }; + + for (groupName in conversions) { + if (conversions.hasOwnProperty(groupName)) { + targetUnit = conversions[groupName]; + group = tree.UnitConversions[groupName]; + + unit.map(applyUnit); + } + } + + unit.cancel(); + + return new(tree.Dimension)(value, unit); + } +}; + +// http://www.w3.org/TR/css3-values/#absolute-lengths +tree.UnitConversions = { + length: { + 'm': 1, + 'cm': 0.01, + 'mm': 0.001, + 'in': 0.0254, + 'pt': 0.0254 / 72, + 'pc': 0.0254 / 72 * 12 + }, + duration: { + 's': 1, + 'ms': 0.001 + }, + angle: { + 'rad': 1/(2*Math.PI), + 'deg': 1/360, + 'grad': 1/400, + 'turn': 1 + } +}; + +tree.Unit = function (numerator, denominator, backupUnit) { + this.numerator = numerator ? numerator.slice(0).sort() : []; + this.denominator = denominator ? denominator.slice(0).sort() : []; + this.backupUnit = backupUnit; +}; + +tree.Unit.prototype = { + type: "Unit", + clone: function () { + return new tree.Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit); + }, + genCSS: function (env, output) { + if (this.numerator.length >= 1) { + output.add(this.numerator[0]); + } else + if (this.denominator.length >= 1) { + output.add(this.denominator[0]); + } else + if ((!env || !env.strictUnits) && this.backupUnit) { + output.add(this.backupUnit); + } + }, + toCSS: tree.toCSS, + + toString: function () { + var i, returnStr = this.numerator.join("*"); + for (i = 0; i < this.denominator.length; i++) { + returnStr += "/" + this.denominator[i]; + } + return returnStr; + }, + + compare: function (other) { + return this.is(other.toString()) ? 0 : -1; + }, + + is: function (unitString) { + return this.toString() === unitString; + }, + + isLength: function () { + return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/)); + }, + + isEmpty: function () { + return this.numerator.length === 0 && this.denominator.length === 0; + }, + + isSingular: function() { + return this.numerator.length <= 1 && this.denominator.length === 0; + }, + + map: function(callback) { + var i; + + for (i = 0; i < this.numerator.length; i++) { + this.numerator[i] = callback(this.numerator[i], false); + } + + for (i = 0; i < this.denominator.length; i++) { + this.denominator[i] = callback(this.denominator[i], true); + } + }, + + usedUnits: function() { + var group, result = {}, mapUnit; + + mapUnit = function (atomicUnit) { + /*jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { + result[groupName] = atomicUnit; + } + + return atomicUnit; + }; + + for (var groupName in tree.UnitConversions) { + if (tree.UnitConversions.hasOwnProperty(groupName)) { + group = tree.UnitConversions[groupName]; + + this.map(mapUnit); + } + } + + return result; + }, + + cancel: function () { + var counter = {}, atomicUnit, i, backup; + + for (i = 0; i < this.numerator.length; i++) { + atomicUnit = this.numerator[i]; + if (!backup) { + backup = atomicUnit; + } + counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; + } + + for (i = 0; i < this.denominator.length; i++) { + atomicUnit = this.denominator[i]; + if (!backup) { + backup = atomicUnit; + } + counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; + } + + this.numerator = []; + this.denominator = []; + + for (atomicUnit in counter) { + if (counter.hasOwnProperty(atomicUnit)) { + var count = counter[atomicUnit]; + + if (count > 0) { + for (i = 0; i < count; i++) { + this.numerator.push(atomicUnit); + } + } else if (count < 0) { + for (i = 0; i < -count; i++) { + this.denominator.push(atomicUnit); + } + } + } + } + + if (this.numerator.length === 0 && this.denominator.length === 0 && backup) { + this.backupUnit = backup; + } + + this.numerator.sort(); + this.denominator.sort(); + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Directive = function (name, value, index, currentFileInfo) { + this.name = name; + + if (Array.isArray(value)) { + this.rules = [new(tree.Ruleset)(null, value)]; + this.rules[0].allowImports = true; + } else { + this.value = value; + } + this.currentFileInfo = currentFileInfo; + +}; +tree.Directive.prototype = { + type: "Directive", + accept: function (visitor) { + if (this.rules) { + this.rules = visitor.visitArray(this.rules); + } + if (this.value) { + this.value = visitor.visit(this.value); + } + }, + genCSS: function (env, output) { + output.add(this.name, this.currentFileInfo, this.index); + if (this.rules) { + tree.outputRuleset(env, output, this.rules); + } else { + output.add(' '); + this.value.genCSS(env, output); + output.add(';'); + } + }, + toCSS: tree.toCSS, + eval: function (env) { + var evaldDirective = this; + if (this.rules) { + env.frames.unshift(this); + evaldDirective = new(tree.Directive)(this.name, null, this.index, this.currentFileInfo); + evaldDirective.rules = [this.rules[0].eval(env)]; + evaldDirective.rules[0].root = true; + env.frames.shift(); + } + return evaldDirective; + }, + variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, + find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, + rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, + markReferenced: function () { + var i, rules; + this.isReferenced = true; + if (this.rules) { + rules = this.rules[0].rules; + for (i = 0; i < rules.length; i++) { + if (rules[i].markReferenced) { + rules[i].markReferenced(); + } + } + } + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Element = function (combinator, value, index, currentFileInfo) { + this.combinator = combinator instanceof tree.Combinator ? + combinator : new(tree.Combinator)(combinator); + + if (typeof(value) === 'string') { + this.value = value.trim(); + } else if (value) { + this.value = value; + } else { + this.value = ""; + } + this.index = index; + this.currentFileInfo = currentFileInfo; +}; +tree.Element.prototype = { + type: "Element", + accept: function (visitor) { + var value = this.value; + this.combinator = visitor.visit(this.combinator); + if (typeof value === "object") { + this.value = visitor.visit(value); + } + }, + eval: function (env) { + return new(tree.Element)(this.combinator, + this.value.eval ? this.value.eval(env) : this.value, + this.index, + this.currentFileInfo); + }, + genCSS: function (env, output) { + output.add(this.toCSS(env), this.currentFileInfo, this.index); + }, + toCSS: function (env) { + var value = (this.value.toCSS ? this.value.toCSS(env) : this.value); + if (value === '' && this.combinator.value.charAt(0) === '&') { + return ''; + } else { + return this.combinator.toCSS(env || {}) + value; + } + } +}; + +tree.Attribute = function (key, op, value) { + this.key = key; + this.op = op; + this.value = value; +}; +tree.Attribute.prototype = { + type: "Attribute", + eval: function (env) { + return new(tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key, + this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value); + }, + genCSS: function (env, output) { + output.add(this.toCSS(env)); + }, + toCSS: function (env) { + var value = this.key.toCSS ? this.key.toCSS(env) : this.key; + + if (this.op) { + value += this.op; + value += (this.value.toCSS ? this.value.toCSS(env) : this.value); + } + + return '[' + value + ']'; + } +}; + +tree.Combinator = function (value) { + if (value === ' ') { + this.value = ' '; + } else { + this.value = value ? value.trim() : ""; + } +}; +tree.Combinator.prototype = { + type: "Combinator", + _outputMap: { + '' : '', + ' ' : ' ', + ':' : ' :', + '+' : ' + ', + '~' : ' ~ ', + '>' : ' > ', + '|' : '|' + }, + _outputMapCompressed: { + '' : '', + ' ' : ' ', + ':' : ' :', + '+' : '+', + '~' : '~', + '>' : '>', + '|' : '|' + }, + genCSS: function (env, output) { + output.add((env.compress ? this._outputMapCompressed : this._outputMap)[this.value]); + }, + toCSS: tree.toCSS +}; + +})(require('../tree')); + +(function (tree) { + +tree.Expression = function (value) { this.value = value; }; +tree.Expression.prototype = { + type: "Expression", + accept: function (visitor) { + if (this.value) { + this.value = visitor.visitArray(this.value); + } + }, + eval: function (env) { + var returnValue, + inParenthesis = this.parens && !this.parensInOp, + doubleParen = false; + if (inParenthesis) { + env.inParenthesis(); + } + if (this.value.length > 1) { + returnValue = new(tree.Expression)(this.value.map(function (e) { + return e.eval(env); + })); + } else if (this.value.length === 1) { + if (this.value[0].parens && !this.value[0].parensInOp) { + doubleParen = true; + } + returnValue = this.value[0].eval(env); + } else { + returnValue = this; + } + if (inParenthesis) { + env.outOfParenthesis(); + } + if (this.parens && this.parensInOp && !(env.isMathOn()) && !doubleParen) { + returnValue = new(tree.Paren)(returnValue); + } + return returnValue; + }, + genCSS: function (env, output) { + for(var i = 0; i < this.value.length; i++) { + this.value[i].genCSS(env, output); + if (i + 1 < this.value.length) { + output.add(" "); + } + } + }, + toCSS: tree.toCSS, + throwAwayComments: function () { + this.value = this.value.filter(function(v) { + return !(v instanceof tree.Comment); + }); + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Extend = function Extend(selector, option, index) { + this.selector = selector; + this.option = option; + this.index = index; + this.object_id = tree.Extend.next_id++; + this.parent_ids = [this.object_id]; + + switch(option) { + case "all": + this.allowBefore = true; + this.allowAfter = true; + break; + default: + this.allowBefore = false; + this.allowAfter = false; + break; + } +}; +tree.Extend.next_id = 0; + +tree.Extend.prototype = { + type: "Extend", + accept: function (visitor) { + this.selector = visitor.visit(this.selector); + }, + eval: function (env) { + return new(tree.Extend)(this.selector.eval(env), this.option, this.index); + }, + clone: function (env) { + return new(tree.Extend)(this.selector, this.option, this.index); + }, + findSelfSelectors: function (selectors) { + var selfElements = [], + i, + selectorElements; + + for(i = 0; i < selectors.length; i++) { + selectorElements = selectors[i].elements; + // duplicate the logic in genCSS function inside the selector node. + // future TODO - move both logics into the selector joiner visitor + if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") { + selectorElements[0].combinator.value = ' '; + } + selfElements = selfElements.concat(selectors[i].elements); + } + + this.selfSelectors = [{ elements: selfElements }]; + } +}; + +})(require('../tree')); + +(function (tree) { +// +// CSS @import node +// +// The general strategy here is that we don't want to wait +// for the parsing to be completed, before we start importing +// the file. That's because in the context of a browser, +// most of the time will be spent waiting for the server to respond. +// +// On creation, we push the import path to our import queue, though +// `import,push`, we also pass it a callback, which it'll call once +// the file has been fetched, and parsed. +// +tree.Import = function (path, features, options, index, currentFileInfo) { + this.options = options; + this.index = index; + this.path = path; + this.features = features; + this.currentFileInfo = currentFileInfo; + + if (this.options.less !== undefined || this.options.inline) { + this.css = !this.options.less || this.options.inline; + } else { + var pathValue = this.getPath(); + if (pathValue && /css([\?;].*)?$/.test(pathValue)) { + this.css = true; + } + } +}; + +// +// The actual import node doesn't return anything, when converted to CSS. +// The reason is that it's used at the evaluation stage, so that the rules +// it imports can be treated like any other rules. +// +// In `eval`, we make sure all Import nodes get evaluated, recursively, so +// we end up with a flat structure, which can easily be imported in the parent +// ruleset. +// +tree.Import.prototype = { + type: "Import", + accept: function (visitor) { + if (this.features) { + this.features = visitor.visit(this.features); + } + this.path = visitor.visit(this.path); + if (!this.options.inline && this.root) { + this.root = visitor.visit(this.root); + } + }, + genCSS: function (env, output) { + if (this.css) { + output.add("@import ", this.currentFileInfo, this.index); + this.path.genCSS(env, output); + if (this.features) { + output.add(" "); + this.features.genCSS(env, output); + } + output.add(';'); + } + }, + toCSS: tree.toCSS, + getPath: function () { + if (this.path instanceof tree.Quoted) { + var path = this.path.value; + return (this.css !== undefined || /(\.[a-z]*$)|([\?;].*)$/.test(path)) ? path : path + '.less'; + } else if (this.path instanceof tree.URL) { + return this.path.value.value; + } + return null; + }, + evalForImport: function (env) { + return new(tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo); + }, + evalPath: function (env) { + var path = this.path.eval(env); + var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; + + if (!(path instanceof tree.URL)) { + if (rootpath) { + var pathValue = path.value; + // Add the base path if the import is relative + if (pathValue && env.isPathRelative(pathValue)) { + path.value = rootpath + pathValue; + } + } + path.value = env.normalizePath(path.value); + } + + return path; + }, + eval: function (env) { + var ruleset, features = this.features && this.features.eval(env); + + if (this.skip) { return []; } + + if (this.options.inline) { + //todo needs to reference css file not import + var contents = new(tree.Anonymous)(this.root, 0, {filename: this.importedFilename}, true); + return this.features ? new(tree.Media)([contents], this.features.value) : [contents]; + } else if (this.css) { + var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index); + if (!newImport.css && this.error) { + throw this.error; + } + return newImport; + } else { + ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0)); + + ruleset.evalImports(env); + + return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules; + } + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.JavaScript = function (string, index, escaped) { + this.escaped = escaped; + this.expression = string; + this.index = index; +}; +tree.JavaScript.prototype = { + type: "JavaScript", + eval: function (env) { + var result, + that = this, + context = {}; + + var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) { + return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env)); + }); + + try { + expression = new(Function)('return (' + expression + ')'); + } catch (e) { + throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" , + index: this.index }; + } + + for (var k in env.frames[0].variables()) { + /*jshint loopfunc:true */ + context[k.slice(1)] = { + value: env.frames[0].variables()[k].value, + toJS: function () { + return this.value.eval(env).toCSS(); + } + }; + } + + try { + result = expression.call(context); + } catch (e) { + throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" , + index: this.index }; + } + if (typeof(result) === 'number') { + return new(tree.Dimension)(result); + } else if (typeof(result) === 'string') { + return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index); + } else if (Array.isArray(result)) { + return new(tree.Anonymous)(result.join(', ')); + } else { + return new(tree.Anonymous)(result); + } + } +}; + +})(require('../tree')); + + +(function (tree) { + +tree.Keyword = function (value) { this.value = value; }; +tree.Keyword.prototype = { + type: "Keyword", + eval: function () { return this; }, + genCSS: function (env, output) { + output.add(this.value); + }, + toCSS: tree.toCSS, + compare: function (other) { + if (other instanceof tree.Keyword) { + return other.value === this.value ? 0 : 1; + } else { + return -1; + } + } +}; + +tree.True = new(tree.Keyword)('true'); +tree.False = new(tree.Keyword)('false'); + +})(require('../tree')); + +(function (tree) { + +tree.Media = function (value, features, index, currentFileInfo) { + this.index = index; + this.currentFileInfo = currentFileInfo; + + var selectors = this.emptySelectors(); + + this.features = new(tree.Value)(features); + this.rules = [new(tree.Ruleset)(selectors, value)]; + this.rules[0].allowImports = true; +}; +tree.Media.prototype = { + type: "Media", + accept: function (visitor) { + if (this.features) { + this.features = visitor.visit(this.features); + } + if (this.rules) { + this.rules = visitor.visitArray(this.rules); + } + }, + genCSS: function (env, output) { + output.add('@media ', this.currentFileInfo, this.index); + this.features.genCSS(env, output); + tree.outputRuleset(env, output, this.rules); + }, + toCSS: tree.toCSS, + eval: function (env) { + if (!env.mediaBlocks) { + env.mediaBlocks = []; + env.mediaPath = []; + } + + var media = new(tree.Media)(null, [], this.index, this.currentFileInfo); + if(this.debugInfo) { + this.rules[0].debugInfo = this.debugInfo; + media.debugInfo = this.debugInfo; + } + var strictMathBypass = false; + if (!env.strictMath) { + strictMathBypass = true; + env.strictMath = true; + } + try { + media.features = this.features.eval(env); + } + finally { + if (strictMathBypass) { + env.strictMath = false; + } + } + + env.mediaPath.push(media); + env.mediaBlocks.push(media); + + env.frames.unshift(this.rules[0]); + media.rules = [this.rules[0].eval(env)]; + env.frames.shift(); + + env.mediaPath.pop(); + + return env.mediaPath.length === 0 ? media.evalTop(env) : + media.evalNested(env); + }, + variable: function (name) { return tree.Ruleset.prototype.variable.call(this.rules[0], name); }, + find: function () { return tree.Ruleset.prototype.find.apply(this.rules[0], arguments); }, + rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.rules[0]); }, + emptySelectors: function() { + var el = new(tree.Element)('', '&', this.index, this.currentFileInfo); + return [new(tree.Selector)([el], null, null, this.index, this.currentFileInfo)]; + }, + markReferenced: function () { + var i, rules = this.rules[0].rules; + this.isReferenced = true; + for (i = 0; i < rules.length; i++) { + if (rules[i].markReferenced) { + rules[i].markReferenced(); + } + } + }, + + evalTop: function (env) { + var result = this; + + // Render all dependent Media blocks. + if (env.mediaBlocks.length > 1) { + var selectors = this.emptySelectors(); + result = new(tree.Ruleset)(selectors, env.mediaBlocks); + result.multiMedia = true; + } + + delete env.mediaBlocks; + delete env.mediaPath; + + return result; + }, + evalNested: function (env) { + var i, value, + path = env.mediaPath.concat([this]); + + // Extract the media-query conditions separated with `,` (OR). + for (i = 0; i < path.length; i++) { + value = path[i].features instanceof tree.Value ? + path[i].features.value : path[i].features; + path[i] = Array.isArray(value) ? value : [value]; + } + + // Trace all permutations to generate the resulting media-query. + // + // (a, b and c) with nested (d, e) -> + // a and d + // a and e + // b and c and d + // b and c and e + this.features = new(tree.Value)(this.permute(path).map(function (path) { + path = path.map(function (fragment) { + return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment); + }); + + for(i = path.length - 1; i > 0; i--) { + path.splice(i, 0, new(tree.Anonymous)("and")); + } + + return new(tree.Expression)(path); + })); + + // Fake a tree-node that doesn't output anything. + return new(tree.Ruleset)([], []); + }, + permute: function (arr) { + if (arr.length === 0) { + return []; + } else if (arr.length === 1) { + return arr[0]; + } else { + var result = []; + var rest = this.permute(arr.slice(1)); + for (var i = 0; i < rest.length; i++) { + for (var j = 0; j < arr[0].length; j++) { + result.push([arr[0][j]].concat(rest[i])); + } + } + return result; + } + }, + bubbleSelectors: function (selectors) { + this.rules = [new(tree.Ruleset)(selectors.slice(0), [this.rules[0]])]; + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.mixin = {}; +tree.mixin.Call = function (elements, args, index, currentFileInfo, important) { + this.selector = new(tree.Selector)(elements); + this.arguments = (args && args.length) ? args : null; + this.index = index; + this.currentFileInfo = currentFileInfo; + this.important = important; +}; +tree.mixin.Call.prototype = { + type: "MixinCall", + accept: function (visitor) { + if (this.selector) { + this.selector = visitor.visit(this.selector); + } + if (this.arguments) { + this.arguments = visitor.visitArray(this.arguments); + } + }, + eval: function (env) { + var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule; + var candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc, defaultUsed = false; + + args = this.arguments && this.arguments.map(function (a) { + return { name: a.name, value: a.value.eval(env) }; + }); + + for (i = 0; i < env.frames.length; i++) { + if ((mixins = env.frames[i].find(this.selector)).length > 0) { + isOneFound = true; + + // To make `default()` function independent of definition order we have two "subpasses" here. + // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), + // and build candidate list with corresponding flags. Then, when we know all possible matches, + // we make a final decision. + + for (m = 0; m < mixins.length; m++) { + mixin = mixins[m]; + isRecursive = false; + for(f = 0; f < env.frames.length; f++) { + if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) { + isRecursive = true; + break; + } + } + if (isRecursive) { + continue; + } + + if (mixin.matchArgs(args, env)) { + candidate = {mixin: mixin}; + + if (mixin.matchCondition) { + for (f = 0; f < 2; f++) { + defaultFunc.value(f); + conditionResult[f] = mixin.matchCondition(args, env); + } + if (conditionResult[0] || conditionResult[1]) { + if (conditionResult[0] != conditionResult[1]) { + if (defaultUsed) { + // todo: ideally, it would make sense to also print the candidate + // mixin definitions that cause the conflict (current one and the + // mixin that set defaultUsed flag). But is there any easy method + // to get their filename/line/index info here? + throw { type: 'Runtime', + message: 'Ambiguous use of `default()` found when matching for `' + + this.format(args) + '`', + index: this.index, filename: this.currentFileInfo.filename }; + } + + defaultUsed = true; + candidate.matchIfDefault = true; + candidate.matchIfDefaultValue = conditionResult[1]; + } + + candidates.push(candidate); + } + } + else { + candidates.push(candidate); + } + + match = true; + } + } + + defaultFunc.reset(); + + for (m in candidates) { + candidate = candidates[m]; + if (!candidate.matchIfDefault || (candidate.matchIfDefaultValue == (candidates.length == 1))) { + try { + mixin = candidate.mixin; + if (!(mixin instanceof tree.mixin.Definition)) { + mixin = new tree.mixin.Definition("", [], mixin.rules, null, false); + mixin.originalRuleset = mixins[m].originalRuleset || mixins[m]; + } + //if (this.important) { + // isImportant = env.isImportant; + // env.isImportant = true; + //} + Array.prototype.push.apply( + rules, mixin.eval(env, args, this.important).rules); + //if (this.important) { + // env.isImportant = isImportant; + //} + } catch (e) { + throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack }; + } + } + } + + if (match) { + if (!this.currentFileInfo || !this.currentFileInfo.reference) { + for (i = 0; i < rules.length; i++) { + rule = rules[i]; + if (rule.markReferenced) { + rule.markReferenced(); + } + } + } + return rules; + } + } + } + if (isOneFound) { + throw { type: 'Runtime', + message: 'No matching definition was found for `' + this.format(args) + '`', + index: this.index, filename: this.currentFileInfo.filename }; + } else { + throw { type: 'Name', + message: this.selector.toCSS().trim() + " is undefined", + index: this.index, filename: this.currentFileInfo.filename }; + } + }, + format: function (args) { + return this.selector.toCSS().trim() + '(' + + (args ? args.map(function (a) { + var argValue = ""; + if (a.name) { + argValue += a.name + ":"; + } + if (a.value.toCSS) { + argValue += a.value.toCSS(); + } else { + argValue += "???"; + } + return argValue; + }).join(', ') : "") + ")"; + } +}; + +tree.mixin.Definition = function (name, params, rules, condition, variadic) { + this.name = name; + this.selectors = [new(tree.Selector)([new(tree.Element)(null, name, this.index, this.currentFileInfo)])]; + this.params = params; + this.condition = condition; + this.variadic = variadic; + this.arity = params.length; + this.rules = rules; + this._lookups = {}; + this.required = params.reduce(function (count, p) { + if (!p.name || (p.name && !p.value)) { return count + 1; } + else { return count; } + }, 0); + this.parent = tree.Ruleset.prototype; + this.frames = []; +}; +tree.mixin.Definition.prototype = { + type: "MixinDefinition", + accept: function (visitor) { + if (this.params && this.params.length) { + this.params = visitor.visitArray(this.params); + } + this.rules = visitor.visitArray(this.rules); + if (this.condition) { + this.condition = visitor.visit(this.condition); + } + }, + variable: function (name) { return this.parent.variable.call(this, name); }, + variables: function () { return this.parent.variables.call(this); }, + find: function () { return this.parent.find.apply(this, arguments); }, + rulesets: function () { return this.parent.rulesets.apply(this); }, + + evalParams: function (env, mixinEnv, args, evaldArguments) { + /*jshint boss:true */ + var frame = new(tree.Ruleset)(null, null), + varargs, arg, + params = this.params.slice(0), + i, j, val, name, isNamedFound, argIndex; + + mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames)); + + if (args) { + args = args.slice(0); + + for(i = 0; i < args.length; i++) { + arg = args[i]; + if (name = (arg && arg.name)) { + isNamedFound = false; + for(j = 0; j < params.length; j++) { + if (!evaldArguments[j] && name === params[j].name) { + evaldArguments[j] = arg.value.eval(env); + frame.prependRule(new(tree.Rule)(name, arg.value.eval(env))); + isNamedFound = true; + break; + } + } + if (isNamedFound) { + args.splice(i, 1); + i--; + continue; + } else { + throw { type: 'Runtime', message: "Named argument for " + this.name + + ' ' + args[i].name + ' not found' }; + } + } + } + } + argIndex = 0; + for (i = 0; i < params.length; i++) { + if (evaldArguments[i]) { continue; } + + arg = args && args[argIndex]; + + if (name = params[i].name) { + if (params[i].variadic && args) { + varargs = []; + for (j = argIndex; j < args.length; j++) { + varargs.push(args[j].value.eval(env)); + } + frame.prependRule(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env))); + } else { + val = arg && arg.value; + if (val) { + val = val.eval(env); + } else if (params[i].value) { + val = params[i].value.eval(mixinEnv); + frame.resetCache(); + } else { + throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + + ' (' + args.length + ' for ' + this.arity + ')' }; + } + + frame.prependRule(new(tree.Rule)(name, val)); + evaldArguments[i] = val; + } + } + + if (params[i].variadic && args) { + for (j = argIndex; j < args.length; j++) { + evaldArguments[j] = args[j].value.eval(env); + } + } + argIndex++; + } + + return frame; + }, + eval: function (env, args, important) { + var _arguments = [], + mixinFrames = this.frames.concat(env.frames), + frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments), + rules, ruleset; + + frame.prependRule(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env))); + + rules = this.rules.slice(0); + + ruleset = new(tree.Ruleset)(null, rules); + ruleset.originalRuleset = this; + ruleset = ruleset.eval(new(tree.evalEnv)(env, [this, frame].concat(mixinFrames))); + if (important) { + ruleset = this.parent.makeImportant.apply(ruleset); + } + return ruleset; + }, + matchCondition: function (args, env) { + if (this.condition && !this.condition.eval( + new(tree.evalEnv)(env, + [this.evalParams(env, new(tree.evalEnv)(env, this.frames.concat(env.frames)), args, [])] // the parameter variables + .concat(this.frames) // the parent namespace/mixin frames + .concat(env.frames)))) { // the current environment frames + return false; + } + return true; + }, + matchArgs: function (args, env) { + var argsLength = (args && args.length) || 0, len; + + if (! this.variadic) { + if (argsLength < this.required) { return false; } + if (argsLength > this.params.length) { return false; } + } else { + if (argsLength < (this.required - 1)) { return false; } + } + + len = Math.min(argsLength, this.arity); + + for (var i = 0; i < len; i++) { + if (!this.params[i].name && !this.params[i].variadic) { + if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) { + return false; + } + } + } + return true; + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Negative = function (node) { + this.value = node; +}; +tree.Negative.prototype = { + type: "Negative", + accept: function (visitor) { + this.value = visitor.visit(this.value); + }, + genCSS: function (env, output) { + output.add('-'); + this.value.genCSS(env, output); + }, + toCSS: tree.toCSS, + eval: function (env) { + if (env.isMathOn()) { + return (new(tree.Operation)('*', [new(tree.Dimension)(-1), this.value])).eval(env); + } + return new(tree.Negative)(this.value.eval(env)); + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Operation = function (op, operands, isSpaced) { + this.op = op.trim(); + this.operands = operands; + this.isSpaced = isSpaced; +}; +tree.Operation.prototype = { + type: "Operation", + accept: function (visitor) { + this.operands = visitor.visit(this.operands); + }, + eval: function (env) { + var a = this.operands[0].eval(env), + b = this.operands[1].eval(env); + + if (env.isMathOn()) { + if (a instanceof tree.Dimension && b instanceof tree.Color) { + a = a.toColor(); + } + if (b instanceof tree.Dimension && a instanceof tree.Color) { + b = b.toColor(); + } + if (!a.operate) { + throw { type: "Operation", + message: "Operation on an invalid type" }; + } + + return a.operate(env, this.op, b); + } else { + return new(tree.Operation)(this.op, [a, b], this.isSpaced); + } + }, + genCSS: function (env, output) { + this.operands[0].genCSS(env, output); + if (this.isSpaced) { + output.add(" "); + } + output.add(this.op); + if (this.isSpaced) { + output.add(" "); + } + this.operands[1].genCSS(env, output); + }, + toCSS: tree.toCSS +}; + +tree.operate = function (env, op, a, b) { + switch (op) { + case '+': return a + b; + case '-': return a - b; + case '*': return a * b; + case '/': return a / b; + } +}; + +})(require('../tree')); + + +(function (tree) { + +tree.Paren = function (node) { + this.value = node; +}; +tree.Paren.prototype = { + type: "Paren", + accept: function (visitor) { + this.value = visitor.visit(this.value); + }, + genCSS: function (env, output) { + output.add('('); + this.value.genCSS(env, output); + output.add(')'); + }, + toCSS: tree.toCSS, + eval: function (env) { + return new(tree.Paren)(this.value.eval(env)); + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Quoted = function (str, content, escaped, index, currentFileInfo) { + this.escaped = escaped; + this.value = content || ''; + this.quote = str.charAt(0); + this.index = index; + this.currentFileInfo = currentFileInfo; +}; +tree.Quoted.prototype = { + type: "Quoted", + genCSS: function (env, output) { + if (!this.escaped) { + output.add(this.quote, this.currentFileInfo, this.index); + } + output.add(this.value); + if (!this.escaped) { + output.add(this.quote); + } + }, + toCSS: tree.toCSS, + eval: function (env) { + var that = this; + var value = this.value.replace(/`([^`]+)`/g, function (_, exp) { + return new(tree.JavaScript)(exp, that.index, true).eval(env).value; + }).replace(/@\{([\w-]+)\}/g, function (_, name) { + var v = new(tree.Variable)('@' + name, that.index, that.currentFileInfo).eval(env, true); + return (v instanceof tree.Quoted) ? v.value : v.toCSS(); + }); + return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo); + }, + compare: function (x) { + if (!x.toCSS) { + return -1; + } + + var left = this.toCSS(), + right = x.toCSS(); + + if (left === right) { + return 0; + } + + return left < right ? -1 : 1; + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Rule = function (name, value, important, merge, index, currentFileInfo, inline) { + this.name = name; + this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]); + this.important = important ? ' ' + important.trim() : ''; + this.merge = merge; + this.index = index; + this.currentFileInfo = currentFileInfo; + this.inline = inline || false; + this.variable = name.charAt && (name.charAt(0) === '@'); +}; + +tree.Rule.prototype = { + type: "Rule", + accept: function (visitor) { + this.value = visitor.visit(this.value); + }, + genCSS: function (env, output) { + output.add(this.name + (env.compress ? ':' : ': '), this.currentFileInfo, this.index); + try { + this.value.genCSS(env, output); + } + catch(e) { + e.index = this.index; + e.filename = this.currentFileInfo.filename; + throw e; + } + output.add(this.important + ((this.inline || (env.lastRule && env.compress)) ? "" : ";"), this.currentFileInfo, this.index); + }, + toCSS: tree.toCSS, + eval: function (env) { + var strictMathBypass = false; + var name = this.name.map ? + this.name.map( function(v) { + return v.eval ? v.eval(env).value : v; + }).join('') : this.name; + if (name === "font" && !env.strictMath) { + strictMathBypass = true; + env.strictMath = true; + } + try { + return new(tree.Rule)(name, + this.value.eval(env), + this.important, + this.merge, + this.index, this.currentFileInfo, this.inline); + } + catch(e) { + if (e.index === undefined) { + e.index = this.index; + } + throw e; + } + finally { + if (strictMathBypass) { + env.strictMath = false; + } + } + }, + makeImportant: function () { + return new(tree.Rule)(this.name, + this.value, + "!important", + this.merge, + this.index, this.currentFileInfo, this.inline); + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Ruleset = function (selectors, rules, strictImports) { + this.selectors = selectors; + this.rules = rules; + this._lookups = {}; + this.strictImports = strictImports; +}; +tree.Ruleset.prototype = { + type: "Ruleset", + accept: function (visitor) { + if (this.paths) { + visitor.visitArray(this.paths, true); + } else if (this.selectors) { + this.selectors = visitor.visitArray(this.selectors); + } + if (this.rules && this.rules.length) { + this.rules = visitor.visitArray(this.rules); + } + }, + eval: function (env) { + var thisSelectors = this.selectors, selectors, + selCnt, i, defaultFunc = tree.defaultFunc; + if (thisSelectors && (selCnt = thisSelectors.length)) { + selectors = []; + defaultFunc.error({ + type: "Syntax", + message: "it is currently only allowed in parametric mixin guards," + }); + for (i = 0; i < selCnt; i++) { + selectors.push(thisSelectors[i].eval(env)); + } + defaultFunc.reset(); + } + + var rules = this.rules ? this.rules.slice(0) : null, + ruleset = new(tree.Ruleset)(selectors, rules, this.strictImports), + rule; + + ruleset.originalRuleset = this; + ruleset.root = this.root; + ruleset.firstRoot = this.firstRoot; + ruleset.allowImports = this.allowImports; + + if(this.debugInfo) { + ruleset.debugInfo = this.debugInfo; + } + + // push the current ruleset to the frames stack + var envFrames = env.frames; + envFrames.unshift(ruleset); + + // currrent selectors + var envSelectors = env.selectors; + if (!envSelectors) { + env.selectors = envSelectors = []; + } + envSelectors.unshift(this.selectors); + + // Evaluate imports + if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { + ruleset.evalImports(env); + } + + // Store the frames around mixin definitions, + // so they can be evaluated like closures when the time comes. + var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0; + for (i = 0; i < rsRuleCnt; i++) { + if (rsRules[i] instanceof tree.mixin.Definition) { + rsRules[i].frames = envFrames.slice(0); + } + } + + var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0; + + // Evaluate mixin calls. + for (i = 0; i < rsRuleCnt; i++) { + if (rsRules[i] instanceof tree.mixin.Call) { + /*jshint loopfunc:true */ + rules = rsRules[i].eval(env).filter(function(r) { + if ((r instanceof tree.Rule) && r.variable) { + // do not pollute the scope if the variable is + // already there. consider returning false here + // but we need a way to "return" variable from mixins + return !(ruleset.variable(r.name)); + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + rsRuleCnt += rules.length - 1; + i += rules.length-1; + ruleset.resetCache(); + } + } + + // Evaluate everything else + for (i = 0; i < rsRuleCnt; i++) { + rule = rsRules[i]; + if (! (rule instanceof tree.mixin.Definition)) { + rsRules[i] = rule.eval ? rule.eval(env) : rule; + } + } + + // Pop the stack + envFrames.shift(); + envSelectors.shift(); + + if (env.mediaBlocks) { + for (i = mediaBlockCount; i < env.mediaBlocks.length; i++) { + env.mediaBlocks[i].bubbleSelectors(selectors); + } + } + + return ruleset; + }, + evalImports: function(env) { + var rules = this.rules, i, importRules; + if (!rules) { return; } + + for (i = 0; i < rules.length; i++) { + if (rules[i] instanceof tree.Import) { + importRules = rules[i].eval(env); + if (importRules && importRules.length) { + rules.splice.apply(rules, [i, 1].concat(importRules)); + i+= importRules.length-1; + } else { + rules.splice(i, 1, importRules); + } + this.resetCache(); + } + } + }, + makeImportant: function() { + return new tree.Ruleset(this.selectors, this.rules.map(function (r) { + if (r.makeImportant) { + return r.makeImportant(); + } else { + return r; + } + }), this.strictImports); + }, + matchArgs: function (args) { + return !args || args.length === 0; + }, + matchCondition: function (args, env) { + var lastSelector = this.selectors[this.selectors.length-1]; + if (lastSelector.condition && + !lastSelector.condition.eval( + new(tree.evalEnv)(env, + env.frames))) { + return false; + } + return true; + }, + resetCache: function () { + this._rulesets = null; + this._variables = null; + this._lookups = {}; + }, + variables: function () { + if (!this._variables) { + this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { + if (r instanceof tree.Rule && r.variable === true) { + hash[r.name] = r; + } + return hash; + }, {}); + } + return this._variables; + }, + variable: function (name) { + return this.variables()[name]; + }, + rulesets: function () { + if (!this.rules) { return null; } + + var _Ruleset = tree.Ruleset, _MixinDefinition = tree.mixin.Definition, + filtRules = [], rules = this.rules, cnt = rules.length, + i, rule; + + for (i = 0; i < cnt; i++) { + rule = rules[i]; + if ((rule instanceof _Ruleset) || (rule instanceof _MixinDefinition)) { + filtRules.push(rule); + } + } + + return filtRules; + }, + prependRule: function (rule) { + var rules = this.rules; + if (rules) { rules.unshift(rule); } else { this.rules = [ rule ]; } + }, + find: function (selector, self) { + self = self || this; + var rules = [], match, + key = selector.toCSS(); + + if (key in this._lookups) { return this._lookups[key]; } + + this.rulesets().forEach(function (rule) { + if (rule !== self) { + for (var j = 0; j < rule.selectors.length; j++) { + match = selector.match(rule.selectors[j]); + if (match) { + if (selector.elements.length > match) { + Array.prototype.push.apply(rules, rule.find( + new(tree.Selector)(selector.elements.slice(match)), self)); + } else { + rules.push(rule); + } + break; + } + } + } + }); + this._lookups[key] = rules; + return rules; + }, + genCSS: function (env, output) { + var i, j, + ruleNodes = [], + rulesetNodes = [], + rulesetNodeCnt, + debugInfo, // Line number debugging + rule, + path; + + env.tabLevel = (env.tabLevel || 0); + + if (!this.root) { + env.tabLevel++; + } + + var tabRuleStr = env.compress ? '' : Array(env.tabLevel + 1).join(" "), + tabSetStr = env.compress ? '' : Array(env.tabLevel).join(" "), + sep; + + for (i = 0; i < this.rules.length; i++) { + rule = this.rules[i]; + if (rule.rules || (rule instanceof tree.Media) || rule instanceof tree.Directive || (this.root && rule instanceof tree.Comment)) { + rulesetNodes.push(rule); + } else { + ruleNodes.push(rule); + } + } + + // If this is the root node, we don't render + // a selector, or {}. + if (!this.root) { + debugInfo = tree.debugInfo(env, this, tabSetStr); + + if (debugInfo) { + output.add(debugInfo); + output.add(tabSetStr); + } + + var paths = this.paths, pathCnt = paths.length, + pathSubCnt; + + sep = env.compress ? ',' : (',\n' + tabSetStr); + + for (i = 0; i < pathCnt; i++) { + path = paths[i]; + if (!(pathSubCnt = path.length)) { continue; } + if (i > 0) { output.add(sep); } + + env.firstSelector = true; + path[0].genCSS(env, output); + + env.firstSelector = false; + for (j = 1; j < pathSubCnt; j++) { + path[j].genCSS(env, output); + } + } + + output.add((env.compress ? '{' : ' {\n') + tabRuleStr); + } + + // Compile rules and rulesets + for (i = 0; i < ruleNodes.length; i++) { + rule = ruleNodes[i]; + + // @page{ directive ends up with root elements inside it, a mix of rules and rulesets + // In this instance we do not know whether it is the last property + if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) { + env.lastRule = true; + } + + if (rule.genCSS) { + rule.genCSS(env, output); + } else if (rule.value) { + output.add(rule.value.toString()); + } + + if (!env.lastRule) { + output.add(env.compress ? '' : ('\n' + tabRuleStr)); + } else { + env.lastRule = false; + } + } + + if (!this.root) { + output.add((env.compress ? '}' : '\n' + tabSetStr + '}')); + env.tabLevel--; + } + + sep = (env.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr); + rulesetNodeCnt = rulesetNodes.length; + if (rulesetNodeCnt) { + if (ruleNodes.length && sep) { output.add(sep); } + rulesetNodes[0].genCSS(env, output); + for (i = 1; i < rulesetNodeCnt; i++) { + if (sep) { output.add(sep); } + rulesetNodes[i].genCSS(env, output); + } + } + + if (!output.isEmpty() && !env.compress && this.firstRoot) { + output.add('\n'); + } + }, + + toCSS: tree.toCSS, + + markReferenced: function () { + for (var s = 0; s < this.selectors.length; s++) { + this.selectors[s].markReferenced(); + } + }, + + joinSelectors: function (paths, context, selectors) { + for (var s = 0; s < selectors.length; s++) { + this.joinSelector(paths, context, selectors[s]); + } + }, + + joinSelector: function (paths, context, selector) { + + var i, j, k, + hasParentSelector, newSelectors, el, sel, parentSel, + newSelectorPath, afterParentJoin, newJoinedSelector, + newJoinedSelectorEmpty, lastSelector, currentElements, + selectorsMultiplied; + + for (i = 0; i < selector.elements.length; i++) { + el = selector.elements[i]; + if (el.value === '&') { + hasParentSelector = true; + } + } + + if (!hasParentSelector) { + if (context.length > 0) { + for (i = 0; i < context.length; i++) { + paths.push(context[i].concat(selector)); + } + } + else { + paths.push([selector]); + } + return; + } + + // The paths are [[Selector]] + // The first list is a list of comma seperated selectors + // The inner list is a list of inheritance seperated selectors + // e.g. + // .a, .b { + // .c { + // } + // } + // == [[.a] [.c]] [[.b] [.c]] + // + + // the elements from the current selector so far + currentElements = []; + // the current list of new selectors to add to the path. + // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors + // by the parents + newSelectors = [[]]; + + for (i = 0; i < selector.elements.length; i++) { + el = selector.elements[i]; + // non parent reference elements just get added + if (el.value !== "&") { + currentElements.push(el); + } else { + // the new list of selectors to add + selectorsMultiplied = []; + + // merge the current list of non parent selector elements + // on to the current list of selectors to add + if (currentElements.length > 0) { + this.mergeElementsOnToSelectors(currentElements, newSelectors); + } + + // loop through our current selectors + for (j = 0; j < newSelectors.length; j++) { + sel = newSelectors[j]; + // if we don't have any parent paths, the & might be in a mixin so that it can be used + // whether there are parents or not + if (context.length === 0) { + // the combinator used on el should now be applied to the next element instead so that + // it is not lost + if (sel.length > 0) { + sel[0].elements = sel[0].elements.slice(0); + sel[0].elements.push(new(tree.Element)(el.combinator, '', 0, el.index, el.currentFileInfo)); + } + selectorsMultiplied.push(sel); + } + else { + // and the parent selectors + for (k = 0; k < context.length; k++) { + parentSel = context[k]; + // We need to put the current selectors + // then join the last selector's elements on to the parents selectors + + // our new selector path + newSelectorPath = []; + // selectors from the parent after the join + afterParentJoin = []; + newJoinedSelectorEmpty = true; + + //construct the joined selector - if & is the first thing this will be empty, + // if not newJoinedSelector will be the last set of elements in the selector + if (sel.length > 0) { + newSelectorPath = sel.slice(0); + lastSelector = newSelectorPath.pop(); + newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0)); + newJoinedSelectorEmpty = false; + } + else { + newJoinedSelector = selector.createDerived([]); + } + + //put together the parent selectors after the join + if (parentSel.length > 1) { + afterParentJoin = afterParentJoin.concat(parentSel.slice(1)); + } + + if (parentSel.length > 0) { + newJoinedSelectorEmpty = false; + + // join the elements so far with the first part of the parent + newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, el.index, el.currentFileInfo)); + newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1)); + } + + if (!newJoinedSelectorEmpty) { + // now add the joined selector + newSelectorPath.push(newJoinedSelector); + } + + // and the rest of the parent + newSelectorPath = newSelectorPath.concat(afterParentJoin); + + // add that to our new set of selectors + selectorsMultiplied.push(newSelectorPath); + } + } + } + + // our new selectors has been multiplied, so reset the state + newSelectors = selectorsMultiplied; + currentElements = []; + } + } + + // if we have any elements left over (e.g. .a& .b == .b) + // add them on to all the current selectors + if (currentElements.length > 0) { + this.mergeElementsOnToSelectors(currentElements, newSelectors); + } + + for (i = 0; i < newSelectors.length; i++) { + if (newSelectors[i].length > 0) { + paths.push(newSelectors[i]); + } + } + }, + + mergeElementsOnToSelectors: function(elements, selectors) { + var i, sel; + + if (selectors.length === 0) { + selectors.push([ new(tree.Selector)(elements) ]); + return; + } + + for (i = 0; i < selectors.length; i++) { + sel = selectors[i]; + + // if the previous thing in sel is a parent this needs to join on to it + if (sel.length > 0) { + sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); + } + else { + sel.push(new(tree.Selector)(elements)); + } + } + } +}; +})(require('../tree')); + +(function (tree) { + +tree.Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) { + this.elements = elements; + this.extendList = extendList; + this.condition = condition; + this.currentFileInfo = currentFileInfo || {}; + this.isReferenced = isReferenced; + if (!condition) { + this.evaldCondition = true; + } +}; +tree.Selector.prototype = { + type: "Selector", + accept: function (visitor) { + if (this.elements) { + this.elements = visitor.visitArray(this.elements); + } + if (this.extendList) { + this.extendList = visitor.visitArray(this.extendList); + } + if (this.condition) { + this.condition = visitor.visit(this.condition); + } + }, + createDerived: function(elements, extendList, evaldCondition) { + evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; + var newSelector = new(tree.Selector)(elements, extendList || this.extendList, this.condition, this.index, this.currentFileInfo, this.isReferenced); + newSelector.evaldCondition = evaldCondition; + return newSelector; + }, + match: function (other) { + var elements = this.elements, + len = elements.length, + oelements, olen, i; + + oelements = other.elements.map( function(v) { + return v.combinator.value + (v.value.value || v.value); + }).join("").match(/[,&#\.\w-]([\w-]|(\\.))*/g); + // ^ regexp could be more simple but see test/less/css-escapes.less:17, doh! + + if (!oelements) { + return 0; + } + + if (oelements[0] === "&") { + oelements.shift(); + } + + olen = oelements.length; + if (olen === 0 || len < olen) { + return 0; + } else { + for (i = 0; i < olen; i++) { + if (elements[i].value !== oelements[i]) { + return 0; + } + } + } + return olen; // return number of matched elements + }, + eval: function (env) { + var evaldCondition = this.condition && this.condition.eval(env), + elements = this.elements, extendList = this.extendList; + + elements = elements && elements.map(function (e) { return e.eval(env); }); + extendList = extendList && extendList.map(function(extend) { return extend.eval(env); }); + + return this.createDerived(elements, extendList, evaldCondition); + }, + genCSS: function (env, output) { + var i, element; + if ((!env || !env.firstSelector) && this.elements[0].combinator.value === "") { + output.add(' ', this.currentFileInfo, this.index); + } + if (!this._css) { + //TODO caching? speed comparison? + for(i = 0; i < this.elements.length; i++) { + element = this.elements[i]; + element.genCSS(env, output); + } + } + }, + toCSS: tree.toCSS, + markReferenced: function () { + this.isReferenced = true; + }, + getIsReferenced: function() { + return !this.currentFileInfo.reference || this.isReferenced; + }, + getIsOutput: function() { + return this.evaldCondition; + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.UnicodeDescriptor = function (value) { + this.value = value; +}; +tree.UnicodeDescriptor.prototype = { + type: "UnicodeDescriptor", + genCSS: function (env, output) { + output.add(this.value); + }, + toCSS: tree.toCSS, + eval: function () { return this; } +}; + +})(require('../tree')); + +(function (tree) { + +tree.URL = function (val, currentFileInfo, isEvald) { + this.value = val; + this.currentFileInfo = currentFileInfo; + this.isEvald = isEvald; +}; +tree.URL.prototype = { + type: "Url", + accept: function (visitor) { + this.value = visitor.visit(this.value); + }, + genCSS: function (env, output) { + output.add("url("); + this.value.genCSS(env, output); + output.add(")"); + }, + toCSS: tree.toCSS, + eval: function (ctx) { + var val = this.value.eval(ctx), + rootpath; + + if (!this.isEvald) { + // Add the base path if the URL is relative + rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; + if (rootpath && typeof val.value === "string" && ctx.isPathRelative(val.value)) { + if (!val.quote) { + rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; }); + } + val.value = rootpath + val.value; + } + + val.value = ctx.normalizePath(val.value); + } + + return new(tree.URL)(val, this.currentFileInfo, true); + } +}; + +})(require('../tree')); + +(function (tree) { + +tree.Value = function (value) { + this.value = value; +}; +tree.Value.prototype = { + type: "Value", + accept: function (visitor) { + if (this.value) { + this.value = visitor.visitArray(this.value); + } + }, + eval: function (env) { + if (this.value.length === 1) { + return this.value[0].eval(env); + } else { + return new(tree.Value)(this.value.map(function (v) { + return v.eval(env); + })); + } + }, + genCSS: function (env, output) { + var i; + for(i = 0; i < this.value.length; i++) { + this.value[i].genCSS(env, output); + if (i+1 < this.value.length) { + output.add((env && env.compress) ? ',' : ', '); + } + } + }, + toCSS: tree.toCSS +}; + +})(require('../tree')); + +(function (tree) { + +tree.Variable = function (name, index, currentFileInfo) { + this.name = name; + this.index = index; + this.currentFileInfo = currentFileInfo || {}; +}; +tree.Variable.prototype = { + type: "Variable", + eval: function (env) { + var variable, name = this.name; + + if (name.indexOf('@@') === 0) { + name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value; + } + + if (this.evaluating) { + throw { type: 'Name', + message: "Recursive variable definition for " + name, + filename: this.currentFileInfo.file, + index: this.index }; + } + + this.evaluating = true; + + variable = tree.find(env.frames, function (frame) { + var v = frame.variable(name); + if (v) { + return v.value.eval(env); + } + }); + if (variable) { + this.evaluating = false; + return variable; + } else { + throw { type: 'Name', + message: "variable " + name + " is undefined", + filename: this.currentFileInfo.filename, + index: this.index }; + } + } +}; + +})(require('../tree')); + +(function (tree) { + + var parseCopyProperties = [ + 'paths', // option - unmodified - paths to search for imports on + 'optimization', // option - optimization level (for the chunker) + 'files', // list of files that have been imported, used for import-once + 'contents', // map - filename to contents of all the files + 'contentsIgnoredChars', // map - filename to lines at the begining of each file to ignore + 'relativeUrls', // option - whether to adjust URL's to be relative + 'rootpath', // option - rootpath to append to URL's + 'strictImports', // option - + 'insecure', // option - whether to allow imports from insecure ssl hosts + 'dumpLineNumbers', // option - whether to dump line numbers + 'compress', // option - whether to compress + 'processImports', // option - whether to process imports. if false then imports will not be imported + 'syncImport', // option - whether to import synchronously + 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true + 'mime', // browser only - mime type for sheet import + 'useFileCache', // browser only - whether to use the per file session cache + 'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc. + ]; + + //currentFileInfo = { + // 'relativeUrls' - option - whether to adjust URL's to be relative + // 'filename' - full resolved filename of current file + // 'rootpath' - path to append to normal URLs for this node + // 'currentDirectory' - path to the current file, absolute + // 'rootFilename' - filename of the base file + // 'entryPath' - absolute path to the entry file + // 'reference' - whether the file should not be output and only output parts that are referenced + + tree.parseEnv = function(options) { + copyFromOriginal(options, this, parseCopyProperties); + + if (!this.contents) { this.contents = {}; } + if (!this.contentsIgnoredChars) { this.contentsIgnoredChars = {}; } + if (!this.files) { this.files = {}; } + + if (!this.currentFileInfo) { + var filename = (options && options.filename) || "input"; + var entryPath = filename.replace(/[^\/\\]*$/, ""); + if (options) { + options.filename = null; + } + this.currentFileInfo = { + filename: filename, + relativeUrls: this.relativeUrls, + rootpath: (options && options.rootpath) || "", + currentDirectory: entryPath, + entryPath: entryPath, + rootFilename: filename + }; + } + }; + + var evalCopyProperties = [ + 'silent', // whether to swallow errors and warnings + 'verbose', // whether to log more activity + 'compress', // whether to compress + 'yuicompress', // whether to compress with the outside tool yui compressor + 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) + 'strictMath', // whether math has to be within parenthesis + 'strictUnits', // whether units need to evaluate correctly + 'cleancss', // whether to compress with clean-css + 'sourceMap', // whether to output a source map + 'importMultiple'// whether we are currently importing multiple copies + ]; + + tree.evalEnv = function(options, frames) { + copyFromOriginal(options, this, evalCopyProperties); + + this.frames = frames || []; + }; + + tree.evalEnv.prototype.inParenthesis = function () { + if (!this.parensStack) { + this.parensStack = []; + } + this.parensStack.push(true); + }; + + tree.evalEnv.prototype.outOfParenthesis = function () { + this.parensStack.pop(); + }; + + tree.evalEnv.prototype.isMathOn = function () { + return this.strictMath ? (this.parensStack && this.parensStack.length) : true; + }; + + tree.evalEnv.prototype.isPathRelative = function (path) { + return !/^(?:[a-z-]+:|\/)/.test(path); + }; + + tree.evalEnv.prototype.normalizePath = function( path ) { + var + segments = path.split("/").reverse(), + segment; + + path = []; + while (segments.length !== 0 ) { + segment = segments.pop(); + switch( segment ) { + case ".": + break; + case "..": + if ((path.length === 0) || (path[path.length - 1] === "..")) { + path.push( segment ); + } else { + path.pop(); + } + break; + default: + path.push( segment ); + break; + } + } + + return path.join("/"); + }; + + //todo - do the same for the toCSS env + //tree.toCSSEnv = function (options) { + //}; + + var copyFromOriginal = function(original, destination, propertiesToCopy) { + if (!original) { return; } + + for(var i = 0; i < propertiesToCopy.length; i++) { + if (original.hasOwnProperty(propertiesToCopy[i])) { + destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; + } + } + }; + +})(require('./tree')); + +(function (tree) { + + var _visitArgs = { visitDeeper: true }, + _hasIndexed = false; + + function _noop(node) { + return node; + } + + function indexNodeTypes(parent, ticker) { + // add .typeIndex to tree node types for lookup table + var key, child; + for (key in parent) { + child = parent[key]; + switch (typeof child) { + case "function": + // ignore bound functions directly on tree which do not have a prototype + // or aren't nodes + if (child.prototype && child.prototype.type) { + child.prototype.typeIndex = ticker++; + } + break; + case "object": + ticker = indexNodeTypes(child, ticker); + break; + } + } + return ticker; + } + + tree.visitor = function(implementation) { + this._implementation = implementation; + this._visitFnCache = []; + + if (!_hasIndexed) { + indexNodeTypes(tree, 1); + _hasIndexed = true; + } + }; + + tree.visitor.prototype = { + visit: function(node) { + if (!node) { + return node; + } + + var nodeTypeIndex = node.typeIndex; + if (!nodeTypeIndex) { + return node; + } + + var visitFnCache = this._visitFnCache, + impl = this._implementation, + aryIndx = nodeTypeIndex << 1, + outAryIndex = aryIndx | 1, + func = visitFnCache[aryIndx], + funcOut = visitFnCache[outAryIndex], + visitArgs = _visitArgs, + fnName; + + visitArgs.visitDeeper = true; + + if (!func) { + fnName = "visit" + node.type; + func = impl[fnName] || _noop; + funcOut = impl[fnName + "Out"] || _noop; + visitFnCache[aryIndx] = func; + visitFnCache[outAryIndex] = funcOut; + } + + if (func !== _noop) { + var newNode = func.call(impl, node, visitArgs); + if (impl.isReplacing) { + node = newNode; + } + } + + if (visitArgs.visitDeeper && node && node.accept) { + node.accept(this); + } + + if (funcOut != _noop) { + funcOut.call(impl, node); + } + + return node; + }, + visitArray: function(nodes, nonReplacing) { + if (!nodes) { + return nodes; + } + + var cnt = nodes.length, i; + + // Non-replacing + if (nonReplacing || !this._implementation.isReplacing) { + for (i = 0; i < cnt; i++) { + this.visit(nodes[i]); + } + return nodes; + } + + // Replacing + var out = []; + for (i = 0; i < cnt; i++) { + var evald = this.visit(nodes[i]); + if (!evald.splice) { + out.push(evald); + } else if (evald.length) { + this.flatten(evald, out); + } + } + return out; + }, + flatten: function(arr, out) { + if (!out) { + out = []; + } + + var cnt, i, item, + nestedCnt, j, nestedItem; + + for (i = 0, cnt = arr.length; i < cnt; i++) { + item = arr[i]; + if (!item.splice) { + out.push(item); + continue; + } + + for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { + nestedItem = item[j]; + if (!nestedItem.splice) { + out.push(nestedItem); + } else if (nestedItem.length) { + this.flatten(nestedItem, out); + } + } + } + + return out; + } + }; + +})(require('./tree')); +(function (tree) { + tree.importVisitor = function(importer, finish, evalEnv) { + this._visitor = new tree.visitor(this); + this._importer = importer; + this._finish = finish; + this.env = evalEnv || new tree.evalEnv(); + this.importCount = 0; + }; + + tree.importVisitor.prototype = { + isReplacing: true, + run: function (root) { + var error; + try { + // process the contents + this._visitor.visit(root); + } + catch(e) { + error = e; + } + + this.isFinished = true; + + if (this.importCount === 0) { + this._finish(error); + } + }, + visitImport: function (importNode, visitArgs) { + var importVisitor = this, + evaldImportNode, + inlineCSS = importNode.options.inline; + + if (!importNode.css || inlineCSS) { + + try { + evaldImportNode = importNode.evalForImport(this.env); + } catch(e){ + if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } + // attempt to eval properly and treat as css + importNode.css = true; + // if that fails, this error will be thrown + importNode.error = e; + } + + if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { + importNode = evaldImportNode; + this.importCount++; + var env = new tree.evalEnv(this.env, this.env.frames.slice(0)); + + if (importNode.options.multiple) { + env.importMultiple = true; + } + + this._importer.push(importNode.getPath(), importNode.currentFileInfo, importNode.options, function (e, root, imported, fullPath) { + if (e && !e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } + + if (imported && !env.importMultiple) { importNode.skip = imported; } + + var subFinish = function(e) { + importVisitor.importCount--; + + if (importVisitor.importCount === 0 && importVisitor.isFinished) { + importVisitor._finish(e); + } + }; + + if (root) { + importNode.root = root; + importNode.importedFilename = fullPath; + if (!inlineCSS && !importNode.skip) { + new(tree.importVisitor)(importVisitor._importer, subFinish, env) + .run(root); + return; + } + } + + subFinish(); + }); + } + } + visitArgs.visitDeeper = false; + return importNode; + }, + visitRule: function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + return ruleNode; + }, + visitDirective: function (directiveNode, visitArgs) { + this.env.frames.unshift(directiveNode); + return directiveNode; + }, + visitDirectiveOut: function (directiveNode) { + this.env.frames.shift(); + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + this.env.frames.unshift(mixinDefinitionNode); + return mixinDefinitionNode; + }, + visitMixinDefinitionOut: function (mixinDefinitionNode) { + this.env.frames.shift(); + }, + visitRuleset: function (rulesetNode, visitArgs) { + this.env.frames.unshift(rulesetNode); + return rulesetNode; + }, + visitRulesetOut: function (rulesetNode) { + this.env.frames.shift(); + }, + visitMedia: function (mediaNode, visitArgs) { + this.env.frames.unshift(mediaNode.ruleset); + return mediaNode; + }, + visitMediaOut: function (mediaNode) { + this.env.frames.shift(); + } + }; + +})(require('./tree')); +(function (tree) { + tree.joinSelectorVisitor = function() { + this.contexts = [[]]; + this._visitor = new tree.visitor(this); + }; + + tree.joinSelectorVisitor.prototype = { + run: function (root) { + return this._visitor.visit(root); + }, + visitRule: function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + + visitRuleset: function (rulesetNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1], + paths = [], selectors; + + this.contexts.push(paths); + + if (! rulesetNode.root) { + selectors = rulesetNode.selectors; + if (selectors) { + selectors = selectors.filter(function(selector) { return selector.getIsOutput(); }); + rulesetNode.selectors = selectors.length ? selectors : (selectors = null); + if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); } + } + if (!selectors) { rulesetNode.rules = null; } + rulesetNode.paths = paths; + } + }, + visitRulesetOut: function (rulesetNode) { + this.contexts.length = this.contexts.length - 1; + }, + visitMedia: function (mediaNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); + } + }; + +})(require('./tree')); +(function (tree) { + tree.toCSSVisitor = function(env) { + this._visitor = new tree.visitor(this); + this._env = env; + }; + + tree.toCSSVisitor.prototype = { + isReplacing: true, + run: function (root) { + return this._visitor.visit(root); + }, + + visitRule: function (ruleNode, visitArgs) { + if (ruleNode.variable) { + return []; + } + return ruleNode; + }, + + visitMixinDefinition: function (mixinNode, visitArgs) { + return []; + }, + + visitExtend: function (extendNode, visitArgs) { + return []; + }, + + visitComment: function (commentNode, visitArgs) { + if (commentNode.isSilent(this._env)) { + return []; + } + return commentNode; + }, + + visitMedia: function(mediaNode, visitArgs) { + mediaNode.accept(this._visitor); + visitArgs.visitDeeper = false; + + if (!mediaNode.rules.length) { + return []; + } + return mediaNode; + }, + + visitDirective: function(directiveNode, visitArgs) { + if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) { + return []; + } + if (directiveNode.name === "@charset") { + // Only output the debug info together with subsequent @charset definitions + // a comment (or @media statement) before the actual @charset directive would + // be considered illegal css as it has to be on the first line + if (this.charset) { + if (directiveNode.debugInfo) { + var comment = new tree.Comment("/* " + directiveNode.toCSS(this._env).replace(/\n/g, "")+" */\n"); + comment.debugInfo = directiveNode.debugInfo; + return this._visitor.visit(comment); + } + return []; + } + this.charset = true; + } + return directiveNode; + }, + + checkPropertiesInRoot: function(rules) { + var ruleNode; + for(var i = 0; i < rules.length; i++) { + ruleNode = rules[i]; + if (ruleNode instanceof tree.Rule && !ruleNode.variable) { + throw { message: "properties must be inside selector blocks, they cannot be in the root.", + index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; + } + } + }, + + visitRuleset: function (rulesetNode, visitArgs) { + var rule, rulesets = []; + if (rulesetNode.firstRoot) { + this.checkPropertiesInRoot(rulesetNode.rules); + } + if (! rulesetNode.root) { + if (rulesetNode.paths) { + rulesetNode.paths = rulesetNode.paths + .filter(function(p) { + var i; + if (p[0].elements[0].combinator.value === ' ') { + p[0].elements[0].combinator = new(tree.Combinator)(''); + } + for(i = 0; i < p.length; i++) { + if (p[i].getIsReferenced() && p[i].getIsOutput()) { + return true; + } + } + return false; + }); + } + + // Compile rules and rulesets + var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0; + for (var i = 0; i < nodeRuleCnt; ) { + rule = nodeRules[i]; + if (rule && rule.rules) { + // visit because we are moving them out from being a child + rulesets.push(this._visitor.visit(rule)); + nodeRules.splice(i, 1); + nodeRuleCnt--; + continue; + } + i++; + } + // accept the visitor to remove rules and refactor itself + // then we can decide now whether we want it or not + if (nodeRuleCnt > 0) { + rulesetNode.accept(this._visitor); + } else { + rulesetNode.rules = null; + } + visitArgs.visitDeeper = false; + + nodeRules = rulesetNode.rules; + if (nodeRules) { + this._mergeRules(nodeRules); + nodeRules = rulesetNode.rules; + } + if (nodeRules) { + this._removeDuplicateRules(nodeRules); + nodeRules = rulesetNode.rules; + } + + // now decide whether we keep the ruleset + if (nodeRules && nodeRules.length > 0 && rulesetNode.paths.length > 0) { + rulesets.splice(0, 0, rulesetNode); + } + } else { + rulesetNode.accept(this._visitor); + visitArgs.visitDeeper = false; + if (rulesetNode.firstRoot || (rulesetNode.rules && rulesetNode.rules.length > 0)) { + rulesets.splice(0, 0, rulesetNode); + } + } + if (rulesets.length === 1) { + return rulesets[0]; + } + return rulesets; + }, + + _removeDuplicateRules: function(rules) { + if (!rules) { return; } + + // remove duplicates + var ruleCache = {}, + ruleList, rule, i; + + for(i = rules.length - 1; i >= 0 ; i--) { + rule = rules[i]; + if (rule instanceof tree.Rule) { + if (!ruleCache[rule.name]) { + ruleCache[rule.name] = rule; + } else { + ruleList = ruleCache[rule.name]; + if (ruleList instanceof tree.Rule) { + ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._env)]; + } + var ruleCSS = rule.toCSS(this._env); + if (ruleList.indexOf(ruleCSS) !== -1) { + rules.splice(i, 1); + } else { + ruleList.push(ruleCSS); + } + } + } + } + }, + + _mergeRules: function (rules) { + if (!rules) { return; } + + var groups = {}, + parts, + rule, + key; + + for (var i = 0; i < rules.length; i++) { + rule = rules[i]; + + if ((rule instanceof tree.Rule) && rule.merge) { + key = [rule.name, + rule.important ? "!" : ""].join(","); + + if (!groups[key]) { + groups[key] = []; + } else { + rules.splice(i--, 1); + } + + groups[key].push(rule); + } + } + + Object.keys(groups).map(function (k) { + parts = groups[k]; + + if (parts.length > 1) { + rule = parts[0]; + + rule.value = new (tree.Value)(parts.map(function (p) { + return p.value; + })); + } + }); + } + }; + +})(require('./tree')); +(function (tree) { + /*jshint loopfunc:true */ + + tree.extendFinderVisitor = function() { + this._visitor = new tree.visitor(this); + this.contexts = []; + this.allExtendsStack = [[]]; + }; + + tree.extendFinderVisitor.prototype = { + run: function (root) { + root = this._visitor.visit(root); + root.allExtends = this.allExtendsStack[0]; + return root; + }, + visitRule: function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitRuleset: function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; + } + + var i, j, extend, allSelectorsExtendList = [], extendList; + + // get &:extend(.a); rules which apply to all selectors in this ruleset + var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0; + for(i = 0; i < ruleCnt; i++) { + if (rulesetNode.rules[i] instanceof tree.Extend) { + allSelectorsExtendList.push(rules[i]); + rulesetNode.extendOnEveryPath = true; + } + } + + // now find every selector and apply the extends that apply to all extends + // and the ones which apply to an individual extend + var paths = rulesetNode.paths; + for(i = 0; i < paths.length; i++) { + var selectorPath = paths[i], + selector = selectorPath[selectorPath.length - 1], + selExtendList = selector.extendList; + + extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList) + : allSelectorsExtendList; + + if (extendList) { + extendList = extendList.map(function(allSelectorsExtend) { + return allSelectorsExtend.clone(); + }); + } + + for(j = 0; j < extendList.length; j++) { + this.foundExtends = true; + extend = extendList[j]; + extend.findSelfSelectors(selectorPath); + extend.ruleset = rulesetNode; + if (j === 0) { extend.firstExtendOnThisSelectorPath = true; } + this.allExtendsStack[this.allExtendsStack.length-1].push(extend); + } + } + + this.contexts.push(rulesetNode.selectors); + }, + visitRulesetOut: function (rulesetNode) { + if (!rulesetNode.root) { + this.contexts.length = this.contexts.length - 1; + } + }, + visitMedia: function (mediaNode, visitArgs) { + mediaNode.allExtends = []; + this.allExtendsStack.push(mediaNode.allExtends); + }, + visitMediaOut: function (mediaNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }, + visitDirective: function (directiveNode, visitArgs) { + directiveNode.allExtends = []; + this.allExtendsStack.push(directiveNode.allExtends); + }, + visitDirectiveOut: function (directiveNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + } + }; + + tree.processExtendsVisitor = function() { + this._visitor = new tree.visitor(this); + }; + + tree.processExtendsVisitor.prototype = { + run: function(root) { + var extendFinder = new tree.extendFinderVisitor(); + extendFinder.run(root); + if (!extendFinder.foundExtends) { return root; } + root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); + this.allExtendsStack = [root.allExtends]; + return this._visitor.visit(root); + }, + doExtendChaining: function (extendsList, extendsListTarget, iterationCount) { + // + // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting + // the selector we would do normally, but we are also adding an extend with the same target selector + // this means this new extend can then go and alter other extends + // + // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors + // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if + // we look at each selector at a time, as is done in visitRuleset + + var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend; + + iterationCount = iterationCount || 0; + + //loop through comparing every extend with every target extend. + // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place + // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one + // and the second is the target. + // the seperation into two lists allows us to process a subset of chains with a bigger set, as is the + // case when processing media queries + for(extendIndex = 0; extendIndex < extendsList.length; extendIndex++){ + for(targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++){ + + extend = extendsList[extendIndex]; + targetExtend = extendsListTarget[targetExtendIndex]; + + // look for circular references + if( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ){ continue; } + + // find a match in the target extends self selector (the bit before :extend) + selectorPath = [targetExtend.selfSelectors[0]]; + matches = extendVisitor.findMatch(extend, selectorPath); + + if (matches.length) { + + // we found a match, so for each self selector.. + extend.selfSelectors.forEach(function(selfSelector) { + + // process the extend as usual + newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector); + + // but now we create a new extend from it + newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0); + newExtend.selfSelectors = newSelector; + + // add the extend onto the list of extends for that selector + newSelector[newSelector.length-1].extendList = [newExtend]; + + // record that we need to add it. + extendsToAdd.push(newExtend); + newExtend.ruleset = targetExtend.ruleset; + + //remember its parents for circular references + newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); + + // only process the selector once.. if we have :extend(.a,.b) then multiple + // extends will look at the same selector path, so when extending + // we know that any others will be duplicates in terms of what is added to the css + if (targetExtend.firstExtendOnThisSelectorPath) { + newExtend.firstExtendOnThisSelectorPath = true; + targetExtend.ruleset.paths.push(newSelector); + } + }); + } + } + } + + if (extendsToAdd.length) { + // try to detect circular references to stop a stack overflow. + // may no longer be needed. + this.extendChainCount++; + if (iterationCount > 100) { + var selectorOne = "{unable to calculate}"; + var selectorTwo = "{unable to calculate}"; + try + { + selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); + selectorTwo = extendsToAdd[0].selector.toCSS(); + } + catch(e) {} + throw {message: "extend circular reference detected. One of the circular extends is currently:"+selectorOne+":extend(" + selectorTwo+")"}; + } + + // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... + return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount+1)); + } else { + return extendsToAdd; + } + }, + visitRule: function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitSelector: function (selectorNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitRuleset: function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; + } + var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [], extendVisitor = this, selectorPath; + + // look at each selector path in the ruleset, find any extend matches and then copy, find and replace + + for(extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { + for(pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { + selectorPath = rulesetNode.paths[pathIndex]; + + // extending extends happens initially, before the main pass + if (rulesetNode.extendOnEveryPath) { continue; } + var extendList = selectorPath[selectorPath.length-1].extendList; + if (extendList && extendList.length) { continue; } + + matches = this.findMatch(allExtends[extendIndex], selectorPath); + + if (matches.length) { + + allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) { + selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector)); + }); + } + } + } + rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); + }, + findMatch: function (extend, haystackSelectorPath) { + // + // look through the haystack selector path to try and find the needle - extend.selector + // returns an array of selector matches that can then be replaced + // + var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement, + targetCombinator, i, + extendVisitor = this, + needleElements = extend.selector.elements, + potentialMatches = [], potentialMatch, matches = []; + + // loop through the haystack elements + for(haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { + hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; + + for(hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { + + haystackElement = hackstackSelector.elements[hackstackElementIndex]; + + // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. + if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { + potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, initialCombinator: haystackElement.combinator}); + } + + for(i = 0; i < potentialMatches.length; i++) { + potentialMatch = potentialMatches[i]; + + // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't + // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out + // what the resulting combinator will be + targetCombinator = haystackElement.combinator.value; + if (targetCombinator === '' && hackstackElementIndex === 0) { + targetCombinator = ' '; + } + + // if we don't match, null our match to indicate failure + if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || + (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { + potentialMatch = null; + } else { + potentialMatch.matched++; + } + + // if we are still valid and have finished, test whether we have elements after and whether these are allowed + if (potentialMatch) { + potentialMatch.finished = potentialMatch.matched === needleElements.length; + if (potentialMatch.finished && + (!extend.allowAfter && (hackstackElementIndex+1 < hackstackSelector.elements.length || haystackSelectorIndex+1 < haystackSelectorPath.length))) { + potentialMatch = null; + } + } + // if null we remove, if not, we are still valid, so either push as a valid match or continue + if (potentialMatch) { + if (potentialMatch.finished) { + potentialMatch.length = needleElements.length; + potentialMatch.endPathIndex = haystackSelectorIndex; + potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match + potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again + matches.push(potentialMatch); + } + } else { + potentialMatches.splice(i, 1); + i--; + } + } + } + } + return matches; + }, + isElementValuesEqual: function(elementValue1, elementValue2) { + if (typeof elementValue1 === "string" || typeof elementValue2 === "string") { + return elementValue1 === elementValue2; + } + if (elementValue1 instanceof tree.Attribute) { + if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { + return false; + } + if (!elementValue1.value || !elementValue2.value) { + if (elementValue1.value || elementValue2.value) { + return false; + } + return true; + } + elementValue1 = elementValue1.value.value || elementValue1.value; + elementValue2 = elementValue2.value.value || elementValue2.value; + return elementValue1 === elementValue2; + } + elementValue1 = elementValue1.value; + elementValue2 = elementValue2.value; + if (elementValue1 instanceof tree.Selector) { + if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { + return false; + } + for(var i = 0; i currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } + + newElements = selector.elements + .slice(currentSelectorPathElementIndex, match.index) + .concat([firstElement]) + .concat(replacementSelector.elements.slice(1)); + + if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { + path[path.length - 1].elements = + path[path.length - 1].elements.concat(newElements); + } else { + path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); + + path.push(new tree.Selector( + newElements + )); + } + currentSelectorPathIndex = match.endPathIndex; + currentSelectorPathElementIndex = match.endPathElementIndex; + if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } + } + + if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathIndex++; + } + + path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); + + return path; + }, + visitRulesetOut: function (rulesetNode) { + }, + visitMedia: function (mediaNode, visitArgs) { + var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }, + visitMediaOut: function (mediaNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }, + visitDirective: function (directiveNode, visitArgs) { + var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }, + visitDirectiveOut: function (directiveNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + } + }; + +})(require('./tree')); + +(function (tree) { + + tree.sourceMapOutput = function (options) { + this._css = []; + this._rootNode = options.rootNode; + this._writeSourceMap = options.writeSourceMap; + this._contentsMap = options.contentsMap; + this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; + this._sourceMapFilename = options.sourceMapFilename; + this._outputFilename = options.outputFilename; + this._sourceMapURL = options.sourceMapURL; + if (options.sourceMapBasepath) { + this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); + } + this._sourceMapRootpath = options.sourceMapRootpath; + this._outputSourceFiles = options.outputSourceFiles; + this._sourceMapGeneratorConstructor = options.sourceMapGenerator || require("source-map").SourceMapGenerator; + + if (this._sourceMapRootpath && this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1) !== '/') { + this._sourceMapRootpath += '/'; + } + + this._lineNumber = 0; + this._column = 0; + }; + + tree.sourceMapOutput.prototype.normalizeFilename = function(filename) { + filename = filename.replace(/\\/g, '/'); + + if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) { + filename = filename.substring(this._sourceMapBasepath.length); + if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') { + filename = filename.substring(1); + } + } + return (this._sourceMapRootpath || "") + filename; + }; + + tree.sourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) { + + //ignore adding empty strings + if (!chunk) { + return; + } + + var lines, + sourceLines, + columns, + sourceColumns, + i; + + if (fileInfo) { + var inputSource = this._contentsMap[fileInfo.filename]; + + // remove vars/banner added to the top of the file + if (this._contentsIgnoredCharsMap[fileInfo.filename]) { + // adjust the index + index -= this._contentsIgnoredCharsMap[fileInfo.filename]; + if (index < 0) { index = 0; } + // adjust the source + inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); + } + inputSource = inputSource.substring(0, index); + sourceLines = inputSource.split("\n"); + sourceColumns = sourceLines[sourceLines.length-1]; + } + + lines = chunk.split("\n"); + columns = lines[lines.length-1]; + + if (fileInfo) { + if (!mapLines) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column}, + original: { line: sourceLines.length, column: sourceColumns.length}, + source: this.normalizeFilename(fileInfo.filename)}); + } else { + for(i = 0; i < lines.length; i++) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0}, + original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0}, + source: this.normalizeFilename(fileInfo.filename)}); + } + } + } + + if (lines.length === 1) { + this._column += columns.length; + } else { + this._lineNumber += lines.length - 1; + this._column = columns.length; + } + + this._css.push(chunk); + }; + + tree.sourceMapOutput.prototype.isEmpty = function() { + return this._css.length === 0; + }; + + tree.sourceMapOutput.prototype.toCSS = function(env) { + this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); + + if (this._outputSourceFiles) { + for(var filename in this._contentsMap) { + var source = this._contentsMap[filename]; + if (this._contentsIgnoredCharsMap[filename]) { + source = source.slice(this._contentsIgnoredCharsMap[filename]); + } + this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); + } + } + + this._rootNode.genCSS(env, this); + + if (this._css.length > 0) { + var sourceMapURL, + sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); + + if (this._sourceMapURL) { + sourceMapURL = this._sourceMapURL; + } else if (this._sourceMapFilename) { + sourceMapURL = this.normalizeFilename(this._sourceMapFilename); + } + + if (this._writeSourceMap) { + this._writeSourceMap(sourceMapContent); + } else { + sourceMapURL = "data:application/json," + encodeURIComponent(sourceMapContent); + } + + if (sourceMapURL) { + this._css.push("/*# sourceMappingURL=" + sourceMapURL + " */"); + } + } + + return this._css.join(''); + }; + +})(require('./tree')); + +// +// browser.js - client-side engine +// +/*global less, window, document, XMLHttpRequest, location */ + +var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol); + +less.env = less.env || (location.hostname == '127.0.0.1' || + location.hostname == '0.0.0.0' || + location.hostname == 'localhost' || + (location.port && + location.port.length > 0) || + isFileProtocol ? 'development' + : 'production'); + +var logLevel = { + info: 2, + errors: 1, + none: 0 +}; + +// The amount of logging in the javascript console. +// 2 - Information and errors +// 1 - Errors +// 0 - None +// Defaults to 2 +less.logLevel = typeof(less.logLevel) != 'undefined' ? less.logLevel : logLevel.info; + +// Load styles asynchronously (default: false) +// +// This is set to `false` by default, so that the body +// doesn't start loading before the stylesheets are parsed. +// Setting this to `true` can result in flickering. +// +less.async = less.async || false; +less.fileAsync = less.fileAsync || false; + +// Interval between watch polls +less.poll = less.poll || (isFileProtocol ? 1000 : 1500); + +//Setup user functions +if (less.functions) { + for(var func in less.functions) { + less.tree.functions[func] = less.functions[func]; + } +} + +var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash); +if (dumpLineNumbers) { + less.dumpLineNumbers = dumpLineNumbers[1]; +} + +var typePattern = /^text\/(x-)?less$/; +var cache = null; +var fileCache = {}; + +function log(str, level) { + if (less.env == 'development' && typeof(console) !== 'undefined' && less.logLevel >= level) { + console.log('less: ' + str); + } +} + +function extractId(href) { + return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain + .replace(/^\//, '' ) // Remove root / + .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension + .replace(/[^\.\w-]+/g, '-') // Replace illegal characters + .replace(/\./g, ':'); // Replace dots with colons(for valid id) +} + +function errorConsole(e, rootHref) { + var template = '{line} {content}'; + var filename = e.filename || rootHref; + var errors = []; + var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + + " in " + filename + " "; + + var errorline = function (e, i, classname) { + if (e.extract[i] !== undefined) { + errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) + .replace(/\{class\}/, classname) + .replace(/\{content\}/, e.extract[i])); + } + }; + + if (e.extract) { + errorline(e, 0, ''); + errorline(e, 1, 'line'); + errorline(e, 2, ''); + content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' + + errors.join('\n'); + } else if (e.stack) { + content += e.stack; + } + log(content, logLevel.errors); +} + +function createCSS(styles, sheet, lastModified) { + // Strip the query-string + var href = sheet.href || ''; + + // If there is no title set, use the filename, minus the extension + var id = 'less:' + (sheet.title || extractId(href)); + + // If this has already been inserted into the DOM, we may need to replace it + var oldCss = document.getElementById(id); + var keepOldCss = false; + + // Create a new stylesheet node for insertion or (if necessary) replacement + var css = document.createElement('style'); + css.setAttribute('type', 'text/css'); + if (sheet.media) { + css.setAttribute('media', sheet.media); + } + css.id = id; + + if (css.styleSheet) { // IE + try { + css.styleSheet.cssText = styles; + } catch (e) { + throw new(Error)("Couldn't reassign styleSheet.cssText."); + } + } else { + css.appendChild(document.createTextNode(styles)); + + // If new contents match contents of oldCss, don't replace oldCss + keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 && + oldCss.firstChild.nodeValue === css.firstChild.nodeValue); + } + + var head = document.getElementsByTagName('head')[0]; + + // If there is no oldCss, just append; otherwise, only append if we need + // to replace oldCss with an updated stylesheet + if (oldCss === null || keepOldCss === false) { + var nextEl = sheet && sheet.nextSibling || null; + if (nextEl) { + nextEl.parentNode.insertBefore(css, nextEl); + } else { + head.appendChild(css); + } + } + if (oldCss && keepOldCss === false) { + oldCss.parentNode.removeChild(oldCss); + } + + // Don't update the local store if the file wasn't modified + if (lastModified && cache) { + log('saving ' + href + ' to cache.', logLevel.info); + try { + cache.setItem(href, styles); + cache.setItem(href + ':timestamp', lastModified); + } catch(e) { + //TODO - could do with adding more robust error handling + log('failed to save', logLevel.errors); + } + } +} + +function errorHTML(e, rootHref) { + var id = 'less-error-message:' + extractId(rootHref || ""); + var template = '
  • {content}
  • '; + var elem = document.createElement('div'), timer, content, errors = []; + var filename = e.filename || rootHref; + var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; + + elem.id = id; + elem.className = "less-error-message"; + + content = '

    ' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + + '

    ' + '

    in ' + filenameNoPath + " "; + + var errorline = function (e, i, classname) { + if (e.extract[i] !== undefined) { + errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) + .replace(/\{class\}/, classname) + .replace(/\{content\}/, e.extract[i])); + } + }; + + if (e.extract) { + errorline(e, 0, ''); + errorline(e, 1, 'line'); + errorline(e, 2, ''); + content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':

    ' + + '
      ' + errors.join('') + '
    '; + } else if (e.stack) { + content += '
    ' + e.stack.split('\n').slice(1).join('
    '); + } + elem.innerHTML = content; + + // CSS for error messages + createCSS([ + '.less-error-message ul, .less-error-message li {', + 'list-style-type: none;', + 'margin-right: 15px;', + 'padding: 4px 0;', + 'margin: 0;', + '}', + '.less-error-message label {', + 'font-size: 12px;', + 'margin-right: 15px;', + 'padding: 4px 0;', + 'color: #cc7777;', + '}', + '.less-error-message pre {', + 'color: #dd6666;', + 'padding: 4px 0;', + 'margin: 0;', + 'display: inline-block;', + '}', + '.less-error-message pre.line {', + 'color: #ff0000;', + '}', + '.less-error-message h3 {', + 'font-size: 20px;', + 'font-weight: bold;', + 'padding: 15px 0 5px 0;', + 'margin: 0;', + '}', + '.less-error-message a {', + 'color: #10a', + '}', + '.less-error-message .error {', + 'color: red;', + 'font-weight: bold;', + 'padding-bottom: 2px;', + 'border-bottom: 1px dashed red;', + '}' + ].join('\n'), { title: 'error-message' }); + + elem.style.cssText = [ + "font-family: Arial, sans-serif", + "border: 1px solid #e00", + "background-color: #eee", + "border-radius: 5px", + "-webkit-border-radius: 5px", + "-moz-border-radius: 5px", + "color: #e00", + "padding: 15px", + "margin-bottom: 15px" + ].join(';'); + + if (less.env == 'development') { + timer = setInterval(function () { + if (document.body) { + if (document.getElementById(id)) { + document.body.replaceChild(elem, document.getElementById(id)); + } else { + document.body.insertBefore(elem, document.body.firstChild); + } + clearInterval(timer); + } + }, 10); + } +} + +function error(e, rootHref) { + if (!less.errorReporting || less.errorReporting === "html") { + errorHTML(e, rootHref); + } else if (less.errorReporting === "console") { + errorConsole(e, rootHref); + } else if (typeof less.errorReporting === 'function') { + less.errorReporting("add", e, rootHref); + } +} + +function removeErrorHTML(path) { + var node = document.getElementById('less-error-message:' + extractId(path)); + if (node) { + node.parentNode.removeChild(node); + } +} + +function removeErrorConsole(path) { + //no action +} + +function removeError(path) { + if (!less.errorReporting || less.errorReporting === "html") { + removeErrorHTML(path); + } else if (less.errorReporting === "console") { + removeErrorConsole(path); + } else if (typeof less.errorReporting === 'function') { + less.errorReporting("remove", path); + } +} + +function loadStyles(modifyVars) { + var styles = document.getElementsByTagName('style'), + style; + for (var i = 0; i < styles.length; i++) { + style = styles[i]; + if (style.type.match(typePattern)) { + var env = new less.tree.parseEnv(less), + lessText = style.innerHTML || ''; + env.filename = document.location.href.replace(/#.*$/, ''); + + if (modifyVars || less.globalVars) { + env.useFileCache = true; + } + + /*jshint loopfunc:true */ + // use closure to store current value of i + var callback = (function(style) { + return function (e, cssAST) { + if (e) { + return error(e, "inline"); + } + var css = cssAST.toCSS(less); + style.type = 'text/css'; + if (style.styleSheet) { + style.styleSheet.cssText = css; + } else { + style.innerHTML = css; + } + }; + })(style); + new(less.Parser)(env).parse(lessText, callback, {globalVars: less.globalVars, modifyVars: modifyVars}); + } + } +} + +function extractUrlParts(url, baseUrl) { + // urlParts[1] = protocol&hostname || / + // urlParts[2] = / if path relative to host base + // urlParts[3] = directories + // urlParts[4] = filename + // urlParts[5] = parameters + + var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i, + urlParts = url.match(urlPartsRegex), + returner = {}, directories = [], i, baseUrlParts; + + if (!urlParts) { + throw new Error("Could not parse sheet href - '"+url+"'"); + } + + // Stylesheets in IE don't always return the full path + if (!urlParts[1] || urlParts[2]) { + baseUrlParts = baseUrl.match(urlPartsRegex); + if (!baseUrlParts) { + throw new Error("Could not parse page url - '"+baseUrl+"'"); + } + urlParts[1] = urlParts[1] || baseUrlParts[1] || ""; + if (!urlParts[2]) { + urlParts[3] = baseUrlParts[3] + urlParts[3]; + } + } + + if (urlParts[3]) { + directories = urlParts[3].replace(/\\/g, "/").split("/"); + + // extract out . before .. so .. doesn't absorb a non-directory + for(i = 0; i < directories.length; i++) { + if (directories[i] === ".") { + directories.splice(i, 1); + i -= 1; + } + } + + for(i = 0; i < directories.length; i++) { + if (directories[i] === ".." && i > 0) { + directories.splice(i-1, 2); + i -= 2; + } + } + } + + returner.hostPart = urlParts[1]; + returner.directories = directories; + returner.path = urlParts[1] + directories.join("/"); + returner.fileUrl = returner.path + (urlParts[4] || ""); + returner.url = returner.fileUrl + (urlParts[5] || ""); + return returner; +} + +function pathDiff(url, baseUrl) { + // diff between two paths to create a relative path + + var urlParts = extractUrlParts(url), + baseUrlParts = extractUrlParts(baseUrl), + i, max, urlDirectories, baseUrlDirectories, diff = ""; + if (urlParts.hostPart !== baseUrlParts.hostPart) { + return ""; + } + max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); + for(i = 0; i < max; i++) { + if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; } + } + baseUrlDirectories = baseUrlParts.directories.slice(i); + urlDirectories = urlParts.directories.slice(i); + for(i = 0; i < baseUrlDirectories.length-1; i++) { + diff += "../"; + } + for(i = 0; i < urlDirectories.length-1; i++) { + diff += urlDirectories[i] + "/"; + } + return diff; +} + +function getXMLHttpRequest() { + if (window.XMLHttpRequest) { + return new XMLHttpRequest(); + } else { + try { + /*global ActiveXObject */ + return new ActiveXObject("MSXML2.XMLHTTP.3.0"); + } catch (e) { + log("browser doesn't support AJAX.", logLevel.errors); + return null; + } + } +} + +function doXHR(url, type, callback, errback) { + var xhr = getXMLHttpRequest(); + var async = isFileProtocol ? less.fileAsync : less.async; + + if (typeof(xhr.overrideMimeType) === 'function') { + xhr.overrideMimeType('text/css'); + } + log("XHR: Getting '" + url + "'", logLevel.info); + xhr.open('GET', url, async); + xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); + xhr.send(null); + + function handleResponse(xhr, callback, errback) { + if (xhr.status >= 200 && xhr.status < 300) { + callback(xhr.responseText, + xhr.getResponseHeader("Last-Modified")); + } else if (typeof(errback) === 'function') { + errback(xhr.status, url); + } + } + + if (isFileProtocol && !less.fileAsync) { + if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { + callback(xhr.responseText); + } else { + errback(xhr.status, url); + } + } else if (async) { + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + handleResponse(xhr, callback, errback); + } + }; + } else { + handleResponse(xhr, callback, errback); + } +} + +function loadFile(originalHref, currentFileInfo, callback, env, modifyVars) { + + if (currentFileInfo && currentFileInfo.currentDirectory && !/^([a-z-]+:)?\//.test(originalHref)) { + originalHref = currentFileInfo.currentDirectory + originalHref; + } + + // sheet may be set to the stylesheet for the initial load or a collection of properties including + // some env variables for imports + var hrefParts = extractUrlParts(originalHref, window.location.href); + var href = hrefParts.url; + var newFileInfo = { + currentDirectory: hrefParts.path, + filename: href + }; + + if (currentFileInfo) { + newFileInfo.entryPath = currentFileInfo.entryPath; + newFileInfo.rootpath = currentFileInfo.rootpath; + newFileInfo.rootFilename = currentFileInfo.rootFilename; + newFileInfo.relativeUrls = currentFileInfo.relativeUrls; + } else { + newFileInfo.entryPath = hrefParts.path; + newFileInfo.rootpath = less.rootpath || hrefParts.path; + newFileInfo.rootFilename = href; + newFileInfo.relativeUrls = env.relativeUrls; + } + + if (newFileInfo.relativeUrls) { + if (env.rootpath) { + newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path; + } else { + newFileInfo.rootpath = hrefParts.path; + } + } + + if (env.useFileCache && fileCache[href]) { + try { + var lessText = fileCache[href]; + callback(null, lessText, href, newFileInfo, { lastModified: new Date() }); + } catch (e) { + callback(e, null, href); + } + return; + } + + doXHR(href, env.mime, function (data, lastModified) { + // per file cache + fileCache[href] = data; + + // Use remote copy (re-parse) + try { + callback(null, data, href, newFileInfo, { lastModified: lastModified }); + } catch (e) { + callback(e, null, href); + } + }, function (status, url) { + callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, href); + }); +} + +function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) { + + var env = new less.tree.parseEnv(less); + env.mime = sheet.type; + + if (modifyVars || less.globalVars) { + env.useFileCache = true; + } + + loadFile(sheet.href, null, function(e, data, path, newFileInfo, webInfo) { + + if (webInfo) { + webInfo.remaining = remaining; + + var css = cache && cache.getItem(path), + timestamp = cache && cache.getItem(path + ':timestamp'); + + if (!reload && timestamp && webInfo.lastModified && + (new(Date)(webInfo.lastModified).valueOf() === + new(Date)(timestamp).valueOf())) { + // Use local copy + createCSS(css, sheet); + webInfo.local = true; + callback(null, null, data, sheet, webInfo, path); + return; + } + } + + //TODO add tests around how this behaves when reloading + removeError(path); + + if (data) { + env.currentFileInfo = newFileInfo; + new(less.Parser)(env).parse(data, function (e, root) { + if (e) { return callback(e, null, null, sheet); } + try { + callback(e, root, data, sheet, webInfo, path); + } catch (e) { + callback(e, null, null, sheet); + } + }, {modifyVars: modifyVars, globalVars: less.globalVars}); + } else { + callback(e, null, null, sheet, webInfo, path); + } + }, env, modifyVars); +} + +function loadStyleSheets(callback, reload, modifyVars) { + for (var i = 0; i < less.sheets.length; i++) { + loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars); + } +} + +function initRunningMode(){ + if (less.env === 'development') { + less.optimization = 0; + less.watchTimer = setInterval(function () { + if (less.watchMode) { + loadStyleSheets(function (e, root, _, sheet, env) { + if (e) { + error(e, sheet.href); + } else if (root) { + createCSS(root.toCSS(less), sheet, env.lastModified); + } + }); + } + }, less.poll); + } else { + less.optimization = 3; + } +} + + + +// +// Watch mode +// +less.watch = function () { + if (!less.watchMode ){ + less.env = 'development'; + initRunningMode(); + } + this.watchMode = true; + return true; +}; + +less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; }; + +if (/!watch/.test(location.hash)) { + less.watch(); +} + +if (less.env != 'development') { + try { + cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage; + } catch (_) {} +} + +// +// Get all tags with the 'rel' attribute set to "stylesheet/less" +// +var links = document.getElementsByTagName('link'); + +less.sheets = []; + +for (var i = 0; i < links.length; i++) { + if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) && + (links[i].type.match(typePattern)))) { + less.sheets.push(links[i]); + } +} + +// +// With this function, it's possible to alter variables and re-render +// CSS without reloading less-files +// +less.modifyVars = function(record) { + less.refresh(false, record); +}; + +less.refresh = function (reload, modifyVars) { + var startTime, endTime; + startTime = endTime = new Date(); + + loadStyleSheets(function (e, root, _, sheet, env) { + if (e) { + return error(e, sheet.href); + } + if (env.local) { + log("loading " + sheet.href + " from cache.", logLevel.info); + } else { + log("parsed " + sheet.href + " successfully.", logLevel.info); + createCSS(root.toCSS(less), sheet, env.lastModified); + } + log("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms', logLevel.info); + if (env.remaining === 0) { + log("css generated in " + (new Date() - startTime) + 'ms', logLevel.info); + } + endTime = new Date(); + }, reload, modifyVars); + + loadStyles(modifyVars); +}; + +less.refreshStyles = loadStyles; + +less.Parser.fileLoader = loadFile; + +less.refresh(less.env === 'development'); + +// amd.js +// +// Define Less as an AMD module. +if (typeof define === "function" && define.amd) { + define(function () { return less; } ); +} + +})(window); +;!function(exports, undefined) { + + var isArray = Array.isArray ? Array.isArray : function _isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + var defaultMaxListeners = 10; + + function init() { + this._events = {}; + if (this._conf) { + configure.call(this, this._conf); + } + } + + function configure(conf) { + if (conf) { + + this._conf = conf; + + conf.delimiter && (this.delimiter = conf.delimiter); + conf.maxListeners && (this._events.maxListeners = conf.maxListeners); + conf.wildcard && (this.wildcard = conf.wildcard); + conf.newListener && (this.newListener = conf.newListener); + + if (this.wildcard) { + this.listenerTree = {}; + } + } + } + + function EventEmitter(conf) { + this._events = {}; + this.newListener = false; + configure.call(this, conf); + } + + // + // Attention, function return type now is array, always ! + // It has zero elements if no any matches found and one or more + // elements (leafs) if there are matches + // + function searchListenerTree(handlers, type, tree, i) { + if (!tree) { + return []; + } + var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, + typeLength = type.length, currentType = type[i], nextType = type[i+1]; + if (i === typeLength && tree._listeners) { + // + // If at the end of the event(s) list and the tree has listeners + // invoke those listeners. + // + if (typeof tree._listeners === 'function') { + handlers && handlers.push(tree._listeners); + return [tree]; + } else { + for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { + handlers && handlers.push(tree._listeners[leaf]); + } + return [tree]; + } + } + + if ((currentType === '*' || currentType === '**') || tree[currentType]) { + // + // If the event emitted is '*' at this part + // or there is a concrete match at this patch + // + if (currentType === '*') { + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); + } + } + return listeners; + } else if(currentType === '**') { + endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); + if(endReached && tree._listeners) { + // The next element has a _listeners, add it to the handlers. + listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); + } + + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + if(branch === '*' || branch === '**') { + if(tree[branch]._listeners && !endReached) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); + } + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } else if(branch === nextType) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); + } else { + // No match on this one, shift into the tree but not in the type array. + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } + } + } + return listeners; + } + + listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); + } + + xTree = tree['*']; + if (xTree) { + // + // If the listener tree will allow any match for this part, + // then recursively explore all branches of the tree + // + searchListenerTree(handlers, type, xTree, i+1); + } + + xxTree = tree['**']; + if(xxTree) { + if(i < typeLength) { + if(xxTree._listeners) { + // If we have a listener on a '**', it will catch all, so add its handler. + searchListenerTree(handlers, type, xxTree, typeLength); + } + + // Build arrays of matching next branches and others. + for(branch in xxTree) { + if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { + if(branch === nextType) { + // We know the next element will match, so jump twice. + searchListenerTree(handlers, type, xxTree[branch], i+2); + } else if(branch === currentType) { + // Current node matches, move into the tree. + searchListenerTree(handlers, type, xxTree[branch], i+1); + } else { + isolatedBranch = {}; + isolatedBranch[branch] = xxTree[branch]; + searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); + } + } + } + } else if(xxTree._listeners) { + // We have reached the end and still on a '**' + searchListenerTree(handlers, type, xxTree, typeLength); + } else if(xxTree['*'] && xxTree['*']._listeners) { + searchListenerTree(handlers, type, xxTree['*'], typeLength); + } + } + + return listeners; + } + + function growListenerTree(type, listener) { + + type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + + // + // Looks for two consecutive '**', if so, don't add the event at all. + // + for(var i = 0, len = type.length; i+1 < len; i++) { + if(type[i] === '**' && type[i+1] === '**') { + return; + } + } + + var tree = this.listenerTree; + var name = type.shift(); + + while (name) { + + if (!tree[name]) { + tree[name] = {}; + } + + tree = tree[name]; + + if (type.length === 0) { + + if (!tree._listeners) { + tree._listeners = listener; + } + else if(typeof tree._listeners === 'function') { + tree._listeners = [tree._listeners, listener]; + } + else if (isArray(tree._listeners)) { + + tree._listeners.push(listener); + + if (!tree._listeners.warned) { + + var m = defaultMaxListeners; + + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } + + if (m > 0 && tree._listeners.length > m) { + + tree._listeners.warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + tree._listeners.length); + console.trace(); + } + } + } + return true; + } + name = type.shift(); + } + return true; + } + + // By default EventEmitters will print a warning if more than + // 10 listeners are added to it. This is a useful default which + // helps finding memory leaks. + // + // Obviously not all Emitters should be limited to 10. This function allows + // that to be increased. Set to zero for unlimited. + + EventEmitter.prototype.delimiter = '.'; + + EventEmitter.prototype.setMaxListeners = function(n) { + this._events || init.call(this); + this._events.maxListeners = n; + if (!this._conf) this._conf = {}; + this._conf.maxListeners = n; + }; + + EventEmitter.prototype.event = ''; + + EventEmitter.prototype.once = function(event, fn) { + this.many(event, 1, fn); + return this; + }; + + EventEmitter.prototype.many = function(event, ttl, fn) { + var self = this; + + if (typeof fn !== 'function') { + throw new Error('many only accepts instances of Function'); + } + + function listener() { + if (--ttl === 0) { + self.off(event, listener); + } + fn.apply(this, arguments); + } + + listener._origin = fn; + + this.on(event, listener); + + return self; + }; + + EventEmitter.prototype.emit = function() { + + this._events || init.call(this); + + var type = arguments[0]; + + if (type === 'newListener' && !this.newListener) { + if (!this._events.newListener) { return false; } + } + + // Loop through the *_all* functions and invoke them. + if (this._all) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + for (i = 0, l = this._all.length; i < l; i++) { + this.event = type; + this._all[i].apply(this, args); + } + } + + // If there is no 'error' event listener then throw. + if (type === 'error') { + + if (!this._all && + !this._events.error && + !(this.wildcard && this.listenerTree.error)) { + + if (arguments[1] instanceof Error) { + throw arguments[1]; // Unhandled 'error' event + } else { + throw new Error("Uncaught, unspecified 'error' event."); + } + return false; + } + } + + var handler; + + if(this.wildcard) { + handler = []; + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + searchListenerTree.call(this, handler, ns, this.listenerTree, 0); + } + else { + handler = this._events[type]; + } + + if (typeof handler === 'function') { + this.event = type; + if (arguments.length === 1) { + handler.call(this); + } + else if (arguments.length > 1) + switch (arguments.length) { + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + handler.apply(this, args); + } + return true; + } + else if (handler) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + + var listeners = handler.slice(); + for (var i = 0, l = listeners.length; i < l; i++) { + this.event = type; + listeners[i].apply(this, args); + } + return (listeners.length > 0) || this._all; + } + else { + return this._all; + } + + }; + + EventEmitter.prototype.on = function(type, listener) { + + if (typeof type === 'function') { + this.onAny(type); + return this; + } + + if (typeof listener !== 'function') { + throw new Error('on only accepts instances of Function'); + } + this._events || init.call(this); + + // To avoid recursion in the case that type == "newListeners"! Before + // adding it to the listeners, first emit "newListeners". + this.emit('newListener', type, listener); + + if(this.wildcard) { + growListenerTree.call(this, type, listener); + return this; + } + + if (!this._events[type]) { + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + } + else if(typeof this._events[type] === 'function') { + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + } + else if (isArray(this._events[type])) { + // If we've already got an array, just append. + this._events[type].push(listener); + + // Check for listener leak + if (!this._events[type].warned) { + + var m = defaultMaxListeners; + + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } + + if (m > 0 && this._events[type].length > m) { + + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + } + return this; + }; + + EventEmitter.prototype.onAny = function(fn) { + + if(!this._all) { + this._all = []; + } + + if (typeof fn !== 'function') { + throw new Error('onAny only accepts instances of Function'); + } + + // Add the function to the event listener collection. + this._all.push(fn); + return this; + }; + + EventEmitter.prototype.addListener = EventEmitter.prototype.on; + + EventEmitter.prototype.off = function(type, listener) { + if (typeof listener !== 'function') { + throw new Error('removeListener only takes instances of Function'); + } + + var handlers,leafs=[]; + + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); + } + else { + // does not use listeners(), so no side effect of creating _events[type] + if (!this._events[type]) return this; + handlers = this._events[type]; + leafs.push({_listeners:handlers}); + } + + for (var iLeaf=0; iLeaf 0) { + fns = this._all; + for(i = 0, l = fns.length; i < l; i++) { + if(fn === fns[i]) { + fns.splice(i, 1); + return this; + } + } + } else { + this._all = []; + } + return this; + }; + + EventEmitter.prototype.removeListener = EventEmitter.prototype.off; + + EventEmitter.prototype.removeAllListeners = function(type) { + if (arguments.length === 0) { + !this._events || init.call(this); + return this; + } + + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); + + for (var iLeaf=0; iLeaf+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; + + // Internal: Get indexes for selector. + // + // selector - String CSS selector + // + // Returns Array of {index, key}. + function parseSelectorIndexes(allIndexes, selector) { + allIndexes = allIndexes.slice(0).concat(allIndexes['default']); + + var allIndexesLen = allIndexes.length, + i, j, m, dup, rest = selector, + key, index, indexes = []; + + do { + chunker.exec(''); + if (m = chunker.exec(rest)) { + rest = m[3]; + if (m[2] || !rest) { + for (i = 0; i < allIndexesLen; i++) { + index = allIndexes[i]; + if (key = index.selector(m[1])) { + j = indexes.length; + dup = false; + while (j--) { + if (indexes[j].index === index && indexes[j].key === key) { + dup = true; + break; + } + } + if (!dup) { + indexes.push({index: index, key: key}); + } + break; + } + } + } + } + } while (m); + + return indexes; + } + + // Internal: Find first item in Array that is a prototype of `proto`. + // + // ary - Array of objects + // proto - Prototype of expected item in `ary` + // + // Returns object from `ary` if found. Otherwise returns undefined. + function findByPrototype(ary, proto) { + var i, len, item; + for (i = 0, len = ary.length; i < len; i++) { + item = ary[i]; + if (proto.isPrototypeOf(item)) { + return item; + } + } + } + + // Public: Log when added selector falls under the default index. + // + // This API should not be considered stable. May change between + // minor versions. + // + // obj - {selector, data} Object + // + // SelectorSet.prototype.logDefaultIndexUsed = function(obj) { + // console.warn(obj.selector, "could not be indexed"); + // }; + // + // Returns nothing. + SelectorSet.prototype.logDefaultIndexUsed = function() {}; + + // Public: Add selector to set. + // + // selector - String CSS selector + // data - Optional data Object (default: undefined) + // + // Returns nothing. + SelectorSet.prototype.add = function(selector, data) { + var obj, i, indexProto, key, index, objs, + selectorIndexes, selectorIndex, + indexes = this.activeIndexes, + selectors = this.selectors; + + if (typeof selector !== 'string') { + return; + } + + obj = { + id: this.uid++, + selector: selector, + data: data + }; + + selectorIndexes = parseSelectorIndexes(this.indexes, selector); + for (i = 0; i < selectorIndexes.length; i++) { + selectorIndex = selectorIndexes[i]; + key = selectorIndex.key; + indexProto = selectorIndex.index; + + index = findByPrototype(indexes, indexProto); + if (!index) { + index = Object.create(indexProto); + index.map = new Map(); + indexes.push(index); + } + + if (indexProto === this.indexes['default']) { + this.logDefaultIndexUsed(obj); + } + objs = index.map.get(key); + if (!objs) { + objs = []; + index.map.set(key, objs); + } + objs.push(obj); + } + + this.size++; + selectors.push(selector); + }; + + // Public: Remove selector from set. + // + // selector - String CSS selector + // data - Optional data Object (default: undefined) + // + // Returns nothing. + SelectorSet.prototype.remove = function(selector, data) { + if (typeof selector !== 'string') { + return; + } + + var selectorIndexes, selectorIndex, i, j, k, selIndex, objs, obj; + var indexes = this.activeIndexes; + var removedIds = {}; + var removeAll = arguments.length === 1; + + selectorIndexes = parseSelectorIndexes(this.indexes, selector); + for (i = 0; i < selectorIndexes.length; i++) { + selectorIndex = selectorIndexes[i]; + + j = indexes.length; + while (j--) { + selIndex = indexes[j]; + if (selectorIndex.index.isPrototypeOf(selIndex)) { + objs = selIndex.map.get(selectorIndex.key); + if (objs) { + k = objs.length; + while (k--) { + obj = objs[k]; + if (obj.selector === selector && (removeAll || obj.data === data)) { + objs.splice(k, 1); + removedIds[obj.id] = true; + } + } + } + break; + } + } + } + + this.size -= Object.keys(removedIds).length; + }; + + // Sort by id property handler. + // + // a - Selector obj. + // b - Selector obj. + // + // Returns Number. + function sortById(a, b) { + return a.id - b.id; + } + + // Public: Find all matching decendants of the context element. + // + // context - An Element + // + // Returns Array of {selector, data, elements} matches. + SelectorSet.prototype.queryAll = function(context) { + if (!this.selectors.length) { + return []; + } + + var matches = {}, results = []; + var els = this.querySelectorAll(this.selectors.join(', '), context); + + var i, j, len, len2, el, m, match, obj; + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + m = this.matches(el); + for (j = 0, len2 = m.length; j < len2; j++) { + obj = m[j]; + if (!matches[obj.id]) { + match = { + id: obj.id, + selector: obj.selector, + data: obj.data, + elements: [] + }; + matches[obj.id] = match; + results.push(match); + } else { + match = matches[obj.id]; + } + match.elements.push(el); + } + } + + return results.sort(sortById); + }; + + // Public: Match element against all selectors in set. + // + // el - An Element + // + // Returns Array of {selector, data} matches. + SelectorSet.prototype.matches = function(el) { + if (!el) { + return []; + } + + var i, j, k, len, len2, len3, index, keys, objs, obj, id; + var indexes = this.activeIndexes, matchedIds = {}, matches = []; + + for (i = 0, len = indexes.length; i < len; i++) { + index = indexes[i]; + keys = index.element(el); + if (keys) { + for (j = 0, len2 = keys.length; j < len2; j++) { + if (objs = index.map.get(keys[j])) { + for (k = 0, len3 = objs.length; k < len3; k++) { + obj = objs[k]; + id = obj.id; + if (!matchedIds[id] && this.matchesSelector(el, obj.selector)) { + matchedIds[id] = true; + matches.push(obj); + } + } + } + } + } + } + + return matches.sort(sortById); + }; + + // Public: Expose SelectorSet as a global on window. + window.SelectorSet = SelectorSet; +})(window); + +(function() { + var MODULES; + + MODULES = { + underscore: this._, + sizzle: this.Sizzle, + less: this.less, + eventemitter2: this.EventEmitter2, + 'selector-set': this.SelectorSet + }; + + this._ = this.__polyfills_originalGlobals['underscore']; + + this.less = this.__polyfills_originalGlobals['less']; + + this.EventEmitter2 = this.__polyfills_originalGlobals['eventemitter2']; + + this.define = function(moduleName, deps, callback) { + var args, depName, first, second, val; + args = (function() { + var _i, _len, _ref, _results; + _results = []; + for (_i = 0, _len = deps.length; _i < _len; _i++) { + depName = deps[_i]; + _ref = depName.split('!'), first = _ref[0], second = _ref[1]; + depName = second || first; + if (!MODULES[depName]) { + throw new Error('Files are not concatenated based on their dependencies'); + } + _results.push(MODULES[depName]); + } + return _results; + })(); + val = callback.apply(this, args); + MODULES[moduleName] = val; + return val; + }; + +}).call(this); + +(function() { + var __slice = [].slice; + + define('polyfill-path/selector-tree', [], function() { + var CHUNKIFY, SelectorTree, chunker; + chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; + CHUNKIFY = function(selector) { + var chunks, m, rest; + rest = selector; + chunks = []; + while (true) { + chunker.exec(''); + if (m = chunker.exec(rest)) { + rest = m[3]; + chunks.push(m[1]); + if (m[2] || !rest) { + break; + } + } + if (!m) { + break; + } + } + return chunks; + }; + return SelectorTree = (function() { + function SelectorTree(children, data) { + this.children = children != null ? children : {}; + this.data = data != null ? data : []; + } + + SelectorTree.prototype._add = function(chunks, datum) { + var first, rest; + if (chunks.length === 0) { + return this.data.push(datum); + } else { + first = chunks[0], rest = 2 <= chunks.length ? __slice.call(chunks, 1) : []; + if (!this.children[first]) { + this.children[first] = new SelectorTree(); + } + return this.children[first]._add(rest, datum); + } + }; + + SelectorTree.prototype.clear = function() { + this.children = {}; + return this.data = []; + }; + + SelectorTree.prototype.add = function(selector, datum) { + var sel, selectors, _i, _len, _results; + selectors = selector.split(','); + _results = []; + for (_i = 0, _len = selectors.length; _i < _len; _i++) { + sel = selectors[_i]; + _results.push(this._add(CHUNKIFY(sel), datum)); + } + return _results; + }; + + SelectorTree.prototype.findMatches = function(rootEl, acc, selectorFirst) { + var els, selector, selectorSnippet, tree, _ref; + if (acc == null) { + acc = {}; + } + if (selectorFirst == null) { + selectorFirst = ''; + } + _ref = this.children; + for (selectorSnippet in _ref) { + tree = _ref[selectorSnippet]; + selector = "" + selectorFirst + " " + selectorSnippet; + if (tree.data.length > 0) { + console.log("KLASDJFKLAJF Querying " + selector); + els = rootEl.querySelectorAll(selector); + acc[selector] = { + els: els, + data: tree.data + }; + } else { + tree.findMatches(rootEl, acc, selector); + } + } + return acc; + }; + + SelectorTree.prototype.getSelectors = function(acc, selectorFirst) { + var selector, selectorSnippet, tree, _ref; + if (acc == null) { + acc = {}; + } + if (selectorFirst == null) { + selectorFirst = ''; + } + _ref = this.children; + for (selectorSnippet in _ref) { + tree = _ref[selectorSnippet]; + selector = "" + selectorFirst + " " + selectorSnippet; + if (tree.data.length > 0) { + acc[selector] = tree.data; + } else { + tree.getSelector(acc, selector); + } + } + return acc; + }; + + SelectorTree.prototype._get = function(chunks) { + var child, first; + if (chunks.length) { + first = chunks.shift(); + child = this.children[first]; + if (child) { + return child._get(chunks); + } else { + return []; + } + } else { + return this.data; + } + }; + + SelectorTree.prototype.get = function(selector) { + var chunks; + chunks = CHUNKIFY(selector); + return this._get(chunks); + }; + + return SelectorTree; + + })(); + }); + +}).call(this); + +(function() { + var __slice = [].slice, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + + define('polyfill-path/fixed-point-runner', ['underscore', 'less', 'eventemitter2', 'selector-set'], function(_, less, EventEmitter, SelectorSet) { + var CSS_FUNCTION_WRAPPER, CSS_SELECTIVITY_COMPARATOR, FixedPointRunner, IMPORTANT_COMPARATOR, IMPORTANT_FIXER, SPECIFICITY_SORT; + CSS_SELECTIVITY_COMPARATOR = function(cls1, cls2) { + var compare, elements1, elements2, isClassOrAttrib, isElementOrPseudo, isIdAttrib; + elements1 = cls1.elements; + elements2 = cls2.elements; + if (!(elements1 || elements2)) { + console.error('BUG: Selectivity Comparator has null elements'); + } + compare = function(iterator, els1, els2) { + var x1, x2; + x1 = _.reduce(elements1, iterator, 0); + x2 = _.reduce(elements2, iterator, 0); + if (x1 < x2) { + return -1; + } + if (x1 > x2) { + return 1; + } + return 0; + }; + isIdAttrib = function(n, el) { + var _ref, _ref1; + return (_ref = '#' === ((_ref1 = el.value) != null ? _ref1[0] : void 0)) != null ? _ref : n + { + 1: n + }; + }; + isClassOrAttrib = function(n, el) { + if ('.' === el.value[0] || '[' === el.value[0]) { + return n + 1; + } + return n; + }; + isElementOrPseudo = function(n, el) { + if ((el.value instanceof less.tree.Attribute) || ':' === el.value[0] || /^[a-zA-Z]/.test(el.value)) { + return n + 1; + } + return n; + }; + return compare(isIdAttrib) || compare(isClassOrAttrib) || compare(isElementOrPseudo); + }; + SPECIFICITY_SORT = function(autogenClasses) { + var autogenClass, foundDisplayRule, i, newRules, rule, _i, _j, _len, _len1, _ref; + newRules = []; + autogenClasses.sort(CSS_SELECTIVITY_COMPARATOR); + for (_i = 0, _len = autogenClasses.length; _i < _len; _i++) { + autogenClass = autogenClasses[_i]; + _ref = autogenClass.rules; + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + rule = _ref[_j]; + newRules.push(rule); + } + } + foundDisplayRule = false; + newRules.reverse(); + i = 0; + while (i < newRules.length) { + if ('display' === newRules[i].name) { + if (foundDisplayRule) { + newRules.splice(i, 1); + continue; + } else { + foundDisplayRule = true; + } + } + i += 1; + } + return newRules; + }; + IMPORTANT_FIXER = function(autogenRules) { + var r, v, _i, _len, _ref, _results; + _results = []; + for (_i = 0, _len = autogenRules.length; _i < _len; _i++) { + r = autogenRules[_i]; + if (!r.important) { + v = (_ref = r.value.value) != null ? _ref[0] : void 0; + if (v instanceof less.tree.Anonymous && /\!important$/.test(v.value)) { + r.important = ' !important'; + _results.push(v.value = v.value.replace(/\s+\!important$/, '')); + } else { + _results.push(void 0); + } + } else { + _results.push(void 0); + } + } + return _results; + }; + IMPORTANT_COMPARATOR = function(a, b) { + if (a.important && b.important) { + return 0; + } + if (a.important) { + return -1; + } + if (b.important) { + return 1; + } + return 0; + }; + CSS_FUNCTION_WRAPPER = function(funcName, func) { + return function() { + var ret; + ret = func.apply(this, [this.env].concat(__slice.call(arguments))); + if (ret == null) { + return new less.tree.Call(funcName, _.toArray(arguments)); + } else if (ret.toCSS) { + return ret; + } else if (ret instanceof Array) { + return new less.tree.ArrayTreeNode(ret); + } else if (_.isString(ret)) { + return new less.tree.Quoted("'" + ret + "'", ret); + } else if (_.isNumber(ret)) { + return new less.tree.Dimension(ret); + } else { + return new less.tree.Anonymous(ret); + } + }; + }; + return FixedPointRunner = (function(_super) { + __extends(FixedPointRunner, _super); + + function FixedPointRunner(rootNode, plugins, set, removeAutogenClasses) { + var func, funcName, plugin, ruleFunc, ruleName, _i, _len, _ref, _ref1, _ref2; + this.rootNode = rootNode; + this.plugins = plugins; + this.set = set; + this.removeAutogenClasses = removeAutogenClasses; + FixedPointRunner.__super__.constructor.call(this, { + wildcard: true + }); + this.squirreledEnv = {}; + this.functions = {}; + this.lookupClasses = {}; + this.lookupCounter = 0; + this.rules = []; + _ref = this.plugins; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + plugin = _ref[_i]; + _ref1 = plugin.functions; + for (funcName in _ref1) { + func = _ref1[funcName]; + this.functions[funcName] = func.bind(plugin); + } + _ref2 = plugin.rules; + for (ruleName in _ref2) { + ruleFunc = _ref2[ruleName]; + this.rules.push({ + name: ruleName, + func: ruleFunc.bind(plugin) + }); + } + } + } + + FixedPointRunner.prototype.lookupAutogenClasses = function(domnode) { + var classes, cls, foundClasses, _i, _len; + if (domnode.className) { + if ('string' === typeof domnode.className) { + classes = domnode.className; + } else { + classes = domnode.className.baseVal; + } + classes = classes.split(' '); + foundClasses = []; + for (_i = 0, _len = classes.length; _i < _len; _i++) { + cls = classes[_i]; + if (/^js-polyfill-autoclass-/.test(cls)) { + foundClasses = foundClasses.concat(this.set.get("." + cls)); + } + } + return foundClasses; + } else { + return []; + } + }; + + FixedPointRunner.prototype.tick = function(interestingNodes) { + var domnode, env, _i, _len, + _this = this; + this.emit('tick.start', interestingNodes.length); + this.somethingChanged = 0; + env = new less.tree.evalEnv(); + env.state = {}; + env.helpers = { + interestingByHref: function(href) { + var id; + if ('#' !== href[0]) { + console.error('ERROR: href must start with a # character'); + } + id = href.substring(1); + if (!_this.squirreledEnv[id]) { + console.error('BUG: id was not marked and squirreled before being looked up'); + } + return _this.squirreledEnv[id]; + }, + markInterestingByHref: function(href) { + var id, target, wasAlreadyMarked; + if ('#' !== href[0]) { + console.error('ERROR: href must start with a # character'); + } + id = href.substring(1); + wasAlreadyMarked = !!_this.squirreledEnv[id]; + if (!wasAlreadyMarked) { + target = document.getElementById(id); + if (target) { + _this.somethingChanged += 1; + target.classList.add('js-polyfill-interesting'); + target.classList.add('js-polyfill-target'); + } else { + console.warn("ERROR: Invalid target id: #" + id); + } + } + return !wasAlreadyMarked; + }, + didSomthingNonIdempotent: function(msg) { + return _this.somethingChanged += 1; + } + }; + for (_i = 0, _len = interestingNodes.length; _i < _len; _i++) { + domnode = interestingNodes[_i]; + this.evalNode(env, domnode); + } + this.emit('tick.end', this.somethingChanged); + return this.somethingChanged; + }; + + FixedPointRunner.prototype.pullRulesFromCache = function(domnode) { + var autogenClasses, autogenRule, autogenRules, filteredRules, id, name, _i, _len; + if (domnode.jsPolyfillId) { + filteredRules = this.lookupClasses[domnode.jsPolyfillId]; + if (filteredRules) { + return filteredRules; + } + } + id = this.lookupCounter += 1; + autogenClasses = this.lookupAutogenClasses(domnode); + autogenRules = SPECIFICITY_SORT(autogenClasses); + IMPORTANT_FIXER(autogenRules); + autogenRules.sort(IMPORTANT_COMPARATOR); + filteredRules = {}; + for (_i = 0, _len = autogenRules.length; _i < _len; _i++) { + autogenRule = autogenRules[_i]; + name = autogenRule.name; + if (name instanceof Array) { + name = name.join(''); + } + if (filteredRules[name] == null) { + filteredRules[name] = []; + } + filteredRules[name].push(autogenRule); + } + this.lookupClasses[id] = filteredRules; + domnode.jsPolyfillId = id; + return filteredRules; + }; + + FixedPointRunner.prototype.evalNode = function(env, domnode) { + var autogenRule, autogenRules, beforeSomethingChanged, filteredRules, i, pluginRule, rule, ruleName, ruleValNode, rules, somethingNotCompleted, targetEnv, understood, understoodRules, unused, _i, _j, _k, _len, _len1, _len2, _ref; + this.emit('tick.node', domnode); + somethingNotCompleted = false; + if (domnode.compareDocumentPosition(document.body) & Node.DOCUMENT_POSITION_DISCONNECTED) { + return; + } + env.helpers.contextNode = domnode; + autogenRules = this.pullRulesFromCache(domnode); + _ref = this.rules; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + pluginRule = _ref[_i]; + if ('*' === pluginRule.name) { + filteredRules = []; + for (unused in autogenRules) { + rules = autogenRules[unused]; + for (_j = 0, _len1 = rules.length; _j < _len1; _j++) { + rule = rules[_j]; + filteredRules.push(rule); + } + } + } else { + filteredRules = autogenRules[pluginRule.name]; + } + understoodRules = {}; + if (filteredRules) { + for (i = _k = 0, _len2 = filteredRules.length; _k < _len2; i = ++_k) { + autogenRule = filteredRules[i]; + ruleName = autogenRule.name; + if (ruleName instanceof Array) { + ruleName = ruleName.join(''); + } + ruleValNode = autogenRule.value; + if (!ruleName) { + continue; + } + if (ruleName in understoodRules) { + continue; + } + if ('completed' === domnode.getAttribute("data-js-polyfill-rule-" + ruleName)) { + continue; + } + beforeSomethingChanged = this.somethingChanged; + if ('*' === pluginRule.name) { + understood = pluginRule.func(env, ruleName, ruleValNode); + } else { + understood = pluginRule.func(env, ruleValNode); + } + somethingNotCompleted = true; + if (understood) { + understoodRules[ruleName] = true; + domnode.setAttribute("data-js-polyfill-rule-" + ruleName, 'evaluated'); + if (understood === 'RULE_COMPLETED') { + this.somethingChanged += 1; + domnode.setAttribute("data-js-polyfill-rule-" + ruleName, 'completed'); + } else if (understood === 'NODE_REMOVED') { + if (domnode.jsPolyfillId) { + delete this.lookupClasses[domnode.jsPolyfillId]; + } + return; + } + break; + } + if (beforeSomethingChanged !== this.somethingChanged) { + break; + } + } + } + } + if (domnode.classList.contains('js-polyfill-target')) { + targetEnv = { + helpers: _.clone(env.helpers), + state: JSON.parse(JSON.stringify(_.omit(env.state, 'buckets'))) + }; + targetEnv.helpers.contextNode = domnode; + return this.squirreledEnv[domnode.id] = targetEnv; + } else if (!somethingNotCompleted) { + domnode.classList.remove('js-polyfill-interesting'); + if (domnode.jsPolyfillId) { + return delete this.lookupClasses[domnode.jsPolyfillId]; + } + } + }; + + FixedPointRunner.prototype.setUp = function() { + var func, funcName, _ref, _results; + this.emit('runner.start'); + _ref = this.functions; + _results = []; + for (funcName in _ref) { + func = _ref[funcName]; + _results.push(less.tree.functions[funcName] = CSS_FUNCTION_WRAPPER(funcName, func)); + } + return _results; + }; + + FixedPointRunner.prototype.done = function() { + var className, classes, discardedClasses, el, funcName, node, nonPolyfillClasses, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1; + for (funcName in this.functions) { + delete less.tree.functions[funcName]; + } + discardedClasses = ['js-polyfill-evaluated', 'js-polyfill-interesting', 'js-polyfill-target']; + for (_i = 0, _len = discardedClasses.length; _i < _len; _i++) { + className = discardedClasses[_i]; + _ref = this.rootNode.querySelectorAll("." + className); + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + el = _ref[_j]; + el.classList.remove(className); + } + } + _ref1 = this.rootNode.querySelectorAll('.js-polyfill-autoclass:not(.js-polyfill-autoclass-keep), .js-polyfill-pseudo'); + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + node = _ref1[_k]; + if (node.classList) { + if ('string' === typeof node.className) { + classes = node.className; + } else { + classes = node.className.baseVal; + } + classes = classes.split(' '); + nonPolyfillClasses = []; + for (_l = 0, _len3 = classes.length; _l < _len3; _l++) { + className = classes[_l]; + if (!/^js-polyfill-/.test(className)) { + nonPolyfillClasses.push(className); + } + if (!this.removeAutogenClasses) { + if (/^js-polyfill-autoclass-/.test(className)) { + nonPolyfillClasses.push(className); + } + } + } + if (nonPolyfillClasses.length > 0) { + node.className = nonPolyfillClasses.join(' '); + } else { + node.removeAttribute('class'); + } + } + } + return this.emit('runner.end'); + }; + + FixedPointRunner.prototype.run = function() { + var changes, interestingNodes; + this.setUp(); + interestingNodes = this.rootNode.querySelectorAll('.js-polyfill-interesting'); + while (changes = this.tick(interestingNodes)) { + interestingNodes = this.rootNode.querySelectorAll('.js-polyfill-interesting'); + } + return this.done(); + }; + + return FixedPointRunner; + + })(EventEmitter); + }); + +}).call(this); + +(function() { + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + define('polyfill-path/selector-visitor', ['underscore', 'less', 'sizzle', 'eventemitter2'], function(_, less, Sizzle, EventEmitter) { + var AbstractSelectorVisitor, LessVisitor, PSEUDO_CLASSES, _ref; + LessVisitor = (function(_super) { + __extends(LessVisitor, _super); + + function LessVisitor(rootNode) { + this.rootNode = rootNode; + this._visitor = new less.tree.visitor(this); + this._frames = []; + } + + LessVisitor.prototype.run = function(root) { + return this._visitor.visit(root); + }; + + LessVisitor.prototype.peek = function() { + return this._frames[this._frames.length - 1]; + }; + + LessVisitor.prototype.push = function(val) { + return this._frames.push(val); + }; + + LessVisitor.prototype.pop = function() { + return this._frames.pop(); + }; + + return LessVisitor; + + })(EventEmitter); + PSEUDO_CLASSES = ['before', 'after', 'outside', 'footnote-call', 'footnote-marker', 'deferred']; + return AbstractSelectorVisitor = (function(_super) { + __extends(AbstractSelectorVisitor, _super); + + function AbstractSelectorVisitor() { + _ref = AbstractSelectorVisitor.__super__.constructor.apply(this, arguments); + return _ref; + } + + AbstractSelectorVisitor.prototype.isPreEvalVisitor = false; + + AbstractSelectorVisitor.prototype.isPreVisitor = false; + + AbstractSelectorVisitor.prototype.isReplacing = false; + + AbstractSelectorVisitor.prototype.operateOnElements = function(frame, nodes, ruleSet, domSelector, pseudoSelector, originalSelector) {}; + + AbstractSelectorVisitor.prototype.doSelector = function(node, visitArgs) { + var element, i, isPseudo, sliceIndex, _i, _len, _ref1; + isPseudo = function(name) { + var _ref1; + return _.isString(name) && /^:/.test(name) && (_ref1 = name.replace(/:/g, ''), __indexOf.call(PSEUDO_CLASSES, _ref1) >= 0); + }; + sliceIndex = node.elements.length; + _ref1 = node.elements; + for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) { + element = _ref1[i]; + if (isPseudo(element.value)) { + sliceIndex = i; + break; + } + } + return { + originalSelector: node, + domSelector: node.createDerived(node.elements.slice(0, sliceIndex)), + pseudoSelector: node.createDerived(node.elements.slice(sliceIndex)) + }; + }; + + AbstractSelectorVisitor.prototype.getNodes = function(selectorStr) { + var err; + try { + return this.rootNode.querySelectorAll(selectorStr); + } catch (_error) { + err = _error; + return Sizzle(selectorStr, this.rootNode); + } + }; + + AbstractSelectorVisitor.prototype.visitRuleset = function(node) { + var context, el, path, sel, selector, selectorStr, _i, _j, _k, _len, _len1, _len2, _ref1, _ref2, _results, + _this = this; + if (node.root) { + return; + } + _ref1 = node.paths; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + path = _ref1[_i]; + context = []; + for (_j = 0, _len1 = path.length; _j < _len1; _j++) { + sel = path[_j]; + selector = this.doSelector(sel); + selectorStr = []; + _ref2 = selector.domSelector.elements; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + el = _ref2[_k]; + selectorStr.push(el.toCSS({})); + if (/^[\*]/.test(el.value)) { + selectorStr.push(':not(.js-polyfill-pseudo)'); + } + } + selectorStr = selectorStr.join(''); + context.push(selectorStr); + } + selectorStr = context.join(''); + this.emit('selector.start', selectorStr, node.debugInfo); + this.emit('selector.end', selectorStr, node.debugInfo, function() { + return _this.getNodes(selectorStr); + }); + if (__indexOf.call(selectorStr, '@') >= 0 || __indexOf.call(selectorStr, '|') >= 0) { + + } else { + this.operateOnElements(null, node, selector.domSelector, selector.pseudoSelector, selector.originalSelector, selectorStr); + } + _results.push(context.pop()); + } + return _results; + }; + + return AbstractSelectorVisitor; + + })(LessVisitor); + }); + +}).call(this); + +(function() { + define('polyfill-path/extras', ['underscore', 'sizzle', 'less'], function(_, Sizzle, less) { + var ElementExtras, pseudo, uniqueId, uniqueIdCount, _base, _base1, _base2, _i, _len, _ref; + uniqueIdCount = 0; + uniqueId = function() { + return "id-added-via-x-ensure-id-" + (uniqueIdCount++); + }; + _ref = ['deferred', 'pass', 'match']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + pseudo = _ref[_i]; + if ((_base = Sizzle.selectors.match)[pseudo] == null) { + _base[pseudo] = RegExp(":?" + pseudo); + } + if ((_base1 = Sizzle.selectors.find)[pseudo] == null) { + _base1[pseudo] = function(match, context, isXML) { + return context; + }; + } + if ((_base2 = Sizzle.selectors.pseudos)[pseudo] == null) { + _base2[pseudo] = function(elem) { + return elem; + }; + } + } + ElementExtras = (function() { + function ElementExtras() {} + + ElementExtras.prototype.functions = { + 'x-selector': function(env, selectorNode) { + if (!(selectorNode instanceof less.tree.Quoted)) { + console.warn("ERROR: x-selector(): expects a Quoted"); + } + return selectorNode.value; + }, + 'x-sort': function(env, bucketElementsNode, sortBySelector) { + var domAry, sorted, + _this = this; + if (sortBySelector == null) { + sortBySelector = null; + } + domAry = bucketElementsNode["eval"](env).values; + sorted = _.clone(domAry).sort(function(a, b) { + if (sortBySelector) { + a = a.querySelector(sortBySelector.value); + if (!a) { + console.error('ERROR: Attempting to sort but cannot find selector'); + } + a = a != null ? a.textContent.trim() : void 0; + b = b.querySelector(sortBySelector.value); + if (!b) { + console.error('ERROR: Attempting to sort but cannot find selector'); + } + b = b != null ? b.textContent.trim() : void 0; + } else { + a = a.textContent.trim(); + b = b.textContent.trim(); + } + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + }); + return sorted; + }, + 'x-target-is': function(env, targetIdNode, selectorNode) { + var context, href, targetEnv; + if (selectorNode == null) { + selectorNode = null; + } + href = targetIdNode["eval"](env).value; + selectorNode = selectorNode["eval"](env); + if (!(selectorNode instanceof less.tree.Quoted)) { + console.warn("ERROR: x-target-is() expects a Quoted"); + } + if (!env.helpers.markInterestingByHref(href)) { + targetEnv = env.helpers.interestingByHref(href); + context = targetEnv.helpers.contextNode; + if (Sizzle.matchesSelector(context, selectorNode.value)) { + return ''; + } else { + return null; + } + } + return null; + } + }; + + ElementExtras.prototype.rules = { + 'x-tag-name': function(env, tagNameNode) { + var child, context, newEl, oldTagName, tagName, _j, _len1, _ref1; + tagNameNode = tagNameNode["eval"](env); + if (!(tagNameNode instanceof less.tree.Quoted)) { + console.warn("ERROR: move-to: expects a Quoted"); + } + context = env.helpers.contextNode; + oldTagName = context.tagName.toLowerCase(); + tagName = tagNameNode.value.toLowerCase(); + if (oldTagName !== tagName) { + newEl = document.createElement(tagName); + newEl.className = context.className; + newEl.setAttribute('data-js-polyfill-tagname-orig', oldTagName); + _ref1 = context.childNodes; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + child = _ref1[_j]; + newEl.appendChild(child); + } + context.parentNode.replaceChild(newEl, context); + env.helpers.contextNode = newEl; + env.helpers.didSomthingNonIdempotent('x-tag-name'); + return 'RULE_COMPLETED'; + } + return false; + }, + 'x-ensure-id': function(env, attributeNameNode) { + attributeNameNode = attributeNameNode["eval"](env); + if (!(attributeNameNode instanceof less.tree.Quoted)) { + console.warn("ERROR: x-ensure-id: expects a Quoted"); + } + if (!env.helpers.contextNode.getAttribute(attributeNameNode.value)) { + env.helpers.contextNode.setAttribute(attributeNameNode.value, uniqueId()); + env.helpers.didSomthingNonIdempotent('x-ensure-id'); + return 'RULE_COMPLETED'; + } + return false; + }, + 'x-attr': function(env, attrsAndVals) { + var setAttr, v, _j, _len1, _ref1, _results, + _this = this; + attrsAndVals = attrsAndVals["eval"](env); + setAttr = function(val) { + var arg, args, attrName, str, _j, _len1; + attrName = _.first(val.value).value; + args = _.rest(val.value); + str = []; + for (_j = 0, _len1 = args.length; _j < _len1; _j++) { + arg = args[_j]; + if (arg instanceof less.tree.Quoted) { + str.push(arg.value); + } else if (arg instanceof less.tree.Call) { + if ('content' === arg.name) { + arg.name = 'x-string-set-content'; + val = arg["eval"](env); + if (val instanceof less.tree.Call) { + return null; + } + str.push(val.value); + arg.name = 'content'; + } else { + return null; + } + } else { + str.push(arg.value); + } + } + return env.helpers.contextNode.setAttribute(attrName, str.join('')); + }; + if (attrsAndVals instanceof less.tree.Expression) { + return setAttr(attrsAndVals); + } else if (attrsAndVals instanceof less.tree.Value) { + _ref1 = attrsAndVals.value; + _results = []; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + v = _ref1[_j]; + _results.push(setAttr(v)); + } + return _results; + } else { + return console.warn('ERROR: invalid arguments given to "x-attr:"'); + } + } + }; + + return ElementExtras; + + })(); + return { + ElementExtras: ElementExtras + }; + }); + +}).call(this); + +(function() { + define('polyfill-path/plugins', ['underscore', 'sizzle', 'less'], function(_, Sizzle, less) { + var ArrayTreeNode, ContentSet, DisplayNone, MoveTo, StringSet, TargetCounter, TargetText, contentsFuncBuilder; + less.tree.ArrayTreeNode = ArrayTreeNode = (function() { + function ArrayTreeNode(values) { + this.values = values; + } + + ArrayTreeNode.prototype["eval"] = function() { + return this; + }; + + return ArrayTreeNode; + + })(); + MoveTo = (function() { + function MoveTo() {} + + MoveTo.prototype.functions = { + 'pending': function(env, bucketNameNode) { + var domAry, footnote, node, pendingPseudo, _i, _j, _len, _len1, _ref; + bucketNameNode = bucketNameNode["eval"](env); + if (!(bucketNameNode instanceof less.tree.Keyword)) { + console.warn("ERROR: pending(): expects a Keyword"); + } + domAry = ((_ref = env.state.buckets) != null ? _ref[bucketNameNode.value] : void 0) || []; + for (_i = 0, _len = domAry.length; _i < _len; _i++) { + node = domAry[_i]; + pendingPseudo = node.querySelector('.js-polyfill-pseudo[data-js-polyfill-rule-content="pending"]'); + if (pendingPseudo) { + return null; + } + } + for (_j = 0, _len1 = domAry.length; _j < _len1; _j++) { + node = domAry[_j]; + footnote = node.querySelector('.js-polyfill-pseudo-footnote-call'); + if (footnote) { + if (node.nextSibling) { + node.parentNode.insertBefore(footnote, node.nextSibling); + } else { + node.parentNode.append(footnote); + } + } + } + if (env.state.buckets) { + delete env.state.buckets[bucketNameNode.value]; + } + return domAry || []; + } + }; + + MoveTo.prototype.rules = { + 'move-to': function(env, bucketNameNode) { + var bucketName, domnode, ruleName, _base, _base1; + bucketNameNode = bucketNameNode["eval"](env); + if (!(bucketNameNode instanceof less.tree.Keyword)) { + console.warn("ERROR: move-to: expects a Keyword"); + } + ruleName = 'move-to'; + domnode = env.helpers.contextNode; + if ('pending' === domnode.getAttribute('data-js-polyfill-rule-content') || domnode.querySelector("[data-js-polyfill-rule-content='pending']")) { + return false; + } + bucketName = bucketNameNode.value; + if ((_base = env.state).buckets == null) { + _base.buckets = {}; + } + if ((_base1 = env.state.buckets)[bucketName] == null) { + _base1[bucketName] = []; + } + env.state.buckets[bucketName].push(env.helpers.contextNode); + return 'RULE_COMPLETED'; + } + }; + + return MoveTo; + + })(); + DisplayNone = (function() { + function DisplayNone() {} + + DisplayNone.prototype.rules = { + 'display': function(env, valNode) { + var context; + valNode = valNode["eval"](env); + if (!(valNode instanceof less.tree.Anonymous)) { + return; + } + if ('none' === valNode.value) { + context = env.helpers.contextNode; + context.parentNode.removeChild(context); + env.helpers.didSomthingNonIdempotent('display:none'); + return 'NODE_REMOVED'; + } + return true; + } + }; + + return DisplayNone; + + })(); + TargetCounter = (function() { + function TargetCounter() {} + + TargetCounter.prototype.functions = { + 'x-parent': function(env, valNode) { + var context; + context = env.helpers.contextNode; + env.helpers.contextNode = context.parentNode; + valNode = valNode["eval"](env); + env.helpers.contextNode = context; + return valNode; + }, + 'attr': function(env, attrNameNode) { + var context, val; + attrNameNode = attrNameNode["eval"](env); + if (!(attrNameNode instanceof less.tree.Keyword)) { + console.warn("ERROR: attr(): expects a Keyword"); + } + context = env.helpers.contextNode; + val = context.getAttribute(attrNameNode.value); + if (val && !isNaN(val)) { + val = parseInt(val); + } + if (!val) { + if (context.classList.contains('js-polyfill-pseudo')) { + if (context.classList.contains('js-polyfill-pseudo-outside')) { + context = context.querySelector(':not(.js-polyfill-pseudo)'); + } else { + if (context.parentNode) { + context = context.parentNode; + while (context.classList.contains('js-polyfill-pseudo')) { + context = context.parentNode; + if (!context) { + break; + } + } + } + } + val = context.getAttribute(attrNameNode.value); + if (val && !isNaN(val)) { + val = parseInt(val); + } + } + } + return val; + }, + 'counter': function(env, counterNameNode, counterType) { + var _ref; + if (counterType == null) { + counterType = null; + } + counterNameNode = counterNameNode["eval"](env); + if (!(counterNameNode instanceof less.tree.Keyword)) { + console.warn("ERROR: counter(): expects a Keyword"); + } + return this.numberingStyle((_ref = env.state.counters) != null ? _ref[counterNameNode.value] : void 0, counterType != null ? counterType["eval"](env).value : void 0); + }, + 'target-counter': function(env, targetIdNode, counterNameNode, counterType) { + var counterName, href, targetEnv, _ref; + if (counterType == null) { + counterType = null; + } + if (!counterNameNode) { + console.error("ERROR: target-counter(): expects a 2nd argument"); + return; + } + counterNameNode = counterNameNode["eval"](env); + if (!(counterNameNode instanceof less.tree.Keyword)) { + console.warn("ERROR: target-counter(): expects a Keyword"); + } + href = targetIdNode["eval"](env).value; + counterName = counterNameNode.value; + if (!href || href[0] !== '#' || href.length < 2) { + return null; + } + if (!env.helpers.markInterestingByHref(href)) { + targetEnv = env.helpers.interestingByHref(href); + return this.numberingStyle((_ref = targetEnv.state.counters) != null ? _ref[counterName] : void 0, counterType != null ? counterType["eval"](env).value : void 0); + } + return null; + } + }; + + TargetCounter.prototype.rules = { + 'counter-increment': function(env, valNode) { + var counterName, counterValue, counters, countersAndNumbers, _base, _base1; + countersAndNumbers = valNode["eval"](env); + counters = this.parseCounters(countersAndNumbers, 1); + if ((_base = env.state).counters == null) { + _base.counters = {}; + } + for (counterName in counters) { + counterValue = counters[counterName]; + if ((_base1 = env.state.counters)[counterName] == null) { + _base1[counterName] = 0; + } + env.state.counters[counterName] += counterValue; + } + return true; + }, + 'counter-reset': function(env, valNode) { + var counterName, counterValue, counters, countersAndNumbers, _base; + countersAndNumbers = valNode["eval"](env); + counters = this.parseCounters(countersAndNumbers, 0); + if ((_base = env.state).counters == null) { + _base.counters = {}; + } + for (counterName in counters) { + counterValue = counters[counterName]; + env.state.counters[counterName] = counterValue; + } + return true; + } + }; + + TargetCounter.prototype.parseCounters = function(val, defaultNum) { + var counters, cssStr, i, name, tokens; + cssStr = val.toCSS({}); + tokens = cssStr.split(' '); + counters = {}; + if ('none' === tokens[0]) { + return counters; + } + i = 0; + while (i < tokens.length) { + name = tokens[i]; + if (i === tokens.length - 1) { + val = defaultNum; + } else if (isNaN(parseInt(tokens[i + 1]))) { + val = defaultNum; + } else { + val = parseInt(tokens[i + 1]); + i++; + } + counters[name] = val; + i++; + } + return counters; + }; + + TargetCounter.prototype.numberingStyle = function(num, style) { + if (num == null) { + num = 0; + } + if (style == null) { + style = 'decimal'; + } + switch (style) { + case 'decimal-leading-zero': + if (num < 10) { + return "0" + num; + } else { + return num; + } + break; + case 'lower-roman': + return this.toRoman(num).toLowerCase(); + case 'upper-roman': + return this.toRoman(num); + case 'lower-latin': + if (!((1 <= num && num <= 26))) { + console.warn('ERROR: number out of range (must be 1...26)'); + return num; + } else { + return String.fromCharCode(num + 96); + } + break; + case 'upper-latin': + if (!((1 <= num && num <= 26))) { + console.warn('ERROR: number out of range (must be 1...26)'); + return num; + } else { + return String.fromCharCode(num + 64); + } + break; + case 'decimal': + return num; + default: + console.warn("ERROR: Counter numbering not supported for list type " + style + ". Using decimal."); + return num; + } + }; + + TargetCounter.prototype.toRoman = function(num) { + var integer, numeral, result, romanNumeralMap, _i, _len, _ref; + romanNumeralMap = [['M', 1000], ['CM', 900], ['D', 500], ['CD', 400], ['C', 100], ['XC', 90], ['L', 50], ['XL', 40], ['X', 10], ['IX', 9], ['V', 5], ['IV', 4], ['I', 1]]; + if (!((0 < num && num < 5000))) { + console.warn('ERROR: number out of range (must be 1..4999)'); + return "" + num; + } + result = ''; + for (_i = 0, _len = romanNumeralMap.length; _i < _len; _i++) { + _ref = romanNumeralMap[_i], numeral = _ref[0], integer = _ref[1]; + while (num >= integer) { + result += numeral; + num -= integer; + } + } + return result; + }; + + return TargetCounter; + + })(); + contentsFuncBuilder = function(defaultType) { + return function(env, typeNode) { + var child, el, els, evaluated, getContents, selector, text, type, val, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, + _this = this; + typeNode = typeNode != null ? typeNode["eval"](env) : void 0; + if ((!typeNode) || typeNode instanceof less.tree.Keyword) { + getContents = function() { + var child, el, _i, _len, _ref, _ref1; + el = env.helpers.contextNode.cloneNode(true); + _ref = _.toArray(el.children); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if ((_ref1 = child.classList) != null ? _ref1.contains('js-polyfill-pseudo') : void 0) { + el.removeChild(child); + } + } + return el.textContent; + }; + type = (typeNode != null ? typeNode.value : void 0) || defaultType; + switch (type) { + case 'contents': + val = getContents(); + break; + case 'first-letter': + val = (_ref = getContents()) != null ? _ref.trim()[0] : void 0; + break; + case 'before': + text = []; + _ref1 = env.helpers.contextNode.children; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + child = _ref1[_i]; + if ((_ref2 = child.classList) != null ? _ref2.contains('js-polyfill-pseudo-before') : void 0) { + text.push(child.textContent); + } + } + evaluated = false; + _ref3 = env.helpers.contextNode.children; + for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { + child = _ref3[_j]; + if (child.classList.contains('js-polyfill-evaluated')) { + evaluated = true; + } + } + if (evaluated) { + val = text.join(''); + } + break; + case 'after': + text = []; + _ref4 = env.helpers.contextNode.children; + for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) { + child = _ref4[_k]; + if ((_ref5 = child.classList) != null ? _ref5.contains('js-polyfill-pseudo-after') : void 0) { + text.push(child.textContent); + } + } + evaluated = false; + _ref6 = env.helpers.contextNode.children; + for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) { + child = _ref6[_l]; + if (child.classList.contains('js-polyfill-evaluated')) { + evaluated = true; + } + } + if (evaluated) { + val = text.join(''); + } + break; + default: + val = typeNode.toCSS({}); + console.error("ERROR: invalid argument to content(). argument=[" + val + "]"); + val = ''; + } + return val; + } else if (typeNode instanceof less.tree.Quoted) { + selector = typeNode.value; + els = Sizzle(selector, env.helpers.contextNode); + if (!els[0]) { + return; + } + text = (function() { + var _len4, _m, _results; + _results = []; + for (_m = 0, _len4 = els.length; _m < _len4; _m++) { + el = els[_m]; + _results.push(el.textContent); + } + return _results; + })(); + return text.join(''); + } else { + return console.warn("ERROR: content(): expects a Keyword or a Selector String"); + } + }; + }; + TargetText = (function() { + function TargetText() {} + + TargetText.prototype.functions = { + 'x-target-text-content': contentsFuncBuilder('before'), + 'target-text': function(env, targetIdNode, contentTypeNode) { + var contents, href, targetEnv; + if (contentTypeNode == null) { + contentTypeNode = null; + } + href = targetIdNode["eval"](env).value; + if (!env.helpers.markInterestingByHref(href)) { + targetEnv = env.helpers.interestingByHref(href); + if (!(contentTypeNode instanceof less.tree.Call)) { + console.warn("ERROR: target-text() expects a function Call"); + } + if ('content' !== contentTypeNode.name) { + console.warn("ERROR: target-text() expects a Call to content()"); + } + contentTypeNode.name = 'x-target-text-content'; + contents = contentTypeNode["eval"](targetEnv).value; + contentTypeNode.name = 'content'; + return contents; + } + return null; + } + }; + + return TargetText; + + })(); + StringSet = (function() { + function StringSet() {} + + StringSet.prototype.functions = { + 'x-string-set-content': contentsFuncBuilder('contents'), + 'string': function(env, stringNameNode) { + var str, _ref; + stringNameNode = stringNameNode["eval"](env); + if (!(stringNameNode instanceof less.tree.Keyword)) { + console.warn("ERROR: string(): expects a Keyword"); + } + str = (_ref = env.state.strings) != null ? _ref[stringNameNode.value] : void 0; + return str; + } + }; + + StringSet.prototype.rules = { + 'string-set': function(env, stringsAndVals) { + var setString, v, _i, _len, _ref, + _this = this; + stringsAndVals = stringsAndVals["eval"](env); + setString = function(val) { + var arg, args, str, stringName, _base, _i, _len; + stringName = _.first(val.value).value; + args = _.rest(val.value); + str = []; + for (_i = 0, _len = args.length; _i < _len; _i++) { + arg = args[_i]; + if (arg instanceof less.tree.Quoted) { + str.push(arg.value); + } else if (arg instanceof less.tree.Call) { + if ('content' === arg.name) { + arg.name = 'x-string-set-content'; + val = arg["eval"](env); + if (val instanceof less.tree.Call) { + return null; + } + str.push(val.value); + arg.name = 'content'; + } else { + console.warn("ERROR: invalid function used. only content() is acceptable. name=[" + arg.name + "]"); + } + } else { + str.push(arg.value); + } + } + if ((_base = env.state).strings == null) { + _base.strings = {}; + } + return env.state.strings[stringName] = str.join(''); + }; + if (stringsAndVals instanceof less.tree.Expression) { + setString(stringsAndVals); + } else if (stringsAndVals instanceof less.tree.Value) { + _ref = stringsAndVals.value; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + v = _ref[_i]; + setString(v); + } + } else { + console.warn('ERROR: invalid arguments given to string-set'); + return false; + } + return true; + } + }; + + return StringSet; + + })(); + ContentSet = (function() { + function ContentSet() {} + + ContentSet.prototype.rules = { + 'content': function(env, valNode) { + var child, domnode, pseudoAfter, val, values, _i, _j, _len, _len1, _ref, _ref1; + valNode = valNode["eval"](env); + values = this.evaluateValNode(valNode); + if (values) { + domnode = env.helpers.contextNode; + _ref = _.toArray(domnode.childNodes); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (!((_ref1 = child.classList) != null ? _ref1.contains('js-polyfill-pseudo') : void 0)) { + domnode.removeChild(child); + } + } + pseudoAfter = domnode.querySelector('.js-polyfill-pseudo-after'); + for (_j = 0, _len1 = values.length; _j < _len1; _j++) { + val = values[_j]; + switch (typeof val) { + case 'string': + val = document.createTextNode(val); + break; + case 'number': + val = document.createTextNode(val); + break; + default: + if (val.ELEMENT_NODE) { + + } else { + throw new Error('BUG: content rule only supports string, number, and DOM Node objects'); + } + } + if (pseudoAfter) { + domnode.insertBefore(val, pseudoAfter); + } else { + domnode.appendChild(val); + } + } + domnode.classList.add('js-polyfill-evaluated'); + return 'RULE_COMPLETED'; + } + return false; + } + }; + + ContentSet.prototype.evaluateValNode = function(valNode) { + var el, r, ret, val, vals, _i, _j, _len, _len1, _ref; + ret = []; + if (valNode instanceof less.tree.Expression) { + vals = valNode.value; + } else { + vals = [valNode]; + } + for (_i = 0, _len = vals.length; _i < _len; _i++) { + val = vals[_i]; + if (val instanceof less.tree.Expression) { + r = this.evaluateValNode(val); + if (r === null) { + return null; + } + ret = ret.concat(r); + } else if (val instanceof less.tree.Quoted) { + ret.push(val.value); + } else if (val instanceof less.tree.Dimension) { + ret.push(val.value); + } else if (val instanceof less.tree.ArrayTreeNode) { + _ref = val.values; + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + el = _ref[_j]; + ret.push(el); + } + } else if (val instanceof less.tree.Call) { + return null; + } else if (val instanceof less.tree.URL) { + return null; + } else if (val instanceof less.tree.Comment) { + ret.push(''); + } else { + console.warn("BUG: Attempting to set content: to something unknown. [" + val.value + "]"); + console.warn(JSON.stringify(val)); + return null; + } + } + return ret; + }; + + return ContentSet; + + })(); + return { + MoveTo: MoveTo, + DisplayNone: DisplayNone, + TargetCounter: TargetCounter, + TargetText: TargetText, + StringSet: StringSet, + ContentSet: ContentSet + }; + }); + +}).call(this); + +(function() { + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + + define('polyfill-path/less-converters', ['underscore', 'sizzle', 'cs!polyfill-path/selector-visitor'], function(_, Sizzle, AbstractSelectorVisitor) { + var AutogenClass, PSEUDO_CLASSES, PseudoExpander, freshClass, freshClassIdCounter, slugify; + PSEUDO_CLASSES = ['before', 'after', 'outside', 'footnote-call', 'footnote-marker', 'running', 'deferred']; + slugify = function(str) { + str = str.replace(/\ +/g, ' '); + str = str.replace(/[^A-Za-z0-9>\[\]\(\)\.]/g, '-'); + str = str.replace(/[\[\]\(\)]/g, '_'); + str = str.replace(/-+/g, '-'); + str = str.replace(/>/g, '-child-'); + str = str.replace(/\./g, '-dot-'); + str = str.replace(/-+/g, '-'); + str = str.replace(/^-|-$/g, ''); + return str; + }; + freshClassIdCounter = 0; + freshClass = function(selectorStr) { + selectorStr = slugify(selectorStr); + return "js-polyfill-autoclass-" + (freshClassIdCounter++) + "-" + selectorStr; + }; + AutogenClass = (function() { + function AutogenClass(selectorStr, elements, rules) { + this.selectorStr = selectorStr; + this.elements = elements; + this.rules = rules; + } + + return AutogenClass; + + })(); + PseudoExpander = (function(_super) { + var selectorTestNode; + + __extends(PseudoExpander, _super); + + PseudoExpander.prototype.PSEUDO_ELEMENT_NAME = 'span'; + + selectorTestNode = document.createElement('span'); + + function PseudoExpander(root, set, interestingSet, plugins) { + var plugin, ruleName, _i, _len; + this.set = set; + this.interestingSet = interestingSet; + PseudoExpander.__super__.constructor.apply(this, arguments); + this.interestingRules = []; + for (_i = 0, _len = plugins.length; _i < _len; _i++) { + plugin = plugins[_i]; + for (ruleName in plugin.rules || {}) { + this.interestingRules[ruleName] = true; + } + } + } + + PseudoExpander.prototype.hasInterestingRules = function(ruleSet) { + var rule, _i, _len, _ref; + if (this.interestingRules['*']) { + return true; + } + _ref = ruleSet.rules; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + rule = _ref[_i]; + if (rule.name in this.interestingRules) { + return true; + } + } + }; + + PseudoExpander.prototype.operateOnElements = function(frame, ruleSet, domSelector, pseudoSelector, originalSelector, selectorStr) { + var autoClass, className, cls, context, e, hasInterestingRules, isBrowserSelector, newClassName, newContexts, node, op, originalContext, outside, pseudoName, pseudoNode, simpleExpand, _i, _j, _len, _len1, _ref; + if (!pseudoSelector.elements.length) { + try { + selectorTestNode.querySelector(selectorStr); + isBrowserSelector = true; + } catch (_error) { + e = _error; + isBrowserSelector = false; + } + if (isBrowserSelector) { + autoClass = new AutogenClass(selectorStr, originalSelector.elements, ruleSet.rules); + this.set.add(selectorStr, autoClass); + } + hasInterestingRules = this.hasInterestingRules(ruleSet); + if (!isBrowserSelector || hasInterestingRules) { + className = freshClass(selectorStr); + _ref = this.getNodes(selectorStr); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + node = _ref[_i]; + if (node.className == null) { + node.className = ''; + } + if (node.classList) { + if (!isBrowserSelector) { + node.classList.add('js-polyfill-autoclass-keep'); + } + node.classList.add('js-polyfill-autoclass'); + node.classList.add('js-polyfill-interesting'); + node.classList.add(className); + } + } + selectorStr = "." + className; + autoClass = new AutogenClass(selectorStr, originalSelector.elements, ruleSet.rules); + this.interestingSet.add(selectorStr, autoClass); + if (!isBrowserSelector && !hasInterestingRules) { + return this.set.add(selectorStr, autoClass); + } + } + } else { + newContexts = (function() { + var _j, _k, _len1, _len2, _ref1, _ref2, _results, + _this = this; + _ref1 = this.getNodes(selectorStr); + _results = []; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + originalContext = _ref1[_j]; + context = originalContext; + _ref2 = pseudoSelector.elements; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + pseudoNode = _ref2[_k]; + pseudoName = pseudoNode.value.replace('::', ':'); + simpleExpand = function(op, pseudoName) { + var cls, pseudo; + cls = "js-polyfill-pseudo-" + pseudoName; + pseudo = Sizzle(" > ." + cls + ", > .js-polyfill-pseudo-outside > ." + cls, context)[0]; + if (pseudo) { + return context = pseudo; + } else { + pseudo = document.createElement(_this.PSEUDO_ELEMENT_NAME); + pseudo.classList.add('js-polyfill-pseudo'); + pseudo.classList.add(cls); + switch (op) { + case 'append': + context.appendChild(pseudo); + break; + case 'prepend': + context.insertBefore(pseudo, context.firstChild); + } + return context = pseudo; + } + }; + selectorStr += pseudoName; + switch (pseudoName) { + case ':before': + simpleExpand('prepend', 'before'); + break; + case ':after': + simpleExpand('append', 'after'); + break; + case ':footnote-marker': + simpleExpand('prepend', 'footnote-marker'); + break; + case ':footnote-call': + simpleExpand('append', 'footnote-call'); + break; + case ':running': + simpleExpand('append', 'footnote-call'); + break; + case ':outside': + op = 'wrap'; + pseudoName = 'outside'; + cls = "js-polyfill-pseudo-" + pseudoName; + if (context.parentNode.classList.contains(cls)) { + context = context.parentNode; + } else { + outside = document.createElement(this.PSEUDO_ELEMENT_NAME); + outside.classList.add('js-polyfill-pseudo'); + outside.classList.add(cls); + context.parentNode.replaceChild(outside, context); + outside.appendChild(context); + context = outside; + } + break; + case ':deferred': + break; + default: + console.error("ERROR: Attempted to expand unsupported pseudo element " + pseudoName); + } + } + _results.push(context); + } + return _results; + }).call(this); + newClassName = freshClass(selectorStr); + for (_j = 0, _len1 = newContexts.length; _j < _len1; _j++) { + context = newContexts[_j]; + context.classList.add('js-polyfill-autoclass'); + context.classList.add('js-polyfill-interesting'); + context.classList.add(newClassName); + } + autoClass = new AutogenClass(selectorStr, pseudoSelector.elements, ruleSet.rules, this.hasInterestingRules(ruleSet)); + selectorStr = "." + newClassName; + this.set.add(selectorStr, autoClass); + if (this.hasInterestingRules(ruleSet)) { + return this.interestingSet.add(selectorStr, autoClass); + } + } + }; + + return PseudoExpander; + + })(AbstractSelectorVisitor); + return { + PseudoExpander: PseudoExpander + }; + }); + +}).call(this); + +(function() { + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __slice = [].slice; + + define('polyfill-path/index', ['underscore', 'less', 'eventemitter2', 'selector-set', 'cs!polyfill-path/selector-tree', 'cs!polyfill-path/less-converters', 'cs!polyfill-path/plugins', 'cs!polyfill-path/extras', 'cs!polyfill-path/fixed-point-runner', 'cs!polyfill-path/selector-visitor'], function(_, less, EventEmitter, SelectorSet, SelectorTree, LESS_CONVERTERS, PLUGINS, EXTRAS, FixedPointRunner, AbstractSelectorVisitor) { + var CSSPolyfills, ContentSet, DisplayNone, ElementExtras, MoveTo, PseudoExpander, StringSet, TargetCounter, TargetText; + PseudoExpander = LESS_CONVERTERS.PseudoExpander; + MoveTo = PLUGINS.MoveTo; + DisplayNone = PLUGINS.DisplayNone; + TargetCounter = PLUGINS.TargetCounter; + TargetText = PLUGINS.TargetText; + StringSet = PLUGINS.StringSet; + ContentSet = PLUGINS.ContentSet; + ElementExtras = EXTRAS.ElementExtras; + CSSPolyfills = (function(_super) { + __extends(CSSPolyfills, _super); + + CSSPolyfills.DEFAULT_PLUGINS = [new MoveTo(), new DisplayNone(), new TargetCounter(), new TargetText(), new StringSet(), new ElementExtras(), new ContentSet()]; + + function CSSPolyfills(config) { + if (config == null) { + config = {}; + } + _.extend(this, config); + _.defaults(this, { + plugins: [], + lessPlugins: [], + pseudoExpanderClass: PseudoExpander, + doNotIncludeDefaultPlugins: false, + removeAutogenClasses: true + }); + if (!this.doNotIncludeDefaultPlugins) { + this.plugins = this.plugins.concat(CSSPolyfills.DEFAULT_PLUGINS); + } + } + + CSSPolyfills.prototype.runTree = function(rootNode, lessTree, cb) { + var SelectorSet_add, allSet, bindAll, changeLessTree, interestingSet, outputRulesetsToString, pseudoExpander, runFixedPoint, + _this = this; + if (cb == null) { + cb = null; + } + this.emit('start'); + if (rootNode.jquery) { + rootNode = rootNode[0]; + } + bindAll = function(emitter, eventNames) { + return _.each(eventNames, function(name) { + return emitter.on(name, function() { + return _this.emit.apply(_this, [name].concat(__slice.call(arguments))); + }); + }); + }; + SelectorSet_add = SelectorSet.prototype.add; + SelectorSet.prototype.add = function(sel, data) { + SelectorSet_add.apply(this, arguments); + if (this.addedSelectors == null) { + this.addedSelectors = []; + } + return this.addedSelectors.push({ + selector: sel, + data: data + }); + }; + outputRulesetsToString = function(outputRulesets) { + var allSelectors, autogenClass, comment, cssStrs, env, originalSelectorStr, rule, rules, selector, selectorStr, start, _i, _j, _len, _len1, _ref; + cssStrs = []; + env = new less.tree.evalEnv(); + env.compress = false; + env.dumpLineNumbers = 'all'; + start = new Date(); + allSelectors = outputRulesets.addedSelectors || []; + for (_i = 0, _len = allSelectors.length; _i < _len; _i++) { + _ref = allSelectors[_i], selectorStr = _ref.selector, autogenClass = _ref.data; + rules = autogenClass.rules, selector = autogenClass.selector; + originalSelectorStr = selector; + if (originalSelectorStr === selectorStr) { + comment = ''; + } else { + comment = "/* BASED_ON: " + originalSelectorStr + " */"; + } + cssStrs.push("" + selectorStr + " { " + comment); + for (_j = 0, _len1 = rules.length; _j < _len1; _j++) { + rule = rules[_j]; + cssStrs.push(" " + (rule.toCSS(env))); + } + cssStrs.push("}"); + } + return cssStrs.join('\n'); + }; + allSet = new SelectorSet(); + interestingSet = new SelectorTree(); + changeLessTree = function(plugins) { + var env; + env = new less.tree.evalEnv(); + env.compress = false; + env.dumpLineNumbers = 'all'; + env.plugins = plugins; + return lessTree.toCSS(env); + }; + runFixedPoint = function(plugins) { + var fixedPointRunner; + fixedPointRunner = new FixedPointRunner(rootNode, plugins, interestingSet, _this.removeAutogenClasses); + bindAll(fixedPointRunner, ['runner.start', 'runner.end', 'tick.start', 'tick.node', 'tick.end']); + fixedPointRunner.run(); + return fixedPointRunner; + }; + if (this.pseudoExpanderClass) { + pseudoExpander = new this.pseudoExpanderClass(rootNode, allSet, interestingSet, this.plugins); + bindAll(pseudoExpander, ['selector.start', 'selector.end']); + this.lessPlugins.push(pseudoExpander); + } + changeLessTree(this.lessPlugins); + runFixedPoint(this.plugins); + if (typeof cb === "function") { + cb(null, outputRulesetsToString(allSet)); + } + return this.emit('end'); + }; + + CSSPolyfills.prototype.run = function(rootNode, cssStyle, filename, cb) { + var _this = this; + return this.parse(cssStyle, filename, function(err, lessTree) { + if (err) { + return typeof cb === "function" ? cb(err, lessTree) : void 0; + } + return _this.runTree(rootNode, lessTree, cb); + }); + }; + + CSSPolyfills.prototype.parse = function(cssStyle, filename, cb) { + var env, parser; + env = { + compress: false, + dumpLineNumbers: 'all', + filename: filename + }; + parser = new less.Parser(env); + return parser.parse(cssStyle, cb); + }; + + return CSSPolyfills; + + })(EventEmitter); + CSSPolyfills.less = less; + CSSPolyfills.AbstractSelectorVisitor = AbstractSelectorVisitor; + if (typeof window !== "undefined" && window !== null) { + window.CSSPolyfills = CSSPolyfills; + } + return CSSPolyfills; + }); + +}).call(this); + +(function() { + this.define = this.__polyfills_originalGlobals['define']; + + if (typeof this.define === "function") { + this.define('polyfill-path/index', function() { + return this.CSSPolyfills; + }); + } + + this.__polyfills_originalGlobals = void 0; + +}).call(this); diff --git a/front/dist/css/app.29fe73fd.css b/front/dist/css/app.29fe73fd.css deleted file mode 100644 index b549038..0000000 --- a/front/dist/css/app.29fe73fd.css +++ /dev/null @@ -1 +0,0 @@ -:root{--back:#fff}#app,body,html{padding:0;margin:0;background:var(--back)}#app,body,html{height:100%;width:100%}#app{display:flex;flex-direction:column;font-size:11pt}#app,header{position:relative}header{box-sizing:border-box;font-size:9pt}main{height:100%;width:100%}main,section{position:relative;display:flex;flex-direction:column}section{box-sizing:border-box;padding:1em}section p{margin-bottom:0;margin-top:0}div[data-v-1af39708]{padding:.5em}div .selected[data-v-1af39708]{background:#f792f7}div p[data-v-1af39708]{margin:0}.streams[data-v-4514be34]{min-width:10em;padding:0;margin-bottom:1em}.message-outer{position:relative;display:block}.message-outer:hover .reactions{display:flex;position:absolute;top:0;left:0;width:100%;height:100%;align-items:center;justify-content:center;background-color:hsla(0,0%,100%,.5);font-size:3rem;pointer-events:none}.reactions,.reactions:after,.reactions:before{all:revert;display:none}.reactions span{pointer-events:auto}.message-data{display:flex;border-bottom:1px solid #666}.message-data>div{flex-grow:1}.message-data .from:after{content:":"}.message-data .time{text-align:right}.message-data-reactions{margin-bottom:1em}.header[data-v-30f46307]{cursor:pointer}@media print{.title[data-v-30f46307]{display:none}}.index[data-v-37f18a26]{page-break-after:always}.rule[data-v-080e408c]{margin:1em 0;position:relative}.rule p[data-v-080e408c]{margin:0}.rule.type-font[data-v-080e408c],.rule.type-raw[data-v-080e408c]{background-color:#333;color:#fff;padding:10px;border-radius:10px;border:1px solid #000;position:relative}.rule.type-font[data-v-080e408c]:after,.rule.type-raw[data-v-080e408c]:after{all:revert;content:"raw css";background-color:#333;border-radius:10px;position:absolute;bottom:-.5em;left:50%;transform:translateX(-50%);padding:5px 10px;font-family:sans-serif;font-size:.8rem;box-shadow:0 0 5px 5px rgba(255,255,0,.7)}.rule.type-font[data-v-080e408c]:after{content:"generated font rule"}.rule.type-font .instructions[data-v-080e408c]{display:none;position:absolute;top:10px;left:10px;padding:10px;width:calc(100% - 40px);height:calc(100% - 40px);align-content:center;justify-content:center;align-items:center;font-family:initial;background-color:hsla(0,0%,100%,.9);color:#000;border-radius:10px;box-shadow:0 0 5px 5px #fff}.rule.type-font:hover .instructions[data-v-080e408c]{display:flex}.rules[data-v-16b43aee]{max-width:unset}@media print{.rules[data-v-16b43aee]{display:none}}#home{position:relative;box-sizing:border-box;height:100%;width:100%;display:flex}.controls-pane{background-color:#aaa}.splitpanes--vertical .splitpanes__pane{overflow-y:scroll}.splitpanes.default-theme .splitpanes__pane{background-color:unset}.pane-wrapper{height:100vh}.controls{display:flex;flex-direction:column;padding:1em}.print .pane-wrapper{height:auto}.print .splitpanes__pane{overflow:initial}.print .content iframe{width:100%;height:100%}.print section{display:block!important}.body{page-break-after:always}.body img{max-width:100%}.float-btn{position:fixed;z-index:1000}@media print{.ui{display:none!important}}.docs[data-v-32f02ba2]{padding:1em;max-width:800px;width:100%;margin:1em auto} \ No newline at end of file diff --git a/front/dist/css/app.428a5fb2.css b/front/dist/css/app.428a5fb2.css deleted file mode 100644 index 2aa7d4a..0000000 --- a/front/dist/css/app.428a5fb2.css +++ /dev/null @@ -1 +0,0 @@ -:root{--back:#fff}#app,body,html{padding:0;margin:0;background:var(--back)}#app,body,html{height:100%;width:100%}#app{display:flex;flex-direction:column;font-size:11pt}#app,header{position:relative}header{box-sizing:border-box;font-size:9pt}main{height:100%;width:100%}main,section{position:relative;display:flex;flex-direction:column}section{box-sizing:border-box;padding:1em}section p{margin-bottom:0;margin-top:0}div[data-v-1af39708]{padding:.5em}div .selected[data-v-1af39708]{background:#f792f7}div p[data-v-1af39708]{margin:0}.streams[data-v-4514be34]{min-width:10em;padding:0;margin-bottom:1em}.message-outer{position:relative;display:block}.message-outer:hover .reactions{display:flex;position:absolute;top:0;left:0;width:100%;height:100%;align-items:center;justify-content:center;background-color:hsla(0,0%,100%,.5);font-size:3rem;pointer-events:none}.reactions,.reactions:after,.reactions:before{all:revert;display:none}.reactions span{pointer-events:auto}.message-data{display:flex;border-bottom:1px solid #666}.message-data>div{flex-grow:1}.message-data .from:after{content:":"}.message-data .time{text-align:right}.message-data-reactions{margin-bottom:1em}.header[data-v-80b6d17a]{cursor:pointer}@media print{.title[data-v-80b6d17a]{display:none}}.rule[data-v-080e408c]{margin:1em 0;position:relative}.rule p[data-v-080e408c]{margin:0}.rule.type-font[data-v-080e408c],.rule.type-raw[data-v-080e408c]{background-color:#333;color:#fff;padding:10px;border-radius:10px;border:1px solid #000;position:relative}.rule.type-font[data-v-080e408c]:after,.rule.type-raw[data-v-080e408c]:after{all:revert;content:"raw css";background-color:#333;border-radius:10px;position:absolute;bottom:-.5em;left:50%;transform:translateX(-50%);padding:5px 10px;font-family:sans-serif;font-size:.8rem;box-shadow:0 0 5px 5px rgba(255,255,0,.7)}.rule.type-font[data-v-080e408c]:after{content:"generated font rule"}.rule.type-font .instructions[data-v-080e408c]{display:none;position:absolute;top:10px;left:10px;padding:10px;width:calc(100% - 40px);height:calc(100% - 40px);align-content:center;justify-content:center;align-items:center;font-family:initial;background-color:hsla(0,0%,100%,.9);color:#000;border-radius:10px;box-shadow:0 0 5px 5px #fff}.rule.type-font:hover .instructions[data-v-080e408c]{display:flex}.rules[data-v-16b43aee]{max-width:unset}@media print{.rules[data-v-16b43aee]{display:none}}#home{position:relative;box-sizing:border-box;height:100%;width:100%;display:flex}.controls-pane{background-color:#aaa}.splitpanes--vertical .splitpanes__pane{overflow-y:scroll}.splitpanes.default-theme .splitpanes__pane{background-color:unset}.pane-wrapper{height:100vh}.controls{display:flex;flex-direction:column;padding:1em}.print .pane-wrapper{height:auto}.print .splitpanes__pane{overflow:initial}.print .content iframe{width:100%;height:100%}.print section{display:block!important}.print .body{page-break-after:always}.body img{max-width:100%}.float-btn{position:fixed;z-index:1000}@media print{.ui{display:none!important}}.docs[data-v-b2769a1a]{padding:1em;max-width:800px;width:100%;margin:1em auto} \ No newline at end of file diff --git a/front/dist/css/app.c01369df.css b/front/dist/css/app.c01369df.css new file mode 100644 index 0000000..ccad6c7 --- /dev/null +++ b/front/dist/css/app.c01369df.css @@ -0,0 +1 @@ +:root{--back:#fff;--pink:#ff85da}#app,body,html{padding:0;margin:0;background:var(--back)}#app,body,html{height:100%;width:100%}#app{display:flex;flex-direction:column;font-size:11pt}#app,header{position:relative}header{box-sizing:border-box;font-size:9pt}main{height:100%;width:100%}main,section{position:relative;display:flex;flex-direction:column}section{box-sizing:border-box;padding:1em}section p{margin-bottom:0;margin-top:0}.li.selected .index[data-v-cdbb2ba0]{position:fixed;background:#fff;margin:0;padding:0;top:calc(var(--top));left:10%;z-index:1;width:auto;box-shadow:0 0 2em 0 var(--pink);max-height:0;transition:all .1s ease;overflow:scroll}.li.selected .index li[data-v-cdbb2ba0]{list-style:none;margin:0;padding:.5em}.li.selected .index li a[data-v-cdbb2ba0]{max-width:16em;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.li.selected .index li[data-v-cdbb2ba0]:hover{background:var(--pink)}.li.selected:hover .index[data-v-cdbb2ba0]{max-height:40em;transition:all .1s ease}@media print{.index li a[data-v-cdbb2ba0]:after{display:block;content:leader(".") target-counter(attr(href url),page,lower-roman)}}@page{@bottom-left{content:counter(page) " of " counter(pages)}}.li[data-v-bb0c01d2]{position:relative;padding:.5em}.li.selected[data-v-bb0c01d2]{background:var(--pink)}.li p[data-v-bb0c01d2]{margin:0}.li p a[data-v-bb0c01d2]{max-width:100%;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.streams[data-v-bf028a98]{min-width:10em;padding:0;margin-bottom:1em}.authors[data-v-e34c1616]{page-break-after:always}.message-outer{position:relative;display:block}.message-outer:hover .reactions{display:flex;position:absolute;top:0;left:0;width:100%;height:100%;align-items:center;justify-content:center;background-color:hsla(0,0%,100%,.5);font-size:3rem;pointer-events:none}.reactions,.reactions:after,.reactions:before{all:revert;display:none}.reactions span{pointer-events:auto}.message-data{display:flex;border-bottom:1px solid #666}.message-data>div{flex-grow:1}.message-data .from:after{content:":"}.message-data .time{text-align:right}.message-data-reactions{margin-bottom:1em}.header[data-v-05955d29]{cursor:pointer}@media print{.title[data-v-05955d29]{display:none}}.rule[data-v-080e408c]{margin:1em 0;position:relative}.rule p[data-v-080e408c]{margin:0}.rule.type-font[data-v-080e408c],.rule.type-raw[data-v-080e408c]{background-color:#333;color:#fff;padding:10px;border-radius:10px;border:1px solid #000;position:relative}.rule.type-font[data-v-080e408c]:after,.rule.type-raw[data-v-080e408c]:after{all:revert;content:"raw css";background-color:#333;border-radius:10px;position:absolute;bottom:-.5em;left:50%;transform:translateX(-50%);padding:5px 10px;font-family:sans-serif;font-size:.8rem;box-shadow:0 0 5px 5px rgba(255,255,0,.7)}.rule.type-font[data-v-080e408c]:after{content:"generated font rule"}.rule.type-font .instructions[data-v-080e408c]{display:none;position:absolute;top:10px;left:10px;padding:10px;width:calc(100% - 40px);height:calc(100% - 40px);align-content:center;justify-content:center;align-items:center;font-family:initial;background-color:hsla(0,0%,100%,.9);color:#000;border-radius:10px;box-shadow:0 0 5px 5px #fff}.rule.type-font:hover .instructions[data-v-080e408c]{display:flex}.rules[data-v-16b43aee]{max-width:unset}@media print{.rules[data-v-16b43aee]{display:none}}#home{position:relative;box-sizing:border-box;height:100%;width:100%;display:flex}.controls-pane{background-color:#aaa}.splitpanes--vertical .splitpanes__pane{overflow-y:scroll}.splitpanes.default-theme .splitpanes__pane{background-color:unset}.pane-wrapper{height:100vh}.controls{display:flex;flex-direction:column;padding:1em}.print .pane-wrapper{height:auto}.print .splitpanes__pane{overflow:initial}.print .content iframe{width:100%;height:100%}.print section{display:block!important}.body{page-break-after:always}.body img{max-width:100%}.float-btn{position:fixed;z-index:1000}@media print{.ui{display:none!important}}.docs[data-v-32f02ba2]{padding:1em;max-width:800px;width:100%;margin:1em auto} \ No newline at end of file diff --git a/front/dist/extra-styles.css b/front/dist/extra-styles.css new file mode 100644 index 0000000..7936298 --- /dev/null +++ b/front/dist/extra-styles.css @@ -0,0 +1,11 @@ +@media print { + .index li a::before { + /* content: target-counter(attr(href), page); */ + /* display: block; */ + content: leader('.') target-counter(attr(href url), page, lower-roman); + } +} + +@page { + counter-increment: page; +} diff --git a/front/dist/index.html b/front/dist/index.html index 1fb4df1..beb1686 100644 --- a/front/dist/index.html +++ b/front/dist/index.html @@ -1 +1 @@ -ChattyPub
    \ No newline at end of file +ChattyPub
    \ No newline at end of file diff --git a/front/dist/js/app.080ffb9e.js b/front/dist/js/app.080ffb9e.js deleted file mode 100644 index ad5c8f5..0000000 --- a/front/dist/js/app.080ffb9e.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(e){function t(t){for(var o,r,s=t[0],i=t[1],c=t[2],u=0,d=[];u"),a="https://chat.hackersanddesigners.nl";t=t.replaceAll('src="','src="'+a),t=t.replaceAll('href="/','href="'+a+"/"),t=t.replaceAll(a+"/user_uploads/","https://chatty-pub-files.hackersanddesigners.nl/files/");var o=this.$store.state.topics.find((function(t){return t.title==e.message.subject})).messages.filter((function(t){return t.responseTo&&t.responseTo.id==e.message.id&&t.responseTo.sender_id==e.message.sender_id&&e.message.content.includes(t.responseTo.quote)}));return o.forEach((function(e){var a=e.reactions.map((function(e){return"u"+e.emoji_code})).join(" ");t=t.replace(e.responseTo.quote,'').concat(e.responseTo.quote,""))})),t},reactions:function(){return this.message.reactions.map((function(e){return he.replace_colons(":"+e.emoji_name+":")}))},classes:function(){return this.message.reactions.map((function(e){return e.emoji_code+" u"+e.emoji_code}))},time:function(){var e=this.message.timestamp,t=1e3*e,a=new Date(t);return a.toLocaleString()}},created:function(){}};a("d3a3");be.render=de;var me=be,_e={name:"Chapter",components:{Message:me},data:function(){return{}},props:["topic","show_message_data"],computed:{messagesToShow:function(){return this.topic.messages.filter((function(e){return!e.responseTo}))}}};a("3c3b");_e.render=fe,_e.__scopeId="data-v-30f46307";var ge=_e,ye={name:"Content",components:{Chapter:ge},props:["print","show_message_data"],computed:Object(s["a"])(Object(s["a"])(Object(s["a"])({},Object(i["c"])(["currentStream","streams"])),Object(i["b"])(["sortedTopics"])),{},{title:function(){var e=this;return this.streams.find((function(t){return t.name==e.currentStream}))?this.currentStream.replace("pub-",""):"Stream does not exist."}}),methods:{toValidID:function(e){return encodeURIComponent("ch-"+e).toLowerCase().replace(/\.|%[0-9a-z]{2}/gi,"")},goTo:function(e){document.querySelector(".".concat(this.currentStream," ").concat(e)).scrollIntoView({behavior:"smooth"})}}};a("1f97");ye.render=ee,ye.__scopeId="data-v-37f18a26";var we=ye,ke=Object(o["withScopeId"])("data-v-16b43aee");Object(o["pushScopeId"])("data-v-16b43aee");var ve={class:"rules"};Object(o["popScopeId"])();var je=ke((function(e,t,a,n,f,r){var s=Object(o["resolveComponent"])("Rule");return Object(o["openBlock"])(),Object(o["createBlock"])("section",ve,[(Object(o["openBlock"])(!0),Object(o["createBlock"])(o["Fragment"],null,Object(o["renderList"])(e.rules,(function(e){return Object(o["openBlock"])(),Object(o["createBlock"])(s,{key:e.id,rule:e},null,8,["rule"])})),128))])})),Se=Object(o["withScopeId"])("data-v-080e408c");Object(o["pushScopeId"])("data-v-080e408c");var Oe={key:0},xe={key:1},Ce={class:"instructions"},De=Object(o["createTextVNode"])("Add the follow to your rule to use this font:"),ze=Object(o["createVNode"])("br",null,null,-1),Te=Object(o["createVNode"])("p",null,"}",-1);Object(o["popScopeId"])();var Be=Se((function(e,t,a,n,f,r){return Object(o["openBlock"])(),Object(o["createBlock"])("div",{class:["rule",r.classes],style:r.rules},["raw"===a.rule.type?(Object(o["openBlock"])(),Object(o["createBlock"])("pre",Oe,Object(o["toDisplayString"])(r.contentFiltered)+"\n ",1)):"font"===a.rule.type?(Object(o["openBlock"])(),Object(o["createBlock"])("span",xe,[Object(o["createVNode"])("pre",{style:r.rules},'@font-face { \n font-family: "'+Object(o["toDisplayString"])(r.font.family)+'"; \n src: "'+Object(o["toDisplayString"])(r.font.src)+'" format('+Object(o["toDisplayString"])("font.format")+"); \n}",5),Object(o["createVNode"])("div",Ce,[Object(o["createVNode"])("span",null,[De,ze,Object(o["createTextVNode"])(' font-family: "'+Object(o["toDisplayString"])(r.font.family)+'"; ',1)])])])):(Object(o["openBlock"])(),Object(o["createBlock"])(o["Fragment"],{key:2},[Object(o["createVNode"])("p",{title:e.toEmojiCode(a.rule.className)},Object(o["toDisplayString"])(a.rule.className)+" {",9,["title"]),(Object(o["openBlock"])(!0),Object(o["createBlock"])(o["Fragment"],null,Object(o["renderList"])(a.rule.rules,(function(e){return Object(o["openBlock"])(),Object(o["createBlock"])("p",{key:e},"  "+Object(o["toDisplayString"])(e),1)})),128)),Te],64))],6)})),Ee={name:"Rule",mixins:[S],props:["rule"],computed:{contentFiltered:function(){var e=this,t=this.emoji_regex,a=this.rule.content.replace(t,(function(t){return t+", .u"+e.toEmojiCode(t)}));return a},classes:function(){return"type-"+this.rule.type},font:function(){return this.rule.content},rules:function(){return"font"!==this.rule.type?this.rule.rules:["font-family: "+this.font.family+";"]}}};a("c251");Ee.render=Be,Ee.__scopeId="data-v-080e408c";var Fe=Ee,Pe={name:"Rules",components:{Rule:Fe},computed:Object(s["a"])({},Object(i["c"])(["rules"])),watch:{rules:function(){console.log("rules")}}};a("5476");Pe.render=je,Pe.__scopeId="data-v-16b43aee";var Ie=Pe,qe=a("512e"),Ne=(a("c1ea"),a("676e")),Ae={name:"Home",components:{Streams:J,Content:we,Rules:Ie,Splitpanes:qe["Splitpanes"],Pane:qe["Pane"]},setup:function(){var e=Object(o["ref"])(null);return{preview:e}},data:function(){return{show_ui:!0,show_message_data:!1,panel_sizes:{0:10,1:55,2:35},expand_content:!1}},computed:{classes:function(){return this.show_ui?"ui":"print"},currentStream:function(){return this.$store.state.currentStream.replace(" ","-")}},methods:{resizer:function(e){for(var t=0;t[1](#footnote1) Mozilla has an excellent [HTML introduction](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started).\n\nAt its heart, HTML is a fairly simple language made up of elements, which can be applied to pieces of text to give them different meaning in a document (Is it a paragraph? Is it a bulleted list? Is it part of a table?), structure a document into logical sections (Does it have a header? Three columns of content? A navigation menu?), and embed content such as images and videos into a page.\nBut what HTML does not do is speficy how these elements should look. That is where CSS comes in.\n\nCSS can be used for very basic document text styling — for example changing the color and size of headings and links. It can be used to create layout — for example turning a single column of text into a layout with a main content area and a sidebar for related information. It can even be used for effects such as animation.\nIn ChattyPub we're mostly interested in the first part.\n\n---\n\n## Rules\n\n#### _Elements and Classes_\n\nIn this section we will talk about CSS in general. ChattyPub uses a slight variation on it, but let's start with the basics.\n\nCSS is a rule-based language — you define rules specifying groups of styles that should be applied to particular elements or groups of elements on your web page. For example \"I want the main heading on my page to be shown as large red text.\"\n\nThe following code shows a very simple CSS rule that would achieve the styling described above:\n\n```css\nh1 {\n color: red;\n font-size: 20px;\n}\n```\n\nThe rule opens with a selector. This selects the HTML element that we are going to style. In this case we are styling all level one headings (`

    `) that appear on the page.\n\nWe then have a set of curly braces `{` `}`. Inside those will be one or more declarations, which take the form of property and value pairs. Each pair specifies a property of the element(s) we are selecting, then a value that we'd like to give the property. Each pair is followed by a semi-colon `;` to indicate the end of the property.\n\nBefore the colon, we have the property, and after the colon, the value. CSS properties have different allowable values, depending on which property is being specified. In our example, we have the color property, which can take various color values. We also have the font-size property. This property can take various size units as a value.\n\nThe example above will style all the `H1` elements on the page. You could also write a selector for all paragraphs (the selector would be `p`), images (`img`) or list items (`li`). This works as long as you want all of the elements of that type in your document to look the same. Most of the time that isn't the case and so you will need to find a way to select a subset of the elements without changing the others. The most common way to do this is to add a class to your HTML element and target that class.\n\nTake this HTML:\n\n```html\n
      \n
    • Item one
    • \n
    • Item two
    • \n
    • Item three
    • \n
    \n```\n\nTo target the class of special you can create a selector that starts with a full stop character.\n\n```css\n.special {\n color: orange;\n font-weight: bold;\n}\n```\n\nThe peroid character in front of special tells the browser that we're creating a class selector.\nYou can apply the class of special to any element on your page that you want to have the same look as this list item.\n\n### Units\n\nIn the `h1` example above, we set the following property: `font-size: 20px;`. This will set the font-size of all H1 headers to 20 pixels. But pixels are not the only units available. Some examples:\n\n- `em` and `rem` - these relative units declare a size dependant on the font-size of the context they get used in. This can be a bit confusing if you're not used to it. Feel free to replace it with on of the values below.\n- `px` - Pixels.\n- `cm` and `in` - centimeters and inches. These units are mostly relevant in print context.\n- `vw` and `vh` - so called viewport units, 100vw is exactly the height of the viewport (the part of the browser that shows the webpage). `vh` is the same, but for the height of the browser.\n- `rgba(r,g,b,a)` strictly speaking not a unit but a function, but it sets the color and transparency of the foreground.\n\n[More information on units](https://www.w3.org/Style/Examples/007/units.en.html).\n\n---\n\n## CSS in ChattyPub\n\nWhen you react to a message in Zulip with an emoji, this emoji gets turned into a class in ChattyPub. So lets say you responded to a message with the strawberry 🍓 emoji. In ChattyPub the message will have class with that emoji as selector. (You can confirm this by rolling over the message, the emoji should popup on a overlay.) So now to style that message, you go to the `#rules` channel and add a message with the following content:\n\n```css\n🍓 {\n color: red;\n}\n```\n\nIt is very similar to the examples above. `🍓` is the selector, so the rule will apply to each message with a strawberry reaction. Then follows the block `{` and `}`. And in the block, there is property, `color: red;`.\n\n_A small difference with regular CSS is that you don't need to add the period in front of the selector ChattyPub will handle that for you._\n\nBecause of the way Zulip handles the emoji reactions, not all emoji are available or sometimes they don't exactly correspond to the emoji you might type in the `#rules` channel. To help with sorting this out you can roll over a message in ChattyPub and see the reactions that are applied. Sometimes the translation is unavailable, in that case you'll see something like `:working_on_it:` instead of the emoji you expected. In that case remove your reaction and find an other emoji that does work.\n\n### About formatting\n\nYou can't enter a tab character in Zulip and the indentation before the property in the rule isn't absolutely necessary. So feel free to leave it out. If you absolutely want to have the indentation, you could write the rule in your favorite editor and copy and paste it into Zulip. If you only want to style a single property you could have the whole rule on a single line like this: `🌕 { box-shadow: 0 0 20px rgba(255,0,0,0.5); }`,\n\n_Don't forget the semi-colon at the end of the property line!_\n\n### Advanced CSS\n\n**Selecting HTML elements and other style rules**\n\nThe reaction/emoji method described above allows to make quick modifications to the style and layout of your publication. But besides this ChattyPub also allows you to style html elements like in regular CSS. To do this just enter your style rule. This snippet will give all HTML links a pink background color:\n\n```css\na {\n background-color: pink;\n}\n```\n\nYou should be able to enter all regular CSS rules this way.\n\n**Bypassing the parser** -_Work in progress_-\n\nIt is possible to bypass the parser and add arbitrary code to the CSS on the page. This allows you to add, for example, `@keyframes` for an animation or media queries. To do this send any message to the `#rules` channel and wrap the message in three backticks like this:\n\n~~~~\n```\n@keyframes example {\n from {background-color: red;}\n to {background-color: yellow;}\n}\n```\n~~~~\n\n---\n\n## Uploading fonts\n\nIt is also possible to upload a custom font to the application. To do this, you send the font in a message to the #rules channel of the publication you want to use it in. You can use `.ttf`, `.otf` or `.woff` formats depending on the browser you are using. The mesage must only contain the font, no other text. ChattyPub will then automatically generate a @font-face rule for the font. The font-family name will be based on the filename.\n\nOnce uploaded the font should show up in the CSS rules section of ChattyPub. To use the font in a style rule, just copy/paste the `font-family: \"font_name_ttf\";` and add it to a rule in the #rules channel.\n\n> Please only upload free or open-source fonts to our server!\n\n## Print settings\n\nTo set the paper size we can use the special selector `@page`. The following snippet set the page size to A5.\n\n```css\n@page {\n size: 148mm 210mm;\n}\n```\n\nThis example sets the page to landscape.\n\n```css\n@page {\n size: landscape;\n}\n```\n\nRegrettably [browser support](https://caniuse.com/css-paged-media) for `@page` is spotty. Currently only MS Edge, Opera and Google Chrome will allow you to set page sizes etc, and even then it is a matter of trial and error.\n\nThe [Paged media module](https://developer.mozilla.org/en-US/docs/Web/CSS/Paged_Media) at Mozilla has an excellent explanation on using `@page`.\n\n### page breaks\n\nBy default pages will automatically wrap to the next page. And ChattyPub adds a page break after each topic. If you want to force a page break you could write a rule for it, using the `page-break-after: always;` property:\n\n```css\n🍏 {\n page-break-after: always;\n}\n```\n\nIf you don't want the page break after an article you can overwrite the default by using:\n\n```css\n.body {\n page-break-after: avoid;\n}\n```\n\nFor some of these rules it may be necessary to use the methods described under [Advanced CSS](#advanced-css) above to enter these rules.\n\n## List of common and handy CSS properties\n\nThere are hundreds of CSS properties. Below is a small selection of some basic properties mostly focussed on layout and type representation, grouped by module.\n\n### Backgrounds and borders\n\n- [background-color](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color)\n- [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) - The border CSS property sets an element's border.\n- [border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius) - The border-radius CSS property rounds the corners of an element's outer border edge.\n- [box-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow) - The box-shadow CSS property adds shadow effects around an element's frame.\n\n### Color\n\n- [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) - The color CSS property sets the foreground color value of an element's text and text decorations.\n- [opacity](https://developer.mozilla.org/en-US/docs/Web/CSS/opacity) - The opacity CSS property sets the opacity of an element. Opacity is the degree to which content behind an element is hidden, and is the opposite of transparency.\n\nA colors value can defined in multiple ways:\n\n- By [name/keyword](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#keywords) - `color: red;` will make your text red.\n- By [hex value](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#hex) - `color: #ff0000;` also red.\n- Or as a [function](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#rgba), which allows transparency. - `color: rgba(255,0,0,0.5);` red, but 50% transparent.\n\n### Box model\n\n- [margin](https://developer.mozilla.org/en-US/docs/Web/CSS/margin) - The margin property sets the margin area on all four sides of an element. Margin refers to space between different elements.\n- [padding](https://developer.mozilla.org/en-US/docs/Web/CSS/padding) - The padding property sets the padding area on all four sides of an element at once. Padding refers to the spacing inside the border of an element.\n\n### Fonts\n\n- [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) - The font-family CSS property specifies a prioritized list of one or more font family names and/or generic family names for the selected element.\n\nYou can choose one of the following generic fonts. Which exact font will be used is dependant on your computers' settings.\n\n```css\nfont-family: serif;\nfont-family: sans-serif;\nfont-family: monospace;\nfont-family: cursive;\nfont-family: fantasy;\n```\n\nIt is also possible to specify an exact font name, but it will only be used if it is actually available on your system.\nFor example following statement will try to use Helvetica if available, but will fallback on a generic sans-serif font if not. (Note the quotes around the font name).\n\n```css\nfont-family: \"Helvetica Neue\", sans-serif;\n```\n\nAlso see the section on uploading fonts below.\n\n- [font-size](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size) - The font-size CSS property sets the size of the font. Changing the font size also updates the sizes of the font size-relative units, such as em, ex, and so forth.\n- [font-style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style) - The font-style CSS property sets whether a font should be styled with a normal, italic, or oblique face from its font-family.\n- [font-weigh](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) - The font-weight CSS property sets the weight (or boldness) of the font. The weights available depend on the font-family that is currently set.\n- [line-height](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height) - The line-height CSS property sets the height of a line box. It's commonly used to set the distance between lines of text.\n\n### Text\n\n- [letter-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/letter-spacing) - The letter-spacing CSS property sets the horizontal spacing behavior between text characters.\n- [text-align](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) - The text-align CSS property sets the horizontal alignment of the content inside a block element.\n- [text-transform](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) - The text-transform CSS property specifies how to capitalize an element's text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.\n- [white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) - The white-space CSS property sets how white space inside an element is handled.\n- [word-break](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break) - The word-break CSS property sets whether line breaks appear wherever the text would otherwise overflow its content box.\n- [word-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/word-spacing) - The word-spacing CSS property sets the length of space between words and between tags.\n- [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) - The text-shadow CSS property adds shadows to text.\n\n### Transforms\n\n- [rotate](https://developer.mozilla.org/en-US/docs/Web/CSS/rotate) - The rotate CSS property allows you to specify rotation of elements\n- [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/scale) - The scale CSS property allows you to specify the scale (size) of elements\n- [translate](https://developer.mozilla.org/en-US/docs/Web/CSS/translate) - The translate CSS property allows you to specify translation transforms (position relative to where it originally was) of elements.\n\n1: I've borrowed shamelessly from Mozilla to make this text: https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps/What_is_CSS and https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML\n"),$e='# ChattyPub Workshop Script\n\n## Introduction\n\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication.\n\nThe workshop will explore in a practical manner how the process of co-designing a publication can unfold, specifically when several people are working at the same time using a chat interface as the main design tool. During HDSA2021 we would like to open up the process of making this tool and explore together its possibilities and limitations. The workshop will take place towards the end of the one-week summer academy program. Thus, we will be able to use some of the documentation produced during the week — workshops scripts, prototypes, game cards, recipes, ... as well as conversations we will have on different platforms – synchronously and asynchronously.\n\nCommands allow you to style the texts and images, but someone else can change their appearance again later! How will we negotiate these design decisions synchronously and asynchronously? The outcome could be a zine, posters or a webpage.\n\nThis script aims to provide the necessary instructions to host a workshop around ChattyPub that can accomodate different skills and knowledges in different contexts.\n\n## Goals\n\n- Learn to collaboratively write, design, and print documents using ChattyPub\n- Produce publications of / relating to HDSA2021 (documentation, prototypes, conversations, etc...)\n- Learn and/or practice styling with CSS & Emojis\n\n## Requirements\n\n- a computer, web-browser, and connection to the internet\n- an account for the Hackers & Designers Zulip instance: https://chat.hackersanddesigners.nl/\n- a printer\n\n## Preparation\n\nBefore the summer academy: Most important is for all workshop participants to set up a Zulip account on our server. The H&D zulip instance can be found at https://chat.hackersanddesigners.nl/ (public sign ups are temporariy open).\n\nOn the first day of the summer academy (monday): Participants are introduced to the Zulip interface and instructed to use it for communication during the course of the week. Zulip makes use of a rather unconventional (but powerful) chat-threading logic, so it would be good to spend some time interacting with it and settle into this new environment.\n\nWorkshop hosts and participants are encouraged to think about how they would like to document their processes during the summer academy. What is included and what isn\'t? How is this shared? Is there a regular moment during the day dedicated to documentation or is it more ad-hoc? We suggest using Etherpad for collaborative note taking, and regularly making screenshots or screenrecordings and photos. We have previously compiled a so-called "tool-ecology", a list of tools we have good experiences with and recommend using during the summer academy: https://etherpad.hackersanddesigners.nl/p/hdsa2021-tool-ecology.\n\nTexts, notes, chats, images, and screenshots will make great material for our workshop.\n\n## How It Works\n\nFor an overview of how ChattyPub works with Zulip, go [here](/docs/Chattypub).\n## Workshop\n\nThe workshop is split over two sessions (over two days) of 4 hours each.\n\n_Opening Session: Introductions & first encounters with ChattyPub_\n\n- Introductory presentation ( 1hr ) -- will be livestreamed in the morning / recorded and shared afterwards.\n - Context and background on H&D\'s publishing activities (Anja & Juliette)\n - Introduction to ChattyPub (Karl).\n - Introduction to CSS (Heerko).\n - How it all comes together (emojis ;])(Karl)\n- Experimenting with ChattyPub! ( 2 hrs )\n - participants with different levels of experience of CSS are grouped together\n - each group follows [these instructions](/docs/Chattypub#content) to make one publication in ChattyPub\n - detailed instructions about CSS can be found [here](/docs/CSS)\n- Brainstorm Session (1 hr)\n - in groups of 2-3, participants brainstorm publications they will make during the main session \n - The goal is to document together, in print, parts of the summer academy.\n - What have you been up to this last week?\n - What did you make? What material did you collect / produce?\n - How will you negotiate this design process?\n - Are roles divided and then switched? \n - If you are planning to print your publication, take into account the printing limitations of your home printer or local print shop.\n - Print settings such as the page size and orientation can all be configure with CSS.\n - If participants are joining remotely, it\'s good that they are paired together.\n\n_Main Session: Chat => Print_\n\n- Making publications ( 2 hrs )\n - Groups work on the publications planned in the previous session \n - Each group makes a stream on Zulip for the publiction\n - They create chapters for their contents\n - They create a "rules" topic for their styles\n - Organizers are available to help where needed\n - At least one or two people per node should be able to help with CSS.\n - Karl and Heerko will be available if bugs / errors occur.\n- Printing Publications ( 1 hr )\n - A printer is required in the space (or easily accessible)\n - Accommodating for different paper sizes is an added bonus\n - Binding could be fun too\n- Sharing outcomes and reflections ( 1 hr ) \n - Round of publications\n - Reflection on process\n - Feedback on ChattyPub\n',Ze='# ChattyPub\n\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication. ChattyPub is a collaborative publication/zine-making tool built on top of the chat platform [Zulip](https://chat.hackersanddesigners.nl). By sending messages, reacting with emoji and writing simple CSS style rules the publication can be collectively designed.\n\n- [Zulip](#zulip)\n- [ChattyPub](#using-chattypub)\n- [Making a publication with Zulip & ChattyPub](#content)\n - [Content](#content)\n - [Rules](#rules)\n - [Printing](#printing)\n- [Typing Emoji](#typing-emoji)\n- [Problems?](#problems)\n\n## Zulip\n\nOn Zulip, conversations are categorized into different "Streams", which are comparable to "channels" in other messaging services like Discord. Streams can be public or private and host conversations consisting of text, images, files, reactions, etc..\n\nWhat differentiates Zulip from most messaging platforms is the way streams are sub-threaded. Zulip introduces the concept of "Topics", which, in the plainest terms, means that messages have subjects. When sending a message to a stream in Zulip, you can also specify the topic of the message and the stream automatically filters messages by their shared topics. If your message\'s topic doesn\'t exist yet, it will be created when you send your message.\n\nZulip allows you to react to messages using emoji\'s as well. We will make heavy use of emojis in ChattyPub.\n\nThere are several ways to engage with Zulip, including a web-client, a desktop app, and a mobile app.\n\n## Using ChattyPub\n\nhttp://chatty-pub.hackersanddesigners.nl\n\nChattyPub is a website that acts as a different interface to the same Zulip service. ChattyPub takes a stream from Zulip, combines messages into long-form articles and uses a design system combining Emojis and CSS syntax to style the messages, effectively turning the stream into a (printable!) webpage.\n\n## Making a publication with Zulip & ChattyPub\n\n### Content\n\n1. Create a stream on Zulip\n - Ensure that either (1) the stream name starts with `pub-` or (2) the stream includes a topic called "rules" (more on that later).\n - Ensure that the stream is public.\n2. Go to [ChattyPub](https://chatty-pub.hackersanddesigners.nl). The stream you created will be visible on the left-side navigation.\n3. Click on your stream.\n4. The main (middle) section of the website will have:\n 1. Your stream name (which will be the name of your publication)\n 2. The topics of your stream organized into a table of contents (which will act as "Chapters" in your publication)\n 3. The topics, in alphabetical order, displaying their messages, in chronological order.\n5. To create a new topic (chapter), return to Zulip and type a message to your stream, making sure to send it to the topic you want to create.\n\n### Rules\n\nThe right-hand side of the ChattyPub interface is reserved for one topic in your stream: "rules". This topic will house definitions for styles you want to apply to messages in your stream.\n\nGo back to Zulip and create the topic in your stream called "rules".\n\nEvery message you send to this topic should consist of a single emoji followed by a set of styles you\'d like applied to messages. For example:\n\n```CSS\n🍓 {\n color: red;\n text-decoration: underline;\n}\n```\n\nThese messages should be unique and follow the CSS syntax, as described in the [introduction to CSS](/docs/CSS). If you are comfortable with CSS, you can skip to the part of the document that describes [how CSS is used in ChattyPub](/docs/CSS#css-in-chattypub).\n\nTo apply these styles to the contents of your publication, head back to any other topic in your stream, select a message you\'d like to style, and react to it with the emoji whose styles you want to apply. On ChattyPub, the message should be rendered with these styles.\n\nIf you\'d like to style only a part of a message, select the message in Zulip and quote and respond to it (in the 3-dot menu). This will produce a text in your input box on the bottom of the interface. Delete the parts of the quoted message that you don\'t want the styles applied to, and send your response. When you react with an emoji to your own response, the part of the original message you quoted will inherit the styles defined for that emoji.\n\nKeep in mind that you can edit your own messages! So if you make a mistake (forgetting the semi-colon at the end of a statement is a common one), roll over your message and click the little pen at the top righthand side of the message.\n\n### Printing\n\n> Regrettably support for setting page size, page breaks etc. using [@page](https://caniuse.com/css-paged-media) is very poor in some browsers. Use MS Edge, Opera or Google Chrome for best results when printing or creating PDFs.\n\nTo print, click on the print button on the left side of the application. This will hide the interface, make all content visible and open the browsers\' Printing dialog box.\n\nIf you want to use background colors or background images in your publication you may have to turn that on in the print settings dialog.\n\nThere is more information on setting up pages sizes etc, in the CSS document.\n\n## Typing Emoji\n\n- [Windows](https://support.microsoft.com/en-us/windows/windows-10-keyboard-tips-and-tricks-588e0b72-0fff-6d3f-aeee-6e5116097942)\n- [Mac](https://www.howtogeek.com/684025/how-to-type-emoji-on-your-mac-with-a-keyboard-shortcut/)\n- Linux varies per distribution. If you run Linux you\'re probably capable of finding out how :)\n\n## Problems\n\nChattyPub is very young and you\'re sure to run into problems. Feel free to contact `@Karl Moubarak`, `@andré` or `@heerko` at https://chat.hackersanddesigners.nl/\n\nBelow are some things that we know of, and are working on:\n\n- :emoji: not working...\n',Ge=(a("e4cb"),{name:"Docs",data:function(){return{files:{Workshop:$e,Chattypub:Ze,CSS:Re}}},computed:{source:function(){return this.files[this.$route.params.slug]}},mounted:function(){var e=this;setTimeout((function(){e.source&&e.$route.hash&&document.querySelector(e.$route.hash).scrollIntoView({behavior:"smooth"})}),100)},methods:{getFileName:function(e,t){var a=e&&"function"===typeof e.match&&e.match(/\/?([^/.]*)\.?([^/]*)$/);return a?t&&a.length>2&&a[2]?a.slice(1).join("."):a[1]:null},handleLinks:function(){var e=this;Array.from(document.querySelectorAll("a")).forEach((function(t){t.addEventListener("click",(function(a){t.pathname.startsWith("/docs/")&&(console.log(t),e.$router.push(t.pathname),a.preventDefault(),document.scroll({top:0}))}))}))}}});a("926b");Ge.render=Le,Ge.__scopeId="data-v-32f02ba2";var Ye=Ge,Je="/",Ke=Object(I["a"])({history:Object(I["b"])(Je),routes:[{path:"/",name:"Home",component:Ve},{path:"/docs",name:"Docs",component:Ye},{path:"/docs/:slug",name:"Doc",props:!0,component:Ye},{path:"/:pathMatch(.*)*",name:"Home",component:Ve}]}),Qe=a("2909"),Xe=a("9558"),et=(a("a1f0"),a("1276"),a("a434"),a("0481"),a("4e82"),a("cd8a")),tt=function(e,t){var a=Object(et["stripHtml"])(e.content).result,o="",n="",f=[],r=(t||"").replace(" ","-"),s=e.id,i=e.content.includes("")||e.content.startsWith("```"),c=/

    0?(o=S.methods.shortcodeToEmoji(d[0]["groups"]["selector"]),S.methods.containsEmoji(o)&&(n=S.methods.toEmojiCode(o)),f=d[0]["groups"]["props"].split("\n"),f=f.filter((function(e){return ft(e)})),{className:o,emoji_code:n,rules:f,parentClassName:r,id:s,content:a,type:l}):(console.log("rejected rule",e),null)},at=function(e){var t={family:"",src:"",format:""},a=e,o=ot(a),n=o.split(".").pop();return t.src="https://chatty-pub-files.hackersanddesigners.nl/files"+a,t.format=nt(n),t.family=o.replace(".","_"),t},ot=function(e){return e.split("\\").pop().split("/").pop()},nt=function(e){var t="truetype";switch(e){case"woff":t="woff";break;case"eof":t="embedded-opentype";break}return t},ft=function(e){return e.match(/.+:.+;/gm)},rt=function(e){e.responseTo={id:e.content.replace(/.*\/near\//gm,"").replace(/\):.*[^]+/gm,""),sender_id:e.content.replace(/@_\*\*.*\|/gm,"").replace(/\*\*.\[said\].*[^]+/gm,""),quote:e.content.replace(/[^]+.*```quote\n/gm,"").replace(/ \n```/gm,"")}},st=function(e){e.responseTo={id:e.content.replace(/.*\/near\//gm,"").replace(/".*[^]+/gm,""),sender_id:e.content.replace(/[^]+data-user-id="/gm,"").replace(/">[^]+/gm,""),quote:e.content.replace(/.*[^]+<\/p>\n

    \n

    /gm,"").replace(/<\/p>\n<\/blockquote>/gm,"")},console.table(e.responseTo)},it=Object(i["a"])({strict:!1,state:{isMobile:!1,streams:[],currentStream:"",rules:[],topics:[],pubStr:"pub-"},mutations:{setMobile:function(e,t){return e.isMobile=t},setStreams:function(e,t){return e.streams=t},setCurStream:function(e,t){return e.currentStream=t},setTopics:function(e,t){return e.topics=t},addMessage:function(e,t){if(t.display_recipient==e.currentStream){t.content.startsWith("@_**")?rt(t):t.content.includes("user-mention")&&t.content.includes("blockquote")&&st(t);var a=e.topics.find((function(e){return e.title==t.subject}));a?a.messages.push(t):e.topics.push({title:t.subject,messages:[t]})}},deleteMessage:function(e,t){var a=t.mid,o=t.subject,n=e.topics.find((function(e){return e.title==o}));if(n){var f=n.messages.find((function(e){return e.id==a}));f&&n.messages.splice(n.messages.indexOf(f),1)}},addReaction:function(e,t){var a=t.mid,o=t.reaction,n=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==a}));n&&n.reactions.push(o)},removeReaction:function(e,t){var a=t.mid,o=t.reaction,n=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==a}));n&&n.reactions.splice(n.reactions.indexOf(o),1)},setRules:function(e,t){e.rules=t.reduce((function(t,a){var o=tt(a,e.currentStream);return null!==o&&t.push(o),t}),[])},addRule:function(e,t){null!==tt(t)&&(e.rules=[].concat(Object(Qe["a"])(e.rules),[tt(t,e.currentStream)]))},editMessage:function(e,t){var a=t.mid,o=t.content,n=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==a})),f=e.rules.find((function(e){return e.id==a}));if(n)n.content=o,n.content.startsWith("@_**")?rt(n):n.content.includes("user-mention")&&n.content.includes("blockquote")&&st(n);else if(f){e.rules.splice(e.rules.indexOf(f),1);var r=[].concat(Object(Qe["a"])(e.rules),[tt({id:a,content:o},e.currentStream)]);e.rules=r}},updateTopic:function(e,t){var a=t.orig_subject,o=t.subject,n=e.topics.find((function(e){return e.title==a}));n&&(n.title=o,n.messages.forEach((function(e){return e.subject=o})))}},actions:{},getters:{rules:function(e){return e.rules},sortedTopics:function(e){return Object(Qe["a"])(e.topics).sort((function(e,t){return e.title.localeCompare(t.title)})).filter((function(e){return e.messages.length>0&&"stream events"!=e.title}))}}}),ct=(a("85e4"),Object(o["createApp"])(D)),lt={html:!0,linkify:!0,typographer:!0};ct.config.globalProperties.$http=T.a,ct.config.globalProperties.$mdOpts=lt,ct.config.globalProperties.$md=new E.a(lt),ct.use(P.a).use(Ke).use(it).mount("#app")},6468:function(e,t,a){"use strict";a("4272")},"7f96":function(e){e.exports=JSON.parse('{"names":["+1","-1","100","1234","8_ball","a","ab","abc","abcd","accessible","accommodations","acrobatics","action","add","aerial_tramway","agent","agony","airplane","airplane_arrival","airplane_departure","alarm","alarm_clock","alchemy","alembic","alert","alien","all_good","alphabet","ambulance","american_football","amphora","anchor","android","angel","anger","anger_bubble","angry","angry_cat","angry_devil","anguish","anguished","ant","anxious","applause","apple","approved","aquarius","arabian_camel","arcade","archery","archive","aries","arms_open","arrival","art","asking_a_question","asterisk","astonished","at_work","athletic_shoe","atm","atom","attachment","avocado","b","baa","baby","baby_bottle","baby_change_station","baby_chick","back","backpack","bacon","badminton","baggage_claim","baguette","balance","ball","balloon","ballot_box","ballpoint_pen","bam","bamboo","banana","bangbang","bank","bar_chart","barber","baseball","basketball","bat","bath","bathtub","battery","beach","beach_umbrella","bear","bed","bedroom","bee","beer","beers","beetle","beginner","bell","bellhop_bell","bento","betrayed","bicycle","big_frown","big_rig","big_smile","bike","bikini","billiards","biohazard","bird","birthday","black_and_white_square","black_belt","black_circle","black_flag","black_heart","black_large_square","black_medium_small_square","black_medium_square","black_small_square","blank","blossom","blow_a_kiss","blowfish","blue_book","blue_circle","blue_heart","blush","blushing","boar","boat","bomb","boo","book","bookmark","books","boom","boot","bouquet","bow","bow_and_arrow","bowling","boxing_glove","boy","bravery","bread","breakfast","bride","bridge","briefcase","brightness","broken_heart","bronze","buddhism","bug","bulb","bull","bullet_train","bullhorn","bulls_eye","bunny","burial","burrito","bus","bus_stop","butterfly","buzz","cactus","cake","calendar","calf","call_me","calling","camel","camera","camping","campsite","cancer","candle","candy","canoe","capital_abcd","capital_letters","capricorn","car","card_index","carousel","carp_streamer","carpenter_square","carrot","cartwheel","castle","cat","caterpillar","caution","cd","celebration","cell_reception","chains","champagne","chart","check","check_mark","checkbox","checkered_flag","cheese","cherries","cherry_blossom","chestnut","chick","chicken","children_crossing","chili_pepper","chipmunk","chocolate","christianity","church","cinema","circle","circus","city","city_sunrise","cl","clap","classical_building","clink","clipboard","clock","clockwise","closed_book","closed_mailbox","closed_umbrella","clothing","cloud","cloudy","clover","clown","clubs","cluck","clue","cock-a-doodle-doo","cocktail","coffee","coffin","cold_sweat","collision","comet","commitment","commodities","composition_book","compression","computer","computer_mouse","concerned","conch","condemned","confetti","confounded","confused","congratulations","construction","construction_worker","construction_zone","control_knobs","convenience_store","cookie","cooking","cool","cop","corn","couch_and_lamp","counterclockwise","cow","cowboy","crab","crash","crayon","crazy","credit_card","cremation","crew","cricket","cricket_bat","crocodile","croissant","cross","cross_mark","crossed_flags","crown","cruise","crushed","cry","crying_cat","crystal","crystal_ball","cucumber","cupid","curry","custard","customs","cute","cyclist","cyclone","dagger","dancer","dancers","dancing","danger","dango","dark_sunglasses","darts","dash","date","death","debit_card","deciduous_tree","decoration","decorative_notebook","decrease","decreasing","deer","denim","department_store","departure","derelict_house","desert","desktop_computer","detective","devil","diamond_with_a_dot","diamonds","dice","die","digital_security","dim","ding","direct_hit","disabled","disappointed","disappointed_relieved","disco","distraught","divide","division","dizzy","do_not_litter","document","dog","dogi","dollar_bills","dollars","dolls","dolphin","done_deal","doner_kebab","donut","door","dormouse","double_down","double_exclamation","double_loop","double_up","doughnut","dove","dove_of_peace","down","down_button","downvote","downwards_trend","dragon","dragon_face","drama","dream","drenched","dress","drinking_water","drive_with_care","drooling","drop","drum","drumstick","duck","duel","dungeon","dvd","e-mail","eagle","ear","ear_of_rice","earth_africa","earth_americas","earth_asia","east","easy_come_easy_go","eating_utensils","egg","eggplant","eight","eight_pointed_star","eight_spoked_asterisk","elderly_man","elderly_woman","electric_plug","elephant","elevated_train","email","embarrassed","empty_mailbox","encrypted","end","engineer","envelope","envy","euro_banknotes","evergreen_tree","exchange","exclamation","exhausted","expecting","explosion","expressionless","eye","eyes","face_palm","face_with_thermometer","factory","fall","fallen_leaf","family","fast_down","fast_forward","fast_reverse","fast_up","fax","fear","feet","fencing","ferris_wheel","ferry","fever","field_hockey","file","file_cabinet","file_folder","film","find","fingers_crossed","fire","fire_engine","fire_truck","fireworks","first_place","fish","fishing","fist","fist_bump","five","fixing","flags","flame","flan","flashlight","fleur_de_lis","flip_flops","flipper","floppy_disk","flower","flu","flushed","fog","foggy","folder","food","football","footprints","fork_and_knife","fork_and_knife_with_plate","fortune_telling","forward","fountain","fountain_pen","four","four_leaf_clover","fox","framed_picture","free","fries","frog","frosty","frown","frowning","fuel_pump","full_battery","full_moon","funeral_urn","furniture","future","gas_pump","gear","gecko","geek","gelato","gem","gemini","ghost","gift","gift_heart","girl","glamour","glass_of_milk","glasses","globe","glowing_star","go","goal","goat","goblin","gold","gold_record","golf","gondola","goodnight","gooooooooal","gorilla","got_it","graduate","grapes","grave","green_apple","green_book","green_heart","grey_exclamation","grey_question","grimacing","grinning","grinning_face_with_smiling_eyes","growing","growing_heart","grumpy","gua_pi_mao","guard","guestrooms","guitar","gun","gym","gymnastics","haircut","half_frown","halo","hamburger","hammer","hammer_and_pick","hammer_and_wrench","hamster","hand","handbag","handball","handshake","handyman","handywoman","happy","hard_hat","harvest","hash","hat","hatching","hatching_chick","haunted","hazard","hazy","head_bandage","heading_down","heading_up","headlines","headphones","hear_no_evil","heart","heart_arrow","heart_box","heart_exclamation","heart_eyes","heart_eyes_cat","heart_kiss","heart_of_gold","heart_pulse","heartache","heartbeat","hearts","helicopter","hello","helmet","helpless","herb","hi","hibiscus","high_brightness","high_five","high_heels","high_speed_train","high_voltage","hinduism","hint","hiss","hocho","hole","hole_in_one","holiday_tree","home_phone","honey","honeybee","horizontal_traffic_light","horn","horse","horse_racing","horse_riding","hospital","hot","hot_pepper","hot_springs","hotdog","hotel","hourglass","hourglass_done","house","houses","hover","hug","humpback_whale","hundred","hungry","hurricane","hurt","hush","hushed","ice_cream","ice_hockey","ice_skate","id","idea","ill","immigration","imp","in_bed","in_love","inbox","inbox_zero","incorrect","increase","increasing","info","information_desk_person","injection","injured","innocent","interrobang","invincible","iphone","islam","island","izakaya_lantern","jack-o-lantern","japan","japan_post","jeans","jeep","joker","joking","joy","joy_cat","joystick","judiasm","juggling","justice","kaaba","kaching","kawaii","keikogi","key","key_signing","keyboard","kick_scooter","kimono","king","kiss","kiss_smiling_eyes","kiss_with_blush","kissing_cat","kitten","kiwi","knife","koala","label","ladybug","landing","landline","lantern","laptop","large_blue_diamond","large_orange_diamond","laughing","laughter_tears","leaves","ledger","left","left_fist","left_hook","left_right","lemon","leo","leopard","lets_eat","level_slider","levitating","lgbtq","libra","lifestyles","lift","light_bulb","light_rail","lightning","lightning_storm","like","link","linked","lion","lips","lips_are_sealed","lipstick","lipstick_kiss","lit","live_long_and_prosper","living_room","lizard","lock_with_key","locked","locked_bag","locker","lol","lollipop","looking","loop","losing_money","louder","loudspeaker","love","love_hotel","love_letter","love_you","low_brightness","lower_left","lower_right","loyalty","lucky","lying","m","mad","magnifying_glass","mahjong","mail","mail_dropoff","mail_received","mail_sent","mailbox","maintenance","maize","man","man_and_woman_couple","man_and_woman_holding_hands","mandarin","mantelpiece_clock","map","maple_leaf","martial_arts","mask","massage","meal","meat","mechanical","medal","medicine","megaphone","melon","memo","men_couple","menorah","mens","meow","merry_go_round","meteor","metro","mic","microphone","microscope","middle_finger","mike","military_medal","milk","milky_way","mine","minibus","minidisc","minus","mischievous","mobile_phone","money","money_face","money_with_wings","monkey","monkey_face","monorail","moon","moon_ceremony","moon_face","mortar_board","mosque","mostly_sunny","mother_christmas","mother_nature","motor_bike","motor_boat","motorcycle","motorway","mount_fuji","mountain","mountain_biker","mountain_cableway","mountain_railway","mountain_sunrise","mouse","mouth","movie","movie_camera","movie_theater","moving_truck","moyai","mrs_claus","multiplication","multiply","muscle","mushroom","music","musical_keyboard","musical_notes","musical_score","mute","mute_notifications","nail_care","nail_polish","namaste","name_badge","naruto","national_park","nauseated","nc17","nerd","nervous","neutral","new","new_baby","new_moon","new_moon_face","new_york","newspaper","next_track","ng","night","night_sky","nine","no_bicycles","no_entry","no_mail","no_mouth","no_pedestrians","no_phones","no_signal","no_smoking","no_sound","non-potable_water","noodles","nope","north","north_east","north_west","nose","not_allowed","note","notebook","notifications","nuclear","number_one","numbers","nursery","nut_and_bolt","o","ocean","ocean_sunrise","octagonal_sign","octopus","oden","office","office_supplies","ogre","oh_no","oil_drum","oink","ok","ok_signal","old_key","older_man","older_woman","om","on","oncoming_automobile","oncoming_bus","oncoming_car","oncoming_police_car","oncoming_streetcar","oncoming_taxi","oncoming_train","oncoming_tram","oncoming_trolley","one","onigiri","oops","open_book","open_hands","open_mouth","ophiuchus","oracle","orange","orange_book","organize","orthodox_cross","outbox","overcast","owl","ox","p","package","paella","page","pager","pained","paintbrush","painting","palette","palm","palm_tree","pancakes","panda","paper","paperclip","paperclip_chain","parking","part_alternation","partly_cloudy","partly_sunny","partly_sunny_with_rain","party_ball","pass","passenger_ship","passport_control","pause","paw_prints","paws","peace","peace_sign","peach","peanuts","pear","pedestrian","pen","pencil","penguin","pensive","performing_arts","persevere","person_frowning","person_pouting","person_tipping_hand","petrol_pump","phone","phone_off","physics","piano","pick","pick_me","picture","pig","pig_nose","piglet","pile_of_poo","pill","pin","pineapple","ping_pong","pirate","pisces","pizza","place_holder","place_of_worship","plant","play","play_pause","play_reverse","playing_cards","plus","point_down","point_left","point_of_information","point_right","point_up","poison","poker_face","police","police_car","pony","poodle","pool","poop","popcorn","post_office","potable_water","potato","pouch","poultry","pound_notes","pouting_cat","pow","power","praise","pray","prayer_beads","pregnant","present","previous_track","price_tag","pride","prince","princess","printer","privacy","prohibited","projector","protected","pumpkin","punch","puppy","purple_heart","purse","push_pin","put_litter_in_its_place","queasy","queen","question","quiet","rabbit","race","racecar","radio","radio_button","radioactive","rage","railway_car","railway_track","rainbow","rainy","raised_hand","raised_hands","raising_hand","ram","ramen","rat","rated_for_violence","receipt","reception","record","recreational_vehicle","recycle","red_book","red_circle","red_triangle_down","red_triangle_up","relaxed","relieved","reminder_ribbon","repeat","repeat_one","reply","rescue_worker","restroom","return","revolving_hearts","rewind","rhinoceros","ribbon","rice","rice_cracker","rideshare","right","right_fist","right_hook","ring","road","road_trip","robot","rock_carving","rock_on","rocket","rofl","roller_coaster","rolling_eyes","rolling_on_the_floor_laughing","rolodex","rooster","rose","rosette","rotating_light","rowboat","rowing","rugby","ruler","runner","running","running_shirt","running_shoe","sad","safe","safety_first","sagittarius","sailboat","sake","salad","sandal","santa","satchel","satellite","satellite_antenna","saxophone","say_cheese","scales","scared","school","school_bus","school_crossing","science","scientist","scissors","scooter","scorpion","scorpius","scream","scream_cat","screw","scroll","sculling","sealed","search","seashell","seat","second_place","secret","secure","see_no_evil","seedling","seeing_stars","selfie","semi_truck","senbei","services","settings","seven","sewing_pin","shadow","shadows","shamrock","shark","shaved_ice","shawarma","sheep","shell","shield","shinto_shrine","ship","shiro","shirt","shock","shoe","shooting_star","shopping_bags","shopping_cart","shopping_trolley","shout","shower","shrimp","shrinking","shrug","shuffle","sick","sign_of_the_horns","signal_bars","signal_strength","silence","silhouette","silhouettes","silver","siren","six","ski","ski_lift","skier","skip_back","skip_forward","skull","skull_and_crossbones","skyline","sleeping","sleepy","sleuth","slight_frown","slot_machine","small_airplane","small_blue_diamond","small_glass","small_orange_diamond","smartphone","smile","smile_cat","smiley","smiley_cat","smiling_devil","smiling_face","smiling_face_with_horns","smiling_imp","smirk","smirk_cat","smitten","smoking","smug","smug_cat","snail","snake","sneaker","sneaky","sneezing","snowboarder","snowflake","snowman","snowstorm","snowy","snowy_mountain","soaked","sob","soccer","soft_ice_cream","soft_serve","softer","solidarity","soon","sort","sos","sound","soup","south","south_east","south_west","souvlaki","space_invader","spades","spaghetti","sparkle","sparkler","sparkles","sparkling_heart","speak_no_evil","speaker","speaking_head","spectacles","speech_balloon","speech_bubble","speechless","speedboat","spider","spider_web","spiral_notebook","spiral_notepad","spiral_shell","spock","spooky","spoon","sports","sprout","spy","squared_ok","squared_up","squid","stadium","star","star_and_crescent","star_of_david","start","station","statue","statue_of_liberty","steam_locomotive","stew","stock_market","stop","stop_button","stop_sign","stopwatch","straightedge","strawberry","streetcar","stressed","strike","striped_pole","stuck_out_tongue","stuck_out_tongue_closed_eyes","stuck_out_tongue_wink","studio_microphone","stuffed_flatbread","subtract","suburb","subway","sun_and_rain","sun_face","sunflower","sunglasses","sunny","sunrise","sunset","sunshowers","surf","surprise","surrender","sushi","suspension_railway","swap","swat","sweat","sweat_drops","sweat_smile","sweet_potato","swim","swords","symbols","synagogue","syringe","table_setting","table_tennis","taco","tada","tag","take_off","taking_a_picture","tanabata_tree","tangerine","tap_water","taurus","taxi","tea","tears","telephone","telescope","television","temperature","tempura","ten","tennis","tent","thank_you","theater","thermometer","thinking","third_place","this","thought","three","thumb_tack","thumbs_down","thumbs_up","thunder_and_rain","thunderstorm","ticket","tie","tiger","tiger_cub","time","time_ticking","timer","times_up","tired","tm","toast","toilet","tokyo_tower","tomato","tongue","tools","top","top_hat","tornado","tortoise","tower","toxic","trackball","tractor","tractor-trailer","trademark","traffic_light","train","train_car","train_tracks","tram","transport_truck","trash_can","tree","triangular_flag","triangular_ruler","trident","triumph","trolley","trophy","tropical_drink","tropical_fish","truck","trumpet","tshirt","tulip","tumbling","turban","turkey","turtle","tuxedo","tv","two","two_hearts","two_men_holding_hands","two_women_holding_hands","typhoon","ufo","umbrella","umbrella_with_rain","umm","unamused","underage","unicorn","unlocked","unread_mail","up","up_button","up_down","upper_left","upper_right","upside_down","upvote","upwards_trend","vase","vertical_traffic_light","very_angry","vhs","vibration_mode","victory","video_camera","video_game","video_recorder","videocassette","violin","virgo","vise","voicemail","volcano","volleyball","volume","vs","wait_one_second","walking","warm","warning","wastebasket","watch","water_buffalo","water_closet","water_drop","water_polo","watermelon","wave","wavy_dash","waxing_moon","wc","weary","weary_cat","web","wedding","weight_lift","welcome","west","whale","wheel_of_dharma","wheelchair","white_and_black_square","white_circle","white_flag","white_flower","white_large_square","white_medium_small_square","white_medium_square","white_small_square","wilted_flower","wind","wind_chime","windy","wine","wink","winner","wish","wish_tree","wolf","woman","women_couple","womens","woof","work_in_progress","work_out","working_on_it","world_map","worried","wrench","wrestling","writing","wrong","wrong_way","www","x","yacht","yam","yellow_heart","yen_banknotes","yin_yang","yum","zap","zero","zip_it","zzz"],"name_to_codepoint":{"100":"1f4af","1234":"1f522","grinning":"1f600","happy":"1f600","smiley":"1f603","big_smile":"1f604","grinning_face_with_smiling_eyes":"1f601","laughing":"1f606","lol":"1f606","sweat_smile":"1f605","joy":"1f602","tears":"1f602","laughter_tears":"1f602","rolling_on_the_floor_laughing":"1f923","rofl":"1f923","smiling_face":"263a","relaxed":"263a","blush":"1f60a","innocent":"1f607","halo":"1f607","smile":"1f642","upside_down":"1f643","oops":"1f643","wink":"1f609","relieved":"1f60c","heart_eyes":"1f60d","in_love":"1f60d","heart_kiss":"1f618","blow_a_kiss":"1f618","kiss":"1f617","kiss_smiling_eyes":"1f619","kiss_with_blush":"1f61a","yum":"1f60b","stuck_out_tongue":"1f61b","mischievous":"1f61b","stuck_out_tongue_wink":"1f61c","joking":"1f61c","crazy":"1f61c","stuck_out_tongue_closed_eyes":"1f61d","money_face":"1f911","kaching":"1f911","hug":"1f917","arms_open":"1f917","nerd":"1f913","geek":"1f913","sunglasses":"1f60e","clown":"1f921","cowboy":"1f920","smirk":"1f60f","smug":"1f60f","unamused":"1f612","disappointed":"1f61e","pensive":"1f614","tired":"1f614","worried":"1f61f","oh_no":"1f615","half_frown":"1f615","concerned":"1f615","confused":"1f615","frown":"1f641","slight_frown":"1f641","sad":"2639","big_frown":"2639","persevere":"1f623","helpless":"1f623","confounded":"1f616","agony":"1f616","anguish":"1f62b","weary":"1f629","distraught":"1f629","triumph":"1f624","angry":"1f620","rage":"1f621","mad":"1f621","grumpy":"1f621","very_angry":"1f621","speechless":"1f636","no_mouth":"1f636","blank":"1f636","poker_face":"1f636","neutral":"1f610","expressionless":"1f611","hushed":"1f62f","frowning":"1f626","anguished":"1f627","pained":"1f627","open_mouth":"1f62e","surprise":"1f62e","astonished":"1f632","dizzy":"1f635","flushed":"1f633","embarrassed":"1f633","blushing":"1f633","scream":"1f631","fear":"1f628","scared":"1f628","shock":"1f628","cold_sweat":"1f630","cry":"1f622","exhausted":"1f625","disappointed_relieved":"1f625","stressed":"1f625","drooling":"1f924","sob":"1f62d","sweat":"1f613","sleepy":"1f62a","sleeping":"1f634","rolling_eyes":"1f644","thinking":"1f914","lying":"1f925","grimacing":"1f62c","nervous":"1f62c","anxious":"1f62c","silence":"1f910","quiet":"1f910","hush":"1f910","zip_it":"1f910","lips_are_sealed":"1f910","nauseated":"1f922","queasy":"1f922","sneezing":"1f927","mask":"1f637","sick":"1f912","flu":"1f912","face_with_thermometer":"1f912","ill":"1f912","fever":"1f912","hurt":"1f915","head_bandage":"1f915","injured":"1f915","smiling_devil":"1f608","smiling_imp":"1f608","smiling_face_with_horns":"1f608","devil":"1f47f","imp":"1f47f","angry_devil":"1f47f","ogre":"1f479","goblin":"1f47a","poop":"1f4a9","pile_of_poo":"1f4a9","ghost":"1f47b","boo":"1f47b","spooky":"1f47b","haunted":"1f47b","skull":"1f480","skull_and_crossbones":"2620","pirate":"2620","death":"2620","hazard":"2620","toxic":"2620","poison":"2620","alien":"1f47d","ufo":"1f47d","space_invader":"1f47e","robot":"1f916","jack-o-lantern":"1f383","pumpkin":"1f383","smiley_cat":"1f63a","smile_cat":"1f638","joy_cat":"1f639","heart_eyes_cat":"1f63b","smirk_cat":"1f63c","smug_cat":"1f63c","kissing_cat":"1f63d","scream_cat":"1f640","weary_cat":"1f640","crying_cat":"1f63f","angry_cat":"1f63e","pouting_cat":"1f63e","open_hands":"1f450","raised_hands":"1f64c","praise":"1f64c","clap":"1f44f","applause":"1f44f","pray":"1f64f","welcome":"1f64f","thank_you":"1f64f","namaste":"1f64f","handshake":"1f91d","done_deal":"1f91d","+1":"1f44d","thumbs_up":"1f44d","like":"1f44d","-1":"1f44e","thumbs_down":"1f44e","fist_bump":"1f44a","punch":"1f44a","fist":"270a","power":"270a","left_fist":"1f91b","right_fist":"1f91c","fingers_crossed":"1f91e","peace_sign":"270c","victory":"270c","rock_on":"1f918","sign_of_the_horns":"1f918","ok":"1f44c","got_it":"1f44c","point_left":"1f448","point_right":"1f449","point_up":"1f446","this":"1f446","point_down":"1f447","wait_one_second":"261d","point_of_information":"261d","asking_a_question":"261d","hand":"270b","raised_hand":"270b","stop":"1f91a","high_five":"1f590","palm":"1f590","spock":"1f596","live_long_and_prosper":"1f596","wave":"1f44b","hello":"1f44b","hi":"1f44b","call_me":"1f919","muscle":"1f4aa","middle_finger":"1f595","writing":"270d","selfie":"1f933","nail_polish":"1f485","nail_care":"1f485","ring":"1f48d","lipstick":"1f484","lipstick_kiss":"1f48b","lips":"1f444","mouth":"1f444","tongue":"1f445","ear":"1f442","nose":"1f443","footprints":"1f463","feet":"1f463","eye":"1f441","eyes":"1f440","looking":"1f440","speaking_head":"1f5e3","silhouette":"1f464","shadow":"1f464","silhouettes":"1f465","shadows":"1f465","baby":"1f476","boy":"1f466","girl":"1f467","man":"1f468","woman":"1f469","older_man":"1f474","elderly_man":"1f474","older_woman":"1f475","elderly_woman":"1f475","gua_pi_mao":"1f472","turban":"1f473","police":"1f46e","cop":"1f46e","construction_worker":"1f477","guard":"1f482","detective":"1f575","spy":"1f575","sleuth":"1f575","agent":"1f575","sneaky":"1f575","mother_christmas":"1f936","mrs_claus":"1f936","santa":"1f385","princess":"1f478","prince":"1f934","bride":"1f470","tuxedo":"1f935","angel":"1f47c","pregnant":"1f930","expecting":"1f930","bow":"1f647","information_desk_person":"1f481","person_tipping_hand":"1f481","no_signal":"1f645","nope":"1f645","ok_signal":"1f646","raising_hand":"1f64b","pick_me":"1f64b","face_palm":"1f926","shrug":"1f937","person_pouting":"1f64e","person_frowning":"1f64d","haircut":"1f487","massage":"1f486","levitating":"1f574","hover":"1f574","dancer":"1f483","dancing":"1f57a","disco":"1f57a","dancers":"1f46f","walking":"1f6b6","pedestrian":"1f6b6","running":"1f3c3","runner":"1f3c3","man_and_woman_holding_hands":"1f46b","man_and_woman_couple":"1f46b","two_women_holding_hands":"1f46d","women_couple":"1f46d","two_men_holding_hands":"1f46c","men_couple":"1f46c","family":"1f46a","clothing":"1f45a","shirt":"1f455","tshirt":"1f455","jeans":"1f456","denim":"1f456","tie":"1f454","dress":"1f457","bikini":"1f459","kimono":"1f458","high_heels":"1f460","sandal":"1f461","flip_flops":"1f461","boot":"1f462","shoe":"1f45e","athletic_shoe":"1f45f","sneaker":"1f45f","running_shoe":"1f45f","hat":"1f452","top_hat":"1f3a9","graduate":"1f393","mortar_board":"1f393","crown":"1f451","queen":"1f451","king":"1f451","helmet":"26d1","hard_hat":"26d1","rescue_worker":"26d1","safety_first":"26d1","invincible":"26d1","backpack":"1f392","satchel":"1f392","pouch":"1f45d","purse":"1f45b","handbag":"1f45c","briefcase":"1f4bc","glasses":"1f453","spectacles":"1f453","dark_sunglasses":"1f576","closed_umbrella":"1f302","umbrella":"2602","puppy":"1f436","kitten":"1f431","dormouse":"1f42d","hamster":"1f439","bunny":"1f430","fox":"1f98a","bear":"1f43b","panda":"1f43c","koala":"1f428","tiger_cub":"1f42f","lion":"1f981","calf":"1f42e","piglet":"1f437","pig_nose":"1f43d","frog":"1f438","monkey_face":"1f435","see_no_evil":"1f648","hear_no_evil":"1f649","speak_no_evil":"1f64a","monkey":"1f412","chicken":"1f414","cluck":"1f414","penguin":"1f427","bird":"1f426","chick":"1f424","baby_chick":"1f424","hatching":"1f423","hatching_chick":"1f423","new_baby":"1f425","duck":"1f986","eagle":"1f985","owl":"1f989","bat":"1f987","wolf":"1f43a","boar":"1f417","pony":"1f434","unicorn":"1f984","bee":"1f41d","buzz":"1f41d","honeybee":"1f41d","bug":"1f41b","caterpillar":"1f41b","butterfly":"1f98b","snail":"1f40c","shell":"1f41a","seashell":"1f41a","conch":"1f41a","spiral_shell":"1f41a","beetle":"1f41e","ladybug":"1f41e","ant":"1f41c","spider":"1f577","web":"1f578","spider_web":"1f578","turtle":"1f422","tortoise":"1f422","snake":"1f40d","hiss":"1f40d","lizard":"1f98e","gecko":"1f98e","scorpion":"1f982","crab":"1f980","squid":"1f991","octopus":"1f419","shrimp":"1f990","tropical_fish":"1f420","fish":"1f41f","blowfish":"1f421","dolphin":"1f42c","flipper":"1f42c","shark":"1f988","whale":"1f433","humpback_whale":"1f40b","crocodile":"1f40a","leopard":"1f406","tiger":"1f405","water_buffalo":"1f403","ox":"1f402","bull":"1f402","cow":"1f404","deer":"1f98c","arabian_camel":"1f42a","camel":"1f42b","elephant":"1f418","rhinoceros":"1f98f","gorilla":"1f98d","horse":"1f40e","pig":"1f416","oink":"1f416","goat":"1f410","ram":"1f40f","sheep":"1f411","baa":"1f411","dog":"1f415","woof":"1f415","poodle":"1f429","cat":"1f408","meow":"1f408","rooster":"1f413","alarm":"1f413","cock-a-doodle-doo":"1f413","turkey":"1f983","dove":"1f54a","dove_of_peace":"1f54a","rabbit":"1f407","mouse":"1f401","rat":"1f400","chipmunk":"1f43f","paw_prints":"1f43e","paws":"1f43e","dragon":"1f409","dragon_face":"1f432","cactus":"1f335","holiday_tree":"1f384","evergreen_tree":"1f332","tree":"1f333","deciduous_tree":"1f333","palm_tree":"1f334","seedling":"1f331","sprout":"1f331","herb":"1f33f","plant":"1f33f","shamrock":"2618","clover":"2618","lucky":"1f340","four_leaf_clover":"1f340","bamboo":"1f38d","wish_tree":"1f38b","tanabata_tree":"1f38b","leaves":"1f343","wind":"1f343","fall":"1f343","fallen_leaf":"1f342","maple_leaf":"1f341","mushroom":"1f344","harvest":"1f33e","ear_of_rice":"1f33e","bouquet":"1f490","tulip":"1f337","flower":"1f337","rose":"1f339","wilted_flower":"1f940","crushed":"1f940","sunflower":"1f33b","blossom":"1f33c","cherry_blossom":"1f338","hibiscus":"1f33a","earth_americas":"1f30e","earth_africa":"1f30d","earth_asia":"1f30f","full_moon":"1f315","new_moon":"1f311","waxing_moon":"1f314","new_moon_face":"1f31a","moon_face":"1f31d","sun_face":"1f31e","goodnight":"1f31b","moon":"1f319","seeing_stars":"1f4ab","star":"2b50","glowing_star":"1f31f","sparkles":"2728","glamour":"2728","high_voltage":"26a1","zap":"26a1","fire":"1f525","lit":"1f525","hot":"1f525","flame":"1f525","boom":"1f4a5","explosion":"1f4a5","crash":"1f4a5","collision":"1f4a5","comet":"2604","meteor":"2604","sunny":"2600","mostly_sunny":"1f324","partly_sunny":"26c5","partly_cloudy":"26c5","cloudy":"1f325","sunshowers":"1f326","sun_and_rain":"1f326","partly_sunny_with_rain":"1f326","rainbow":"1f308","pride":"1f308","lgbtq":"1f308","cloud":"2601","overcast":"2601","rainy":"1f327","soaked":"1f327","drenched":"1f327","thunderstorm":"26c8","thunder_and_rain":"26c8","lightning":"1f329","lightning_storm":"1f329","snowy":"1f328","snowstorm":"1f328","snowman":"2603","frosty":"26c4","snowflake":"2744","windy":"1f32c","mother_nature":"1f32c","dash":"1f4a8","tornado":"1f32a","fog":"1f32b","hazy":"1f32b","ocean":"1f30a","drop":"1f4a7","water_drop":"1f4a7","sweat_drops":"1f4a6","umbrella_with_rain":"2614","green_apple":"1f34f","apple":"1f34e","pear":"1f350","orange":"1f34a","tangerine":"1f34a","mandarin":"1f34a","lemon":"1f34b","banana":"1f34c","watermelon":"1f349","grapes":"1f347","strawberry":"1f353","melon":"1f348","cherries":"1f352","peach":"1f351","pineapple":"1f34d","kiwi":"1f95d","avocado":"1f951","tomato":"1f345","eggplant":"1f346","cucumber":"1f952","carrot":"1f955","corn":"1f33d","maize":"1f33d","hot_pepper":"1f336","chili_pepper":"1f336","potato":"1f954","yam":"1f360","sweet_potato":"1f360","chestnut":"1f330","peanuts":"1f95c","honey":"1f36f","croissant":"1f950","bread":"1f35e","baguette":"1f956","cheese":"1f9c0","egg":"1f95a","cooking":"1f373","bacon":"1f953","pancakes":"1f95e","breakfast":"1f95e","tempura":"1f364","drumstick":"1f357","poultry":"1f357","meat":"1f356","pizza":"1f355","hotdog":"1f32d","hamburger":"1f354","fries":"1f35f","doner_kebab":"1f959","shawarma":"1f959","souvlaki":"1f959","stuffed_flatbread":"1f959","taco":"1f32e","burrito":"1f32f","salad":"1f957","paella":"1f958","spaghetti":"1f35d","ramen":"1f35c","noodles":"1f35c","food":"1f372","soup":"1f372","stew":"1f372","naruto":"1f365","sushi":"1f363","bento":"1f371","curry":"1f35b","rice":"1f35a","onigiri":"1f359","senbei":"1f358","rice_cracker":"1f358","oden":"1f362","dango":"1f361","shaved_ice":"1f367","ice_cream":"1f368","gelato":"1f368","soft_serve":"1f366","soft_ice_cream":"1f366","cake":"1f370","birthday":"1f382","custard":"1f36e","flan":"1f36e","lollipop":"1f36d","candy":"1f36c","chocolate":"1f36b","popcorn":"1f37f","donut":"1f369","doughnut":"1f369","cookie":"1f36a","milk":"1f95b","glass_of_milk":"1f95b","baby_bottle":"1f37c","coffee":"2615","tea":"1f375","sake":"1f376","beer":"1f37a","beers":"1f37b","clink":"1f942","toast":"1f942","wine":"1f377","small_glass":"1f943","cocktail":"1f378","tropical_drink":"1f379","champagne":"1f37e","spoon":"1f944","fork_and_knife":"1f374","eating_utensils":"1f374","hungry":"1f37d","meal":"1f37d","table_setting":"1f37d","fork_and_knife_with_plate":"1f37d","lets_eat":"1f37d","football":"26bd","soccer":"26bd","basketball":"1f3c0","american_football":"1f3c8","baseball":"26be","tennis":"1f3be","volleyball":"1f3d0","rugby":"1f3c9","billiards":"1f3b1","pool":"1f3b1","8_ball":"1f3b1","ping_pong":"1f3d3","table_tennis":"1f3d3","badminton":"1f3f8","gooooooooal":"1f945","goal":"1f945","ice_hockey":"1f3d2","field_hockey":"1f3d1","cricket":"1f3cf","cricket_bat":"1f3cf","hole_in_one":"26f3","bow_and_arrow":"1f3f9","archery":"1f3f9","fishing":"1f3a3","boxing_glove":"1f94a","black_belt":"1f94b","keikogi":"1f94b","dogi":"1f94b","martial_arts":"1f94b","ice_skate":"26f8","ski":"1f3bf","skier":"26f7","snowboarder":"1f3c2","lift":"1f3cb","work_out":"1f3cb","weight_lift":"1f3cb","gym":"1f3cb","fencing":"1f93a","wrestling":"1f93c","cartwheel":"1f938","acrobatics":"1f938","gymnastics":"1f938","tumbling":"1f938","ball":"26f9","sports":"26f9","handball":"1f93e","golf":"1f3cc","surf":"1f3c4","swim":"1f3ca","water_polo":"1f93d","rowboat":"1f6a3","crew":"1f6a3","sculling":"1f6a3","rowing":"1f6a3","horse_racing":"1f3c7","horse_riding":"1f3c7","cyclist":"1f6b4","mountain_biker":"1f6b5","running_shirt":"1f3bd","medal":"1f3c5","military_medal":"1f396","first_place":"1f947","gold":"1f947","number_one":"1f947","second_place":"1f948","silver":"1f948","third_place":"1f949","bronze":"1f949","trophy":"1f3c6","winner":"1f3c6","rosette":"1f3f5","reminder_ribbon":"1f397","pass":"1f3ab","ticket":"1f39f","circus":"1f3aa","juggling":"1f939","performing_arts":"1f3ad","drama":"1f3ad","theater":"1f3ad","art":"1f3a8","palette":"1f3a8","painting":"1f3a8","action":"1f3ac","microphone":"1f3a4","mike":"1f3a4","mic":"1f3a4","headphones":"1f3a7","musical_score":"1f3bc","piano":"1f3b9","musical_keyboard":"1f3b9","drum":"1f941","saxophone":"1f3b7","trumpet":"1f3ba","guitar":"1f3b8","violin":"1f3bb","dice":"1f3b2","die":"1f3b2","direct_hit":"1f3af","darts":"1f3af","bulls_eye":"1f3af","strike":"1f3b3","bowling":"1f3b3","video_game":"1f3ae","slot_machine":"1f3b0","car":"1f697","taxi":"1f695","rideshare":"1f695","recreational_vehicle":"1f699","jeep":"1f699","bus":"1f68c","school_bus":"1f68c","trolley":"1f68e","racecar":"1f3ce","police_car":"1f693","ambulance":"1f691","fire_truck":"1f692","fire_engine":"1f692","minibus":"1f690","moving_truck":"1f69a","truck":"1f69b","tractor-trailer":"1f69b","big_rig":"1f69b","semi_truck":"1f69b","transport_truck":"1f69b","tractor":"1f69c","kick_scooter":"1f6f4","bike":"1f6b2","bicycle":"1f6b2","scooter":"1f6f5","motor_bike":"1f6f5","motorcycle":"1f3cd","siren":"1f6a8","rotating_light":"1f6a8","alert":"1f6a8","oncoming_police_car":"1f694","oncoming_bus":"1f68d","oncoming_car":"1f698","oncoming_automobile":"1f698","oncoming_taxi":"1f696","aerial_tramway":"1f6a1","ski_lift":"1f6a1","gondola":"1f6a0","mountain_cableway":"1f6a0","suspension_railway":"1f69f","railway_car":"1f683","train_car":"1f683","tram":"1f68b","streetcar":"1f68b","mountain_railway":"1f69e","monorail":"1f69d","elevated_train":"1f69d","high_speed_train":"1f684","bullet_train":"1f685","light_rail":"1f688","train":"1f682","steam_locomotive":"1f682","oncoming_train":"1f686","subway":"1f687","oncoming_tram":"1f68a","oncoming_streetcar":"1f68a","oncoming_trolley":"1f68a","station":"1f689","helicopter":"1f681","small_airplane":"1f6e9","airplane":"2708","take_off":"1f6eb","departure":"1f6eb","airplane_departure":"1f6eb","landing":"1f6ec","arrival":"1f6ec","airplane_arrival":"1f6ec","rocket":"1f680","satellite":"1f6f0","seat":"1f4ba","canoe":"1f6f6","boat":"26f5","sailboat":"26f5","motor_boat":"1f6e5","speedboat":"1f6a4","passenger_ship":"1f6f3","yacht":"1f6f3","cruise":"1f6f3","ferry":"26f4","ship":"1f6a2","anchor":"2693","work_in_progress":"1f6a7","construction_zone":"1f6a7","fuel_pump":"26fd","gas_pump":"26fd","petrol_pump":"26fd","bus_stop":"1f68f","traffic_light":"1f6a6","vertical_traffic_light":"1f6a6","horizontal_traffic_light":"1f6a5","map":"1f5fa","world_map":"1f5fa","road_trip":"1f5fa","rock_carving":"1f5ff","moyai":"1f5ff","statue":"1f5fd","new_york":"1f5fd","statue_of_liberty":"1f5fd","fountain":"26f2","tower":"1f5fc","tokyo_tower":"1f5fc","castle":"1f3f0","shiro":"1f3ef","stadium":"1f3df","ferris_wheel":"1f3a1","roller_coaster":"1f3a2","carousel":"1f3a0","merry_go_round":"1f3a0","beach_umbrella":"26f1","beach":"1f3d6","island":"1f3dd","mountain":"26f0","snowy_mountain":"1f3d4","mount_fuji":"1f5fb","volcano":"1f30b","desert":"1f3dc","campsite":"1f3d5","tent":"26fa","camping":"26fa","railway_track":"1f6e4","train_tracks":"1f6e4","road":"1f6e3","motorway":"1f6e3","construction":"1f3d7","factory":"1f3ed","house":"1f3e0","suburb":"1f3e1","houses":"1f3d8","derelict_house":"1f3da","condemned":"1f3da","office":"1f3e2","department_store":"1f3ec","japan_post":"1f3e3","post_office":"1f3e4","hospital":"1f3e5","bank":"1f3e6","hotel":"1f3e8","convenience_store":"1f3ea","school":"1f3eb","love_hotel":"1f3e9","wedding":"1f492","classical_building":"1f3db","church":"26ea","mosque":"1f54c","synagogue":"1f54d","kaaba":"1f54b","shinto_shrine":"26e9","japan":"1f5fe","moon_ceremony":"1f391","national_park":"1f3de","sunrise":"1f305","ocean_sunrise":"1f305","mountain_sunrise":"1f304","shooting_star":"1f320","wish":"1f320","sparkler":"1f387","fireworks":"1f386","city_sunrise":"1f307","sunset":"1f306","city":"1f3d9","skyline":"1f3d9","night":"1f303","milky_way":"1f30c","night_sky":"1f30c","bridge":"1f309","foggy":"1f301","watch":"231a","mobile_phone":"1f4f1","smartphone":"1f4f1","iphone":"1f4f1","android":"1f4f1","calling":"1f4f2","computer":"1f4bb","laptop":"1f4bb","keyboard":"2328","desktop_computer":"1f5a5","printer":"1f5a8","computer_mouse":"1f5b1","trackball":"1f5b2","joystick":"1f579","arcade":"1f579","compression":"1f5dc","vise":"1f5dc","gold_record":"1f4bd","minidisc":"1f4bd","floppy_disk":"1f4be","cd":"1f4bf","dvd":"1f4c0","vhs":"1f4fc","videocassette":"1f4fc","camera":"1f4f7","taking_a_picture":"1f4f8","say_cheese":"1f4f8","video_camera":"1f4f9","video_recorder":"1f4f9","movie_camera":"1f3a5","projector":"1f4fd","movie":"1f4fd","film":"1f39e","landline":"1f4de","home_phone":"1f4de","phone":"260e","telephone":"260e","pager":"1f4df","fax":"1f4e0","tv":"1f4fa","television":"1f4fa","radio":"1f4fb","studio_microphone":"1f399","volume":"1f39a","level_slider":"1f39a","control_knobs":"1f39b","stopwatch":"23f1","timer":"23f2","alarm_clock":"23f0","mantelpiece_clock":"1f570","times_up":"231b","hourglass_done":"231b","time_ticking":"23f3","hourglass":"23f3","satellite_antenna":"1f4e1","battery":"1f50b","full_battery":"1f50b","electric_plug":"1f50c","light_bulb":"1f4a1","bulb":"1f4a1","idea":"1f4a1","flashlight":"1f526","candle":"1f56f","wastebasket":"1f5d1","trash_can":"1f5d1","oil_drum":"1f6e2","commodities":"1f6e2","losing_money":"1f4b8","easy_come_easy_go":"1f4b8","money_with_wings":"1f4b8","dollar_bills":"1f4b5","yen_banknotes":"1f4b4","euro_banknotes":"1f4b6","pound_notes":"1f4b7","money":"1f4b0","credit_card":"1f4b3","debit_card":"1f4b3","gem":"1f48e","crystal":"1f48e","justice":"2696","scales":"2696","balance":"2696","fixing":"1f527","wrench":"1f527","hammer":"1f528","maintenance":"1f528","handyman":"1f528","handywoman":"1f528","at_work":"2692","hammer_and_pick":"2692","working_on_it":"1f6e0","hammer_and_wrench":"1f6e0","tools":"1f6e0","mine":"26cf","pick":"26cf","nut_and_bolt":"1f529","screw":"1f529","gear":"2699","settings":"2699","mechanical":"2699","engineer":"2699","chains":"26d3","gun":"1f52b","bomb":"1f4a3","knife":"1f52a","hocho":"1f52a","betrayed":"1f52a","dagger":"1f5e1","rated_for_violence":"1f5e1","duel":"2694","swords":"2694","shield":"1f6e1","smoking":"1f6ac","coffin":"26b0","burial":"26b0","grave":"26b0","funeral_urn":"26b1","cremation":"26b1","vase":"1f3fa","amphora":"1f3fa","crystal_ball":"1f52e","oracle":"1f52e","future":"1f52e","fortune_telling":"1f52e","prayer_beads":"1f4ff","barber":"1f488","striped_pole":"1f488","alchemy":"2697","alembic":"2697","telescope":"1f52d","science":"1f52c","microscope":"1f52c","scientist":"1f52c","hole":"1f573","medicine":"1f48a","pill":"1f48a","injection":"1f489","syringe":"1f489","temperature":"1f321","thermometer":"1f321","warm":"1f321","toilet":"1f6bd","potable_water":"1f6b0","tap_water":"1f6b0","drinking_water":"1f6b0","shower":"1f6bf","bathtub":"1f6c1","bath":"1f6c0","bellhop_bell":"1f6ce","reception":"1f6ce","services":"1f6ce","ding":"1f6ce","key":"1f511","secret":"1f5dd","dungeon":"1f5dd","old_key":"1f5dd","encrypted":"1f5dd","clue":"1f5dd","hint":"1f5dd","door":"1f6aa","living_room":"1f6cb","furniture":"1f6cb","couch_and_lamp":"1f6cb","lifestyles":"1f6cb","bed":"1f6cf","bedroom":"1f6cf","in_bed":"1f6cc","accommodations":"1f6cc","guestrooms":"1f6cc","picture":"1f5bc","framed_picture":"1f5bc","shopping_bags":"1f6cd","shopping_cart":"1f6d2","shopping_trolley":"1f6d2","gift":"1f381","present":"1f381","balloon":"1f388","celebration":"1f388","carp_streamer":"1f38f","flags":"1f38f","ribbon":"1f380","decoration":"1f380","confetti":"1f38a","party_ball":"1f38a","tada":"1f389","congratulations":"1f389","dolls":"1f38e","lantern":"1f3ee","izakaya_lantern":"1f3ee","wind_chime":"1f390","email":"2709","envelope":"2709","mail":"2709","mail_sent":"1f4e9","sealed":"1f4e9","mail_received":"1f4e8","e-mail":"1f4e7","love_letter":"1f48c","inbox":"1f4e5","outbox":"1f4e4","package":"1f4e6","label":"1f3f7","tag":"1f3f7","price_tag":"1f3f7","closed_mailbox":"1f4ea","mailbox":"1f4eb","unread_mail":"1f4ec","inbox_zero":"1f4ed","empty_mailbox":"1f4ed","no_mail":"1f4ed","mail_dropoff":"1f4ee","horn":"1f4ef","scroll":"1f4dc","receipt":"1f4c3","document":"1f4c4","paper":"1f4c4","file":"1f4c4","page":"1f4c4","place_holder":"1f4d1","bar_chart":"1f4ca","chart":"1f4c8","upwards_trend":"1f4c8","growing":"1f4c8","increasing":"1f4c8","downwards_trend":"1f4c9","shrinking":"1f4c9","decreasing":"1f4c9","spiral_notepad":"1f5d2","date":"1f4c6","calendar":"1f4c5","rolodex":"1f4c7","card_index":"1f4c7","archive":"1f5c3","ballot_box":"1f5f3","file_cabinet":"1f5c4","clipboard":"1f4cb","organize":"1f4c1","file_folder":"1f4c1","folder":"1f4c2","sort":"1f5c2","newspaper":"1f5de","swat":"1f5de","headlines":"1f4f0","notebook":"1f4d3","composition_book":"1f4d3","decorative_notebook":"1f4d4","ledger":"1f4d2","spiral_notebook":"1f4d2","red_book":"1f4d5","closed_book":"1f4d5","green_book":"1f4d7","blue_book":"1f4d8","orange_book":"1f4d9","books":"1f4da","book":"1f4d6","open_book":"1f4d6","bookmark":"1f516","link":"1f517","paperclip":"1f4ce","attachment":"1f4ce","office_supplies":"1f587","paperclip_chain":"1f587","linked":"1f587","carpenter_square":"1f4d0","triangular_ruler":"1f4d0","ruler":"1f4cf","straightedge":"1f4cf","push_pin":"1f4cc","thumb_tack":"1f4cc","pin":"1f4cd","sewing_pin":"1f4cd","scissors":"2702","pen":"1f58a","ballpoint_pen":"1f58a","fountain_pen":"1f58b","paintbrush":"1f58c","crayon":"1f58d","memo":"1f4dd","note":"1f4dd","pencil":"270f","search":"1f50d","find":"1f50d","magnifying_glass":"1f50d","privacy":"1f50f","key_signing":"1f50f","digital_security":"1f50f","protected":"1f50f","secure":"1f510","lock_with_key":"1f510","safe":"1f510","commitment":"1f510","loyalty":"1f510","locked":"1f512","unlocked":"1f513","heart":"2764","love":"2764","love_you":"2764","yellow_heart":"1f49b","heart_of_gold":"1f49b","green_heart":"1f49a","envy":"1f49a","blue_heart":"1f499","purple_heart":"1f49c","bravery":"1f49c","black_heart":"1f5a4","broken_heart":"1f494","heartache":"1f494","heart_exclamation":"2763","two_hearts":"1f495","revolving_hearts":"1f49e","heartbeat":"1f493","heart_pulse":"1f497","growing_heart":"1f497","sparkling_heart":"1f496","cupid":"1f498","smitten":"1f498","heart_arrow":"1f498","gift_heart":"1f49d","heart_box":"1f49f","peace":"262e","cross":"271d","christianity":"271d","star_and_crescent":"262a","islam":"262a","om":"1f549","hinduism":"1f549","wheel_of_dharma":"2638","buddhism":"2638","star_of_david":"2721","judiasm":"2721","menorah":"1f54e","yin_yang":"262f","orthodox_cross":"2626","place_of_worship":"1f6d0","ophiuchus":"26ce","aries":"2648","taurus":"2649","gemini":"264a","cancer":"264b","leo":"264c","virgo":"264d","libra":"264e","scorpius":"264f","sagittarius":"2650","capricorn":"2651","aquarius":"2652","pisces":"2653","id":"1f194","atom":"269b","physics":"269b","radioactive":"2622","nuclear":"2622","biohazard":"2623","phone_off":"1f4f4","vibration_mode":"1f4f3","eight_pointed_star":"2734","vs":"1f19a","white_flower":"1f4ae","a":"1f170","b":"1f171","ab":"1f18e","cl":"1f191","o":"1f17e","sos":"1f198","cross_mark":"274c","incorrect":"274c","wrong":"274c","circle":"2b55","stop_sign":"1f6d1","octagonal_sign":"1f6d1","no_entry":"26d4","wrong_way":"26d4","name_badge":"1f4db","prohibited":"1f6ab","not_allowed":"1f6ab","hundred":"1f4af","anger":"1f4a2","bam":"1f4a2","pow":"1f4a2","hot_springs":"2668","no_pedestrians":"1f6b7","do_not_litter":"1f6af","no_bicycles":"1f6b3","non-potable_water":"1f6b1","underage":"1f51e","nc17":"1f51e","no_phones":"1f4f5","no_smoking":"1f6ad","exclamation":"2757","grey_exclamation":"2755","question":"2753","grey_question":"2754","bangbang":"203c","double_exclamation":"203c","interrobang":"2049","low_brightness":"1f505","dim":"1f505","brightness":"1f506","high_brightness":"1f506","part_alternation":"303d","warning":"26a0","caution":"26a0","danger":"26a0","children_crossing":"1f6b8","school_crossing":"1f6b8","drive_with_care":"1f6b8","trident":"1f531","fleur_de_lis":"269c","beginner":"1f530","recycle":"267b","check":"2705","all_good":"2705","approved":"2705","stock_market":"1f4b9","sparkle":"2747","eight_spoked_asterisk":"2733","x":"274e","www":"1f310","globe":"1f310","cute":"1f4a0","kawaii":"1f4a0","diamond_with_a_dot":"1f4a0","metro":"24c2","m":"24c2","cyclone":"1f300","hurricane":"1f300","typhoon":"1f300","zzz":"1f4a4","atm":"1f3e7","wc":"1f6be","water_closet":"1f6be","accessible":"267f","wheelchair":"267f","disabled":"267f","parking":"1f17f","p":"1f17f","passport_control":"1f6c2","immigration":"1f6c2","customs":"1f6c3","baggage_claim":"1f6c4","locker":"1f6c5","locked_bag":"1f6c5","mens":"1f6b9","womens":"1f6ba","baby_change_station":"1f6bc","nursery":"1f6bc","restroom":"1f6bb","put_litter_in_its_place":"1f6ae","cinema":"1f3a6","movie_theater":"1f3a6","cell_reception":"1f4f6","signal_strength":"1f4f6","signal_bars":"1f4f6","symbols":"1f523","info":"2139","abc":"1f524","abcd":"1f521","alphabet":"1f521","capital_abcd":"1f520","capital_letters":"1f520","ng":"1f196","squared_ok":"1f197","squared_up":"1f199","cool":"1f192","new":"1f195","free":"1f193","zero":"0030-20e3","one":"0031-20e3","two":"0032-20e3","three":"0033-20e3","four":"0034-20e3","five":"0035-20e3","six":"0036-20e3","seven":"0037-20e3","eight":"0038-20e3","nine":"0039-20e3","ten":"1f51f","numbers":"1f522","hash":"0023-20e3","asterisk":"002a-20e3","play":"25b6","pause":"23f8","play_pause":"23ef","stop_button":"23f9","record":"23fa","next_track":"23ed","skip_forward":"23ed","previous_track":"23ee","skip_back":"23ee","fast_forward":"23e9","rewind":"23ea","fast_reverse":"23ea","double_up":"23eb","fast_up":"23eb","double_down":"23ec","fast_down":"23ec","play_reverse":"25c0","upvote":"1f53c","up_button":"1f53c","increase":"1f53c","downvote":"1f53d","down_button":"1f53d","decrease":"1f53d","right":"27a1","east":"27a1","left":"2b05","west":"2b05","up":"2b06","north":"2b06","down":"2b07","south":"2b07","upper_right":"2197","north_east":"2197","lower_right":"2198","south_east":"2198","lower_left":"2199","south_west":"2199","upper_left":"2196","north_west":"2196","up_down":"2195","left_right":"2194","swap":"2194","forward":"21aa","right_hook":"21aa","reply":"21a9","left_hook":"21a9","heading_up":"2934","heading_down":"2935","shuffle":"1f500","repeat":"1f501","repeat_one":"1f502","counterclockwise":"1f504","return":"1f504","clockwise":"1f503","music":"1f3b5","musical_notes":"1f3b6","plus":"2795","add":"2795","minus":"2796","subtract":"2796","division":"2797","divide":"2797","multiplication":"2716","multiply":"2716","dollars":"1f4b2","exchange":"1f4b1","tm":"2122","trademark":"2122","wavy_dash":"3030","loop":"27b0","double_loop":"27bf","voicemail":"27bf","end":"1f51a","back":"1f519","on":"1f51b","top":"1f51d","soon":"1f51c","check_mark":"2714","checkbox":"2611","radio_button":"1f518","white_circle":"26aa","black_circle":"26ab","red_circle":"1f534","blue_circle":"1f535","red_triangle_up":"1f53a","red_triangle_down":"1f53b","small_orange_diamond":"1f538","small_blue_diamond":"1f539","large_orange_diamond":"1f536","large_blue_diamond":"1f537","black_and_white_square":"1f533","white_and_black_square":"1f532","black_small_square":"25aa","white_small_square":"25ab","black_medium_small_square":"25fe","white_medium_small_square":"25fd","black_medium_square":"25fc","white_medium_square":"25fb","black_large_square":"2b1b","white_large_square":"2b1c","speaker":"1f508","mute":"1f507","no_sound":"1f507","softer":"1f509","louder":"1f50a","sound":"1f50a","notifications":"1f514","bell":"1f514","mute_notifications":"1f515","megaphone":"1f4e3","shout":"1f4e3","loudspeaker":"1f4e2","bullhorn":"1f4e2","umm":"1f4ac","speech_balloon":"1f4ac","speech_bubble":"1f5e8","thought":"1f4ad","dream":"1f4ad","anger_bubble":"1f5ef","spades":"2660","clubs":"2663","hearts":"2665","diamonds":"2666","joker":"1f0cf","playing_cards":"1f3b4","mahjong":"1f004","time":"1f557","clock":"1f557","white_flag":"1f3f3","surrender":"1f3f3","black_flag":"1f3f4","checkered_flag":"1f3c1","race":"1f3c1","go":"1f3c1","start":"1f3c1","triangular_flag":"1f6a9","crossed_flags":"1f38c","solidarity":"1f38c"},"codepoint_to_name":{"2049":"interrobang","2122":"tm","2139":"info","2194":"left_right","2195":"up_down","2196":"upper_left","2197":"upper_right","2198":"lower_right","2199":"lower_left","2328":"keyboard","2600":"sunny","2601":"cloud","2602":"umbrella","2603":"snowman","2604":"comet","2611":"checkbox","2614":"umbrella_with_rain","2615":"coffee","2618":"shamrock","2620":"skull_and_crossbones","2622":"radioactive","2623":"biohazard","2626":"orthodox_cross","2638":"wheel_of_dharma","2639":"sad","2648":"aries","2649":"taurus","2650":"sagittarius","2651":"capricorn","2652":"aquarius","2653":"pisces","2660":"spades","2663":"clubs","2665":"hearts","2666":"diamonds","2668":"hot_springs","2692":"at_work","2693":"anchor","2694":"duel","2696":"justice","2697":"alchemy","2699":"gear","2702":"scissors","2705":"check","2708":"airplane","2709":"email","2714":"check_mark","2716":"multiplication","2721":"star_of_david","2728":"sparkles","2733":"eight_spoked_asterisk","2734":"eight_pointed_star","2744":"snowflake","2747":"sparkle","2753":"question","2754":"grey_question","2755":"grey_exclamation","2757":"exclamation","2763":"heart_exclamation","2764":"heart","2795":"plus","2796":"minus","2797":"division","2934":"heading_up","2935":"heading_down","3030":"wavy_dash","1f600":"grinning","1f603":"smiley","1f604":"big_smile","1f601":"grinning_face_with_smiling_eyes","1f606":"laughing","1f605":"sweat_smile","1f602":"joy","1f923":"rolling_on_the_floor_laughing","263a":"smiling_face","1f60a":"blush","1f607":"innocent","1f642":"smile","1f643":"upside_down","1f609":"wink","1f60c":"relieved","1f60d":"heart_eyes","1f618":"heart_kiss","1f617":"kiss","1f619":"kiss_smiling_eyes","1f61a":"kiss_with_blush","1f60b":"yum","1f61b":"stuck_out_tongue","1f61c":"stuck_out_tongue_wink","1f61d":"stuck_out_tongue_closed_eyes","1f911":"money_face","1f917":"hug","1f913":"nerd","1f60e":"sunglasses","1f921":"clown","1f920":"cowboy","1f60f":"smirk","1f612":"unamused","1f61e":"disappointed","1f614":"pensive","1f61f":"worried","1f615":"oh_no","1f641":"frown","1f623":"persevere","1f616":"confounded","1f62b":"anguish","1f629":"weary","1f624":"triumph","1f620":"angry","1f621":"rage","1f636":"speechless","1f610":"neutral","1f611":"expressionless","1f62f":"hushed","1f626":"frowning","1f627":"anguished","1f62e":"open_mouth","1f632":"astonished","1f635":"dizzy","1f633":"flushed","1f631":"scream","1f628":"fear","1f630":"cold_sweat","1f622":"cry","1f625":"exhausted","1f924":"drooling","1f62d":"sob","1f613":"sweat","1f62a":"sleepy","1f634":"sleeping","1f644":"rolling_eyes","1f914":"thinking","1f925":"lying","1f62c":"grimacing","1f910":"silence","1f922":"nauseated","1f927":"sneezing","1f637":"mask","1f912":"sick","1f915":"hurt","1f608":"smiling_devil","1f47f":"devil","1f479":"ogre","1f47a":"goblin","1f4a9":"poop","1f47b":"ghost","1f480":"skull","1f47d":"alien","1f47e":"space_invader","1f916":"robot","1f383":"jack-o-lantern","1f63a":"smiley_cat","1f638":"smile_cat","1f639":"joy_cat","1f63b":"heart_eyes_cat","1f63c":"smirk_cat","1f63d":"kissing_cat","1f640":"scream_cat","1f63f":"crying_cat","1f63e":"angry_cat","1f450":"open_hands","1f64c":"raised_hands","1f44f":"clap","1f64f":"pray","1f91d":"handshake","1f44d":"+1","1f44e":"-1","1f44a":"fist_bump","270a":"fist","1f91b":"left_fist","1f91c":"right_fist","1f91e":"fingers_crossed","270c":"peace_sign","1f918":"rock_on","1f44c":"ok","1f448":"point_left","1f449":"point_right","1f446":"point_up","1f447":"point_down","261d":"wait_one_second","270b":"hand","1f91a":"stop","1f590":"high_five","1f596":"spock","1f44b":"wave","1f919":"call_me","1f4aa":"muscle","1f595":"middle_finger","270d":"writing","1f933":"selfie","1f485":"nail_polish","1f48d":"ring","1f484":"lipstick","1f48b":"lipstick_kiss","1f444":"lips","1f445":"tongue","1f442":"ear","1f443":"nose","1f463":"footprints","1f441":"eye","1f440":"eyes","1f5e3":"speaking_head","1f464":"silhouette","1f465":"silhouettes","1f476":"baby","1f466":"boy","1f467":"girl","1f468":"man","1f469":"woman","1f474":"older_man","1f475":"older_woman","1f472":"gua_pi_mao","1f473":"turban","1f46e":"police","1f477":"construction_worker","1f482":"guard","1f575":"detective","1f936":"mother_christmas","1f385":"santa","1f478":"princess","1f934":"prince","1f470":"bride","1f935":"tuxedo","1f47c":"angel","1f930":"pregnant","1f647":"bow","1f481":"information_desk_person","1f645":"no_signal","1f646":"ok_signal","1f64b":"raising_hand","1f926":"face_palm","1f937":"shrug","1f64e":"person_pouting","1f64d":"person_frowning","1f487":"haircut","1f486":"massage","1f574":"levitating","1f483":"dancer","1f57a":"dancing","1f46f":"dancers","1f6b6":"walking","1f3c3":"running","1f46b":"man_and_woman_holding_hands","1f46d":"two_women_holding_hands","1f46c":"two_men_holding_hands","1f46a":"family","1f45a":"clothing","1f455":"shirt","1f456":"jeans","1f454":"tie","1f457":"dress","1f459":"bikini","1f458":"kimono","1f460":"high_heels","1f461":"sandal","1f462":"boot","1f45e":"shoe","1f45f":"athletic_shoe","1f452":"hat","1f3a9":"top_hat","1f393":"graduate","1f451":"crown","26d1":"helmet","1f392":"backpack","1f45d":"pouch","1f45b":"purse","1f45c":"handbag","1f4bc":"briefcase","1f453":"glasses","1f576":"dark_sunglasses","1f302":"closed_umbrella","1f436":"puppy","1f431":"kitten","1f42d":"dormouse","1f439":"hamster","1f430":"bunny","1f98a":"fox","1f43b":"bear","1f43c":"panda","1f428":"koala","1f42f":"tiger_cub","1f981":"lion","1f42e":"calf","1f437":"piglet","1f43d":"pig_nose","1f438":"frog","1f435":"monkey_face","1f648":"see_no_evil","1f649":"hear_no_evil","1f64a":"speak_no_evil","1f412":"monkey","1f414":"chicken","1f427":"penguin","1f426":"bird","1f424":"chick","1f423":"hatching","1f425":"new_baby","1f986":"duck","1f985":"eagle","1f989":"owl","1f987":"bat","1f43a":"wolf","1f417":"boar","1f434":"pony","1f984":"unicorn","1f41d":"bee","1f41b":"bug","1f98b":"butterfly","1f40c":"snail","1f41a":"shell","1f41e":"beetle","1f41c":"ant","1f577":"spider","1f578":"web","1f422":"turtle","1f40d":"snake","1f98e":"lizard","1f982":"scorpion","1f980":"crab","1f991":"squid","1f419":"octopus","1f990":"shrimp","1f420":"tropical_fish","1f41f":"fish","1f421":"blowfish","1f42c":"dolphin","1f988":"shark","1f433":"whale","1f40b":"humpback_whale","1f40a":"crocodile","1f406":"leopard","1f405":"tiger","1f403":"water_buffalo","1f402":"ox","1f404":"cow","1f98c":"deer","1f42a":"arabian_camel","1f42b":"camel","1f418":"elephant","1f98f":"rhinoceros","1f98d":"gorilla","1f40e":"horse","1f416":"pig","1f410":"goat","1f40f":"ram","1f411":"sheep","1f415":"dog","1f429":"poodle","1f408":"cat","1f413":"rooster","1f983":"turkey","1f54a":"dove","1f407":"rabbit","1f401":"mouse","1f400":"rat","1f43f":"chipmunk","1f43e":"paw_prints","1f409":"dragon","1f432":"dragon_face","1f335":"cactus","1f384":"holiday_tree","1f332":"evergreen_tree","1f333":"tree","1f334":"palm_tree","1f331":"seedling","1f33f":"herb","1f340":"lucky","1f38d":"bamboo","1f38b":"wish_tree","1f343":"leaves","1f342":"fallen_leaf","1f341":"maple_leaf","1f344":"mushroom","1f33e":"harvest","1f490":"bouquet","1f337":"tulip","1f339":"rose","1f940":"wilted_flower","1f33b":"sunflower","1f33c":"blossom","1f338":"cherry_blossom","1f33a":"hibiscus","1f30e":"earth_americas","1f30d":"earth_africa","1f30f":"earth_asia","1f315":"full_moon","1f311":"new_moon","1f314":"waxing_moon","1f31a":"new_moon_face","1f31d":"moon_face","1f31e":"sun_face","1f31b":"goodnight","1f319":"moon","1f4ab":"seeing_stars","2b50":"star","1f31f":"glowing_star","26a1":"high_voltage","1f525":"fire","1f4a5":"boom","1f324":"mostly_sunny","26c5":"partly_sunny","1f325":"cloudy","1f326":"sunshowers","1f308":"rainbow","1f327":"rainy","26c8":"thunderstorm","1f329":"lightning","1f328":"snowy","26c4":"frosty","1f32c":"windy","1f4a8":"dash","1f32a":"tornado","1f32b":"fog","1f30a":"ocean","1f4a7":"drop","1f4a6":"sweat_drops","1f34f":"green_apple","1f34e":"apple","1f350":"pear","1f34a":"orange","1f34b":"lemon","1f34c":"banana","1f349":"watermelon","1f347":"grapes","1f353":"strawberry","1f348":"melon","1f352":"cherries","1f351":"peach","1f34d":"pineapple","1f95d":"kiwi","1f951":"avocado","1f345":"tomato","1f346":"eggplant","1f952":"cucumber","1f955":"carrot","1f33d":"corn","1f336":"hot_pepper","1f954":"potato","1f360":"yam","1f330":"chestnut","1f95c":"peanuts","1f36f":"honey","1f950":"croissant","1f35e":"bread","1f956":"baguette","1f9c0":"cheese","1f95a":"egg","1f373":"cooking","1f953":"bacon","1f95e":"pancakes","1f364":"tempura","1f357":"drumstick","1f356":"meat","1f355":"pizza","1f32d":"hotdog","1f354":"hamburger","1f35f":"fries","1f959":"doner_kebab","1f32e":"taco","1f32f":"burrito","1f957":"salad","1f958":"paella","1f35d":"spaghetti","1f35c":"ramen","1f372":"food","1f365":"naruto","1f363":"sushi","1f371":"bento","1f35b":"curry","1f35a":"rice","1f359":"onigiri","1f358":"senbei","1f362":"oden","1f361":"dango","1f367":"shaved_ice","1f368":"ice_cream","1f366":"soft_serve","1f370":"cake","1f382":"birthday","1f36e":"custard","1f36d":"lollipop","1f36c":"candy","1f36b":"chocolate","1f37f":"popcorn","1f369":"donut","1f36a":"cookie","1f95b":"milk","1f37c":"baby_bottle","1f375":"tea","1f376":"sake","1f37a":"beer","1f37b":"beers","1f942":"clink","1f377":"wine","1f943":"small_glass","1f378":"cocktail","1f379":"tropical_drink","1f37e":"champagne","1f944":"spoon","1f374":"fork_and_knife","1f37d":"hungry","26bd":"football","1f3c0":"basketball","1f3c8":"american_football","26be":"baseball","1f3be":"tennis","1f3d0":"volleyball","1f3c9":"rugby","1f3b1":"billiards","1f3d3":"ping_pong","1f3f8":"badminton","1f945":"gooooooooal","1f3d2":"ice_hockey","1f3d1":"field_hockey","1f3cf":"cricket","26f3":"hole_in_one","1f3f9":"bow_and_arrow","1f3a3":"fishing","1f94a":"boxing_glove","1f94b":"black_belt","26f8":"ice_skate","1f3bf":"ski","26f7":"skier","1f3c2":"snowboarder","1f3cb":"lift","1f93a":"fencing","1f93c":"wrestling","1f938":"cartwheel","26f9":"ball","1f93e":"handball","1f3cc":"golf","1f3c4":"surf","1f3ca":"swim","1f93d":"water_polo","1f6a3":"rowboat","1f3c7":"horse_racing","1f6b4":"cyclist","1f6b5":"mountain_biker","1f3bd":"running_shirt","1f3c5":"medal","1f396":"military_medal","1f947":"first_place","1f948":"second_place","1f949":"third_place","1f3c6":"trophy","1f3f5":"rosette","1f397":"reminder_ribbon","1f3ab":"pass","1f39f":"ticket","1f3aa":"circus","1f939":"juggling","1f3ad":"performing_arts","1f3a8":"art","1f3ac":"action","1f3a4":"microphone","1f3a7":"headphones","1f3bc":"musical_score","1f3b9":"piano","1f941":"drum","1f3b7":"saxophone","1f3ba":"trumpet","1f3b8":"guitar","1f3bb":"violin","1f3b2":"dice","1f3af":"direct_hit","1f3b3":"strike","1f3ae":"video_game","1f3b0":"slot_machine","1f697":"car","1f695":"taxi","1f699":"recreational_vehicle","1f68c":"bus","1f68e":"trolley","1f3ce":"racecar","1f693":"police_car","1f691":"ambulance","1f692":"fire_truck","1f690":"minibus","1f69a":"moving_truck","1f69b":"truck","1f69c":"tractor","1f6f4":"kick_scooter","1f6b2":"bike","1f6f5":"scooter","1f3cd":"motorcycle","1f6a8":"siren","1f694":"oncoming_police_car","1f68d":"oncoming_bus","1f698":"oncoming_car","1f696":"oncoming_taxi","1f6a1":"aerial_tramway","1f6a0":"gondola","1f69f":"suspension_railway","1f683":"railway_car","1f68b":"tram","1f69e":"mountain_railway","1f69d":"monorail","1f684":"high_speed_train","1f685":"bullet_train","1f688":"light_rail","1f682":"train","1f686":"oncoming_train","1f687":"subway","1f68a":"oncoming_tram","1f689":"station","1f681":"helicopter","1f6e9":"small_airplane","1f6eb":"take_off","1f6ec":"landing","1f680":"rocket","1f6f0":"satellite","1f4ba":"seat","1f6f6":"canoe","26f5":"boat","1f6e5":"motor_boat","1f6a4":"speedboat","1f6f3":"passenger_ship","26f4":"ferry","1f6a2":"ship","1f6a7":"work_in_progress","26fd":"fuel_pump","1f68f":"bus_stop","1f6a6":"traffic_light","1f6a5":"horizontal_traffic_light","1f5fa":"map","1f5ff":"rock_carving","1f5fd":"statue","26f2":"fountain","1f5fc":"tower","1f3f0":"castle","1f3ef":"shiro","1f3df":"stadium","1f3a1":"ferris_wheel","1f3a2":"roller_coaster","1f3a0":"carousel","26f1":"beach_umbrella","1f3d6":"beach","1f3dd":"island","26f0":"mountain","1f3d4":"snowy_mountain","1f5fb":"mount_fuji","1f30b":"volcano","1f3dc":"desert","1f3d5":"campsite","26fa":"tent","1f6e4":"railway_track","1f6e3":"road","1f3d7":"construction","1f3ed":"factory","1f3e0":"house","1f3e1":"suburb","1f3d8":"houses","1f3da":"derelict_house","1f3e2":"office","1f3ec":"department_store","1f3e3":"japan_post","1f3e4":"post_office","1f3e5":"hospital","1f3e6":"bank","1f3e8":"hotel","1f3ea":"convenience_store","1f3eb":"school","1f3e9":"love_hotel","1f492":"wedding","1f3db":"classical_building","26ea":"church","1f54c":"mosque","1f54d":"synagogue","1f54b":"kaaba","26e9":"shinto_shrine","1f5fe":"japan","1f391":"moon_ceremony","1f3de":"national_park","1f305":"sunrise","1f304":"mountain_sunrise","1f320":"shooting_star","1f387":"sparkler","1f386":"fireworks","1f307":"city_sunrise","1f306":"sunset","1f3d9":"city","1f303":"night","1f30c":"milky_way","1f309":"bridge","1f301":"foggy","231a":"watch","1f4f1":"mobile_phone","1f4f2":"calling","1f4bb":"computer","1f5a5":"desktop_computer","1f5a8":"printer","1f5b1":"computer_mouse","1f5b2":"trackball","1f579":"joystick","1f5dc":"compression","1f4bd":"gold_record","1f4be":"floppy_disk","1f4bf":"cd","1f4c0":"dvd","1f4fc":"vhs","1f4f7":"camera","1f4f8":"taking_a_picture","1f4f9":"video_camera","1f3a5":"movie_camera","1f4fd":"projector","1f39e":"film","1f4de":"landline","260e":"phone","1f4df":"pager","1f4e0":"fax","1f4fa":"tv","1f4fb":"radio","1f399":"studio_microphone","1f39a":"volume","1f39b":"control_knobs","23f1":"stopwatch","23f2":"timer","23f0":"alarm_clock","1f570":"mantelpiece_clock","231b":"times_up","23f3":"time_ticking","1f4e1":"satellite_antenna","1f50b":"battery","1f50c":"electric_plug","1f4a1":"light_bulb","1f526":"flashlight","1f56f":"candle","1f5d1":"wastebasket","1f6e2":"oil_drum","1f4b8":"losing_money","1f4b5":"dollar_bills","1f4b4":"yen_banknotes","1f4b6":"euro_banknotes","1f4b7":"pound_notes","1f4b0":"money","1f4b3":"credit_card","1f48e":"gem","1f527":"fixing","1f528":"hammer","1f6e0":"working_on_it","26cf":"mine","1f529":"nut_and_bolt","26d3":"chains","1f52b":"gun","1f4a3":"bomb","1f52a":"knife","1f5e1":"dagger","1f6e1":"shield","1f6ac":"smoking","26b0":"coffin","26b1":"funeral_urn","1f3fa":"vase","1f52e":"crystal_ball","1f4ff":"prayer_beads","1f488":"barber","1f52d":"telescope","1f52c":"science","1f573":"hole","1f48a":"medicine","1f489":"injection","1f321":"temperature","1f6bd":"toilet","1f6b0":"potable_water","1f6bf":"shower","1f6c1":"bathtub","1f6c0":"bath","1f6ce":"bellhop_bell","1f511":"key","1f5dd":"secret","1f6aa":"door","1f6cb":"living_room","1f6cf":"bed","1f6cc":"in_bed","1f5bc":"picture","1f6cd":"shopping_bags","1f6d2":"shopping_cart","1f381":"gift","1f388":"balloon","1f38f":"carp_streamer","1f380":"ribbon","1f38a":"confetti","1f389":"tada","1f38e":"dolls","1f3ee":"lantern","1f390":"wind_chime","1f4e9":"mail_sent","1f4e8":"mail_received","1f4e7":"e-mail","1f48c":"love_letter","1f4e5":"inbox","1f4e4":"outbox","1f4e6":"package","1f3f7":"label","1f4ea":"closed_mailbox","1f4eb":"mailbox","1f4ec":"unread_mail","1f4ed":"inbox_zero","1f4ee":"mail_dropoff","1f4ef":"horn","1f4dc":"scroll","1f4c3":"receipt","1f4c4":"document","1f4d1":"place_holder","1f4ca":"bar_chart","1f4c8":"chart","1f4c9":"downwards_trend","1f5d2":"spiral_notepad","1f4c6":"date","1f4c5":"calendar","1f4c7":"rolodex","1f5c3":"archive","1f5f3":"ballot_box","1f5c4":"file_cabinet","1f4cb":"clipboard","1f4c1":"organize","1f4c2":"folder","1f5c2":"sort","1f5de":"newspaper","1f4f0":"headlines","1f4d3":"notebook","1f4d4":"decorative_notebook","1f4d2":"ledger","1f4d5":"red_book","1f4d7":"green_book","1f4d8":"blue_book","1f4d9":"orange_book","1f4da":"books","1f4d6":"book","1f516":"bookmark","1f517":"link","1f4ce":"paperclip","1f587":"office_supplies","1f4d0":"carpenter_square","1f4cf":"ruler","1f4cc":"push_pin","1f4cd":"pin","1f58a":"pen","1f58b":"fountain_pen","1f58c":"paintbrush","1f58d":"crayon","1f4dd":"memo","270f":"pencil","1f50d":"search","1f50f":"privacy","1f510":"secure","1f512":"locked","1f513":"unlocked","1f49b":"yellow_heart","1f49a":"green_heart","1f499":"blue_heart","1f49c":"purple_heart","1f5a4":"black_heart","1f494":"broken_heart","1f495":"two_hearts","1f49e":"revolving_hearts","1f493":"heartbeat","1f497":"heart_pulse","1f496":"sparkling_heart","1f498":"cupid","1f49d":"gift_heart","1f49f":"heart_box","262e":"peace","271d":"cross","262a":"star_and_crescent","1f549":"om","1f54e":"menorah","262f":"yin_yang","1f6d0":"place_of_worship","26ce":"ophiuchus","264a":"gemini","264b":"cancer","264c":"leo","264d":"virgo","264e":"libra","264f":"scorpius","1f194":"id","269b":"atom","1f4f4":"phone_off","1f4f3":"vibration_mode","1f19a":"vs","1f4ae":"white_flower","1f170":"a","1f171":"b","1f18e":"ab","1f191":"cl","1f17e":"o","1f198":"sos","274c":"cross_mark","2b55":"circle","1f6d1":"stop_sign","26d4":"no_entry","1f4db":"name_badge","1f6ab":"prohibited","1f4af":"100","1f4a2":"anger","1f6b7":"no_pedestrians","1f6af":"do_not_litter","1f6b3":"no_bicycles","1f6b1":"non-potable_water","1f51e":"underage","1f4f5":"no_phones","1f6ad":"no_smoking","203c":"bangbang","1f505":"low_brightness","1f506":"brightness","303d":"part_alternation","26a0":"warning","1f6b8":"children_crossing","1f531":"trident","269c":"fleur_de_lis","1f530":"beginner","267b":"recycle","1f4b9":"stock_market","274e":"x","1f310":"www","1f4a0":"cute","24c2":"metro","1f300":"cyclone","1f4a4":"zzz","1f3e7":"atm","1f6be":"wc","267f":"accessible","1f17f":"parking","1f6c2":"passport_control","1f6c3":"customs","1f6c4":"baggage_claim","1f6c5":"locker","1f6b9":"mens","1f6ba":"womens","1f6bc":"baby_change_station","1f6bb":"restroom","1f6ae":"put_litter_in_its_place","1f3a6":"cinema","1f4f6":"cell_reception","1f523":"symbols","1f524":"abc","1f521":"abcd","1f520":"capital_abcd","1f196":"ng","1f197":"squared_ok","1f199":"squared_up","1f192":"cool","1f195":"new","1f193":"free","0030-20e3":"zero","0031-20e3":"one","0032-20e3":"two","0033-20e3":"three","0034-20e3":"four","0035-20e3":"five","0036-20e3":"six","0037-20e3":"seven","0038-20e3":"eight","0039-20e3":"nine","1f51f":"ten","1f522":"1234","0023-20e3":"hash","002a-20e3":"asterisk","25b6":"play","23f8":"pause","23ef":"play_pause","23f9":"stop_button","23fa":"record","23ed":"next_track","23ee":"previous_track","23e9":"fast_forward","23ea":"rewind","23eb":"double_up","23ec":"double_down","25c0":"play_reverse","1f53c":"upvote","1f53d":"downvote","27a1":"right","2b05":"left","2b06":"up","2b07":"down","21aa":"forward","21a9":"reply","1f500":"shuffle","1f501":"repeat","1f502":"repeat_one","1f504":"counterclockwise","1f503":"clockwise","1f3b5":"music","1f3b6":"musical_notes","1f4b2":"dollars","1f4b1":"exchange","27b0":"loop","27bf":"double_loop","1f51a":"end","1f519":"back","1f51b":"on","1f51d":"top","1f51c":"soon","1f518":"radio_button","26aa":"white_circle","26ab":"black_circle","1f534":"red_circle","1f535":"blue_circle","1f53a":"red_triangle_up","1f53b":"red_triangle_down","1f538":"small_orange_diamond","1f539":"small_blue_diamond","1f536":"large_orange_diamond","1f537":"large_blue_diamond","1f533":"black_and_white_square","1f532":"white_and_black_square","25aa":"black_small_square","25ab":"white_small_square","25fe":"black_medium_small_square","25fd":"white_medium_small_square","25fc":"black_medium_square","25fb":"white_medium_square","2b1b":"black_large_square","2b1c":"white_large_square","1f508":"speaker","1f507":"mute","1f509":"softer","1f50a":"louder","1f514":"notifications","1f515":"mute_notifications","1f4e3":"megaphone","1f4e2":"loudspeaker","1f4ac":"umm","1f5e8":"speech_bubble","1f4ad":"thought","1f5ef":"anger_bubble","1f0cf":"joker","1f3b4":"playing_cards","1f004":"mahjong","1f557":"time","1f3f3":"white_flag","1f3f4":"black_flag","1f3c1":"checkered_flag","1f6a9":"triangular_flag","1f38c":"crossed_flags"},"emoji_catalog":{"Symbols":["1f3e7","1f6ae","1f6b0","267f","1f6b9","1f6ba","1f6bb","1f6bc","1f6be","1f6c2","1f6c3","1f6c4","1f6c5","26a0","1f6b8","26d4","1f6ab","1f6b3","1f6ad","1f6af","1f6b1","1f6b7","1f4f5","1f51e","2622","2623","2b06","2197","27a1","2198","2b07","2199","2b05","2196","2195","2194","21a9","21aa","2934","2935","1f503","1f504","1f519","1f51a","1f51b","1f51c","1f51d","1f6d0","269b","1f549","2721","2638","262f","271d","2626","262a","262e","1f54e","2648","2649","264a","264b","264c","264d","264e","264f","2650","2651","2652","2653","26ce","1f500","1f501","1f502","25b6","23e9","23ed","23ef","25c0","23ea","23ee","1f53c","23eb","1f53d","23ec","23f8","23f9","23fa","1f3a6","1f505","1f506","1f4f6","1f4f3","1f4f4","2716","2795","2796","2797","203c","2049","2753","2754","2755","2757","3030","1f4b1","1f4b2","267b","269c","1f531","1f4db","1f530","2b55","2705","2611","2714","274c","274e","27b0","27bf","303d","2733","2734","2747","2122","0023-20e3","002a-20e3","0030-20e3","0031-20e3","0032-20e3","0033-20e3","0034-20e3","0035-20e3","0036-20e3","0037-20e3","0038-20e3","0039-20e3","1f51f","1f520","1f521","1f522","1f523","1f524","1f170","1f18e","1f171","1f191","1f192","1f193","2139","1f194","24c2","1f195","1f196","1f17e","1f197","1f17f","1f198","1f199","1f19a","1f534","1f535","26ab","26aa","2b1b","2b1c","25fc","25fb","25fe","25fd","25aa","25ab","1f536","1f537","1f538","1f539","1f53a","1f53b","1f4a0","1f518","1f533","1f532"],"Activities":["1f383","1f384","1f386","1f387","2728","1f388","1f389","1f38a","1f38b","1f38d","1f38e","1f38f","1f390","1f391","1f380","1f381","1f397","1f39f","1f3ab","1f396","1f3c6","1f3c5","1f947","1f948","1f949","26bd","26be","1f3c0","1f3d0","1f3c8","1f3c9","1f3be","1f3b3","1f3cf","1f3d1","1f3d2","1f3d3","1f3f8","1f94a","1f94b","1f945","26f3","26f8","1f3a3","1f3bd","1f3bf","1f3af","1f3b1","1f52e","1f3ae","1f579","1f3b0","1f3b2","2660","2665","2666","2663","1f0cf","1f004","1f3b4","1f3ad","1f5bc","1f3a8"],"Travel & Places":["1f30d","1f30e","1f30f","1f310","1f5fa","1f5fe","1f3d4","26f0","1f30b","1f5fb","1f3d5","1f3d6","1f3dc","1f3dd","1f3de","1f3df","1f3db","1f3d7","1f3d8","1f3da","1f3e0","1f3e1","1f3e2","1f3e3","1f3e4","1f3e5","1f3e6","1f3e8","1f3e9","1f3ea","1f3eb","1f3ec","1f3ed","1f3ef","1f3f0","1f492","1f5fc","1f5fd","26ea","1f54c","1f54d","26e9","1f54b","26f2","26fa","1f301","1f303","1f3d9","1f304","1f305","1f306","1f307","1f309","2668","1f3a0","1f3a1","1f3a2","1f488","1f3aa","1f682","1f683","1f684","1f685","1f686","1f687","1f688","1f689","1f68a","1f69d","1f69e","1f68b","1f68c","1f68d","1f68e","1f690","1f691","1f692","1f693","1f694","1f695","1f696","1f697","1f698","1f699","1f69a","1f69b","1f69c","1f3ce","1f3cd","1f6f5","1f6b2","1f6f4","1f68f","1f6e3","1f6e4","1f6e2","26fd","1f6a8","1f6a5","1f6a6","1f6d1","1f6a7","2693","26f5","1f6f6","1f6a4","1f6f3","26f4","1f6e5","1f6a2","2708","1f6e9","1f6eb","1f6ec","1f4ba","1f681","1f69f","1f6a0","1f6a1","1f6f0","1f680","1f6ce","231b","23f3","231a","23f0","23f1","23f2","1f570","1f557","1f311","1f314","1f315","1f319","1f31a","1f31b","1f321","2600","1f31d","1f31e","2b50","1f31f","1f320","1f30c","2601","26c5","26c8","1f324","1f325","1f326","1f327","1f328","1f329","1f32a","1f32b","1f32c","1f300","1f308","1f302","2602","2614","26f1","26a1","2744","2603","26c4","2604","1f525","1f4a7","1f30a"],"Food & Drink":["1f347","1f348","1f349","1f34a","1f34b","1f34c","1f34d","1f34e","1f34f","1f350","1f351","1f352","1f353","1f95d","1f345","1f951","1f346","1f954","1f955","1f33d","1f336","1f952","1f344","1f95c","1f330","1f35e","1f950","1f956","1f95e","1f9c0","1f356","1f357","1f953","1f354","1f35f","1f355","1f32d","1f32e","1f32f","1f959","1f95a","1f373","1f958","1f372","1f957","1f37f","1f371","1f358","1f359","1f35a","1f35b","1f35c","1f35d","1f360","1f362","1f363","1f364","1f365","1f361","1f980","1f990","1f991","1f366","1f367","1f368","1f369","1f36a","1f382","1f370","1f36b","1f36c","1f36d","1f36e","1f36f","1f37c","1f95b","2615","1f375","1f376","1f37e","1f377","1f378","1f379","1f37a","1f37b","1f942","1f943","1f37d","1f374","1f944","1f52a","1f3fa"],"Animals & Nature":["1f435","1f412","1f98d","1f436","1f415","1f429","1f43a","1f98a","1f431","1f408","1f981","1f42f","1f405","1f406","1f434","1f40e","1f984","1f98c","1f42e","1f402","1f403","1f404","1f437","1f416","1f417","1f43d","1f40f","1f411","1f410","1f42a","1f42b","1f418","1f98f","1f42d","1f401","1f400","1f439","1f430","1f407","1f43f","1f987","1f43b","1f428","1f43c","1f43e","1f983","1f414","1f413","1f423","1f424","1f425","1f426","1f427","1f54a","1f985","1f986","1f989","1f438","1f40a","1f422","1f98e","1f40d","1f432","1f409","1f433","1f40b","1f42c","1f41f","1f420","1f421","1f988","1f419","1f41a","1f40c","1f98b","1f41b","1f41c","1f41d","1f41e","1f577","1f578","1f982","1f490","1f338","1f4ae","1f3f5","1f339","1f940","1f33a","1f33b","1f33c","1f337","1f331","1f332","1f333","1f334","1f335","1f33e","1f33f","2618","1f340","1f341","1f342","1f343"],"People & Body":["1f44b","1f91a","1f590","270b","1f596","1f44c","270c","1f91e","1f918","1f919","1f448","1f449","1f446","1f595","1f447","261d","1f44d","1f44e","270a","1f44a","1f91b","1f91c","1f44f","1f64c","1f450","1f91d","1f64f","270d","1f485","1f933","1f4aa","1f442","1f443","1f440","1f441","1f445","1f444","1f476","1f466","1f467","1f468","1f469","1f474","1f475","1f64d","1f64e","1f645","1f646","1f481","1f64b","1f647","1f926","1f937","1f46e","1f575","1f482","1f477","1f934","1f478","1f473","1f472","1f935","1f470","1f930","1f47c","1f385","1f936","1f486","1f487","1f6b6","1f3c3","1f483","1f57a","1f574","1f46f","1f93a","1f3c7","26f7","1f3c2","1f3cc","1f3c4","1f6a3","1f3ca","26f9","1f3cb","1f6b4","1f6b5","1f938","1f93c","1f93d","1f93e","1f939","1f6c0","1f6cc","1f46d","1f46b","1f46c","1f46a","1f5e3","1f464","1f465","1f463"],"Flags":["1f3c1","1f6a9","1f38c","1f3f4","1f3f3"],"Objects":["1f453","1f576","1f454","1f455","1f456","1f457","1f458","1f459","1f45a","1f45b","1f45c","1f45d","1f6cd","1f392","1f45e","1f45f","1f460","1f461","1f462","1f451","1f452","1f3a9","1f393","26d1","1f4ff","1f484","1f48d","1f48e","1f507","1f508","1f509","1f50a","1f4e2","1f4e3","1f4ef","1f514","1f515","1f3bc","1f3b5","1f3b6","1f399","1f39a","1f39b","1f3a4","1f3a7","1f4fb","1f3b7","1f3b8","1f3b9","1f3ba","1f3bb","1f941","1f4f1","1f4f2","260e","1f4de","1f4df","1f4e0","1f50b","1f50c","1f4bb","1f5a5","1f5a8","2328","1f5b1","1f5b2","1f4bd","1f4be","1f4bf","1f4c0","1f3a5","1f39e","1f4fd","1f3ac","1f4fa","1f4f7","1f4f8","1f4f9","1f4fc","1f50d","1f56f","1f4a1","1f526","1f3ee","1f4d4","1f4d5","1f4d6","1f4d7","1f4d8","1f4d9","1f4da","1f4d3","1f4d2","1f4c3","1f4dc","1f4c4","1f4f0","1f5de","1f4d1","1f516","1f3f7","1f4b0","1f4b4","1f4b5","1f4b6","1f4b7","1f4b8","1f4b3","1f4b9","2709","1f4e7","1f4e8","1f4e9","1f4e4","1f4e5","1f4e6","1f4eb","1f4ea","1f4ec","1f4ed","1f4ee","1f5f3","270f","1f58b","1f58a","1f58c","1f58d","1f4dd","1f4bc","1f4c1","1f4c2","1f5c2","1f4c5","1f4c6","1f5d2","1f4c7","1f4c8","1f4c9","1f4ca","1f4cb","1f4cc","1f4cd","1f4ce","1f587","1f4cf","1f4d0","2702","1f5c3","1f5c4","1f5d1","1f512","1f513","1f50f","1f510","1f511","1f5dd","1f528","26cf","2692","1f6e0","1f5e1","2694","1f52b","1f3f9","1f6e1","1f527","1f529","2699","1f5dc","2696","1f517","26d3","2697","1f52c","1f52d","1f4e1","1f489","1f48a","1f6aa","1f6cf","1f6cb","1f6bd","1f6bf","1f6c1","1f6d2","1f6ac","26b0","26b1","1f5ff"],"Smileys & Emotion":["1f600","1f603","1f604","1f601","1f606","1f605","1f923","1f602","1f642","1f643","1f609","1f60a","1f607","1f60d","1f618","1f617","263a","1f61a","1f619","1f60b","1f61b","1f61c","1f61d","1f911","1f917","1f914","1f910","1f610","1f611","1f636","1f60f","1f612","1f644","1f62c","1f925","1f60c","1f614","1f62a","1f924","1f634","1f637","1f912","1f915","1f922","1f927","1f635","1f920","1f60e","1f913","1f615","1f61f","1f641","2639","1f62e","1f62f","1f632","1f633","1f626","1f627","1f628","1f630","1f625","1f622","1f62d","1f631","1f616","1f623","1f61e","1f613","1f629","1f62b","1f624","1f621","1f620","1f608","1f47f","1f480","2620","1f4a9","1f921","1f479","1f47a","1f47b","1f47d","1f47e","1f916","1f63a","1f638","1f639","1f63b","1f63c","1f63d","1f640","1f63f","1f63e","1f648","1f649","1f64a","1f48b","1f48c","1f498","1f49d","1f496","1f497","1f493","1f49e","1f495","1f49f","2763","1f494","2764","1f49b","1f49a","1f499","1f49c","1f5a4","1f4af","1f4a2","1f4a5","1f4ab","1f4a6","1f4a8","1f573","1f4a3","1f4ac","1f5e8","1f5ef","1f4ad","1f4a4"]},"emoticon_conversions":{":)":":smile:","(:":":smile:",":(":":frown:","<3":":heart:",":|":":neutral:",":/":":confused:",";)":":wink:",":D":":grinning:",":o":":open_mouth:",":O":":open_mouth:",":p":":stuck_out_tongue:",":P":":stuck_out_tongue:"}}')},"926b":function(e,t,a){"use strict";a("456a")},c251:function(e,t,a){"use strict";a("31dc")},cd41:function(e,t,a){},d3a3:function(e,t,a){"use strict";a("0a7f")},eebe:function(e,t,a){"use strict";a("3dff")},fa46:function(e,t,a){},fbf7:function(e,t,a){},ff23:function(e,t,a){"use strict";a("48f8")}}); -//# sourceMappingURL=app.080ffb9e.js.map \ No newline at end of file diff --git a/front/dist/js/app.080ffb9e.js.map b/front/dist/js/app.080ffb9e.js.map deleted file mode 100644 index 02311ab..0000000 --- a/front/dist/js/app.080ffb9e.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/components/Streams/index.vue?7f18","webpack:///./src/components/Content/index.vue?d9b0","webpack:///./src/components/Content/Chapter.vue?c76c","webpack:///./src/components/Rules/index.vue?3d5f","webpack:///./src/App.vue","webpack:///./src/api/zulip/index.js","webpack:///./src/api/index.js","webpack:///./src/components/Rules/Styles.vue","webpack:///./src/mixins/emoji.js","webpack:///./src/components/Rules/Styles.vue?9ff1","webpack:///./src/App.vue?dfb6","webpack:///./src/views/Home.vue","webpack:///./src/components/Streams/index.vue","webpack:///./src/components/Streams/Stream.vue","webpack:///./src/components/Streams/Stream.vue?bf73","webpack:///./src/components/Streams/index.vue?ec5a","webpack:///./src/components/Content/index.vue","webpack:///./src/components/Content/Chapter.vue","webpack:///./src/components/Content/Message.vue","webpack:///./src/components/Content/Message.vue?82d8","webpack:///./src/components/Content/Chapter.vue?e7a9","webpack:///./src/components/Content/index.vue?b460","webpack:///./src/components/Rules/index.vue","webpack:///./src/components/Rules/Rule.vue","webpack:///./src/components/Rules/Rule.vue?c086","webpack:///./src/components/Rules/index.vue?977c","webpack:///./src/views/Home.vue?ab8c","webpack:///./src/views/Docs.vue","webpack:///./docs/CSS.md","webpack:///./docs/Workshop.md","webpack:///./docs/Chattypub.md","webpack:///./src/views/Docs.vue?f08d","webpack:///./src/router/index.js","webpack:///./src/store/index.js","webpack:///./src/main.js","webpack:///./src/App.vue?a6ea","webpack:///./src/views/Docs.vue?40b0","webpack:///./src/components/Rules/Rule.vue?5fb1","webpack:///./src/components/Content/Message.vue?e8d6","webpack:///./src/components/Streams/Stream.vue?70d6","webpack:///./src/views/Home.vue?3cf0"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","id","class","isMobile","Component","zulip","require","config","username","process","apiKey","realm","init","Promise","resolve","reject","then","client","catch","error","getStreams","streams","retrieve","getTopics","stream","topics","stream_id","getMsgs","topic","params","messages","anchor","num_before","num_after","narrow","operator","operand","getAllMsgs","listen","cb","callOnEachEvent","event","getSubs","subscriptions","addSub","users","me","add","JSON","stringify","sendMsg","send","to","type","content","emoji_regex","methods","toEmojiCode","emoji","replace","codePointAt","toString","shortcodeToEmoji","code","indexOf","k","replaceAll","trim","zulip_emoji","name_to_codepoint","console","log","parseInt","String","fromCodePoint","containsEmoji","str","regexExp","test","mixins","computed","el","generateStyleRules","styles","this","rules","map","family","src","format","className","startsWith","parentClassName","createStyleElement","style","document","createElement","innerText","mounted","head","appendChild","watch","newStyle","replaceChild","render","components","Styles","api","zulipClient","created","$store","commit","checkIfMobile","addEventListener","$router","beforeEach","afterEach","from","path","currentStream","find","setUpDoc","innerWidth","filter","pubStr","eventHandler","includes","message","subject","message_id","mid","rendered_content","op","reaction","emoji_code","emoji_name","reaction_type","for","href","classes","show_ui","toggle_ui","resizer","size","panel_sizes","min-size","print","show_message_data","expand_content","ref","selected","props","state","__scopeId","Stream","title","sortedTopics","toValidID","goTo","messagesToShow","sender_full_name","time","source","$mdOpts","reactions","EmojiConvertor","emojiConv","rawJSON","url","referrers","responseTo","sender_id","quote","forEach","join","replace_colons","ts","timestamp","ts_ms","date_ob","Date","toLocaleString","Message","Chapter","string","encodeURIComponent","toLowerCase","querySelector","scrollIntoView","behavior","rule","contentFiltered","font","dec","reg","Rule","Streams","Content","Rules","Splitpanes","Pane","setup","preview","0","1","2","panels","prev","setTimeout","print_preview","getElementById","paged","flow","total","evt","undefined","$forceUpdate","files","file","$route","slug","html","Workshop","Chattypub","CSS","hash","getFileName","includeExtension","matches","match","handleLinks","Array","querySelectorAll","a","e","pathname","preventDefault","scroll","top","createRouter","history","createWebHistory","routes","component","Home","Docs","toCSS","stripHtml","is_codeblock","is_font","regex","results","matchAll","re_path","exec","split","validateRule","filename","getFilename","ext","pop","getFormat","fmt","handleMDReply","handleHTMLReply","table","createStore","strict","mutations","setMobile","mobile","setStreams","setCurStream","setTopics","addMessage","display_recipient","deleteMessage","addReaction","flat","removeReaction","setRules","reduce","acc","cur","addRule","editMessage","newRules","updateTopic","orig_subject","actions","getters","sort","b","localeCompare","app","createApp","App","mdOpts","linkify","typographer","globalProperties","$http","Axios","$md","MarkdownIt","use","VueMarkdownIt","router","store","mount"],"mappings":"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","file":"js/app.080ffb9e.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"app\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([0,\"chunk-vendors\"]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./index.vue?vue&type=style&index=0&id=4514be34&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./index.vue?vue&type=style&index=0&id=37f18a26&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Chapter.vue?vue&type=style&index=0&id=30f46307&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./index.vue?vue&type=style&index=0&id=16b43aee&scoped=true&lang=css\"","\n\n\n\n\n","const \n\n zulip = require(\"zulip-js\"),\n config = {\n username: process.env.VUE_APP_ZULIP_email,\n apiKey: process.env.VUE_APP_ZULIP_key,\n realm: process.env.VUE_APP_ZULIP_site,\n },\n \n init = () => ( new \n Promise((resolve, reject) => {\n zulip(config)\n .then(client => resolve(client))\n .catch(error => reject(error))\n })\n ),\n \n getStreams = client => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .retrieve()\n .then(result => resolve(result.streams))\n .catch(error => reject(error))\n })\n ),\n \n getTopics = (client, stream) => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .topics\n .retrieve({ stream_id: stream })\n .then(result => resolve(result.topics))\n .catch(error => reject(error))\n })\n ),\n \n getMsgs = (client, stream, topic, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .retrieve(params || {\n anchor: \"newest\",\n num_before: 1000,\n num_after: 0,\n // apply_markdown: false,\n narrow: [\n { operator: \"stream\", operand: stream },\n { operator: \"topic\", operand: topic },\n ],\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n getAllMsgs = (client, stream, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .retrieve(params || {\n anchor: \"newest\",\n num_before: 1000,\n num_after: 0,\n // apply_markdown: false,\n narrow: [{ operator: \"stream\", operand: stream }],\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n listen = (client, cb) => {\n client\n .callOnEachEvent(\n event => cb(event), \n [ 'message' ],\n [ { operator: \"stream\", operand: \"chatty\" } ]\n )\n },\n \n getSubs = client => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .subscriptions\n .retrieve()\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n addSub = (client, stream) => ( new\n Promise((resolve, reject) => {\n client\n .users\n .me\n .subscriptions\n .add(\n {\n subscriptions: JSON.stringify([{ name: stream }]),\n }\n )\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n sendMsg = (client, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .send(params || {\n to: \"chatty\",\n type: \"stream\",\n topic: \"content\",\n content: \"I come not, friends, to steal away your hearts.\",\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n )\n\nexport default {\n init,\n config,\n getStreams,\n getTopics,\n getMsgs,\n getAllMsgs,\n listen,\n sendMsg,\n getSubs,\n addSub,\n}\n","import zulip from './zulip'\n\nexport default {\n zulip\n}\n","\n\n","// let toUTF16 = (codePoint) => {\n// var TEN_BITS = parseInt(\"1111111111\", 2);\n// if (codePoint <= 0xffff) {\n// return u(codePoint);\n// }\n// codePoint -= 0x10000;\n// // Shift right to get to most significant 10 bits\n// var leadSurrogate = 0xd800 + (codePoint >> 10);\n// // Mask to get least significant 10 bits\n// var tailSurrogate = 0xdc00 + (codePoint & TEN_BITS);\n// return u(leadSurrogate) + (tailSurrogate);\n// }\n\n// let u = (codeUnit) => {\n// return \"\\\\u\" + codeUnit.toString(16).toUpperCase();\n// }\nimport zulip_emoji from \"../data/emoji_codes.json\";\n\nexport default {\n data() {\n return {\n emoji_regex: /(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*/gi\n }\n },\n\n methods: {\n toEmojiCode: (emoji) => {\n return emoji.replace(/\\p{Emoji}/gu, (m) => m.codePointAt(0).toString(16));\n },\n\n shortcodeToEmoji: (code) => {\n if (code.indexOf(\":\") !== 0) return code;\n let k = code.replaceAll(\":\", '').trim();\n let emoji = zulip_emoji.name_to_codepoint[k];\n console.log(k, emoji, parseInt(emoji,16), String.fromCodePoint(parseInt(\"0x\"+emoji)))\n return String.fromCodePoint(parseInt(\"0x\"+emoji))\n },\n \n // toEmojiCode: (emoji) => {\n // emoji.replace(/\\p{Emoji}/gu, function (m) {\n // toUTF16(m.codePointAt(0));\n // });\n // return emoji;\n // },\n\n containsEmoji(str) {\n // Regular expression to match emoji\n const regexExp = /(\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff])/gi;\n return regexExp.test(str); // true\n },\n }\n}","import { render } from \"./Styles.vue?vue&type=template&id=7b4da880\"\nimport script from \"./Styles.vue?vue&type=script&lang=js\"\nexport * from \"./Styles.vue?vue&type=script&lang=js\"\nscript.render = render\n\nexport default script","import { render } from \"./App.vue?vue&type=template&id=6d28ae45\"\nimport script from \"./App.vue?vue&type=script&lang=js\"\nexport * from \"./App.vue?vue&type=script&lang=js\"\n\nimport \"./App.vue?vue&type=style&index=0&id=6d28ae45&lang=css\"\nscript.render = render\n\nexport default script","\n\n\n\n","\n\n\n\n","\n\n\n\n","import { render } from \"./Stream.vue?vue&type=template&id=1af39708&scoped=true\"\nimport script from \"./Stream.vue?vue&type=script&lang=js\"\nexport * from \"./Stream.vue?vue&type=script&lang=js\"\n\nimport \"./Stream.vue?vue&type=style&index=0&id=1af39708&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-1af39708\"\n\nexport default script","import { render } from \"./index.vue?vue&type=template&id=4514be34&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=4514be34&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-4514be34\"\n\nexport default script","\n\n\n\n","\n\n\n\n","\n\n\n\n","import { render } from \"./Message.vue?vue&type=template&id=e48b70e8\"\nimport script from \"./Message.vue?vue&type=script&lang=js\"\nexport * from \"./Message.vue?vue&type=script&lang=js\"\n\nimport \"./Message.vue?vue&type=style&index=0&id=e48b70e8&lang=css\"\nscript.render = render\n\nexport default script","import { render } from \"./Chapter.vue?vue&type=template&id=30f46307&scoped=true\"\nimport script from \"./Chapter.vue?vue&type=script&lang=js\"\nexport * from \"./Chapter.vue?vue&type=script&lang=js\"\n\nimport \"./Chapter.vue?vue&type=style&index=0&id=30f46307&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-30f46307\"\n\nexport default script","import { render } from \"./index.vue?vue&type=template&id=37f18a26&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=37f18a26&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-37f18a26\"\n\nexport default script","\n\n\n\n","\n\n\n\n","import { render } from \"./Rule.vue?vue&type=template&id=080e408c&scoped=true\"\nimport script from \"./Rule.vue?vue&type=script&lang=js\"\nexport * from \"./Rule.vue?vue&type=script&lang=js\"\n\nimport \"./Rule.vue?vue&type=style&index=0&id=080e408c&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-080e408c\"\n\nexport default script","import { render } from \"./index.vue?vue&type=template&id=16b43aee&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=16b43aee&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-16b43aee\"\n\nexport default script","import { render } from \"./Home.vue?vue&type=template&id=39e10b20\"\nimport script from \"./Home.vue?vue&type=script&lang=js\"\nexport * from \"./Home.vue?vue&type=script&lang=js\"\n\nimport \"./Home.vue?vue&type=style&index=0&id=39e10b20&lang=css\"\nscript.render = render\n\nexport default script","/* eslint-disable */\n\n\n\n\n\n","export default \"# CSS\\n\\nIn this document we take a look at what CSS is and how it can be applied to a publication in ChattyPub.\\n\\n- [What is CSS](#what-is-css)\\n- [Rules](#rules)\\n- [Css in ChattyPub](#css-in-chattypub)\\n - [About formatting](#about-formatting)\\n - [Advanced CSS](#advanced-css)\\n- [Uploading fonts](#uploading-fonts)\\n- [Print settings](#print-settings)\\n - [Page breaks](#page-breaks)\\n- [Common CSS properties](#properties)\\n - [Backgrounds and borders](#backgrounds)\\n - [Color](#color)\\n - [Box model](#box-model)\\n - [Fonts](#fonts)\\n - [Text](#text)\\n - [Transforms](#transforms)\\n\\n---\\n\\n## What is CSS?\\n\\nCSS (Cascading Style Sheets) is the language that allows you to style and layout HTML web pages. This article explains what CSS is, with some simple syntax examples, and also covers some key terms about the language.\\n\\nSince this document relates specifically to ChattyPub, the focus is going to be on the parts of the language that are supported by this platform. Because CSS is specifically oriented towards styling HTML (and related languages like SVG and XML) you have to have a basic understanding of HTML.[1](#footnote1) Mozilla has an excellent [HTML introduction](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started).\\n\\nAt its heart, HTML is a fairly simple language made up of elements, which can be applied to pieces of text to give them different meaning in a document (Is it a paragraph? Is it a bulleted list? Is it part of a table?), structure a document into logical sections (Does it have a header? Three columns of content? A navigation menu?), and embed content such as images and videos into a page.\\nBut what HTML does not do is speficy how these elements should look. That is where CSS comes in.\\n\\nCSS can be used for very basic document text styling — for example changing the color and size of headings and links. It can be used to create layout — for example turning a single column of text into a layout with a main content area and a sidebar for related information. It can even be used for effects such as animation.\\nIn ChattyPub we're mostly interested in the first part.\\n\\n---\\n\\n## Rules\\n\\n#### _Elements and Classes_\\n\\nIn this section we will talk about CSS in general. ChattyPub uses a slight variation on it, but let's start with the basics.\\n\\nCSS is a rule-based language — you define rules specifying groups of styles that should be applied to particular elements or groups of elements on your web page. For example \\\"I want the main heading on my page to be shown as large red text.\\\"\\n\\nThe following code shows a very simple CSS rule that would achieve the styling described above:\\n\\n```css\\nh1 {\\n color: red;\\n font-size: 20px;\\n}\\n```\\n\\nThe rule opens with a selector. This selects the HTML element that we are going to style. In this case we are styling all level one headings (`

    `) that appear on the page.\\n\\nWe then have a set of curly braces `{` `}`. Inside those will be one or more declarations, which take the form of property and value pairs. Each pair specifies a property of the element(s) we are selecting, then a value that we'd like to give the property. Each pair is followed by a semi-colon `;` to indicate the end of the property.\\n\\nBefore the colon, we have the property, and after the colon, the value. CSS properties have different allowable values, depending on which property is being specified. In our example, we have the color property, which can take various color values. We also have the font-size property. This property can take various size units as a value.\\n\\nThe example above will style all the `H1` elements on the page. You could also write a selector for all paragraphs (the selector would be `p`), images (`img`) or list items (`li`). This works as long as you want all of the elements of that type in your document to look the same. Most of the time that isn't the case and so you will need to find a way to select a subset of the elements without changing the others. The most common way to do this is to add a class to your HTML element and target that class.\\n\\nTake this HTML:\\n\\n```html\\n
      \\n
    • Item one
    • \\n
    • Item two
    • \\n
    • Item three
    • \\n
    \\n```\\n\\nTo target the class of special you can create a selector that starts with a full stop character.\\n\\n```css\\n.special {\\n color: orange;\\n font-weight: bold;\\n}\\n```\\n\\nThe peroid character in front of special tells the browser that we're creating a class selector.\\nYou can apply the class of special to any element on your page that you want to have the same look as this list item.\\n\\n### Units\\n\\nIn the `h1` example above, we set the following property: `font-size: 20px;`. This will set the font-size of all H1 headers to 20 pixels. But pixels are not the only units available. Some examples:\\n\\n- `em` and `rem` - these relative units declare a size dependant on the font-size of the context they get used in. This can be a bit confusing if you're not used to it. Feel free to replace it with on of the values below.\\n- `px` - Pixels.\\n- `cm` and `in` - centimeters and inches. These units are mostly relevant in print context.\\n- `vw` and `vh` - so called viewport units, 100vw is exactly the height of the viewport (the part of the browser that shows the webpage). `vh` is the same, but for the height of the browser.\\n- `rgba(r,g,b,a)` strictly speaking not a unit but a function, but it sets the color and transparency of the foreground.\\n\\n[More information on units](https://www.w3.org/Style/Examples/007/units.en.html).\\n\\n---\\n\\n## CSS in ChattyPub\\n\\nWhen you react to a message in Zulip with an emoji, this emoji gets turned into a class in ChattyPub. So lets say you responded to a message with the strawberry 🍓 emoji. In ChattyPub the message will have class with that emoji as selector. (You can confirm this by rolling over the message, the emoji should popup on a overlay.) So now to style that message, you go to the `#rules` channel and add a message with the following content:\\n\\n```css\\n🍓 {\\n color: red;\\n}\\n```\\n\\nIt is very similar to the examples above. `🍓` is the selector, so the rule will apply to each message with a strawberry reaction. Then follows the block `{` and `}`. And in the block, there is property, `color: red;`.\\n\\n_A small difference with regular CSS is that you don't need to add the period in front of the selector ChattyPub will handle that for you._\\n\\nBecause of the way Zulip handles the emoji reactions, not all emoji are available or sometimes they don't exactly correspond to the emoji you might type in the `#rules` channel. To help with sorting this out you can roll over a message in ChattyPub and see the reactions that are applied. Sometimes the translation is unavailable, in that case you'll see something like `:working_on_it:` instead of the emoji you expected. In that case remove your reaction and find an other emoji that does work.\\n\\n### About formatting\\n\\nYou can't enter a tab character in Zulip and the indentation before the property in the rule isn't absolutely necessary. So feel free to leave it out. If you absolutely want to have the indentation, you could write the rule in your favorite editor and copy and paste it into Zulip. If you only want to style a single property you could have the whole rule on a single line like this: `🌕 { box-shadow: 0 0 20px rgba(255,0,0,0.5); }`,\\n\\n_Don't forget the semi-colon at the end of the property line!_\\n\\n### Advanced CSS\\n\\n**Selecting HTML elements and other style rules**\\n\\nThe reaction/emoji method described above allows to make quick modifications to the style and layout of your publication. But besides this ChattyPub also allows you to style html elements like in regular CSS. To do this just enter your style rule. This snippet will give all HTML links a pink background color:\\n\\n```css\\na {\\n background-color: pink;\\n}\\n```\\n\\nYou should be able to enter all regular CSS rules this way.\\n\\n**Bypassing the parser** -_Work in progress_-\\n\\nIt is possible to bypass the parser and add arbitrary code to the CSS on the page. This allows you to add, for example, `@keyframes` for an animation or media queries. To do this send any message to the `#rules` channel and wrap the message in three backticks like this:\\n\\n~~~~\\n```\\n@keyframes example {\\n from {background-color: red;}\\n to {background-color: yellow;}\\n}\\n```\\n~~~~\\n\\n---\\n\\n## Uploading fonts\\n\\nIt is also possible to upload a custom font to the application. To do this, you send the font in a message to the #rules channel of the publication you want to use it in. You can use `.ttf`, `.otf` or `.woff` formats depending on the browser you are using. The mesage must only contain the font, no other text. ChattyPub will then automatically generate a @font-face rule for the font. The font-family name will be based on the filename.\\n\\nOnce uploaded the font should show up in the CSS rules section of ChattyPub. To use the font in a style rule, just copy/paste the `font-family: \\\"font_name_ttf\\\";` and add it to a rule in the #rules channel.\\n\\n> Please only upload free or open-source fonts to our server!\\n\\n## Print settings\\n\\nTo set the paper size we can use the special selector `@page`. The following snippet set the page size to A5.\\n\\n```css\\n@page {\\n size: 148mm 210mm;\\n}\\n```\\n\\nThis example sets the page to landscape.\\n\\n```css\\n@page {\\n size: landscape;\\n}\\n```\\n\\nRegrettably [browser support](https://caniuse.com/css-paged-media) for `@page` is spotty. Currently only MS Edge, Opera and Google Chrome will allow you to set page sizes etc, and even then it is a matter of trial and error.\\n\\nThe [Paged media module](https://developer.mozilla.org/en-US/docs/Web/CSS/Paged_Media) at Mozilla has an excellent explanation on using `@page`.\\n\\n### page breaks\\n\\nBy default pages will automatically wrap to the next page. And ChattyPub adds a page break after each topic. If you want to force a page break you could write a rule for it, using the `page-break-after: always;` property:\\n\\n```css\\n🍏 {\\n page-break-after: always;\\n}\\n```\\n\\nIf you don't want the page break after an article you can overwrite the default by using:\\n\\n```css\\n.body {\\n page-break-after: avoid;\\n}\\n```\\n\\nFor some of these rules it may be necessary to use the methods described under [Advanced CSS](#advanced-css) above to enter these rules.\\n\\n##
    List of common and handy CSS properties\\n\\nThere are hundreds of CSS properties. Below is a small selection of some basic properties mostly focussed on layout and type representation, grouped by module.\\n\\n### Backgrounds and borders\\n\\n- [background-color](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color)\\n- [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) - The border CSS property sets an element's border.\\n- [border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius) - The border-radius CSS property rounds the corners of an element's outer border edge.\\n- [box-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow) - The box-shadow CSS property adds shadow effects around an element's frame.\\n\\n### Color\\n\\n- [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) - The color CSS property sets the foreground color value of an element's text and text decorations.\\n- [opacity](https://developer.mozilla.org/en-US/docs/Web/CSS/opacity) - The opacity CSS property sets the opacity of an element. Opacity is the degree to which content behind an element is hidden, and is the opposite of transparency.\\n\\nA colors value can defined in multiple ways:\\n\\n- By [name/keyword](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#keywords) - `color: red;` will make your text red.\\n- By [hex value](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#hex) - `color: #ff0000;` also red.\\n- Or as a [function](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#rgba), which allows transparency. - `color: rgba(255,0,0,0.5);` red, but 50% transparent.\\n\\n### Box model\\n\\n- [margin](https://developer.mozilla.org/en-US/docs/Web/CSS/margin) - The margin property sets the margin area on all four sides of an element. Margin refers to space between different elements.\\n- [padding](https://developer.mozilla.org/en-US/docs/Web/CSS/padding) - The padding property sets the padding area on all four sides of an element at once. Padding refers to the spacing inside the border of an element.\\n\\n### Fonts\\n\\n- [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) - The font-family CSS property specifies a prioritized list of one or more font family names and/or generic family names for the selected element.\\n\\nYou can choose one of the following generic fonts. Which exact font will be used is dependant on your computers' settings.\\n\\n```css\\nfont-family: serif;\\nfont-family: sans-serif;\\nfont-family: monospace;\\nfont-family: cursive;\\nfont-family: fantasy;\\n```\\n\\nIt is also possible to specify an exact font name, but it will only be used if it is actually available on your system.\\nFor example following statement will try to use Helvetica if available, but will fallback on a generic sans-serif font if not. (Note the quotes around the font name).\\n\\n```css\\nfont-family: \\\"Helvetica Neue\\\", sans-serif;\\n```\\n\\nAlso see the section on uploading fonts below.\\n\\n- [font-size](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size) - The font-size CSS property sets the size of the font. Changing the font size also updates the sizes of the font size-relative units, such as em, ex, and so forth.\\n- [font-style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style) - The font-style CSS property sets whether a font should be styled with a normal, italic, or oblique face from its font-family.\\n- [font-weigh](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) - The font-weight CSS property sets the weight (or boldness) of the font. The weights available depend on the font-family that is currently set.\\n- [line-height](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height) - The line-height CSS property sets the height of a line box. It's commonly used to set the distance between lines of text.\\n\\n### Text\\n\\n- [letter-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/letter-spacing) - The letter-spacing CSS property sets the horizontal spacing behavior between text characters.\\n- [text-align](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) - The text-align CSS property sets the horizontal alignment of the content inside a block element.\\n- [text-transform](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) - The text-transform CSS property specifies how to capitalize an element's text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.\\n- [white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) - The white-space CSS property sets how white space inside an element is handled.\\n- [word-break](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break) - The word-break CSS property sets whether line breaks appear wherever the text would otherwise overflow its content box.\\n- [word-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/word-spacing) - The word-spacing CSS property sets the length of space between words and between tags.\\n- [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) - The text-shadow CSS property adds shadows to text.\\n\\n### Transforms\\n\\n- [rotate](https://developer.mozilla.org/en-US/docs/Web/CSS/rotate) - The rotate CSS property allows you to specify rotation of elements\\n- [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/scale) - The scale CSS property allows you to specify the scale (size) of elements\\n- [translate](https://developer.mozilla.org/en-US/docs/Web/CSS/translate) - The translate CSS property allows you to specify translation transforms (position relative to where it originally was) of elements.\\n\\n1: I've borrowed shamelessly from Mozilla to make this text: https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps/What_is_CSS and https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML\\n\";","export default \"# ChattyPub Workshop Script\\n\\n## Introduction\\n\\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication.\\n\\nThe workshop will explore in a practical manner how the process of co-designing a publication can unfold, specifically when several people are working at the same time using a chat interface as the main design tool. During HDSA2021 we would like to open up the process of making this tool and explore together its possibilities and limitations. The workshop will take place towards the end of the one-week summer academy program. Thus, we will be able to use some of the documentation produced during the week — workshops scripts, prototypes, game cards, recipes, ... as well as conversations we will have on different platforms – synchronously and asynchronously.\\n\\nCommands allow you to style the texts and images, but someone else can change their appearance again later! How will we negotiate these design decisions synchronously and asynchronously? The outcome could be a zine, posters or a webpage.\\n\\nThis script aims to provide the necessary instructions to host a workshop around ChattyPub that can accomodate different skills and knowledges in different contexts.\\n\\n## Goals\\n\\n- Learn to collaboratively write, design, and print documents using ChattyPub\\n- Produce publications of / relating to HDSA2021 (documentation, prototypes, conversations, etc...)\\n- Learn and/or practice styling with CSS & Emojis\\n\\n## Requirements\\n\\n- a computer, web-browser, and connection to the internet\\n- an account for the Hackers & Designers Zulip instance: https://chat.hackersanddesigners.nl/\\n- a printer\\n\\n## Preparation\\n\\nBefore the summer academy: Most important is for all workshop participants to set up a Zulip account on our server. The H&D zulip instance can be found at https://chat.hackersanddesigners.nl/ (public sign ups are temporariy open).\\n\\nOn the first day of the summer academy (monday): Participants are introduced to the Zulip interface and instructed to use it for communication during the course of the week. Zulip makes use of a rather unconventional (but powerful) chat-threading logic, so it would be good to spend some time interacting with it and settle into this new environment.\\n\\nWorkshop hosts and participants are encouraged to think about how they would like to document their processes during the summer academy. What is included and what isn't? How is this shared? Is there a regular moment during the day dedicated to documentation or is it more ad-hoc? We suggest using Etherpad for collaborative note taking, and regularly making screenshots or screenrecordings and photos. We have previously compiled a so-called \\\"tool-ecology\\\", a list of tools we have good experiences with and recommend using during the summer academy: https://etherpad.hackersanddesigners.nl/p/hdsa2021-tool-ecology.\\n\\nTexts, notes, chats, images, and screenshots will make great material for our workshop.\\n\\n## How It Works\\n\\nFor an overview of how ChattyPub works with Zulip, go [here](/docs/Chattypub).\\n## Workshop\\n\\nThe workshop is split over two sessions (over two days) of 4 hours each.\\n\\n_Opening Session: Introductions & first encounters with ChattyPub_\\n\\n- Introductory presentation ( 1hr ) -- will be livestreamed in the morning / recorded and shared afterwards.\\n - Context and background on H&D's publishing activities (Anja & Juliette)\\n - Introduction to ChattyPub (Karl).\\n - Introduction to CSS (Heerko).\\n - How it all comes together (emojis ;])(Karl)\\n- Experimenting with ChattyPub! ( 2 hrs )\\n - participants with different levels of experience of CSS are grouped together\\n - each group follows [these instructions](/docs/Chattypub#content) to make one publication in ChattyPub\\n - detailed instructions about CSS can be found [here](/docs/CSS)\\n- Brainstorm Session (1 hr)\\n - in groups of 2-3, participants brainstorm publications they will make during the main session \\n - The goal is to document together, in print, parts of the summer academy.\\n - What have you been up to this last week?\\n - What did you make? What material did you collect / produce?\\n - How will you negotiate this design process?\\n - Are roles divided and then switched? \\n - If you are planning to print your publication, take into account the printing limitations of your home printer or local print shop.\\n - Print settings such as the page size and orientation can all be configure with CSS.\\n - If participants are joining remotely, it's good that they are paired together.\\n\\n_Main Session: Chat => Print_\\n\\n- Making publications ( 2 hrs )\\n - Groups work on the publications planned in the previous session \\n - Each group makes a stream on Zulip for the publiction\\n - They create chapters for their contents\\n - They create a \\\"rules\\\" topic for their styles\\n - Organizers are available to help where needed\\n - At least one or two people per node should be able to help with CSS.\\n - Karl and Heerko will be available if bugs / errors occur.\\n- Printing Publications ( 1 hr )\\n - A printer is required in the space (or easily accessible)\\n - Accommodating for different paper sizes is an added bonus\\n - Binding could be fun too\\n- Sharing outcomes and reflections ( 1 hr ) \\n - Round of publications\\n - Reflection on process\\n - Feedback on ChattyPub\\n\";","export default \"# ChattyPub\\n\\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication. ChattyPub is a collaborative publication/zine-making tool built on top of the chat platform [Zulip](https://chat.hackersanddesigners.nl). By sending messages, reacting with emoji and writing simple CSS style rules the publication can be collectively designed.\\n\\n- [Zulip](#zulip)\\n- [ChattyPub](#using-chattypub)\\n- [Making a publication with Zulip & ChattyPub](#content)\\n - [Content](#content)\\n - [Rules](#rules)\\n - [Printing](#printing)\\n- [Typing Emoji](#typing-emoji)\\n- [Problems?](#problems)\\n\\n## Zulip\\n\\nOn Zulip, conversations are categorized into different \\\"Streams\\\", which are comparable to \\\"channels\\\" in other messaging services like Discord. Streams can be public or private and host conversations consisting of text, images, files, reactions, etc..\\n\\nWhat differentiates Zulip from most messaging platforms is the way streams are sub-threaded. Zulip introduces the concept of \\\"Topics\\\", which, in the plainest terms, means that messages have subjects. When sending a message to a stream in Zulip, you can also specify the topic of the message and the stream automatically filters messages by their shared topics. If your message's topic doesn't exist yet, it will be created when you send your message.\\n\\nZulip allows you to react to messages using emoji's as well. We will make heavy use of emojis in ChattyPub.\\n\\nThere are several ways to engage with Zulip, including a web-client, a desktop app, and a mobile app.\\n\\n## Using ChattyPub\\n\\nhttp://chatty-pub.hackersanddesigners.nl\\n\\nChattyPub is a website that acts as a different interface to the same Zulip service. ChattyPub takes a stream from Zulip, combines messages into long-form articles and uses a design system combining Emojis and CSS syntax to style the messages, effectively turning the stream into a (printable!) webpage.\\n\\n## Making a publication with Zulip & ChattyPub\\n\\n### Content\\n\\n1. Create a stream on Zulip\\n - Ensure that either (1) the stream name starts with `pub-` or (2) the stream includes a topic called \\\"rules\\\" (more on that later).\\n - Ensure that the stream is public.\\n2. Go to [ChattyPub](https://chatty-pub.hackersanddesigners.nl). The stream you created will be visible on the left-side navigation.\\n3. Click on your stream.\\n4. The main (middle) section of the website will have:\\n 1. Your stream name (which will be the name of your publication)\\n 2. The topics of your stream organized into a table of contents (which will act as \\\"Chapters\\\" in your publication)\\n 3. The topics, in alphabetical order, displaying their messages, in chronological order.\\n5. To create a new topic (chapter), return to Zulip and type a message to your stream, making sure to send it to the topic you want to create.\\n\\n### Rules\\n\\nThe right-hand side of the ChattyPub interface is reserved for one topic in your stream: \\\"rules\\\". This topic will house definitions for styles you want to apply to messages in your stream.\\n\\nGo back to Zulip and create the topic in your stream called \\\"rules\\\".\\n\\nEvery message you send to this topic should consist of a single emoji followed by a set of styles you'd like applied to messages. For example:\\n\\n```CSS\\n🍓 {\\n color: red;\\n text-decoration: underline;\\n}\\n```\\n\\nThese messages should be unique and follow the CSS syntax, as described in the [introduction to CSS](/docs/CSS). If you are comfortable with CSS, you can skip to the part of the document that describes [how CSS is used in ChattyPub](/docs/CSS#css-in-chattypub).\\n\\nTo apply these styles to the contents of your publication, head back to any other topic in your stream, select a message you'd like to style, and react to it with the emoji whose styles you want to apply. On ChattyPub, the message should be rendered with these styles.\\n\\nIf you'd like to style only a part of a message, select the message in Zulip and quote and respond to it (in the 3-dot menu). This will produce a text in your input box on the bottom of the interface. Delete the parts of the quoted message that you don't want the styles applied to, and send your response. When you react with an emoji to your own response, the part of the original message you quoted will inherit the styles defined for that emoji.\\n\\nKeep in mind that you can edit your own messages! So if you make a mistake (forgetting the semi-colon at the end of a statement is a common one), roll over your message and click the little pen at the top righthand side of the message.\\n\\n### Printing\\n\\n> Regrettably support for setting page size, page breaks etc. using [@page](https://caniuse.com/css-paged-media) is very poor in some browsers. Use MS Edge, Opera or Google Chrome for best results when printing or creating PDFs.\\n\\nTo print, click on the print button on the left side of the application. This will hide the interface, make all content visible and open the browsers' Printing dialog box.\\n\\nIf you want to use background colors or background images in your publication you may have to turn that on in the print settings dialog.\\n\\nThere is more information on setting up pages sizes etc, in the CSS document.\\n\\n## Typing Emoji\\n\\n- [Windows](https://support.microsoft.com/en-us/windows/windows-10-keyboard-tips-and-tricks-588e0b72-0fff-6d3f-aeee-6e5116097942)\\n- [Mac](https://www.howtogeek.com/684025/how-to-type-emoji-on-your-mac-with-a-keyboard-shortcut/)\\n- Linux varies per distribution. If you run Linux you're probably capable of finding out how :)\\n\\n## Problems\\n\\nChattyPub is very young and you're sure to run into problems. Feel free to contact `@Karl Moubarak`, `@andré` or `@heerko` at https://chat.hackersanddesigners.nl/\\n\\nBelow are some things that we know of, and are working on:\\n\\n- :emoji: not working...\\n\";","import { render } from \"./Docs.vue?vue&type=template&id=32f02ba2&scoped=true\"\nimport script from \"./Docs.vue?vue&type=script&lang=js\"\nexport * from \"./Docs.vue?vue&type=script&lang=js\"\n\nimport \"./Docs.vue?vue&type=style&index=0&id=32f02ba2&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-32f02ba2\"\n\nexport default script","import { createRouter, createWebHistory } from 'vue-router'\n\nimport Home from '../views/Home'\nimport Docs from '../views/Docs.vue'\n\nconst path = '/' \n\nexport default createRouter({\n history: createWebHistory(path),\n routes: [\n {\n path: '/',\n name: 'Home',\n component: Home,\n },\n {\n path: '/docs',\n name: 'Docs',\n component: Docs,\n },\n {\n path: '/docs/:slug',\n name: 'Doc',\n props: true,\n component: Docs,\n },\n {\n path: '/:pathMatch(.*)*',\n name: 'Home',\n component: Home,\n },\n ],\n})\n\n\n","/*eslint no-unused-vars: \"off\"*/\n/*eslint no-undef: \"off\"*/\n\n// import Vue from 'vue'\nimport { createStore } from 'vuex'\nimport emoji from \"../mixins/emoji\"\nimport { stripHtml } from \"string-strip-html\"\n\n/* \n\nTODO: fix this frankenfunction. Its not pretty but it works, so I am leaving it for now. \n\n\n*/\nlet toCSS = (message, currentStream) => {\n let content = stripHtml(message.content).result;\n let className = \"\",\n emoji_code = \"\",\n rules = [],\n parentClassName = (currentStream || \"\").replace(\" \", \"-\"),\n id = message.id,\n is_codeblock = message.content.includes(\"\") || message.content.startsWith(\"```\"),\n is_font = /

    .+)\\s*\\n?{\\n?(?(.*;\\n?)+)}/gm\n let results = content.matchAll(regex);\n results = Array.from(results);\n\n if (is_font) { // font\n let re_path = /\\/user_uploads(\\/.*?\\.(?:ttf|otf|woff))/gm;\n content = re_path.exec(message.content)[1];\n return { className: '', emoji_code: '', rules: [], parentClassName: '', id: id, content: font(content), type: type }\n } else if (is_codeblock) {\n return { className: '', emoji_code: '', rules: [], parentClassName: '', id: id, content: content, type: type }\n } else if (results.length > 0) { // rule and raw\n className = emoji.methods.shortcodeToEmoji(results[0]['groups']['selector']);\n if (emoji.methods.containsEmoji(className)) {\n emoji_code = emoji.methods.toEmojiCode(className);\n }\n rules = results[0]['groups']['props'].split(\"\\n\");\n rules = rules.filter((rule) => validateRule(rule))\n return { className, emoji_code, rules, parentClassName, id, content, type };\n }\n console.log(\"rejected rule\", message)\n return null;\n}\n\nlet font = (content) => {\n let font = {\n family: \"\",\n src: \"\",\n format: \"\",\n };\n let path = content;\n let filename = getFilename(path);\n let ext = filename.split(\".\").pop();\n font.src =\n \"https://chatty-pub-files.hackersanddesigners.nl/files\" + path;\n font.format = getFormat(ext);\n font.family = filename.replace(\".\", \"_\");\n return font;\n}\n\nlet getFilename = (str) => {\n return str.split(\"\\\\\").pop().split(\"/\").pop();\n}\n\nlet getFormat = (ext) => {\n let fmt = \"truetype\";\n switch (ext) {\n case 'woff':\n fmt = \"woff\";\n break;\n case 'eof':\n fmt = \"embedded-opentype\";\n break;\n }\n return fmt;\n}\n\nlet validateRule = (rule) => {\n return rule.match(/.+:.+;/gm);\n}\n\n// parsing replies, there are two scenarios:\n// we are either getting the message as plain markdown\n// or we are getting the message pre-rendered as HTML (default Zulip behaviour)\n// see /src/api/zulip/index.js line 36\n\nconst handleMDReply = message => {\n message.responseTo = {\n id: message.content\n .replace(/.*\\/near\\//gm, '')\n .replace(/\\):.*[^]+/gm, ''),\n sender_id: message.content\n .replace(/@_\\*\\*.*\\|/gm, '')\n .replace(/\\*\\*.\\[said\\].*[^]+/gm, ''),\n quote: message.content\n .replace(/[^]+.*```quote\\n/gm, '')\n .replace(/ \\n```/gm, '')\n }\n // console.log(message.responseTo)\n}\n\nconst handleHTMLReply = message => {\n message.responseTo = {\n id: message.content\n .replace(/.*\\/near\\//gm, '')\n .replace(/\".*[^]+/gm, ''),\n sender_id: message.content\n .replace(/[^]+data-user-id=\"/gm, '')\n .replace(/\">[^]+/gm, ''),\n quote: message.content\n .replace(/.*[^]+<\\/p>\\n

    \\n

    /gm, '')\n .replace(/<\\/p>\\n<\\/blockquote>/gm, '')\n // .replace(/\\n/gm, '')\n }\n console.table(message.responseTo)\n}\n\nexport default createStore({\n\n strict: process.env.NODE_ENV !== 'production',\n\n state: {\n isMobile: false,\n streams: [],\n currentStream: '',\n rules: [],\n topics: [],\n pubStr: 'pub-',\n },\n\n mutations: {\n\n setMobile: (state, mobile) => state.isMobile = mobile,\n setStreams: (state, streams) => state.streams = streams,\n setCurStream: (state, stream) => state.currentStream = stream,\n setTopics: (state, topics) => state.topics = topics,\n addMessage: (state, message) => {\n if (message.display_recipient == state.currentStream) {\n if (message.content.startsWith('@_**')) {\n handleMDReply(message)\n } else if (\n message.content.includes('user-mention') &&\n message.content.includes('blockquote')\n ) {\n handleHTMLReply(message)\n }\n const topic = state.topics.find(topic => topic.title == message.subject)\n if (topic) {\n topic.messages.push(message)\n } else {\n state.topics.push({\n title: message.subject,\n messages: [message]\n })\n }\n }\n },\n deleteMessage: (state, { mid, subject }) => {\n const topic = state.topics.find(t => t.title == subject)\n if (topic) {\n const message = topic.messages.find(m => m.id == mid)\n if (message) {\n topic.messages.splice(topic.messages.indexOf(message), 1)\n }\n }\n },\n addReaction: (state, { mid, reaction }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n if (message) {\n message.reactions.push(reaction)\n }\n },\n removeReaction: (state, { mid, reaction }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n if (message) {\n message.reactions.splice(message.reactions.indexOf(reaction), 1)\n }\n },\n setRules: (state, rules) => {\n state.rules = rules.reduce((acc, cur) => {\n let rule = toCSS(cur, state.currentStream);\n if (rule !== null) {\n acc.push(rule);\n }\n return acc\n }, [])\n },\n addRule: (state, rule) => {\n if (toCSS(rule) !== null) {\n // state.rules.push(toCSS(rule, state.currentStream))\n // vue will not update if i use rules.push(rule)\n state.rules = [...state.rules, ...[toCSS(rule, state.currentStream)]]\n }\n },\n editMessage: (state, { mid, content }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n const rule = state.rules.find(r => r.id == mid)\n if (message) {\n message.content = content\n if (message.content.startsWith('@_**')) {\n handleMDReply(message)\n } else if (\n message.content.includes('user-mention') &&\n message.content.includes('blockquote')\n ) {\n handleHTMLReply(message)\n }\n } else if (rule) {\n // state.rules[state.rules.indexOf(rule)] = toCSS({\n // id: mid, content: content,\n // }, state.currentStream)\n\n // vue will not update if i use rules.push(rule) \n state.rules.splice(state.rules.indexOf(rule), 1)\n const newRules = [...state.rules, ...[toCSS({\n id: mid, content: content,\n }, state.currentStream)]]\n state.rules = newRules\n }\n },\n\n updateTopic: (state, { orig_subject, subject }) => {\n const topic = state.topics.find(t => t.title == orig_subject)\n if (topic) {\n topic.title = subject\n topic.messages.forEach(m => m.subject = subject)\n }\n }\n\n },\n\n actions: {\n },\n\n getters: {\n rules: state => state.rules,\n sortedTopics: state => (\n [...state.topics]\n .sort((a, b) => a.title.localeCompare(b.title))\n .filter(t => (\n t.messages.length > 0 &&\n t.title != 'stream events'\n ))\n )\n }\n\n})\n","import { createApp } from 'vue'\nimport App from './App'\nimport Axios from 'axios'\nimport MarkdownIt from 'markdown-it'\nimport VueMarkdownIt from 'vue3-markdown-it'\nimport router from './router'\nimport store from './store'\n\nimport 'highlight.js/styles/vs.css';\n\nconst app = createApp(App)\n\nconst mdOpts = {\n html: true,\n linkify: true,\n typographer: true\n}\n\napp.config.globalProperties.$http = Axios\napp.config.globalProperties.$mdOpts = mdOpts\napp.config.globalProperties.$md = new MarkdownIt(mdOpts)\n\napp\n .use(VueMarkdownIt)\n .use(router)\n .use(store)\n .mount('#app')\n\n\n\n","export * from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../node_modules/vue-loader-v16/dist/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./App.vue?vue&type=style&index=0&id=6d28ae45&lang=css\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Docs.vue?vue&type=style&index=0&id=32f02ba2&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Rule.vue?vue&type=style&index=0&id=080e408c&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Message.vue?vue&type=style&index=0&id=e48b70e8&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Stream.vue?vue&type=style&index=0&id=1af39708&scoped=true&lang=css\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Home.vue?vue&type=style&index=0&id=39e10b20&lang=css\""],"sourceRoot":""} \ No newline at end of file diff --git a/front/dist/js/app.185d5e35.js b/front/dist/js/app.185d5e35.js new file mode 100644 index 0000000..46fe1db --- /dev/null +++ b/front/dist/js/app.185d5e35.js @@ -0,0 +1,2 @@ +(function(e){function t(t){for(var o,r,s=t[0],i=t[1],c=t[2],u=0,d=[];u"),a="https://chat.hackersanddesigners.nl";t=t.replaceAll('src="','src="'+a),t=t.replaceAll('href="/','href="'+a+"/"),t=t.replaceAll(a+"/user_uploads/","https://chatty-pub-files.hackersanddesigners.nl/files/"),t=this.replaceAllEmojiCodes(t);var o=this.$store.state.topics.find((function(t){return t.title==e.message.subject})).messages.filter((function(t){return t.responseTo&&t.responseTo.id==e.message.id&&t.responseTo.sender_id==e.message.sender_id&&e.message.content.includes(t.responseTo.quote)}));return o.forEach((function(e){var a=e.reactions.map((function(e){return"u"+e.emoji_code})).join(" ");t=t.replace(e.responseTo.quote,'').concat(e.responseTo.quote,""))})),t},reactions:function(){return this.message.reactions.map((function(e){return Fe.replace_colons(":"+e.emoji_name+":")}))},classes:function(){return this.message.reactions.map((function(e){return e.emoji_code+" u"+e.emoji_code}))},time:function(){var e=this.message.timestamp,t=1e3*e,a=new Date(t);return a.toLocaleString()}},created:function(){}};a("b47d");const Ae=D()(qe,[["render",Pe]]);var Ne=Ae,Ve={name:"Chapter",components:{Message:Ne},props:["topic","show_message_data"],computed:{messagesToShow:function(){return this.topic.messages.filter((function(e){return!e.responseTo}))}}};a("9954");const Me=D()(Ve,[["render",Ce],["__scopeId","data-v-05955d29"]]);var We=Me,Ue={name:"Content",components:{Chapter:We,Toc:ae,Authors:ke},props:["print","show_message_data"],computed:Object(s["a"])(Object(s["a"])(Object(s["a"])({},Object(i["c"])(["currentStream","streams"])),Object(i["b"])(["sortedTopics"])),{},{foundStream:function(){var e=this;return this.streams.find((function(t){return t.name==e.currentStream.name}))},title:function(){return this.foundStream?this.currentStream.name:"/"==this.$route.path?"<= pick a stream":"Stream does not exist."},description:function(){return this.title&&this.foundStream&&this.foundStream.description.replace("_PUB_","")},authors:function(){return[].concat(Object(de["a"])(new Set(this.title&&this.foundStream&&this.sortedTopics.map((function(e){return e.messages})).flat().map((function(e){return e.sender_full_name})))),["Pub Bot"])}}),methods:{toValidID:function(e){return encodeURIComponent("ch-"+e).toLowerCase().replace(/\.|%[0-9a-z]{2}/gi,"").replace(/\(|\)/gi,"")}}};const Le=D()(Ue,[["render",ue],["__scopeId","data-v-2d35224f"]]);var He=Le,Re=Object(o["withScopeId"])("data-v-16b43aee");Object(o["pushScopeId"])("data-v-16b43aee");var $e={class:"rules"};Object(o["popScopeId"])();var Ze=Re((function(e,t,a,n,f,r){var s=Object(o["resolveComponent"])("Rule");return Object(o["openBlock"])(),Object(o["createBlock"])("section",$e,[(Object(o["openBlock"])(!0),Object(o["createBlock"])(o["Fragment"],null,Object(o["renderList"])(e.rules,(function(e){return Object(o["openBlock"])(),Object(o["createBlock"])(s,{key:e.id,rule:e},null,8,["rule"])})),128))])})),Ge=Object(o["withScopeId"])("data-v-080e408c");Object(o["pushScopeId"])("data-v-080e408c");var Ye={key:0},Je={key:1},Ke={class:"instructions"},Qe=Object(o["createTextVNode"])("Add the follow to your rule to use this font:"),Xe=Object(o["createVNode"])("br",null,null,-1),et=Object(o["createVNode"])("p",null,"}",-1);Object(o["popScopeId"])();var tt=Ge((function(e,t,a,n,f,r){return Object(o["openBlock"])(),Object(o["createBlock"])("div",{class:["rule",r.classes],style:r.rules},["raw"===a.rule.type?(Object(o["openBlock"])(),Object(o["createBlock"])("pre",Ye,Object(o["toDisplayString"])(r.contentFiltered)+"\n ",1)):"font"===a.rule.type?(Object(o["openBlock"])(),Object(o["createBlock"])("span",Je,[Object(o["createVNode"])("pre",{style:r.rules},'@font-face { \n font-family: "'+Object(o["toDisplayString"])(r.font.family)+'"; \n src: "'+Object(o["toDisplayString"])(r.font.src)+'" format('+Object(o["toDisplayString"])("font.format")+"); \n}",5),Object(o["createVNode"])("div",Ke,[Object(o["createVNode"])("span",null,[Qe,Xe,Object(o["createTextVNode"])(' font-family: "'+Object(o["toDisplayString"])(r.font.family)+'"; ',1)])])])):(Object(o["openBlock"])(),Object(o["createBlock"])(o["Fragment"],{key:2},[Object(o["createVNode"])("p",{title:e.toEmojiCode(a.rule.className)},Object(o["toDisplayString"])(a.rule.className)+" {",9,["title"]),(Object(o["openBlock"])(!0),Object(o["createBlock"])(o["Fragment"],null,Object(o["renderList"])(a.rule.rules,(function(e){return Object(o["openBlock"])(),Object(o["createBlock"])("p",{key:e},"  "+Object(o["toDisplayString"])(e),1)})),128)),et],64))],6)})),at={name:"Rule",mixins:[O],props:["rule"],computed:{contentFiltered:function(){var e=this,t=this.emoji_regex,a=this.rule.content.replace(t,(function(t){return t+", .u"+e.toEmojiCode(t)}));return a},classes:function(){return"type-"+this.rule.type},font:function(){return this.rule.content},rules:function(){return"font"!==this.rule.type?this.rule.rules:["font-family: "+this.font.family+";"]}}};a("c251");const ot=D()(at,[["render",tt],["__scopeId","data-v-080e408c"]]);var nt=ot,ft={name:"Rules",components:{Rule:nt},computed:Object(s["a"])({},Object(i["c"])(["rules"])),watch:{rules:function(){console.log("rules")}}};a("5476");const rt=D()(ft,[["render",Ze],["__scopeId","data-v-16b43aee"]]);var st=rt,it=a("512e"),ct=(a("c1ea"),a("676e")),lt={name:"Home",components:{Streams:ie,Content:He,Rules:st,Splitpanes:it["Splitpanes"],Pane:it["Pane"]},setup:function(){var e=Object(o["ref"])(null);return{preview:e}},data:function(){return{show_ui:!0,show_message_data:!1,panel_sizes:{0:10,1:55,2:35},expand_content:!1}},computed:{classes:function(){return this.show_ui?"ui":"print"},currentStream:function(){return this.$store.state.currentStream.slug}},methods:{resizer:function(e){for(var t=0;there.\n\n- [What is CSS](#what-is-css)\n- [Rules](#rules)\n- [Css in ChattyPub](#css-in-chattypub)\n - [About formatting](#about-formatting)\n - [Advanced CSS](#advanced-css)\n- [Uploading fonts](#uploading-fonts)\n- [Print settings](#print-settings)\n - [Page breaks](#page-breaks)\n- [Common CSS properties](#properties)\n - [Backgrounds and borders](#backgrounds)\n - [Color](#color)\n - [Box model](#box-model)\n - [Fonts](#fonts)\n - [Text](#text)\n - [Transforms](#transforms)\n\n---\n\n## What is CSS?\n\nCSS (Cascading Style Sheets) is the language that allows you to style and layout HTML web pages. This article explains what CSS is, with some simple syntax examples, and also covers some key terms about the language.\n\nSince this document relates specifically to ChattyPub, the focus is going to be on the parts of the language that are supported by this platform. Because CSS is specifically oriented towards styling HTML (and related languages like SVG and XML) you have to have a basic understanding of HTML.[1](#footnote1) Mozilla has an excellent [HTML introduction](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started).\n\nAt its heart, HTML is a fairly simple language made up of elements, which can be applied to pieces of text to give them different meaning in a document (Is it a paragraph? Is it a bulleted list? Is it part of a table?), structure a document into logical sections (Does it have a header? Three columns of content? A navigation menu?), and embed content such as images and videos into a page.\nBut what HTML does not do is speficy how these elements should look. That is where CSS comes in.\n\nCSS can be used for very basic document text styling — for example changing the color and size of headings and links. It can be used to create layout — for example turning a single column of text into a layout with a main content area and a sidebar for related information. It can even be used for effects such as animation.\nIn ChattyPub we're mostly interested in the first part.\n\n---\n\n## Rules\n\n#### _Elements and Classes_\n\nIn this section we will talk about CSS in general. ChattyPub uses a slight variation on it, but let's start with the basics.\n\nCSS is a rule-based language — you define rules specifying groups of styles that should be applied to particular elements or groups of elements on your web page. For example \"I want the main heading on my page to be shown as large red text.\"\n\nThe following code shows a very simple CSS rule that would achieve the styling described above:\n\n```css\nh1 {\n color: red;\n font-size: 20px;\n}\n```\n\nThe rule opens with a selector. This selects the HTML element that we are going to style. In this case we are styling all level one headings (`

    `) that appear on the page.\n\nWe then have a set of curly braces `{` `}`. Inside those will be one or more declarations, which take the form of property and value pairs. Each pair specifies a property of the element(s) we are selecting, then a value that we'd like to give the property. Each pair is followed by a semi-colon `;` to indicate the end of the property.\n\nBefore the colon, we have the property, and after the colon, the value. CSS properties have different allowable values, depending on which property is being specified. In our example, we have the color property, which can take various color values. We also have the font-size property. This property can take various size units as a value.\n\nThe example above will style all the `H1` elements on the page. You could also write a selector for all paragraphs (the selector would be `p`), images (`img`) or list items (`li`). This works as long as you want all of the elements of that type in your document to look the same. Most of the time that isn't the case and so you will need to find a way to select a subset of the elements without changing the others. The most common way to do this is to add a class to your HTML element and target that class.\n\nTake this HTML:\n\n```html\n
      \n
    • Item one
    • \n
    • Item two
    • \n
    • Item three
    • \n
    \n```\n\nTo target the class of special you can create a selector that starts with a full stop character.\n\n```css\n.special {\n color: orange;\n font-weight: bold;\n}\n```\n\nThe peroid character in front of special tells the browser that we're creating a class selector.\nYou can apply the class of special to any element on your page that you want to have the same look as this list item.\n\n### Units\n\nIn the `h1` example above, we set the following property: `font-size: 20px;`. This will set the font-size of all H1 headers to 20 pixels. But pixels are not the only units available. Some examples:\n\n- `em` and `rem` - these relative units declare a size dependant on the font-size of the context they get used in. This can be a bit confusing if you're not used to it. Feel free to replace it with on of the values below.\n- `px` - Pixels.\n- `cm` and `in` - centimeters and inches. These units are mostly relevant in print context.\n- `vw` and `vh` - so called viewport units, 100vw is exactly the height of the viewport (the part of the browser that shows the webpage). `vh` is the same, but for the height of the browser.\n- `rgba(r,g,b,a)` strictly speaking not a unit but a function, but it sets the color and transparency of the foreground.\n\n[More information on units](https://www.w3.org/Style/Examples/007/units.en.html).\n\n---\n\n## CSS in ChattyPub\n\nWhen you react to a message in Zulip with an emoji, this emoji gets turned into a class in ChattyPub. So lets say you responded to a message with the strawberry 🍓 emoji. In ChattyPub the message will have class with that emoji as selector. (You can confirm this by rolling over the message, the emoji should popup on a overlay.) So now to style that message, you go to the `#rules` channel and add a message with the following content:\n\n```css\n🍓 {\n color: red;\n}\n```\n\nIt is very similar to the examples above. `🍓` is the selector, so the rule will apply to each message with a strawberry reaction. Then follows the block `{` and `}`. And in the block, there is property, `color: red;`.\n\n_A small difference with regular CSS is that you don't need to add the period in front of the selector ChattyPub will handle that for you._\n\nBecause of the way Zulip handles the emoji reactions, not all emoji are available or sometimes they don't exactly correspond to the emoji you might type in the `#rules` channel. To help with sorting this out you can roll over a message in ChattyPub and see the reactions that are applied. Sometimes the translation is unavailable, in that case you'll see something like `:working_on_it:` instead of the emoji you expected. In that case remove your reaction and find an other emoji that does work.\n\n### About formatting\n\nYou can't enter a tab character in Zulip and the indentation before the property in the rule isn't absolutely necessary. So feel free to leave it out. If you absolutely want to have the indentation, you could write the rule in your favorite editor and copy and paste it into Zulip. Make sure that the selector, each property and the closing accolade are all on their own line. __Don't forget the semi-colon at the end of each property line!__\n\n### Advanced CSS\n\n**Selecting HTML elements and other style rules**\n\nThe reaction/emoji method described above allows to make quick modifications to the style and layout of your publication. But besides this ChattyPub also allows you to style html elements like in regular CSS. To do this just enter your style rule. This snippet will give all HTML links a pink background color:\n\n```css\na {\n background-color: pink;\n}\n```\n\nYou should be able to enter all regular CSS rules this way.\n\n**Bypassing the parser** -_Work in progress_-\n\nIt is possible to bypass the parser and add arbitrary code to the CSS on the page. This allows you to add, for example, `@keyframes` for an animation or media queries. To do this send any message to the `#rules` channel and wrap the message in three backticks like this:\n\n~~~~\n```\n@keyframes example {\n from {background-color: red;}\n to {background-color: yellow;}\n}\n```\n~~~~\n\n---\n\n## Uploading fonts\n\nIt is also possible to upload a custom font to the application. To do this, you send the font in a message to the #rules channel of the publication you want to use it in. You can use `.ttf`, `.otf` or `.woff`/`.woff2` formats depending on the browser you are using. The mesage must only contain the font, no other text. ChattyPub will then automatically generate a @font-face rule for the font. The font-family name will be based on the filename.\n\nOnce uploaded the font should show up in the CSS rules section of ChattyPub. To use the font in a style rule, just copy/paste the `font-family: \"font_name_ttf\";` and add it to a rule in the #rules channel.\n\n> Please only upload free or open-source fonts to our server!\n\n## Print settings\n\nTo set the paper size we can use the special selector `@page`. The following snippet set the page size to A5.\n\n```css\n@page {\n size: 148mm 210mm;\n}\n```\n\nThis example sets the page to landscape.\n\n```css\n@page {\n size: landscape;\n}\n```\n\nWe've tried to get the browser to add crop and alignment marks, but we've haven't been able to get it to work. If you do, please let us know!\n\n```css\n@page {\n marks: crop cross;\n}\n```\n\nRegrettably [browser support](https://caniuse.com/css-paged-media) for `@page` is spotty. Currently only MS Edge, Opera and Google Chrome will allow you to set page sizes etc, and even then it is a matter of trial and error.\n\nThe [Paged media module](https://developer.mozilla.org/en-US/docs/Web/CSS/Paged_Media) at Mozilla has an excellent explanation on using `@page`.\n\n### page breaks\n\nBy default pages will automatically wrap to the next page. And ChattyPub adds a page break after each topic. If you want to force a page break you could write a rule for it, using the `page-break-after: always;` property:\n\n```css\n🍏 {\n page-break-after: always;\n}\n```\n\nIf you don't want the page break after an article you can overwrite the default by using:\n\n```css\n.body {\n page-break-after: avoid;\n}\n```\n\nFor some of these rules it may be necessary to use the methods described under [Advanced CSS](#advanced-css) above to enter these rules.\n\n## List of common and handy CSS properties\n\nThere are hundreds of CSS properties. Below is a small selection of some basic properties mostly focussed on layout and type representation, grouped by module.\n\n### Backgrounds and borders\n\n- [background-color](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color)\n- [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) - The border CSS property sets an element's border.\n- [border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius) - The border-radius CSS property rounds the corners of an element's outer border edge.\n- [box-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow) - The box-shadow CSS property adds shadow effects around an element's frame.\n\n### Color\n\n- [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) - The color CSS property sets the foreground color value of an element's text and text decorations.\n- [opacity](https://developer.mozilla.org/en-US/docs/Web/CSS/opacity) - The opacity CSS property sets the opacity of an element. Opacity is the degree to which content behind an element is hidden, and is the opposite of transparency.\n\nA colors value can defined in multiple ways:\n\n- By [name/keyword](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#keywords) - `color: red;` will make your text red.\n- By [hex value](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#hex) - `color: #ff0000;` also red.\n- Or as a [function](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#rgba), which allows transparency. - `color: rgba(255,0,0,0.5);` red, but 50% transparent.\n\n### Box model\n\n- [margin](https://developer.mozilla.org/en-US/docs/Web/CSS/margin) - The margin property sets the margin area on all four sides of an element. Margin refers to space between different elements.\n- [padding](https://developer.mozilla.org/en-US/docs/Web/CSS/padding) - The padding property sets the padding area on all four sides of an element at once. Padding refers to the spacing inside the border of an element.\n\n### Fonts\n\n- [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) - The font-family CSS property specifies a prioritized list of one or more font family names and/or generic family names for the selected element.\n\nYou can choose one of the following generic fonts. Which exact font will be used is dependant on your computers' settings.\n\n```css\nfont-family: serif;\nfont-family: sans-serif;\nfont-family: monospace;\nfont-family: cursive;\nfont-family: fantasy;\n```\n\nIt is also possible to specify an exact font name, but it will only be used if it is actually available on your system.\nFor example following statement will try to use Helvetica if available, but will fallback on a generic sans-serif font if not. (Note the quotes around the font name).\n\n```css\nfont-family: \"Helvetica Neue\", sans-serif;\n```\n\nAlso see the section on uploading fonts below.\n\n- [font-size](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size) - The font-size CSS property sets the size of the font. Changing the font size also updates the sizes of the font size-relative units, such as em, ex, and so forth.\n- [font-style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style) - The font-style CSS property sets whether a font should be styled with a normal, italic, or oblique face from its font-family.\n- [font-weigh](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) - The font-weight CSS property sets the weight (or boldness) of the font. The weights available depend on the font-family that is currently set.\n- [line-height](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height) - The line-height CSS property sets the height of a line box. It's commonly used to set the distance between lines of text.\n\n### Text\n\n- [letter-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/letter-spacing) - The letter-spacing CSS property sets the horizontal spacing behavior between text characters.\n- [text-align](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) - The text-align CSS property sets the horizontal alignment of the content inside a block element.\n- [text-transform](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) - The text-transform CSS property specifies how to capitalize an element's text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.\n- [white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) - The white-space CSS property sets how white space inside an element is handled.\n- [word-break](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break) - The word-break CSS property sets whether line breaks appear wherever the text would otherwise overflow its content box.\n- [word-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/word-spacing) - The word-spacing CSS property sets the length of space between words and between tags.\n- [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) - The text-shadow CSS property adds shadows to text.\n\n### Transforms\n\n- [rotate](https://developer.mozilla.org/en-US/docs/Web/CSS/rotate) - The rotate CSS property allows you to specify rotation of elements\n- [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/scale) - The scale CSS property allows you to specify the scale (size) of elements\n- [translate](https://developer.mozilla.org/en-US/docs/Web/CSS/translate) - The translate CSS property allows you to specify translation transforms (position relative to where it originally was) of elements.\n\n1: I've borrowed shamelessly from Mozilla to make this text: https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps/What_is_CSS and https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML\n"),yt='# ChattyPub Workshop Script\n\n## Introduction\n\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication.\n\nThe workshop will explore in a practical manner how the process of co-designing a publication can unfold, specifically when several people are working at the same time using a chat interface as the main design tool. During HDSA2021 we would like to open up the process of making this tool and explore together its possibilities and limitations. The workshop will take place towards the end of the one-week summer academy program. Thus, we will be able to use some of the documentation produced during the week — workshops scripts, prototypes, game cards, recipes, ... as well as conversations we will have on different platforms – synchronously and asynchronously.\n\nCommands allow you to style the texts and images, but someone else can change their appearance again later! How will we negotiate these design decisions synchronously and asynchronously? The outcome could be a zine, posters or a webpage.\n\nThis script aims to provide the necessary instructions to host a workshop around ChattyPub that can accomodate different skills and knowledges in different contexts.\n\n## Goals\n\n- Learn to collaboratively write, design, and print documents using ChattyPub\n- Produce publications of / relating to HDSA2021 (documentation, prototypes, conversations, etc...)\n- Learn and/or practice styling with CSS & Emojis\n\n## Requirements\n\n- a computer, web-browser, and connection to the internet\n- an account for the Hackers & Designers Zulip instance: https://chat.hackersanddesigners.nl/\n- a printer\n\n## Preparation\n\nBefore the summer academy: Most important is for all workshop participants to set up a Zulip account on our server. The H&D zulip instance can be found at https://chat.hackersanddesigners.nl/ (public sign ups are temporariy open).\n\nOn the first day of the summer academy (monday): Participants are introduced to the Zulip interface and instructed to use it for communication during the course of the week. Zulip makes use of a rather unconventional (but powerful) chat-threading logic, so it would be good to spend some time interacting with it and settle into this new environment.\n\nWorkshop hosts and participants are encouraged to think about how they would like to document their processes during the summer academy. What is included and what isn\'t? How is this shared? Is there a regular moment during the day dedicated to documentation or is it more ad-hoc? We suggest using Etherpad for collaborative note taking, and regularly making screenshots or screenrecordings and photos. We have previously compiled a so-called "tool-ecology", a list of tools we have good experiences with and recommend using during the summer academy: https://etherpad.hackersanddesigners.nl/p/hdsa2021-tool-ecology.\n\nTexts, notes, chats, images, and screenshots will make great material for our workshop.\n\n## How It Works\n\nFor an overview of how ChattyPub works with Zulip, go [here](/docs/Chattypub).\n## Workshop\n\nThe workshop is split over two sessions (over two days) of 4 hours each.\n\n_Opening Session: Introductions & first encounters with ChattyPub_\n\n- Introductory presentation ( 1hr ) -- will be livestreamed in the morning / recorded and shared afterwards.\n - Context and background on H&D\'s publishing activities (Anja & Juliette) [slides](https://hackersanddesigners.github.io/chatty-pub-css-slides/assets/hdsa-chattypub-intro.pdf)\n - Introduction to ChattyPub (Karl).\n - Introduction to CSS (Heerko). [slides](https://hackersanddesigners.github.io/chatty-pub-css-slides/)\n - How it all comes together (emojis ;])(Karl)\n- Experimenting with ChattyPub! ( 2 hrs )\n - participants with different levels of experience of CSS are grouped together\n - each group follows [these instructions](/docs/Chattypub#content) to make one publication in ChattyPub\n - detailed instructions about CSS can be found [here](/docs/CSS)\n- Brainstorm Session (1 hr)\n - in groups of 2-3, participants brainstorm publications they will make during the main session \n - The goal is to document together, in print, parts of the summer academy.\n - What have you been up to this last week?\n - What did you make? What material did you collect / produce?\n - How will you negotiate this design process?\n - Are roles divided and then switched? \n - If you are planning to print your publication, take into account the printing limitations of your home printer or local print shop.\n - Print settings such as the page size and orientation can all be configure with CSS.\n - If participants are joining remotely, it\'s good that they are paired together.\n\n_Main Session: Chat => Print_\n\n- Making publications ( 2 hrs )\n - Groups work on the publications planned in the previous session \n - Each group makes a stream on Zulip for the publiction\n - They create chapters for their contents\n - They create a "rules" topic for their styles\n - Organizers are available to help where needed\n - At least one or two people per node should be able to help with CSS.\n - Karl and Heerko will be available if bugs / errors occur.\n- Printing Publications ( 1 hr )\n - A printer is required in the space (or easily accessible)\n - Accommodating for different paper sizes is an added bonus\n - Binding could be fun too\n- Sharing outcomes and reflections ( 1 hr ) \n - Round of publications\n - Reflection on process\n - Feedback on ChattyPub\n',wt='# ChattyPub\n\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication. ChattyPub is a collaborative publication/zine-making tool built on top of the chat platform [Zulip](https://chat.hackersanddesigners.nl). By sending messages, reacting with emoji and writing simple CSS style rules the publication can be collectively designed.\n\n- [Zulip](#zulip)\n- [ChattyPub](#using-chattypub)\n- [Making a publication with Zulip & ChattyPub](#content)\n - [Content](#content)\n - [Rules](#rules)\n - [Printing](#printing)\n- [Typing Emoji](#typing-emoji)\n- [Problems?](#problems)\n\n## Zulip\n\nOn Zulip, conversations are categorized into different "Streams", which are comparable to "channels" in other messaging services like Discord. Streams can be public or private and host conversations consisting of text, images, files, reactions, etc..\n\nWhat differentiates Zulip from most messaging platforms is the way streams are sub-threaded. Zulip introduces the concept of "Topics", which, in the plainest terms, means that messages have subjects. When sending a message to a stream in Zulip, you can also specify the topic of the message and the stream automatically filters messages by their shared topics. If your message\'s topic doesn\'t exist yet, it will be created when you send your message.\n\nZulip allows you to react to messages using emoji\'s as well. We will make heavy use of emojis in ChattyPub.\n\nThere are several ways to engage with Zulip, including a web-client, a desktop app, and a mobile app.\n\n## Using ChattyPub\n\nhttp://chatty-pub.hackersanddesigners.nl\n\nChattyPub is a website that acts as a different interface to the same Zulip service. ChattyPub takes a stream from Zulip, combines messages into long-form articles and uses a design system combining Emojis and CSS syntax to style the messages, effectively turning the stream into a (printable!) webpage.\n\n## Making a publication with Zulip & ChattyPub\n\n### Content\n\n1. Create a stream on Zulip\n - Ensure that either (1) the stream name starts with `pub-` or (2) the stream descriptio includes this text:`_PUB_`.\n - Ensure that the stream name does not have any uderscores.\n - Ensure that the stream is public.\n2. Go to [ChattyPub](https://chatty-pub.hackersanddesigners.nl). The stream you created will be visible on the left-side navigation.\n3. Click on your stream.\n4. The main (middle) section of the website will have:\n 1. Your stream name (which will be the name of your publication)\n 2. The topics of your stream organized into a table of contents (which will act as "Chapters" in your publication)\n 3. The topics, in alphabetical order, displaying their messages, in chronological order.\n5. To create a new topic (chapter), return to Zulip and type a message to your stream, making sure to send it to the topic you want to create.\n\n### Rules\n\nThe right-hand side of the ChattyPub interface is reserved for one topic in your stream: "rules". This topic will house definitions for styles you want to apply to messages in your stream.\n\nGo back to Zulip and create the topic in your stream called "rules".\n\nEvery message you send to this topic should consist of a single emoji followed by a set of styles you\'d like applied to messages. For example:\n\n```CSS\n🍓 {\n color: red;\n text-decoration: underline;\n}\n```\n\nThese messages should be unique and follow the CSS syntax, as described in the [introduction to CSS](/docs/CSS). If you are comfortable with CSS, you can skip to the part of the document that describes [how CSS is used in ChattyPub](/docs/CSS#css-in-chattypub).\n\nTo apply these styles to the contents of your publication, head back to any other topic in your stream, select a message you\'d like to style, and react to it with the emoji whose styles you want to apply. On ChattyPub, the message should be rendered with these styles.\n\nIf you\'d like to style only a part of a message, select the message in Zulip and quote and respond to it (in the 3-dot menu). This will produce a text in your input box on the bottom of the interface. Delete the parts of the quoted message that you don\'t want the styles applied to, and send your response. When you react with an emoji to your own response, the part of the original message you quoted will inherit the styles defined for that emoji.\n\nKeep in mind that you can edit your own messages! So if you make a mistake (forgetting the semi-colon at the end of a statement is a common one), roll over your message and click the little pen at the top righthand side of the message.\n\n### Printing\n\n> Regrettably support for setting page size, page breaks etc. using [@page](https://caniuse.com/css-paged-media) is very poor in some browsers. Use MS Edge, Opera or Google Chrome for best results when printing or creating PDFs.\n\nTo print, click on the print button on the left side of the application. This will hide the interface, make all content visible and open the browsers\' Printing dialog box.\n\nIf you want to use background colors or background images in your publication you may have to turn that on in the print settings dialog.\n\nThere is more information on setting up pages sizes etc, in the CSS document.\n\n## Typing Emoji\n\n- [Windows](https://support.microsoft.com/en-us/windows/windows-10-keyboard-tips-and-tricks-588e0b72-0fff-6d3f-aeee-6e5116097942)\n- [Mac](https://www.howtogeek.com/684025/how-to-type-emoji-on-your-mac-with-a-keyboard-shortcut/)\n- Linux varies per distribution. If you run Linux you\'re probably capable of finding out how :)\n\n## Problems\n\nChattyPub is very young and you\'re sure to run into problems. Feel free to contact `@Karl Moubarak`, `@andré` or `@heerko` at https://chat.hackersanddesigners.nl/\n\nBelow are some things that we know of, and are working on:\n\n- :emoji: not working...\n',kt=(a("e4cb"),{name:"Docs",data:function(){return{files:{Workshop:yt,Chattypub:wt,CSS:gt}}},computed:{source:function(){return this.files[this.$route.params.slug]}},mounted:function(){var e=this;setTimeout((function(){e.source&&e.$route.hash&&document.querySelector(e.$route.hash).scrollIntoView({behavior:"smooth"})}),100)},methods:{getFileName:function(e,t){var a=e&&"function"===typeof e.match&&e.match(/\/?([^/.]*)\.?([^/]*)$/);return a?t&&a.length>2&&a[2]?a.slice(1).join("."):a[1]:null},handleLinks:function(){var e=this;Array.from(document.querySelectorAll("a")).forEach((function(t){t.addEventListener("click",(function(a){t.pathname.startsWith("/docs/")&&(console.log(t),e.$router.push(t.pathname),a.preventDefault(),document.scroll({top:0}))}))}))}}});a("926b");const vt=D()(kt,[["render",_t],["__scopeId","data-v-32f02ba2"]]);var jt=vt,St="/",Ot=Object(M["a"])({history:Object(M["b"])(St),routes:[{path:"/",name:"Home",component:dt},{path:"/docs",name:"Docs",component:jt},{path:"/docs/:slug",name:"Doc",props:!0,component:jt},{path:"/:pathMatch(.*)*",name:"Home",component:dt}]}),Ct=a("9558"),xt=(a("a1f0"),a("1276"),a("a434"),a("cd8a")),Dt=function(e,t){var a=Object(xt["stripHtml"])(e.content).result,o="",n="",f=[],r=t&&t.slug||"",s=e.id,i=e.content.includes("")||e.content.startsWith("```"),c=/

    0?(o=O.methods.replaceAllEmojiCodes(d[0]["groups"]["selector"]),O.methods.containsEmoji(o)&&(n=O.methods.toEmojiCode(o)),f=d[0]["groups"]["props"].split("\n"),f=f.filter((function(e){return Pt(e)})),{className:o,emoji_code:n,rules:f,parentClassName:r,id:s,content:a,type:l}):(console.log("rejected rule",e),null)},zt=function(e){return e.replaceAll("```","")},Tt=function(e){var t={family:"",src:"",format:""},a=e,o=Bt(a),n=o.split(".").pop();return t.src="https://chatty-pub-files.hackersanddesigners.nl/files"+a,t.format=Et(n),t.family=o.replace(".","_"),t},Bt=function(e){return e.split("\\").pop().split("/").pop()},Et=function(e){var t="truetype";switch(e){case"woff":t="woff";break;case"woff2":t="woff2";break;case"eof":t="embedded-opentype";break}return t},Pt=function(e){return e.match(/.+:.+;/gm)},It=function(e){e.responseTo={id:e.content.replace(/.*\/near\//gm,"").replace(/\):.*[^]+/gm,""),sender_id:e.content.replace(/@_\*\*.*\|/gm,"").replace(/\*\*.\[said\].*[^]+/gm,""),quote:e.content.replace(/[^]+.*```quote\n/gm,"").replace(/ \n```/gm,"")}},Ft=function(e){e.responseTo={id:e.content.replace(/.*\/near\//gm,"").replace(/".*[^]+/gm,""),sender_id:e.content.replace(/[^]+data-user-id="/gm,"").replace(/">[^]+/gm,""),quote:e.content.replace(/.*[^]+<\/p>\n

    \n

    /gm,"").replace(/<\/p>\n<\/blockquote>/gm,"")}},qt=Object(i["a"])({strict:!1,state:{isMobile:!1,streams:[],currentStream:{},rules:[],topics:[],pubStr:"pub-"},mutations:{setMobile:function(e,t){return e.isMobile=t},setStreams:function(e,t){return e.streams=t},setCurStream:function(e,t){return e.currentStream=t},setTopics:function(e,t){return e.topics=t},addMessage:function(e,t){t.content.startsWith("@_**")?It(t):t.content.includes("user-mention")&&t.content.includes("blockquote")&&Ft(t);var a=e.topics.find((function(e){return e.title==t.subject}));a?a.messages.push(t):e.topics.push({title:t.subject,messages:[t]})},deleteMessage:function(e,t){var a=t.mid,o=t.subject,n=e.topics.find((function(e){return e.title==o}));if(n){var f=n.messages.find((function(e){return e.id==a}));f&&n.messages.splice(n.messages.indexOf(f),1)}},addReaction:function(e,t){var a=t.mid,o=t.reaction,n=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==a}));n&&n.reactions.push(o)},removeReaction:function(e,t){var a=t.mid,o=t.reaction,n=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==a}));n&&n.reactions.splice(n.reactions.indexOf(o),1)},setRules:function(e,t){e.rules=t.reduce((function(t,a){var o=Dt(a,e.currentStream);return null!==o&&t.push(o),t}),[])},addRule:function(e,t){null!==Dt(t)&&(e.rules=[].concat(Object(de["a"])(e.rules),[Dt(t,e.currentStream)]))},editMessage:function(e,t){var a=t.mid,o=t.content,n=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==a})),f=e.rules.find((function(e){return e.id==a}));if(n)n.content=o,n.content.startsWith("@_**")?It(n):n.content.includes("user-mention")&&n.content.includes("blockquote")&&Ft(n);else if(f){e.rules.splice(e.rules.indexOf(f),1);var r=[].concat(Object(de["a"])(e.rules),[Dt({id:a,content:o},e.currentStream)]);e.rules=r}},updateTopic:function(e,t){var a=t.orig_subject,o=t.subject,n=e.topics.find((function(e){return e.title==a}));n&&(n.title=o,n.messages.forEach((function(e){return e.subject=o})))}},actions:{},getters:{rules:function(e){return e.rules},filteredTopics:function(e){return Object(de["a"])(e.topics).filter((function(e){return e.messages.length>0&&"stream events"!=e.title}))},sortedTopics:function(e,t){return t.filteredTopics.sort((function(e,t){return e.title.localeCompare(t.title,void 0,{numeric:!0,sensitivity:"base"})}))}}}),At=(a("85e4"),Object(o["createApp"])(P)),Nt={html:!0,linkify:!0,typographer:!0};At.config.globalProperties.$http=F.a,At.config.globalProperties.$mdOpts=Nt,At.config.globalProperties.$md=new A.a(Nt),At.use(V.a).use(Ot).use(qt).mount("#app")},"5d4f":function(e,t,a){"use strict";a("675b")},"675b":function(e,t,a){},"76e8":function(e,t,a){},"7b4c":function(e,t,a){},"7f6d":function(e,t,a){"use strict";a("76e8")},"7f96":function(e){e.exports=JSON.parse('{"names":["+1","-1","100","1234","8_ball","a","ab","abc","abcd","accessible","accommodations","acrobatics","action","add","aerial_tramway","agent","agony","airplane","airplane_arrival","airplane_departure","alarm","alarm_clock","alchemy","alembic","alert","alien","all_good","alphabet","ambulance","american_football","amphora","anchor","android","angel","anger","anger_bubble","angry","angry_cat","angry_devil","anguish","anguished","ant","anxious","applause","apple","approved","aquarius","arabian_camel","arcade","archery","archive","aries","arms_open","arrival","art","asking_a_question","asterisk","astonished","at_work","athletic_shoe","atm","atom","attachment","avocado","b","baa","baby","baby_bottle","baby_change_station","baby_chick","back","backpack","bacon","badminton","baggage_claim","baguette","balance","ball","balloon","ballot_box","ballpoint_pen","bam","bamboo","banana","bangbang","bank","bar_chart","barber","baseball","basketball","bat","bath","bathtub","battery","beach","beach_umbrella","bear","bed","bedroom","bee","beer","beers","beetle","beginner","bell","bellhop_bell","bento","betrayed","bicycle","big_frown","big_rig","big_smile","bike","bikini","billiards","biohazard","bird","birthday","black_and_white_square","black_belt","black_circle","black_flag","black_heart","black_large_square","black_medium_small_square","black_medium_square","black_small_square","blank","blossom","blow_a_kiss","blowfish","blue_book","blue_circle","blue_heart","blush","blushing","boar","boat","bomb","boo","book","bookmark","books","boom","boot","bouquet","bow","bow_and_arrow","bowling","boxing_glove","boy","bravery","bread","breakfast","bride","bridge","briefcase","brightness","broken_heart","bronze","buddhism","bug","bulb","bull","bullet_train","bullhorn","bulls_eye","bunny","burial","burrito","bus","bus_stop","butterfly","buzz","cactus","cake","calendar","calf","call_me","calling","camel","camera","camping","campsite","cancer","candle","candy","canoe","capital_abcd","capital_letters","capricorn","car","card_index","carousel","carp_streamer","carpenter_square","carrot","cartwheel","castle","cat","caterpillar","caution","cd","celebration","cell_reception","chains","champagne","chart","check","check_mark","checkbox","checkered_flag","cheese","cherries","cherry_blossom","chestnut","chick","chicken","children_crossing","chili_pepper","chipmunk","chocolate","christianity","church","cinema","circle","circus","city","city_sunrise","cl","clap","classical_building","clink","clipboard","clock","clockwise","closed_book","closed_mailbox","closed_umbrella","clothing","cloud","cloudy","clover","clown","clubs","cluck","clue","cock-a-doodle-doo","cocktail","coffee","coffin","cold_sweat","collision","comet","commitment","commodities","composition_book","compression","computer","computer_mouse","concerned","conch","condemned","confetti","confounded","confused","congratulations","construction","construction_worker","construction_zone","control_knobs","convenience_store","cookie","cooking","cool","cop","corn","couch_and_lamp","counterclockwise","cow","cowboy","crab","crash","crayon","crazy","credit_card","cremation","crew","cricket","cricket_bat","crocodile","croissant","cross","cross_mark","crossed_flags","crown","cruise","crushed","cry","crying_cat","crystal","crystal_ball","cucumber","cupid","curry","custard","customs","cute","cyclist","cyclone","dagger","dancer","dancers","dancing","danger","dango","dark_sunglasses","darts","dash","date","death","debit_card","deciduous_tree","decoration","decorative_notebook","decrease","decreasing","deer","denim","department_store","departure","derelict_house","desert","desktop_computer","detective","devil","diamond_with_a_dot","diamonds","dice","die","digital_security","dim","ding","direct_hit","disabled","disappointed","disappointed_relieved","disco","distraught","divide","division","dizzy","do_not_litter","document","dog","dogi","dollar_bills","dollars","dolls","dolphin","done_deal","doner_kebab","donut","door","dormouse","double_down","double_exclamation","double_loop","double_up","doughnut","dove","dove_of_peace","down","down_button","downvote","downwards_trend","dragon","dragon_face","drama","dream","drenched","dress","drinking_water","drive_with_care","drooling","drop","drum","drumstick","duck","duel","dungeon","dvd","e-mail","eagle","ear","ear_of_rice","earth_africa","earth_americas","earth_asia","east","easy_come_easy_go","eating_utensils","egg","eggplant","eight","eight_pointed_star","eight_spoked_asterisk","elderly_man","elderly_woman","electric_plug","elephant","elevated_train","email","embarrassed","empty_mailbox","encrypted","end","engineer","envelope","envy","euro_banknotes","evergreen_tree","exchange","exclamation","exhausted","expecting","explosion","expressionless","eye","eyes","face_palm","face_with_thermometer","factory","fall","fallen_leaf","family","fast_down","fast_forward","fast_reverse","fast_up","fax","fear","feet","fencing","ferris_wheel","ferry","fever","field_hockey","file","file_cabinet","file_folder","film","find","fingers_crossed","fire","fire_engine","fire_truck","fireworks","first_place","fish","fishing","fist","fist_bump","five","fixing","flags","flame","flan","flashlight","fleur_de_lis","flip_flops","flipper","floppy_disk","flower","flu","flushed","fog","foggy","folder","food","football","footprints","fork_and_knife","fork_and_knife_with_plate","fortune_telling","forward","fountain","fountain_pen","four","four_leaf_clover","fox","framed_picture","free","fries","frog","frosty","frown","frowning","fuel_pump","full_battery","full_moon","funeral_urn","furniture","future","gas_pump","gear","gecko","geek","gelato","gem","gemini","ghost","gift","gift_heart","girl","glamour","glass_of_milk","glasses","globe","glowing_star","go","goal","goat","goblin","gold","gold_record","golf","gondola","goodnight","gooooooooal","gorilla","got_it","graduate","grapes","grave","green_apple","green_book","green_heart","grey_exclamation","grey_question","grimacing","grinning","grinning_face_with_smiling_eyes","growing","growing_heart","grumpy","gua_pi_mao","guard","guestrooms","guitar","gun","gym","gymnastics","haircut","half_frown","halo","hamburger","hammer","hammer_and_pick","hammer_and_wrench","hamster","hand","handbag","handball","handshake","handyman","handywoman","happy","hard_hat","harvest","hash","hat","hatching","hatching_chick","haunted","hazard","hazy","head_bandage","heading_down","heading_up","headlines","headphones","hear_no_evil","heart","heart_arrow","heart_box","heart_exclamation","heart_eyes","heart_eyes_cat","heart_kiss","heart_of_gold","heart_pulse","heartache","heartbeat","hearts","helicopter","hello","helmet","helpless","herb","hi","hibiscus","high_brightness","high_five","high_heels","high_speed_train","high_voltage","hinduism","hint","hiss","hocho","hole","hole_in_one","holiday_tree","home_phone","honey","honeybee","horizontal_traffic_light","horn","horse","horse_racing","horse_riding","hospital","hot","hot_pepper","hot_springs","hotdog","hotel","hourglass","hourglass_done","house","houses","hover","hug","humpback_whale","hundred","hungry","hurricane","hurt","hush","hushed","ice_cream","ice_hockey","ice_skate","id","idea","ill","immigration","imp","in_bed","in_love","inbox","inbox_zero","incorrect","increase","increasing","info","information_desk_person","injection","injured","innocent","interrobang","invincible","iphone","islam","island","izakaya_lantern","jack-o-lantern","japan","japan_post","jeans","jeep","joker","joking","joy","joy_cat","joystick","judiasm","juggling","justice","kaaba","kaching","kawaii","keikogi","key","key_signing","keyboard","kick_scooter","kimono","king","kiss","kiss_smiling_eyes","kiss_with_blush","kissing_cat","kitten","kiwi","knife","koala","label","ladybug","landing","landline","lantern","laptop","large_blue_diamond","large_orange_diamond","laughing","laughter_tears","leaves","ledger","left","left_fist","left_hook","left_right","lemon","leo","leopard","lets_eat","level_slider","levitating","lgbtq","libra","lifestyles","lift","light_bulb","light_rail","lightning","lightning_storm","like","link","linked","lion","lips","lips_are_sealed","lipstick","lipstick_kiss","lit","live_long_and_prosper","living_room","lizard","lock_with_key","locked","locked_bag","locker","lol","lollipop","looking","loop","losing_money","louder","loudspeaker","love","love_hotel","love_letter","love_you","low_brightness","lower_left","lower_right","loyalty","lucky","lying","m","mad","magnifying_glass","mahjong","mail","mail_dropoff","mail_received","mail_sent","mailbox","maintenance","maize","man","man_and_woman_couple","man_and_woman_holding_hands","mandarin","mantelpiece_clock","map","maple_leaf","martial_arts","mask","massage","meal","meat","mechanical","medal","medicine","megaphone","melon","memo","men_couple","menorah","mens","meow","merry_go_round","meteor","metro","mic","microphone","microscope","middle_finger","mike","military_medal","milk","milky_way","mine","minibus","minidisc","minus","mischievous","mobile_phone","money","money_face","money_with_wings","monkey","monkey_face","monorail","moon","moon_ceremony","moon_face","mortar_board","mosque","mostly_sunny","mother_christmas","mother_nature","motor_bike","motor_boat","motorcycle","motorway","mount_fuji","mountain","mountain_biker","mountain_cableway","mountain_railway","mountain_sunrise","mouse","mouth","movie","movie_camera","movie_theater","moving_truck","moyai","mrs_claus","multiplication","multiply","muscle","mushroom","music","musical_keyboard","musical_notes","musical_score","mute","mute_notifications","nail_care","nail_polish","namaste","name_badge","naruto","national_park","nauseated","nc17","nerd","nervous","neutral","new","new_baby","new_moon","new_moon_face","new_york","newspaper","next_track","ng","night","night_sky","nine","no_bicycles","no_entry","no_mail","no_mouth","no_pedestrians","no_phones","no_signal","no_smoking","no_sound","non-potable_water","noodles","nope","north","north_east","north_west","nose","not_allowed","note","notebook","notifications","nuclear","number_one","numbers","nursery","nut_and_bolt","o","ocean","ocean_sunrise","octagonal_sign","octopus","oden","office","office_supplies","ogre","oh_no","oil_drum","oink","ok","ok_signal","old_key","older_man","older_woman","om","on","oncoming_automobile","oncoming_bus","oncoming_car","oncoming_police_car","oncoming_streetcar","oncoming_taxi","oncoming_train","oncoming_tram","oncoming_trolley","one","onigiri","oops","open_book","open_hands","open_mouth","ophiuchus","oracle","orange","orange_book","organize","orthodox_cross","outbox","overcast","owl","ox","p","package","paella","page","pager","pained","paintbrush","painting","palette","palm","palm_tree","pancakes","panda","paper","paperclip","paperclip_chain","parking","part_alternation","partly_cloudy","partly_sunny","partly_sunny_with_rain","party_ball","pass","passenger_ship","passport_control","pause","paw_prints","paws","peace","peace_sign","peach","peanuts","pear","pedestrian","pen","pencil","penguin","pensive","performing_arts","persevere","person_frowning","person_pouting","person_tipping_hand","petrol_pump","phone","phone_off","physics","piano","pick","pick_me","picture","pig","pig_nose","piglet","pile_of_poo","pill","pin","pineapple","ping_pong","pirate","pisces","pizza","place_holder","place_of_worship","plant","play","play_pause","play_reverse","playing_cards","plus","point_down","point_left","point_of_information","point_right","point_up","poison","poker_face","police","police_car","pony","poodle","pool","poop","popcorn","post_office","potable_water","potato","pouch","poultry","pound_notes","pouting_cat","pow","power","praise","pray","prayer_beads","pregnant","present","previous_track","price_tag","pride","prince","princess","printer","privacy","prohibited","projector","protected","pumpkin","punch","puppy","purple_heart","purse","push_pin","put_litter_in_its_place","queasy","queen","question","quiet","rabbit","race","racecar","radio","radio_button","radioactive","rage","railway_car","railway_track","rainbow","rainy","raised_hand","raised_hands","raising_hand","ram","ramen","rat","rated_for_violence","receipt","reception","record","recreational_vehicle","recycle","red_book","red_circle","red_triangle_down","red_triangle_up","relaxed","relieved","reminder_ribbon","repeat","repeat_one","reply","rescue_worker","restroom","return","revolving_hearts","rewind","rhinoceros","ribbon","rice","rice_cracker","rideshare","right","right_fist","right_hook","ring","road","road_trip","robot","rock_carving","rock_on","rocket","rofl","roller_coaster","rolling_eyes","rolling_on_the_floor_laughing","rolodex","rooster","rose","rosette","rotating_light","rowboat","rowing","rugby","ruler","runner","running","running_shirt","running_shoe","sad","safe","safety_first","sagittarius","sailboat","sake","salad","sandal","santa","satchel","satellite","satellite_antenna","saxophone","say_cheese","scales","scared","school","school_bus","school_crossing","science","scientist","scissors","scooter","scorpion","scorpius","scream","scream_cat","screw","scroll","sculling","sealed","search","seashell","seat","second_place","secret","secure","see_no_evil","seedling","seeing_stars","selfie","semi_truck","senbei","services","settings","seven","sewing_pin","shadow","shadows","shamrock","shark","shaved_ice","shawarma","sheep","shell","shield","shinto_shrine","ship","shiro","shirt","shock","shoe","shooting_star","shopping_bags","shopping_cart","shopping_trolley","shout","shower","shrimp","shrinking","shrug","shuffle","sick","sign_of_the_horns","signal_bars","signal_strength","silence","silhouette","silhouettes","silver","siren","six","ski","ski_lift","skier","skip_back","skip_forward","skull","skull_and_crossbones","skyline","sleeping","sleepy","sleuth","slight_frown","slot_machine","small_airplane","small_blue_diamond","small_glass","small_orange_diamond","smartphone","smile","smile_cat","smiley","smiley_cat","smiling_devil","smiling_face","smiling_face_with_horns","smiling_imp","smirk","smirk_cat","smitten","smoking","smug","smug_cat","snail","snake","sneaker","sneaky","sneezing","snowboarder","snowflake","snowman","snowstorm","snowy","snowy_mountain","soaked","sob","soccer","soft_ice_cream","soft_serve","softer","solidarity","soon","sort","sos","sound","soup","south","south_east","south_west","souvlaki","space_invader","spades","spaghetti","sparkle","sparkler","sparkles","sparkling_heart","speak_no_evil","speaker","speaking_head","spectacles","speech_balloon","speech_bubble","speechless","speedboat","spider","spider_web","spiral_notebook","spiral_notepad","spiral_shell","spock","spooky","spoon","sports","sprout","spy","squared_ok","squared_up","squid","stadium","star","star_and_crescent","star_of_david","start","station","statue","statue_of_liberty","steam_locomotive","stew","stock_market","stop","stop_button","stop_sign","stopwatch","straightedge","strawberry","streetcar","stressed","strike","striped_pole","stuck_out_tongue","stuck_out_tongue_closed_eyes","stuck_out_tongue_wink","studio_microphone","stuffed_flatbread","subtract","suburb","subway","sun_and_rain","sun_face","sunflower","sunglasses","sunny","sunrise","sunset","sunshowers","surf","surprise","surrender","sushi","suspension_railway","swap","swat","sweat","sweat_drops","sweat_smile","sweet_potato","swim","swords","symbols","synagogue","syringe","table_setting","table_tennis","taco","tada","tag","take_off","taking_a_picture","tanabata_tree","tangerine","tap_water","taurus","taxi","tea","tears","telephone","telescope","television","temperature","tempura","ten","tennis","tent","thank_you","theater","thermometer","thinking","third_place","this","thought","three","thumb_tack","thumbs_down","thumbs_up","thunder_and_rain","thunderstorm","ticket","tie","tiger","tiger_cub","time","time_ticking","timer","times_up","tired","tm","toast","toilet","tokyo_tower","tomato","tongue","tools","top","top_hat","tornado","tortoise","tower","toxic","trackball","tractor","tractor-trailer","trademark","traffic_light","train","train_car","train_tracks","tram","transport_truck","trash_can","tree","triangular_flag","triangular_ruler","trident","triumph","trolley","trophy","tropical_drink","tropical_fish","truck","trumpet","tshirt","tulip","tumbling","turban","turkey","turtle","tuxedo","tv","two","two_hearts","two_men_holding_hands","two_women_holding_hands","typhoon","ufo","umbrella","umbrella_with_rain","umm","unamused","underage","unicorn","unlocked","unread_mail","up","up_button","up_down","upper_left","upper_right","upside_down","upvote","upwards_trend","vase","vertical_traffic_light","very_angry","vhs","vibration_mode","victory","video_camera","video_game","video_recorder","videocassette","violin","virgo","vise","voicemail","volcano","volleyball","volume","vs","wait_one_second","walking","warm","warning","wastebasket","watch","water_buffalo","water_closet","water_drop","water_polo","watermelon","wave","wavy_dash","waxing_moon","wc","weary","weary_cat","web","wedding","weight_lift","welcome","west","whale","wheel_of_dharma","wheelchair","white_and_black_square","white_circle","white_flag","white_flower","white_large_square","white_medium_small_square","white_medium_square","white_small_square","wilted_flower","wind","wind_chime","windy","wine","wink","winner","wish","wish_tree","wolf","woman","women_couple","womens","woof","work_in_progress","work_out","working_on_it","world_map","worried","wrench","wrestling","writing","wrong","wrong_way","www","x","yacht","yam","yellow_heart","yen_banknotes","yin_yang","yum","zap","zero","zip_it","zzz"],"name_to_codepoint":{"100":"1f4af","1234":"1f522","grinning":"1f600","happy":"1f600","smiley":"1f603","big_smile":"1f604","grinning_face_with_smiling_eyes":"1f601","laughing":"1f606","lol":"1f606","sweat_smile":"1f605","joy":"1f602","tears":"1f602","laughter_tears":"1f602","rolling_on_the_floor_laughing":"1f923","rofl":"1f923","smiling_face":"263a","relaxed":"263a","blush":"1f60a","innocent":"1f607","halo":"1f607","smile":"1f642","upside_down":"1f643","oops":"1f643","wink":"1f609","relieved":"1f60c","heart_eyes":"1f60d","in_love":"1f60d","heart_kiss":"1f618","blow_a_kiss":"1f618","kiss":"1f617","kiss_smiling_eyes":"1f619","kiss_with_blush":"1f61a","yum":"1f60b","stuck_out_tongue":"1f61b","mischievous":"1f61b","stuck_out_tongue_wink":"1f61c","joking":"1f61c","crazy":"1f61c","stuck_out_tongue_closed_eyes":"1f61d","money_face":"1f911","kaching":"1f911","hug":"1f917","arms_open":"1f917","nerd":"1f913","geek":"1f913","sunglasses":"1f60e","clown":"1f921","cowboy":"1f920","smirk":"1f60f","smug":"1f60f","unamused":"1f612","disappointed":"1f61e","pensive":"1f614","tired":"1f614","worried":"1f61f","oh_no":"1f615","half_frown":"1f615","concerned":"1f615","confused":"1f615","frown":"1f641","slight_frown":"1f641","sad":"2639","big_frown":"2639","persevere":"1f623","helpless":"1f623","confounded":"1f616","agony":"1f616","anguish":"1f62b","weary":"1f629","distraught":"1f629","triumph":"1f624","angry":"1f620","rage":"1f621","mad":"1f621","grumpy":"1f621","very_angry":"1f621","speechless":"1f636","no_mouth":"1f636","blank":"1f636","poker_face":"1f636","neutral":"1f610","expressionless":"1f611","hushed":"1f62f","frowning":"1f626","anguished":"1f627","pained":"1f627","open_mouth":"1f62e","surprise":"1f62e","astonished":"1f632","dizzy":"1f635","flushed":"1f633","embarrassed":"1f633","blushing":"1f633","scream":"1f631","fear":"1f628","scared":"1f628","shock":"1f628","cold_sweat":"1f630","cry":"1f622","exhausted":"1f625","disappointed_relieved":"1f625","stressed":"1f625","drooling":"1f924","sob":"1f62d","sweat":"1f613","sleepy":"1f62a","sleeping":"1f634","rolling_eyes":"1f644","thinking":"1f914","lying":"1f925","grimacing":"1f62c","nervous":"1f62c","anxious":"1f62c","silence":"1f910","quiet":"1f910","hush":"1f910","zip_it":"1f910","lips_are_sealed":"1f910","nauseated":"1f922","queasy":"1f922","sneezing":"1f927","mask":"1f637","sick":"1f912","flu":"1f912","face_with_thermometer":"1f912","ill":"1f912","fever":"1f912","hurt":"1f915","head_bandage":"1f915","injured":"1f915","smiling_devil":"1f608","smiling_imp":"1f608","smiling_face_with_horns":"1f608","devil":"1f47f","imp":"1f47f","angry_devil":"1f47f","ogre":"1f479","goblin":"1f47a","poop":"1f4a9","pile_of_poo":"1f4a9","ghost":"1f47b","boo":"1f47b","spooky":"1f47b","haunted":"1f47b","skull":"1f480","skull_and_crossbones":"2620","pirate":"2620","death":"2620","hazard":"2620","toxic":"2620","poison":"2620","alien":"1f47d","ufo":"1f47d","space_invader":"1f47e","robot":"1f916","jack-o-lantern":"1f383","pumpkin":"1f383","smiley_cat":"1f63a","smile_cat":"1f638","joy_cat":"1f639","heart_eyes_cat":"1f63b","smirk_cat":"1f63c","smug_cat":"1f63c","kissing_cat":"1f63d","scream_cat":"1f640","weary_cat":"1f640","crying_cat":"1f63f","angry_cat":"1f63e","pouting_cat":"1f63e","open_hands":"1f450","raised_hands":"1f64c","praise":"1f64c","clap":"1f44f","applause":"1f44f","pray":"1f64f","welcome":"1f64f","thank_you":"1f64f","namaste":"1f64f","handshake":"1f91d","done_deal":"1f91d","+1":"1f44d","thumbs_up":"1f44d","like":"1f44d","-1":"1f44e","thumbs_down":"1f44e","fist_bump":"1f44a","punch":"1f44a","fist":"270a","power":"270a","left_fist":"1f91b","right_fist":"1f91c","fingers_crossed":"1f91e","peace_sign":"270c","victory":"270c","rock_on":"1f918","sign_of_the_horns":"1f918","ok":"1f44c","got_it":"1f44c","point_left":"1f448","point_right":"1f449","point_up":"1f446","this":"1f446","point_down":"1f447","wait_one_second":"261d","point_of_information":"261d","asking_a_question":"261d","hand":"270b","raised_hand":"270b","stop":"1f91a","high_five":"1f590","palm":"1f590","spock":"1f596","live_long_and_prosper":"1f596","wave":"1f44b","hello":"1f44b","hi":"1f44b","call_me":"1f919","muscle":"1f4aa","middle_finger":"1f595","writing":"270d","selfie":"1f933","nail_polish":"1f485","nail_care":"1f485","ring":"1f48d","lipstick":"1f484","lipstick_kiss":"1f48b","lips":"1f444","mouth":"1f444","tongue":"1f445","ear":"1f442","nose":"1f443","footprints":"1f463","feet":"1f463","eye":"1f441","eyes":"1f440","looking":"1f440","speaking_head":"1f5e3","silhouette":"1f464","shadow":"1f464","silhouettes":"1f465","shadows":"1f465","baby":"1f476","boy":"1f466","girl":"1f467","man":"1f468","woman":"1f469","older_man":"1f474","elderly_man":"1f474","older_woman":"1f475","elderly_woman":"1f475","gua_pi_mao":"1f472","turban":"1f473","police":"1f46e","cop":"1f46e","construction_worker":"1f477","guard":"1f482","detective":"1f575","spy":"1f575","sleuth":"1f575","agent":"1f575","sneaky":"1f575","mother_christmas":"1f936","mrs_claus":"1f936","santa":"1f385","princess":"1f478","prince":"1f934","bride":"1f470","tuxedo":"1f935","angel":"1f47c","pregnant":"1f930","expecting":"1f930","bow":"1f647","information_desk_person":"1f481","person_tipping_hand":"1f481","no_signal":"1f645","nope":"1f645","ok_signal":"1f646","raising_hand":"1f64b","pick_me":"1f64b","face_palm":"1f926","shrug":"1f937","person_pouting":"1f64e","person_frowning":"1f64d","haircut":"1f487","massage":"1f486","levitating":"1f574","hover":"1f574","dancer":"1f483","dancing":"1f57a","disco":"1f57a","dancers":"1f46f","walking":"1f6b6","pedestrian":"1f6b6","running":"1f3c3","runner":"1f3c3","man_and_woman_holding_hands":"1f46b","man_and_woman_couple":"1f46b","two_women_holding_hands":"1f46d","women_couple":"1f46d","two_men_holding_hands":"1f46c","men_couple":"1f46c","family":"1f46a","clothing":"1f45a","shirt":"1f455","tshirt":"1f455","jeans":"1f456","denim":"1f456","tie":"1f454","dress":"1f457","bikini":"1f459","kimono":"1f458","high_heels":"1f460","sandal":"1f461","flip_flops":"1f461","boot":"1f462","shoe":"1f45e","athletic_shoe":"1f45f","sneaker":"1f45f","running_shoe":"1f45f","hat":"1f452","top_hat":"1f3a9","graduate":"1f393","mortar_board":"1f393","crown":"1f451","queen":"1f451","king":"1f451","helmet":"26d1","hard_hat":"26d1","rescue_worker":"26d1","safety_first":"26d1","invincible":"26d1","backpack":"1f392","satchel":"1f392","pouch":"1f45d","purse":"1f45b","handbag":"1f45c","briefcase":"1f4bc","glasses":"1f453","spectacles":"1f453","dark_sunglasses":"1f576","closed_umbrella":"1f302","umbrella":"2602","puppy":"1f436","kitten":"1f431","dormouse":"1f42d","hamster":"1f439","bunny":"1f430","fox":"1f98a","bear":"1f43b","panda":"1f43c","koala":"1f428","tiger_cub":"1f42f","lion":"1f981","calf":"1f42e","piglet":"1f437","pig_nose":"1f43d","frog":"1f438","monkey_face":"1f435","see_no_evil":"1f648","hear_no_evil":"1f649","speak_no_evil":"1f64a","monkey":"1f412","chicken":"1f414","cluck":"1f414","penguin":"1f427","bird":"1f426","chick":"1f424","baby_chick":"1f424","hatching":"1f423","hatching_chick":"1f423","new_baby":"1f425","duck":"1f986","eagle":"1f985","owl":"1f989","bat":"1f987","wolf":"1f43a","boar":"1f417","pony":"1f434","unicorn":"1f984","bee":"1f41d","buzz":"1f41d","honeybee":"1f41d","bug":"1f41b","caterpillar":"1f41b","butterfly":"1f98b","snail":"1f40c","shell":"1f41a","seashell":"1f41a","conch":"1f41a","spiral_shell":"1f41a","beetle":"1f41e","ladybug":"1f41e","ant":"1f41c","spider":"1f577","web":"1f578","spider_web":"1f578","turtle":"1f422","tortoise":"1f422","snake":"1f40d","hiss":"1f40d","lizard":"1f98e","gecko":"1f98e","scorpion":"1f982","crab":"1f980","squid":"1f991","octopus":"1f419","shrimp":"1f990","tropical_fish":"1f420","fish":"1f41f","blowfish":"1f421","dolphin":"1f42c","flipper":"1f42c","shark":"1f988","whale":"1f433","humpback_whale":"1f40b","crocodile":"1f40a","leopard":"1f406","tiger":"1f405","water_buffalo":"1f403","ox":"1f402","bull":"1f402","cow":"1f404","deer":"1f98c","arabian_camel":"1f42a","camel":"1f42b","elephant":"1f418","rhinoceros":"1f98f","gorilla":"1f98d","horse":"1f40e","pig":"1f416","oink":"1f416","goat":"1f410","ram":"1f40f","sheep":"1f411","baa":"1f411","dog":"1f415","woof":"1f415","poodle":"1f429","cat":"1f408","meow":"1f408","rooster":"1f413","alarm":"1f413","cock-a-doodle-doo":"1f413","turkey":"1f983","dove":"1f54a","dove_of_peace":"1f54a","rabbit":"1f407","mouse":"1f401","rat":"1f400","chipmunk":"1f43f","paw_prints":"1f43e","paws":"1f43e","dragon":"1f409","dragon_face":"1f432","cactus":"1f335","holiday_tree":"1f384","evergreen_tree":"1f332","tree":"1f333","deciduous_tree":"1f333","palm_tree":"1f334","seedling":"1f331","sprout":"1f331","herb":"1f33f","plant":"1f33f","shamrock":"2618","clover":"2618","lucky":"1f340","four_leaf_clover":"1f340","bamboo":"1f38d","wish_tree":"1f38b","tanabata_tree":"1f38b","leaves":"1f343","wind":"1f343","fall":"1f343","fallen_leaf":"1f342","maple_leaf":"1f341","mushroom":"1f344","harvest":"1f33e","ear_of_rice":"1f33e","bouquet":"1f490","tulip":"1f337","flower":"1f337","rose":"1f339","wilted_flower":"1f940","crushed":"1f940","sunflower":"1f33b","blossom":"1f33c","cherry_blossom":"1f338","hibiscus":"1f33a","earth_americas":"1f30e","earth_africa":"1f30d","earth_asia":"1f30f","full_moon":"1f315","new_moon":"1f311","waxing_moon":"1f314","new_moon_face":"1f31a","moon_face":"1f31d","sun_face":"1f31e","goodnight":"1f31b","moon":"1f319","seeing_stars":"1f4ab","star":"2b50","glowing_star":"1f31f","sparkles":"2728","glamour":"2728","high_voltage":"26a1","zap":"26a1","fire":"1f525","lit":"1f525","hot":"1f525","flame":"1f525","boom":"1f4a5","explosion":"1f4a5","crash":"1f4a5","collision":"1f4a5","comet":"2604","meteor":"2604","sunny":"2600","mostly_sunny":"1f324","partly_sunny":"26c5","partly_cloudy":"26c5","cloudy":"1f325","sunshowers":"1f326","sun_and_rain":"1f326","partly_sunny_with_rain":"1f326","rainbow":"1f308","pride":"1f308","lgbtq":"1f308","cloud":"2601","overcast":"2601","rainy":"1f327","soaked":"1f327","drenched":"1f327","thunderstorm":"26c8","thunder_and_rain":"26c8","lightning":"1f329","lightning_storm":"1f329","snowy":"1f328","snowstorm":"1f328","snowman":"2603","frosty":"26c4","snowflake":"2744","windy":"1f32c","mother_nature":"1f32c","dash":"1f4a8","tornado":"1f32a","fog":"1f32b","hazy":"1f32b","ocean":"1f30a","drop":"1f4a7","water_drop":"1f4a7","sweat_drops":"1f4a6","umbrella_with_rain":"2614","green_apple":"1f34f","apple":"1f34e","pear":"1f350","orange":"1f34a","tangerine":"1f34a","mandarin":"1f34a","lemon":"1f34b","banana":"1f34c","watermelon":"1f349","grapes":"1f347","strawberry":"1f353","melon":"1f348","cherries":"1f352","peach":"1f351","pineapple":"1f34d","kiwi":"1f95d","avocado":"1f951","tomato":"1f345","eggplant":"1f346","cucumber":"1f952","carrot":"1f955","corn":"1f33d","maize":"1f33d","hot_pepper":"1f336","chili_pepper":"1f336","potato":"1f954","yam":"1f360","sweet_potato":"1f360","chestnut":"1f330","peanuts":"1f95c","honey":"1f36f","croissant":"1f950","bread":"1f35e","baguette":"1f956","cheese":"1f9c0","egg":"1f95a","cooking":"1f373","bacon":"1f953","pancakes":"1f95e","breakfast":"1f95e","tempura":"1f364","drumstick":"1f357","poultry":"1f357","meat":"1f356","pizza":"1f355","hotdog":"1f32d","hamburger":"1f354","fries":"1f35f","doner_kebab":"1f959","shawarma":"1f959","souvlaki":"1f959","stuffed_flatbread":"1f959","taco":"1f32e","burrito":"1f32f","salad":"1f957","paella":"1f958","spaghetti":"1f35d","ramen":"1f35c","noodles":"1f35c","food":"1f372","soup":"1f372","stew":"1f372","naruto":"1f365","sushi":"1f363","bento":"1f371","curry":"1f35b","rice":"1f35a","onigiri":"1f359","senbei":"1f358","rice_cracker":"1f358","oden":"1f362","dango":"1f361","shaved_ice":"1f367","ice_cream":"1f368","gelato":"1f368","soft_serve":"1f366","soft_ice_cream":"1f366","cake":"1f370","birthday":"1f382","custard":"1f36e","flan":"1f36e","lollipop":"1f36d","candy":"1f36c","chocolate":"1f36b","popcorn":"1f37f","donut":"1f369","doughnut":"1f369","cookie":"1f36a","milk":"1f95b","glass_of_milk":"1f95b","baby_bottle":"1f37c","coffee":"2615","tea":"1f375","sake":"1f376","beer":"1f37a","beers":"1f37b","clink":"1f942","toast":"1f942","wine":"1f377","small_glass":"1f943","cocktail":"1f378","tropical_drink":"1f379","champagne":"1f37e","spoon":"1f944","fork_and_knife":"1f374","eating_utensils":"1f374","hungry":"1f37d","meal":"1f37d","table_setting":"1f37d","fork_and_knife_with_plate":"1f37d","lets_eat":"1f37d","football":"26bd","soccer":"26bd","basketball":"1f3c0","american_football":"1f3c8","baseball":"26be","tennis":"1f3be","volleyball":"1f3d0","rugby":"1f3c9","billiards":"1f3b1","pool":"1f3b1","8_ball":"1f3b1","ping_pong":"1f3d3","table_tennis":"1f3d3","badminton":"1f3f8","gooooooooal":"1f945","goal":"1f945","ice_hockey":"1f3d2","field_hockey":"1f3d1","cricket":"1f3cf","cricket_bat":"1f3cf","hole_in_one":"26f3","bow_and_arrow":"1f3f9","archery":"1f3f9","fishing":"1f3a3","boxing_glove":"1f94a","black_belt":"1f94b","keikogi":"1f94b","dogi":"1f94b","martial_arts":"1f94b","ice_skate":"26f8","ski":"1f3bf","skier":"26f7","snowboarder":"1f3c2","lift":"1f3cb","work_out":"1f3cb","weight_lift":"1f3cb","gym":"1f3cb","fencing":"1f93a","wrestling":"1f93c","cartwheel":"1f938","acrobatics":"1f938","gymnastics":"1f938","tumbling":"1f938","ball":"26f9","sports":"26f9","handball":"1f93e","golf":"1f3cc","surf":"1f3c4","swim":"1f3ca","water_polo":"1f93d","rowboat":"1f6a3","crew":"1f6a3","sculling":"1f6a3","rowing":"1f6a3","horse_racing":"1f3c7","horse_riding":"1f3c7","cyclist":"1f6b4","mountain_biker":"1f6b5","running_shirt":"1f3bd","medal":"1f3c5","military_medal":"1f396","first_place":"1f947","gold":"1f947","number_one":"1f947","second_place":"1f948","silver":"1f948","third_place":"1f949","bronze":"1f949","trophy":"1f3c6","winner":"1f3c6","rosette":"1f3f5","reminder_ribbon":"1f397","pass":"1f3ab","ticket":"1f39f","circus":"1f3aa","juggling":"1f939","performing_arts":"1f3ad","drama":"1f3ad","theater":"1f3ad","art":"1f3a8","palette":"1f3a8","painting":"1f3a8","action":"1f3ac","microphone":"1f3a4","mike":"1f3a4","mic":"1f3a4","headphones":"1f3a7","musical_score":"1f3bc","piano":"1f3b9","musical_keyboard":"1f3b9","drum":"1f941","saxophone":"1f3b7","trumpet":"1f3ba","guitar":"1f3b8","violin":"1f3bb","dice":"1f3b2","die":"1f3b2","direct_hit":"1f3af","darts":"1f3af","bulls_eye":"1f3af","strike":"1f3b3","bowling":"1f3b3","video_game":"1f3ae","slot_machine":"1f3b0","car":"1f697","taxi":"1f695","rideshare":"1f695","recreational_vehicle":"1f699","jeep":"1f699","bus":"1f68c","school_bus":"1f68c","trolley":"1f68e","racecar":"1f3ce","police_car":"1f693","ambulance":"1f691","fire_truck":"1f692","fire_engine":"1f692","minibus":"1f690","moving_truck":"1f69a","truck":"1f69b","tractor-trailer":"1f69b","big_rig":"1f69b","semi_truck":"1f69b","transport_truck":"1f69b","tractor":"1f69c","kick_scooter":"1f6f4","bike":"1f6b2","bicycle":"1f6b2","scooter":"1f6f5","motor_bike":"1f6f5","motorcycle":"1f3cd","siren":"1f6a8","rotating_light":"1f6a8","alert":"1f6a8","oncoming_police_car":"1f694","oncoming_bus":"1f68d","oncoming_car":"1f698","oncoming_automobile":"1f698","oncoming_taxi":"1f696","aerial_tramway":"1f6a1","ski_lift":"1f6a1","gondola":"1f6a0","mountain_cableway":"1f6a0","suspension_railway":"1f69f","railway_car":"1f683","train_car":"1f683","tram":"1f68b","streetcar":"1f68b","mountain_railway":"1f69e","monorail":"1f69d","elevated_train":"1f69d","high_speed_train":"1f684","bullet_train":"1f685","light_rail":"1f688","train":"1f682","steam_locomotive":"1f682","oncoming_train":"1f686","subway":"1f687","oncoming_tram":"1f68a","oncoming_streetcar":"1f68a","oncoming_trolley":"1f68a","station":"1f689","helicopter":"1f681","small_airplane":"1f6e9","airplane":"2708","take_off":"1f6eb","departure":"1f6eb","airplane_departure":"1f6eb","landing":"1f6ec","arrival":"1f6ec","airplane_arrival":"1f6ec","rocket":"1f680","satellite":"1f6f0","seat":"1f4ba","canoe":"1f6f6","boat":"26f5","sailboat":"26f5","motor_boat":"1f6e5","speedboat":"1f6a4","passenger_ship":"1f6f3","yacht":"1f6f3","cruise":"1f6f3","ferry":"26f4","ship":"1f6a2","anchor":"2693","work_in_progress":"1f6a7","construction_zone":"1f6a7","fuel_pump":"26fd","gas_pump":"26fd","petrol_pump":"26fd","bus_stop":"1f68f","traffic_light":"1f6a6","vertical_traffic_light":"1f6a6","horizontal_traffic_light":"1f6a5","map":"1f5fa","world_map":"1f5fa","road_trip":"1f5fa","rock_carving":"1f5ff","moyai":"1f5ff","statue":"1f5fd","new_york":"1f5fd","statue_of_liberty":"1f5fd","fountain":"26f2","tower":"1f5fc","tokyo_tower":"1f5fc","castle":"1f3f0","shiro":"1f3ef","stadium":"1f3df","ferris_wheel":"1f3a1","roller_coaster":"1f3a2","carousel":"1f3a0","merry_go_round":"1f3a0","beach_umbrella":"26f1","beach":"1f3d6","island":"1f3dd","mountain":"26f0","snowy_mountain":"1f3d4","mount_fuji":"1f5fb","volcano":"1f30b","desert":"1f3dc","campsite":"1f3d5","tent":"26fa","camping":"26fa","railway_track":"1f6e4","train_tracks":"1f6e4","road":"1f6e3","motorway":"1f6e3","construction":"1f3d7","factory":"1f3ed","house":"1f3e0","suburb":"1f3e1","houses":"1f3d8","derelict_house":"1f3da","condemned":"1f3da","office":"1f3e2","department_store":"1f3ec","japan_post":"1f3e3","post_office":"1f3e4","hospital":"1f3e5","bank":"1f3e6","hotel":"1f3e8","convenience_store":"1f3ea","school":"1f3eb","love_hotel":"1f3e9","wedding":"1f492","classical_building":"1f3db","church":"26ea","mosque":"1f54c","synagogue":"1f54d","kaaba":"1f54b","shinto_shrine":"26e9","japan":"1f5fe","moon_ceremony":"1f391","national_park":"1f3de","sunrise":"1f305","ocean_sunrise":"1f305","mountain_sunrise":"1f304","shooting_star":"1f320","wish":"1f320","sparkler":"1f387","fireworks":"1f386","city_sunrise":"1f307","sunset":"1f306","city":"1f3d9","skyline":"1f3d9","night":"1f303","milky_way":"1f30c","night_sky":"1f30c","bridge":"1f309","foggy":"1f301","watch":"231a","mobile_phone":"1f4f1","smartphone":"1f4f1","iphone":"1f4f1","android":"1f4f1","calling":"1f4f2","computer":"1f4bb","laptop":"1f4bb","keyboard":"2328","desktop_computer":"1f5a5","printer":"1f5a8","computer_mouse":"1f5b1","trackball":"1f5b2","joystick":"1f579","arcade":"1f579","compression":"1f5dc","vise":"1f5dc","gold_record":"1f4bd","minidisc":"1f4bd","floppy_disk":"1f4be","cd":"1f4bf","dvd":"1f4c0","vhs":"1f4fc","videocassette":"1f4fc","camera":"1f4f7","taking_a_picture":"1f4f8","say_cheese":"1f4f8","video_camera":"1f4f9","video_recorder":"1f4f9","movie_camera":"1f3a5","projector":"1f4fd","movie":"1f4fd","film":"1f39e","landline":"1f4de","home_phone":"1f4de","phone":"260e","telephone":"260e","pager":"1f4df","fax":"1f4e0","tv":"1f4fa","television":"1f4fa","radio":"1f4fb","studio_microphone":"1f399","volume":"1f39a","level_slider":"1f39a","control_knobs":"1f39b","stopwatch":"23f1","timer":"23f2","alarm_clock":"23f0","mantelpiece_clock":"1f570","times_up":"231b","hourglass_done":"231b","time_ticking":"23f3","hourglass":"23f3","satellite_antenna":"1f4e1","battery":"1f50b","full_battery":"1f50b","electric_plug":"1f50c","light_bulb":"1f4a1","bulb":"1f4a1","idea":"1f4a1","flashlight":"1f526","candle":"1f56f","wastebasket":"1f5d1","trash_can":"1f5d1","oil_drum":"1f6e2","commodities":"1f6e2","losing_money":"1f4b8","easy_come_easy_go":"1f4b8","money_with_wings":"1f4b8","dollar_bills":"1f4b5","yen_banknotes":"1f4b4","euro_banknotes":"1f4b6","pound_notes":"1f4b7","money":"1f4b0","credit_card":"1f4b3","debit_card":"1f4b3","gem":"1f48e","crystal":"1f48e","justice":"2696","scales":"2696","balance":"2696","fixing":"1f527","wrench":"1f527","hammer":"1f528","maintenance":"1f528","handyman":"1f528","handywoman":"1f528","at_work":"2692","hammer_and_pick":"2692","working_on_it":"1f6e0","hammer_and_wrench":"1f6e0","tools":"1f6e0","mine":"26cf","pick":"26cf","nut_and_bolt":"1f529","screw":"1f529","gear":"2699","settings":"2699","mechanical":"2699","engineer":"2699","chains":"26d3","gun":"1f52b","bomb":"1f4a3","knife":"1f52a","hocho":"1f52a","betrayed":"1f52a","dagger":"1f5e1","rated_for_violence":"1f5e1","duel":"2694","swords":"2694","shield":"1f6e1","smoking":"1f6ac","coffin":"26b0","burial":"26b0","grave":"26b0","funeral_urn":"26b1","cremation":"26b1","vase":"1f3fa","amphora":"1f3fa","crystal_ball":"1f52e","oracle":"1f52e","future":"1f52e","fortune_telling":"1f52e","prayer_beads":"1f4ff","barber":"1f488","striped_pole":"1f488","alchemy":"2697","alembic":"2697","telescope":"1f52d","science":"1f52c","microscope":"1f52c","scientist":"1f52c","hole":"1f573","medicine":"1f48a","pill":"1f48a","injection":"1f489","syringe":"1f489","temperature":"1f321","thermometer":"1f321","warm":"1f321","toilet":"1f6bd","potable_water":"1f6b0","tap_water":"1f6b0","drinking_water":"1f6b0","shower":"1f6bf","bathtub":"1f6c1","bath":"1f6c0","bellhop_bell":"1f6ce","reception":"1f6ce","services":"1f6ce","ding":"1f6ce","key":"1f511","secret":"1f5dd","dungeon":"1f5dd","old_key":"1f5dd","encrypted":"1f5dd","clue":"1f5dd","hint":"1f5dd","door":"1f6aa","living_room":"1f6cb","furniture":"1f6cb","couch_and_lamp":"1f6cb","lifestyles":"1f6cb","bed":"1f6cf","bedroom":"1f6cf","in_bed":"1f6cc","accommodations":"1f6cc","guestrooms":"1f6cc","picture":"1f5bc","framed_picture":"1f5bc","shopping_bags":"1f6cd","shopping_cart":"1f6d2","shopping_trolley":"1f6d2","gift":"1f381","present":"1f381","balloon":"1f388","celebration":"1f388","carp_streamer":"1f38f","flags":"1f38f","ribbon":"1f380","decoration":"1f380","confetti":"1f38a","party_ball":"1f38a","tada":"1f389","congratulations":"1f389","dolls":"1f38e","lantern":"1f3ee","izakaya_lantern":"1f3ee","wind_chime":"1f390","email":"2709","envelope":"2709","mail":"2709","mail_sent":"1f4e9","sealed":"1f4e9","mail_received":"1f4e8","e-mail":"1f4e7","love_letter":"1f48c","inbox":"1f4e5","outbox":"1f4e4","package":"1f4e6","label":"1f3f7","tag":"1f3f7","price_tag":"1f3f7","closed_mailbox":"1f4ea","mailbox":"1f4eb","unread_mail":"1f4ec","inbox_zero":"1f4ed","empty_mailbox":"1f4ed","no_mail":"1f4ed","mail_dropoff":"1f4ee","horn":"1f4ef","scroll":"1f4dc","receipt":"1f4c3","document":"1f4c4","paper":"1f4c4","file":"1f4c4","page":"1f4c4","place_holder":"1f4d1","bar_chart":"1f4ca","chart":"1f4c8","upwards_trend":"1f4c8","growing":"1f4c8","increasing":"1f4c8","downwards_trend":"1f4c9","shrinking":"1f4c9","decreasing":"1f4c9","spiral_notepad":"1f5d2","date":"1f4c6","calendar":"1f4c5","rolodex":"1f4c7","card_index":"1f4c7","archive":"1f5c3","ballot_box":"1f5f3","file_cabinet":"1f5c4","clipboard":"1f4cb","organize":"1f4c1","file_folder":"1f4c1","folder":"1f4c2","sort":"1f5c2","newspaper":"1f5de","swat":"1f5de","headlines":"1f4f0","notebook":"1f4d3","composition_book":"1f4d3","decorative_notebook":"1f4d4","ledger":"1f4d2","spiral_notebook":"1f4d2","red_book":"1f4d5","closed_book":"1f4d5","green_book":"1f4d7","blue_book":"1f4d8","orange_book":"1f4d9","books":"1f4da","book":"1f4d6","open_book":"1f4d6","bookmark":"1f516","link":"1f517","paperclip":"1f4ce","attachment":"1f4ce","office_supplies":"1f587","paperclip_chain":"1f587","linked":"1f587","carpenter_square":"1f4d0","triangular_ruler":"1f4d0","ruler":"1f4cf","straightedge":"1f4cf","push_pin":"1f4cc","thumb_tack":"1f4cc","pin":"1f4cd","sewing_pin":"1f4cd","scissors":"2702","pen":"1f58a","ballpoint_pen":"1f58a","fountain_pen":"1f58b","paintbrush":"1f58c","crayon":"1f58d","memo":"1f4dd","note":"1f4dd","pencil":"270f","search":"1f50d","find":"1f50d","magnifying_glass":"1f50d","privacy":"1f50f","key_signing":"1f50f","digital_security":"1f50f","protected":"1f50f","secure":"1f510","lock_with_key":"1f510","safe":"1f510","commitment":"1f510","loyalty":"1f510","locked":"1f512","unlocked":"1f513","heart":"2764","love":"2764","love_you":"2764","yellow_heart":"1f49b","heart_of_gold":"1f49b","green_heart":"1f49a","envy":"1f49a","blue_heart":"1f499","purple_heart":"1f49c","bravery":"1f49c","black_heart":"1f5a4","broken_heart":"1f494","heartache":"1f494","heart_exclamation":"2763","two_hearts":"1f495","revolving_hearts":"1f49e","heartbeat":"1f493","heart_pulse":"1f497","growing_heart":"1f497","sparkling_heart":"1f496","cupid":"1f498","smitten":"1f498","heart_arrow":"1f498","gift_heart":"1f49d","heart_box":"1f49f","peace":"262e","cross":"271d","christianity":"271d","star_and_crescent":"262a","islam":"262a","om":"1f549","hinduism":"1f549","wheel_of_dharma":"2638","buddhism":"2638","star_of_david":"2721","judiasm":"2721","menorah":"1f54e","yin_yang":"262f","orthodox_cross":"2626","place_of_worship":"1f6d0","ophiuchus":"26ce","aries":"2648","taurus":"2649","gemini":"264a","cancer":"264b","leo":"264c","virgo":"264d","libra":"264e","scorpius":"264f","sagittarius":"2650","capricorn":"2651","aquarius":"2652","pisces":"2653","id":"1f194","atom":"269b","physics":"269b","radioactive":"2622","nuclear":"2622","biohazard":"2623","phone_off":"1f4f4","vibration_mode":"1f4f3","eight_pointed_star":"2734","vs":"1f19a","white_flower":"1f4ae","a":"1f170","b":"1f171","ab":"1f18e","cl":"1f191","o":"1f17e","sos":"1f198","cross_mark":"274c","incorrect":"274c","wrong":"274c","circle":"2b55","stop_sign":"1f6d1","octagonal_sign":"1f6d1","no_entry":"26d4","wrong_way":"26d4","name_badge":"1f4db","prohibited":"1f6ab","not_allowed":"1f6ab","hundred":"1f4af","anger":"1f4a2","bam":"1f4a2","pow":"1f4a2","hot_springs":"2668","no_pedestrians":"1f6b7","do_not_litter":"1f6af","no_bicycles":"1f6b3","non-potable_water":"1f6b1","underage":"1f51e","nc17":"1f51e","no_phones":"1f4f5","no_smoking":"1f6ad","exclamation":"2757","grey_exclamation":"2755","question":"2753","grey_question":"2754","bangbang":"203c","double_exclamation":"203c","interrobang":"2049","low_brightness":"1f505","dim":"1f505","brightness":"1f506","high_brightness":"1f506","part_alternation":"303d","warning":"26a0","caution":"26a0","danger":"26a0","children_crossing":"1f6b8","school_crossing":"1f6b8","drive_with_care":"1f6b8","trident":"1f531","fleur_de_lis":"269c","beginner":"1f530","recycle":"267b","check":"2705","all_good":"2705","approved":"2705","stock_market":"1f4b9","sparkle":"2747","eight_spoked_asterisk":"2733","x":"274e","www":"1f310","globe":"1f310","cute":"1f4a0","kawaii":"1f4a0","diamond_with_a_dot":"1f4a0","metro":"24c2","m":"24c2","cyclone":"1f300","hurricane":"1f300","typhoon":"1f300","zzz":"1f4a4","atm":"1f3e7","wc":"1f6be","water_closet":"1f6be","accessible":"267f","wheelchair":"267f","disabled":"267f","parking":"1f17f","p":"1f17f","passport_control":"1f6c2","immigration":"1f6c2","customs":"1f6c3","baggage_claim":"1f6c4","locker":"1f6c5","locked_bag":"1f6c5","mens":"1f6b9","womens":"1f6ba","baby_change_station":"1f6bc","nursery":"1f6bc","restroom":"1f6bb","put_litter_in_its_place":"1f6ae","cinema":"1f3a6","movie_theater":"1f3a6","cell_reception":"1f4f6","signal_strength":"1f4f6","signal_bars":"1f4f6","symbols":"1f523","info":"2139","abc":"1f524","abcd":"1f521","alphabet":"1f521","capital_abcd":"1f520","capital_letters":"1f520","ng":"1f196","squared_ok":"1f197","squared_up":"1f199","cool":"1f192","new":"1f195","free":"1f193","zero":"0030-20e3","one":"0031-20e3","two":"0032-20e3","three":"0033-20e3","four":"0034-20e3","five":"0035-20e3","six":"0036-20e3","seven":"0037-20e3","eight":"0038-20e3","nine":"0039-20e3","ten":"1f51f","numbers":"1f522","hash":"0023-20e3","asterisk":"002a-20e3","play":"25b6","pause":"23f8","play_pause":"23ef","stop_button":"23f9","record":"23fa","next_track":"23ed","skip_forward":"23ed","previous_track":"23ee","skip_back":"23ee","fast_forward":"23e9","rewind":"23ea","fast_reverse":"23ea","double_up":"23eb","fast_up":"23eb","double_down":"23ec","fast_down":"23ec","play_reverse":"25c0","upvote":"1f53c","up_button":"1f53c","increase":"1f53c","downvote":"1f53d","down_button":"1f53d","decrease":"1f53d","right":"27a1","east":"27a1","left":"2b05","west":"2b05","up":"2b06","north":"2b06","down":"2b07","south":"2b07","upper_right":"2197","north_east":"2197","lower_right":"2198","south_east":"2198","lower_left":"2199","south_west":"2199","upper_left":"2196","north_west":"2196","up_down":"2195","left_right":"2194","swap":"2194","forward":"21aa","right_hook":"21aa","reply":"21a9","left_hook":"21a9","heading_up":"2934","heading_down":"2935","shuffle":"1f500","repeat":"1f501","repeat_one":"1f502","counterclockwise":"1f504","return":"1f504","clockwise":"1f503","music":"1f3b5","musical_notes":"1f3b6","plus":"2795","add":"2795","minus":"2796","subtract":"2796","division":"2797","divide":"2797","multiplication":"2716","multiply":"2716","dollars":"1f4b2","exchange":"1f4b1","tm":"2122","trademark":"2122","wavy_dash":"3030","loop":"27b0","double_loop":"27bf","voicemail":"27bf","end":"1f51a","back":"1f519","on":"1f51b","top":"1f51d","soon":"1f51c","check_mark":"2714","checkbox":"2611","radio_button":"1f518","white_circle":"26aa","black_circle":"26ab","red_circle":"1f534","blue_circle":"1f535","red_triangle_up":"1f53a","red_triangle_down":"1f53b","small_orange_diamond":"1f538","small_blue_diamond":"1f539","large_orange_diamond":"1f536","large_blue_diamond":"1f537","black_and_white_square":"1f533","white_and_black_square":"1f532","black_small_square":"25aa","white_small_square":"25ab","black_medium_small_square":"25fe","white_medium_small_square":"25fd","black_medium_square":"25fc","white_medium_square":"25fb","black_large_square":"2b1b","white_large_square":"2b1c","speaker":"1f508","mute":"1f507","no_sound":"1f507","softer":"1f509","louder":"1f50a","sound":"1f50a","notifications":"1f514","bell":"1f514","mute_notifications":"1f515","megaphone":"1f4e3","shout":"1f4e3","loudspeaker":"1f4e2","bullhorn":"1f4e2","umm":"1f4ac","speech_balloon":"1f4ac","speech_bubble":"1f5e8","thought":"1f4ad","dream":"1f4ad","anger_bubble":"1f5ef","spades":"2660","clubs":"2663","hearts":"2665","diamonds":"2666","joker":"1f0cf","playing_cards":"1f3b4","mahjong":"1f004","time":"1f557","clock":"1f557","white_flag":"1f3f3","surrender":"1f3f3","black_flag":"1f3f4","checkered_flag":"1f3c1","race":"1f3c1","go":"1f3c1","start":"1f3c1","triangular_flag":"1f6a9","crossed_flags":"1f38c","solidarity":"1f38c"},"codepoint_to_name":{"2049":"interrobang","2122":"tm","2139":"info","2194":"left_right","2195":"up_down","2196":"upper_left","2197":"upper_right","2198":"lower_right","2199":"lower_left","2328":"keyboard","2600":"sunny","2601":"cloud","2602":"umbrella","2603":"snowman","2604":"comet","2611":"checkbox","2614":"umbrella_with_rain","2615":"coffee","2618":"shamrock","2620":"skull_and_crossbones","2622":"radioactive","2623":"biohazard","2626":"orthodox_cross","2638":"wheel_of_dharma","2639":"sad","2648":"aries","2649":"taurus","2650":"sagittarius","2651":"capricorn","2652":"aquarius","2653":"pisces","2660":"spades","2663":"clubs","2665":"hearts","2666":"diamonds","2668":"hot_springs","2692":"at_work","2693":"anchor","2694":"duel","2696":"justice","2697":"alchemy","2699":"gear","2702":"scissors","2705":"check","2708":"airplane","2709":"email","2714":"check_mark","2716":"multiplication","2721":"star_of_david","2728":"sparkles","2733":"eight_spoked_asterisk","2734":"eight_pointed_star","2744":"snowflake","2747":"sparkle","2753":"question","2754":"grey_question","2755":"grey_exclamation","2757":"exclamation","2763":"heart_exclamation","2764":"heart","2795":"plus","2796":"minus","2797":"division","2934":"heading_up","2935":"heading_down","3030":"wavy_dash","1f600":"grinning","1f603":"smiley","1f604":"big_smile","1f601":"grinning_face_with_smiling_eyes","1f606":"laughing","1f605":"sweat_smile","1f602":"joy","1f923":"rolling_on_the_floor_laughing","263a":"smiling_face","1f60a":"blush","1f607":"innocent","1f642":"smile","1f643":"upside_down","1f609":"wink","1f60c":"relieved","1f60d":"heart_eyes","1f618":"heart_kiss","1f617":"kiss","1f619":"kiss_smiling_eyes","1f61a":"kiss_with_blush","1f60b":"yum","1f61b":"stuck_out_tongue","1f61c":"stuck_out_tongue_wink","1f61d":"stuck_out_tongue_closed_eyes","1f911":"money_face","1f917":"hug","1f913":"nerd","1f60e":"sunglasses","1f921":"clown","1f920":"cowboy","1f60f":"smirk","1f612":"unamused","1f61e":"disappointed","1f614":"pensive","1f61f":"worried","1f615":"oh_no","1f641":"frown","1f623":"persevere","1f616":"confounded","1f62b":"anguish","1f629":"weary","1f624":"triumph","1f620":"angry","1f621":"rage","1f636":"speechless","1f610":"neutral","1f611":"expressionless","1f62f":"hushed","1f626":"frowning","1f627":"anguished","1f62e":"open_mouth","1f632":"astonished","1f635":"dizzy","1f633":"flushed","1f631":"scream","1f628":"fear","1f630":"cold_sweat","1f622":"cry","1f625":"exhausted","1f924":"drooling","1f62d":"sob","1f613":"sweat","1f62a":"sleepy","1f634":"sleeping","1f644":"rolling_eyes","1f914":"thinking","1f925":"lying","1f62c":"grimacing","1f910":"silence","1f922":"nauseated","1f927":"sneezing","1f637":"mask","1f912":"sick","1f915":"hurt","1f608":"smiling_devil","1f47f":"devil","1f479":"ogre","1f47a":"goblin","1f4a9":"poop","1f47b":"ghost","1f480":"skull","1f47d":"alien","1f47e":"space_invader","1f916":"robot","1f383":"jack-o-lantern","1f63a":"smiley_cat","1f638":"smile_cat","1f639":"joy_cat","1f63b":"heart_eyes_cat","1f63c":"smirk_cat","1f63d":"kissing_cat","1f640":"scream_cat","1f63f":"crying_cat","1f63e":"angry_cat","1f450":"open_hands","1f64c":"raised_hands","1f44f":"clap","1f64f":"pray","1f91d":"handshake","1f44d":"+1","1f44e":"-1","1f44a":"fist_bump","270a":"fist","1f91b":"left_fist","1f91c":"right_fist","1f91e":"fingers_crossed","270c":"peace_sign","1f918":"rock_on","1f44c":"ok","1f448":"point_left","1f449":"point_right","1f446":"point_up","1f447":"point_down","261d":"wait_one_second","270b":"hand","1f91a":"stop","1f590":"high_five","1f596":"spock","1f44b":"wave","1f919":"call_me","1f4aa":"muscle","1f595":"middle_finger","270d":"writing","1f933":"selfie","1f485":"nail_polish","1f48d":"ring","1f484":"lipstick","1f48b":"lipstick_kiss","1f444":"lips","1f445":"tongue","1f442":"ear","1f443":"nose","1f463":"footprints","1f441":"eye","1f440":"eyes","1f5e3":"speaking_head","1f464":"silhouette","1f465":"silhouettes","1f476":"baby","1f466":"boy","1f467":"girl","1f468":"man","1f469":"woman","1f474":"older_man","1f475":"older_woman","1f472":"gua_pi_mao","1f473":"turban","1f46e":"police","1f477":"construction_worker","1f482":"guard","1f575":"detective","1f936":"mother_christmas","1f385":"santa","1f478":"princess","1f934":"prince","1f470":"bride","1f935":"tuxedo","1f47c":"angel","1f930":"pregnant","1f647":"bow","1f481":"information_desk_person","1f645":"no_signal","1f646":"ok_signal","1f64b":"raising_hand","1f926":"face_palm","1f937":"shrug","1f64e":"person_pouting","1f64d":"person_frowning","1f487":"haircut","1f486":"massage","1f574":"levitating","1f483":"dancer","1f57a":"dancing","1f46f":"dancers","1f6b6":"walking","1f3c3":"running","1f46b":"man_and_woman_holding_hands","1f46d":"two_women_holding_hands","1f46c":"two_men_holding_hands","1f46a":"family","1f45a":"clothing","1f455":"shirt","1f456":"jeans","1f454":"tie","1f457":"dress","1f459":"bikini","1f458":"kimono","1f460":"high_heels","1f461":"sandal","1f462":"boot","1f45e":"shoe","1f45f":"athletic_shoe","1f452":"hat","1f3a9":"top_hat","1f393":"graduate","1f451":"crown","26d1":"helmet","1f392":"backpack","1f45d":"pouch","1f45b":"purse","1f45c":"handbag","1f4bc":"briefcase","1f453":"glasses","1f576":"dark_sunglasses","1f302":"closed_umbrella","1f436":"puppy","1f431":"kitten","1f42d":"dormouse","1f439":"hamster","1f430":"bunny","1f98a":"fox","1f43b":"bear","1f43c":"panda","1f428":"koala","1f42f":"tiger_cub","1f981":"lion","1f42e":"calf","1f437":"piglet","1f43d":"pig_nose","1f438":"frog","1f435":"monkey_face","1f648":"see_no_evil","1f649":"hear_no_evil","1f64a":"speak_no_evil","1f412":"monkey","1f414":"chicken","1f427":"penguin","1f426":"bird","1f424":"chick","1f423":"hatching","1f425":"new_baby","1f986":"duck","1f985":"eagle","1f989":"owl","1f987":"bat","1f43a":"wolf","1f417":"boar","1f434":"pony","1f984":"unicorn","1f41d":"bee","1f41b":"bug","1f98b":"butterfly","1f40c":"snail","1f41a":"shell","1f41e":"beetle","1f41c":"ant","1f577":"spider","1f578":"web","1f422":"turtle","1f40d":"snake","1f98e":"lizard","1f982":"scorpion","1f980":"crab","1f991":"squid","1f419":"octopus","1f990":"shrimp","1f420":"tropical_fish","1f41f":"fish","1f421":"blowfish","1f42c":"dolphin","1f988":"shark","1f433":"whale","1f40b":"humpback_whale","1f40a":"crocodile","1f406":"leopard","1f405":"tiger","1f403":"water_buffalo","1f402":"ox","1f404":"cow","1f98c":"deer","1f42a":"arabian_camel","1f42b":"camel","1f418":"elephant","1f98f":"rhinoceros","1f98d":"gorilla","1f40e":"horse","1f416":"pig","1f410":"goat","1f40f":"ram","1f411":"sheep","1f415":"dog","1f429":"poodle","1f408":"cat","1f413":"rooster","1f983":"turkey","1f54a":"dove","1f407":"rabbit","1f401":"mouse","1f400":"rat","1f43f":"chipmunk","1f43e":"paw_prints","1f409":"dragon","1f432":"dragon_face","1f335":"cactus","1f384":"holiday_tree","1f332":"evergreen_tree","1f333":"tree","1f334":"palm_tree","1f331":"seedling","1f33f":"herb","1f340":"lucky","1f38d":"bamboo","1f38b":"wish_tree","1f343":"leaves","1f342":"fallen_leaf","1f341":"maple_leaf","1f344":"mushroom","1f33e":"harvest","1f490":"bouquet","1f337":"tulip","1f339":"rose","1f940":"wilted_flower","1f33b":"sunflower","1f33c":"blossom","1f338":"cherry_blossom","1f33a":"hibiscus","1f30e":"earth_americas","1f30d":"earth_africa","1f30f":"earth_asia","1f315":"full_moon","1f311":"new_moon","1f314":"waxing_moon","1f31a":"new_moon_face","1f31d":"moon_face","1f31e":"sun_face","1f31b":"goodnight","1f319":"moon","1f4ab":"seeing_stars","2b50":"star","1f31f":"glowing_star","26a1":"high_voltage","1f525":"fire","1f4a5":"boom","1f324":"mostly_sunny","26c5":"partly_sunny","1f325":"cloudy","1f326":"sunshowers","1f308":"rainbow","1f327":"rainy","26c8":"thunderstorm","1f329":"lightning","1f328":"snowy","26c4":"frosty","1f32c":"windy","1f4a8":"dash","1f32a":"tornado","1f32b":"fog","1f30a":"ocean","1f4a7":"drop","1f4a6":"sweat_drops","1f34f":"green_apple","1f34e":"apple","1f350":"pear","1f34a":"orange","1f34b":"lemon","1f34c":"banana","1f349":"watermelon","1f347":"grapes","1f353":"strawberry","1f348":"melon","1f352":"cherries","1f351":"peach","1f34d":"pineapple","1f95d":"kiwi","1f951":"avocado","1f345":"tomato","1f346":"eggplant","1f952":"cucumber","1f955":"carrot","1f33d":"corn","1f336":"hot_pepper","1f954":"potato","1f360":"yam","1f330":"chestnut","1f95c":"peanuts","1f36f":"honey","1f950":"croissant","1f35e":"bread","1f956":"baguette","1f9c0":"cheese","1f95a":"egg","1f373":"cooking","1f953":"bacon","1f95e":"pancakes","1f364":"tempura","1f357":"drumstick","1f356":"meat","1f355":"pizza","1f32d":"hotdog","1f354":"hamburger","1f35f":"fries","1f959":"doner_kebab","1f32e":"taco","1f32f":"burrito","1f957":"salad","1f958":"paella","1f35d":"spaghetti","1f35c":"ramen","1f372":"food","1f365":"naruto","1f363":"sushi","1f371":"bento","1f35b":"curry","1f35a":"rice","1f359":"onigiri","1f358":"senbei","1f362":"oden","1f361":"dango","1f367":"shaved_ice","1f368":"ice_cream","1f366":"soft_serve","1f370":"cake","1f382":"birthday","1f36e":"custard","1f36d":"lollipop","1f36c":"candy","1f36b":"chocolate","1f37f":"popcorn","1f369":"donut","1f36a":"cookie","1f95b":"milk","1f37c":"baby_bottle","1f375":"tea","1f376":"sake","1f37a":"beer","1f37b":"beers","1f942":"clink","1f377":"wine","1f943":"small_glass","1f378":"cocktail","1f379":"tropical_drink","1f37e":"champagne","1f944":"spoon","1f374":"fork_and_knife","1f37d":"hungry","26bd":"football","1f3c0":"basketball","1f3c8":"american_football","26be":"baseball","1f3be":"tennis","1f3d0":"volleyball","1f3c9":"rugby","1f3b1":"billiards","1f3d3":"ping_pong","1f3f8":"badminton","1f945":"gooooooooal","1f3d2":"ice_hockey","1f3d1":"field_hockey","1f3cf":"cricket","26f3":"hole_in_one","1f3f9":"bow_and_arrow","1f3a3":"fishing","1f94a":"boxing_glove","1f94b":"black_belt","26f8":"ice_skate","1f3bf":"ski","26f7":"skier","1f3c2":"snowboarder","1f3cb":"lift","1f93a":"fencing","1f93c":"wrestling","1f938":"cartwheel","26f9":"ball","1f93e":"handball","1f3cc":"golf","1f3c4":"surf","1f3ca":"swim","1f93d":"water_polo","1f6a3":"rowboat","1f3c7":"horse_racing","1f6b4":"cyclist","1f6b5":"mountain_biker","1f3bd":"running_shirt","1f3c5":"medal","1f396":"military_medal","1f947":"first_place","1f948":"second_place","1f949":"third_place","1f3c6":"trophy","1f3f5":"rosette","1f397":"reminder_ribbon","1f3ab":"pass","1f39f":"ticket","1f3aa":"circus","1f939":"juggling","1f3ad":"performing_arts","1f3a8":"art","1f3ac":"action","1f3a4":"microphone","1f3a7":"headphones","1f3bc":"musical_score","1f3b9":"piano","1f941":"drum","1f3b7":"saxophone","1f3ba":"trumpet","1f3b8":"guitar","1f3bb":"violin","1f3b2":"dice","1f3af":"direct_hit","1f3b3":"strike","1f3ae":"video_game","1f3b0":"slot_machine","1f697":"car","1f695":"taxi","1f699":"recreational_vehicle","1f68c":"bus","1f68e":"trolley","1f3ce":"racecar","1f693":"police_car","1f691":"ambulance","1f692":"fire_truck","1f690":"minibus","1f69a":"moving_truck","1f69b":"truck","1f69c":"tractor","1f6f4":"kick_scooter","1f6b2":"bike","1f6f5":"scooter","1f3cd":"motorcycle","1f6a8":"siren","1f694":"oncoming_police_car","1f68d":"oncoming_bus","1f698":"oncoming_car","1f696":"oncoming_taxi","1f6a1":"aerial_tramway","1f6a0":"gondola","1f69f":"suspension_railway","1f683":"railway_car","1f68b":"tram","1f69e":"mountain_railway","1f69d":"monorail","1f684":"high_speed_train","1f685":"bullet_train","1f688":"light_rail","1f682":"train","1f686":"oncoming_train","1f687":"subway","1f68a":"oncoming_tram","1f689":"station","1f681":"helicopter","1f6e9":"small_airplane","1f6eb":"take_off","1f6ec":"landing","1f680":"rocket","1f6f0":"satellite","1f4ba":"seat","1f6f6":"canoe","26f5":"boat","1f6e5":"motor_boat","1f6a4":"speedboat","1f6f3":"passenger_ship","26f4":"ferry","1f6a2":"ship","1f6a7":"work_in_progress","26fd":"fuel_pump","1f68f":"bus_stop","1f6a6":"traffic_light","1f6a5":"horizontal_traffic_light","1f5fa":"map","1f5ff":"rock_carving","1f5fd":"statue","26f2":"fountain","1f5fc":"tower","1f3f0":"castle","1f3ef":"shiro","1f3df":"stadium","1f3a1":"ferris_wheel","1f3a2":"roller_coaster","1f3a0":"carousel","26f1":"beach_umbrella","1f3d6":"beach","1f3dd":"island","26f0":"mountain","1f3d4":"snowy_mountain","1f5fb":"mount_fuji","1f30b":"volcano","1f3dc":"desert","1f3d5":"campsite","26fa":"tent","1f6e4":"railway_track","1f6e3":"road","1f3d7":"construction","1f3ed":"factory","1f3e0":"house","1f3e1":"suburb","1f3d8":"houses","1f3da":"derelict_house","1f3e2":"office","1f3ec":"department_store","1f3e3":"japan_post","1f3e4":"post_office","1f3e5":"hospital","1f3e6":"bank","1f3e8":"hotel","1f3ea":"convenience_store","1f3eb":"school","1f3e9":"love_hotel","1f492":"wedding","1f3db":"classical_building","26ea":"church","1f54c":"mosque","1f54d":"synagogue","1f54b":"kaaba","26e9":"shinto_shrine","1f5fe":"japan","1f391":"moon_ceremony","1f3de":"national_park","1f305":"sunrise","1f304":"mountain_sunrise","1f320":"shooting_star","1f387":"sparkler","1f386":"fireworks","1f307":"city_sunrise","1f306":"sunset","1f3d9":"city","1f303":"night","1f30c":"milky_way","1f309":"bridge","1f301":"foggy","231a":"watch","1f4f1":"mobile_phone","1f4f2":"calling","1f4bb":"computer","1f5a5":"desktop_computer","1f5a8":"printer","1f5b1":"computer_mouse","1f5b2":"trackball","1f579":"joystick","1f5dc":"compression","1f4bd":"gold_record","1f4be":"floppy_disk","1f4bf":"cd","1f4c0":"dvd","1f4fc":"vhs","1f4f7":"camera","1f4f8":"taking_a_picture","1f4f9":"video_camera","1f3a5":"movie_camera","1f4fd":"projector","1f39e":"film","1f4de":"landline","260e":"phone","1f4df":"pager","1f4e0":"fax","1f4fa":"tv","1f4fb":"radio","1f399":"studio_microphone","1f39a":"volume","1f39b":"control_knobs","23f1":"stopwatch","23f2":"timer","23f0":"alarm_clock","1f570":"mantelpiece_clock","231b":"times_up","23f3":"time_ticking","1f4e1":"satellite_antenna","1f50b":"battery","1f50c":"electric_plug","1f4a1":"light_bulb","1f526":"flashlight","1f56f":"candle","1f5d1":"wastebasket","1f6e2":"oil_drum","1f4b8":"losing_money","1f4b5":"dollar_bills","1f4b4":"yen_banknotes","1f4b6":"euro_banknotes","1f4b7":"pound_notes","1f4b0":"money","1f4b3":"credit_card","1f48e":"gem","1f527":"fixing","1f528":"hammer","1f6e0":"working_on_it","26cf":"mine","1f529":"nut_and_bolt","26d3":"chains","1f52b":"gun","1f4a3":"bomb","1f52a":"knife","1f5e1":"dagger","1f6e1":"shield","1f6ac":"smoking","26b0":"coffin","26b1":"funeral_urn","1f3fa":"vase","1f52e":"crystal_ball","1f4ff":"prayer_beads","1f488":"barber","1f52d":"telescope","1f52c":"science","1f573":"hole","1f48a":"medicine","1f489":"injection","1f321":"temperature","1f6bd":"toilet","1f6b0":"potable_water","1f6bf":"shower","1f6c1":"bathtub","1f6c0":"bath","1f6ce":"bellhop_bell","1f511":"key","1f5dd":"secret","1f6aa":"door","1f6cb":"living_room","1f6cf":"bed","1f6cc":"in_bed","1f5bc":"picture","1f6cd":"shopping_bags","1f6d2":"shopping_cart","1f381":"gift","1f388":"balloon","1f38f":"carp_streamer","1f380":"ribbon","1f38a":"confetti","1f389":"tada","1f38e":"dolls","1f3ee":"lantern","1f390":"wind_chime","1f4e9":"mail_sent","1f4e8":"mail_received","1f4e7":"e-mail","1f48c":"love_letter","1f4e5":"inbox","1f4e4":"outbox","1f4e6":"package","1f3f7":"label","1f4ea":"closed_mailbox","1f4eb":"mailbox","1f4ec":"unread_mail","1f4ed":"inbox_zero","1f4ee":"mail_dropoff","1f4ef":"horn","1f4dc":"scroll","1f4c3":"receipt","1f4c4":"document","1f4d1":"place_holder","1f4ca":"bar_chart","1f4c8":"chart","1f4c9":"downwards_trend","1f5d2":"spiral_notepad","1f4c6":"date","1f4c5":"calendar","1f4c7":"rolodex","1f5c3":"archive","1f5f3":"ballot_box","1f5c4":"file_cabinet","1f4cb":"clipboard","1f4c1":"organize","1f4c2":"folder","1f5c2":"sort","1f5de":"newspaper","1f4f0":"headlines","1f4d3":"notebook","1f4d4":"decorative_notebook","1f4d2":"ledger","1f4d5":"red_book","1f4d7":"green_book","1f4d8":"blue_book","1f4d9":"orange_book","1f4da":"books","1f4d6":"book","1f516":"bookmark","1f517":"link","1f4ce":"paperclip","1f587":"office_supplies","1f4d0":"carpenter_square","1f4cf":"ruler","1f4cc":"push_pin","1f4cd":"pin","1f58a":"pen","1f58b":"fountain_pen","1f58c":"paintbrush","1f58d":"crayon","1f4dd":"memo","270f":"pencil","1f50d":"search","1f50f":"privacy","1f510":"secure","1f512":"locked","1f513":"unlocked","1f49b":"yellow_heart","1f49a":"green_heart","1f499":"blue_heart","1f49c":"purple_heart","1f5a4":"black_heart","1f494":"broken_heart","1f495":"two_hearts","1f49e":"revolving_hearts","1f493":"heartbeat","1f497":"heart_pulse","1f496":"sparkling_heart","1f498":"cupid","1f49d":"gift_heart","1f49f":"heart_box","262e":"peace","271d":"cross","262a":"star_and_crescent","1f549":"om","1f54e":"menorah","262f":"yin_yang","1f6d0":"place_of_worship","26ce":"ophiuchus","264a":"gemini","264b":"cancer","264c":"leo","264d":"virgo","264e":"libra","264f":"scorpius","1f194":"id","269b":"atom","1f4f4":"phone_off","1f4f3":"vibration_mode","1f19a":"vs","1f4ae":"white_flower","1f170":"a","1f171":"b","1f18e":"ab","1f191":"cl","1f17e":"o","1f198":"sos","274c":"cross_mark","2b55":"circle","1f6d1":"stop_sign","26d4":"no_entry","1f4db":"name_badge","1f6ab":"prohibited","1f4af":"100","1f4a2":"anger","1f6b7":"no_pedestrians","1f6af":"do_not_litter","1f6b3":"no_bicycles","1f6b1":"non-potable_water","1f51e":"underage","1f4f5":"no_phones","1f6ad":"no_smoking","203c":"bangbang","1f505":"low_brightness","1f506":"brightness","303d":"part_alternation","26a0":"warning","1f6b8":"children_crossing","1f531":"trident","269c":"fleur_de_lis","1f530":"beginner","267b":"recycle","1f4b9":"stock_market","274e":"x","1f310":"www","1f4a0":"cute","24c2":"metro","1f300":"cyclone","1f4a4":"zzz","1f3e7":"atm","1f6be":"wc","267f":"accessible","1f17f":"parking","1f6c2":"passport_control","1f6c3":"customs","1f6c4":"baggage_claim","1f6c5":"locker","1f6b9":"mens","1f6ba":"womens","1f6bc":"baby_change_station","1f6bb":"restroom","1f6ae":"put_litter_in_its_place","1f3a6":"cinema","1f4f6":"cell_reception","1f523":"symbols","1f524":"abc","1f521":"abcd","1f520":"capital_abcd","1f196":"ng","1f197":"squared_ok","1f199":"squared_up","1f192":"cool","1f195":"new","1f193":"free","0030-20e3":"zero","0031-20e3":"one","0032-20e3":"two","0033-20e3":"three","0034-20e3":"four","0035-20e3":"five","0036-20e3":"six","0037-20e3":"seven","0038-20e3":"eight","0039-20e3":"nine","1f51f":"ten","1f522":"1234","0023-20e3":"hash","002a-20e3":"asterisk","25b6":"play","23f8":"pause","23ef":"play_pause","23f9":"stop_button","23fa":"record","23ed":"next_track","23ee":"previous_track","23e9":"fast_forward","23ea":"rewind","23eb":"double_up","23ec":"double_down","25c0":"play_reverse","1f53c":"upvote","1f53d":"downvote","27a1":"right","2b05":"left","2b06":"up","2b07":"down","21aa":"forward","21a9":"reply","1f500":"shuffle","1f501":"repeat","1f502":"repeat_one","1f504":"counterclockwise","1f503":"clockwise","1f3b5":"music","1f3b6":"musical_notes","1f4b2":"dollars","1f4b1":"exchange","27b0":"loop","27bf":"double_loop","1f51a":"end","1f519":"back","1f51b":"on","1f51d":"top","1f51c":"soon","1f518":"radio_button","26aa":"white_circle","26ab":"black_circle","1f534":"red_circle","1f535":"blue_circle","1f53a":"red_triangle_up","1f53b":"red_triangle_down","1f538":"small_orange_diamond","1f539":"small_blue_diamond","1f536":"large_orange_diamond","1f537":"large_blue_diamond","1f533":"black_and_white_square","1f532":"white_and_black_square","25aa":"black_small_square","25ab":"white_small_square","25fe":"black_medium_small_square","25fd":"white_medium_small_square","25fc":"black_medium_square","25fb":"white_medium_square","2b1b":"black_large_square","2b1c":"white_large_square","1f508":"speaker","1f507":"mute","1f509":"softer","1f50a":"louder","1f514":"notifications","1f515":"mute_notifications","1f4e3":"megaphone","1f4e2":"loudspeaker","1f4ac":"umm","1f5e8":"speech_bubble","1f4ad":"thought","1f5ef":"anger_bubble","1f0cf":"joker","1f3b4":"playing_cards","1f004":"mahjong","1f557":"time","1f3f3":"white_flag","1f3f4":"black_flag","1f3c1":"checkered_flag","1f6a9":"triangular_flag","1f38c":"crossed_flags"},"emoji_catalog":{"Symbols":["1f3e7","1f6ae","1f6b0","267f","1f6b9","1f6ba","1f6bb","1f6bc","1f6be","1f6c2","1f6c3","1f6c4","1f6c5","26a0","1f6b8","26d4","1f6ab","1f6b3","1f6ad","1f6af","1f6b1","1f6b7","1f4f5","1f51e","2622","2623","2b06","2197","27a1","2198","2b07","2199","2b05","2196","2195","2194","21a9","21aa","2934","2935","1f503","1f504","1f519","1f51a","1f51b","1f51c","1f51d","1f6d0","269b","1f549","2721","2638","262f","271d","2626","262a","262e","1f54e","2648","2649","264a","264b","264c","264d","264e","264f","2650","2651","2652","2653","26ce","1f500","1f501","1f502","25b6","23e9","23ed","23ef","25c0","23ea","23ee","1f53c","23eb","1f53d","23ec","23f8","23f9","23fa","1f3a6","1f505","1f506","1f4f6","1f4f3","1f4f4","2716","2795","2796","2797","203c","2049","2753","2754","2755","2757","3030","1f4b1","1f4b2","267b","269c","1f531","1f4db","1f530","2b55","2705","2611","2714","274c","274e","27b0","27bf","303d","2733","2734","2747","2122","0023-20e3","002a-20e3","0030-20e3","0031-20e3","0032-20e3","0033-20e3","0034-20e3","0035-20e3","0036-20e3","0037-20e3","0038-20e3","0039-20e3","1f51f","1f520","1f521","1f522","1f523","1f524","1f170","1f18e","1f171","1f191","1f192","1f193","2139","1f194","24c2","1f195","1f196","1f17e","1f197","1f17f","1f198","1f199","1f19a","1f534","1f535","26ab","26aa","2b1b","2b1c","25fc","25fb","25fe","25fd","25aa","25ab","1f536","1f537","1f538","1f539","1f53a","1f53b","1f4a0","1f518","1f533","1f532"],"Activities":["1f383","1f384","1f386","1f387","2728","1f388","1f389","1f38a","1f38b","1f38d","1f38e","1f38f","1f390","1f391","1f380","1f381","1f397","1f39f","1f3ab","1f396","1f3c6","1f3c5","1f947","1f948","1f949","26bd","26be","1f3c0","1f3d0","1f3c8","1f3c9","1f3be","1f3b3","1f3cf","1f3d1","1f3d2","1f3d3","1f3f8","1f94a","1f94b","1f945","26f3","26f8","1f3a3","1f3bd","1f3bf","1f3af","1f3b1","1f52e","1f3ae","1f579","1f3b0","1f3b2","2660","2665","2666","2663","1f0cf","1f004","1f3b4","1f3ad","1f5bc","1f3a8"],"Travel & Places":["1f30d","1f30e","1f30f","1f310","1f5fa","1f5fe","1f3d4","26f0","1f30b","1f5fb","1f3d5","1f3d6","1f3dc","1f3dd","1f3de","1f3df","1f3db","1f3d7","1f3d8","1f3da","1f3e0","1f3e1","1f3e2","1f3e3","1f3e4","1f3e5","1f3e6","1f3e8","1f3e9","1f3ea","1f3eb","1f3ec","1f3ed","1f3ef","1f3f0","1f492","1f5fc","1f5fd","26ea","1f54c","1f54d","26e9","1f54b","26f2","26fa","1f301","1f303","1f3d9","1f304","1f305","1f306","1f307","1f309","2668","1f3a0","1f3a1","1f3a2","1f488","1f3aa","1f682","1f683","1f684","1f685","1f686","1f687","1f688","1f689","1f68a","1f69d","1f69e","1f68b","1f68c","1f68d","1f68e","1f690","1f691","1f692","1f693","1f694","1f695","1f696","1f697","1f698","1f699","1f69a","1f69b","1f69c","1f3ce","1f3cd","1f6f5","1f6b2","1f6f4","1f68f","1f6e3","1f6e4","1f6e2","26fd","1f6a8","1f6a5","1f6a6","1f6d1","1f6a7","2693","26f5","1f6f6","1f6a4","1f6f3","26f4","1f6e5","1f6a2","2708","1f6e9","1f6eb","1f6ec","1f4ba","1f681","1f69f","1f6a0","1f6a1","1f6f0","1f680","1f6ce","231b","23f3","231a","23f0","23f1","23f2","1f570","1f557","1f311","1f314","1f315","1f319","1f31a","1f31b","1f321","2600","1f31d","1f31e","2b50","1f31f","1f320","1f30c","2601","26c5","26c8","1f324","1f325","1f326","1f327","1f328","1f329","1f32a","1f32b","1f32c","1f300","1f308","1f302","2602","2614","26f1","26a1","2744","2603","26c4","2604","1f525","1f4a7","1f30a"],"Food & Drink":["1f347","1f348","1f349","1f34a","1f34b","1f34c","1f34d","1f34e","1f34f","1f350","1f351","1f352","1f353","1f95d","1f345","1f951","1f346","1f954","1f955","1f33d","1f336","1f952","1f344","1f95c","1f330","1f35e","1f950","1f956","1f95e","1f9c0","1f356","1f357","1f953","1f354","1f35f","1f355","1f32d","1f32e","1f32f","1f959","1f95a","1f373","1f958","1f372","1f957","1f37f","1f371","1f358","1f359","1f35a","1f35b","1f35c","1f35d","1f360","1f362","1f363","1f364","1f365","1f361","1f980","1f990","1f991","1f366","1f367","1f368","1f369","1f36a","1f382","1f370","1f36b","1f36c","1f36d","1f36e","1f36f","1f37c","1f95b","2615","1f375","1f376","1f37e","1f377","1f378","1f379","1f37a","1f37b","1f942","1f943","1f37d","1f374","1f944","1f52a","1f3fa"],"Animals & Nature":["1f435","1f412","1f98d","1f436","1f415","1f429","1f43a","1f98a","1f431","1f408","1f981","1f42f","1f405","1f406","1f434","1f40e","1f984","1f98c","1f42e","1f402","1f403","1f404","1f437","1f416","1f417","1f43d","1f40f","1f411","1f410","1f42a","1f42b","1f418","1f98f","1f42d","1f401","1f400","1f439","1f430","1f407","1f43f","1f987","1f43b","1f428","1f43c","1f43e","1f983","1f414","1f413","1f423","1f424","1f425","1f426","1f427","1f54a","1f985","1f986","1f989","1f438","1f40a","1f422","1f98e","1f40d","1f432","1f409","1f433","1f40b","1f42c","1f41f","1f420","1f421","1f988","1f419","1f41a","1f40c","1f98b","1f41b","1f41c","1f41d","1f41e","1f577","1f578","1f982","1f490","1f338","1f4ae","1f3f5","1f339","1f940","1f33a","1f33b","1f33c","1f337","1f331","1f332","1f333","1f334","1f335","1f33e","1f33f","2618","1f340","1f341","1f342","1f343"],"People & Body":["1f44b","1f91a","1f590","270b","1f596","1f44c","270c","1f91e","1f918","1f919","1f448","1f449","1f446","1f595","1f447","261d","1f44d","1f44e","270a","1f44a","1f91b","1f91c","1f44f","1f64c","1f450","1f91d","1f64f","270d","1f485","1f933","1f4aa","1f442","1f443","1f440","1f441","1f445","1f444","1f476","1f466","1f467","1f468","1f469","1f474","1f475","1f64d","1f64e","1f645","1f646","1f481","1f64b","1f647","1f926","1f937","1f46e","1f575","1f482","1f477","1f934","1f478","1f473","1f472","1f935","1f470","1f930","1f47c","1f385","1f936","1f486","1f487","1f6b6","1f3c3","1f483","1f57a","1f574","1f46f","1f93a","1f3c7","26f7","1f3c2","1f3cc","1f3c4","1f6a3","1f3ca","26f9","1f3cb","1f6b4","1f6b5","1f938","1f93c","1f93d","1f93e","1f939","1f6c0","1f6cc","1f46d","1f46b","1f46c","1f46a","1f5e3","1f464","1f465","1f463"],"Flags":["1f3c1","1f6a9","1f38c","1f3f4","1f3f3"],"Objects":["1f453","1f576","1f454","1f455","1f456","1f457","1f458","1f459","1f45a","1f45b","1f45c","1f45d","1f6cd","1f392","1f45e","1f45f","1f460","1f461","1f462","1f451","1f452","1f3a9","1f393","26d1","1f4ff","1f484","1f48d","1f48e","1f507","1f508","1f509","1f50a","1f4e2","1f4e3","1f4ef","1f514","1f515","1f3bc","1f3b5","1f3b6","1f399","1f39a","1f39b","1f3a4","1f3a7","1f4fb","1f3b7","1f3b8","1f3b9","1f3ba","1f3bb","1f941","1f4f1","1f4f2","260e","1f4de","1f4df","1f4e0","1f50b","1f50c","1f4bb","1f5a5","1f5a8","2328","1f5b1","1f5b2","1f4bd","1f4be","1f4bf","1f4c0","1f3a5","1f39e","1f4fd","1f3ac","1f4fa","1f4f7","1f4f8","1f4f9","1f4fc","1f50d","1f56f","1f4a1","1f526","1f3ee","1f4d4","1f4d5","1f4d6","1f4d7","1f4d8","1f4d9","1f4da","1f4d3","1f4d2","1f4c3","1f4dc","1f4c4","1f4f0","1f5de","1f4d1","1f516","1f3f7","1f4b0","1f4b4","1f4b5","1f4b6","1f4b7","1f4b8","1f4b3","1f4b9","2709","1f4e7","1f4e8","1f4e9","1f4e4","1f4e5","1f4e6","1f4eb","1f4ea","1f4ec","1f4ed","1f4ee","1f5f3","270f","1f58b","1f58a","1f58c","1f58d","1f4dd","1f4bc","1f4c1","1f4c2","1f5c2","1f4c5","1f4c6","1f5d2","1f4c7","1f4c8","1f4c9","1f4ca","1f4cb","1f4cc","1f4cd","1f4ce","1f587","1f4cf","1f4d0","2702","1f5c3","1f5c4","1f5d1","1f512","1f513","1f50f","1f510","1f511","1f5dd","1f528","26cf","2692","1f6e0","1f5e1","2694","1f52b","1f3f9","1f6e1","1f527","1f529","2699","1f5dc","2696","1f517","26d3","2697","1f52c","1f52d","1f4e1","1f489","1f48a","1f6aa","1f6cf","1f6cb","1f6bd","1f6bf","1f6c1","1f6d2","1f6ac","26b0","26b1","1f5ff"],"Smileys & Emotion":["1f600","1f603","1f604","1f601","1f606","1f605","1f923","1f602","1f642","1f643","1f609","1f60a","1f607","1f60d","1f618","1f617","263a","1f61a","1f619","1f60b","1f61b","1f61c","1f61d","1f911","1f917","1f914","1f910","1f610","1f611","1f636","1f60f","1f612","1f644","1f62c","1f925","1f60c","1f614","1f62a","1f924","1f634","1f637","1f912","1f915","1f922","1f927","1f635","1f920","1f60e","1f913","1f615","1f61f","1f641","2639","1f62e","1f62f","1f632","1f633","1f626","1f627","1f628","1f630","1f625","1f622","1f62d","1f631","1f616","1f623","1f61e","1f613","1f629","1f62b","1f624","1f621","1f620","1f608","1f47f","1f480","2620","1f4a9","1f921","1f479","1f47a","1f47b","1f47d","1f47e","1f916","1f63a","1f638","1f639","1f63b","1f63c","1f63d","1f640","1f63f","1f63e","1f648","1f649","1f64a","1f48b","1f48c","1f498","1f49d","1f496","1f497","1f493","1f49e","1f495","1f49f","2763","1f494","2764","1f49b","1f49a","1f499","1f49c","1f5a4","1f4af","1f4a2","1f4a5","1f4ab","1f4a6","1f4a8","1f573","1f4a3","1f4ac","1f5e8","1f5ef","1f4ad","1f4a4"]},"emoticon_conversions":{":)":":smile:","(:":":smile:",":(":":frown:","<3":":heart:",":|":":neutral:",":/":":confused:",";)":":wink:",":D":":grinning:",":o":":open_mouth:",":O":":open_mouth:",":p":":stuck_out_tongue:",":P":":stuck_out_tongue:"}}')},"89d6":function(e,t,a){},"926b":function(e,t,a){"use strict";a("e3c5")},9954:function(e,t,a){"use strict";a("7b4c")},a5fc:function(e,t,a){"use strict";a("d984")},a872:function(e,t,a){},a946:function(e,t,a){},b47d:function(e,t,a){"use strict";a("27d4")},c251:function(e,t,a){"use strict";a("09f1")},d984:function(e,t,a){},e3c5:function(e,t,a){}}); +//# sourceMappingURL=app.185d5e35.js.map \ No newline at end of file diff --git a/front/dist/js/app.185d5e35.js.map b/front/dist/js/app.185d5e35.js.map new file mode 100644 index 0000000..f829e02 --- /dev/null +++ b/front/dist/js/app.185d5e35.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/components/Content/Toc.vue?f408","webpack:///./src/components/Streams/Stream.vue?c28b","webpack:///./src/components/Rules/index.vue?03cd","webpack:///./src/components/Content/Authors.vue?7f90","webpack:///./src/App.vue","webpack:///./src/api/zulip/index.js","webpack:///./src/api/index.js","webpack:///./src/components/Rules/Styles.vue","webpack:///./src/mixins/emoji.js","webpack:///./src/components/Rules/Styles.vue?c5e6","webpack:///./src/App.vue?97f5","webpack:///./src/views/Home.vue","webpack:///./src/components/Streams/index.vue","webpack:///./src/components/Streams/Stream.vue","webpack:///./src/components/Content/Toc.vue","webpack:///./src/components/Content/Toc.vue?2575","webpack:///./src/components/Streams/Stream.vue?fb31","webpack:///./src/components/Streams/index.vue?8680","webpack:///./src/components/Content/index.vue","webpack:///./src/components/Content/Authors.vue","webpack:///./src/components/Content/Authors.vue?62e1","webpack:///./src/components/Content/Chapter.vue","webpack:///./src/components/Content/Message.vue","webpack:///./src/components/Content/Message.vue?3100","webpack:///./src/components/Content/Chapter.vue?28f3","webpack:///./src/components/Content/index.vue?4e8c","webpack:///./src/components/Rules/index.vue","webpack:///./src/components/Rules/Rule.vue","webpack:///./src/components/Rules/Rule.vue?1f70","webpack:///./src/components/Rules/index.vue?0ce9","webpack:///./src/views/Home.vue?c772","webpack:///./src/views/Docs.vue","webpack:///./docs/CSS.md","webpack:///./docs/Workshop.md","webpack:///./docs/Chattypub.md","webpack:///./src/views/Docs.vue?3bf9","webpack:///./src/router/index.js","webpack:///./src/store/index.js","webpack:///./src/main.js","webpack:///./src/components/Streams/index.vue?444f","webpack:///./src/views/Home.vue?7548","webpack:///./src/views/Docs.vue?be63","webpack:///./src/components/Content/Chapter.vue?d5a8","webpack:///./src/App.vue?5959","webpack:///./src/components/Content/Message.vue?a225","webpack:///./src/components/Rules/Rule.vue?3b2c"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","id","class","isMobile","Component","zulip","require","config","username","process","apiKey","realm","init","Promise","resolve","reject","then","client","catch","error","getStreams","streams","retrieve","getUsers","users","members","getTopics","stream","topics","stream_id","getMsgs","topic","params","messages","anchor","num_before","num_after","narrow","operator","operand","getAllMsgs","listen","cb","callOnEachEvent","event","getSubs","subscriptions","addSub","me","add","JSON","stringify","sendMsg","send","to","type","content","emoji_regex","methods","toEmojiCode","emoji","replace","codePointAt","toString","shortcodeToEmoji","code","indexOf","k","replaceAll","trim","zulip_emoji","name_to_codepoint","String","fromCodePoint","parseInt","containsEmoji","str","regexExp","test","replaceAllEmojiCodes","regex","match","mixins","computed","el","generateStyleRules","styles","this","rules","map","console","log","family","src","format","className","startsWith","parentClassName","createStyleElement","style","document","createElement","innerText","mounted","head","appendChild","watch","newStyle","replaceChild","__exports__","components","Styles","api","zulipClient","created","$store","commit","checkIfMobile","addEventListener","$router","beforeEach","afterEach","from","path","slug","currentStream","find","setUpDoc","innerWidth","filter","pubStr","description","includes","sort","a","b","date_created","eventHandler","message","subject","display_recipient","message_id","mid","rendered_content","op","reaction","emoji_code","emoji_name","reaction_type","render","for","href","classes","show_ui","toggle_ui","resizer","size","panel_sizes","min-size","print","show_message_data","expand_content","ref","isSelected","sortedTopics","top","title","toValidID","goTo","props","string","encodeURIComponent","toLowerCase","querySelector","scrollIntoView","behavior","Toc","Number","$el","offsetTop","Stream","source","$mdOpts","authors","author","isLast","isBeforeLast","item","array","messagesToShow","sender_full_name","time","reactions","EmojiConvertor","emojiConv","rawJSON","url","referrers","state","responseTo","sender_id","quote","forEach","join","replace_colons","ts","timestamp","ts_ms","date_ob","Date","toLocaleString","Message","Chapter","Authors","foundStream","$route","Set","flat","rule","contentFiltered","font","dec","reg","Rule","Streams","Content","Rules","Splitpanes","Pane","setup","preview","0","1","2","panels","prev","setTimeout","print_preview","getElementById","paged","flow","total","evt","undefined","$forceUpdate","files","file","html","Workshop","Chattypub","CSS","hash","getFileName","includeExtension","matches","handleLinks","Array","querySelectorAll","e","pathname","preventDefault","scroll","createRouter","history","createWebHistory","routes","component","Home","Docs","toCSS","stripHtml","is_codeblock","is_font","results","matchAll","re_path","exec","cleanupCodeBlock","split","validateRule","filename","getFilename","ext","pop","getFormat","fmt","handleMDReply","handleHTMLReply","createStore","strict","mutations","setMobile","mobile","setStreams","setCurStream","setTopics","addMessage","deleteMessage","addReaction","removeReaction","setRules","reduce","acc","cur","addRule","editMessage","newRules","updateTopic","orig_subject","actions","getters","filteredTopics","localeCompare","numeric","sensitivity","app","createApp","App","mdOpts","linkify","typographer","globalProperties","$http","Axios","$md","MarkdownIt","use","VueMarkdownIt","router","store","mount"],"mappings":"aACE,SAASA,EAAqBC,GAQ7B,IAPA,IAMIC,EAAUC,EANVC,EAAWH,EAAK,GAChBI,EAAcJ,EAAK,GACnBK,EAAiBL,EAAK,GAIHM,EAAI,EAAGC,EAAW,GACpCD,EAAIH,EAASK,OAAQF,IACzBJ,EAAUC,EAASG,GAChBG,OAAOC,UAAUC,eAAeC,KAAKC,EAAiBX,IAAYW,EAAgBX,IACpFK,EAASO,KAAKD,EAAgBX,GAAS,IAExCW,EAAgBX,GAAW,EAE5B,IAAID,KAAYG,EACZK,OAAOC,UAAUC,eAAeC,KAAKR,EAAaH,KACpDc,EAAQd,GAAYG,EAAYH,IAG/Be,GAAqBA,EAAoBhB,GAE5C,MAAMO,EAASC,OACdD,EAASU,OAATV,GAOD,OAHAW,EAAgBJ,KAAKK,MAAMD,EAAiBb,GAAkB,IAGvDe,IAER,SAASA,IAER,IADA,IAAIC,EACIf,EAAI,EAAGA,EAAIY,EAAgBV,OAAQF,IAAK,CAG/C,IAFA,IAAIgB,EAAiBJ,EAAgBZ,GACjCiB,GAAY,EACRC,EAAI,EAAGA,EAAIF,EAAed,OAAQgB,IAAK,CAC9C,IAAIC,EAAQH,EAAeE,GACG,IAA3BX,EAAgBY,KAAcF,GAAY,GAE3CA,IACFL,EAAgBQ,OAAOpB,IAAK,GAC5Be,EAASM,EAAoBA,EAAoBC,EAAIN,EAAe,KAItE,OAAOD,EAIR,IAAIQ,EAAmB,GAKnBhB,EAAkB,CACrB,IAAO,GAGJK,EAAkB,GAGtB,SAASS,EAAoB1B,GAG5B,GAAG4B,EAAiB5B,GACnB,OAAO4B,EAAiB5B,GAAU6B,QAGnC,IAAIC,EAASF,EAAiB5B,GAAY,CACzCK,EAAGL,EACH+B,GAAG,EACHF,QAAS,IAUV,OANAf,EAAQd,GAAUW,KAAKmB,EAAOD,QAASC,EAAQA,EAAOD,QAASH,GAG/DI,EAAOC,GAAI,EAGJD,EAAOD,QAKfH,EAAoBM,EAAIlB,EAGxBY,EAAoBO,EAAIL,EAGxBF,EAAoBQ,EAAI,SAASL,EAASM,EAAMC,GAC3CV,EAAoBW,EAAER,EAASM,IAClC3B,OAAO8B,eAAeT,EAASM,EAAM,CAAEI,YAAY,EAAMC,IAAKJ,KAKhEV,EAAoBe,EAAI,SAASZ,GACX,qBAAXa,QAA0BA,OAAOC,aAC1CnC,OAAO8B,eAAeT,EAASa,OAAOC,YAAa,CAAEC,MAAO,WAE7DpC,OAAO8B,eAAeT,EAAS,aAAc,CAAEe,OAAO,KAQvDlB,EAAoBmB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQlB,EAAoBkB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,kBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKxC,OAAOyC,OAAO,MAGvB,GAFAvB,EAAoBe,EAAEO,GACtBxC,OAAO8B,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOlB,EAAoBQ,EAAEc,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRtB,EAAoB0B,EAAI,SAAStB,GAChC,IAAIM,EAASN,GAAUA,EAAOiB,WAC7B,WAAwB,OAAOjB,EAAO,YACtC,WAA8B,OAAOA,GAEtC,OADAJ,EAAoBQ,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRV,EAAoBW,EAAI,SAASgB,EAAQC,GAAY,OAAO9C,OAAOC,UAAUC,eAAeC,KAAK0C,EAAQC,IAGzG5B,EAAoB6B,EAAI,IAExB,IAAIC,EAAaC,OAAO,gBAAkBA,OAAO,iBAAmB,GAChEC,EAAmBF,EAAW3C,KAAKsC,KAAKK,GAC5CA,EAAW3C,KAAOf,EAClB0D,EAAaA,EAAWG,QACxB,IAAI,IAAItD,EAAI,EAAGA,EAAImD,EAAWjD,OAAQF,IAAKP,EAAqB0D,EAAWnD,IAC3E,IAAIU,EAAsB2C,EAI1BzC,EAAgBJ,KAAK,CAAC,EAAE,kBAEjBM,K,wJCvJT,W,oCCAA,W,kCCAA,W,oCCAA,W,wPCCE,yBAaM,OAbDyC,GAAG,MAAOC,MAAK,SAAa,EAAAC,Y,CAC/B,yBAAU,GAKV,yBAMO,aALL,yBAIc,Q,8BAHZ,gBADqBC,EACrB,EADqBA,UACrB,MAD8B,CAC9B,yBAEa,iBAFD5B,KAAK,iBAAiBW,KAAK,U,+BACrC,iBAA6B,E,yBAA7B,yBAA6B,qCAAbiB,S,6NCRxBC,EAAUC,EAAQ,QAClBC,EAAU,CACRC,SAAWC,sCACXC,OAAWD,mCACXE,MAAWF,uCAGbG,EAAU,kBAAQ,IAChBC,SAAQ,SAACC,EAASC,GAChBV,EAAME,GACLS,MAAK,SAAAC,GAAM,OAAIH,EAAQG,MACvBC,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAI3BC,EAAa,SAAAH,GAAM,OAAM,IACvBJ,SAAQ,SAACC,EAASC,GACjBE,EACCI,QACAC,WACCN,MAAK,SAAAvD,GAAM,OAAIqD,EAAQrD,EAAO4D,YAC9BH,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAI3BI,EAAW,SAAAN,GAAM,OAAM,IACrBJ,SAAQ,SAACC,EAASC,GACjBE,EACCO,MACAF,WACCN,MAAK,SAAAvD,GAAM,OAAIqD,EAAQrD,EAAOgE,YAC9BP,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAI3BO,EAAY,SAACT,EAAQU,GAAT,OAAsB,IAChCd,SAAQ,SAACC,EAASC,GACjBE,EACCI,QACAO,OACAN,SAAS,CAAEO,UAAWF,IACrBX,MAAK,SAAAvD,GAAM,OAAIqD,EAAQrD,EAAOmE,WAC9BV,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAI3BW,EAAU,SAACb,EAAQU,EAAQI,EAAOC,GAAxB,OAAqC,IAC7CnB,SAAQ,SAACC,EAASC,GACjBE,EACCgB,SACAX,SAASU,GAAU,CACjBE,OAAQ,SACRC,WAAY,IACZC,UAAW,EAEXC,OAAQ,CACN,CAAEC,SAAU,SAAUC,QAASZ,GAC/B,CAAEW,SAAU,QAAUC,QAASR,MAGlCf,MAAK,SAAAvD,GAAM,OAAIqD,EAAQrD,MACvByD,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAI3BqB,EAAa,SAACvB,EAAQU,EAAQK,GAAjB,OAA8B,IACzCnB,SAAQ,SAACC,EAASC,GACjBE,EACCgB,SACAX,SAASU,GAAU,CACjBE,OAAQ,SACRC,WAAY,IACZC,UAAW,EAEXC,OAAQ,CAAC,CAAEC,SAAU,SAAUC,QAASZ,MAEzCX,MAAK,SAAAvD,GAAM,OAAIqD,EAAQrD,MACvByD,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAI3BsB,EAAS,SAACxB,EAAQyB,GAChBzB,EACC0B,iBACC,SAAAC,GAAK,OAAIF,EAAGE,KACZ,CAAE,WACF,CAAE,CAAEN,SAAU,SAAUC,QAAS,aAIrCM,EAAU,SAAA5B,GAAM,OAAM,IACpBJ,SAAQ,SAACC,EAASC,GACjBE,EACCI,QACAyB,cACAxB,WACCN,MAAK,SAAAvD,GAAM,OAAIqD,EAAQrD,MACvByD,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAI3B4B,EAAS,SAAC9B,EAAQU,GAAT,OAAsB,IAC7Bd,SAAQ,SAACC,EAASC,GAChBE,EACCO,MACAwB,GACAF,cACAG,IACC,CACEH,cAAeI,KAAKC,UAAU,CAAC,CAAE3E,KAAMmD,OAG1CX,MAAK,SAAAvD,GAAM,OAAIqD,EAAQrD,MACvByD,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAI3BiC,EAAU,SAACnC,EAAQe,GAAT,OAAsB,IAC9BnB,SAAQ,SAACC,EAASC,GAChBE,EACCgB,SACAoB,KAAKrB,GAAU,CACdsB,GAAI,SACJC,KAAM,SACNxB,MAAO,UACPyB,QAAS,oDAEVxC,MAAK,SAAAvD,GAAM,OAAIqD,EAAQrD,MACvByD,OAAM,SAAAC,GAAK,OAAIJ,EAAOI,UAId,GACbP,OACAL,SACAa,aACAG,WACAG,YACAI,UACAU,aACAC,SACAW,UACAP,UACAE,UC/Ia,GACb1C,S,wDCFA,yBAAqB,Y,kECiBR,GACbjE,KADa,WAEX,MAAO,CACLqH,YAAa,uVAIjBC,QAAS,CACPC,YAAa,SAACC,GACZ,OAAOA,EAAMC,QAAQ,i9CAAe,SAACxF,GAAD,OAAOA,EAAEyF,YAAY,GAAGC,SAAS,QAGvEC,iBAAkB,SAACC,GACjB,GAA0B,IAAtBA,EAAKC,QAAQ,KAAY,OAAOD,EACpC,IAAIE,EAAIF,EAAKG,WAAW,IAAK,IAAIC,OAC7BT,EAAQU,EAAYC,kBAAkBJ,GAC1C,OAAKP,EAEEY,OAAOC,cAAcC,SAAS,KAAKd,IAFvBK,GAYrBU,cArBO,SAqBOC,GAEZ,IAAMC,EAAW,sGACjB,OAAOA,EAASC,KAAKF,IAIvBG,qBA5BO,SA4BcvB,GAAS,WACxBwB,EAAQ,eAIZ,OAHAxB,EAAUA,EAAQY,WAAWY,GAAO,SAACC,GACnC,OAAO,EAAKjB,iBAAiBiB,MAExBzB,KDjDE,GACbhF,KAAM,SACN0G,OAAQ,CAAC,GACTC,SAAU,kBACL,eAAS,CAAC,WAEf/I,KANa,WAOX,MAAO,CACLgJ,GAAI,OAGR1B,QAAS,CACP2B,mBADO,WACc,WACfC,EAAS,GA6Bb,OA5BAC,KAAKC,MAAMC,KAAI,SAAC3G,GACd,OAAQA,EAAEyE,MACR,IAAK,MACHmC,QAAQC,IAAI,MAAO7G,EAAE0E,SACrB8B,GAAUxG,EAAE0E,QAAQY,WAAW,KAAM,KACrC,MACF,IAAK,OAEHkB,GAAK,qCAAmCxG,EAAE0E,QAAQoC,OAA7C,wBAAmE9G,EAAE0E,QAAQqC,IAA7E,sBAA8F/G,EAAE0E,QAAQsC,OAAxG,SACL,MACF,QACMhH,EAAEiH,UAAUC,WAAW,KACzBV,GAAUxG,EAAEiH,WAEZT,GAAK,WAASxG,EAAEmH,gBAAX,YAA8BnH,EAAEiH,WACjC,EAAKpB,cAAc7F,EAAEiH,aACvBT,GAAK,aAAWxG,EAAEmH,gBAAb,cAAkC,EAAKtC,YAC1C7E,EAAEiH,cAIRT,GAAU,IACVxG,EAAE0G,MAAMC,KAAI,SAACzH,GACXsH,GAAUtH,KAEZsH,GAAU,QAGTA,GAETY,mBAjCO,WAkCL,IAAIC,EAAQC,SAASC,cAAc,SAEnC,OADAF,EAAMG,UAAYf,KAAKF,qBAChBc,IAGXI,QAlDa,WAmDXhB,KAAKH,GAAKG,KAAKW,qBACfE,SAASI,KAAKC,YAAYlB,KAAKH,KAEjCsB,MAAO,CACLlB,MADK,WAEH,IAAMmB,EAAWpB,KAAKW,qBACtBE,SAASI,KAAKI,aAAaD,EAAUpB,KAAKH,IAC1CG,KAAKH,GAAKuB,K,qBE9DhB,MAAME,EAA2B,IAAgB,EAAQ,CAAC,CAAC,SAAS,KAErD,QLeA,GACbrI,KAAM,MACNsI,WAAY,CACVC,UAEF3K,KALa,WAMX,MAAO,CACL4K,IAAKA,EACLC,YAAa,OAGjB9B,SAAU,kBACL,eAAS,CAAC,WAAY,SAAU,gBAAiB,aAEtD+B,QAda,WAcH,WACR3B,KAAK4B,OAAOC,OAAO,YAAa7B,KAAK8B,iBACrCvH,OAAOwH,iBAAiB,UAAU,WAChC,EAAKH,OAAOC,OAAO,YAAa,EAAKC,oBAGvC9B,KAAKgC,QAAQC,WAAb,wCAAwB,iGACjB,EAAKP,aAAsC,GAAvB,EAAK5F,QAAQzE,OADhB,gCAEd,EAAKwE,aAFS,4CAMxBmE,KAAKgC,QAAQE,WAAU,SAACnE,EAAIoE,GACtBpE,EAAGqE,OAASD,EAAKC,OACnB,EAAKR,OAAOC,OAAO,YAAa,IAChC,EAAKD,OAAOC,OAAO,WAAY,IAC/B,EAAKD,OAAOC,OAAO,eAAgB,CACjC5I,KAAM8E,EAAGqE,KAAK9D,QAAQ,IAAK,IAAIO,WAAW,IAAK,KAC/CwD,KAAMtE,EAAGqE,KAAK9D,QAAQ,IAAK,IAAIO,WAAW,IAAK,OAGpB,IAA3B,EAAKyD,cAAcD,MAEnB,EAAKvG,QAAQyG,MAAK,SAAA9J,GAAA,OAClBA,EAAEQ,MAAQ,EAAKqJ,cAAcrJ,MAC7BR,EAAE4J,MAAQ,EAAKC,cAAcD,SAG7BlC,QAAQC,IAAI,gBACZ,EAAKoC,SAAS,EAAKF,gBAEnBnC,QAAQC,IAAI,8BAMpBjC,QAAS,CACP2D,cAAe,kBAAMvH,OAAOkI,WAAa,KAEzC5G,WAHO,WAGM,WACX,OAAO,IAAIP,SAAQ,SAAAC,GACjBkG,EAAI3G,MAAMO,OAAOI,KAAjB,yDAAsB,WAAMC,GAAN,oGACpB,EAAKgG,YAAchG,EADC,SAEE+F,EAAI3G,MAAMe,WAAWH,GAFvB,OAEdI,EAFc,wBAGCA,GAHD,IAGpB,2BAAWM,EAAmB,QAC5BA,EAAOiG,KAAOjG,EAAOnD,KAAK4F,WAAW,IAAK,KAJxB,8BAMpB,EAAK+C,OAAOC,OACV,aACA/F,EAAQ4G,QAAO,SAACjK,GAAD,OACbA,EAAEQ,KAAKwH,WAAW,EAAKkC,SACvBlK,EAAEmK,YAAYC,SAAS,YACtBC,MAAK,SAACC,EAAGC,GAAJ,OACNA,EAAEC,aACFF,EAAEE,iBAGNxB,EAAI3G,MAAMoC,OAAO,EAAKwE,YAAa,EAAKwB,cACxC3H,IAjBoB,2CAAtB,2DAsBJiH,SA3BO,SA2BEpG,GAAQ,WACfqF,EAAI3G,MAAMwC,QAAQ0C,KAAK0B,aAAajG,MAAK,SAACvD,GAErCA,EAAOqF,cAAc2C,KAAI,SAACzH,GAAD,OAAOA,EAAEQ,QAAM4J,SAAS,EAAKP,cAAcrJ,OAErEwI,EAAI3G,MAAM0C,OAAO,EAAKkE,YAAa,EAAKY,cAAcrJ,SAI1DwI,EAAI3G,MAAMmC,WAAW+C,KAAK0B,YAAatF,EAAOnD,MAAMwC,MAAK,SAACvD,GACxD,IAAK,IAAIY,EAAI,EAAGA,EAAIZ,EAAOwE,SAASrF,OAAQyB,IAAK,CAC/C,IAAMqK,EAAUjL,EAAOwE,SAAS5D,GACT,SAAnBqK,EAAQC,QACV,EAAKxB,OAAOC,OAAO,UAAWsB,GAE9B,EAAKvB,OAAOC,OAAO,aAAcsB,QAMzCD,aAhDO,SAgDM7F,GAEX,OADA8C,QAAQC,IAAI,SAAU/C,GACdA,EAAMW,MACZ,IAAK,UACH,GAAIX,EAAM8F,QAAQE,mBAAqBrD,KAAKsC,cAAcrJ,KAAM,CAC9D,OAAQoE,EAAM8F,QAAQC,SACpB,IAAK,QACHpD,KAAK4B,OAAOC,OAAO,UAAWxE,EAAM8F,SACpC,MACF,QACEnD,KAAK4B,OAAOC,OAAO,aAAcxE,EAAM8F,SACvC,MAEJ,MAEF,MAEF,IAAK,iBACHnD,KAAK4B,OAAOC,OAAO,gBAAiBxE,EAAMiG,YAC1C,MAEF,IAAK,iBACHtD,KAAK4B,OAAOC,OAAO,cAAe,CAChC0B,IAAKlG,EAAMiG,WACXrF,QAASZ,EAAMmG,mBAEjB,MAEF,IAAK,WACHxD,KAAK4B,OAAOC,OAAZ,UAAsBxE,EAAMoG,GAA5B,YAA0C,CACxCF,IAAKlG,EAAMiG,WACXI,SAAU,CACRC,WAAYtG,EAAMsG,WAClBC,WAAYvG,EAAMuG,WAClBC,cAAexG,EAAMwG,iBAGzB,MAEF,QACE1D,QAAQC,IAAI,qBAAsB/C,EAAMW,U,UM1JlD,MAAM,EAA2B,IAAgB,EAAQ,CAAC,CAAC,SAAS8F,KAErD,Q,8ECIFnJ,MAAM,Y,GAIFoJ,IAAI,Y,+BAMP,2B,EAGJ,yBAKI,KALDpJ,MAAM,UAAQ,C,6BAAC,uEAEhB,yBAAuD,KAApDqJ,KAAK,uCAAsC,S,6BAAS,2H,oRA3BjE,yBAgDM,OAhDDrJ,MAAK,CAAC,eAAuB,EAAAsJ,U,CACjB,EAAAC,Q,iEAAf,yBAES,U,MAFgB,QAAK,8BAAE,EAAAC,WAAA,EAAAA,UAAA,qBAAWxJ,MAAM,gB,6BAC5C,EAAAuJ,QAAO,eAAqB,OACjC,IACA,yBA2Ca,GA3CDvJ,MAAM,gBAAiB,SAAQ,EAAAyJ,S,+BACzC,iBA4BO,CA1BC,EAAAF,S,yBAFR,yBA4BO,G,MA3BLvJ,MAAM,gBAEL0J,KAAM,EAAAC,YAAW,GAClBC,WAAS,K,+BAET,iBAAW,CAAX,yBAAW,GACX,yBAoBM,MApBN,EAoBM,CAnBJ,yBAAsE,UAA7D,QAAK,8BAAE,EAAAJ,WAAA,EAAAA,UAAA,sB,6BAAc,EAAAD,QAAO,eAAqB,MAAG,GAC7D,yBAAqC,UAA5B,QAAK,8BAAE,EAAAM,OAAA,EAAAA,MAAA,sBAAO,SAEvB,yBAQC,QARD,EAQC,C,4BAPE,yBAKC,SAJAxG,KAAK,WACLtD,GAAG,WACHhB,MAAM,I,qDACG,EAAA+K,kBAAiB,K,gCAAjB,EAAAA,qB,IAIb,EAMA,yBAA6D,UAApD,QAAK,+BAAE,EAAAzC,QAAQrK,KAAI,kBAAoB,c,yDAGpD,yBAMO,GANA0M,KAAM,EAAAC,YAAW,GAAM3J,MAAO,EAAA2H,e,+BACnC,iBAIE,CAJF,yBAIE,GAHCkC,OAAQ,EAAAN,SAAW,EAAAQ,eACnBD,kBAAmB,EAAAA,kBACpBE,IAAI,W,mEAGI,EAAAT,S,yBAAZ,yBAEO,G,MAFeG,KAAM,EAAAC,YAAW,GAAKC,WAAS,M,+BACnD,iBAAS,CAAT,yBAAS,O,2LC1CN5J,MAAM,W,uIAAf,yBAOU,UAPV,EAOU,E,2BANR,yBAKE,2CAJiB,EAAAmB,SAAO,SAAjBM,G,gCADT,yBAKE,GAHCpC,IAAKoC,EAAO1B,GACZ0B,OAAQA,EACRwI,WAAY,EAAAtC,cAAcrJ,MAAQmD,EAAOnD,M,+ICJzC0B,MAAM,Q,mLADX,yBAYM,OAZAA,MAAK,gBAAqB,EAAAiK,c,CAC9B,yBAII,IAJJ,EAII,CAHF,yBAEc,GAFA7G,GAAI,EAAA3B,OAAOiG,M,YACvB,iBAAiB,C,0DAAd,EAAAjG,OAAOnD,MAAI,O,iBAIV,EAAA2L,Y,yBADR,yBAIE,G,MAFCC,aAAc,EAAAA,aACdC,IAAK,EAAAA,K,sPCTV,yBAYK,MAXHnK,MAAM,QACLiG,MAAK,SAAa,EAAAkE,IAAG,O,6BAEtB,yBAOK,2CAPe,EAAAD,cAAY,SAArBrI,G,gCAAX,yBAOK,MAP8BxC,IAAKwC,EAAMuI,O,CAC5C,yBAKc,GAJXhH,GAAE,WAAM,EAAAiH,UAAUxI,EAAMuI,QACxB,QAAK,+CAAO,EAAAE,KAAA,WAAS,EAAAD,UAAUxI,EAAMuI,WAAK,W,YAE3C,iBAAiB,C,0DAAdvI,EAAMuI,OAAK,O,8CAQP,IACb9L,KAAM,QACNiM,MAAO,CAAE,eAAgB,OACzB/G,QAAS,CACP6G,UADO,SACGG,GACR,OAAOC,mBAAmB,MAAQD,GAC/BE,cACA/G,QAAQ,oBAAqB,IAC7BA,QAAQ,UAAW,KAExB2G,KAPO,SAOFvK,GACHmG,SAASyE,cAAT,UAA0B5K,IAAM6K,eAAe,CAC7CC,SAAU,c,UCvBlB,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,GAAQ,CAAC,YAAY,qBAE1E,UFWA,IACbvM,KAAM,SACNsI,WAAY,CAAEkE,QACdP,MAAO,CACL,SACA,cAEFrO,KAPa,WAQX,MAAO,CACLiO,IAAKY,SAGT9F,SAAU,kBACL,eAAW,CACZ,kBAGJoB,QAjBa,WAkBXhB,KAAK8E,IAAM9E,KAAK2F,IAAIC,Y,UG/BxB,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,GAAQ,CAAC,YAAY,qBAE1E,UJMA,IACb3M,KAAM,UACNsI,WAAY,CACVsE,WAEFjG,SAAU,kBACL,eAAS,CACV,UACA,oB,UKhBN,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,GAAQ,CAAC,YAAY,qBAE1E,U,mGCPPjF,MAAM,S,gRADZ,yBAsBU,gBArBR,yBAAkC,KAAlC,GAAkC,6BAAb,EAAAoK,OAAK,GAC1B,yBAKmB,EALnB,wBAKmB,CAJjBpK,MAAM,cACLmL,OAAQ,EAAAlD,aACD,EAAAmD,SAAO,oBAGjB,yBAEE,GADClB,aAAc,EAAAA,cAAY,yBAE7B,yBAEE,GADCmB,QAAS,EAAAA,SAAO,qB,2BAEnB,yBAOE,2CANgB,EAAAnB,cAAY,SAArBrI,G,gCADT,yBAOE,GALCxC,IAAKwC,EAAMuI,MACXrK,GAAI,EAAAsK,UAAUxI,EAAMuI,OACpBvI,MAAOA,EACPgI,MAAO,EAAAA,MACPC,kBAAmB,EAAAA,mB,2NCpBrB9J,MAAM,W,4HAAT,yBAWI,IAXJ,GAWI,E,2BAVF,yBASO,2CAPY,EAAAqL,SAAO,SAAjBC,G,gCAFT,yBASO,QARLtL,MAAM,SAELX,IAAKiM,G,CAEN,yBAAyB,yCAAhBA,GAAM,GACH,EAAAC,OAAOD,EAAQ,EAAAD,U,yBAA3B,yBAA6C,UAAR,MACpB,EAAAG,aAAaF,EAAQ,EAAAD,U,yBAAtC,yBAA4D,UAAZ,W,yBAChD,yBAAsB,UAAT,Y,WAMJ,IACb/M,KAAM,UACNiM,MAAO,CAAE,WACT/G,QAAS,CACP+H,OAAQ,SAACE,EAAMC,GAAP,OACNA,EAAM1H,QAAQyH,KAAUC,EAAMhP,OAAS,GAEzC8O,aAAc,SAACC,EAAMC,GAAP,OACZA,EAAM1H,QAAQyH,KAAUC,EAAMhP,OAAS,K,UCjB7C,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,IAAQ,CAAC,YAAY,qBAE1E,U,mGCRRsD,MAAM,Q,IACLA,MAAM,U,GAMN,yBAAmB,YAAb,KAAM,G,0IAPlB,yBAYM,MAZN,GAYM,CAXJ,yBAEK,KAFL,GAEK,CADH,yBAA8B,yCAArB,EAAA6B,MAAMuI,OAAK,KAEtB,yBAKM,a,2BAJJ,yBAGO,2CAHiB,EAAAuB,gBAAc,SAAzBnD,G,gCAAb,yBAGO,QAHkCnJ,IAAKmJ,EAAQzI,I,CACpD,yBAAqE,GAA3DyI,QAASA,EAAUsB,kBAAmB,EAAAA,mB,wCAChD,Q,iBCPD9J,MAAM,iB,UACJA,MAAM,gB,IACJA,MAAM,Q,IACNA,MAAM,Q,UAKRA,MAAM,0B,IASNA,MAAM,gB,iHAjBb,yBAsBM,MAtBN,GAsBM,CArB4B,EAAA8J,mB,yBAAhC,yBAGM,MAHN,GAGM,CAFJ,yBAAsD,MAAtD,GAAsD,6BAAjC,EAAAtB,QAAQoD,kBAAgB,GAC7C,yBAAkC,MAAlC,GAAkC,6BAAb,EAAAC,MAAI,M,uCAE3B,yBAEM,OAFA7L,MAAK,CAAE,EAAAsJ,QAAe,Y,CAC1B,yBAAwE,EAAxE,wBAAwE,CAArD6B,OAAQ,EAAA7H,SAAiB,EAAA8H,SAAO,qB,GAEX,EAAAtB,mB,yBAA1C,yBAQM,MARN,GAQM,E,2BAPJ,yBAMO,2CAJc,EAAAtB,QAAQsD,WAAS,SAA7B/C,G,gCAFT,yBAMO,QALL/I,MAAM,WAELX,IAAK0J,G,6BAEHzE,OAAOC,cAAa,KAAQwE,EAASC,aAAU,M,gDAGtD,yBAIM,MAJN,GAIM,E,2BAHJ,yBAEO,2CAFkB,EAAA8C,WAAS,SAArB/C,G,gCAAb,yBAEO,QAF8B1J,IAAK0J,EAAWqB,MAAOrB,G,6BACvD,EAAAjF,iBAAiBiF,IAAQ,gB,kCAQhCgD,GAAiB,EAAQ,QACzBC,GAAY,IAAID,GAGL,IACbzN,KAAM,UACNiM,MAAO,CAAC,UAAW,qBACnBvF,OAAQ,CAAC,GACTC,SAAU,CACRgH,QADQ,WAEN,MAAO,YAAcjJ,KAAKC,UAAUoC,KAAKmD,QAAS,KAAM,GAAK,SAE/DlF,QAJQ,WAIE,WACR,IAAI+B,KAAKmD,QAAQlF,QAAS,MAAO,GACjC,IAAIlF,EAAIiH,KAAKmD,QAAQlF,QAAQK,QAAQ,KAAM,SAEvCuI,EAAM,sCACV9N,EAAIA,EAAE8F,WAAW,QAAS,QAAUgI,GACpC9N,EAAIA,EAAE8F,WAAW,UAAW,SAAWgI,EAAM,KAI7C9N,EAAIA,EAAE8F,WACJgI,EAAM,iBACN,0DAGF9N,EAAIiH,KAAKR,qBAAqBzG,GAE9B,IAAM+N,EAAY9G,KAAK4B,OAAOmF,MAAM1K,OACjCkG,MAAK,SAAC5I,GAAD,OAAOA,EAAEoL,OAAS,EAAK5B,QAAQC,WACpC1G,SAASgG,QACR,SAAC5J,GAAD,OACEA,EAAEkO,YACFlO,EAAEkO,WAAWtM,IAAM,EAAKyI,QAAQzI,IAChC5B,EAAEkO,WAAWC,WAAa,EAAK9D,QAAQ8D,WACvC,EAAK9D,QAAQlF,QAAQ4E,SAAS/J,EAAEkO,WAAWE,UAWjD,OARAJ,EAAUK,SAAQ,SAACrO,GACjB,IAAMmL,EAAUnL,EAAE2N,UAAUvG,KAAI,SAAC3G,GAAD,MAAO,IAAMA,EAAEoK,cAAYyD,KAAK,KAChErO,EAAIA,EAAEuF,QACJxF,EAAEkO,WAAWE,MADX,uBAEcjD,EAFd,aAE0BnL,EAAEkO,WAAWE,MAFvC,eAMCnO,GAET0N,UAzCQ,WAgDN,OAAOzG,KAAKmD,QAAQsD,UAAUvG,KAAI,SAAC3G,GAAD,OAChCoN,GAAUU,eAAe,IAAM9N,EAAEqK,WAAa,SAGlDK,QApDQ,WAqDN,OAAOjE,KAAKmD,QAAQsD,UAAUvG,KAC5B,SAAC3G,GAAD,OAAOA,EAAEoK,WAAa,KAAOpK,EAAEoK,eAGnC6C,KAzDQ,WA0DN,IAAIc,EAAKtH,KAAKmD,QAAQoE,UAClBC,EAAa,IAALF,EACRG,EAAU,IAAIC,KAAKF,GACvB,OAAOC,EAAQE,mBAGnBhG,QApEa,c,UCzBf,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,MAErD,UFUA,IACb1I,KAAM,UACNsI,WAAY,CACVqG,YAEF1C,MAAO,CAAC,QAAS,qBACjBtF,SAAU,CACR0G,eADQ,WAEN,OAAOtG,KAAKxD,MAAME,SAASgG,QAAO,SAAC5J,GAAD,OAAQA,EAAEkO,iB,UGpBlD,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,IAAQ,CAAC,YAAY,qBAE1E,UNuBA,IACb/N,KAAM,UACNsI,WAAY,CACVsG,WACApC,OACAqC,YAEF5C,MAAO,CAAC,QAAS,qBACjBtF,SAAU,gDACL,eAAS,CAAC,gBAAiB,aAC3B,eAAW,CAAC,kBAFT,IAGNmI,YAHQ,WAGM,WACZ,OAAO/H,KAAKlE,QAAQyG,MAAK,SAAA9J,GAAA,OAAKA,EAAEQ,MAAQ,EAAKqJ,cAAcrJ,SAE7D8L,MANQ,WAON,OAAO/E,KAAK+H,YACR/H,KAAKsC,cAAcrJ,KACC,KAApB+G,KAAKgI,OAAO5F,KACZ,mBACA,2BAENQ,YAbQ,WAcN,OAAO5C,KAAK+E,OACZ/E,KAAK+H,aACL/H,KAAK+H,YAAYnF,YAAYtE,QAAQ,QAAS,KAEhD0H,QAlBQ,WAmBN,gCACK,IAAIiC,IACLjI,KAAK+E,OACL/E,KAAK+H,aACL/H,KAAK6E,aACJ3E,KAAI,SAAAvG,GAAA,OAAKA,EAAE+C,YACXwL,OACAhI,KAAI,SAAApH,GAAA,OAAKA,EAAEyN,sBAEX,CAAE,eAIXpI,QAAS,CACP6G,UADO,SACGG,GACR,OAAOC,mBAAmB,MAAQD,GAC/BE,cACA/G,QAAQ,oBAAqB,IAC7BA,QAAQ,UAAW,OOxE5B,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,IAAQ,CAAC,YAAY,qBAE1E,U,mGCNJ3D,MAAM,S,uIAAf,yBAOU,UAPV,GAOU,E,2BALR,yBAIE,2CAHe,EAAAsF,OAAK,SAAbkI,G,gCADT,yBAIE,GAFCnO,IAAKmO,EAAKzN,GACVyN,KAAMA,G,wJCMFxN,MAAM,gB,gCAEN,iD,GAA6C,yBAAM,mB,GAQxD,yBAAQ,SAAL,KAAC,G,2FArBR,yBAuBM,OAvBDA,MAAK,CAAC,OAAe,EAAAsJ,SAAUrD,MAAO,EAAAX,O,CACrB,QAAT,EAAAkI,KAAKnK,M,yBAAhB,yBAEM,sCADA,EAAAoK,iBAAkB,SACxB,IAC0B,SAAT,EAAAD,KAAKnK,M,yBAAtB,yBAaO,WAZL,yBAKC,OALK4C,MAAO,EAAAX,OAAO,kCAEV,6BAAG,EAAAoI,KAAKhI,QAAS,gBACzB,6BAAG,EAAAgI,KAAK/H,KAAM,YAAS,6BAAG,eAAgB,SACjD,GAEK,yBAKM,MALN,GAKM,CAJJ,yBAGO,a,GAFyC,G,6BAAM,kBACtC,6BAAG,EAAA+H,KAAKhI,QAAS,MACjC,W,yBAGJ,yBAIW,uBAHT,yBAAkE,KAA9D0E,MAAO,EAAA3G,YAAY,EAAA+J,KAAK3H,Y,6BAAe,EAAA2H,KAAK3H,WAAY,KAAE,c,2BAC9D,yBAA4D,2CAA3C,EAAA2H,KAAKlI,OAAK,SAAjBqI,G,gCAAV,yBAA4D,KAA9BtO,IAAKsO,GAAK,KAAO,6BAAGA,GAAG,M,MACrD,I,YAQS,IACbrP,KAAM,OACN0G,OAAQ,CAAC,GACTuF,MAAO,CAAC,QACRtF,SAAU,CACRwI,gBADQ,WACU,WACZG,EAAMvI,KAAK9B,YACXnF,EAAIiH,KAAKmI,KAAKlK,QAAQK,QAAQiK,GAAK,SAACxP,GACtC,OAAOA,EAAI,OAAS,EAAKqF,YAAYrF,MAGvC,OAAOA,GAETkL,QATQ,WAUN,MAAO,QAAUjE,KAAKmI,KAAKnK,MAE7BqK,KAZQ,WAaN,OAAOrI,KAAKmI,KAAKlK,SAEnBgC,MAfQ,WAgBN,MAAuB,SAAnBD,KAAKmI,KAAKnK,KAAwBgC,KAAKmI,KAAKlI,MACpC,CAAC,gBAAkBD,KAAKqI,KAAKhI,OAAS,Q,UC5CxD,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,IAAQ,CAAC,YAAY,qBAE1E,UFMA,IACbpH,KAAM,QACNsI,WAAY,CACViH,SAEF5I,SAAU,kBACL,eAAS,CACV,WAGJuB,MAAO,CACLlB,MADK,WAEHE,QAAQC,IAAI,Y,UGpBlB,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,IAAQ,CAAC,YAAY,qBAE1E,U,sClBuDA,IACbnH,KAAM,OACNsI,WAAY,CACVkH,WACAC,WACAC,SACAC,WAAA,iBACAC,KAAA,YAEFC,MATa,WAUX,IAAMC,EAAU,iBAAI,MACpB,MAAO,CACLA,YAGJlS,KAAM,WACJ,MAAO,CACLqN,SAAS,EACTO,mBAAmB,EACnBH,YAAa,CAAE0E,EAAG,GAAIC,EAAG,GAAIC,EAAG,IAChCxE,gBAAgB,IAGpB9E,SAAU,CACRqE,QADQ,WAEN,OAAOjE,KAAKkE,QAAU,KAAO,SAE/B5B,cAJQ,WAKN,OAAOtC,KAAK4B,OAAOmF,MAAMzE,cAAcD,OAG3ClE,QAAS,CACPiG,QADO,SACC+E,GACN,IAAK,IAAIhS,EAAI,EAAGA,EAAIgS,EAAO9R,OAAQF,IACjC6I,KAAKsE,YAAYnN,GAAKgS,EAAOhS,GAAGkN,MAGpCG,MANO,WAMC,WACF4E,EAAOpJ,KAAKkE,QAChBlE,KAAKmE,UAAU,MAAM,GACrBkF,YAAW,WACT9O,OAAOiK,QACH4E,GAAM,EAAKjF,UAAU,MAAM,KAC9B,MAELmF,cAdO,WAeLtJ,KAAK0E,gBAAiB,EACtB,IAAIzG,EAAU4C,SAAS0I,eAAe,WAClCC,EAAQ,IAAI,gBAChBA,EACGT,QAAQ9K,EAAS,CAAC,wBAAyB+B,KAAK+I,SAChDtN,MAAK,SAACgO,GACLtJ,QAAQC,IAAI,WAAYqJ,EAAKC,MAAO,cAG1CvF,UAxBO,SAwBGwF,EAAK5C,GACY/G,KAAKkE,aAAhB0F,IAAV7C,EAAoCA,GACnB/G,KAAKkE,QAC1BlE,KAAK6J,kB,UmBnHX,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,KAErD,U,mGCNRlP,MAAM,sB,gCAEiB,qB,6MAF5B,yBAgBM,MAhBN,GAgBM,CAfJ,yBAOK,WANH,yBAA4D,WAAxD,yBAAmD,GAAtCoD,GAAG,KAAG,C,YAAC,iBAAiB,C,2CACzC,yBAIK,2CAJqB,EAAA+L,OAAK,SAAnBC,EAAM/P,G,gCAAlB,yBAIK,MAJ6BA,IAAKA,GAAG,CACxC,yBAEc,GAFA+D,GAAE,gBAAW/D,I,aACzB,iBAAS,C,0DAANA,GAAG,O,+BAID,EAAAgO,OAAOvL,OAAO4F,M,yBAAzB,yBAMM,UALJ,yBAIE,EAJF,wBAIE,CAHCyD,OAAQ,EAAAA,OACRkE,MAAM,GACC,EAAAjE,SAAO,uB,4CChBR,I,8BAAA,4ygBCAA,q+KCAA,qyLH8BA,I,UAAA,CACb9M,KAAM,OACNpC,KAFa,WAGX,MAAO,CACLiT,MAAO,CACLG,SAAU,GACVC,UAAW,GACXC,IAAK,MAIXvK,SAAU,CACRkG,OADQ,WAEN,OAAO9F,KAAK8J,MAAM9J,KAAKgI,OAAOvL,OAAO4F,QAGzCrB,QAhBa,WAgBH,WACRqI,YAAW,WACL,EAAKvD,QAAU,EAAKkC,OAAOoC,MAC7BvJ,SACCyE,cAAc,EAAK0C,OAAOoC,MAC1B7E,eAAe,CACdC,SAAU,aAIb,MAELrH,QAAS,CACPkM,YADO,SACKxD,EAAKyD,GACf,IAAIC,EACF1D,GACqB,oBAAdA,EAAInH,OACXmH,EAAInH,MAAM,0BACZ,OAAK6K,EAEDD,GAAoBC,EAAQlT,OAAS,GAAKkT,EAAQ,GAC7CA,EAAQ9P,MAAM,GAAG2M,KAAK,KAExBmD,EAAQ,GALM,MAOvBC,YAbO,WAaO,WACZC,MAAMtI,KAAKtB,SAAS6J,iBAAiB,MACpCvD,SAAQ,SAAApE,GACPA,EAAEhB,iBAAiB,SAAS,SAAA4I,GACtB5H,EAAE6H,SAASnK,WAAW,YACxBN,QAAQC,IAAI2C,GACZ,EAAKf,QAAQrK,KAAKoL,EAAE6H,UACpBD,EAAEE,iBACFhK,SAASiK,OAAO,CAAChG,IAAK,e,UIxElC,MAAM,GAA2B,IAAgB,GAAQ,CAAC,CAAC,SAAS,IAAQ,CAAC,YAAY,qBAE1E,UCJT1C,GAAO,IAEE2I,kBAAa,CAC1BC,QAASC,eAAiB7I,IAC1B8I,OAAQ,CACN,CACE9I,KAAM,IACNnJ,KAAM,OACNkS,UAAWC,IAEb,CACEhJ,KAAM,QACNnJ,KAAM,OACNkS,UAAWE,IAEb,CACEjJ,KAAM,cACNnJ,KAAM,MACNiM,OAAO,EACPiG,UAAWE,IAEb,CACEjJ,KAAM,mBACNnJ,KAAM,OACNkS,UAAWC,O,0DCdbE,GAAQ,SAACnI,EAASb,GACpB,IAAIrE,EAAUsN,wBAAUpI,EAAQlF,SAAS/F,OACrCsI,EAAY,GACdmD,EAAa,GACb1D,EAAQ,GACRS,EAAmB4B,GAAiBA,EAAcD,MAAQ,GAC1D3H,EAAKyI,EAAQzI,GACb8Q,EAAerI,EAAQlF,QAAQ4E,SAAS,WAAaM,EAAQlF,QAAQwC,WAAW,OAChFgL,EAAU,oCAAoClM,KAAK4D,EAAQlF,SAEzDD,EAAOwN,EAAe,MAAQC,EAAU,OAAS,OAEjDhM,EAAK,gBAAG,sKAAH,sBACLiM,EAAUzN,EAAQ0N,SAASlM,GAG/B,GAFAiM,EAAUjB,MAAMtI,KAAKuJ,GAEjBD,EAAS,CACX,IAAIG,EAAU,4CAEd,OADA3N,EAAU2N,EAAQC,KAAK1I,EAAQlF,SAAS,GACjC,CAAEuC,UAAW,GAAImD,WAAY,GAAI1D,MAAO,GAAIS,gBAAiB,GAAIhG,GAAIA,EAAIuD,QAASoK,GAAKpK,GAAUD,KAAMA,GACzG,OAAIwN,EACF,CAAEhL,UAAW,GAAImD,WAAY,GAAI1D,MAAO,GAAIS,gBAAiB,GAAIhG,GAAIA,EAAIuD,QAAS6N,GAAiB7N,GAAUD,KAAMA,GACjH0N,EAAQrU,OAAS,GAC1BmJ,EAAYnC,EAAMF,QAAQqB,qBAAqBkM,EAAQ,GAAG,UAAU,aAChErN,EAAMF,QAAQiB,cAAcoB,KAC9BmD,EAAatF,EAAMF,QAAQC,YAAYoC,IAEzCP,EAAQyL,EAAQ,GAAG,UAAU,SAASK,MAAM,MAC5C9L,EAAQA,EAAMyC,QAAO,SAACyF,GAAD,OAAU6D,GAAa7D,MACrC,CAAE3H,YAAWmD,aAAY1D,QAAOS,kBAAiBhG,KAAIuD,UAASD,UAEvEmC,QAAQC,IAAI,gBAAiB+C,GACtB,OAGL2I,GAAmB,SAAC7N,GACtB,OAAOA,EAAQY,WAAW,MAAO,KAG/BwJ,GAAO,SAACpK,GACV,IAAIoK,EAAO,CACThI,OAAQ,GACRC,IAAK,GACLC,OAAQ,IAEN6B,EAAOnE,EACPgO,EAAWC,GAAY9J,GACvB+J,EAAMF,EAASF,MAAM,KAAKK,MAK9B,OAJA/D,EAAK/H,IACH,wDAA0D8B,EAC5DiG,EAAK9H,OAAS8L,GAAUF,GACxB9D,EAAKhI,OAAS4L,EAAS3N,QAAQ,IAAK,KAC7B+J,GAGL6D,GAAc,SAAC7M,GACjB,OAAOA,EAAI0M,MAAM,MAAMK,MAAML,MAAM,KAAKK,OAGtCC,GAAY,SAACF,GACf,IAAIG,EAAM,WACV,OAAQH,GACN,IAAK,OACHG,EAAM,OACN,MACF,IAAK,QACHA,EAAM,QACN,MACF,IAAK,MACHA,EAAM,oBACN,MAEJ,OAAOA,GAGLN,GAAe,SAAC7D,GAClB,OAAOA,EAAKzI,MAAM,aAQd6M,GAAgB,SAAApJ,GACpBA,EAAQ6D,WAAa,CACnBtM,GAAIyI,EAAQlF,QACTK,QAAQ,eAAgB,IACxBA,QAAQ,cAAe,IAC1B2I,UAAW9D,EAAQlF,QAChBK,QAAQ,eAAgB,IACxBA,QAAQ,wBAAyB,IACpC4I,MAAO/D,EAAQlF,QACZK,QAAQ,qBAAsB,IAC9BA,QAAQ,WAAY,MAKrBkO,GAAkB,SAAArJ,GACtBA,EAAQ6D,WAAa,CACnBtM,GAAIyI,EAAQlF,QACTK,QAAQ,eAAgB,IACxBA,QAAQ,YAAa,IACxB2I,UAAW9D,EAAQlF,QAChBK,QAAQ,uBAAwB,IAChCA,QAAQ,WAAY,IACvB4I,MAAO/D,EAAQlF,QACZK,QAAQ,mCAAoC,IAC5CA,QAAQ,0BAA2B,MAM3BmO,kBAAY,CAEzBC,QAAQxR,EAER6L,MAAO,CACLnM,UAAgB,EAChBkB,QAAgB,GAChBwG,cAAgB,GAChBrC,MAAgB,GAChB5D,OAAgB,GAChBsG,OAAgB,QAGlBgK,UAAW,CAETC,UAAe,SAAC7F,EAAO8F,GAAR,OAAoB9F,EAAMnM,SAAWiS,GACpDC,WAAe,SAAC/F,EAAOjL,GAAR,OAAoBiL,EAAMjL,QAAUA,GACnDiR,aAAe,SAAChG,EAAO3K,GAAR,OAAoB2K,EAAMzE,cAAgBlG,GACzD4Q,UAAe,SAACjG,EAAO1K,GAAR,OAAoB0K,EAAM1K,OAASA,GAClD4Q,WAAe,SAAClG,EAAO5D,GACjBA,EAAQlF,QAAQwC,WAAW,QAC7B8L,GAAcpJ,GAEdA,EAAQlF,QAAQ4E,SAAS,iBACzBM,EAAQlF,QAAQ4E,SAAS,eAEzB2J,GAAgBrJ,GAElB,IAAM3G,EAAQuK,EAAM1K,OAAOkG,MAAK,SAAA/F,GAAK,OAAIA,EAAMuI,OAAS5B,EAAQC,WAC5D5G,EACFA,EAAME,SAAS/E,KAAKwL,GAEpB4D,EAAM1K,OAAO1E,KAAK,CAChBoN,MAAO5B,EAAQC,QACf1G,SAAU,CAACyG,MAIjB+J,cAAe,SAACnG,EAAD,GAA6B,IAAnBxD,EAAmB,EAAnBA,IAAKH,EAAc,EAAdA,QACtB5G,EAAQuK,EAAM1K,OAAOkG,MAAK,SAAA5I,GAAC,OAAIA,EAAEoL,OAAS3B,KAChD,GAAI5G,EAAO,CACT,IAAM2G,EAAU3G,EAAME,SAAS6F,MAAK,SAAAzJ,GAAC,OAAIA,EAAE4B,IAAM6I,KAC7CJ,GACF3G,EAAME,SAASnE,OAAOiE,EAAME,SAASiC,QAAQwE,GAAU,KAI7DgK,YAAa,SAACpG,EAAD,GAA8B,IAApBxD,EAAoB,EAApBA,IAAKG,EAAe,EAAfA,SACpBP,EAAU4D,EAAM1K,OACnB6D,KAAI,SAAAvG,GAAC,OAAIA,EAAE+C,YACXwL,OACA3F,MAAK,SAAAzJ,GAAC,OAAIA,EAAE4B,IAAM6I,KACjBJ,GACFA,EAAQsD,UAAU9O,KAAK+L,IAG3B0J,eAAgB,SAACrG,EAAD,GAA8B,IAApBxD,EAAoB,EAApBA,IAAKG,EAAe,EAAfA,SACvBP,EAAU4D,EAAM1K,OACnB6D,KAAI,SAAAvG,GAAC,OAAIA,EAAE+C,YACXwL,OACA3F,MAAK,SAAAzJ,GAAC,OAAIA,EAAE4B,IAAM6I,KACjBJ,GACFA,EAAQsD,UAAUlO,OAAO4K,EAAQsD,UAAU9H,QAAQ+E,GAAW,IAGlE2J,SAAU,SAACtG,EAAO9G,GAChB8G,EAAM9G,MAAQA,EAAMqN,QAAO,SAACC,EAAKC,GAC/B,IAAIrF,EAAOmD,GAAMkC,EAAKzG,EAAMzE,eAI5B,OAHa,OAAT6F,GACFoF,EAAI5V,KAAKwQ,GAEJoF,IACN,KAELE,QAAS,SAAC1G,EAAOoB,GACK,OAAhBmD,GAAMnD,KAGRpB,EAAM9G,MAAN,0BAAkB8G,EAAM9G,OAAU,CAACqL,GAAMnD,EAAMpB,EAAMzE,mBAGzDoL,YAAa,SAAC3G,EAAD,GAA6B,IAAnBxD,EAAmB,EAAnBA,IAAKtF,EAAc,EAAdA,QACpBkF,EAAU4D,EAAM1K,OACnB6D,KAAI,SAAAvG,GAAC,OAAIA,EAAE+C,YACXwL,OACA3F,MAAK,SAAAzJ,GAAC,OAAIA,EAAE4B,IAAM6I,KACf4E,EAAOpB,EAAM9G,MAAMsC,MAAK,SAAAhJ,GAAC,OAAIA,EAAEmB,IAAM6I,KAC3C,GAAIJ,EACFA,EAAQlF,QAAUA,EACdkF,EAAQlF,QAAQwC,WAAW,QAC7B8L,GAAcpJ,GAEdA,EAAQlF,QAAQ4E,SAAS,iBACzBM,EAAQlF,QAAQ4E,SAAS,eAEzB2J,GAAgBrJ,QAEb,GAAIgF,EAAM,CAMfpB,EAAM9G,MAAM1H,OAAOwO,EAAM9G,MAAMtB,QAAQwJ,GAAO,GAC9C,IAAMwF,EAAW,GAAH,uBAAO5G,EAAM9G,OAAU,CAACqL,GAAM,CAC1C5Q,GAAI6I,EAAKtF,QAASA,GACjB8I,EAAMzE,iBACTyE,EAAM9G,MAAQ0N,IAIlBC,YAAa,SAAC7G,EAAD,GAAsC,IAA5B8G,EAA4B,EAA5BA,aAAczK,EAAc,EAAdA,QAC7B5G,EAAQuK,EAAM1K,OAAOkG,MAAK,SAAA5I,GAAC,OAAIA,EAAEoL,OAAS8I,KAC5CrR,IACFA,EAAMuI,MAAQ3B,EACd5G,EAAME,SAASyK,SAAQ,SAAArO,GAAC,OAAIA,EAAEsK,QAAUA,QAM9C0K,QAAS,GAGTC,QAAS,CAEP9N,MAAO,SAAA8G,GAAK,OAAIA,EAAM9G,OAEtB+N,eAAgB,SAAAjH,GAAK,OACnB,gBAAIA,EAAM1K,QACTqG,QAAO,SAAA/I,GAAC,OACPA,EAAE+C,SAASrF,OAAS,GACT,iBAAXsC,EAAEoL,UAINF,aAAc,SAACkC,EAAOgH,GAAR,OACZA,EAAQC,eACPlL,MAAK,SAACC,EAAEC,GAAH,OACJD,EAAEgC,MAAMkJ,cAAcjL,EAAE+B,WAAO6E,EAAW,CACxCsE,SAAc,EACdC,YAAc,gBCrQlBC,I,UAASC,uBAAUC,IAEnBC,GAAS,CACbvE,MAAc,EACdwE,SAAc,EACdC,aAAc,GAGhBL,GAAIpT,OAAO0T,iBAAiBC,MAAUC,IACtCR,GAAIpT,OAAO0T,iBAAiB3I,QAAUwI,GACtCH,GAAIpT,OAAO0T,iBAAiBG,IAAU,IAAIC,IAAWP,IAErDH,GACGW,IAAIC,KACJD,IAAIE,IACJF,IAAIG,IACJC,MAAM,S,oCC1BT,W,+GCAA,W,sq0ECAA,W,kCCAA,W,kCCAA,W,gFCAA,W,kCCAA,W","file":"js/app.185d5e35.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"app\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([0,\"chunk-vendors\"]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Toc.vue?vue&type=style&index=0&id=cdbb2ba0&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Stream.vue?vue&type=style&index=0&id=bb0c01d2&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./index.vue?vue&type=style&index=0&id=16b43aee&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Authors.vue?vue&type=style&index=0&id=e34c1616&scoped=true&lang=css\"","\n\n\n\n\n","const \n\n zulip = require(\"zulip-js\"),\n config = {\n username : process.env.VUE_APP_ZULIP_email,\n apiKey : process.env.VUE_APP_ZULIP_key,\n realm : process.env.VUE_APP_ZULIP_site,\n },\n \n init = () => ( new \n Promise((resolve, reject) => {\n zulip(config)\n .then(client => resolve(client))\n .catch(error => reject(error))\n })\n ),\n \n getStreams = client => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .retrieve()\n .then(result => resolve(result.streams))\n .catch(error => reject(error))\n })\n ),\n \n getUsers = client => ( new\n Promise((resolve, reject) => {\n client\n .users\n .retrieve()\n .then(result => resolve(result.members))\n .catch(error => reject(error))\n })\n ),\n \n getTopics = (client, stream) => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .topics\n .retrieve({ stream_id: stream })\n .then(result => resolve(result.topics))\n .catch(error => reject(error))\n })\n ),\n \n getMsgs = (client, stream, topic, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .retrieve(params || {\n anchor: \"newest\",\n num_before: 1000,\n num_after: 0,\n // apply_markdown: false,\n narrow: [\n { operator: \"stream\", operand: stream },\n { operator: \"topic\", operand: topic },\n ],\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n getAllMsgs = (client, stream, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .retrieve(params || {\n anchor: \"newest\",\n num_before: 1000,\n num_after: 0,\n // apply_markdown: false,\n narrow: [{ operator: \"stream\", operand: stream }],\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n listen = (client, cb) => {\n client\n .callOnEachEvent(\n event => cb(event), \n [ 'message' ],\n [ { operator: \"stream\", operand: \"chatty\" } ]\n )\n },\n \n getSubs = client => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .subscriptions\n .retrieve()\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n addSub = (client, stream) => ( new\n Promise((resolve, reject) => {\n client\n .users\n .me\n .subscriptions\n .add(\n {\n subscriptions: JSON.stringify([{ name: stream }]),\n }\n )\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n sendMsg = (client, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .send(params || {\n to: \"chatty\",\n type: \"stream\",\n topic: \"content\",\n content: \"I come not, friends, to steal away your hearts.\",\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n )\n\nexport default {\n init,\n config,\n getStreams,\n getUsers,\n getTopics,\n getMsgs,\n getAllMsgs,\n listen,\n sendMsg,\n getSubs,\n addSub,\n}\n","import zulip from './zulip'\n\nexport default {\n zulip\n}\n","\n\n","// let toUTF16 = (codePoint) => {\n// var TEN_BITS = parseInt(\"1111111111\", 2);\n// if (codePoint <= 0xffff) {\n// return u(codePoint);\n// }\n// codePoint -= 0x10000;\n// // Shift right to get to most significant 10 bits\n// var leadSurrogate = 0xd800 + (codePoint >> 10);\n// // Mask to get least significant 10 bits\n// var tailSurrogate = 0xdc00 + (codePoint & TEN_BITS);\n// return u(leadSurrogate) + (tailSurrogate);\n// }\n\n// let u = (codeUnit) => {\n// return \"\\\\u\" + codeUnit.toString(16).toUpperCase();\n// }\nimport zulip_emoji from \"../data/emoji_codes.json\";\n\nexport default {\n data() {\n return {\n emoji_regex: /(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*/gi\n }\n },\n\n methods: {\n toEmojiCode: (emoji) => {\n return emoji.replace(/\\p{Emoji}/gu, (m) => m.codePointAt(0).toString(16));\n },\n\n shortcodeToEmoji: (code) => {\n if (code.indexOf(\":\") !== 0) return code;\n let k = code.replaceAll(\":\", '').trim();\n let emoji = zulip_emoji.name_to_codepoint[k];\n if (!emoji) return code;\n // console.log(k, emoji, parseInt(emoji,16), String.fromCodePoint(parseInt(\"0x\"+emoji)))\n return String.fromCodePoint(parseInt(\"0x\"+emoji))\n },\n \n // toEmojiCode: (emoji) => {\n // emoji.replace(/\\p{Emoji}/gu, function (m) {\n // toUTF16(m.codePointAt(0));\n // });\n // return emoji;\n // },\n\n containsEmoji(str) {\n // Regular expression to match emoji\n const regexExp = /(\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff])/gi;\n return regexExp.test(str); // true\n },\n\n\n replaceAllEmojiCodes(content) {\n let regex = /:([^\\s]+):/gm;\n content = content.replaceAll(regex, (match) => {\n return this.shortcodeToEmoji(match);\n })\n return content;\n }\n }\n}","import { render } from \"./Styles.vue?vue&type=template&id=7b4da880\"\nimport script from \"./Styles.vue?vue&type=script&lang=js\"\nexport * from \"./Styles.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { render } from \"./App.vue?vue&type=template&id=59161f7f\"\nimport script from \"./App.vue?vue&type=script&lang=js\"\nexport * from \"./App.vue?vue&type=script&lang=js\"\n\nimport \"./App.vue?vue&type=style&index=0&id=59161f7f&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\n\n\n\n","\n\n\n\n\n","\n\n\n\n\n","\n\n\n\n\n","import { render } from \"./Toc.vue?vue&type=template&id=cdbb2ba0&scoped=true\"\nimport script from \"./Toc.vue?vue&type=script&lang=js\"\nexport * from \"./Toc.vue?vue&type=script&lang=js\"\n\nimport \"./Toc.vue?vue&type=style&index=0&id=cdbb2ba0&scoped=true&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-cdbb2ba0\"]])\n\nexport default __exports__","import { render } from \"./Stream.vue?vue&type=template&id=bb0c01d2&scoped=true\"\nimport script from \"./Stream.vue?vue&type=script&lang=js\"\nexport * from \"./Stream.vue?vue&type=script&lang=js\"\n\nimport \"./Stream.vue?vue&type=style&index=0&id=bb0c01d2&scoped=true&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-bb0c01d2\"]])\n\nexport default __exports__","import { render } from \"./index.vue?vue&type=template&id=bf028a98&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=bf028a98&scoped=true&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-bf028a98\"]])\n\nexport default __exports__","\n\n\n\n\n","\n\n\n\n\n","import { render } from \"./Authors.vue?vue&type=template&id=e34c1616&scoped=true\"\nimport script from \"./Authors.vue?vue&type=script&lang=js\"\nexport * from \"./Authors.vue?vue&type=script&lang=js\"\n\nimport \"./Authors.vue?vue&type=style&index=0&id=e34c1616&scoped=true&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-e34c1616\"]])\n\nexport default __exports__","\n\n\n\n\n","\n\n\n\n","import { render } from \"./Message.vue?vue&type=template&id=4a330fa6\"\nimport script from \"./Message.vue?vue&type=script&lang=js\"\nexport * from \"./Message.vue?vue&type=script&lang=js\"\n\nimport \"./Message.vue?vue&type=style&index=0&id=4a330fa6&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { render } from \"./Chapter.vue?vue&type=template&id=05955d29&scoped=true\"\nimport script from \"./Chapter.vue?vue&type=script&lang=js\"\nexport * from \"./Chapter.vue?vue&type=script&lang=js\"\n\nimport \"./Chapter.vue?vue&type=style&index=0&id=05955d29&scoped=true&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-05955d29\"]])\n\nexport default __exports__","import { render } from \"./index.vue?vue&type=template&id=2d35224f&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-2d35224f\"]])\n\nexport default __exports__","\n\n\n\n","\n\n\n\n","import { render } from \"./Rule.vue?vue&type=template&id=080e408c&scoped=true\"\nimport script from \"./Rule.vue?vue&type=script&lang=js\"\nexport * from \"./Rule.vue?vue&type=script&lang=js\"\n\nimport \"./Rule.vue?vue&type=style&index=0&id=080e408c&scoped=true&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-080e408c\"]])\n\nexport default __exports__","import { render } from \"./index.vue?vue&type=template&id=16b43aee&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=16b43aee&scoped=true&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-16b43aee\"]])\n\nexport default __exports__","import { render } from \"./Home.vue?vue&type=template&id=7eb04b2a\"\nimport script from \"./Home.vue?vue&type=script&lang=js\"\nexport * from \"./Home.vue?vue&type=script&lang=js\"\n\nimport \"./Home.vue?vue&type=style&index=0&id=7eb04b2a&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","/* eslint-disable */\n\n\n\n\n\n","export default \"# CSS\\n\\nIn this document we take a look at what CSS is and how it can be applied to a publication in ChattyPub.\\n## The slides based on this document can be found here.\\n\\n- [What is CSS](#what-is-css)\\n- [Rules](#rules)\\n- [Css in ChattyPub](#css-in-chattypub)\\n - [About formatting](#about-formatting)\\n - [Advanced CSS](#advanced-css)\\n- [Uploading fonts](#uploading-fonts)\\n- [Print settings](#print-settings)\\n - [Page breaks](#page-breaks)\\n- [Common CSS properties](#properties)\\n - [Backgrounds and borders](#backgrounds)\\n - [Color](#color)\\n - [Box model](#box-model)\\n - [Fonts](#fonts)\\n - [Text](#text)\\n - [Transforms](#transforms)\\n\\n---\\n\\n## What is CSS?\\n\\nCSS (Cascading Style Sheets) is the language that allows you to style and layout HTML web pages. This article explains what CSS is, with some simple syntax examples, and also covers some key terms about the language.\\n\\nSince this document relates specifically to ChattyPub, the focus is going to be on the parts of the language that are supported by this platform. Because CSS is specifically oriented towards styling HTML (and related languages like SVG and XML) you have to have a basic understanding of HTML.[1](#footnote1) Mozilla has an excellent [HTML introduction](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started).\\n\\nAt its heart, HTML is a fairly simple language made up of elements, which can be applied to pieces of text to give them different meaning in a document (Is it a paragraph? Is it a bulleted list? Is it part of a table?), structure a document into logical sections (Does it have a header? Three columns of content? A navigation menu?), and embed content such as images and videos into a page.\\nBut what HTML does not do is speficy how these elements should look. That is where CSS comes in.\\n\\nCSS can be used for very basic document text styling — for example changing the color and size of headings and links. It can be used to create layout — for example turning a single column of text into a layout with a main content area and a sidebar for related information. It can even be used for effects such as animation.\\nIn ChattyPub we're mostly interested in the first part.\\n\\n---\\n\\n## Rules\\n\\n#### _Elements and Classes_\\n\\nIn this section we will talk about CSS in general. ChattyPub uses a slight variation on it, but let's start with the basics.\\n\\nCSS is a rule-based language — you define rules specifying groups of styles that should be applied to particular elements or groups of elements on your web page. For example \\\"I want the main heading on my page to be shown as large red text.\\\"\\n\\nThe following code shows a very simple CSS rule that would achieve the styling described above:\\n\\n```css\\nh1 {\\n color: red;\\n font-size: 20px;\\n}\\n```\\n\\nThe rule opens with a selector. This selects the HTML element that we are going to style. In this case we are styling all level one headings (`

    `) that appear on the page.\\n\\nWe then have a set of curly braces `{` `}`. Inside those will be one or more declarations, which take the form of property and value pairs. Each pair specifies a property of the element(s) we are selecting, then a value that we'd like to give the property. Each pair is followed by a semi-colon `;` to indicate the end of the property.\\n\\nBefore the colon, we have the property, and after the colon, the value. CSS properties have different allowable values, depending on which property is being specified. In our example, we have the color property, which can take various color values. We also have the font-size property. This property can take various size units as a value.\\n\\nThe example above will style all the `H1` elements on the page. You could also write a selector for all paragraphs (the selector would be `p`), images (`img`) or list items (`li`). This works as long as you want all of the elements of that type in your document to look the same. Most of the time that isn't the case and so you will need to find a way to select a subset of the elements without changing the others. The most common way to do this is to add a class to your HTML element and target that class.\\n\\nTake this HTML:\\n\\n```html\\n
      \\n
    • Item one
    • \\n
    • Item two
    • \\n
    • Item three
    • \\n
    \\n```\\n\\nTo target the class of special you can create a selector that starts with a full stop character.\\n\\n```css\\n.special {\\n color: orange;\\n font-weight: bold;\\n}\\n```\\n\\nThe peroid character in front of special tells the browser that we're creating a class selector.\\nYou can apply the class of special to any element on your page that you want to have the same look as this list item.\\n\\n### Units\\n\\nIn the `h1` example above, we set the following property: `font-size: 20px;`. This will set the font-size of all H1 headers to 20 pixels. But pixels are not the only units available. Some examples:\\n\\n- `em` and `rem` - these relative units declare a size dependant on the font-size of the context they get used in. This can be a bit confusing if you're not used to it. Feel free to replace it with on of the values below.\\n- `px` - Pixels.\\n- `cm` and `in` - centimeters and inches. These units are mostly relevant in print context.\\n- `vw` and `vh` - so called viewport units, 100vw is exactly the height of the viewport (the part of the browser that shows the webpage). `vh` is the same, but for the height of the browser.\\n- `rgba(r,g,b,a)` strictly speaking not a unit but a function, but it sets the color and transparency of the foreground.\\n\\n[More information on units](https://www.w3.org/Style/Examples/007/units.en.html).\\n\\n---\\n\\n## CSS in ChattyPub\\n\\nWhen you react to a message in Zulip with an emoji, this emoji gets turned into a class in ChattyPub. So lets say you responded to a message with the strawberry 🍓 emoji. In ChattyPub the message will have class with that emoji as selector. (You can confirm this by rolling over the message, the emoji should popup on a overlay.) So now to style that message, you go to the `#rules` channel and add a message with the following content:\\n\\n```css\\n🍓 {\\n color: red;\\n}\\n```\\n\\nIt is very similar to the examples above. `🍓` is the selector, so the rule will apply to each message with a strawberry reaction. Then follows the block `{` and `}`. And in the block, there is property, `color: red;`.\\n\\n_A small difference with regular CSS is that you don't need to add the period in front of the selector ChattyPub will handle that for you._\\n\\nBecause of the way Zulip handles the emoji reactions, not all emoji are available or sometimes they don't exactly correspond to the emoji you might type in the `#rules` channel. To help with sorting this out you can roll over a message in ChattyPub and see the reactions that are applied. Sometimes the translation is unavailable, in that case you'll see something like `:working_on_it:` instead of the emoji you expected. In that case remove your reaction and find an other emoji that does work.\\n\\n### About formatting\\n\\nYou can't enter a tab character in Zulip and the indentation before the property in the rule isn't absolutely necessary. So feel free to leave it out. If you absolutely want to have the indentation, you could write the rule in your favorite editor and copy and paste it into Zulip. Make sure that the selector, each property and the closing accolade are all on their own line. __Don't forget the semi-colon at the end of each property line!__\\n\\n### Advanced CSS\\n\\n**Selecting HTML elements and other style rules**\\n\\nThe reaction/emoji method described above allows to make quick modifications to the style and layout of your publication. But besides this ChattyPub also allows you to style html elements like in regular CSS. To do this just enter your style rule. This snippet will give all HTML links a pink background color:\\n\\n```css\\na {\\n background-color: pink;\\n}\\n```\\n\\nYou should be able to enter all regular CSS rules this way.\\n\\n**Bypassing the parser** -_Work in progress_-\\n\\nIt is possible to bypass the parser and add arbitrary code to the CSS on the page. This allows you to add, for example, `@keyframes` for an animation or media queries. To do this send any message to the `#rules` channel and wrap the message in three backticks like this:\\n\\n~~~~\\n```\\n@keyframes example {\\n from {background-color: red;}\\n to {background-color: yellow;}\\n}\\n```\\n~~~~\\n\\n---\\n\\n## Uploading fonts\\n\\nIt is also possible to upload a custom font to the application. To do this, you send the font in a message to the #rules channel of the publication you want to use it in. You can use `.ttf`, `.otf` or `.woff`/`.woff2` formats depending on the browser you are using. The mesage must only contain the font, no other text. ChattyPub will then automatically generate a @font-face rule for the font. The font-family name will be based on the filename.\\n\\nOnce uploaded the font should show up in the CSS rules section of ChattyPub. To use the font in a style rule, just copy/paste the `font-family: \\\"font_name_ttf\\\";` and add it to a rule in the #rules channel.\\n\\n> Please only upload free or open-source fonts to our server!\\n\\n## Print settings\\n\\nTo set the paper size we can use the special selector `@page`. The following snippet set the page size to A5.\\n\\n```css\\n@page {\\n size: 148mm 210mm;\\n}\\n```\\n\\nThis example sets the page to landscape.\\n\\n```css\\n@page {\\n size: landscape;\\n}\\n```\\n\\nWe've tried to get the browser to add crop and alignment marks, but we've haven't been able to get it to work. If you do, please let us know!\\n\\n```css\\n@page {\\n marks: crop cross;\\n}\\n```\\n\\nRegrettably [browser support](https://caniuse.com/css-paged-media) for `@page` is spotty. Currently only MS Edge, Opera and Google Chrome will allow you to set page sizes etc, and even then it is a matter of trial and error.\\n\\nThe [Paged media module](https://developer.mozilla.org/en-US/docs/Web/CSS/Paged_Media) at Mozilla has an excellent explanation on using `@page`.\\n\\n### page breaks\\n\\nBy default pages will automatically wrap to the next page. And ChattyPub adds a page break after each topic. If you want to force a page break you could write a rule for it, using the `page-break-after: always;` property:\\n\\n```css\\n🍏 {\\n page-break-after: always;\\n}\\n```\\n\\nIf you don't want the page break after an article you can overwrite the default by using:\\n\\n```css\\n.body {\\n page-break-after: avoid;\\n}\\n```\\n\\nFor some of these rules it may be necessary to use the methods described under [Advanced CSS](#advanced-css) above to enter these rules.\\n\\n## List of common and handy CSS properties\\n\\nThere are hundreds of CSS properties. Below is a small selection of some basic properties mostly focussed on layout and type representation, grouped by module.\\n\\n### Backgrounds and borders\\n\\n- [background-color](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color)\\n- [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) - The border CSS property sets an element's border.\\n- [border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius) - The border-radius CSS property rounds the corners of an element's outer border edge.\\n- [box-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow) - The box-shadow CSS property adds shadow effects around an element's frame.\\n\\n### Color\\n\\n- [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) - The color CSS property sets the foreground color value of an element's text and text decorations.\\n- [opacity](https://developer.mozilla.org/en-US/docs/Web/CSS/opacity) - The opacity CSS property sets the opacity of an element. Opacity is the degree to which content behind an element is hidden, and is the opposite of transparency.\\n\\nA colors value can defined in multiple ways:\\n\\n- By [name/keyword](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#keywords) - `color: red;` will make your text red.\\n- By [hex value](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#hex) - `color: #ff0000;` also red.\\n- Or as a [function](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#rgba), which allows transparency. - `color: rgba(255,0,0,0.5);` red, but 50% transparent.\\n\\n### Box model\\n\\n- [margin](https://developer.mozilla.org/en-US/docs/Web/CSS/margin) - The margin property sets the margin area on all four sides of an element. Margin refers to space between different elements.\\n- [padding](https://developer.mozilla.org/en-US/docs/Web/CSS/padding) - The padding property sets the padding area on all four sides of an element at once. Padding refers to the spacing inside the border of an element.\\n\\n### Fonts\\n\\n- [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) - The font-family CSS property specifies a prioritized list of one or more font family names and/or generic family names for the selected element.\\n\\nYou can choose one of the following generic fonts. Which exact font will be used is dependant on your computers' settings.\\n\\n```css\\nfont-family: serif;\\nfont-family: sans-serif;\\nfont-family: monospace;\\nfont-family: cursive;\\nfont-family: fantasy;\\n```\\n\\nIt is also possible to specify an exact font name, but it will only be used if it is actually available on your system.\\nFor example following statement will try to use Helvetica if available, but will fallback on a generic sans-serif font if not. (Note the quotes around the font name).\\n\\n```css\\nfont-family: \\\"Helvetica Neue\\\", sans-serif;\\n```\\n\\nAlso see the section on uploading fonts below.\\n\\n- [font-size](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size) - The font-size CSS property sets the size of the font. Changing the font size also updates the sizes of the font size-relative units, such as em, ex, and so forth.\\n- [font-style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style) - The font-style CSS property sets whether a font should be styled with a normal, italic, or oblique face from its font-family.\\n- [font-weigh](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) - The font-weight CSS property sets the weight (or boldness) of the font. The weights available depend on the font-family that is currently set.\\n- [line-height](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height) - The line-height CSS property sets the height of a line box. It's commonly used to set the distance between lines of text.\\n\\n### Text\\n\\n- [letter-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/letter-spacing) - The letter-spacing CSS property sets the horizontal spacing behavior between text characters.\\n- [text-align](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) - The text-align CSS property sets the horizontal alignment of the content inside a block element.\\n- [text-transform](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) - The text-transform CSS property specifies how to capitalize an element's text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.\\n- [white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) - The white-space CSS property sets how white space inside an element is handled.\\n- [word-break](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break) - The word-break CSS property sets whether line breaks appear wherever the text would otherwise overflow its content box.\\n- [word-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/word-spacing) - The word-spacing CSS property sets the length of space between words and between tags.\\n- [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) - The text-shadow CSS property adds shadows to text.\\n\\n### Transforms\\n\\n- [rotate](https://developer.mozilla.org/en-US/docs/Web/CSS/rotate) - The rotate CSS property allows you to specify rotation of elements\\n- [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/scale) - The scale CSS property allows you to specify the scale (size) of elements\\n- [translate](https://developer.mozilla.org/en-US/docs/Web/CSS/translate) - The translate CSS property allows you to specify translation transforms (position relative to where it originally was) of elements.\\n\\n1: I've borrowed shamelessly from Mozilla to make this text: https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps/What_is_CSS and https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML\\n\";","export default \"# ChattyPub Workshop Script\\n\\n## Introduction\\n\\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication.\\n\\nThe workshop will explore in a practical manner how the process of co-designing a publication can unfold, specifically when several people are working at the same time using a chat interface as the main design tool. During HDSA2021 we would like to open up the process of making this tool and explore together its possibilities and limitations. The workshop will take place towards the end of the one-week summer academy program. Thus, we will be able to use some of the documentation produced during the week — workshops scripts, prototypes, game cards, recipes, ... as well as conversations we will have on different platforms – synchronously and asynchronously.\\n\\nCommands allow you to style the texts and images, but someone else can change their appearance again later! How will we negotiate these design decisions synchronously and asynchronously? The outcome could be a zine, posters or a webpage.\\n\\nThis script aims to provide the necessary instructions to host a workshop around ChattyPub that can accomodate different skills and knowledges in different contexts.\\n\\n## Goals\\n\\n- Learn to collaboratively write, design, and print documents using ChattyPub\\n- Produce publications of / relating to HDSA2021 (documentation, prototypes, conversations, etc...)\\n- Learn and/or practice styling with CSS & Emojis\\n\\n## Requirements\\n\\n- a computer, web-browser, and connection to the internet\\n- an account for the Hackers & Designers Zulip instance: https://chat.hackersanddesigners.nl/\\n- a printer\\n\\n## Preparation\\n\\nBefore the summer academy: Most important is for all workshop participants to set up a Zulip account on our server. The H&D zulip instance can be found at https://chat.hackersanddesigners.nl/ (public sign ups are temporariy open).\\n\\nOn the first day of the summer academy (monday): Participants are introduced to the Zulip interface and instructed to use it for communication during the course of the week. Zulip makes use of a rather unconventional (but powerful) chat-threading logic, so it would be good to spend some time interacting with it and settle into this new environment.\\n\\nWorkshop hosts and participants are encouraged to think about how they would like to document their processes during the summer academy. What is included and what isn't? How is this shared? Is there a regular moment during the day dedicated to documentation or is it more ad-hoc? We suggest using Etherpad for collaborative note taking, and regularly making screenshots or screenrecordings and photos. We have previously compiled a so-called \\\"tool-ecology\\\", a list of tools we have good experiences with and recommend using during the summer academy: https://etherpad.hackersanddesigners.nl/p/hdsa2021-tool-ecology.\\n\\nTexts, notes, chats, images, and screenshots will make great material for our workshop.\\n\\n## How It Works\\n\\nFor an overview of how ChattyPub works with Zulip, go [here](/docs/Chattypub).\\n## Workshop\\n\\nThe workshop is split over two sessions (over two days) of 4 hours each.\\n\\n_Opening Session: Introductions & first encounters with ChattyPub_\\n\\n- Introductory presentation ( 1hr ) -- will be livestreamed in the morning / recorded and shared afterwards.\\n - Context and background on H&D's publishing activities (Anja & Juliette) [slides](https://hackersanddesigners.github.io/chatty-pub-css-slides/assets/hdsa-chattypub-intro.pdf)\\n - Introduction to ChattyPub (Karl).\\n - Introduction to CSS (Heerko). [slides](https://hackersanddesigners.github.io/chatty-pub-css-slides/)\\n - How it all comes together (emojis ;])(Karl)\\n- Experimenting with ChattyPub! ( 2 hrs )\\n - participants with different levels of experience of CSS are grouped together\\n - each group follows [these instructions](/docs/Chattypub#content) to make one publication in ChattyPub\\n - detailed instructions about CSS can be found [here](/docs/CSS)\\n- Brainstorm Session (1 hr)\\n - in groups of 2-3, participants brainstorm publications they will make during the main session \\n - The goal is to document together, in print, parts of the summer academy.\\n - What have you been up to this last week?\\n - What did you make? What material did you collect / produce?\\n - How will you negotiate this design process?\\n - Are roles divided and then switched? \\n - If you are planning to print your publication, take into account the printing limitations of your home printer or local print shop.\\n - Print settings such as the page size and orientation can all be configure with CSS.\\n - If participants are joining remotely, it's good that they are paired together.\\n\\n_Main Session: Chat => Print_\\n\\n- Making publications ( 2 hrs )\\n - Groups work on the publications planned in the previous session \\n - Each group makes a stream on Zulip for the publiction\\n - They create chapters for their contents\\n - They create a \\\"rules\\\" topic for their styles\\n - Organizers are available to help where needed\\n - At least one or two people per node should be able to help with CSS.\\n - Karl and Heerko will be available if bugs / errors occur.\\n- Printing Publications ( 1 hr )\\n - A printer is required in the space (or easily accessible)\\n - Accommodating for different paper sizes is an added bonus\\n - Binding could be fun too\\n- Sharing outcomes and reflections ( 1 hr ) \\n - Round of publications\\n - Reflection on process\\n - Feedback on ChattyPub\\n\";","export default \"# ChattyPub\\n\\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication. ChattyPub is a collaborative publication/zine-making tool built on top of the chat platform [Zulip](https://chat.hackersanddesigners.nl). By sending messages, reacting with emoji and writing simple CSS style rules the publication can be collectively designed.\\n\\n- [Zulip](#zulip)\\n- [ChattyPub](#using-chattypub)\\n- [Making a publication with Zulip & ChattyPub](#content)\\n - [Content](#content)\\n - [Rules](#rules)\\n - [Printing](#printing)\\n- [Typing Emoji](#typing-emoji)\\n- [Problems?](#problems)\\n\\n## Zulip\\n\\nOn Zulip, conversations are categorized into different \\\"Streams\\\", which are comparable to \\\"channels\\\" in other messaging services like Discord. Streams can be public or private and host conversations consisting of text, images, files, reactions, etc..\\n\\nWhat differentiates Zulip from most messaging platforms is the way streams are sub-threaded. Zulip introduces the concept of \\\"Topics\\\", which, in the plainest terms, means that messages have subjects. When sending a message to a stream in Zulip, you can also specify the topic of the message and the stream automatically filters messages by their shared topics. If your message's topic doesn't exist yet, it will be created when you send your message.\\n\\nZulip allows you to react to messages using emoji's as well. We will make heavy use of emojis in ChattyPub.\\n\\nThere are several ways to engage with Zulip, including a web-client, a desktop app, and a mobile app.\\n\\n## Using ChattyPub\\n\\nhttp://chatty-pub.hackersanddesigners.nl\\n\\nChattyPub is a website that acts as a different interface to the same Zulip service. ChattyPub takes a stream from Zulip, combines messages into long-form articles and uses a design system combining Emojis and CSS syntax to style the messages, effectively turning the stream into a (printable!) webpage.\\n\\n## Making a publication with Zulip & ChattyPub\\n\\n### Content\\n\\n1. Create a stream on Zulip\\n - Ensure that either (1) the stream name starts with `pub-` or (2) the stream descriptio includes this text:`_PUB_`.\\n - Ensure that the stream name does not have any uderscores.\\n - Ensure that the stream is public.\\n2. Go to [ChattyPub](https://chatty-pub.hackersanddesigners.nl). The stream you created will be visible on the left-side navigation.\\n3. Click on your stream.\\n4. The main (middle) section of the website will have:\\n 1. Your stream name (which will be the name of your publication)\\n 2. The topics of your stream organized into a table of contents (which will act as \\\"Chapters\\\" in your publication)\\n 3. The topics, in alphabetical order, displaying their messages, in chronological order.\\n5. To create a new topic (chapter), return to Zulip and type a message to your stream, making sure to send it to the topic you want to create.\\n\\n### Rules\\n\\nThe right-hand side of the ChattyPub interface is reserved for one topic in your stream: \\\"rules\\\". This topic will house definitions for styles you want to apply to messages in your stream.\\n\\nGo back to Zulip and create the topic in your stream called \\\"rules\\\".\\n\\nEvery message you send to this topic should consist of a single emoji followed by a set of styles you'd like applied to messages. For example:\\n\\n```CSS\\n🍓 {\\n color: red;\\n text-decoration: underline;\\n}\\n```\\n\\nThese messages should be unique and follow the CSS syntax, as described in the [introduction to CSS](/docs/CSS). If you are comfortable with CSS, you can skip to the part of the document that describes [how CSS is used in ChattyPub](/docs/CSS#css-in-chattypub).\\n\\nTo apply these styles to the contents of your publication, head back to any other topic in your stream, select a message you'd like to style, and react to it with the emoji whose styles you want to apply. On ChattyPub, the message should be rendered with these styles.\\n\\nIf you'd like to style only a part of a message, select the message in Zulip and quote and respond to it (in the 3-dot menu). This will produce a text in your input box on the bottom of the interface. Delete the parts of the quoted message that you don't want the styles applied to, and send your response. When you react with an emoji to your own response, the part of the original message you quoted will inherit the styles defined for that emoji.\\n\\nKeep in mind that you can edit your own messages! So if you make a mistake (forgetting the semi-colon at the end of a statement is a common one), roll over your message and click the little pen at the top righthand side of the message.\\n\\n### Printing\\n\\n> Regrettably support for setting page size, page breaks etc. using [@page](https://caniuse.com/css-paged-media) is very poor in some browsers. Use MS Edge, Opera or Google Chrome for best results when printing or creating PDFs.\\n\\nTo print, click on the print button on the left side of the application. This will hide the interface, make all content visible and open the browsers' Printing dialog box.\\n\\nIf you want to use background colors or background images in your publication you may have to turn that on in the print settings dialog.\\n\\nThere is more information on setting up pages sizes etc, in the CSS document.\\n\\n## Typing Emoji\\n\\n- [Windows](https://support.microsoft.com/en-us/windows/windows-10-keyboard-tips-and-tricks-588e0b72-0fff-6d3f-aeee-6e5116097942)\\n- [Mac](https://www.howtogeek.com/684025/how-to-type-emoji-on-your-mac-with-a-keyboard-shortcut/)\\n- Linux varies per distribution. If you run Linux you're probably capable of finding out how :)\\n\\n## Problems\\n\\nChattyPub is very young and you're sure to run into problems. Feel free to contact `@Karl Moubarak`, `@andré` or `@heerko` at https://chat.hackersanddesigners.nl/\\n\\nBelow are some things that we know of, and are working on:\\n\\n- :emoji: not working...\\n\";","import { render } from \"./Docs.vue?vue&type=template&id=32f02ba2&scoped=true\"\nimport script from \"./Docs.vue?vue&type=script&lang=js\"\nexport * from \"./Docs.vue?vue&type=script&lang=js\"\n\nimport \"./Docs.vue?vue&type=style&index=0&id=32f02ba2&scoped=true&lang=css\"\n\nimport exportComponent from \"/Users/km/Desktop/CHATTYPUB/front/node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-32f02ba2\"]])\n\nexport default __exports__","import { createRouter, createWebHistory } from 'vue-router'\n\nimport Home from '../views/Home'\nimport Docs from '../views/Docs.vue'\n\nconst path = '/' \n\nexport default createRouter({\n history: createWebHistory(path),\n routes: [\n {\n path: '/',\n name: 'Home',\n component: Home,\n },\n {\n path: '/docs',\n name: 'Docs',\n component: Docs,\n },\n {\n path: '/docs/:slug',\n name: 'Doc',\n props: true,\n component: Docs,\n },\n {\n path: '/:pathMatch(.*)*',\n name: 'Home',\n component: Home,\n },\n ],\n})\n\n\n","/*eslint no-unused-vars: \"off\"*/\n/*eslint no-undef: \"off\"*/\n\n// import Vue from 'vue'\nimport { createStore } from 'vuex'\nimport emoji from \"../mixins/emoji\"\nimport { stripHtml } from \"string-strip-html\"\n\n/* \n\nTODO: fix this frankenfunction. Its not pretty but it works, so I am leaving it for now. \n\nDoes various conversion and parsing to turn a message in the rules channel into an object we can use in the rules and style component \n\n*/\nlet toCSS = (message, currentStream) => {\n let content = stripHtml(message.content).result;\n let className = \"\",\n emoji_code = \"\",\n rules = [],\n parentClassName = (currentStream && currentStream.slug || \"\"),\n id = message.id,\n is_codeblock = message.content.includes(\"\") || message.content.startsWith(\"```\"),\n is_font = /

    .+)\\s*\\n?{\\n?(?(.*;\\n?)+)}/gm\n let results = content.matchAll(regex);\n results = Array.from(results);\n\n if (is_font) { // font\n let re_path = /\\/user_uploads(\\/.*?\\.(?:ttf|otf|woff))/gm;\n content = re_path.exec(message.content)[1];\n return { className: '', emoji_code: '', rules: [], parentClassName: '', id: id, content: font(content), type: type }\n } else if (is_codeblock) {\n return { className: '', emoji_code: '', rules: [], parentClassName: '', id: id, content: cleanupCodeBlock(content), type: type }\n } else if (results.length > 0) { // rule and raw\n className = emoji.methods.replaceAllEmojiCodes(results[0]['groups']['selector']);\n if (emoji.methods.containsEmoji(className)) {\n emoji_code = emoji.methods.toEmojiCode(className);\n }\n rules = results[0]['groups']['props'].split(\"\\n\");\n rules = rules.filter((rule) => validateRule(rule))\n return { className, emoji_code, rules, parentClassName, id, content, type };\n }\n console.log(\"rejected rule\", message)\n return null;\n}\n\nlet cleanupCodeBlock = (content) => {\n return content.replaceAll('```', '');\n}\n\nlet font = (content) => {\n let font = {\n family: \"\",\n src: \"\",\n format: \"\",\n };\n let path = content;\n let filename = getFilename(path);\n let ext = filename.split(\".\").pop();\n font.src =\n \"https://chatty-pub-files.hackersanddesigners.nl/files\" + path;\n font.format = getFormat(ext);\n font.family = filename.replace(\".\", \"_\");\n return font;\n}\n\nlet getFilename = (str) => {\n return str.split(\"\\\\\").pop().split(\"/\").pop();\n}\n\nlet getFormat = (ext) => {\n let fmt = \"truetype\";\n switch (ext) {\n case 'woff':\n fmt = \"woff\";\n break;\n case 'woff2':\n fmt = \"woff2\";\n break;\n case 'eof':\n fmt = \"embedded-opentype\";\n break;\n }\n return fmt;\n}\n\nlet validateRule = (rule) => {\n return rule.match(/.+:.+;/gm);\n}\n\n// parsing replies, there are two scenarios:\n// we are either getting the message as plain markdown\n// or we are getting the message pre-rendered as HTML (default Zulip behaviour)\n// see /src/api/zulip/index.js line 36\n\nconst handleMDReply = message => {\n message.responseTo = {\n id: message.content\n .replace(/.*\\/near\\//gm, '')\n .replace(/\\):.*[^]+/gm, ''),\n sender_id: message.content\n .replace(/@_\\*\\*.*\\|/gm, '')\n .replace(/\\*\\*.\\[said\\].*[^]+/gm, ''),\n quote: message.content\n .replace(/[^]+.*```quote\\n/gm, '')\n .replace(/ \\n```/gm, '')\n }\n // console.log(message.responseTo)\n}\n\nconst handleHTMLReply = message => {\n message.responseTo = {\n id: message.content\n .replace(/.*\\/near\\//gm, '')\n .replace(/\".*[^]+/gm, ''),\n sender_id: message.content\n .replace(/[^]+data-user-id=\"/gm, '')\n .replace(/\">[^]+/gm, ''),\n quote: message.content\n .replace(/.*[^]+<\\/p>\\n

    \\n

    /gm, '')\n .replace(/<\\/p>\\n<\\/blockquote>/gm, '')\n // .replace(/\\n/gm, '')\n }\n // console.table(message.responseTo)\n}\n\nexport default createStore({\n\n strict: process.env.NODE_ENV !== 'production',\n\n state: {\n isMobile : false,\n streams : [],\n currentStream : {},\n rules : [],\n topics : [],\n pubStr : 'pub-',\n },\n\n mutations: {\n\n setMobile : (state, mobile) => state.isMobile = mobile,\n setStreams : (state, streams) => state.streams = streams,\n setCurStream : (state, stream) => state.currentStream = stream,\n setTopics : (state, topics) => state.topics = topics,\n addMessage : (state, message) => {\n if (message.content.startsWith('@_**')) {\n handleMDReply(message)\n } else if (\n message.content.includes('user-mention') &&\n message.content.includes('blockquote')\n ) {\n handleHTMLReply(message)\n }\n const topic = state.topics.find(topic => topic.title == message.subject)\n if (topic) {\n topic.messages.push(message)\n } else {\n state.topics.push({\n title: message.subject,\n messages: [message]\n })\n }\n },\n deleteMessage: (state, { mid, subject }) => {\n const topic = state.topics.find(t => t.title == subject)\n if (topic) {\n const message = topic.messages.find(m => m.id == mid)\n if (message) {\n topic.messages.splice(topic.messages.indexOf(message), 1)\n }\n }\n },\n addReaction: (state, { mid, reaction }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n if (message) {\n message.reactions.push(reaction)\n }\n },\n removeReaction: (state, { mid, reaction }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n if (message) {\n message.reactions.splice(message.reactions.indexOf(reaction), 1)\n }\n },\n setRules: (state, rules) => {\n state.rules = rules.reduce((acc, cur) => {\n let rule = toCSS(cur, state.currentStream);\n if (rule !== null) {\n acc.push(rule);\n }\n return acc\n }, [])\n },\n addRule: (state, rule) => {\n if (toCSS(rule) !== null) {\n // state.rules.push(toCSS(rule, state.currentStream))\n // vue will not update if i use rules.push(rule)\n state.rules = [...state.rules, ...[toCSS(rule, state.currentStream)]]\n }\n },\n editMessage: (state, { mid, content }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n const rule = state.rules.find(r => r.id == mid)\n if (message) {\n message.content = content\n if (message.content.startsWith('@_**')) {\n handleMDReply(message)\n } else if (\n message.content.includes('user-mention') &&\n message.content.includes('blockquote')\n ) {\n handleHTMLReply(message)\n }\n } else if (rule) {\n // state.rules[state.rules.indexOf(rule)] = toCSS({\n // id: mid, content: content,\n // }, state.currentStream)\n\n // vue will not update if i use rules.push(rule) \n state.rules.splice(state.rules.indexOf(rule), 1)\n const newRules = [...state.rules, ...[toCSS({\n id: mid, content: content,\n }, state.currentStream)]]\n state.rules = newRules\n }\n },\n\n updateTopic: (state, { orig_subject, subject }) => {\n const topic = state.topics.find(t => t.title == orig_subject)\n if (topic) {\n topic.title = subject\n topic.messages.forEach(m => m.subject = subject)\n }\n }\n\n },\n\n actions: {\n },\n\n getters: {\n\n rules: state => state.rules,\n\n filteredTopics: state => (\n [...state.topics]\n .filter(t => (\n t.messages.length > 0 &&\n t.title != 'stream events'\n ))\n ),\n\n sortedTopics: (state, getters) => (\n getters.filteredTopics\n .sort((a,b) => \n a.title.localeCompare(b.title, undefined, { \n numeric : true,\n sensitivity : 'base'\n })\n )\n )\n }\n\n})\n","import { createApp } from 'vue'\nimport App from './App'\nimport Axios from 'axios'\nimport MarkdownIt from 'markdown-it'\nimport VueMarkdownIt from 'vue3-markdown-it'\nimport router from './router'\nimport store from './store'\n\nimport 'highlight.js/styles/vs.css';\n\nconst app = createApp(App)\n\nconst mdOpts = {\n html : true,\n linkify : true,\n typographer : true\n}\n\napp.config.globalProperties.$http = Axios\napp.config.globalProperties.$mdOpts = mdOpts\napp.config.globalProperties.$md = new MarkdownIt(mdOpts)\n\napp\n .use(VueMarkdownIt)\n .use(router)\n .use(store)\n .mount('#app')\n","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./index.vue?vue&type=style&index=0&id=bf028a98&scoped=true&lang=css\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Home.vue?vue&type=style&index=0&id=7eb04b2a&lang=css\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Docs.vue?vue&type=style&index=0&id=32f02ba2&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Chapter.vue?vue&type=style&index=0&id=05955d29&scoped=true&lang=css\"","export * from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./App.vue?vue&type=style&index=0&id=59161f7f&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Message.vue?vue&type=style&index=0&id=4a330fa6&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Rule.vue?vue&type=style&index=0&id=080e408c&scoped=true&lang=css\""],"sourceRoot":""} \ No newline at end of file diff --git a/front/dist/js/app.343fd0d3.js b/front/dist/js/app.343fd0d3.js deleted file mode 100644 index b29bcbc..0000000 --- a/front/dist/js/app.343fd0d3.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(e){function t(t){for(var o,r,i=t[0],c=t[1],l=t[2],d=0,p=[];d"),n="https://chat.hackersanddesigners.nl";t=t.replaceAll('src="','src="'+n),t=t.replaceAll('href="/','href="'+n+"/"),t=t.replaceAll(n+"/user_uploads/","https://chatty-pub-files.hackersanddesigners.nl/files/");var o=this.$store.state.topics.find((function(t){return t.title==e.message.subject})).messages.filter((function(t){return t.responseTo&&t.responseTo.id==e.message.id&&t.responseTo.sender_id==e.message.sender_id&&e.message.content.includes(t.responseTo.quote)}));return o.forEach((function(e){var n=e.reactions.map((function(e){return"u"+e.emoji_code})).join(" ");t=t.replace(e.responseTo.quote,'').concat(e.responseTo.quote,""))})),t},reactions:function(){return this.message.reactions.map((function(e){return me.replace_colons(":"+e.emoji_name+":")}))},classes:function(){return this.message.reactions.map((function(e){return e.emoji_code+" u"+e.emoji_code}))},time:function(){var e=this.message.timestamp,t=1e3*e,n=new Date(t);return n.toLocaleString()}},created:function(){}};n("d022");fe.render=pe;var be=fe,ge={name:"Chapter",components:{Message:be},data:function(){return{}},props:["topic","show_message_data"],computed:{messagesToShow:function(){return this.topic.messages.filter((function(e){return!e.responseTo}))}}};n("df14");ge.render=se,ge.__scopeId="data-v-80b6d17a";var ye=ge,we={name:"Content",components:{Chapter:ye},props:["print","show_message_data"],computed:Object(i["a"])(Object(i["a"])(Object(i["a"])({},Object(c["c"])(["currentStream","streams"])),Object(c["b"])(["sortedTopics"])),{},{title:function(){var e=this;return this.streams.find((function(t){return t.name==e.currentStream}))?this.currentStream.replace("pub-",""):"Stream does not exist."}}),methods:{toValidID:function(e){return encodeURIComponent("ch-"+e).toLowerCase().replace(/\.|%[0-9a-z]{2}/gi,"")},goTo:function(e){document.querySelector(".".concat(this.currentStream," ").concat(e)).scrollIntoView({behavior:"smooth"})}}};n("1782");we.render=X,we.__scopeId="data-v-c018ffc4";var ve=we,Se=Object(o["withScopeId"])("data-v-16b43aee");Object(o["pushScopeId"])("data-v-16b43aee");var je={class:"rules"};Object(o["popScopeId"])();var ke=Se((function(e,t,n,a,s,r){var i=Object(o["resolveComponent"])("Rule");return Object(o["openBlock"])(),Object(o["createBlock"])("section",je,[(Object(o["openBlock"])(!0),Object(o["createBlock"])(o["Fragment"],null,Object(o["renderList"])(e.rules,(function(e){return Object(o["openBlock"])(),Object(o["createBlock"])(i,{key:e.id,rule:e},null,8,["rule"])})),128))])})),Oe=Object(o["withScopeId"])("data-v-080e408c");Object(o["pushScopeId"])("data-v-080e408c");var Ce={key:0},De={key:1},_e={class:"instructions"},xe=Object(o["createTextVNode"])("Add the follow to your rule to use this font:"),Te=Object(o["createVNode"])("br",null,null,-1),Be=Object(o["createVNode"])("p",null,"}",-1);Object(o["popScopeId"])();var Ee=Oe((function(e,t,n,a,s,r){return Object(o["openBlock"])(),Object(o["createBlock"])("div",{class:["rule",r.classes],style:r.rules},["raw"===n.rule.type?(Object(o["openBlock"])(),Object(o["createBlock"])("pre",Ce,Object(o["toDisplayString"])(r.contentFiltered)+"\n ",1)):"font"===n.rule.type?(Object(o["openBlock"])(),Object(o["createBlock"])("span",De,[Object(o["createVNode"])("pre",{style:r.rules},'@font-face { \n font-family: "'+Object(o["toDisplayString"])(r.font.family)+'"; \n src: "'+Object(o["toDisplayString"])(r.font.src)+'" format('+Object(o["toDisplayString"])("font.format")+"); \n}",5),Object(o["createVNode"])("div",_e,[Object(o["createVNode"])("span",null,[xe,Te,Object(o["createTextVNode"])(' font-family: "'+Object(o["toDisplayString"])(r.font.family)+'"; ',1)])])])):(Object(o["openBlock"])(),Object(o["createBlock"])(o["Fragment"],{key:2},[Object(o["createVNode"])("p",{title:e.toEmojiCode(n.rule.className)},Object(o["toDisplayString"])(n.rule.className)+" {",9,["title"]),(Object(o["openBlock"])(!0),Object(o["createBlock"])(o["Fragment"],null,Object(o["renderList"])(n.rule.rules,(function(e){return Object(o["openBlock"])(),Object(o["createBlock"])("p",{key:e},"  "+Object(o["toDisplayString"])(e),1)})),128)),Be],64))],6)})),ze={name:"Rule",mixins:[k],props:["rule"],computed:{contentFiltered:function(){var e=this,t=this.emoji_regex,n=this.rule.content.replace(t,(function(t){return t+", .u"+e.toEmojiCode(t)}));return n},classes:function(){return"type-"+this.rule.type},font:function(){return this.rule.content},rules:function(){return"font"!==this.rule.type?this.rule.rules:["font-family: "+this.font.family+";"]}}};n("c251");ze.render=Ee,ze.__scopeId="data-v-080e408c";var Fe=ze,Pe={name:"Rules",components:{Rule:Fe},computed:Object(i["a"])({},Object(c["c"])(["rules"])),watch:{rules:function(){console.log("rules")}}};n("5476");Pe.render=ke,Pe.__scopeId="data-v-16b43aee";var Ie=Pe,Ne=n("512e"),Ve=(n("c1ea"),n("676e")),Ae={name:"Home",components:{Streams:Y,Content:ve,Rules:Ie,Splitpanes:Ne["Splitpanes"],Pane:Ne["Pane"]},setup:function(){var e=Object(o["ref"])(null);return{preview:e}},data:function(){return{show_ui:!0,show_message_data:!1,panel_sizes:{0:10,1:55,2:35},expand_content:!1}},computed:{classes:function(){return this.show_ui?"ui":"print"},currentStream:function(){return this.$store.state.currentStream}},methods:{resizer:function(e){for(var t=0;t[1](#footnote1) Mozilla has an excellent [HTML introduction](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started).\n\nAt its heart, HTML is a fairly simple language made up of elements, which can be applied to pieces of text to give them different meaning in a document (Is it a paragraph? Is it a bulleted list? Is it part of a table?), structure a document into logical sections (Does it have a header? Three columns of content? A navigation menu?), and embed content such as images and videos into a page.\nBut what HTML does not do is speficy how these elements should look. That is where CSS comes in.\n\nCSS can be used for very basic document text styling — for example changing the color and size of headings and links. It can be used to create layout — for example turning a single column of text into a layout with a main content area and a sidebar for related information. It can even be used for effects such as animation.\nIn ChattyPub we're mostly interested in the first part.\n\n---\n\n## Rules\n\n#### _Elements and Classes_\n\nIn this section we will talk about CSS in general. ChattyPub uses a slight variation on it, but let's start with the basics.\n\nCSS is a rule-based language — you define rules specifying groups of styles that should be applied to particular elements or groups of elements on your web page. For example \"I want the main heading on my page to be shown as large red text.\"\n\nThe following code shows a very simple CSS rule that would achieve the styling described above:\n\n```css\nh1 {\n color: red;\n font-size: 20px;\n}\n```\n\nThe rule opens with a selector. This selects the HTML element that we are going to style. In this case we are styling all level one headings (`

    `) that appear on the page.\n\nWe then have a set of curly braces `{` `}`. Inside those will be one or more declarations, which take the form of property and value pairs. Each pair specifies a property of the element(s) we are selecting, then a value that we'd like to give the property. Each pair is followed by a semi-colon `;` to indicate the end of the property.\n\nBefore the colon, we have the property, and after the colon, the value. CSS properties have different allowable values, depending on which property is being specified. In our example, we have the color property, which can take various color values. We also have the font-size property. This property can take various size units as a value.\n\nThe example above will style all the `H1` elements on the page. You could also write a selector for all paragraphs (the selector would be `p`), images (`img`) or list items (`li`). This works as long as you want all of the elements of that type in your document to look the same. Most of the time that isn't the case and so you will need to find a way to select a subset of the elements without changing the others. The most common way to do this is to add a class to your HTML element and target that class.\n\nTake this HTML:\n\n```html\n
      \n
    • Item one
    • \n
    • Item two
    • \n
    • Item three
    • \n
    \n```\n\nTo target the class of special you can create a selector that starts with a full stop character.\n\n```css\n.special {\n color: orange;\n font-weight: bold;\n}\n```\n\nThe peroid character in front of special tells the browser that we're creating a class selector.\nYou can apply the class of special to any element on your page that you want to have the same look as this list item.\n\n### Units\n\nIn the `h1` example above, we set the following property: `font-size: 20px;`. This will set the font-size of all H1 headers to 20 pixels. But pixels are not the only units available. Some examples:\n\n- `em` and `rem` - these relative units declare a size dependant on the font-size of the context they get used in. This can be a bit confusing if you're not used to it. Feel free to replace it with on of the values below.\n- `px` - Pixels.\n- `cm` and `in` - centimeters and inches. These units are mostly relevant in print context.\n- `vw` and `vh` - so called viewport units, 100vw is exactly the height of the viewport (the part of the browser that shows the webpage). `vh` is the same, but for the height of the browser.\n- `rgba(r,g,b,a)` strictly speaking not a unit but a function, but it sets the color and transparency of the foreground.\n\n[More information on units](https://www.w3.org/Style/Examples/007/units.en.html).\n\n---\n\n## CSS in ChattyPub\n\nWhen you react to a message in Zulip with an emoji, this emoji gets turned into a class in ChattyPub. So lets say you responded to a message with the strawberry 🍓 emoji. In ChattyPub the message will have class with that emoji as selector. (You can confirm this by rolling over the message, the emoji should popup on a overlay.) So now to style that message, you go to the `#rules` channel and add a message with the following content:\n\n```css\n🍓 {\n color: red;\n}\n```\n\nIt is very similar to the examples above. `🍓` is the selector, so the rule will apply to each message with a strawberry reaction. Then follows the block `{` and `}`. And in the block, there is property, `color: red;`.\n\n_A small difference with regular CSS is that you don't need to add the period in front of the selector ChattyPub will handle that for you._\n\nBecause of the way Zulip handles the emoji reactions, not all emoji are available or sometimes they don't exactly correspond to the emoji you might type in the `#rules` channel. To help with sorting this out you can roll over a message in ChattyPub and see the reactions that are applied. Sometimes the translation is unavailable, in that case you'll see something like `:working_on_it:` instead of the emoji you expected. In that case remove your reaction and find an other emoji that does work.\n\n### About formatting\n\nYou can't enter a tab character in Zulip and the indentation before the property in the rule isn't absolutely necessary. So feel free to leave it out. If you absolutely want to have the indentation, you could write the rule in your favorite editor and copy and paste it into Zulip. If you only want to style a single property you could have the whole rule on a single line like this: `🌕 { box-shadow: 0 0 20px rgba(255,0,0,0.5); }`,\n\n_Don't forget the semi-colon at the end of the property line!_\n\n### Advanced CSS\n\n**Selecting HTML elements and other style rules**\n\nThe reaction/emoji method described above allows to make quick modifications to the style and layout of your publication. But besides this ChattyPub also allows you to style html elements like in regular CSS. To do this just enter your style rule. This snippet will give all HTML links a pink background color:\n\n```css\na {\n background-color: pink;\n}\n```\n\nYou should be able to enter all regular CSS rules this way.\n\n**Bypassing the parser** -_Work in progress_-\n\nIt is possible to bypass the parser and add arbitrary code to the CSS on the page. This allows you to add, for example, `@keyframes` for an animation or media queries. To do this send any message to the #rules channel and wrap the message in three backticks like this:\n\n\n```\n@keyframes example {\n from {background-color: red;}\n to {background-color: yellow;}\n}\n```\n\n\n---\n\n## Uploading fonts\n\nIt is also possible to upload a custom font to the application. To do this, you send the font in a message to the #rules channel of the publication you want to use it in. You can use `.ttf`, `.otf` or `.woff` formats depending on the browser you are using. The mesage must only contain the font, no other text. ChattyPub will then automatically generate a @font-face rule for the font. The font-family name will be based on the filename.\n\nOnce uploaded the font should show up in the CSS rules section of ChattyPub. To use the font in a style rule, just copy/paste the `font-family: \"font_name_ttf\";` and add it to a rule in the #rules channel.\n\n> Please only upload free or open-source fonts to our server!\n\n## Print settings\n\nTo set the paper size we can use the special selector `@page`. The following snippet set the page size to A5.\n\n```css\n@page {\n size: 148mm 210mm;\n}\n```\n\nRegrettably [browser support](https://caniuse.com/css-paged-media) for `@page` is spotty. Currently only MS Edge, Opera and Google Chrome will allow you to set page sizes etc.\n\n[Pagedmedia.org](https://www.pagedmedia.org/pagedjs-sneak-peeks/) has an excellent explanation on using `@page`. The [Paged media module](https://developer.mozilla.org/en-US/docs/Web/CSS/Paged_Media) at Mozilla as well.\n\n### page breaks\n\nBy default pages will automatically wrap to the next page. And ChattyPub adds a page break after each topic. If you want to force a page break you could write a rule for it, using the `page-break-after: always;` property:\n\n```\n📄 {\npage-break-after: always;\n}\n```\n\nFor some of these rules it may be necessary to use the methods described under [Advanced CSS](#advanced-css) above to enter these rules.\n\n## List of common and handy CSS properties\n\nThere are hundreds of CSS properties. Below is a small selection of some basic properties mostly focussed on layout and type representation, grouped by module.\n\n### Backgrounds and borders\n\n- [background-color](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color)\n- [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) - The border CSS property sets an element's border.\n- [border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius) - The border-radius CSS property rounds the corners of an element's outer border edge.\n- [box-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow) - The box-shadow CSS property adds shadow effects around an element's frame.\n\n### Color\n\n- [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) - The color CSS property sets the foreground color value of an element's text and text decorations.\n- [opacity](https://developer.mozilla.org/en-US/docs/Web/CSS/opacity) - The opacity CSS property sets the opacity of an element. Opacity is the degree to which content behind an element is hidden, and is the opposite of transparency.\n\nA colors value can defined in multiple ways:\n\n- By [name/keyword](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#keywords) - `color: red;` will make your text red.\n- By [hex value](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#hex) - `color: #ff0000;` also red.\n- Or as a [function](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#rgba), which allows transparency. - `color: rgba(255,0,0,0.5);` red, but 50% transparent.\n\n### Box model\n\n- [margin](https://developer.mozilla.org/en-US/docs/Web/CSS/margin) - The margin property sets the margin area on all four sides of an element. Margin refers to space between different elements.\n- [padding](https://developer.mozilla.org/en-US/docs/Web/CSS/padding) - The padding property sets the padding area on all four sides of an element at once. Padding refers to the spacing inside the border of an element.\n\n### Fonts\n\n- [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) - The font-family CSS property specifies a prioritized list of one or more font family names and/or generic family names for the selected element.\n\nYou can choose one of the following generic fonts. Which exact font will be used is dependant on your computers' settings.\n\n```css\nfont-family: serif;\nfont-family: sans-serif;\nfont-family: monospace;\nfont-family: cursive;\nfont-family: fantasy;\n```\n\nIt is also possible to specify an exact font name, but it will only be used if it is actually available on your system.\nFor example following statement will try to use Helvetica if available, but will fallback on a generic sans-serif font if not. (Note the quotes around the font name).\n\n```css\nfont-family: \"Helvetica Neue\", sans-serif;\n```\n\nAlso see the section on uploading fonts below.\n\n- [font-size](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size) - The font-size CSS property sets the size of the font. Changing the font size also updates the sizes of the font size-relative units, such as em, ex, and so forth.\n- [font-style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style) - The font-style CSS property sets whether a font should be styled with a normal, italic, or oblique face from its font-family.\n- [font-weigh](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) - The font-weight CSS property sets the weight (or boldness) of the font. The weights available depend on the font-family that is currently set.\n- [line-height](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height) - The line-height CSS property sets the height of a line box. It's commonly used to set the distance between lines of text.\n\n### Text\n\n- [letter-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/letter-spacing) - The letter-spacing CSS property sets the horizontal spacing behavior between text characters.\n- [text-align](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) - The text-align CSS property sets the horizontal alignment of the content inside a block element.\n- [text-transform](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) - The text-transform CSS property specifies how to capitalize an element's text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.\n- [white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) - The white-space CSS property sets how white space inside an element is handled.\n- [word-break](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break) - The word-break CSS property sets whether line breaks appear wherever the text would otherwise overflow its content box.\n- [word-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/word-spacing) - The word-spacing CSS property sets the length of space between words and between tags.\n- [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) - The text-shadow CSS property adds shadows to text.\n\n### Transforms\n\n- [rotate](https://developer.mozilla.org/en-US/docs/Web/CSS/rotate) - The rotate CSS property allows you to specify rotation of elements\n- [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/scale) - The scale CSS property allows you to specify the scale (size) of elements\n- [translate](https://developer.mozilla.org/en-US/docs/Web/CSS/translate) - The translate CSS property allows you to specify translation transforms (position relative to where it originally was) of elements.\n\n
    1: I've borrowed shamelessly from Mozilla to make this text: https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps/What_is_CSS and https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML\n"),$e="# ChattyPub Workshop Script\n\n## Introduction\n\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication.\n\nThe workshop will explore in a practical manner how the process of co-designing a publication can unfold, specifically when several people are working at the same time using a chat interface as the main design tool. During HDSA2021 we would like to open up the process of making this tool and explore together its possibilities and limitations. The workshop will take place towards the end of the one-week summer academy program. Thus, we will be able to use some of the documentation produced during the week — workshops scripts, prototypes, game cards, recipes, ... as well as conversations we will have on different platforms – synchronously and asynchronously.\n\nCommands allow you to style the texts and images, but someone else can change their appearance again later! How will we negotiate these design decisions synchronously and asynchronously? The outcome could be a zine, posters or a webpage.\n\nThis script aims to provide the necessary instructions to host a workshop around ChattyPub that can accomodate different skills and knowledges in different contexts.\n\n## Goals\n\n- Learn to collaboratively write, design, and print documents using ChattyPub\n- Produce publications of / relating to HDSA2021 (documentation, prototypes, conversations, etc...)\n- Learn and/or practice styling with CSS & Emojis\n\n## Requirements\n\n- a computer, web-browser, and connection to the internet\n- an account for the Hackers & Designers Zulip instance: https://chat.hackersanddesigners.nl/\n- a printer\n\n## Preparation\n\nBefore the summer academy: Most important is for all workshop participants to set up a Zulip account on our server. The H&D zulip instance can be found at https://chat.hackersanddesigners.nl/ (public sign ups are temporariy open).\n\nOn the first day of the summer academy (monday): Participants are introduced to the Zulip interface and instructed to use it for communication during the course of the week. Zulip makes use of a rather unconventional (but powerful) chat-threading logic, so it would be good to spend some time interacting with it and settle into this new environment.\n\nWorkshop hosts and participants are encouraged to think about how they would like to document their processes during the summer academy. What is included and what isn't? How is this shared? Is there a regular moment during the day dedicated to documentation or is it more ad-hoc? We suggest using Etherpad for collaborative note taking, and regularly making screenshots or screenrecordings and photos. We have previously compiled a so-called \"tool-ecology\", a list of tools we have good experiences with and recommend using during the summer academy: https://etherpad.hackersanddesigners.nl/p/hdsa2021-tool-ecology.\n\nTexts, notes, chats, images, and screenshots will make great material for our workshop.\n\n## How It Works\n\nFor an overview of how ChattyPub works with Zulip, go [here](#Chattypub).\n## Workshop\n\nThe workshop is split over two sessions (over two days) of 4 hours each.\n\n_Opening Session: Introductions & first encounters with ChattyPub_\n\n- Introductory presentation ( 1hr ) -- will be livestreamed in the morning / recorded and shared afterwards.\n - Context and background on H&D's publishing activities (Anja & Juliette)\n - Introduction to ChattyPub (Karl).\n - Introduction to CSS (Heerko).\n - How it all comes together (emojis ;])(Karl)\n- Experimenting with ChattyPub! ( 2 hrs )\n - participants with different levels of experience of CSS are grouped together\n - each group follows [these instructions](#content) to make one publication in ChattyPub\n - detailed instructions about CSS can be found [here](#CSS)\n- Brainstorm Session (1 hr) [also for the brainstorm it would be nice to add some suggestions for how to do this if you are not in Amsterdam and maybe not even togeter in a room.]\n - in groups of 2-3, participants brainstorm publications they will make during the main session [Is this brainstorm about content? or about the negotiation process for the layout? can we come up with a format for the brainstorm or some questions as an aid?]\n - If you are planning to print your publication, take into account the printing limitations of your home printer or local print shop [take into account in what way? regarding the format? will i need to adjust something in the css? or in regards to bw/color? ]\n\n_Main Session: Chat => Print_\n\n- Making publications ( 2 hrs )\n - Groups work on the publications planned in the previous session [how? will there be channels prepared? are people making their own channels?]\n - Organizers are available to help where needed [who are the organizers? in vienna and pittsburgh people will be online on their own.. how do they prepare for that?]\n- Printing Publications ( 1 hr )\n - A printer is required in the space (or easily accessible)\n - Accommodating for different paper sizes is an added bonus\n - Binding could be fun too\n- Sharing outcomes and reflections ( 1 hr ) [add link and time in different time zones]\n - Round of publications\n - Reflection on process\n - Feedback on ChattyPub\n",qe='# ChattyPub\n\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication. ChattyPub is a collaborative publication/zine-making tool built on top of the chat platform [Zulip](https://chat.hackersanddesigners.nl). By sending messages, reacting with emoji and writing simple CSS style rules the publication can be collectively designed.\n\n- [Zulip](#zulip)\n- [ChattyPub](#using-chattypub)\n- [Making a publication with Zulip & ChattyPub](#content)\n - [Content](#content)\n - [Rules](#rules)\n - [Printing](#printing)\n- [Typing Emoji](#typing-emoji)\n- [Problems?](#problems)\n\n## Zulip\n\nOn Zulip, conversations are categorized into different "Streams", which are comparable to "channels" in other messaging services like Discord. Streams can be public or private and host conversations consisting of text, images, files, reactions, etc..\n\nWhat differentiates Zulip from most messaging platforms is the way streams are sub-threaded. Zulip introduces the concept of "Topics", which, in the plainest terms, means that messages have subjects. When sending a message to a stream in Zulip, you can also specify the topic of the message and the stream automatically filters messages by their shared topics. If your message\'s topic doesn\'t exist yet, it will be created when you send your message.\n\nZulip allows you to react to messages using emoji\'s as well. We will make heavy use of emojis in ChattyPub.\n\nThere are several ways to engage with Zulip, including a web-client, a desktop app, and a mobile app.\n\n## Using ChattyPub\n\nhttp://chatty-pub.hackersanddesigners.nl\n\nChattyPub is a website that acts as a different interface to the same Zulip service. ChattyPub takes a stream from Zulip, combines messages into long-form articles and uses a design system combining Emojis and CSS syntax to style the messages, effectively turning the stream into a (printable!) webpage.\n\n## Making a publication with Zulip & ChattyPub\n\n### Content\n\n1. Create a stream on Zulip\n - Ensure that either (1) the stream name starts with `pub-` or (2) the stream includes a topic called "rules" (more on that later).\n - Ensure that the stream is public.\n2. Go to [ChattyPub](https://chatty-pub.hackersanddesigners.nl). The stream you created will be visible on the left-side navigation.\n3. Click on your stream.\n4. The main (middle) section of the website will have:\n 1. Your stream name (which will be the name of your publication)\n 2. The topics of your stream organized into a table of contents (which will act as "Chapters" in your publication)\n 3. The topics, in alphabetical order, displaying their messages, in chronological order.\n5. To create a new topic (chapter), return to Zulip and type a message to your stream, making sure to send it to the topic you want to create.\n\n### Rules\n\nThe right-hand side of the ChattyPub interface is reserved for one topic in your stream: "rules". This topic will house definitions for styles you want to apply to messages in your stream.\n\nGo back to Zulip and create the topic in your stream called "rules".\n\nEvery message you send to this topic should consist of a single emoji followed by a set of styles you\'d like applied to messages. For example:\n\n```CSS\n🍓 {\n color: red;\n text-decoration: underline;\n}\n```\n\nThese messages should be unique and follow the CSS syntax, as described in the [introduction to CSS](#CSS). If you are comfortable with CSS, you can skip to the part of the document that describes [how CSS is used in ChattyPub](#css-in-chatty-pub).\n\nTo apply these styles to the contents of your publication, head back to any other topic in your stream, select a message you\'d like to style, and react to it with the emoji whose styles you want to apply. On ChattyPub, the message should be rendered with these styles.\n\nIf you\'d like to style only a part of a message, select the message in Zulip and quote and respond to it (in the 3-dot menu). This will produce a text in your input box on the bottom of the interface. Delete the parts of the quoted message that you don\'t want the styles applied to, and send your response. When you react with an emoji to your own response, the part of the original message you quoted will inherit the styles defined for that emoji.\n\nKeep in mind that you can edit your own messages! So if you make a mistake (forgetting the semi-colon at the end of a statement is a common one), roll over your message and click the little pen at the top righthand side of the message.\n\n### Printing\n\n> Regrettably support for setting page size, page breaks etc. using [@page](https://caniuse.com/css-paged-media) is very poor in some browsers. Use MS Edge, Opera or Google Chrome for best results when printing or creating PDFs.\n\nTo print, click on the print button on the left side of the application. This will hide the interface, make all content visible and open the browsers\' Printing dialog box.\n\nIf you want to use background colors or background images in your publication you may have to turn that on in the print settings dialog.\n\nThere is more information on setting up pages sizes etc, in the CSS document.\n\n## Typing Emoji\n\n- [Windows](https://support.microsoft.com/en-us/windows/windows-10-keyboard-tips-and-tricks-588e0b72-0fff-6d3f-aeee-6e5116097942)\n- [Mac](https://www.howtogeek.com/684025/how-to-type-emoji-on-your-mac-with-a-keyboard-shortcut/)\n- Linux varies per distribution. If you run Linux you\'re probably capable of finding out how :)\n\n## Problems\n\nChattyPub is very young and you\'re sure to run into problems. Feel free to contact `@Karl Moubarak`, `@andré` or `@heerko` at https://chat.hackersanddesigners.nl/\n\nBelow are some things that we know of, and are working on:\n\n- :emoji: not working...\n',Ge=(n("e4cb"),{name:"Docs",components:[F.a],data:function(){return{files:{Workshop:$e,Chattypub:qe,CSS:Ze},selected:""}},computed:{source:function(){return this.files[this.selected]}},methods:{select:function(e){this.selected=e},getFileName:function(e,t){var n=e&&"function"===typeof e.match&&e.match(/\/?([^/.]*)\.?([^/]*)$/);return n?t&&n.length>2&&n[2]?n.slice(1).join("."):n[1]:null}}});n("8001");Ge.render=Re,Ge.__scopeId="data-v-b2769a1a";var Ye=Ge,Je="/",Ke=Object(P["a"])({history:Object(P["b"])(Je),routes:[{path:"/",name:"Home",component:Me},{path:"/docs",name:"Docs",component:Ye},{path:"/:pathMatch(.*)*",name:"Home",component:Me}]}),Qe=n("2909"),Xe=n("9558"),et=(n("a1f0"),n("a630"),n("3ca3"),n("1276"),n("a434"),n("0481"),n("4e82"),n("cd8a")),tt=n("edbf"),nt=new tt,ot=function(e,t){var n=Object(et["stripHtml"])(e.content).result,o="",a="",s=[],r=t,i=e.id,c=e.content.includes("")||e.content.startsWith("```"),l=/

    0?(o=nt.replace_colons(p[0]["groups"]["selector"]),k.methods.containsEmoji(o)&&(a=k.methods.toEmojiCode(o)),s=p[0]["groups"]["props"].split("\n"),s=s.filter((function(e){return it(e)})),{className:o,emoji_code:a,rules:s,parentClassName:r,id:i,content:n,type:u}):null},at=function(e){var t={family:"",src:"",format:""},n=e,o=st(n),a=o.split(".").pop();return t.src="https://chatty-pub-files.hackersanddesigners.nl/files"+n,t.format=rt(a),t.family=o.replace(".","_"),t},st=function(e){return e.split("\\").pop().split("/").pop()},rt=function(e){var t="truetype";switch(e){case"woff":t="woff";break;case"eof":t="embedded-opentype";break}return t},it=function(e){return e.match(/.+:.+;/gm)},ct=function(e){e.responseTo={id:e.content.replace(/.*\/near\//gm,"").replace(/\):.*[^]+/gm,""),sender_id:e.content.replace(/@_\*\*.*\|/gm,"").replace(/\*\*.\[said\].*[^]+/gm,""),quote:e.content.replace(/[^]+.*```quote\n/gm,"").replace(/ \n```/gm,"")}},lt=function(e){e.responseTo={id:e.content.replace(/.*\/near\//gm,"").replace(/".*[^]+/gm,""),sender_id:e.content.replace(/[^]+data-user-id="/gm,"").replace(/">[^]+/gm,""),quote:e.content.replace(/.*[^]+<\/p>\n

    \n

    /gm,"").replace(/<\/p>\n<\/blockquote>/gm,"")},console.table(e.responseTo)},ut=Object(c["a"])({strict:!1,state:{isMobile:!1,streams:[],currentStream:"",rules:[],topics:[],pubStr:"pub-"},mutations:{setMobile:function(e,t){return e.isMobile=t},setStreams:function(e,t){return e.streams=t},setCurStream:function(e,t){return e.currentStream=t},setTopics:function(e,t){return e.topics=t},addMessage:function(e,t){if(t.display_recipient==e.currentStream){t.content.startsWith("@_**")?ct(t):t.content.includes("user-mention")&&t.content.includes("blockquote")&<(t);var n=e.topics.find((function(e){return e.title==t.subject}));n?n.messages.push(t):e.topics.push({title:t.subject,messages:[t]})}},deleteMessage:function(e,t){var n=t.mid,o=t.subject,a=e.topics.find((function(e){return e.title==o}));if(a){var s=a.messages.find((function(e){return e.id==n}));s&&a.messages.splice(a.messages.indexOf(s),1)}},addReaction:function(e,t){var n=t.mid,o=t.reaction,a=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==n}));a&&a.reactions.push(o)},removeReaction:function(e,t){var n=t.mid,o=t.reaction,a=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==n}));a&&a.reactions.splice(a.reactions.indexOf(o),1)},setRules:function(e,t){e.rules=t.reduce((function(t,n){var o=ot(n,e.currentStream);return null!==o&&t.push(o),t}),[])},addRule:function(e,t){null!==ot(t)&&(e.rules=[].concat(Object(Qe["a"])(e.rules),[ot(t,e.currentStream)]))},editMessage:function(e,t){var n=t.mid,o=t.content,a=e.topics.map((function(e){return e.messages})).flat().find((function(e){return e.id==n})),s=e.rules.find((function(e){return e.id==n}));if(a)a.content=o,a.content.startsWith("@_**")?ct(a):a.content.includes("user-mention")&&a.content.includes("blockquote")&<(a);else if(s){e.rules.splice(e.rules.indexOf(s),1);var r=[].concat(Object(Qe["a"])(e.rules),[ot({id:n,content:o},e.currentStream)]);e.rules=r}},updateTopic:function(e,t){var n=t.orig_subject,o=t.subject,a=e.topics.find((function(e){return e.title==n}));a&&(a.title=o,a.messages.forEach((function(e){return e.subject=o})))}},actions:{},getters:{rules:function(e){return e.rules},sortedTopics:function(e){return Object(Qe["a"])(e.topics).sort((function(e,t){return e.title.localeCompare(t.title)})).filter((function(e){return e.messages.length>0&&"stream events"!=e.title}))}}}),dt=(n("85e4"),Object(o["createApp"])(_)),pt={html:!0,linkify:!0,typographer:!0};dt.config.globalProperties.$http=T.a,dt.config.globalProperties.$mdOpts=pt,dt.config.globalProperties.$md=new E.a(pt),dt.use(F.a).use(Ke).use(ut).mount("#app")},"62d7":function(e,t,n){},6338:function(e,t,n){},6468:function(e,t,n){"use strict";n("10a7")},8001:function(e,t,n){"use strict";n("1d78")},"899e":function(e,t,n){},a946:function(e,t,n){},b191:function(e,t,n){},b560:function(e,t,n){"use strict";n("b191")},c251:function(e,t,n){"use strict";n("09f1")},d022:function(e,t,n){"use strict";n("62d7")},df14:function(e,t,n){"use strict";n("e1ca")},e1ca:function(e,t,n){},eebe:function(e,t,n){"use strict";n("6338")},f43e:function(e,t,n){}}); -//# sourceMappingURL=app.343fd0d3.js.map \ No newline at end of file diff --git a/front/dist/js/app.343fd0d3.js.map b/front/dist/js/app.343fd0d3.js.map deleted file mode 100644 index 2a5b3cc..0000000 --- a/front/dist/js/app.343fd0d3.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/components/Streams/index.vue?d359","webpack:///./src/components/Content/index.vue?93d5","webpack:///./src/components/Rules/index.vue?03cd","webpack:///./src/App.vue","webpack:///./src/api/zulip/index.js","webpack:///./src/api/index.js","webpack:///./src/components/Rules/Styles.vue","webpack:///./src/mixins/emoji.js","webpack:///./src/components/Rules/Styles.vue?c5e6","webpack:///./src/App.vue?97f5","webpack:///./src/views/Home.vue","webpack:///./src/components/Streams/index.vue","webpack:///./src/components/Streams/Stream.vue","webpack:///./src/components/Streams/Stream.vue?fb31","webpack:///./src/components/Streams/index.vue?8680","webpack:///./src/components/Content/index.vue","webpack:///./src/components/Content/Chapter.vue","webpack:///./src/components/Content/Message.vue","webpack:///./src/components/Content/Message.vue?3100","webpack:///./src/components/Content/Chapter.vue?28f3","webpack:///./src/components/Content/index.vue?4e8c","webpack:///./src/components/Rules/index.vue","webpack:///./src/components/Rules/Rule.vue","webpack:///./src/components/Rules/Rule.vue?1f70","webpack:///./src/components/Rules/index.vue?0ce9","webpack:///./src/views/Home.vue?c772","webpack:///./src/views/Docs.vue","webpack:///./docs/CSS.md","webpack:///./docs/Workshop.md","webpack:///./docs/Chattypub.md","webpack:///./src/views/Docs.vue?3bf9","webpack:///./src/router/index.js","webpack:///./src/store/index.js","webpack:///./src/main.js","webpack:///./src/App.vue?b754","webpack:///./src/views/Docs.vue?0756","webpack:///./src/views/Home.vue?4fa3","webpack:///./src/components/Rules/Rule.vue?3b2c","webpack:///./src/components/Content/Message.vue?990d","webpack:///./src/components/Content/Chapter.vue?a885","webpack:///./src/components/Streams/Stream.vue?6225"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","id","class","isMobile","Component","zulip","require","config","username","process","apiKey","realm","init","Promise","resolve","reject","then","client","catch","error","getStreams","streams","retrieve","getTopics","stream","topics","stream_id","getMsgs","topic","params","messages","anchor","num_before","num_after","narrow","operator","operand","getAllMsgs","listen","cb","callOnEachEvent","event","getSubs","subscriptions","addSub","users","me","add","JSON","stringify","sendMsg","send","to","type","content","emoji_regex","methods","toEmojiCode","emoji","replace","codePointAt","toString","containsEmoji","str","regexExp","test","mixins","computed","el","generateStyleRules","styles","this","rules","map","console","log","replaceAll","family","src","format","className","startsWith","parentClassName","createStyleElement","style","document","createElement","innerText","mounted","head","appendChild","watch","newStyle","replaceChild","render","components","Styles","api","zulipClient","created","$store","commit","checkIfMobile","addEventListener","$router","beforeEach","afterEach","from","path","currentStream","find","setUpDoc","innerWidth","filter","pubStr","eventHandler","includes","message","subject","message_id","mid","rendered_content","op","reaction","emoji_code","emoji_name","reaction_type","for","href","classes","show_ui","toggle_ui","resizer","size","panel_sizes","min-size","print","show_message_data","expand_content","ref","selected","props","state","__scopeId","Stream","title","sortedTopics","toValidID","goTo","messagesToShow","sender_full_name","time","source","$mdOpts","reactions","String","fromCodePoint","EmojiConvertor","emojiConv","rawJSON","url","referrers","responseTo","sender_id","quote","forEach","join","replace_colons","ts","timestamp","ts_ms","date_ob","Date","toLocaleString","Message","Chapter","string","encodeURIComponent","toLowerCase","querySelector","scrollIntoView","behavior","rule","contentFiltered","font","dec","reg","Rule","Streams","Content","Rules","Splitpanes","Pane","setup","preview","0","1","2","panels","prev","setTimeout","print_preview","getElementById","paged","flow","total","evt","undefined","$forceUpdate","files","file","select","html","Workshop","Chattypub","CSS","getFileName","includeExtension","matches","match","createRouter","history","createWebHistory","routes","component","Home","Docs","toCSS","stripHtml","is_codeblock","is_font","regex","results","matchAll","Array","re_path","exec","split","validateRule","filename","getFilename","ext","pop","getFormat","fmt","handleMDReply","handleHTMLReply","table","createStore","strict","mutations","setMobile","mobile","setStreams","setCurStream","setTopics","addMessage","display_recipient","deleteMessage","indexOf","addReaction","flat","removeReaction","setRules","reduce","acc","cur","addRule","editMessage","newRules","updateTopic","orig_subject","actions","getters","sort","a","b","localeCompare","app","createApp","App","mdOpts","linkify","typographer","globalProperties","$http","Axios","$md","MarkdownIt","use","VueMarkdownIt","router","store","mount"],"mappings":"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","file":"js/app.343fd0d3.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"app\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([0,\"chunk-vendors\"]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./index.vue?vue&type=style&index=0&id=4514be34&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./index.vue?vue&type=style&index=0&id=c018ffc4&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./index.vue?vue&type=style&index=0&id=16b43aee&scoped=true&lang=css\"","\n\n\n\n\n","const \n\n zulip = require(\"zulip-js\"),\n config = {\n username: process.env.VUE_APP_ZULIP_email,\n apiKey: process.env.VUE_APP_ZULIP_key,\n realm: process.env.VUE_APP_ZULIP_site,\n },\n \n init = () => ( new \n Promise((resolve, reject) => {\n zulip(config)\n .then(client => resolve(client))\n .catch(error => reject(error))\n })\n ),\n \n getStreams = client => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .retrieve()\n .then(result => resolve(result.streams))\n .catch(error => reject(error))\n })\n ),\n \n getTopics = (client, stream) => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .topics\n .retrieve({ stream_id: stream })\n .then(result => resolve(result.topics))\n .catch(error => reject(error))\n })\n ),\n \n getMsgs = (client, stream, topic, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .retrieve(params || {\n anchor: \"newest\",\n num_before: 1000,\n num_after: 0,\n // apply_markdown: false,\n narrow: [\n { operator: \"stream\", operand: stream },\n { operator: \"topic\", operand: topic },\n ],\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n getAllMsgs = (client, stream, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .retrieve(params || {\n anchor: \"newest\",\n num_before: 1000,\n num_after: 0,\n // apply_markdown: false,\n narrow: [{ operator: \"stream\", operand: stream }],\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n listen = (client, cb) => {\n client\n .callOnEachEvent(\n event => cb(event), \n [ 'message' ],\n [ { operator: \"stream\", operand: \"chatty\" } ]\n )\n },\n \n getSubs = client => ( new\n Promise((resolve, reject) => {\n client\n .streams\n .subscriptions\n .retrieve()\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n addSub = (client, stream) => ( new\n Promise((resolve, reject) => {\n client\n .users\n .me\n .subscriptions\n .add(\n {\n subscriptions: JSON.stringify([{ name: stream }]),\n }\n )\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n ),\n \n sendMsg = (client, params) => ( new\n Promise((resolve, reject) => {\n client\n .messages\n .send(params || {\n to: \"chatty\",\n type: \"stream\",\n topic: \"content\",\n content: \"I come not, friends, to steal away your hearts.\",\n })\n .then(result => resolve(result))\n .catch(error => reject(error))\n })\n )\n\nexport default {\n init,\n config,\n getStreams,\n getTopics,\n getMsgs,\n getAllMsgs,\n listen,\n sendMsg,\n getSubs,\n addSub,\n}\n","import zulip from './zulip'\n\nexport default {\n zulip\n}\n","\n\n","// let toUTF16 = (codePoint) => {\n// var TEN_BITS = parseInt(\"1111111111\", 2);\n// if (codePoint <= 0xffff) {\n// return u(codePoint);\n// }\n// codePoint -= 0x10000;\n// // Shift right to get to most significant 10 bits\n// var leadSurrogate = 0xd800 + (codePoint >> 10);\n// // Mask to get least significant 10 bits\n// var tailSurrogate = 0xdc00 + (codePoint & TEN_BITS);\n// return u(leadSurrogate) + (tailSurrogate);\n// }\n\n// let u = (codeUnit) => {\n// return \"\\\\u\" + codeUnit.toString(16).toUpperCase();\n// }\n\nexport default {\n data() {\n return {\n emoji_regex: /(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*/gi\n }\n },\n\n methods: {\n toEmojiCode: (emoji) => {\n return emoji.replace(/\\p{Emoji}/gu, (m) => m.codePointAt(0).toString(16));\n },\n\n // toEmojiCode: (emoji) => {\n // emoji.replace(/\\p{Emoji}/gu, function (m) {\n // toUTF16(m.codePointAt(0));\n // });\n // return emoji;\n // },\n\n containsEmoji(str) {\n // Regular expression to match emoji\n const regexExp = /(\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff])/gi;\n return regexExp.test(str); // true\n },\n }\n}","import { render } from \"./Styles.vue?vue&type=template&id=7b4da880\"\nimport script from \"./Styles.vue?vue&type=script&lang=js\"\nexport * from \"./Styles.vue?vue&type=script&lang=js\"\nscript.render = render\n\nexport default script","import { render } from \"./App.vue?vue&type=template&id=6d28ae45\"\nimport script from \"./App.vue?vue&type=script&lang=js\"\nexport * from \"./App.vue?vue&type=script&lang=js\"\n\nimport \"./App.vue?vue&type=style&index=0&id=6d28ae45&lang=css\"\nscript.render = render\n\nexport default script","\n\n\n\n","\n\n\n\n","\n\n\n\n","import { render } from \"./Stream.vue?vue&type=template&id=1af39708&scoped=true\"\nimport script from \"./Stream.vue?vue&type=script&lang=js\"\nexport * from \"./Stream.vue?vue&type=script&lang=js\"\n\nimport \"./Stream.vue?vue&type=style&index=0&id=1af39708&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-1af39708\"\n\nexport default script","import { render } from \"./index.vue?vue&type=template&id=4514be34&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=4514be34&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-4514be34\"\n\nexport default script","\n\n\n\n","\n\n\n\n","\n\n\n\n","import { render } from \"./Message.vue?vue&type=template&id=76a5b3df\"\nimport script from \"./Message.vue?vue&type=script&lang=js\"\nexport * from \"./Message.vue?vue&type=script&lang=js\"\n\nimport \"./Message.vue?vue&type=style&index=0&id=76a5b3df&lang=css\"\nscript.render = render\n\nexport default script","import { render } from \"./Chapter.vue?vue&type=template&id=80b6d17a&scoped=true\"\nimport script from \"./Chapter.vue?vue&type=script&lang=js\"\nexport * from \"./Chapter.vue?vue&type=script&lang=js\"\n\nimport \"./Chapter.vue?vue&type=style&index=0&id=80b6d17a&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-80b6d17a\"\n\nexport default script","import { render } from \"./index.vue?vue&type=template&id=c018ffc4&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=c018ffc4&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-c018ffc4\"\n\nexport default script","\n\n\n\n","\n\n\n\n","import { render } from \"./Rule.vue?vue&type=template&id=080e408c&scoped=true\"\nimport script from \"./Rule.vue?vue&type=script&lang=js\"\nexport * from \"./Rule.vue?vue&type=script&lang=js\"\n\nimport \"./Rule.vue?vue&type=style&index=0&id=080e408c&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-080e408c\"\n\nexport default script","import { render } from \"./index.vue?vue&type=template&id=16b43aee&scoped=true\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport \"./index.vue?vue&type=style&index=0&id=16b43aee&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-16b43aee\"\n\nexport default script","import { render } from \"./Home.vue?vue&type=template&id=71897d50\"\nimport script from \"./Home.vue?vue&type=script&lang=js\"\nexport * from \"./Home.vue?vue&type=script&lang=js\"\n\nimport \"./Home.vue?vue&type=style&index=0&id=71897d50&lang=css\"\nscript.render = render\n\nexport default script","/* eslint-disable */\n\n\n\n\n\n","export default \"# CSS\\n\\nIn this document we take a look at what CSS is and how it can be applied to a publication in ChattyPub.\\n\\n- [What is CSS](#what-is-css)\\n- [Rules](#rules)\\n- [Css in ChattyPub](#css-in-ChattyPub)\\n- [Uploading fonts](#uploading-fonts)\\n- [Print settings](#print-settings)\\n\\n---\\n\\n## What is CSS?\\n\\nCSS (Cascading Style Sheets) is the language that allows you to style and layout HTML web pages. This article explains what CSS is, with some simple syntax examples, and also covers some key terms about the language.\\n\\nSince this document relates specifically to ChattyPub, the focus is going to be on the parts of the language that are supported by this platform. Because CSS is specifically oriented towards styling HTML (and related languages like SVG and XML) you have to have a basic understanding of HTML.[1](#footnote1) Mozilla has an excellent [HTML introduction](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started).\\n\\nAt its heart, HTML is a fairly simple language made up of elements, which can be applied to pieces of text to give them different meaning in a document (Is it a paragraph? Is it a bulleted list? Is it part of a table?), structure a document into logical sections (Does it have a header? Three columns of content? A navigation menu?), and embed content such as images and videos into a page.\\nBut what HTML does not do is speficy how these elements should look. That is where CSS comes in.\\n\\nCSS can be used for very basic document text styling — for example changing the color and size of headings and links. It can be used to create layout — for example turning a single column of text into a layout with a main content area and a sidebar for related information. It can even be used for effects such as animation.\\nIn ChattyPub we're mostly interested in the first part.\\n\\n---\\n\\n## Rules\\n\\n#### _Elements and Classes_\\n\\nIn this section we will talk about CSS in general. ChattyPub uses a slight variation on it, but let's start with the basics.\\n\\nCSS is a rule-based language — you define rules specifying groups of styles that should be applied to particular elements or groups of elements on your web page. For example \\\"I want the main heading on my page to be shown as large red text.\\\"\\n\\nThe following code shows a very simple CSS rule that would achieve the styling described above:\\n\\n```css\\nh1 {\\n color: red;\\n font-size: 20px;\\n}\\n```\\n\\nThe rule opens with a selector. This selects the HTML element that we are going to style. In this case we are styling all level one headings (`

    `) that appear on the page.\\n\\nWe then have a set of curly braces `{` `}`. Inside those will be one or more declarations, which take the form of property and value pairs. Each pair specifies a property of the element(s) we are selecting, then a value that we'd like to give the property. Each pair is followed by a semi-colon `;` to indicate the end of the property.\\n\\nBefore the colon, we have the property, and after the colon, the value. CSS properties have different allowable values, depending on which property is being specified. In our example, we have the color property, which can take various color values. We also have the font-size property. This property can take various size units as a value.\\n\\nThe example above will style all the `H1` elements on the page. You could also write a selector for all paragraphs (the selector would be `p`), images (`img`) or list items (`li`). This works as long as you want all of the elements of that type in your document to look the same. Most of the time that isn't the case and so you will need to find a way to select a subset of the elements without changing the others. The most common way to do this is to add a class to your HTML element and target that class.\\n\\nTake this HTML:\\n\\n```html\\n
      \\n
    • Item one
    • \\n
    • Item two
    • \\n
    • Item three
    • \\n
    \\n```\\n\\nTo target the class of special you can create a selector that starts with a full stop character.\\n\\n```css\\n.special {\\n color: orange;\\n font-weight: bold;\\n}\\n```\\n\\nThe peroid character in front of special tells the browser that we're creating a class selector.\\nYou can apply the class of special to any element on your page that you want to have the same look as this list item.\\n\\n### Units\\n\\nIn the `h1` example above, we set the following property: `font-size: 20px;`. This will set the font-size of all H1 headers to 20 pixels. But pixels are not the only units available. Some examples:\\n\\n- `em` and `rem` - these relative units declare a size dependant on the font-size of the context they get used in. This can be a bit confusing if you're not used to it. Feel free to replace it with on of the values below.\\n- `px` - Pixels.\\n- `cm` and `in` - centimeters and inches. These units are mostly relevant in print context.\\n- `vw` and `vh` - so called viewport units, 100vw is exactly the height of the viewport (the part of the browser that shows the webpage). `vh` is the same, but for the height of the browser.\\n- `rgba(r,g,b,a)` strictly speaking not a unit but a function, but it sets the color and transparency of the foreground.\\n\\n[More information on units](https://www.w3.org/Style/Examples/007/units.en.html).\\n\\n---\\n\\n## CSS in ChattyPub\\n\\nWhen you react to a message in Zulip with an emoji, this emoji gets turned into a class in ChattyPub. So lets say you responded to a message with the strawberry 🍓 emoji. In ChattyPub the message will have class with that emoji as selector. (You can confirm this by rolling over the message, the emoji should popup on a overlay.) So now to style that message, you go to the `#rules` channel and add a message with the following content:\\n\\n```css\\n🍓 {\\n color: red;\\n}\\n```\\n\\nIt is very similar to the examples above. `🍓` is the selector, so the rule will apply to each message with a strawberry reaction. Then follows the block `{` and `}`. And in the block, there is property, `color: red;`.\\n\\n_A small difference with regular CSS is that you don't need to add the period in front of the selector ChattyPub will handle that for you._\\n\\nBecause of the way Zulip handles the emoji reactions, not all emoji are available or sometimes they don't exactly correspond to the emoji you might type in the `#rules` channel. To help with sorting this out you can roll over a message in ChattyPub and see the reactions that are applied. Sometimes the translation is unavailable, in that case you'll see something like `:working_on_it:` instead of the emoji you expected. In that case remove your reaction and find an other emoji that does work.\\n\\n### About formatting\\n\\nYou can't enter a tab character in Zulip and the indentation before the property in the rule isn't absolutely necessary. So feel free to leave it out. If you absolutely want to have the indentation, you could write the rule in your favorite editor and copy and paste it into Zulip. If you only want to style a single property you could have the whole rule on a single line like this: `🌕 { box-shadow: 0 0 20px rgba(255,0,0,0.5); }`,\\n\\n_Don't forget the semi-colon at the end of the property line!_\\n\\n### Advanced CSS\\n\\n**Selecting HTML elements and other style rules**\\n\\nThe reaction/emoji method described above allows to make quick modifications to the style and layout of your publication. But besides this ChattyPub also allows you to style html elements like in regular CSS. To do this just enter your style rule. This snippet will give all HTML links a pink background color:\\n\\n```css\\na {\\n background-color: pink;\\n}\\n```\\n\\nYou should be able to enter all regular CSS rules this way.\\n\\n**Bypassing the parser** -_Work in progress_-\\n\\nIt is possible to bypass the parser and add arbitrary code to the CSS on the page. This allows you to add, for example, `@keyframes` for an animation or media queries. To do this send any message to the #rules channel and wrap the message in three backticks like this:\\n\\n\\n```\\n@keyframes example {\\n from {background-color: red;}\\n to {background-color: yellow;}\\n}\\n```\\n\\n\\n---\\n\\n## Uploading fonts\\n\\nIt is also possible to upload a custom font to the application. To do this, you send the font in a message to the #rules channel of the publication you want to use it in. You can use `.ttf`, `.otf` or `.woff` formats depending on the browser you are using. The mesage must only contain the font, no other text. ChattyPub will then automatically generate a @font-face rule for the font. The font-family name will be based on the filename.\\n\\nOnce uploaded the font should show up in the CSS rules section of ChattyPub. To use the font in a style rule, just copy/paste the `font-family: \\\"font_name_ttf\\\";` and add it to a rule in the #rules channel.\\n\\n> Please only upload free or open-source fonts to our server!\\n\\n## Print settings\\n\\nTo set the paper size we can use the special selector `@page`. The following snippet set the page size to A5.\\n\\n```css\\n@page {\\n size: 148mm 210mm;\\n}\\n```\\n\\nRegrettably [browser support](https://caniuse.com/css-paged-media) for `@page` is spotty. Currently only MS Edge, Opera and Google Chrome will allow you to set page sizes etc.\\n\\n[Pagedmedia.org](https://www.pagedmedia.org/pagedjs-sneak-peeks/) has an excellent explanation on using `@page`. The [Paged media module](https://developer.mozilla.org/en-US/docs/Web/CSS/Paged_Media) at Mozilla as well.\\n\\n### page breaks\\n\\nBy default pages will automatically wrap to the next page. And ChattyPub adds a page break after each topic. If you want to force a page break you could write a rule for it, using the `page-break-after: always;` property:\\n\\n```\\n📄 {\\npage-break-after: always;\\n}\\n```\\n\\nFor some of these rules it may be necessary to use the methods described under [Advanced CSS](#advanced-css) above to enter these rules.\\n\\n## List of common and handy CSS properties\\n\\nThere are hundreds of CSS properties. Below is a small selection of some basic properties mostly focussed on layout and type representation, grouped by module.\\n\\n### Backgrounds and borders\\n\\n- [background-color](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color)\\n- [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) - The border CSS property sets an element's border.\\n- [border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius) - The border-radius CSS property rounds the corners of an element's outer border edge.\\n- [box-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow) - The box-shadow CSS property adds shadow effects around an element's frame.\\n\\n### Color\\n\\n- [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) - The color CSS property sets the foreground color value of an element's text and text decorations.\\n- [opacity](https://developer.mozilla.org/en-US/docs/Web/CSS/opacity) - The opacity CSS property sets the opacity of an element. Opacity is the degree to which content behind an element is hidden, and is the opposite of transparency.\\n\\nA colors value can defined in multiple ways:\\n\\n- By [name/keyword](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#keywords) - `color: red;` will make your text red.\\n- By [hex value](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#hex) - `color: #ff0000;` also red.\\n- Or as a [function](http://web.simmons.edu/~grovesd/comm244/notes/week3/css-colors#rgba), which allows transparency. - `color: rgba(255,0,0,0.5);` red, but 50% transparent.\\n\\n### Box model\\n\\n- [margin](https://developer.mozilla.org/en-US/docs/Web/CSS/margin) - The margin property sets the margin area on all four sides of an element. Margin refers to space between different elements.\\n- [padding](https://developer.mozilla.org/en-US/docs/Web/CSS/padding) - The padding property sets the padding area on all four sides of an element at once. Padding refers to the spacing inside the border of an element.\\n\\n### Fonts\\n\\n- [font-family](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) - The font-family CSS property specifies a prioritized list of one or more font family names and/or generic family names for the selected element.\\n\\nYou can choose one of the following generic fonts. Which exact font will be used is dependant on your computers' settings.\\n\\n```css\\nfont-family: serif;\\nfont-family: sans-serif;\\nfont-family: monospace;\\nfont-family: cursive;\\nfont-family: fantasy;\\n```\\n\\nIt is also possible to specify an exact font name, but it will only be used if it is actually available on your system.\\nFor example following statement will try to use Helvetica if available, but will fallback on a generic sans-serif font if not. (Note the quotes around the font name).\\n\\n```css\\nfont-family: \\\"Helvetica Neue\\\", sans-serif;\\n```\\n\\nAlso see the section on uploading fonts below.\\n\\n- [font-size](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size) - The font-size CSS property sets the size of the font. Changing the font size also updates the sizes of the font size-relative units, such as em, ex, and so forth.\\n- [font-style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style) - The font-style CSS property sets whether a font should be styled with a normal, italic, or oblique face from its font-family.\\n- [font-weigh](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight) - The font-weight CSS property sets the weight (or boldness) of the font. The weights available depend on the font-family that is currently set.\\n- [line-height](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height) - The line-height CSS property sets the height of a line box. It's commonly used to set the distance between lines of text.\\n\\n### Text\\n\\n- [letter-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/letter-spacing) - The letter-spacing CSS property sets the horizontal spacing behavior between text characters.\\n- [text-align](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) - The text-align CSS property sets the horizontal alignment of the content inside a block element.\\n- [text-transform](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform) - The text-transform CSS property specifies how to capitalize an element's text. It can be used to make text appear in all-uppercase or all-lowercase, or with each word capitalized.\\n- [white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space) - The white-space CSS property sets how white space inside an element is handled.\\n- [word-break](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break) - The word-break CSS property sets whether line breaks appear wherever the text would otherwise overflow its content box.\\n- [word-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/word-spacing) - The word-spacing CSS property sets the length of space between words and between tags.\\n- [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) - The text-shadow CSS property adds shadows to text.\\n\\n### Transforms\\n\\n- [rotate](https://developer.mozilla.org/en-US/docs/Web/CSS/rotate) - The rotate CSS property allows you to specify rotation of elements\\n- [scale](https://developer.mozilla.org/en-US/docs/Web/CSS/scale) - The scale CSS property allows you to specify the scale (size) of elements\\n- [translate](https://developer.mozilla.org/en-US/docs/Web/CSS/translate) - The translate CSS property allows you to specify translation transforms (position relative to where it originally was) of elements.\\n\\n
    1: I've borrowed shamelessly from Mozilla to make this text: https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps/What_is_CSS and https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML\\n\";","export default \"# ChattyPub Workshop Script\\n\\n## Introduction\\n\\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication.\\n\\nThe workshop will explore in a practical manner how the process of co-designing a publication can unfold, specifically when several people are working at the same time using a chat interface as the main design tool. During HDSA2021 we would like to open up the process of making this tool and explore together its possibilities and limitations. The workshop will take place towards the end of the one-week summer academy program. Thus, we will be able to use some of the documentation produced during the week — workshops scripts, prototypes, game cards, recipes, ... as well as conversations we will have on different platforms – synchronously and asynchronously.\\n\\nCommands allow you to style the texts and images, but someone else can change their appearance again later! How will we negotiate these design decisions synchronously and asynchronously? The outcome could be a zine, posters or a webpage.\\n\\nThis script aims to provide the necessary instructions to host a workshop around ChattyPub that can accomodate different skills and knowledges in different contexts.\\n\\n## Goals\\n\\n- Learn to collaboratively write, design, and print documents using ChattyPub\\n- Produce publications of / relating to HDSA2021 (documentation, prototypes, conversations, etc...)\\n- Learn and/or practice styling with CSS & Emojis\\n\\n## Requirements\\n\\n- a computer, web-browser, and connection to the internet\\n- an account for the Hackers & Designers Zulip instance: https://chat.hackersanddesigners.nl/\\n- a printer\\n\\n## Preparation\\n\\nBefore the summer academy: Most important is for all workshop participants to set up a Zulip account on our server. The H&D zulip instance can be found at https://chat.hackersanddesigners.nl/ (public sign ups are temporariy open).\\n\\nOn the first day of the summer academy (monday): Participants are introduced to the Zulip interface and instructed to use it for communication during the course of the week. Zulip makes use of a rather unconventional (but powerful) chat-threading logic, so it would be good to spend some time interacting with it and settle into this new environment.\\n\\nWorkshop hosts and participants are encouraged to think about how they would like to document their processes during the summer academy. What is included and what isn't? How is this shared? Is there a regular moment during the day dedicated to documentation or is it more ad-hoc? We suggest using Etherpad for collaborative note taking, and regularly making screenshots or screenrecordings and photos. We have previously compiled a so-called \\\"tool-ecology\\\", a list of tools we have good experiences with and recommend using during the summer academy: https://etherpad.hackersanddesigners.nl/p/hdsa2021-tool-ecology.\\n\\nTexts, notes, chats, images, and screenshots will make great material for our workshop.\\n\\n## How It Works\\n\\nFor an overview of how ChattyPub works with Zulip, go [here](#Chattypub).\\n## Workshop\\n\\nThe workshop is split over two sessions (over two days) of 4 hours each.\\n\\n_Opening Session: Introductions & first encounters with ChattyPub_\\n\\n- Introductory presentation ( 1hr ) -- will be livestreamed in the morning / recorded and shared afterwards.\\n - Context and background on H&D's publishing activities (Anja & Juliette)\\n - Introduction to ChattyPub (Karl).\\n - Introduction to CSS (Heerko).\\n - How it all comes together (emojis ;])(Karl)\\n- Experimenting with ChattyPub! ( 2 hrs )\\n - participants with different levels of experience of CSS are grouped together\\n - each group follows [these instructions](#content) to make one publication in ChattyPub\\n - detailed instructions about CSS can be found [here](#CSS)\\n- Brainstorm Session (1 hr) [also for the brainstorm it would be nice to add some suggestions for how to do this if you are not in Amsterdam and maybe not even togeter in a room.]\\n - in groups of 2-3, participants brainstorm publications they will make during the main session [Is this brainstorm about content? or about the negotiation process for the layout? can we come up with a format for the brainstorm or some questions as an aid?]\\n - If you are planning to print your publication, take into account the printing limitations of your home printer or local print shop [take into account in what way? regarding the format? will i need to adjust something in the css? or in regards to bw/color? ]\\n\\n_Main Session: Chat => Print_\\n\\n- Making publications ( 2 hrs )\\n - Groups work on the publications planned in the previous session [how? will there be channels prepared? are people making their own channels?]\\n - Organizers are available to help where needed [who are the organizers? in vienna and pittsburgh people will be online on their own.. how do they prepare for that?]\\n- Printing Publications ( 1 hr )\\n - A printer is required in the space (or easily accessible)\\n - Accommodating for different paper sizes is an added bonus\\n - Binding could be fun too\\n- Sharing outcomes and reflections ( 1 hr ) [add link and time in different time zones]\\n - Round of publications\\n - Reflection on process\\n - Feedback on ChattyPub\\n\";","export default \"# ChattyPub\\n\\nChattyPub is a design tool in the making – leveraging a chat interface to apply styles and formats to the content of a publication. ChattyPub is a collaborative publication/zine-making tool built on top of the chat platform [Zulip](https://chat.hackersanddesigners.nl). By sending messages, reacting with emoji and writing simple CSS style rules the publication can be collectively designed.\\n\\n- [Zulip](#zulip)\\n- [ChattyPub](#using-chattypub)\\n- [Making a publication with Zulip & ChattyPub](#content)\\n - [Content](#content)\\n - [Rules](#rules)\\n - [Printing](#printing)\\n- [Typing Emoji](#typing-emoji)\\n- [Problems?](#problems)\\n\\n## Zulip\\n\\nOn Zulip, conversations are categorized into different \\\"Streams\\\", which are comparable to \\\"channels\\\" in other messaging services like Discord. Streams can be public or private and host conversations consisting of text, images, files, reactions, etc..\\n\\nWhat differentiates Zulip from most messaging platforms is the way streams are sub-threaded. Zulip introduces the concept of \\\"Topics\\\", which, in the plainest terms, means that messages have subjects. When sending a message to a stream in Zulip, you can also specify the topic of the message and the stream automatically filters messages by their shared topics. If your message's topic doesn't exist yet, it will be created when you send your message.\\n\\nZulip allows you to react to messages using emoji's as well. We will make heavy use of emojis in ChattyPub.\\n\\nThere are several ways to engage with Zulip, including a web-client, a desktop app, and a mobile app.\\n\\n## Using ChattyPub\\n\\nhttp://chatty-pub.hackersanddesigners.nl\\n\\nChattyPub is a website that acts as a different interface to the same Zulip service. ChattyPub takes a stream from Zulip, combines messages into long-form articles and uses a design system combining Emojis and CSS syntax to style the messages, effectively turning the stream into a (printable!) webpage.\\n\\n## Making a publication with Zulip & ChattyPub\\n\\n### Content\\n\\n1. Create a stream on Zulip\\n - Ensure that either (1) the stream name starts with `pub-` or (2) the stream includes a topic called \\\"rules\\\" (more on that later).\\n - Ensure that the stream is public.\\n2. Go to [ChattyPub](https://chatty-pub.hackersanddesigners.nl). The stream you created will be visible on the left-side navigation.\\n3. Click on your stream.\\n4. The main (middle) section of the website will have:\\n 1. Your stream name (which will be the name of your publication)\\n 2. The topics of your stream organized into a table of contents (which will act as \\\"Chapters\\\" in your publication)\\n 3. The topics, in alphabetical order, displaying their messages, in chronological order.\\n5. To create a new topic (chapter), return to Zulip and type a message to your stream, making sure to send it to the topic you want to create.\\n\\n### Rules\\n\\nThe right-hand side of the ChattyPub interface is reserved for one topic in your stream: \\\"rules\\\". This topic will house definitions for styles you want to apply to messages in your stream.\\n\\nGo back to Zulip and create the topic in your stream called \\\"rules\\\".\\n\\nEvery message you send to this topic should consist of a single emoji followed by a set of styles you'd like applied to messages. For example:\\n\\n```CSS\\n🍓 {\\n color: red;\\n text-decoration: underline;\\n}\\n```\\n\\nThese messages should be unique and follow the CSS syntax, as described in the [introduction to CSS](#CSS). If you are comfortable with CSS, you can skip to the part of the document that describes [how CSS is used in ChattyPub](#css-in-chatty-pub).\\n\\nTo apply these styles to the contents of your publication, head back to any other topic in your stream, select a message you'd like to style, and react to it with the emoji whose styles you want to apply. On ChattyPub, the message should be rendered with these styles.\\n\\nIf you'd like to style only a part of a message, select the message in Zulip and quote and respond to it (in the 3-dot menu). This will produce a text in your input box on the bottom of the interface. Delete the parts of the quoted message that you don't want the styles applied to, and send your response. When you react with an emoji to your own response, the part of the original message you quoted will inherit the styles defined for that emoji.\\n\\nKeep in mind that you can edit your own messages! So if you make a mistake (forgetting the semi-colon at the end of a statement is a common one), roll over your message and click the little pen at the top righthand side of the message.\\n\\n### Printing\\n\\n> Regrettably support for setting page size, page breaks etc. using [@page](https://caniuse.com/css-paged-media) is very poor in some browsers. Use MS Edge, Opera or Google Chrome for best results when printing or creating PDFs.\\n\\nTo print, click on the print button on the left side of the application. This will hide the interface, make all content visible and open the browsers' Printing dialog box.\\n\\nIf you want to use background colors or background images in your publication you may have to turn that on in the print settings dialog.\\n\\nThere is more information on setting up pages sizes etc, in the CSS document.\\n\\n## Typing Emoji\\n\\n- [Windows](https://support.microsoft.com/en-us/windows/windows-10-keyboard-tips-and-tricks-588e0b72-0fff-6d3f-aeee-6e5116097942)\\n- [Mac](https://www.howtogeek.com/684025/how-to-type-emoji-on-your-mac-with-a-keyboard-shortcut/)\\n- Linux varies per distribution. If you run Linux you're probably capable of finding out how :)\\n\\n## Problems\\n\\nChattyPub is very young and you're sure to run into problems. Feel free to contact `@Karl Moubarak`, `@andré` or `@heerko` at https://chat.hackersanddesigners.nl/\\n\\nBelow are some things that we know of, and are working on:\\n\\n- :emoji: not working...\\n\";","import { render } from \"./Docs.vue?vue&type=template&id=b2769a1a&scoped=true\"\nimport script from \"./Docs.vue?vue&type=script&lang=js\"\nexport * from \"./Docs.vue?vue&type=script&lang=js\"\n\nimport \"./Docs.vue?vue&type=style&index=0&id=b2769a1a&scoped=true&lang=css\"\nscript.render = render\nscript.__scopeId = \"data-v-b2769a1a\"\n\nexport default script","import { createRouter, createWebHistory } from 'vue-router'\n\nimport Home from '../views/Home'\nimport Docs from '../views/Docs.vue'\n\nconst path = '/' \n\nexport default createRouter({\n history: createWebHistory(path),\n routes: [\n {\n path: '/',\n name: 'Home',\n component: Home,\n },\n {\n path: '/docs',\n name: 'Docs',\n component: Docs,\n },\n {\n path: '/:pathMatch(.*)*',\n name: 'Home',\n component: Home,\n },\n ],\n})\n\n\n","/*eslint no-unused-vars: \"off\"*/\n/*eslint no-undef: \"off\"*/\n\n// import Vue from 'vue'\nimport { createStore } from 'vuex'\nimport emoji from \"../mixins/emoji\"\nimport { stripHtml } from \"string-strip-html\"\n\nvar EmojiConvertor = require('emoji-js');\nvar emojiConv = new EmojiConvertor();\n\nlet toCSS = (message, currentStream) => {\n let content = stripHtml(message.content).result;\n let className = \"\",\n emoji_code = \"\",\n rules = [],\n parentClassName = currentStream,\n id = message.id,\n is_codeblock = message.content.includes(\"\") || message.content.startsWith(\"```\"),\n is_font = /

    .+)\\s*\\n?{\\n?(?[\\s\\w.~:>-]+\\s*:\\s*.+;?\\n?)*\\n?}/gm\n\n let type = is_codeblock ? \"raw\" : is_font ? \"font\" : \"rule\"; // okay okay okay, i know this is ugly :)\n\n let regex = /\\s?(?.+)\\s*\\n?{\\n?(?(.*;\\n?)+)}/gm\n let results = content.matchAll(regex);\n results = Array.from(results);\n if (is_font) { // font\n let re_path = /\\/user_uploads(\\/.*?\\.(?:ttf|otf|woff))/gm;\n // content = message.content.matchAll(re_path);\n content = re_path.exec(message.content)[1];\n // console.log(message.content, content)\n return { className: '', emoji_code: '', rules: [], parentClassName: '', id: id, content: font(content), type: type }\n } else if (results.length > 0) { // rule and raw\n className = emojiConv.replace_colons(results[0]['groups']['selector']);\n if (emoji.methods.containsEmoji(className)) {\n emoji_code = emoji.methods.toEmojiCode(className);\n }\n rules = results[0]['groups']['props'].split(\"\\n\");\n rules = rules.filter((rule) => validateRule(rule))\n return { className, emoji_code, rules, parentClassName, id, content, type };\n }\n return null;\n}\n\nlet font = (content) => {\n let font = {\n family: \"\",\n src: \"\",\n format: \"\",\n };\n let path = content;\n let filename = getFilename(path);\n let ext = filename.split(\".\").pop();\n font.src =\n \"https://chatty-pub-files.hackersanddesigners.nl/files\" + path;\n font.format = getFormat(ext);\n font.family = filename.replace(\".\", \"_\");\n return font;\n}\n\nlet getFilename = (str) => {\n return str.split(\"\\\\\").pop().split(\"/\").pop();\n}\n\nlet getFormat = (ext) => {\n let fmt = \"truetype\";\n switch (ext) {\n case 'woff':\n fmt = \"woff\";\n break;\n case 'eof':\n fmt = \"embedded-opentype\";\n break;\n }\n return fmt;\n}\n\nlet validateRule = (rule) => {\n return rule.match(/.+:.+;/gm);\n}\n\n// parsing replies, there are two scenarios:\n// we are either getting the message as plain markdown\n// or we are getting the message pre-rendered as HTML (default Zulip behaviour)\n// see /src/api/zulip/index.js line 36\n\nconst handleMDReply = message => {\n message.responseTo = {\n id: message.content\n .replace(/.*\\/near\\//gm, '')\n .replace(/\\):.*[^]+/gm, ''),\n sender_id: message.content\n .replace(/@_\\*\\*.*\\|/gm, '')\n .replace(/\\*\\*.\\[said\\].*[^]+/gm, ''),\n quote: message.content\n .replace(/[^]+.*```quote\\n/gm, '')\n .replace(/ \\n```/gm, '')\n }\n // console.log(message.responseTo)\n}\n\nconst handleHTMLReply = message => {\n message.responseTo = {\n id: message.content\n .replace(/.*\\/near\\//gm, '')\n .replace(/\".*[^]+/gm, ''),\n sender_id: message.content\n .replace(/[^]+data-user-id=\"/gm, '')\n .replace(/\">[^]+/gm, ''),\n quote: message.content\n .replace(/.*[^]+<\\/p>\\n

    \\n

    /gm, '')\n .replace(/<\\/p>\\n<\\/blockquote>/gm, '')\n // .replace(/\\n/gm, '')\n }\n console.table(message.responseTo)\n}\n\nexport default createStore({\n\n strict: process.env.NODE_ENV !== 'production',\n\n state: {\n isMobile: false,\n streams: [],\n currentStream: '',\n rules: [],\n topics: [],\n pubStr: 'pub-',\n },\n\n mutations: {\n\n setMobile: (state, mobile) => state.isMobile = mobile,\n setStreams: (state, streams) => state.streams = streams,\n setCurStream: (state, stream) => state.currentStream = stream,\n setTopics: (state, topics) => state.topics = topics,\n addMessage: (state, message) => {\n if (message.display_recipient == state.currentStream) {\n if (message.content.startsWith('@_**')) {\n handleMDReply(message)\n } else if (\n message.content.includes('user-mention') &&\n message.content.includes('blockquote')\n ) {\n handleHTMLReply(message)\n }\n const topic = state.topics.find(topic => topic.title == message.subject)\n if (topic) {\n topic.messages.push(message)\n } else {\n state.topics.push({\n title: message.subject,\n messages: [message]\n })\n }\n }\n },\n deleteMessage: (state, { mid, subject }) => {\n const topic = state.topics.find(t => t.title == subject)\n if (topic) {\n const message = topic.messages.find(m => m.id == mid)\n if (message) {\n topic.messages.splice(topic.messages.indexOf(message), 1)\n }\n }\n },\n addReaction: (state, { mid, reaction }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n if (message) {\n message.reactions.push(reaction)\n }\n },\n removeReaction: (state, { mid, reaction }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n if (message) {\n message.reactions.splice(message.reactions.indexOf(reaction), 1)\n }\n },\n setRules: (state, rules) => {\n state.rules = rules.reduce((acc, cur) => {\n let rule = toCSS(cur, state.currentStream);\n if (rule !== null) {\n acc.push(rule);\n }\n return acc\n }, [])\n },\n addRule: (state, rule) => {\n if (toCSS(rule) !== null) {\n // state.rules.push(toCSS(rule, state.currentStream))\n // vue will not update if i use rules.push(rule)\n state.rules = [...state.rules, ...[toCSS(rule, state.currentStream)]]\n }\n },\n editMessage: (state, { mid, content }) => {\n const message = state.topics\n .map(t => t.messages)\n .flat()\n .find(m => m.id == mid)\n const rule = state.rules.find(r => r.id == mid)\n if (message) {\n message.content = content\n if (message.content.startsWith('@_**')) {\n handleMDReply(message)\n } else if (\n message.content.includes('user-mention') &&\n message.content.includes('blockquote')\n ) {\n handleHTMLReply(message)\n }\n } else if (rule) {\n // state.rules[state.rules.indexOf(rule)] = toCSS({\n // id: mid, content: content,\n // }, state.currentStream)\n\n // vue will not update if i use rules.push(rule) \n state.rules.splice(state.rules.indexOf(rule), 1)\n const newRules = [...state.rules, ...[toCSS({\n id: mid, content: content,\n }, state.currentStream)]]\n state.rules = newRules\n }\n },\n\n updateTopic: (state, { orig_subject, subject }) => {\n const topic = state.topics.find(t => t.title == orig_subject)\n if (topic) {\n topic.title = subject\n topic.messages.forEach(m => m.subject = subject)\n }\n }\n\n },\n\n actions: {\n },\n\n getters: {\n rules: state => state.rules,\n sortedTopics: state => (\n [...state.topics]\n .sort((a, b) => a.title.localeCompare(b.title))\n .filter(t => (\n t.messages.length > 0 &&\n t.title != 'stream events'\n ))\n )\n }\n\n})\n","import { createApp } from 'vue'\nimport App from './App'\nimport Axios from 'axios'\nimport MarkdownIt from 'markdown-it'\nimport VueMarkdownIt from 'vue3-markdown-it'\nimport router from './router'\nimport store from './store'\n\nimport 'highlight.js/styles/vs.css';\n\nconst app = createApp(App)\n\nconst mdOpts = {\n html: true,\n linkify: true,\n typographer: true\n}\n\napp.config.globalProperties.$http = Axios\napp.config.globalProperties.$mdOpts = mdOpts\napp.config.globalProperties.$md = new MarkdownIt(mdOpts)\n\napp\n .use(VueMarkdownIt)\n .use(router)\n .use(store)\n .mount('#app')\n\n\n\n","export * from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./App.vue?vue&type=style&index=0&id=6d28ae45&lang=css\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Docs.vue?vue&type=style&index=0&id=b2769a1a&scoped=true&lang=css\"","export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Home.vue?vue&type=style&index=0&id=71897d50&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Rule.vue?vue&type=style&index=0&id=080e408c&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Message.vue?vue&type=style&index=0&id=76a5b3df&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Chapter.vue?vue&type=style&index=0&id=80b6d17a&scoped=true&lang=css\"","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--6-oneOf-1-1!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Stream.vue?vue&type=style&index=0&id=1af39708&scoped=true&lang=css\""],"sourceRoot":""} \ No newline at end of file diff --git a/front/dist/js/chunk-vendors.97da1489.js b/front/dist/js/chunk-vendors.26f1d600.js similarity index 51% rename from front/dist/js/chunk-vendors.97da1489.js rename to front/dist/js/chunk-vendors.26f1d600.js index 34147ef..828ceaa 100644 --- a/front/dist/js/chunk-vendors.97da1489.js +++ b/front/dist/js/chunk-vendors.26f1d600.js @@ -1,4 +1,4 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-vendors"],{"0068":function(e,t,n){"use strict";function r(e){return Object.prototype.toString.call(e)}function a(e){return"[object String]"===r(e)}var i=Object.prototype.hasOwnProperty;function o(e,t){return i.call(e,t)}function s(e){var t=Array.prototype.slice.call(arguments,1);return t.forEach((function(t){if(t){if("object"!==typeof t)throw new TypeError(t+"must be object");Object.keys(t).forEach((function(n){e[n]=t[n]}))}})),e}function l(e,t,n){return[].concat(e.slice(0,t),n,e.slice(t+1))}function c(e){return!(e>=55296&&e<=57343)&&(!(e>=64976&&e<=65007)&&(65535!==(65535&e)&&65534!==(65535&e)&&(!(e>=0&&e<=8)&&(11!==e&&(!(e>=14&&e<=31)&&(!(e>=127&&e<=159)&&!(e>1114111)))))))}function d(e){if(e>65535){e-=65536;var t=55296+(e>>10),n=56320+(1023&e);return String.fromCharCode(t,n)}return String.fromCharCode(e)}var u=/\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g,p=/&([a-z#][a-z0-9]{1,31});/gi,f=new RegExp(u.source+"|"+p.source,"gi"),m=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,_=n("bd68");function g(e,t){var n=0;return o(_,t)?_[t]:35===t.charCodeAt(0)&&m.test(t)&&(n="x"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10),c(n))?d(n):e}function h(e){return e.indexOf("\\")<0?e:e.replace(u,"$1")}function b(e){return e.indexOf("\\")<0&&e.indexOf("&")<0?e:e.replace(f,(function(e,t,n){return t||g(e,n)}))}var S=/[&<>"]/,E=/[&<>"]/g,y={"&":"&","<":"<",">":">",'"':"""};function v(e){return y[e]}function T(e){return S.test(e)?e.replace(E,v):e}var C=/[.?*+^$[\]\\(){}|-]/g;function O(e){return e.replace(C,"\\$&")}function x(e){switch(e){case 9:case 32:return!0}return!1}function w(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1}var A=n("7ca0");function R(e){return A.test(e)}function N(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}}function k(e){return e=e.trim().replace(/\s+/g," "),"Ṿ"==="ẞ".toLowerCase()&&(e=e.replace(/ẞ/g,"ß")),e.toLowerCase().toUpperCase()}t.lib={},t.lib.mdurl=n("d8a6"),t.lib.ucmicro=n("d5d1"),t.assign=s,t.isString=a,t.has=o,t.unescapeMd=h,t.unescapeAll=b,t.isValidEntityCode=c,t.fromCodePoint=d,t.escapeHtml=T,t.arrayReplaceAt=l,t.isSpace=x,t.isWhiteSpace=w,t.isMdAsciiPunct=N,t.isPunctChar=R,t.escapeRE=O,t.normalizeReference=k},"00ee":function(e,t,n){var r=n("b622"),a=r("toStringTag"),i={};i[a]="z",e.exports="[object z]"===String(i)},"0195":function(e,t,n){"use strict";var r=n("4373");function a(e){return{retrieve:function(t){var n="".concat(e.apiURL,"/users");return r(n,e,"GET",t)},create:function(t){var n="".concat(e.apiURL,"/users");return r(n,e,"POST",t)},me:{pointer:{retrieve:function(t){var n="".concat(e.apiURL,"/users/me/pointer");return r(n,e,"GET",t)},update:function(t){var n="".concat(e.apiURL,"/users/me/pointer");return r(n,e,"POST",{pointer:t})}},getProfile:function(){var t="".concat(e.apiURL,"/users/me");return r(t,e,"GET")},subscriptions:{add:function(t){var n="".concat(e.apiURL,"/users/me/subscriptions");return r(n,e,"POST",t)},remove:function(t){var n="".concat(e.apiURL,"/users/me/subscriptions");return r(n,e,"DELETE",t)}},alertWords:{retrieve:function(t){var n="".concat(e.apiURL,"/users/me/alert_words");return r(n,e,"GET",t)}}}}}e.exports=a},"0366":function(e,t,n){var r=n("1c0b");e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 0:return function(){return e.call(t)};case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,a){return e.call(t,n,r,a)}}return function(){return e.apply(t,arguments)}}},"0481":function(e,t,n){"use strict";var r=n("23e7"),a=n("a2bf"),i=n("7b0b"),o=n("50c4"),s=n("a691"),l=n("65f0");r({target:"Array",proto:!0},{flat:function(){var e=arguments.length?arguments[0]:void 0,t=i(this),n=o(t.length),r=l(t,0);return r.length=a(r,t,t,n,0,void 0===e?1:s(e)),r}})},"04d1":function(e,t,n){var r=n("342f"),a=r.match(/firefox\/(\d+)/i);e.exports=!!a&&+a[1]},"057f":function(e,t,n){var r=n("fc6a"),a=n("241c").f,i={}.toString,o="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(e){try{return a(e)}catch(t){return o.slice()}};e.exports.f=function(e){return o&&"[object Window]"==i.call(e)?s(e):a(r(e))}},"06c5":function(e,t,n){"use strict";n.d(t,"a",(function(){return a}));n("fb6a"),n("d3b7"),n("b0c0"),n("a630"),n("3ca3");var r=n("6b75");function a(e,t){if(e){if("string"===typeof e)return Object(r["a"])(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Object(r["a"])(e,t):void 0}}},"06cf":function(e,t,n){var r=n("83ab"),a=n("d1e7"),i=n("5c6c"),o=n("fc6a"),s=n("c04e"),l=n("5135"),c=n("0cfb"),d=Object.getOwnPropertyDescriptor;t.f=r?d:function(e,t){if(e=o(e),t=s(t,!0),c)try{return d(e,t)}catch(n){}if(l(e,t))return i(!a.f.call(e,t),e[t])}},"0758":function(e,t,n){"use strict";var r=n("0068").isSpace;e.exports=function(e,t,n,a){var i,o,s,l,c=e.bMarks[t]+e.tShift[t],d=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4)return!1;if(i=e.src.charCodeAt(c),35!==i||c>=d)return!1;o=1,i=e.src.charCodeAt(++c);while(35===i&&c6||cc&&r(e.src.charCodeAt(s-1))&&(d=s),e.line=t+1,l=e.push("heading_open","h"+String(o),1),l.markup="########".slice(0,o),l.map=[t,e.line],l=e.push("inline","",0),l.content=e.src.slice(c,d).trim(),l.map=[t,e.line],l.children=[],l=e.push("heading_close","h"+String(o),-1),l.markup="########".slice(0,o)),!0)}},"08ae":function(e,t,n){"use strict";var r=n("0068"),a=n("565b"),i=n("7cc2"),o=n("a915"),s=n("7696"),l=n("4cb4"),c=n("fbcd"),d=n("d8a6"),u=n("1985"),p={default:n("8a31"),zero:n("1caa"),commonmark:n("428d")},f=/^(vbscript|javascript|file|data):/,m=/^data:image\/(gif|png|jpeg|webp);/;function _(e){var t=e.trim().toLowerCase();return!f.test(t)||!!m.test(t)}var g=["http:","https:","mailto:"];function h(e){var t=d.parse(e,!0);if(t.hostname&&(!t.protocol||g.indexOf(t.protocol)>=0))try{t.hostname=u.toASCII(t.hostname)}catch(n){}return d.encode(d.format(t))}function b(e){var t=d.parse(e,!0);if(t.hostname&&(!t.protocol||g.indexOf(t.protocol)>=0))try{t.hostname=u.toUnicode(t.hostname)}catch(n){}return d.decode(d.format(t),d.decode.defaultChars+"%")}function S(e,t){if(!(this instanceof S))return new S(e,t);t||r.isString(e)||(t=e||{},e="default"),this.inline=new l,this.block=new s,this.core=new o,this.renderer=new i,this.linkify=new c,this.validateLink=_,this.normalizeLink=h,this.normalizeLinkText=b,this.utils=r,this.helpers=r.assign({},a),this.options={},this.configure(e),t&&this.set(t)}S.prototype.set=function(e){return r.assign(this.options,e),this},S.prototype.configure=function(e){var t,n=this;if(r.isString(e)&&(t=e,e=p[t],!e))throw new Error('Wrong `markdown-it` preset "'+t+'", check name');if(!e)throw new Error("Wrong `markdown-it` preset, can't be empty");return e.options&&n.set(e.options),e.components&&Object.keys(e.components).forEach((function(t){e.components[t].rules&&n[t].ruler.enableOnly(e.components[t].rules),e.components[t].rules2&&n[t].ruler2.enableOnly(e.components[t].rules2)})),this},S.prototype.enable=function(e,t){var n=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach((function(t){n=n.concat(this[t].ruler.enable(e,!0))}),this),n=n.concat(this.inline.ruler2.enable(e,!0));var r=e.filter((function(e){return n.indexOf(e)<0}));if(r.length&&!t)throw new Error("MarkdownIt. Failed to enable unknown rule(s): "+r);return this},S.prototype.disable=function(e,t){var n=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach((function(t){n=n.concat(this[t].ruler.disable(e,!0))}),this),n=n.concat(this.inline.ruler2.disable(e,!0));var r=e.filter((function(e){return n.indexOf(e)<0}));if(r.length&&!t)throw new Error("MarkdownIt. Failed to disable unknown rule(s): "+r);return this},S.prototype.use=function(e){var t=[this].concat(Array.prototype.slice.call(arguments,1));return e.apply(e,t),this},S.prototype.parse=function(e,t){if("string"!==typeof e)throw new Error("Input data should be a String");var n=new this.core.State(e,this,t);return this.core.process(n),n.tokens},S.prototype.render=function(e,t){return t=t||{},this.renderer.render(this.parse(e,t),this.options,t)},S.prototype.parseInline=function(e,t){var n=new this.core.State(e,this,t);return n.inlineMode=!0,this.core.process(n),n.tokens},S.prototype.renderInline=function(e,t){return t=t||{},this.renderer.render(this.parseInline(e,t),this.options,t)},e.exports=S},"096b":function(e,t,n){"use strict";function r(e,t,n){this.type=e,this.tag=t,this.attrs=null,this.map=null,this.nesting=n,this.level=0,this.children=null,this.content="",this.markup="",this.info="",this.meta=null,this.block=!1,this.hidden=!1}r.prototype.attrIndex=function(e){var t,n,r;if(!this.attrs)return-1;for(t=this.attrs,n=0,r=t.length;n=0&&(n=this.attrs[t][1]),n},r.prototype.attrJoin=function(e,t){var n=this.attrIndex(e);n<0?this.attrPush([e,t]):this.attrs[n][1]=this.attrs[n][1]+" "+t},e.exports=r},"097b":function(e,t,n){"use strict";var r=n("096b"),a=n("0068").isWhiteSpace,i=n("0068").isPunctChar,o=n("0068").isMdAsciiPunct;function s(e,t,n,r){this.src=e,this.env=n,this.md=t,this.tokens=r,this.tokens_meta=Array(r.length),this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache={},this.delimiters=[],this._prev_delimiters=[],this.backticks={},this.backticksScanned=!1}s.prototype.pushPending=function(){var e=new r("text","",0);return e.content=this.pending,e.level=this.pendingLevel,this.tokens.push(e),this.pending="",e},s.prototype.push=function(e,t,n){this.pending&&this.pushPending();var a=new r(e,t,n),i=null;return n<0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),a.level=this.level,n>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],i={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(a),this.tokens_meta.push(i),a},s.prototype.scanDelims=function(e,t){var n,r,s,l,c,d,u,p,f,m=e,_=!0,g=!0,h=this.posMax,b=this.src.charCodeAt(e);n=e>0?this.src.charCodeAt(e-1):32;while(m]*>)/g,s=/\$([$&'`]|\d{1,2})/g;e.exports=function(e,t,n,l,c,d){var u=n+e.length,p=l.length,f=s;return void 0!==c&&(c=r(c),f=o),i.call(d,f,(function(r,i){var o;switch(i.charAt(0)){case"$":return"$";case"&":return e;case"`":return t.slice(0,n);case"'":return t.slice(u);case"<":o=c[i.slice(1,-1)];break;default:var s=+i;if(0===s)return r;if(s>p){var d=a(s/10);return 0===d?r:d<=p?void 0===l[d-1]?i.charAt(1):l[d-1]+i.charAt(1):r}o=l[s-1]}return void 0===o?"":o}))}},"0cfb":function(e,t,n){var r=n("83ab"),a=n("d039"),i=n("cc12");e.exports=!r&&!a((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},"0df6":function(e,t,n){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},"0e9e":function(e,t,n){"use strict";var r=n("4ea4"),a=r(n("9523"));function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t1||"".split(/.?/).length?function(e,n){var r=String(o(this)),i=void 0===n?g:n>>>0;if(0===i)return[];if(void 0===e)return[r];if(!a(e))return t.call(r,e,i);var s,l,c,d=[],p=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(e.sticky?"y":""),f=0,_=new RegExp(e.source,p+"g");while(s=u.call(_,r)){if(l=_.lastIndex,l>f&&(d.push(r.slice(f,s.index)),s.length>1&&s.index=i))break;_.lastIndex===s.index&&_.lastIndex++}return f===r.length?!c&&_.test("")||d.push(""):d.push(r.slice(f)),d.length>i?d.slice(0,i):d}:"0".split(void 0,0).length?function(e,n){return void 0===e&&0===n?[]:t.call(this,e,n)}:t,[function(t,n){var a=o(this),i=void 0==t?void 0:t[e];return void 0!==i?i.call(t,a,n):r.call(String(a),t,n)},function(e,a){var o=n(r,e,this,a,r!==t);if(o.done)return o.value;var u=i(e),p=String(this),m=s(u,RegExp),h=u.unicode,b=(u.ignoreCase?"i":"")+(u.multiline?"m":"")+(u.unicode?"u":"")+(f?"g":"y"),S=new m(f?"^(?:"+u.source+")":u,b),E=void 0===a?g:a>>>0;if(0===E)return[];if(0===p.length)return null===d(S,p)?[p]:[];var y=0,v=0,T=[];while(v1?arguments[1]:void 0)}},1985:function(e,t,n){(function(e,r){var a;/*! https://mths.be/punycode v1.4.1 by @mathias */(function(i){t&&t.nodeType,e&&e.nodeType;var o="object"==typeof r&&r;o.global!==o&&o.window!==o&&o.self;var s,l=2147483647,c=36,d=1,u=26,p=38,f=700,m=72,_=128,g="-",h=/^xn--/,b=/[^\x20-\x7E]/,S=/[\x2E\u3002\uFF0E\uFF61]/g,E={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},y=c-d,v=Math.floor,T=String.fromCharCode;function C(e){throw new RangeError(E[e])}function O(e,t){var n=e.length,r=[];while(n--)r[n]=t(e[n]);return r}function x(e,t){var n=e.split("@"),r="";n.length>1&&(r=n[0]+"@",e=n[1]),e=e.replace(S,".");var a=e.split("."),i=O(a,t).join(".");return r+i}function w(e){var t,n,r=[],a=0,i=e.length;while(a=55296&&t<=56319&&a65535&&(e-=65536,t+=T(e>>>10&1023|55296),e=56320|1023&e),t+=T(e),t})).join("")}function R(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:c}function N(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function k(e,t,n){var r=0;for(e=n?v(e/f):e>>1,e+=v(e/t);e>y*u>>1;r+=c)e=v(e/y);return v(r+(y+1)*e/(e+p))}function I(e){var t,n,r,a,i,o,s,p,f,h,b=[],S=e.length,E=0,y=_,T=m;for(n=e.lastIndexOf(g),n<0&&(n=0),r=0;r=128&&C("not-basic"),b.push(e.charCodeAt(r));for(a=n>0?n+1:0;a=S&&C("invalid-input"),p=R(e.charCodeAt(a++)),(p>=c||p>v((l-E)/o))&&C("overflow"),E+=p*o,f=s<=T?d:s>=T+u?u:s-T,pv(l/h)&&C("overflow"),o*=h}t=b.length+1,T=k(E-i,t,0==i),v(E/t)>l-y&&C("overflow"),y+=v(E/t),E%=t,b.splice(E++,0,y)}return A(b)}function D(e){var t,n,r,a,i,o,s,p,f,h,b,S,E,y,O,x=[];for(e=w(e),S=e.length,t=_,n=0,i=m,o=0;o=t&&bv((l-n)/E)&&C("overflow"),n+=(s-t)*E,t=s,o=0;ol&&C("overflow"),b==t){for(p=n,f=c;;f+=c){if(h=f<=i?d:f>=i+u?u:f-i,p=4)return!1;for(p=e.parentType,e.parentType="paragraph";f3)){if(e.sCount[f]>=e.blkIndent&&(l=e.bMarks[f]+e.tShift[f],c=e.eMarks[f],l=c)))){d=61===u?1:2;break}if(!(e.sCount[f]<0)){for(a=!1,i=0,o=m.length;i=51||!r((function(){var t=[],n=t.constructor={};return n[o]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},"1fb5":function(e,t,n){"use strict";t.byteLength=d,t.toByteArray=p,t.fromByteArray=_;for(var r=[],a=[],i="undefined"!==typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,l=o.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");-1===n&&(n=t);var r=n===t?0:4-n%4;return[n,r]}function d(e){var t=c(e),n=t[0],r=t[1];return 3*(n+r)/4-r}function u(e,t,n){return 3*(t+n)/4-n}function p(e){var t,n,r=c(e),o=r[0],s=r[1],l=new i(u(e,o,s)),d=0,p=s>0?o-4:o;for(n=0;n>16&255,l[d++]=t>>8&255,l[d++]=255&t;return 2===s&&(t=a[e.charCodeAt(n)]<<2|a[e.charCodeAt(n+1)]>>4,l[d++]=255&t),1===s&&(t=a[e.charCodeAt(n)]<<10|a[e.charCodeAt(n+1)]<<4|a[e.charCodeAt(n+2)]>>2,l[d++]=t>>8&255,l[d++]=255&t),l}function f(e){return r[e>>18&63]+r[e>>12&63]+r[e>>6&63]+r[63&e]}function m(e,t,n){for(var r,a=[],i=t;il?l:s+o));return 1===a?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===a&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"=")),i.join("")}a["-".charCodeAt(0)]=62,a["_".charCodeAt(0)]=63},2085:function(e,t,n){"use strict";e.exports=function(e){var t,n,r=0,a=e.tokens,i=e.tokens.length;for(t=n=0;t0&&r++,"text"===a[t].type&&t+1p;p++)if(m=T(e[p]),m&&m instanceof c)return m;return new c(!1)}d=u.call(e)}_=d.next;while(!(g=_.call(d)).done){try{m=T(g.value)}catch(C){throw l(d),C}if("object"==typeof m&&m&&m instanceof c)return m}return new c(!1)}},"23cb":function(e,t,n){var r=n("a691"),a=Math.max,i=Math.min;e.exports=function(e,t){var n=r(e);return n<0?a(n+t,0):i(n,t)}},"23e7":function(e,t,n){var r=n("da84"),a=n("06cf").f,i=n("9112"),o=n("6eeb"),s=n("ce4e"),l=n("e893"),c=n("94ca");e.exports=function(e,t){var n,d,u,p,f,m,_=e.target,g=e.global,h=e.stat;if(d=g?r:h?r[_]||s(_,{}):(r[_]||{}).prototype,d)for(u in t){if(f=t[u],e.noTargetGet?(m=a(d,u),p=m&&m.value):p=d[u],n=c(g?u:_+(h?".":"#")+u,e.forced),!n&&void 0!==p){if(typeof f===typeof p)continue;l(f,p)}(e.sham||p&&p.sham)&&i(f,"sham",!0),o(d,u,f,e)}}},"241c":function(e,t,n){var r=n("ca84"),a=n("7839"),i=a.concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return r(e,i)}},2444:function(e,t,n){"use strict";(function(t){var r=n("c532"),a=n("c8af"),i={"Content-Type":"application/x-www-form-urlencoded"};function o(e,t){!r.isUndefined(e)&&r.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function s(){var e;return("undefined"!==typeof XMLHttpRequest||"undefined"!==typeof t&&"[object process]"===Object.prototype.toString.call(t))&&(e=n("b50d")),e}var l={adapter:s(),transformRequest:[function(e,t){return a(t,"Accept"),a(t,"Content-Type"),r.isFormData(e)||r.isArrayBuffer(e)||r.isBuffer(e)||r.isStream(e)||r.isFile(e)||r.isBlob(e)?e:r.isArrayBufferView(e)?e.buffer:r.isURLSearchParams(e)?(o(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):r.isObject(e)?(o(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"===typeof e)try{e=JSON.parse(e)}catch(t){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};r.forEach(["delete","get","head"],(function(e){l.headers[e]={}})),r.forEach(["post","put","patch"],(function(e){l.headers[e]=r.merge(i)})),e.exports=l}).call(this,n("4362"))},2532:function(e,t,n){"use strict";var r=n("23e7"),a=n("5a34"),i=n("1d80"),o=n("ab13");r({target:"String",proto:!0,forced:!o("includes")},{includes:function(e){return!!~String(i(this)).indexOf(a(e),arguments.length>1?arguments[1]:void 0)}})},"25f0":function(e,t,n){"use strict";var r=n("6eeb"),a=n("825a"),i=n("d039"),o=n("ad6d"),s="toString",l=RegExp.prototype,c=l[s],d=i((function(){return"/a/b"!=c.call({source:"a",flags:"b"})})),u=c.name!=s;(d||u)&&r(RegExp.prototype,s,(function(){var e=a(this),t=String(e.source),n=e.flags,r=String(void 0===n&&e instanceof RegExp&&!("flags"in l)?o.call(e):n);return"/"+t+"/"+r}),{unsafe:!0})},2626:function(e,t,n){"use strict";var r=n("d066"),a=n("9bf2"),i=n("b622"),o=n("83ab"),s=i("species");e.exports=function(e){var t=r(e),n=a.f;o&&t&&!t[s]&&n(t,s,{configurable:!0,get:function(){return this}})}},"278c":function(e,t,n){var r=n("c135"),a=n("9b42"),i=n("6613"),o=n("c240");function s(e,t){return r(e)||a(e,t)||i(e,t)||o()}e.exports=s,e.exports["default"]=e.exports,e.exports.__esModule=!0},"28ec":function(e,t,n){"use strict";var r=/^([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/,a=/^([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)$/;e.exports=function(e,t){var n,i,o,s,l,c,d=e.pos;if(60!==e.src.charCodeAt(d))return!1;for(l=e.pos,c=e.posMax;;){if(++d>=c)return!1;if(s=e.src.charCodeAt(d),60===s)return!1;if(62===s)break}return n=e.src.slice(l+1,d),a.test(n)?(i=e.md.normalizeLink(n),!!e.md.validateLink(i)&&(t||(o=e.push("link_open","a",1),o.attrs=[["href",i]],o.markup="autolink",o.info="auto",o=e.push("text","",0),o.content=e.md.normalizeLinkText(n),o=e.push("link_close","a",-1),o.markup="autolink",o.info="auto"),e.pos+=n.length+2,!0)):!!r.test(n)&&(i=e.md.normalizeLink("mailto:"+n),!!e.md.validateLink(i)&&(t||(o=e.push("link_open","a",1),o.attrs=[["href",i]],o.markup="autolink",o.info="auto",o=e.push("text","",0),o.content=e.md.normalizeLinkText(n),o=e.push("link_close","a",-1),o.markup="autolink",o.info="auto"),e.pos+=n.length+2,!0))}},2909:function(e,t,n){"use strict";n.d(t,"a",(function(){return l}));var r=n("6b75");function a(e){if(Array.isArray(e))return Object(r["a"])(e)}n("a4d3"),n("e01a"),n("d3b7"),n("d28b"),n("3ca3"),n("ddb0"),n("a630");function i(e){if("undefined"!==typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}var o=n("06c5");function s(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function l(e){return a(e)||i(e)||Object(o["a"])(e)||s()}},"2a62":function(e,t,n){var r=n("825a");e.exports=function(e){var t=e["return"];if(void 0!==t)return r(t.call(e)).value}},"2ca0":function(e,t,n){"use strict";var r=n("23e7"),a=n("06cf").f,i=n("50c4"),o=n("5a34"),s=n("1d80"),l=n("ab13"),c=n("c430"),d="".startsWith,u=Math.min,p=l("startsWith"),f=!c&&!p&&!!function(){var e=a(String.prototype,"startsWith");return e&&!e.writable}();r({target:"String",proto:!0,forced:!f&&!p},{startsWith:function(e){var t=String(s(this));o(e);var n=i(u(arguments.length>1?arguments[1]:void 0,t.length)),r=String(e);return d?d.call(t,r,n):t.slice(n,n+r.length)===r}})},"2cf4":function(e,t,n){var r,a,i,o=n("da84"),s=n("d039"),l=n("0366"),c=n("1be4"),d=n("cc12"),u=n("1cdc"),p=n("605d"),f=o.location,m=o.setImmediate,_=o.clearImmediate,g=o.process,h=o.MessageChannel,b=o.Dispatch,S=0,E={},y="onreadystatechange",v=function(e){if(E.hasOwnProperty(e)){var t=E[e];delete E[e],t()}},T=function(e){return function(){v(e)}},C=function(e){v(e.data)},O=function(e){o.postMessage(e+"",f.protocol+"//"+f.host)};m&&_||(m=function(e){var t=[],n=1;while(arguments.length>n)t.push(arguments[n++]);return E[++S]=function(){("function"==typeof e?e:Function(e)).apply(void 0,t)},r(S),S},_=function(e){delete E[e]},p?r=function(e){g.nextTick(T(e))}:b&&b.now?r=function(e){b.now(T(e))}:h&&!u?(a=new h,i=a.port2,a.port1.onmessage=C,r=l(i.postMessage,i,1)):o.addEventListener&&"function"==typeof postMessage&&!o.importScripts&&f&&"file:"!==f.protocol&&!s(O)?(r=O,o.addEventListener("message",C,!1)):r=y in d("script")?function(e){c.appendChild(d("script"))[y]=function(){c.removeChild(this),v(e)}}:function(e){setTimeout(T(e),0)}),e.exports={set:m,clear:_}},"2d00":function(e,t,n){var r,a,i=n("da84"),o=n("342f"),s=i.process,l=s&&s.versions,c=l&&l.v8;c?(r=c.split("."),a=r[0]<4?1:r[0]+r[1]):o&&(r=o.match(/Edge\/(\d+)/),(!r||r[1]>=74)&&(r=o.match(/Chrome\/(\d+)/),r&&(a=r[1]))),e.exports=a&&+a},"2d83":function(e,t,n){"use strict";var r=n("387f");e.exports=function(e,t,n,a,i){var o=new Error(e);return r(o,t,n,a,i)}},"2e67":function(e,t,n){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},"2e94":function(e,t,n){n("6d93"),e.exports=self.fetch.bind(self)},"30b5":function(e,t,n){"use strict";var r=n("c532");function a(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(r.isURLSearchParams(t))i=t.toString();else{var o=[];r.forEach(t,(function(e,t){null!==e&&"undefined"!==typeof e&&(r.isArray(e)?t+="[]":e=[e],r.forEach(e,(function(e){r.isDate(e)?e=e.toISOString():r.isObject(e)&&(e=JSON.stringify(e)),o.push(a(t)+"="+a(e))})))})),i=o.join("&")}if(i){var s=e.indexOf("#");-1!==s&&(e=e.slice(0,s)),e+=(-1===e.indexOf("?")?"?":"&")+i}return e}},3408:function(e,t,n){"use strict";e.exports=function(e){var t;e.inlineMode?(t=new e.Token("inline","",0),t.content=e.src,t.map=[0,1],t.children=[],e.tokens.push(t)):e.md.block.parse(e.src,e.md,e.env,e.tokens)}},"342f":function(e,t,n){var r=n("d066");e.exports=r("navigator","userAgent")||""},3487:function(e,t,n){"use strict";var r=n("4ea4"),a=r(n("9523"));function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t1&&(r.to=JSON.stringify(r.to)),s(n,e,"POST",r)}}}e.exports=l},"35a1":function(e,t,n){var r=n("f5df"),a=n("3f8c"),i=n("b622"),o=i("iterator");e.exports=function(e){if(void 0!=e)return e[o]||e["@@iterator"]||a[r(e)]}},"37e8":function(e,t,n){var r=n("83ab"),a=n("9bf2"),i=n("825a"),o=n("df75");e.exports=r?Object.defineProperties:function(e,t){i(e);var n,r=o(t),s=r.length,l=0;while(s>l)a.f(e,n=r[l++],t[n]);return e}},"387f":function(e,t,n){"use strict";e.exports=function(e,t,n,r,a){return e.config=t,n&&(e.code=n),e.request=r,e.response=a,e.isAxiosError=!0,e.toJSON=function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code}},e}},"38b4":function(e,t,n){"use strict";var r=n("4ea4");Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=void 0;var a=r(n("a34a")),i=r(n("c973")),o=n("3e8f"),s=n("6343");function l(e){return c.apply(this,arguments)}function c(){return c=(0,i["default"])(a["default"].mark((function e(t){var n,r,i;return a["default"].wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,o.promises.readFile(t,"utf8");case 2:return n=e.sent,r=(0,s.parse)(n),i={realm:r.api.site,username:r.api.email,apiKey:r.api.key},i.apiURL="".concat(r.api.site,"/api/v1"),e.abrupt("return",i);case 7:case"end":return e.stop()}}),e)}))),c.apply(this,arguments)}var d=l;t["default"]=d},3934:function(e,t,n){"use strict";var r=n("c532");e.exports=r.isStandardBrowserEnv()?function(){var e,t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");function a(e){var r=e;return t&&(n.setAttribute("href",r),r=n.href),n.setAttribute("href",r),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:"/"===n.pathname.charAt(0)?n.pathname:"/"+n.pathname}}return e=a(window.location.href),function(t){var n=r.isString(t)?a(t):t;return n.protocol===e.protocol&&n.host===e.host}}():function(){return function(){return!0}}()},"3bbe":function(e,t,n){var r=n("861d");e.exports=function(e){if(!r(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},"3ca3":function(e,t,n){"use strict";var r=n("6547").charAt,a=n("69f3"),i=n("7dd0"),o="String Iterator",s=a.set,l=a.getterFor(o);i(String,"String",(function(e){s(this,{type:o,string:String(e),index:0})}),(function(){var e,t=l(this),n=t.string,a=t.index;return a>=n.length?{value:void 0,done:!0}:(e=r(n,a),t.index+=e.length,{value:e,done:!1})}))},"3e8f":function(e,t){},"3f4e":function(e,t,n){"use strict";n.d(t,"setupDevtoolsPlugin",(function(){return i}));var r=n("abc5"),a=n("b774");function i(e,t){const n=Object(r["a"])();if(n)n.emit(a["a"],e,t);else{const n=Object(r["b"])(),a=n.__VUE_DEVTOOLS_PLUGINS__=n.__VUE_DEVTOOLS_PLUGINS__||[];a.push({pluginDescriptor:e,setupFn:t})}}},"3f8c":function(e,t){e.exports={}},4236:function(e,t,n){"use strict";var r=n("0068").isSpace;e.exports=function(e,t){var n,a,i=e.pos;if(10!==e.src.charCodeAt(i))return!1;n=e.pending.length-1,a=e.posMax,t||(n>=0&&32===e.pending.charCodeAt(n)?n>=1&&32===e.pending.charCodeAt(n-1)?(e.pending=e.pending.replace(/ +$/,""),e.push("hardbreak","br",0)):(e.pending=e.pending.slice(0,-1),e.push("softbreak","br",0)):e.push("softbreak","br",0)),i++;while(i3)&&!(e.sCount[l]<0)){for(r=!1,a=0,i=c.length;a=o)return-1;if(n=e.src.charCodeAt(i++),n<48||n>57)return-1;for(;;){if(i>=o)return-1;if(n=e.src.charCodeAt(i++),!(n>=48&&n<=57)){if(41===n||46===n)break;return-1}if(i-a>=10)return-1}return i=4)return!1;if(e.listIndent>=0&&e.sCount[t]-e.listIndent>=4&&e.sCount[t]=e.blkIndent&&(M=!0),(R=i(e,t))>=0){if(f=!0,k=e.bMarks[t]+e.tShift[t],S=Number(e.src.substr(k,R-k-1)),M&&1!==S)return!1}else{if(!((R=a(e,t))>=0))return!1;f=!1}if(M&&e.skipSpaces(R)>=e.eMarks[t])return!1;if(b=e.src.charCodeAt(R-1),r)return!0;h=e.tokens.length,f?(L=e.push("ordered_list_open","ol",1),1!==S&&(L.attrs=[["start",S]])):L=e.push("bullet_list_open","ul",1),L.map=g=[t,0],L.markup=String.fromCharCode(b),y=t,N=!1,D=e.md.block.ruler.getRules("list"),C=e.parentType,e.parentType="list";while(y=E?1:v-p,u>4&&(u=1),d=p+u,L=e.push("list_item_open","li",1),L.markup=String.fromCharCode(b),L.map=m=[t,0],w=e.tight,x=e.tShift[t],O=e.sCount[t],T=e.listIndent,e.listIndent=e.blkIndent,e.blkIndent=d,e.tight=!0,e.tShift[t]=l-e.bMarks[t],e.sCount[t]=v,l>=E&&e.isEmpty(t+1)?e.line=Math.min(e.line+2,n):e.md.block.tokenize(e,t,n,!0),e.tight&&!N||(P=!1),N=e.line-t>1&&e.isEmpty(e.line-1),e.blkIndent=e.listIndent,e.listIndent=T,e.tShift[t]=x,e.sCount[t]=O,e.tight=w,L=e.push("list_item_close","li",-1),L.markup=String.fromCharCode(b),y=t=e.line,m[1]=y,l=e.bMarks[t],y>=n)break;if(e.sCount[y]=4)break;for(I=!1,c=0,_=D.length;c<_;c++)if(D[c](e,y,n,!0)){I=!0;break}if(I)break;if(f){if(R=i(e,y),R<0)break}else if(R=a(e,y),R<0)break;if(b!==e.src.charCodeAt(R-1))break}return L=f?e.push("ordered_list_close","ol",-1):e.push("bullet_list_close","ul",-1),L.markup=String.fromCharCode(b),g[1]=y,e.line=y,e.parentType=C,P&&o(e,h),!0}},"4c26":function(e,t,n){"use strict";var r=/\r\n?|\n/g,a=/\0/g;e.exports=function(e){var t;t=e.src.replace(r,"\n"),t=t.replace(a,"�"),e.src=t}},"4cb4":function(e,t,n){"use strict";var r=n("4883"),a=[["text",n("baca")],["newline",n("4236")],["escape",n("6e00")],["backticks",n("4a94")],["strikethrough",n("922c").tokenize],["emphasis",n("c8a9").tokenize],["link",n("cd0f")],["image",n("932d")],["autolink",n("28ec")],["html_inline",n("c2d8")],["entity",n("5b54")]],i=[["balance_pairs",n("838d")],["strikethrough",n("922c").postProcess],["emphasis",n("c8a9").postProcess],["text_collapse",n("2085")]];function o(){var e;for(this.ruler=new r,e=0;e=i)break}else e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()},o.prototype.parse=function(e,t,n,r){var a,i,o,s=new this.State(e,t,n,r);for(this.tokenize(s),i=this.ruler2.getRules(""),o=i.length,a=0;a-1,n&&(t=t.replace(/y/g,"")));var s=o(v?new b(e,t):b(e,t),r?this:S,O);if(T&&n){var l=m(s);l.sticky=!0}return s},x=function(e){e in O||s(O,e,{configurable:!0,get:function(){return b[e]},set:function(t){b[e]=t}})},w=l(b),A=0;while(w.length>A)x(w[A++]);S.constructor=O,O.prototype=S,p(a,"RegExp",O)}_("RegExp")},"4d64":function(e,t,n){var r=n("fc6a"),a=n("50c4"),i=n("23cb"),o=function(e){return function(t,n,o){var s,l=r(t),c=a(l.length),d=i(o,c);if(e&&n!=n){while(c>d)if(s=l[d++],s!=s)return!0}else for(;c>d;d++)if((e||d in l)&&l[d]===n)return e||d||0;return!e&&-1}};e.exports={includes:o(!0),indexOf:o(!1)}},"4de4":function(e,t,n){"use strict";var r=n("23e7"),a=n("b727").filter,i=n("1dde"),o=i("filter");r({target:"Array",proto:!0,forced:!o},{filter:function(e){return a(this,e,arguments.length>1?arguments[1]:void 0)}})},"4df4":function(e,t,n){"use strict";var r=n("0366"),a=n("7b0b"),i=n("9bdd"),o=n("e95a"),s=n("50c4"),l=n("8418"),c=n("35a1");e.exports=function(e){var t,n,d,u,p,f,m=a(e),_="function"==typeof this?this:Array,g=arguments.length,h=g>1?arguments[1]:void 0,b=void 0!==h,S=c(m),E=0;if(b&&(h=r(h,g>2?arguments[2]:void 0,2)),void 0==S||_==Array&&o(S))for(t=s(m.length),n=new _(t);t>E;E++)f=b?h(m[E],E):m[E],l(n,E,f);else for(u=S.call(m),p=u.next,n=new _;!(d=p.call(u)).done;E++)f=b?i(u,h,[d.value,E],!0):d.value,l(n,E,f);return n.length=E,n}},"4e82":function(e,t,n){"use strict";var r=n("23e7"),a=n("1c0b"),i=n("7b0b"),o=n("50c4"),s=n("d039"),l=n("addb"),c=n("a640"),d=n("04d1"),u=n("d998"),p=n("2d00"),f=n("512c"),m=[],_=m.sort,g=s((function(){m.sort(void 0)})),h=s((function(){m.sort(null)})),b=c("sort"),S=!s((function(){if(p)return p<70;if(!(d&&d>3)){if(u)return!0;if(f)return f<603;var e,t,n,r,a="";for(e=65;e<76;e++){switch(t=String.fromCharCode(e),e){case 66:case 69:case 70:case 72:n=3;break;case 68:case 71:n=4;break;default:n=2}for(r=0;r<47;r++)m.push({k:t+r,v:n})}for(m.sort((function(e,t){return t.v-e.v})),r=0;rString(n)?1:-1}};r({target:"Array",proto:!0,forced:E},{sort:function(e){void 0!==e&&a(e);var t=i(this);if(S)return void 0===e?_.call(t):_.call(t,e);var n,r,s=[],c=o(t.length);for(r=0;r0?a(r(e),9007199254740991):0}},"512c":function(e,t,n){var r=n("342f"),a=r.match(/AppleWebKit\/(\d+)\./);e.exports=!!a&&+a[1]},"512e":function(e,t,n){e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="fae3")}({"00ee":function(e,t,n){var r=n("b622"),a=r("toStringTag"),i={};i[a]="z",e.exports="[object z]"===String(i)},"0366":function(e,t,n){var r=n("1c0b");e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 0:return function(){return e.call(t)};case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,a){return e.call(t,n,r,a)}}return function(){return e.apply(t,arguments)}}},"057f":function(e,t,n){var r=n("fc6a"),a=n("241c").f,i={}.toString,o="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(e){try{return a(e)}catch(t){return o.slice()}};e.exports.f=function(e){return o&&"[object Window]"==i.call(e)?s(e):a(r(e))}},"06cf":function(e,t,n){var r=n("83ab"),a=n("d1e7"),i=n("5c6c"),o=n("fc6a"),s=n("c04e"),l=n("5135"),c=n("0cfb"),d=Object.getOwnPropertyDescriptor;t.f=r?d:function(e,t){if(e=o(e),t=s(t,!0),c)try{return d(e,t)}catch(n){}if(l(e,t))return i(!a.f.call(e,t),e[t])}},"0cfb":function(e,t,n){var r=n("83ab"),a=n("d039"),i=n("cc12");e.exports=!r&&!a((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},"13d5":function(e,t,n){"use strict";var r=n("23e7"),a=n("d58f").left,i=n("a640"),o=n("ae40"),s=i("reduce"),l=o("reduce",{1:0});r({target:"Array",proto:!0,forced:!s||!l},{reduce:function(e){return a(this,e,arguments.length,arguments.length>1?arguments[1]:void 0)}})},"159b":function(e,t,n){var r=n("da84"),a=n("fdbc"),i=n("17c2"),o=n("9112");for(var s in a){var l=r[s],c=l&&l.prototype;if(c&&c.forEach!==i)try{o(c,"forEach",i)}catch(d){c.forEach=i}}},"17c2":function(e,t,n){"use strict";var r=n("b727").forEach,a=n("a640"),i=n("ae40"),o=a("forEach"),s=i("forEach");e.exports=o&&s?[].forEach:function(e){return r(this,e,arguments.length>1?arguments[1]:void 0)}},"1be4":function(e,t,n){var r=n("d066");e.exports=r("document","documentElement")},"1c0b":function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},"1c7e":function(e,t,n){var r=n("b622"),a=r("iterator"),i=!1;try{var o=0,s={next:function(){return{done:!!o++}},return:function(){i=!0}};s[a]=function(){return this},Array.from(s,(function(){throw 2}))}catch(l){}e.exports=function(e,t){if(!t&&!i)return!1;var n=!1;try{var r={};r[a]=function(){return{next:function(){return{done:n=!0}}}},e(r)}catch(l){}return n}},"1d80":function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},"1dde":function(e,t,n){var r=n("d039"),a=n("b622"),i=n("2d00"),o=a("species");e.exports=function(e){return i>=51||!r((function(){var t=[],n=t.constructor={};return n[o]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},"23cb":function(e,t,n){var r=n("a691"),a=Math.max,i=Math.min;e.exports=function(e,t){var n=r(e);return n<0?a(n+t,0):i(n,t)}},"23e7":function(e,t,n){var r=n("da84"),a=n("06cf").f,i=n("9112"),o=n("6eeb"),s=n("ce4e"),l=n("e893"),c=n("94ca");e.exports=function(e,t){var n,d,u,p,f,m,_=e.target,g=e.global,h=e.stat;if(d=g?r:h?r[_]||s(_,{}):(r[_]||{}).prototype,d)for(u in t){if(f=t[u],e.noTargetGet?(m=a(d,u),p=m&&m.value):p=d[u],n=c(g?u:_+(h?".":"#")+u,e.forced),!n&&void 0!==p){if(typeof f===typeof p)continue;l(f,p)}(e.sham||p&&p.sham)&&i(f,"sham",!0),o(d,u,f,e)}}},"241c":function(e,t,n){var r=n("ca84"),a=n("7839"),i=a.concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return r(e,i)}},2532:function(e,t,n){"use strict";var r=n("23e7"),a=n("5a34"),i=n("1d80"),o=n("ab13");r({target:"String",proto:!0,forced:!o("includes")},{includes:function(e){return!!~String(i(this)).indexOf(a(e),arguments.length>1?arguments[1]:void 0)}})},"25f0":function(e,t,n){"use strict";var r=n("6eeb"),a=n("825a"),i=n("d039"),o=n("ad6d"),s="toString",l=RegExp.prototype,c=l[s],d=i((function(){return"/a/b"!=c.call({source:"a",flags:"b"})})),u=c.name!=s;(d||u)&&r(RegExp.prototype,s,(function(){var e=a(this),t=String(e.source),n=e.flags,r=String(void 0===n&&e instanceof RegExp&&!("flags"in l)?o.call(e):n);return"/"+t+"/"+r}),{unsafe:!0})},"2d00":function(e,t,n){var r,a,i=n("da84"),o=n("342f"),s=i.process,l=s&&s.versions,c=l&&l.v8;c?(r=c.split("."),a=r[0]+r[1]):o&&(r=o.match(/Edge\/(\d+)/),(!r||r[1]>=74)&&(r=o.match(/Chrome\/(\d+)/),r&&(a=r[1]))),e.exports=a&&+a},"342f":function(e,t,n){var r=n("d066");e.exports=r("navigator","userAgent")||""},"35a1":function(e,t,n){var r=n("f5df"),a=n("3f8c"),i=n("b622"),o=i("iterator");e.exports=function(e){if(void 0!=e)return e[o]||e["@@iterator"]||a[r(e)]}},"37e8":function(e,t,n){var r=n("83ab"),a=n("9bf2"),i=n("825a"),o=n("df75");e.exports=r?Object.defineProperties:function(e,t){i(e);var n,r=o(t),s=r.length,l=0;while(s>l)a.f(e,n=r[l++],t[n]);return e}},"3bbe":function(e,t,n){var r=n("861d");e.exports=function(e){if(!r(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},"3ca3":function(e,t,n){"use strict";var r=n("6547").charAt,a=n("69f3"),i=n("7dd0"),o="String Iterator",s=a.set,l=a.getterFor(o);i(String,"String",(function(e){s(this,{type:o,string:String(e),index:0})}),(function(){var e,t=l(this),n=t.string,a=t.index;return a>=n.length?{value:void 0,done:!0}:(e=r(n,a),t.index+=e.length,{value:e,done:!1})}))},"3f8c":function(e,t){e.exports={}},4160:function(e,t,n){"use strict";var r=n("23e7"),a=n("17c2");r({target:"Array",proto:!0,forced:[].forEach!=a},{forEach:a})},"428f":function(e,t,n){var r=n("da84");e.exports=r},"44ad":function(e,t,n){var r=n("d039"),a=n("c6b6"),i="".split;e.exports=r((function(){return!Object("z").propertyIsEnumerable(0)}))?function(e){return"String"==a(e)?i.call(e,""):Object(e)}:Object},"44d2":function(e,t,n){var r=n("b622"),a=n("7c73"),i=n("9bf2"),o=r("unscopables"),s=Array.prototype;void 0==s[o]&&i.f(s,o,{configurable:!0,value:a(null)}),e.exports=function(e){s[o][e]=!0}},"44e7":function(e,t,n){var r=n("861d"),a=n("c6b6"),i=n("b622"),o=i("match");e.exports=function(e){var t;return r(e)&&(void 0!==(t=e[o])?!!t:"RegExp"==a(e))}},"45fc":function(e,t,n){"use strict";var r=n("23e7"),a=n("b727").some,i=n("a640"),o=n("ae40"),s=i("some"),l=o("some");r({target:"Array",proto:!0,forced:!s||!l},{some:function(e){return a(this,e,arguments.length>1?arguments[1]:void 0)}})},4930:function(e,t,n){var r=n("d039");e.exports=!!Object.getOwnPropertySymbols&&!r((function(){return!String(Symbol())}))},"4d64":function(e,t,n){var r=n("fc6a"),a=n("50c4"),i=n("23cb"),o=function(e){return function(t,n,o){var s,l=r(t),c=a(l.length),d=i(o,c);if(e&&n!=n){while(c>d)if(s=l[d++],s!=s)return!0}else for(;c>d;d++)if((e||d in l)&&l[d]===n)return e||d||0;return!e&&-1}};e.exports={includes:o(!0),indexOf:o(!1)}},"4de4":function(e,t,n){"use strict";var r=n("23e7"),a=n("b727").filter,i=n("1dde"),o=n("ae40"),s=i("filter"),l=o("filter");r({target:"Array",proto:!0,forced:!s||!l},{filter:function(e){return a(this,e,arguments.length>1?arguments[1]:void 0)}})},"4df4":function(e,t,n){"use strict";var r=n("0366"),a=n("7b0b"),i=n("9bdd"),o=n("e95a"),s=n("50c4"),l=n("8418"),c=n("35a1");e.exports=function(e){var t,n,d,u,p,f,m=a(e),_="function"==typeof this?this:Array,g=arguments.length,h=g>1?arguments[1]:void 0,b=void 0!==h,S=c(m),E=0;if(b&&(h=r(h,g>2?arguments[2]:void 0,2)),void 0==S||_==Array&&o(S))for(t=s(m.length),n=new _(t);t>E;E++)f=b?h(m[E],E):m[E],l(n,E,f);else for(u=S.call(m),p=u.next,n=new _;!(d=p.call(u)).done;E++)f=b?i(u,h,[d.value,E],!0):d.value,l(n,E,f);return n.length=E,n}},"4fad":function(e,t,n){var r=n("23e7"),a=n("6f53").entries;r({target:"Object",stat:!0},{entries:function(e){return a(e)}})},"50c4":function(e,t,n){var r=n("a691"),a=Math.min;e.exports=function(e){return e>0?a(r(e),9007199254740991):0}},5135:function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},5692:function(e,t,n){var r=n("c430"),a=n("c6cd");(e.exports=function(e,t){return a[e]||(a[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.6.5",mode:r?"pure":"global",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})},"56ef":function(e,t,n){var r=n("d066"),a=n("241c"),i=n("7418"),o=n("825a");e.exports=r("Reflect","ownKeys")||function(e){var t=a.f(o(e)),n=i.f;return n?t.concat(n(e)):t}},5899:function(e,t){e.exports="\t\n\v\f\r                 \u2028\u2029\ufeff"},"58a8":function(e,t,n){var r=n("1d80"),a=n("5899"),i="["+a+"]",o=RegExp("^"+i+i+"*"),s=RegExp(i+i+"*$"),l=function(e){return function(t){var n=String(r(t));return 1&e&&(n=n.replace(o,"")),2&e&&(n=n.replace(s,"")),n}};e.exports={start:l(1),end:l(2),trim:l(3)}},"5a34":function(e,t,n){var r=n("44e7");e.exports=function(e){if(r(e))throw TypeError("The method doesn't accept regular expressions");return e}},"5c6c":function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},6547:function(e,t,n){var r=n("a691"),a=n("1d80"),i=function(e){return function(t,n){var i,o,s=String(a(t)),l=r(n),c=s.length;return l<0||l>=c?e?"":void 0:(i=s.charCodeAt(l),i<55296||i>56319||l+1===c||(o=s.charCodeAt(l+1))<56320||o>57343?e?s.charAt(l):i:e?s.slice(l,l+2):o-56320+(i-55296<<10)+65536)}};e.exports={codeAt:i(!1),charAt:i(!0)}},"65f0":function(e,t,n){var r=n("861d"),a=n("e8b5"),i=n("b622"),o=i("species");e.exports=function(e,t){var n;return a(e)&&(n=e.constructor,"function"!=typeof n||n!==Array&&!a(n.prototype)?r(n)&&(n=n[o],null===n&&(n=void 0)):n=void 0),new(void 0===n?Array:n)(0===t?0:t)}},"69f3":function(e,t,n){var r,a,i,o=n("7f9a"),s=n("da84"),l=n("861d"),c=n("9112"),d=n("5135"),u=n("f772"),p=n("d012"),f=s.WeakMap,m=function(e){return i(e)?a(e):r(e,{})},_=function(e){return function(t){var n;if(!l(t)||(n=a(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}};if(o){var g=new f,h=g.get,b=g.has,S=g.set;r=function(e,t){return S.call(g,e,t),t},a=function(e){return h.call(g,e)||{}},i=function(e){return b.call(g,e)}}else{var E=u("state");p[E]=!0,r=function(e,t){return c(e,E,t),t},a=function(e){return d(e,E)?e[E]:{}},i=function(e){return d(e,E)}}e.exports={set:r,get:a,has:i,enforce:m,getterFor:_}},"6b0a":function(e,t,n){"use strict";n("cebe")},"6eeb":function(e,t,n){var r=n("da84"),a=n("9112"),i=n("5135"),o=n("ce4e"),s=n("8925"),l=n("69f3"),c=l.get,d=l.enforce,u=String(String).split("String");(e.exports=function(e,t,n,s){var l=!!s&&!!s.unsafe,c=!!s&&!!s.enumerable,p=!!s&&!!s.noTargetGet;"function"==typeof n&&("string"!=typeof t||i(n,"name")||a(n,"name",t),d(n).source=u.join("string"==typeof t?t:"")),e!==r?(l?!p&&e[t]&&(c=!0):delete e[t],c?e[t]=n:a(e,t,n)):c?e[t]=n:o(t,n)})(Function.prototype,"toString",(function(){return"function"==typeof this&&c(this).source||s(this)}))},"6f53":function(e,t,n){var r=n("83ab"),a=n("df75"),i=n("fc6a"),o=n("d1e7").f,s=function(e){return function(t){var n,s=i(t),l=a(s),c=l.length,d=0,u=[];while(c>d)n=l[d++],r&&!o.call(s,n)||u.push(e?[n,s[n]]:s[n]);return u}};e.exports={entries:s(!0),values:s(!1)}},7156:function(e,t,n){var r=n("861d"),a=n("d2bb");e.exports=function(e,t,n){var i,o;return a&&"function"==typeof(i=t.constructor)&&i!==n&&r(o=i.prototype)&&o!==n.prototype&&a(e,o),e}},7418:function(e,t){t.f=Object.getOwnPropertySymbols},"746f":function(e,t,n){var r=n("428f"),a=n("5135"),i=n("e538"),o=n("9bf2").f;e.exports=function(e){var t=r.Symbol||(r.Symbol={});a(t,e)||o(t,e,{value:i.f(e)})}},7839:function(e,t){e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},"7b0b":function(e,t,n){var r=n("1d80");e.exports=function(e){return Object(r(e))}},"7c73":function(e,t,n){var r,a=n("825a"),i=n("37e8"),o=n("7839"),s=n("d012"),l=n("1be4"),c=n("cc12"),d=n("f772"),u=">",p="<",f="prototype",m="script",_=d("IE_PROTO"),g=function(){},h=function(e){return p+m+u+e+p+"/"+m+u},b=function(e){e.write(h("")),e.close();var t=e.parentWindow.Object;return e=null,t},S=function(){var e,t=c("iframe"),n="java"+m+":";return t.style.display="none",l.appendChild(t),t.src=String(n),e=t.contentWindow.document,e.open(),e.write(h("document.F=Object")),e.close(),e.F},E=function(){try{r=document.domain&&new ActiveXObject("htmlfile")}catch(t){}E=r?b(r):S();var e=o.length;while(e--)delete E[f][o[e]];return E()};s[_]=!0,e.exports=Object.create||function(e,t){var n;return null!==e?(g[f]=a(e),n=new g,g[f]=null,n[_]=e):n=E(),void 0===t?n:i(n,t)}},"7db0":function(e,t,n){"use strict";var r=n("23e7"),a=n("b727").find,i=n("44d2"),o=n("ae40"),s="find",l=!0,c=o(s);s in[]&&Array(1)[s]((function(){l=!1})),r({target:"Array",proto:!0,forced:l||!c},{find:function(e){return a(this,e,arguments.length>1?arguments[1]:void 0)}}),i(s)},"7dd0":function(e,t,n){"use strict";var r=n("23e7"),a=n("9ed3"),i=n("e163"),o=n("d2bb"),s=n("d44e"),l=n("9112"),c=n("6eeb"),d=n("b622"),u=n("c430"),p=n("3f8c"),f=n("ae93"),m=f.IteratorPrototype,_=f.BUGGY_SAFARI_ITERATORS,g=d("iterator"),h="keys",b="values",S="entries",E=function(){return this};e.exports=function(e,t,n,d,f,y,v){a(n,t,d);var T,C,O,x=function(e){if(e===f&&k)return k;if(!_&&e in R)return R[e];switch(e){case h:return function(){return new n(this,e)};case b:return function(){return new n(this,e)};case S:return function(){return new n(this,e)}}return function(){return new n(this)}},w=t+" Iterator",A=!1,R=e.prototype,N=R[g]||R["@@iterator"]||f&&R[f],k=!_&&N||x(f),I="Array"==t&&R.entries||N;if(I&&(T=i(I.call(new e)),m!==Object.prototype&&T.next&&(u||i(T)===m||(o?o(T,m):"function"!=typeof T[g]&&l(T,g,E)),s(T,w,!0,!0),u&&(p[w]=E))),f==b&&N&&N.name!==b&&(A=!0,k=function(){return N.call(this)}),u&&!v||R[g]===k||l(R,g,k),p[t]=k,f)if(C={values:x(b),keys:y?k:x(h),entries:x(S)},v)for(O in C)(_||A||!(O in R))&&c(R,O,C[O]);else r({target:t,proto:!0,forced:_||A},C);return C}},"7f9a":function(e,t,n){var r=n("da84"),a=n("8925"),i=r.WeakMap;e.exports="function"===typeof i&&/native code/.test(a(i))},"825a":function(e,t,n){var r=n("861d");e.exports=function(e){if(!r(e))throw TypeError(String(e)+" is not an object");return e}},"83ab":function(e,t,n){var r=n("d039");e.exports=!r((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},8418:function(e,t,n){"use strict";var r=n("c04e"),a=n("9bf2"),i=n("5c6c");e.exports=function(e,t,n){var o=r(t);o in e?a.f(e,o,i(0,n)):e[o]=n}},"861d":function(e,t){e.exports=function(e){return"object"===typeof e?null!==e:"function"===typeof e}},8875:function(e,t,n){var r,a,i;(function(n,o){a=[],r=o,i="function"===typeof r?r.apply(t,a):r,void 0===i||(e.exports=i)})("undefined"!==typeof self&&self,(function(){function e(){var t=Object.getOwnPropertyDescriptor(document,"currentScript");if(!t&&"currentScript"in document&&document.currentScript)return document.currentScript;if(t&&t.get!==e&&document.currentScript)return document.currentScript;try{throw new Error}catch(f){var n,r,a,i=/.*at [^(]*\((.*):(.+):(.+)\)$/gi,o=/@([^@]*):(\d+):(\d+)\s*$/gi,s=i.exec(f.stack)||o.exec(f.stack),l=s&&s[1]||!1,c=s&&s[2]||!1,d=document.location.href.replace(document.location.hash,""),u=document.getElementsByTagName("script");l===d&&(n=document.documentElement.outerHTML,r=new RegExp("(?:[^\\n]+?\\n){0,"+(c-2)+"}[^<]*