diff --git a/.gitignore b/.gitignore index 6526cbd49b..c7e719529f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ _site/ _draft/ .jekyll-cache/ +.obsidian/ +.env +.DS_Store diff --git a/.obsidian/app.json b/.obsidian/app.json new file mode 100644 index 0000000000..af13dfbcde --- /dev/null +++ b/.obsidian/app.json @@ -0,0 +1,3 @@ +{ + "attachmentFolderPath": "assets/images/EM" +} \ No newline at end of file diff --git a/.obsidian/appearance.json b/.obsidian/appearance.json new file mode 100644 index 0000000000..c8c365d89b --- /dev/null +++ b/.obsidian/appearance.json @@ -0,0 +1,3 @@ +{ + "accentColor": "" +} \ No newline at end of file diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json new file mode 100644 index 0000000000..d3f66fab1d --- /dev/null +++ b/.obsidian/community-plugins.json @@ -0,0 +1,3 @@ +[ + "obsidian-git" +] \ No newline at end of file diff --git a/.obsidian/core-plugins-migration.json b/.obsidian/core-plugins-migration.json new file mode 100644 index 0000000000..2239c74e81 --- /dev/null +++ b/.obsidian/core-plugins-migration.json @@ -0,0 +1,30 @@ +{ + "file-explorer": true, + "global-search": true, + "switcher": true, + "graph": true, + "backlink": true, + "outgoing-link": true, + "tag-pane": true, + "page-preview": true, + "daily-notes": true, + "templates": true, + "note-composer": true, + "command-palette": true, + "slash-command": false, + "editor-status": true, + "markdown-importer": false, + "zk-prefixer": false, + "random-note": false, + "outline": true, + "word-count": true, + "slides": false, + "audio-recorder": false, + "workspaces": false, + "file-recovery": true, + "publish": false, + "sync": false, + "canvas": true, + "properties": false, + "bookmarks": true +} \ No newline at end of file diff --git a/.obsidian/core-plugins.json b/.obsidian/core-plugins.json new file mode 100644 index 0000000000..9405bfdc22 --- /dev/null +++ b/.obsidian/core-plugins.json @@ -0,0 +1,20 @@ +[ + "file-explorer", + "global-search", + "switcher", + "graph", + "backlink", + "canvas", + "outgoing-link", + "tag-pane", + "page-preview", + "daily-notes", + "templates", + "note-composer", + "command-palette", + "editor-status", + "bookmarks", + "outline", + "word-count", + "file-recovery" +] \ No newline at end of file diff --git a/.obsidian/hotkeys.json b/.obsidian/hotkeys.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/.obsidian/hotkeys.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.obsidian/plugins/obsidian-git/data.json b/.obsidian/plugins/obsidian-git/data.json new file mode 100644 index 0000000000..7f90fce12a --- /dev/null +++ b/.obsidian/plugins/obsidian-git/data.json @@ -0,0 +1,55 @@ +{ + "commitMessage": "vault backup: {{date}}", + "commitDateFormat": "YYYY-MM-DD HH:mm:ss", + "autoSaveInterval": 0, + "autoPushInterval": 0, + "autoPullInterval": 0, + "autoPullOnBoot": false, + "disablePush": false, + "pullBeforePush": true, + "disablePopups": false, + "listChangedFilesInMessageBody": false, + "showStatusBar": false, + "updateSubmodules": false, + "syncMethod": "merge", + "customMessageOnAutoBackup": false, + "autoBackupAfterFileChange": false, + "treeStructure": false, + "refreshSourceControl": false, + "basePath": "", + "differentIntervalCommitAndPush": false, + "changedFilesInStatusBar": false, + "showedMobileNotice": true, + "refreshSourceControlTimer": 7000, + "showBranchStatusBar": false, + "setLastSaveToLastCommit": false, + "submoduleRecurseCheckout": false, + "gitDir": "", + "showFileMenu": false, + "lineAuthor": { + "show": false, + "followMovement": "inactive", + "authorDisplay": "initials", + "showCommitHash": false, + "dateTimeFormatOptions": "date", + "dateTimeFormatCustomString": "YYYY-MM-DD HH:mm", + "dateTimeTimezone": "viewer-local", + "coloringMaxAge": "1y", + "colorNew": { + "r": 255, + "g": 150, + "b": 150 + }, + "colorOld": { + "r": 120, + "g": 160, + "b": 255 + }, + "textColorCss": "var(--text-muted)", + "ignoreWhitespace": false, + "gutterSpacingFallbackLength": 5, + "lastShownAuthorDisplay": "initials", + "lastShownDateTimeFormatOptions": "date" + }, + "autoCommitMessage": "ankadutt: {{date}}" +} \ No newline at end of file diff --git a/.obsidian/plugins/obsidian-git/main.js b/.obsidian/plugins/obsidian-git/main.js new file mode 100644 index 0000000000..4c577c138b --- /dev/null +++ b/.obsidian/plugins/obsidian-git/main.js @@ -0,0 +1,43666 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source visit the plugins github repository (https://github.com/denolehov/obsidian-git) +*/ + +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; +}; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key2 of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key2) && key2 !== except) + __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js +var require_base64_js = __commonJS({ + "node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + exports2.byteLength = byteLength; + exports2.toByteArray = toByteArray; + exports2.fromByteArray = fromByteArray; + var lookup = []; + var revLookup = []; + var Arr = typeof Uint8Array !== "undefined" ? Uint8Array : Array; + var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + for (i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i]; + revLookup[code.charCodeAt(i)] = i; + } + var i; + var len; + revLookup["-".charCodeAt(0)] = 62; + revLookup["_".charCodeAt(0)] = 63; + function getLens(b64) { + var len2 = b64.length; + if (len2 % 4 > 0) { + throw new Error("Invalid string. Length must be a multiple of 4"); + } + var validLen = b64.indexOf("="); + if (validLen === -1) + validLen = len2; + var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4; + return [validLen, placeHoldersLen]; + } + function byteLength(b64) { + var lens = getLens(b64); + var validLen = lens[0]; + var placeHoldersLen = lens[1]; + return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen; + } + function _byteLength(b64, validLen, placeHoldersLen) { + return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen; + } + function toByteArray(b64) { + var tmp; + var lens = getLens(b64); + var validLen = lens[0]; + var placeHoldersLen = lens[1]; + var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)); + var curByte = 0; + var len2 = placeHoldersLen > 0 ? validLen - 4 : validLen; + var i2; + for (i2 = 0; i2 < len2; i2 += 4) { + tmp = revLookup[b64.charCodeAt(i2)] << 18 | revLookup[b64.charCodeAt(i2 + 1)] << 12 | revLookup[b64.charCodeAt(i2 + 2)] << 6 | revLookup[b64.charCodeAt(i2 + 3)]; + arr[curByte++] = tmp >> 16 & 255; + arr[curByte++] = tmp >> 8 & 255; + arr[curByte++] = tmp & 255; + } + if (placeHoldersLen === 2) { + tmp = revLookup[b64.charCodeAt(i2)] << 2 | revLookup[b64.charCodeAt(i2 + 1)] >> 4; + arr[curByte++] = tmp & 255; + } + if (placeHoldersLen === 1) { + tmp = revLookup[b64.charCodeAt(i2)] << 10 | revLookup[b64.charCodeAt(i2 + 1)] << 4 | revLookup[b64.charCodeAt(i2 + 2)] >> 2; + arr[curByte++] = tmp >> 8 & 255; + arr[curByte++] = tmp & 255; + } + return arr; + } + function tripletToBase64(num2) { + return lookup[num2 >> 18 & 63] + lookup[num2 >> 12 & 63] + lookup[num2 >> 6 & 63] + lookup[num2 & 63]; + } + function encodeChunk(uint8, start, end) { + var tmp; + var output = []; + for (var i2 = start; i2 < end; i2 += 3) { + tmp = (uint8[i2] << 16 & 16711680) + (uint8[i2 + 1] << 8 & 65280) + (uint8[i2 + 2] & 255); + output.push(tripletToBase64(tmp)); + } + return output.join(""); + } + function fromByteArray(uint8) { + var tmp; + var len2 = uint8.length; + var extraBytes = len2 % 3; + var parts = []; + var maxChunkLength = 16383; + for (var i2 = 0, len22 = len2 - extraBytes; i2 < len22; i2 += maxChunkLength) { + parts.push(encodeChunk(uint8, i2, i2 + maxChunkLength > len22 ? len22 : i2 + maxChunkLength)); + } + if (extraBytes === 1) { + tmp = uint8[len2 - 1]; + parts.push( + lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "==" + ); + } else if (extraBytes === 2) { + tmp = (uint8[len2 - 2] << 8) + uint8[len2 - 1]; + parts.push( + lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "=" + ); + } + return parts.join(""); + } + } +}); + +// node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js +var require_ieee754 = __commonJS({ + "node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js"(exports2) { + init_polyfill_buffer(); + exports2.read = function(buffer2, offset, isLE, mLen, nBytes) { + var e, m; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var nBits = -7; + var i = isLE ? nBytes - 1 : 0; + var d = isLE ? -1 : 1; + var s = buffer2[offset + i]; + i += d; + e = s & (1 << -nBits) - 1; + s >>= -nBits; + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer2[offset + i], i += d, nBits -= 8) { + } + m = e & (1 << -nBits) - 1; + e >>= -nBits; + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer2[offset + i], i += d, nBits -= 8) { + } + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : (s ? -1 : 1) * Infinity; + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); + }; + exports2.write = function(buffer2, value, offset, isLE, mLen, nBytes) { + var e, m, c; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0; + var i = isLE ? 0 : nBytes - 1; + var d = isLE ? 1 : -1; + var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0; + value = Math.abs(value); + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + for (; mLen >= 8; buffer2[offset + i] = m & 255, i += d, m /= 256, mLen -= 8) { + } + e = e << mLen | m; + eLen += mLen; + for (; eLen > 0; buffer2[offset + i] = e & 255, i += d, e /= 256, eLen -= 8) { + } + buffer2[offset + i - d] |= s * 128; + }; + } +}); + +// node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js +var require_buffer = __commonJS({ + "node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var base64 = require_base64_js(); + var ieee754 = require_ieee754(); + var customInspectSymbol = typeof Symbol === "function" && typeof Symbol["for"] === "function" ? Symbol["for"]("nodejs.util.inspect.custom") : null; + exports2.Buffer = Buffer2; + exports2.SlowBuffer = SlowBuffer; + exports2.INSPECT_MAX_BYTES = 50; + var K_MAX_LENGTH = 2147483647; + exports2.kMaxLength = K_MAX_LENGTH; + Buffer2.TYPED_ARRAY_SUPPORT = typedArraySupport(); + if (!Buffer2.TYPED_ARRAY_SUPPORT && typeof console !== "undefined" && typeof console.error === "function") { + console.error( + "This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support." + ); + } + function typedArraySupport() { + try { + const arr = new Uint8Array(1); + const proto = { foo: function() { + return 42; + } }; + Object.setPrototypeOf(proto, Uint8Array.prototype); + Object.setPrototypeOf(arr, proto); + return arr.foo() === 42; + } catch (e) { + return false; + } + } + Object.defineProperty(Buffer2.prototype, "parent", { + enumerable: true, + get: function() { + if (!Buffer2.isBuffer(this)) + return void 0; + return this.buffer; + } + }); + Object.defineProperty(Buffer2.prototype, "offset", { + enumerable: true, + get: function() { + if (!Buffer2.isBuffer(this)) + return void 0; + return this.byteOffset; + } + }); + function createBuffer(length) { + if (length > K_MAX_LENGTH) { + throw new RangeError('The value "' + length + '" is invalid for option "size"'); + } + const buf = new Uint8Array(length); + Object.setPrototypeOf(buf, Buffer2.prototype); + return buf; + } + function Buffer2(arg, encodingOrOffset, length) { + if (typeof arg === "number") { + if (typeof encodingOrOffset === "string") { + throw new TypeError( + 'The "string" argument must be of type string. Received type number' + ); + } + return allocUnsafe(arg); + } + return from(arg, encodingOrOffset, length); + } + Buffer2.poolSize = 8192; + function from(value, encodingOrOffset, length) { + if (typeof value === "string") { + return fromString2(value, encodingOrOffset); + } + if (ArrayBuffer.isView(value)) { + return fromArrayView(value); + } + if (value == null) { + throw new TypeError( + "The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof value + ); + } + if (isInstance(value, ArrayBuffer) || value && isInstance(value.buffer, ArrayBuffer)) { + return fromArrayBuffer(value, encodingOrOffset, length); + } + if (typeof SharedArrayBuffer !== "undefined" && (isInstance(value, SharedArrayBuffer) || value && isInstance(value.buffer, SharedArrayBuffer))) { + return fromArrayBuffer(value, encodingOrOffset, length); + } + if (typeof value === "number") { + throw new TypeError( + 'The "value" argument must not be of type number. Received type number' + ); + } + const valueOf = value.valueOf && value.valueOf(); + if (valueOf != null && valueOf !== value) { + return Buffer2.from(valueOf, encodingOrOffset, length); + } + const b = fromObject(value); + if (b) + return b; + if (typeof Symbol !== "undefined" && Symbol.toPrimitive != null && typeof value[Symbol.toPrimitive] === "function") { + return Buffer2.from(value[Symbol.toPrimitive]("string"), encodingOrOffset, length); + } + throw new TypeError( + "The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof value + ); + } + Buffer2.from = function(value, encodingOrOffset, length) { + return from(value, encodingOrOffset, length); + }; + Object.setPrototypeOf(Buffer2.prototype, Uint8Array.prototype); + Object.setPrototypeOf(Buffer2, Uint8Array); + function assertSize(size) { + if (typeof size !== "number") { + throw new TypeError('"size" argument must be of type number'); + } else if (size < 0) { + throw new RangeError('The value "' + size + '" is invalid for option "size"'); + } + } + function alloc(size, fill, encoding) { + assertSize(size); + if (size <= 0) { + return createBuffer(size); + } + if (fill !== void 0) { + return typeof encoding === "string" ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill); + } + return createBuffer(size); + } + Buffer2.alloc = function(size, fill, encoding) { + return alloc(size, fill, encoding); + }; + function allocUnsafe(size) { + assertSize(size); + return createBuffer(size < 0 ? 0 : checked(size) | 0); + } + Buffer2.allocUnsafe = function(size) { + return allocUnsafe(size); + }; + Buffer2.allocUnsafeSlow = function(size) { + return allocUnsafe(size); + }; + function fromString2(string, encoding) { + if (typeof encoding !== "string" || encoding === "") { + encoding = "utf8"; + } + if (!Buffer2.isEncoding(encoding)) { + throw new TypeError("Unknown encoding: " + encoding); + } + const length = byteLength(string, encoding) | 0; + let buf = createBuffer(length); + const actual = buf.write(string, encoding); + if (actual !== length) { + buf = buf.slice(0, actual); + } + return buf; + } + function fromArrayLike(array) { + const length = array.length < 0 ? 0 : checked(array.length) | 0; + const buf = createBuffer(length); + for (let i = 0; i < length; i += 1) { + buf[i] = array[i] & 255; + } + return buf; + } + function fromArrayView(arrayView) { + if (isInstance(arrayView, Uint8Array)) { + const copy2 = new Uint8Array(arrayView); + return fromArrayBuffer(copy2.buffer, copy2.byteOffset, copy2.byteLength); + } + return fromArrayLike(arrayView); + } + function fromArrayBuffer(array, byteOffset, length) { + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('"offset" is outside of buffer bounds'); + } + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('"length" is outside of buffer bounds'); + } + let buf; + if (byteOffset === void 0 && length === void 0) { + buf = new Uint8Array(array); + } else if (length === void 0) { + buf = new Uint8Array(array, byteOffset); + } else { + buf = new Uint8Array(array, byteOffset, length); + } + Object.setPrototypeOf(buf, Buffer2.prototype); + return buf; + } + function fromObject(obj) { + if (Buffer2.isBuffer(obj)) { + const len = checked(obj.length) | 0; + const buf = createBuffer(len); + if (buf.length === 0) { + return buf; + } + obj.copy(buf, 0, 0, len); + return buf; + } + if (obj.length !== void 0) { + if (typeof obj.length !== "number" || numberIsNaN(obj.length)) { + return createBuffer(0); + } + return fromArrayLike(obj); + } + if (obj.type === "Buffer" && Array.isArray(obj.data)) { + return fromArrayLike(obj.data); + } + } + function checked(length) { + if (length >= K_MAX_LENGTH) { + throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + K_MAX_LENGTH.toString(16) + " bytes"); + } + return length | 0; + } + function SlowBuffer(length) { + if (+length != length) { + length = 0; + } + return Buffer2.alloc(+length); + } + Buffer2.isBuffer = function isBuffer(b) { + return b != null && b._isBuffer === true && b !== Buffer2.prototype; + }; + Buffer2.compare = function compare(a, b) { + if (isInstance(a, Uint8Array)) + a = Buffer2.from(a, a.offset, a.byteLength); + if (isInstance(b, Uint8Array)) + b = Buffer2.from(b, b.offset, b.byteLength); + if (!Buffer2.isBuffer(a) || !Buffer2.isBuffer(b)) { + throw new TypeError( + 'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array' + ); + } + if (a === b) + return 0; + let x = a.length; + let y = b.length; + for (let i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i]; + y = b[i]; + break; + } + } + if (x < y) + return -1; + if (y < x) + return 1; + return 0; + }; + Buffer2.isEncoding = function isEncoding(encoding) { + switch (String(encoding).toLowerCase()) { + case "hex": + case "utf8": + case "utf-8": + case "ascii": + case "latin1": + case "binary": + case "base64": + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return true; + default: + return false; + } + }; + Buffer2.concat = function concat(list, length) { + if (!Array.isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers'); + } + if (list.length === 0) { + return Buffer2.alloc(0); + } + let i; + if (length === void 0) { + length = 0; + for (i = 0; i < list.length; ++i) { + length += list[i].length; + } + } + const buffer2 = Buffer2.allocUnsafe(length); + let pos = 0; + for (i = 0; i < list.length; ++i) { + let buf = list[i]; + if (isInstance(buf, Uint8Array)) { + if (pos + buf.length > buffer2.length) { + if (!Buffer2.isBuffer(buf)) + buf = Buffer2.from(buf); + buf.copy(buffer2, pos); + } else { + Uint8Array.prototype.set.call( + buffer2, + buf, + pos + ); + } + } else if (!Buffer2.isBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers'); + } else { + buf.copy(buffer2, pos); + } + pos += buf.length; + } + return buffer2; + }; + function byteLength(string, encoding) { + if (Buffer2.isBuffer(string)) { + return string.length; + } + if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) { + return string.byteLength; + } + if (typeof string !== "string") { + throw new TypeError( + 'The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type ' + typeof string + ); + } + const len = string.length; + const mustMatch = arguments.length > 2 && arguments[2] === true; + if (!mustMatch && len === 0) + return 0; + let loweredCase = false; + for (; ; ) { + switch (encoding) { + case "ascii": + case "latin1": + case "binary": + return len; + case "utf8": + case "utf-8": + return utf8ToBytes(string).length; + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return len * 2; + case "hex": + return len >>> 1; + case "base64": + return base64ToBytes(string).length; + default: + if (loweredCase) { + return mustMatch ? -1 : utf8ToBytes(string).length; + } + encoding = ("" + encoding).toLowerCase(); + loweredCase = true; + } + } + } + Buffer2.byteLength = byteLength; + function slowToString(encoding, start, end) { + let loweredCase = false; + if (start === void 0 || start < 0) { + start = 0; + } + if (start > this.length) { + return ""; + } + if (end === void 0 || end > this.length) { + end = this.length; + } + if (end <= 0) { + return ""; + } + end >>>= 0; + start >>>= 0; + if (end <= start) { + return ""; + } + if (!encoding) + encoding = "utf8"; + while (true) { + switch (encoding) { + case "hex": + return hexSlice(this, start, end); + case "utf8": + case "utf-8": + return utf8Slice(this, start, end); + case "ascii": + return asciiSlice(this, start, end); + case "latin1": + case "binary": + return latin1Slice(this, start, end); + case "base64": + return base64Slice(this, start, end); + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return utf16leSlice(this, start, end); + default: + if (loweredCase) + throw new TypeError("Unknown encoding: " + encoding); + encoding = (encoding + "").toLowerCase(); + loweredCase = true; + } + } + } + Buffer2.prototype._isBuffer = true; + function swap(b, n, m) { + const i = b[n]; + b[n] = b[m]; + b[m] = i; + } + Buffer2.prototype.swap16 = function swap16() { + const len = this.length; + if (len % 2 !== 0) { + throw new RangeError("Buffer size must be a multiple of 16-bits"); + } + for (let i = 0; i < len; i += 2) { + swap(this, i, i + 1); + } + return this; + }; + Buffer2.prototype.swap32 = function swap32() { + const len = this.length; + if (len % 4 !== 0) { + throw new RangeError("Buffer size must be a multiple of 32-bits"); + } + for (let i = 0; i < len; i += 4) { + swap(this, i, i + 3); + swap(this, i + 1, i + 2); + } + return this; + }; + Buffer2.prototype.swap64 = function swap64() { + const len = this.length; + if (len % 8 !== 0) { + throw new RangeError("Buffer size must be a multiple of 64-bits"); + } + for (let i = 0; i < len; i += 8) { + swap(this, i, i + 7); + swap(this, i + 1, i + 6); + swap(this, i + 2, i + 5); + swap(this, i + 3, i + 4); + } + return this; + }; + Buffer2.prototype.toString = function toString() { + const length = this.length; + if (length === 0) + return ""; + if (arguments.length === 0) + return utf8Slice(this, 0, length); + return slowToString.apply(this, arguments); + }; + Buffer2.prototype.toLocaleString = Buffer2.prototype.toString; + Buffer2.prototype.equals = function equals2(b) { + if (!Buffer2.isBuffer(b)) + throw new TypeError("Argument must be a Buffer"); + if (this === b) + return true; + return Buffer2.compare(this, b) === 0; + }; + Buffer2.prototype.inspect = function inspect() { + let str = ""; + const max = exports2.INSPECT_MAX_BYTES; + str = this.toString("hex", 0, max).replace(/(.{2})/g, "$1 ").trim(); + if (this.length > max) + str += " ... "; + return ""; + }; + if (customInspectSymbol) { + Buffer2.prototype[customInspectSymbol] = Buffer2.prototype.inspect; + } + Buffer2.prototype.compare = function compare(target, start, end, thisStart, thisEnd) { + if (isInstance(target, Uint8Array)) { + target = Buffer2.from(target, target.offset, target.byteLength); + } + if (!Buffer2.isBuffer(target)) { + throw new TypeError( + 'The "target" argument must be one of type Buffer or Uint8Array. Received type ' + typeof target + ); + } + if (start === void 0) { + start = 0; + } + if (end === void 0) { + end = target ? target.length : 0; + } + if (thisStart === void 0) { + thisStart = 0; + } + if (thisEnd === void 0) { + thisEnd = this.length; + } + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError("out of range index"); + } + if (thisStart >= thisEnd && start >= end) { + return 0; + } + if (thisStart >= thisEnd) { + return -1; + } + if (start >= end) { + return 1; + } + start >>>= 0; + end >>>= 0; + thisStart >>>= 0; + thisEnd >>>= 0; + if (this === target) + return 0; + let x = thisEnd - thisStart; + let y = end - start; + const len = Math.min(x, y); + const thisCopy = this.slice(thisStart, thisEnd); + const targetCopy = target.slice(start, end); + for (let i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i]; + y = targetCopy[i]; + break; + } + } + if (x < y) + return -1; + if (y < x) + return 1; + return 0; + }; + function bidirectionalIndexOf(buffer2, val, byteOffset, encoding, dir) { + if (buffer2.length === 0) + return -1; + if (typeof byteOffset === "string") { + encoding = byteOffset; + byteOffset = 0; + } else if (byteOffset > 2147483647) { + byteOffset = 2147483647; + } else if (byteOffset < -2147483648) { + byteOffset = -2147483648; + } + byteOffset = +byteOffset; + if (numberIsNaN(byteOffset)) { + byteOffset = dir ? 0 : buffer2.length - 1; + } + if (byteOffset < 0) + byteOffset = buffer2.length + byteOffset; + if (byteOffset >= buffer2.length) { + if (dir) + return -1; + else + byteOffset = buffer2.length - 1; + } else if (byteOffset < 0) { + if (dir) + byteOffset = 0; + else + return -1; + } + if (typeof val === "string") { + val = Buffer2.from(val, encoding); + } + if (Buffer2.isBuffer(val)) { + if (val.length === 0) { + return -1; + } + return arrayIndexOf(buffer2, val, byteOffset, encoding, dir); + } else if (typeof val === "number") { + val = val & 255; + if (typeof Uint8Array.prototype.indexOf === "function") { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer2, val, byteOffset); + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer2, val, byteOffset); + } + } + return arrayIndexOf(buffer2, [val], byteOffset, encoding, dir); + } + throw new TypeError("val must be string, number or Buffer"); + } + function arrayIndexOf(arr, val, byteOffset, encoding, dir) { + let indexSize = 1; + let arrLength = arr.length; + let valLength = val.length; + if (encoding !== void 0) { + encoding = String(encoding).toLowerCase(); + if (encoding === "ucs2" || encoding === "ucs-2" || encoding === "utf16le" || encoding === "utf-16le") { + if (arr.length < 2 || val.length < 2) { + return -1; + } + indexSize = 2; + arrLength /= 2; + valLength /= 2; + byteOffset /= 2; + } + } + function read(buf, i2) { + if (indexSize === 1) { + return buf[i2]; + } else { + return buf.readUInt16BE(i2 * indexSize); + } + } + let i; + if (dir) { + let foundIndex = -1; + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) + foundIndex = i; + if (i - foundIndex + 1 === valLength) + return foundIndex * indexSize; + } else { + if (foundIndex !== -1) + i -= i - foundIndex; + foundIndex = -1; + } + } + } else { + if (byteOffset + valLength > arrLength) + byteOffset = arrLength - valLength; + for (i = byteOffset; i >= 0; i--) { + let found = true; + for (let j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false; + break; + } + } + if (found) + return i; + } + } + return -1; + } + Buffer2.prototype.includes = function includes(val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1; + }; + Buffer2.prototype.indexOf = function indexOf(val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true); + }; + Buffer2.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false); + }; + function hexWrite(buf, string, offset, length) { + offset = Number(offset) || 0; + const remaining = buf.length - offset; + if (!length) { + length = remaining; + } else { + length = Number(length); + if (length > remaining) { + length = remaining; + } + } + const strLen = string.length; + if (length > strLen / 2) { + length = strLen / 2; + } + let i; + for (i = 0; i < length; ++i) { + const parsed = parseInt(string.substr(i * 2, 2), 16); + if (numberIsNaN(parsed)) + return i; + buf[offset + i] = parsed; + } + return i; + } + function utf8Write(buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length); + } + function asciiWrite(buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length); + } + function base64Write(buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length); + } + function ucs2Write(buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length); + } + Buffer2.prototype.write = function write(string, offset, length, encoding) { + if (offset === void 0) { + encoding = "utf8"; + length = this.length; + offset = 0; + } else if (length === void 0 && typeof offset === "string") { + encoding = offset; + length = this.length; + offset = 0; + } else if (isFinite(offset)) { + offset = offset >>> 0; + if (isFinite(length)) { + length = length >>> 0; + if (encoding === void 0) + encoding = "utf8"; + } else { + encoding = length; + length = void 0; + } + } else { + throw new Error( + "Buffer.write(string, encoding, offset[, length]) is no longer supported" + ); + } + const remaining = this.length - offset; + if (length === void 0 || length > remaining) + length = remaining; + if (string.length > 0 && (length < 0 || offset < 0) || offset > this.length) { + throw new RangeError("Attempt to write outside buffer bounds"); + } + if (!encoding) + encoding = "utf8"; + let loweredCase = false; + for (; ; ) { + switch (encoding) { + case "hex": + return hexWrite(this, string, offset, length); + case "utf8": + case "utf-8": + return utf8Write(this, string, offset, length); + case "ascii": + case "latin1": + case "binary": + return asciiWrite(this, string, offset, length); + case "base64": + return base64Write(this, string, offset, length); + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return ucs2Write(this, string, offset, length); + default: + if (loweredCase) + throw new TypeError("Unknown encoding: " + encoding); + encoding = ("" + encoding).toLowerCase(); + loweredCase = true; + } + } + }; + Buffer2.prototype.toJSON = function toJSON() { + return { + type: "Buffer", + data: Array.prototype.slice.call(this._arr || this, 0) + }; + }; + function base64Slice(buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf); + } else { + return base64.fromByteArray(buf.slice(start, end)); + } + } + function utf8Slice(buf, start, end) { + end = Math.min(buf.length, end); + const res = []; + let i = start; + while (i < end) { + const firstByte = buf[i]; + let codePoint = null; + let bytesPerSequence = firstByte > 239 ? 4 : firstByte > 223 ? 3 : firstByte > 191 ? 2 : 1; + if (i + bytesPerSequence <= end) { + let secondByte, thirdByte, fourthByte, tempCodePoint; + switch (bytesPerSequence) { + case 1: + if (firstByte < 128) { + codePoint = firstByte; + } + break; + case 2: + secondByte = buf[i + 1]; + if ((secondByte & 192) === 128) { + tempCodePoint = (firstByte & 31) << 6 | secondByte & 63; + if (tempCodePoint > 127) { + codePoint = tempCodePoint; + } + } + break; + case 3: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + if ((secondByte & 192) === 128 && (thirdByte & 192) === 128) { + tempCodePoint = (firstByte & 15) << 12 | (secondByte & 63) << 6 | thirdByte & 63; + if (tempCodePoint > 2047 && (tempCodePoint < 55296 || tempCodePoint > 57343)) { + codePoint = tempCodePoint; + } + } + break; + case 4: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + fourthByte = buf[i + 3]; + if ((secondByte & 192) === 128 && (thirdByte & 192) === 128 && (fourthByte & 192) === 128) { + tempCodePoint = (firstByte & 15) << 18 | (secondByte & 63) << 12 | (thirdByte & 63) << 6 | fourthByte & 63; + if (tempCodePoint > 65535 && tempCodePoint < 1114112) { + codePoint = tempCodePoint; + } + } + } + } + if (codePoint === null) { + codePoint = 65533; + bytesPerSequence = 1; + } else if (codePoint > 65535) { + codePoint -= 65536; + res.push(codePoint >>> 10 & 1023 | 55296); + codePoint = 56320 | codePoint & 1023; + } + res.push(codePoint); + i += bytesPerSequence; + } + return decodeCodePointsArray(res); + } + var MAX_ARGUMENTS_LENGTH = 4096; + function decodeCodePointsArray(codePoints) { + const len = codePoints.length; + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints); + } + let res = ""; + let i = 0; + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ); + } + return res; + } + function asciiSlice(buf, start, end) { + let ret = ""; + end = Math.min(buf.length, end); + for (let i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 127); + } + return ret; + } + function latin1Slice(buf, start, end) { + let ret = ""; + end = Math.min(buf.length, end); + for (let i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]); + } + return ret; + } + function hexSlice(buf, start, end) { + const len = buf.length; + if (!start || start < 0) + start = 0; + if (!end || end < 0 || end > len) + end = len; + let out = ""; + for (let i = start; i < end; ++i) { + out += hexSliceLookupTable[buf[i]]; + } + return out; + } + function utf16leSlice(buf, start, end) { + const bytes = buf.slice(start, end); + let res = ""; + for (let i = 0; i < bytes.length - 1; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256); + } + return res; + } + Buffer2.prototype.slice = function slice(start, end) { + const len = this.length; + start = ~~start; + end = end === void 0 ? len : ~~end; + if (start < 0) { + start += len; + if (start < 0) + start = 0; + } else if (start > len) { + start = len; + } + if (end < 0) { + end += len; + if (end < 0) + end = 0; + } else if (end > len) { + end = len; + } + if (end < start) + end = start; + const newBuf = this.subarray(start, end); + Object.setPrototypeOf(newBuf, Buffer2.prototype); + return newBuf; + }; + function checkOffset(offset, ext, length) { + if (offset % 1 !== 0 || offset < 0) + throw new RangeError("offset is not uint"); + if (offset + ext > length) + throw new RangeError("Trying to access beyond buffer length"); + } + Buffer2.prototype.readUintLE = Buffer2.prototype.readUIntLE = function readUIntLE(offset, byteLength2, noAssert) { + offset = offset >>> 0; + byteLength2 = byteLength2 >>> 0; + if (!noAssert) + checkOffset(offset, byteLength2, this.length); + let val = this[offset]; + let mul = 1; + let i = 0; + while (++i < byteLength2 && (mul *= 256)) { + val += this[offset + i] * mul; + } + return val; + }; + Buffer2.prototype.readUintBE = Buffer2.prototype.readUIntBE = function readUIntBE(offset, byteLength2, noAssert) { + offset = offset >>> 0; + byteLength2 = byteLength2 >>> 0; + if (!noAssert) { + checkOffset(offset, byteLength2, this.length); + } + let val = this[offset + --byteLength2]; + let mul = 1; + while (byteLength2 > 0 && (mul *= 256)) { + val += this[offset + --byteLength2] * mul; + } + return val; + }; + Buffer2.prototype.readUint8 = Buffer2.prototype.readUInt8 = function readUInt8(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 1, this.length); + return this[offset]; + }; + Buffer2.prototype.readUint16LE = Buffer2.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 2, this.length); + return this[offset] | this[offset + 1] << 8; + }; + Buffer2.prototype.readUint16BE = Buffer2.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 2, this.length); + return this[offset] << 8 | this[offset + 1]; + }; + Buffer2.prototype.readUint32LE = Buffer2.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 4, this.length); + return (this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16) + this[offset + 3] * 16777216; + }; + Buffer2.prototype.readUint32BE = Buffer2.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 4, this.length); + return this[offset] * 16777216 + (this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3]); + }; + Buffer2.prototype.readBigUInt64LE = defineBigIntMethod(function readBigUInt64LE(offset) { + offset = offset >>> 0; + validateNumber(offset, "offset"); + const first2 = this[offset]; + const last2 = this[offset + 7]; + if (first2 === void 0 || last2 === void 0) { + boundsError(offset, this.length - 8); + } + const lo = first2 + this[++offset] * 2 ** 8 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 24; + const hi = this[++offset] + this[++offset] * 2 ** 8 + this[++offset] * 2 ** 16 + last2 * 2 ** 24; + return BigInt(lo) + (BigInt(hi) << BigInt(32)); + }); + Buffer2.prototype.readBigUInt64BE = defineBigIntMethod(function readBigUInt64BE(offset) { + offset = offset >>> 0; + validateNumber(offset, "offset"); + const first2 = this[offset]; + const last2 = this[offset + 7]; + if (first2 === void 0 || last2 === void 0) { + boundsError(offset, this.length - 8); + } + const hi = first2 * 2 ** 24 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + this[++offset]; + const lo = this[++offset] * 2 ** 24 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + last2; + return (BigInt(hi) << BigInt(32)) + BigInt(lo); + }); + Buffer2.prototype.readIntLE = function readIntLE(offset, byteLength2, noAssert) { + offset = offset >>> 0; + byteLength2 = byteLength2 >>> 0; + if (!noAssert) + checkOffset(offset, byteLength2, this.length); + let val = this[offset]; + let mul = 1; + let i = 0; + while (++i < byteLength2 && (mul *= 256)) { + val += this[offset + i] * mul; + } + mul *= 128; + if (val >= mul) + val -= Math.pow(2, 8 * byteLength2); + return val; + }; + Buffer2.prototype.readIntBE = function readIntBE(offset, byteLength2, noAssert) { + offset = offset >>> 0; + byteLength2 = byteLength2 >>> 0; + if (!noAssert) + checkOffset(offset, byteLength2, this.length); + let i = byteLength2; + let mul = 1; + let val = this[offset + --i]; + while (i > 0 && (mul *= 256)) { + val += this[offset + --i] * mul; + } + mul *= 128; + if (val >= mul) + val -= Math.pow(2, 8 * byteLength2); + return val; + }; + Buffer2.prototype.readInt8 = function readInt8(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 1, this.length); + if (!(this[offset] & 128)) + return this[offset]; + return (255 - this[offset] + 1) * -1; + }; + Buffer2.prototype.readInt16LE = function readInt16LE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 2, this.length); + const val = this[offset] | this[offset + 1] << 8; + return val & 32768 ? val | 4294901760 : val; + }; + Buffer2.prototype.readInt16BE = function readInt16BE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 2, this.length); + const val = this[offset + 1] | this[offset] << 8; + return val & 32768 ? val | 4294901760 : val; + }; + Buffer2.prototype.readInt32LE = function readInt32LE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 4, this.length); + return this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16 | this[offset + 3] << 24; + }; + Buffer2.prototype.readInt32BE = function readInt32BE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 4, this.length); + return this[offset] << 24 | this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3]; + }; + Buffer2.prototype.readBigInt64LE = defineBigIntMethod(function readBigInt64LE(offset) { + offset = offset >>> 0; + validateNumber(offset, "offset"); + const first2 = this[offset]; + const last2 = this[offset + 7]; + if (first2 === void 0 || last2 === void 0) { + boundsError(offset, this.length - 8); + } + const val = this[offset + 4] + this[offset + 5] * 2 ** 8 + this[offset + 6] * 2 ** 16 + (last2 << 24); + return (BigInt(val) << BigInt(32)) + BigInt(first2 + this[++offset] * 2 ** 8 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 24); + }); + Buffer2.prototype.readBigInt64BE = defineBigIntMethod(function readBigInt64BE(offset) { + offset = offset >>> 0; + validateNumber(offset, "offset"); + const first2 = this[offset]; + const last2 = this[offset + 7]; + if (first2 === void 0 || last2 === void 0) { + boundsError(offset, this.length - 8); + } + const val = (first2 << 24) + // Overflow + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + this[++offset]; + return (BigInt(val) << BigInt(32)) + BigInt(this[++offset] * 2 ** 24 + this[++offset] * 2 ** 16 + this[++offset] * 2 ** 8 + last2); + }); + Buffer2.prototype.readFloatLE = function readFloatLE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 4, this.length); + return ieee754.read(this, offset, true, 23, 4); + }; + Buffer2.prototype.readFloatBE = function readFloatBE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 4, this.length); + return ieee754.read(this, offset, false, 23, 4); + }; + Buffer2.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 8, this.length); + return ieee754.read(this, offset, true, 52, 8); + }; + Buffer2.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 8, this.length); + return ieee754.read(this, offset, false, 52, 8); + }; + function checkInt(buf, value, offset, ext, max, min) { + if (!Buffer2.isBuffer(buf)) + throw new TypeError('"buffer" argument must be a Buffer instance'); + if (value > max || value < min) + throw new RangeError('"value" argument is out of bounds'); + if (offset + ext > buf.length) + throw new RangeError("Index out of range"); + } + Buffer2.prototype.writeUintLE = Buffer2.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength2, noAssert) { + value = +value; + offset = offset >>> 0; + byteLength2 = byteLength2 >>> 0; + if (!noAssert) { + const maxBytes = Math.pow(2, 8 * byteLength2) - 1; + checkInt(this, value, offset, byteLength2, maxBytes, 0); + } + let mul = 1; + let i = 0; + this[offset] = value & 255; + while (++i < byteLength2 && (mul *= 256)) { + this[offset + i] = value / mul & 255; + } + return offset + byteLength2; + }; + Buffer2.prototype.writeUintBE = Buffer2.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength2, noAssert) { + value = +value; + offset = offset >>> 0; + byteLength2 = byteLength2 >>> 0; + if (!noAssert) { + const maxBytes = Math.pow(2, 8 * byteLength2) - 1; + checkInt(this, value, offset, byteLength2, maxBytes, 0); + } + let i = byteLength2 - 1; + let mul = 1; + this[offset + i] = value & 255; + while (--i >= 0 && (mul *= 256)) { + this[offset + i] = value / mul & 255; + } + return offset + byteLength2; + }; + Buffer2.prototype.writeUint8 = Buffer2.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 1, 255, 0); + this[offset] = value & 255; + return offset + 1; + }; + Buffer2.prototype.writeUint16LE = Buffer2.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 2, 65535, 0); + this[offset] = value & 255; + this[offset + 1] = value >>> 8; + return offset + 2; + }; + Buffer2.prototype.writeUint16BE = Buffer2.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 2, 65535, 0); + this[offset] = value >>> 8; + this[offset + 1] = value & 255; + return offset + 2; + }; + Buffer2.prototype.writeUint32LE = Buffer2.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 4, 4294967295, 0); + this[offset + 3] = value >>> 24; + this[offset + 2] = value >>> 16; + this[offset + 1] = value >>> 8; + this[offset] = value & 255; + return offset + 4; + }; + Buffer2.prototype.writeUint32BE = Buffer2.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 4, 4294967295, 0); + this[offset] = value >>> 24; + this[offset + 1] = value >>> 16; + this[offset + 2] = value >>> 8; + this[offset + 3] = value & 255; + return offset + 4; + }; + function wrtBigUInt64LE(buf, value, offset, min, max) { + checkIntBI(value, min, max, buf, offset, 7); + let lo = Number(value & BigInt(4294967295)); + buf[offset++] = lo; + lo = lo >> 8; + buf[offset++] = lo; + lo = lo >> 8; + buf[offset++] = lo; + lo = lo >> 8; + buf[offset++] = lo; + let hi = Number(value >> BigInt(32) & BigInt(4294967295)); + buf[offset++] = hi; + hi = hi >> 8; + buf[offset++] = hi; + hi = hi >> 8; + buf[offset++] = hi; + hi = hi >> 8; + buf[offset++] = hi; + return offset; + } + function wrtBigUInt64BE(buf, value, offset, min, max) { + checkIntBI(value, min, max, buf, offset, 7); + let lo = Number(value & BigInt(4294967295)); + buf[offset + 7] = lo; + lo = lo >> 8; + buf[offset + 6] = lo; + lo = lo >> 8; + buf[offset + 5] = lo; + lo = lo >> 8; + buf[offset + 4] = lo; + let hi = Number(value >> BigInt(32) & BigInt(4294967295)); + buf[offset + 3] = hi; + hi = hi >> 8; + buf[offset + 2] = hi; + hi = hi >> 8; + buf[offset + 1] = hi; + hi = hi >> 8; + buf[offset] = hi; + return offset + 8; + } + Buffer2.prototype.writeBigUInt64LE = defineBigIntMethod(function writeBigUInt64LE(value, offset = 0) { + return wrtBigUInt64LE(this, value, offset, BigInt(0), BigInt("0xffffffffffffffff")); + }); + Buffer2.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE(value, offset = 0) { + return wrtBigUInt64BE(this, value, offset, BigInt(0), BigInt("0xffffffffffffffff")); + }); + Buffer2.prototype.writeIntLE = function writeIntLE(value, offset, byteLength2, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) { + const limit = Math.pow(2, 8 * byteLength2 - 1); + checkInt(this, value, offset, byteLength2, limit - 1, -limit); + } + let i = 0; + let mul = 1; + let sub = 0; + this[offset] = value & 255; + while (++i < byteLength2 && (mul *= 256)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1; + } + this[offset + i] = (value / mul >> 0) - sub & 255; + } + return offset + byteLength2; + }; + Buffer2.prototype.writeIntBE = function writeIntBE(value, offset, byteLength2, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) { + const limit = Math.pow(2, 8 * byteLength2 - 1); + checkInt(this, value, offset, byteLength2, limit - 1, -limit); + } + let i = byteLength2 - 1; + let mul = 1; + let sub = 0; + this[offset + i] = value & 255; + while (--i >= 0 && (mul *= 256)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1; + } + this[offset + i] = (value / mul >> 0) - sub & 255; + } + return offset + byteLength2; + }; + Buffer2.prototype.writeInt8 = function writeInt8(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 1, 127, -128); + if (value < 0) + value = 255 + value + 1; + this[offset] = value & 255; + return offset + 1; + }; + Buffer2.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 2, 32767, -32768); + this[offset] = value & 255; + this[offset + 1] = value >>> 8; + return offset + 2; + }; + Buffer2.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 2, 32767, -32768); + this[offset] = value >>> 8; + this[offset + 1] = value & 255; + return offset + 2; + }; + Buffer2.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 4, 2147483647, -2147483648); + this[offset] = value & 255; + this[offset + 1] = value >>> 8; + this[offset + 2] = value >>> 16; + this[offset + 3] = value >>> 24; + return offset + 4; + }; + Buffer2.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) + checkInt(this, value, offset, 4, 2147483647, -2147483648); + if (value < 0) + value = 4294967295 + value + 1; + this[offset] = value >>> 24; + this[offset + 1] = value >>> 16; + this[offset + 2] = value >>> 8; + this[offset + 3] = value & 255; + return offset + 4; + }; + Buffer2.prototype.writeBigInt64LE = defineBigIntMethod(function writeBigInt64LE(value, offset = 0) { + return wrtBigUInt64LE(this, value, offset, -BigInt("0x8000000000000000"), BigInt("0x7fffffffffffffff")); + }); + Buffer2.prototype.writeBigInt64BE = defineBigIntMethod(function writeBigInt64BE(value, offset = 0) { + return wrtBigUInt64BE(this, value, offset, -BigInt("0x8000000000000000"), BigInt("0x7fffffffffffffff")); + }); + function checkIEEE754(buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) + throw new RangeError("Index out of range"); + if (offset < 0) + throw new RangeError("Index out of range"); + } + function writeFloat(buf, value, offset, littleEndian, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 34028234663852886e22, -34028234663852886e22); + } + ieee754.write(buf, value, offset, littleEndian, 23, 4); + return offset + 4; + } + Buffer2.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert); + }; + Buffer2.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert); + }; + function writeDouble(buf, value, offset, littleEndian, noAssert) { + value = +value; + offset = offset >>> 0; + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 17976931348623157e292, -17976931348623157e292); + } + ieee754.write(buf, value, offset, littleEndian, 52, 8); + return offset + 8; + } + Buffer2.prototype.writeDoubleLE = function writeDoubleLE(value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert); + }; + Buffer2.prototype.writeDoubleBE = function writeDoubleBE(value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert); + }; + Buffer2.prototype.copy = function copy2(target, targetStart, start, end) { + if (!Buffer2.isBuffer(target)) + throw new TypeError("argument should be a Buffer"); + if (!start) + start = 0; + if (!end && end !== 0) + end = this.length; + if (targetStart >= target.length) + targetStart = target.length; + if (!targetStart) + targetStart = 0; + if (end > 0 && end < start) + end = start; + if (end === start) + return 0; + if (target.length === 0 || this.length === 0) + return 0; + if (targetStart < 0) { + throw new RangeError("targetStart out of bounds"); + } + if (start < 0 || start >= this.length) + throw new RangeError("Index out of range"); + if (end < 0) + throw new RangeError("sourceEnd out of bounds"); + if (end > this.length) + end = this.length; + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start; + } + const len = end - start; + if (this === target && typeof Uint8Array.prototype.copyWithin === "function") { + this.copyWithin(targetStart, start, end); + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, end), + targetStart + ); + } + return len; + }; + Buffer2.prototype.fill = function fill(val, start, end, encoding) { + if (typeof val === "string") { + if (typeof start === "string") { + encoding = start; + start = 0; + end = this.length; + } else if (typeof end === "string") { + encoding = end; + end = this.length; + } + if (encoding !== void 0 && typeof encoding !== "string") { + throw new TypeError("encoding must be a string"); + } + if (typeof encoding === "string" && !Buffer2.isEncoding(encoding)) { + throw new TypeError("Unknown encoding: " + encoding); + } + if (val.length === 1) { + const code = val.charCodeAt(0); + if (encoding === "utf8" && code < 128 || encoding === "latin1") { + val = code; + } + } + } else if (typeof val === "number") { + val = val & 255; + } else if (typeof val === "boolean") { + val = Number(val); + } + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError("Out of range index"); + } + if (end <= start) { + return this; + } + start = start >>> 0; + end = end === void 0 ? this.length : end >>> 0; + if (!val) + val = 0; + let i; + if (typeof val === "number") { + for (i = start; i < end; ++i) { + this[i] = val; + } + } else { + const bytes = Buffer2.isBuffer(val) ? val : Buffer2.from(val, encoding); + const len = bytes.length; + if (len === 0) { + throw new TypeError('The value "' + val + '" is invalid for argument "value"'); + } + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len]; + } + } + return this; + }; + var errors = {}; + function E(sym, getMessage, Base) { + errors[sym] = class NodeError extends Base { + constructor() { + super(); + Object.defineProperty(this, "message", { + value: getMessage.apply(this, arguments), + writable: true, + configurable: true + }); + this.name = `${this.name} [${sym}]`; + this.stack; + delete this.name; + } + get code() { + return sym; + } + set code(value) { + Object.defineProperty(this, "code", { + configurable: true, + enumerable: true, + value, + writable: true + }); + } + toString() { + return `${this.name} [${sym}]: ${this.message}`; + } + }; + } + E( + "ERR_BUFFER_OUT_OF_BOUNDS", + function(name) { + if (name) { + return `${name} is outside of buffer bounds`; + } + return "Attempt to access memory outside buffer bounds"; + }, + RangeError + ); + E( + "ERR_INVALID_ARG_TYPE", + function(name, actual) { + return `The "${name}" argument must be of type number. Received type ${typeof actual}`; + }, + TypeError + ); + E( + "ERR_OUT_OF_RANGE", + function(str, range, input) { + let msg = `The value of "${str}" is out of range.`; + let received = input; + if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) { + received = addNumericalSeparator(String(input)); + } else if (typeof input === "bigint") { + received = String(input); + if (input > BigInt(2) ** BigInt(32) || input < -(BigInt(2) ** BigInt(32))) { + received = addNumericalSeparator(received); + } + received += "n"; + } + msg += ` It must be ${range}. Received ${received}`; + return msg; + }, + RangeError + ); + function addNumericalSeparator(val) { + let res = ""; + let i = val.length; + const start = val[0] === "-" ? 1 : 0; + for (; i >= start + 4; i -= 3) { + res = `_${val.slice(i - 3, i)}${res}`; + } + return `${val.slice(0, i)}${res}`; + } + function checkBounds(buf, offset, byteLength2) { + validateNumber(offset, "offset"); + if (buf[offset] === void 0 || buf[offset + byteLength2] === void 0) { + boundsError(offset, buf.length - (byteLength2 + 1)); + } + } + function checkIntBI(value, min, max, buf, offset, byteLength2) { + if (value > max || value < min) { + const n = typeof min === "bigint" ? "n" : ""; + let range; + if (byteLength2 > 3) { + if (min === 0 || min === BigInt(0)) { + range = `>= 0${n} and < 2${n} ** ${(byteLength2 + 1) * 8}${n}`; + } else { + range = `>= -(2${n} ** ${(byteLength2 + 1) * 8 - 1}${n}) and < 2 ** ${(byteLength2 + 1) * 8 - 1}${n}`; + } + } else { + range = `>= ${min}${n} and <= ${max}${n}`; + } + throw new errors.ERR_OUT_OF_RANGE("value", range, value); + } + checkBounds(buf, offset, byteLength2); + } + function validateNumber(value, name) { + if (typeof value !== "number") { + throw new errors.ERR_INVALID_ARG_TYPE(name, "number", value); + } + } + function boundsError(value, length, type) { + if (Math.floor(value) !== value) { + validateNumber(value, type); + throw new errors.ERR_OUT_OF_RANGE(type || "offset", "an integer", value); + } + if (length < 0) { + throw new errors.ERR_BUFFER_OUT_OF_BOUNDS(); + } + throw new errors.ERR_OUT_OF_RANGE( + type || "offset", + `>= ${type ? 1 : 0} and <= ${length}`, + value + ); + } + var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g; + function base64clean(str) { + str = str.split("=")[0]; + str = str.trim().replace(INVALID_BASE64_RE, ""); + if (str.length < 2) + return ""; + while (str.length % 4 !== 0) { + str = str + "="; + } + return str; + } + function utf8ToBytes(string, units) { + units = units || Infinity; + let codePoint; + const length = string.length; + let leadSurrogate = null; + const bytes = []; + for (let i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i); + if (codePoint > 55295 && codePoint < 57344) { + if (!leadSurrogate) { + if (codePoint > 56319) { + if ((units -= 3) > -1) + bytes.push(239, 191, 189); + continue; + } else if (i + 1 === length) { + if ((units -= 3) > -1) + bytes.push(239, 191, 189); + continue; + } + leadSurrogate = codePoint; + continue; + } + if (codePoint < 56320) { + if ((units -= 3) > -1) + bytes.push(239, 191, 189); + leadSurrogate = codePoint; + continue; + } + codePoint = (leadSurrogate - 55296 << 10 | codePoint - 56320) + 65536; + } else if (leadSurrogate) { + if ((units -= 3) > -1) + bytes.push(239, 191, 189); + } + leadSurrogate = null; + if (codePoint < 128) { + if ((units -= 1) < 0) + break; + bytes.push(codePoint); + } else if (codePoint < 2048) { + if ((units -= 2) < 0) + break; + bytes.push( + codePoint >> 6 | 192, + codePoint & 63 | 128 + ); + } else if (codePoint < 65536) { + if ((units -= 3) < 0) + break; + bytes.push( + codePoint >> 12 | 224, + codePoint >> 6 & 63 | 128, + codePoint & 63 | 128 + ); + } else if (codePoint < 1114112) { + if ((units -= 4) < 0) + break; + bytes.push( + codePoint >> 18 | 240, + codePoint >> 12 & 63 | 128, + codePoint >> 6 & 63 | 128, + codePoint & 63 | 128 + ); + } else { + throw new Error("Invalid code point"); + } + } + return bytes; + } + function asciiToBytes(str) { + const byteArray = []; + for (let i = 0; i < str.length; ++i) { + byteArray.push(str.charCodeAt(i) & 255); + } + return byteArray; + } + function utf16leToBytes(str, units) { + let c, hi, lo; + const byteArray = []; + for (let i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) + break; + c = str.charCodeAt(i); + hi = c >> 8; + lo = c % 256; + byteArray.push(lo); + byteArray.push(hi); + } + return byteArray; + } + function base64ToBytes(str) { + return base64.toByteArray(base64clean(str)); + } + function blitBuffer(src, dst, offset, length) { + let i; + for (i = 0; i < length; ++i) { + if (i + offset >= dst.length || i >= src.length) + break; + dst[i + offset] = src[i]; + } + return i; + } + function isInstance(obj, type) { + return obj instanceof type || obj != null && obj.constructor != null && obj.constructor.name != null && obj.constructor.name === type.name; + } + function numberIsNaN(obj) { + return obj !== obj; + } + var hexSliceLookupTable = function() { + const alphabet = "0123456789abcdef"; + const table = new Array(256); + for (let i = 0; i < 16; ++i) { + const i16 = i * 16; + for (let j = 0; j < 16; ++j) { + table[i16 + j] = alphabet[i] + alphabet[j]; + } + } + return table; + }(); + function defineBigIntMethod(fn) { + return typeof BigInt === "undefined" ? BufferBigIntNotDefined : fn; + } + function BufferBigIntNotDefined() { + throw new Error("BigInt not supported"); + } + } +}); + +// polyfill_buffer.js +var import_obsidian, buffer, Buffer; +var init_polyfill_buffer = __esm({ + "polyfill_buffer.js"() { + import_obsidian = require("obsidian"); + if (import_obsidian.Platform.isMobileApp) { + buffer = require_buffer().Buffer; + } else { + buffer = global.Buffer; + } + Buffer = buffer; + } +}); + +// node_modules/.pnpm/async-lock@1.4.0/node_modules/async-lock/lib/index.js +var require_lib = __commonJS({ + "node_modules/.pnpm/async-lock@1.4.0/node_modules/async-lock/lib/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var AsyncLock2 = function(opts) { + opts = opts || {}; + this.Promise = opts.Promise || Promise; + this.queues = /* @__PURE__ */ Object.create(null); + this.domainReentrant = opts.domainReentrant || false; + if (this.domainReentrant) { + if (typeof process === "undefined" || typeof process.domain === "undefined") { + throw new Error( + "Domain-reentrant locks require `process.domain` to exist. Please flip `opts.domainReentrant = false`, use a NodeJS version that still implements Domain, or install a browser polyfill." + ); + } + this.domains = /* @__PURE__ */ Object.create(null); + } + this.timeout = opts.timeout || AsyncLock2.DEFAULT_TIMEOUT; + this.maxOccupationTime = opts.maxOccupationTime || AsyncLock2.DEFAULT_MAX_OCCUPATION_TIME; + this.maxExecutionTime = opts.maxExecutionTime || AsyncLock2.DEFAULT_MAX_EXECUTION_TIME; + if (opts.maxPending === Infinity || Number.isInteger(opts.maxPending) && opts.maxPending >= 0) { + this.maxPending = opts.maxPending; + } else { + this.maxPending = AsyncLock2.DEFAULT_MAX_PENDING; + } + }; + AsyncLock2.DEFAULT_TIMEOUT = 0; + AsyncLock2.DEFAULT_MAX_OCCUPATION_TIME = 0; + AsyncLock2.DEFAULT_MAX_EXECUTION_TIME = 0; + AsyncLock2.DEFAULT_MAX_PENDING = 1e3; + AsyncLock2.prototype.acquire = function(key2, fn, cb, opts) { + if (Array.isArray(key2)) { + return this._acquireBatch(key2, fn, cb, opts); + } + if (typeof fn !== "function") { + throw new Error("You must pass a function to execute"); + } + var deferredResolve = null; + var deferredReject = null; + var deferred2 = null; + if (typeof cb !== "function") { + opts = cb; + cb = null; + deferred2 = new this.Promise(function(resolve, reject) { + deferredResolve = resolve; + deferredReject = reject; + }); + } + opts = opts || {}; + var resolved = false; + var timer = null; + var occupationTimer = null; + var executionTimer = null; + var self2 = this; + var done = function(locked, err, ret) { + if (occupationTimer) { + clearTimeout(occupationTimer); + occupationTimer = null; + } + if (executionTimer) { + clearTimeout(executionTimer); + executionTimer = null; + } + if (locked) { + if (!!self2.queues[key2] && self2.queues[key2].length === 0) { + delete self2.queues[key2]; + } + if (self2.domainReentrant) { + delete self2.domains[key2]; + } + } + if (!resolved) { + if (!deferred2) { + if (typeof cb === "function") { + cb(err, ret); + } + } else { + if (err) { + deferredReject(err); + } else { + deferredResolve(ret); + } + } + resolved = true; + } + if (locked) { + if (!!self2.queues[key2] && self2.queues[key2].length > 0) { + self2.queues[key2].shift()(); + } + } + }; + var exec = function(locked) { + if (resolved) { + return done(locked); + } + if (timer) { + clearTimeout(timer); + timer = null; + } + if (self2.domainReentrant && locked) { + self2.domains[key2] = process.domain; + } + var maxExecutionTime = opts.maxExecutionTime || self2.maxExecutionTime; + if (maxExecutionTime) { + executionTimer = setTimeout(function() { + if (!!self2.queues[key2]) { + done(locked, new Error("Maximum execution time is exceeded " + key2)); + } + }, maxExecutionTime); + } + if (fn.length === 1) { + var called = false; + try { + fn(function(err, ret) { + if (!called) { + called = true; + done(locked, err, ret); + } + }); + } catch (err) { + if (!called) { + called = true; + done(locked, err); + } + } + } else { + self2._promiseTry(function() { + return fn(); + }).then(function(ret) { + done(locked, void 0, ret); + }, function(error) { + done(locked, error); + }); + } + }; + if (self2.domainReentrant && !!process.domain) { + exec = process.domain.bind(exec); + } + if (!self2.queues[key2]) { + self2.queues[key2] = []; + exec(true); + } else if (self2.domainReentrant && !!process.domain && process.domain === self2.domains[key2]) { + exec(false); + } else if (self2.queues[key2].length >= self2.maxPending) { + done(false, new Error("Too many pending tasks in queue " + key2)); + } else { + var taskFn = function() { + exec(true); + }; + if (opts.skipQueue) { + self2.queues[key2].unshift(taskFn); + } else { + self2.queues[key2].push(taskFn); + } + var timeout = opts.timeout || self2.timeout; + if (timeout) { + timer = setTimeout(function() { + timer = null; + done(false, new Error("async-lock timed out in queue " + key2)); + }, timeout); + } + } + var maxOccupationTime = opts.maxOccupationTime || self2.maxOccupationTime; + if (maxOccupationTime) { + occupationTimer = setTimeout(function() { + if (!!self2.queues[key2]) { + done(false, new Error("Maximum occupation time is exceeded in queue " + key2)); + } + }, maxOccupationTime); + } + if (deferred2) { + return deferred2; + } + }; + AsyncLock2.prototype._acquireBatch = function(keys, fn, cb, opts) { + if (typeof cb !== "function") { + opts = cb; + cb = null; + } + var self2 = this; + var getFn = function(key2, fn2) { + return function(cb2) { + self2.acquire(key2, fn2, cb2, opts); + }; + }; + var fnx = keys.reduceRight(function(prev, key2) { + return getFn(key2, prev); + }, fn); + if (typeof cb === "function") { + fnx(cb); + } else { + return new this.Promise(function(resolve, reject) { + if (fnx.length === 1) { + fnx(function(err, ret) { + if (err) { + reject(err); + } else { + resolve(ret); + } + }); + } else { + resolve(fnx()); + } + }); + } + }; + AsyncLock2.prototype.isBusy = function(key2) { + if (!key2) { + return Object.keys(this.queues).length > 0; + } else { + return !!this.queues[key2]; + } + }; + AsyncLock2.prototype._promiseTry = function(fn) { + try { + return this.Promise.resolve(fn()); + } catch (e) { + return this.Promise.reject(e); + } + }; + module2.exports = AsyncLock2; + } +}); + +// node_modules/.pnpm/async-lock@1.4.0/node_modules/async-lock/index.js +var require_async_lock = __commonJS({ + "node_modules/.pnpm/async-lock@1.4.0/node_modules/async-lock/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + module2.exports = require_lib(); + } +}); + +// node_modules/.pnpm/inherits@2.0.4/node_modules/inherits/inherits_browser.js +var require_inherits_browser = __commonJS({ + "node_modules/.pnpm/inherits@2.0.4/node_modules/inherits/inherits_browser.js"(exports2, module2) { + init_polyfill_buffer(); + if (typeof Object.create === "function") { + module2.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + } + }; + } else { + module2.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + var TempCtor = function() { + }; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + } + }; + } + } +}); + +// node_modules/.pnpm/safe-buffer@5.2.1/node_modules/safe-buffer/index.js +var require_safe_buffer = __commonJS({ + "node_modules/.pnpm/safe-buffer@5.2.1/node_modules/safe-buffer/index.js"(exports2, module2) { + init_polyfill_buffer(); + var buffer2 = require_buffer(); + var Buffer2 = buffer2.Buffer; + function copyProps(src, dst) { + for (var key2 in src) { + dst[key2] = src[key2]; + } + } + if (Buffer2.from && Buffer2.alloc && Buffer2.allocUnsafe && Buffer2.allocUnsafeSlow) { + module2.exports = buffer2; + } else { + copyProps(buffer2, exports2); + exports2.Buffer = SafeBuffer; + } + function SafeBuffer(arg, encodingOrOffset, length) { + return Buffer2(arg, encodingOrOffset, length); + } + SafeBuffer.prototype = Object.create(Buffer2.prototype); + copyProps(Buffer2, SafeBuffer); + SafeBuffer.from = function(arg, encodingOrOffset, length) { + if (typeof arg === "number") { + throw new TypeError("Argument must not be a number"); + } + return Buffer2(arg, encodingOrOffset, length); + }; + SafeBuffer.alloc = function(size, fill, encoding) { + if (typeof size !== "number") { + throw new TypeError("Argument must be a number"); + } + var buf = Buffer2(size); + if (fill !== void 0) { + if (typeof encoding === "string") { + buf.fill(fill, encoding); + } else { + buf.fill(fill); + } + } else { + buf.fill(0); + } + return buf; + }; + SafeBuffer.allocUnsafe = function(size) { + if (typeof size !== "number") { + throw new TypeError("Argument must be a number"); + } + return Buffer2(size); + }; + SafeBuffer.allocUnsafeSlow = function(size) { + if (typeof size !== "number") { + throw new TypeError("Argument must be a number"); + } + return buffer2.SlowBuffer(size); + }; + } +}); + +// node_modules/.pnpm/sha.js@2.4.11/node_modules/sha.js/hash.js +var require_hash = __commonJS({ + "node_modules/.pnpm/sha.js@2.4.11/node_modules/sha.js/hash.js"(exports2, module2) { + init_polyfill_buffer(); + var Buffer2 = require_safe_buffer().Buffer; + function Hash2(blockSize, finalSize) { + this._block = Buffer2.alloc(blockSize); + this._finalSize = finalSize; + this._blockSize = blockSize; + this._len = 0; + } + Hash2.prototype.update = function(data, enc) { + if (typeof data === "string") { + enc = enc || "utf8"; + data = Buffer2.from(data, enc); + } + var block = this._block; + var blockSize = this._blockSize; + var length = data.length; + var accum = this._len; + for (var offset = 0; offset < length; ) { + var assigned = accum % blockSize; + var remainder = Math.min(length - offset, blockSize - assigned); + for (var i = 0; i < remainder; i++) { + block[assigned + i] = data[offset + i]; + } + accum += remainder; + offset += remainder; + if (accum % blockSize === 0) { + this._update(block); + } + } + this._len += length; + return this; + }; + Hash2.prototype.digest = function(enc) { + var rem = this._len % this._blockSize; + this._block[rem] = 128; + this._block.fill(0, rem + 1); + if (rem >= this._finalSize) { + this._update(this._block); + this._block.fill(0); + } + var bits = this._len * 8; + if (bits <= 4294967295) { + this._block.writeUInt32BE(bits, this._blockSize - 4); + } else { + var lowBits = (bits & 4294967295) >>> 0; + var highBits = (bits - lowBits) / 4294967296; + this._block.writeUInt32BE(highBits, this._blockSize - 8); + this._block.writeUInt32BE(lowBits, this._blockSize - 4); + } + this._update(this._block); + var hash2 = this._hash(); + return enc ? hash2.toString(enc) : hash2; + }; + Hash2.prototype._update = function() { + throw new Error("_update must be implemented by subclass"); + }; + module2.exports = Hash2; + } +}); + +// node_modules/.pnpm/sha.js@2.4.11/node_modules/sha.js/sha1.js +var require_sha1 = __commonJS({ + "node_modules/.pnpm/sha.js@2.4.11/node_modules/sha.js/sha1.js"(exports2, module2) { + init_polyfill_buffer(); + var inherits = require_inherits_browser(); + var Hash2 = require_hash(); + var Buffer2 = require_safe_buffer().Buffer; + var K2 = [ + 1518500249, + 1859775393, + 2400959708 | 0, + 3395469782 | 0 + ]; + var W = new Array(80); + function Sha1() { + this.init(); + this._w = W; + Hash2.call(this, 64, 56); + } + inherits(Sha1, Hash2); + Sha1.prototype.init = function() { + this._a = 1732584193; + this._b = 4023233417; + this._c = 2562383102; + this._d = 271733878; + this._e = 3285377520; + return this; + }; + function rotl1(num2) { + return num2 << 1 | num2 >>> 31; + } + function rotl5(num2) { + return num2 << 5 | num2 >>> 27; + } + function rotl30(num2) { + return num2 << 30 | num2 >>> 2; + } + function ft(s, b, c, d) { + if (s === 0) + return b & c | ~b & d; + if (s === 2) + return b & c | b & d | c & d; + return b ^ c ^ d; + } + Sha1.prototype._update = function(M) { + var W2 = this._w; + var a = this._a | 0; + var b = this._b | 0; + var c = this._c | 0; + var d = this._d | 0; + var e = this._e | 0; + for (var i = 0; i < 16; ++i) + W2[i] = M.readInt32BE(i * 4); + for (; i < 80; ++i) + W2[i] = rotl1(W2[i - 3] ^ W2[i - 8] ^ W2[i - 14] ^ W2[i - 16]); + for (var j = 0; j < 80; ++j) { + var s = ~~(j / 20); + var t = rotl5(a) + ft(s, b, c, d) + e + W2[j] + K2[s] | 0; + e = d; + d = c; + c = rotl30(b); + b = a; + a = t; + } + this._a = a + this._a | 0; + this._b = b + this._b | 0; + this._c = c + this._c | 0; + this._d = d + this._d | 0; + this._e = e + this._e | 0; + }; + Sha1.prototype._hash = function() { + var H = Buffer2.allocUnsafe(20); + H.writeInt32BE(this._a | 0, 0); + H.writeInt32BE(this._b | 0, 4); + H.writeInt32BE(this._c | 0, 8); + H.writeInt32BE(this._d | 0, 12); + H.writeInt32BE(this._e | 0, 16); + return H; + }; + module2.exports = Sha1; + } +}); + +// node_modules/.pnpm/crc-32@1.2.2/node_modules/crc-32/crc32.js +var require_crc32 = __commonJS({ + "node_modules/.pnpm/crc-32@1.2.2/node_modules/crc-32/crc32.js"(exports2) { + init_polyfill_buffer(); + var CRC32; + (function(factory) { + if (typeof DO_NOT_EXPORT_CRC === "undefined") { + if ("object" === typeof exports2) { + factory(exports2); + } else if ("function" === typeof define && define.amd) { + define(function() { + var module3 = {}; + factory(module3); + return module3; + }); + } else { + factory(CRC32 = {}); + } + } else { + factory(CRC32 = {}); + } + })(function(CRC322) { + CRC322.version = "1.2.2"; + function signed_crc_table() { + var c = 0, table = new Array(256); + for (var n = 0; n != 256; ++n) { + c = n; + c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1; + c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1; + c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1; + c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1; + c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1; + c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1; + c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1; + c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1; + table[n] = c; + } + return typeof Int32Array !== "undefined" ? new Int32Array(table) : table; + } + var T0 = signed_crc_table(); + function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table = typeof Int32Array !== "undefined" ? new Int32Array(4096) : new Array(4096); + for (n = 0; n != 256; ++n) + table[n] = T[n]; + for (n = 0; n != 256; ++n) { + v = T[n]; + for (c = 256 + n; c < 4096; c += 256) + v = table[c] = v >>> 8 ^ T[v & 255]; + } + var out = []; + for (n = 1; n != 16; ++n) + out[n - 1] = typeof Int32Array !== "undefined" ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; + } + var TT = slice_by_16_tables(T0); + var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; + var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; + var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; + function crc32_bstr(bstr, seed) { + var C = seed ^ -1; + for (var i = 0, L = bstr.length; i < L; ) + C = C >>> 8 ^ T0[(C ^ bstr.charCodeAt(i++)) & 255]; + return ~C; + } + function crc32_buf(B, seed) { + var C = seed ^ -1, L = B.length - 15, i = 0; + for (; i < L; ) + C = Tf[B[i++] ^ C & 255] ^ Te[B[i++] ^ C >> 8 & 255] ^ Td[B[i++] ^ C >> 16 & 255] ^ Tc[B[i++] ^ C >>> 24] ^ Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; + L += 15; + while (i < L) + C = C >>> 8 ^ T0[(C ^ B[i++]) & 255]; + return ~C; + } + function crc32_str(str, seed) { + var C = seed ^ -1; + for (var i = 0, L = str.length, c = 0, d = 0; i < L; ) { + c = str.charCodeAt(i++); + if (c < 128) { + C = C >>> 8 ^ T0[(C ^ c) & 255]; + } else if (c < 2048) { + C = C >>> 8 ^ T0[(C ^ (192 | c >> 6 & 31)) & 255]; + C = C >>> 8 ^ T0[(C ^ (128 | c & 63)) & 255]; + } else if (c >= 55296 && c < 57344) { + c = (c & 1023) + 64; + d = str.charCodeAt(i++) & 1023; + C = C >>> 8 ^ T0[(C ^ (240 | c >> 8 & 7)) & 255]; + C = C >>> 8 ^ T0[(C ^ (128 | c >> 2 & 63)) & 255]; + C = C >>> 8 ^ T0[(C ^ (128 | d >> 6 & 15 | (c & 3) << 4)) & 255]; + C = C >>> 8 ^ T0[(C ^ (128 | d & 63)) & 255]; + } else { + C = C >>> 8 ^ T0[(C ^ (224 | c >> 12 & 15)) & 255]; + C = C >>> 8 ^ T0[(C ^ (128 | c >> 6 & 63)) & 255]; + C = C >>> 8 ^ T0[(C ^ (128 | c & 63)) & 255]; + } + } + return ~C; + } + CRC322.table = T0; + CRC322.bstr = crc32_bstr; + CRC322.buf = crc32_buf; + CRC322.str = crc32_str; + }); + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/utils/common.js +var require_common = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/utils/common.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var TYPED_OK = typeof Uint8Array !== "undefined" && typeof Uint16Array !== "undefined" && typeof Int32Array !== "undefined"; + function _has(obj, key2) { + return Object.prototype.hasOwnProperty.call(obj, key2); + } + exports2.assign = function(obj) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { + continue; + } + if (typeof source !== "object") { + throw new TypeError(source + "must be non-object"); + } + for (var p in source) { + if (_has(source, p)) { + obj[p] = source[p]; + } + } + } + return obj; + }; + exports2.shrinkBuf = function(buf, size) { + if (buf.length === size) { + return buf; + } + if (buf.subarray) { + return buf.subarray(0, size); + } + buf.length = size; + return buf; + }; + var fnTyped = { + arraySet: function(dest, src, src_offs, len, dest_offs) { + if (src.subarray && dest.subarray) { + dest.set(src.subarray(src_offs, src_offs + len), dest_offs); + return; + } + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function(chunks) { + var i, l, len, pos, chunk, result; + len = 0; + for (i = 0, l = chunks.length; i < l; i++) { + len += chunks[i].length; + } + result = new Uint8Array(len); + pos = 0; + for (i = 0, l = chunks.length; i < l; i++) { + chunk = chunks[i]; + result.set(chunk, pos); + pos += chunk.length; + } + return result; + } + }; + var fnUntyped = { + arraySet: function(dest, src, src_offs, len, dest_offs) { + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function(chunks) { + return [].concat.apply([], chunks); + } + }; + exports2.setTyped = function(on) { + if (on) { + exports2.Buf8 = Uint8Array; + exports2.Buf16 = Uint16Array; + exports2.Buf32 = Int32Array; + exports2.assign(exports2, fnTyped); + } else { + exports2.Buf8 = Array; + exports2.Buf16 = Array; + exports2.Buf32 = Array; + exports2.assign(exports2, fnUntyped); + } + }; + exports2.setTyped(TYPED_OK); + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/trees.js +var require_trees = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/trees.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var utils = require_common(); + var Z_FIXED = 4; + var Z_BINARY = 0; + var Z_TEXT = 1; + var Z_UNKNOWN = 2; + function zero(buf) { + var len = buf.length; + while (--len >= 0) { + buf[len] = 0; + } + } + var STORED_BLOCK = 0; + var STATIC_TREES = 1; + var DYN_TREES = 2; + var MIN_MATCH = 3; + var MAX_MATCH = 258; + var LENGTH_CODES = 29; + var LITERALS = 256; + var L_CODES = LITERALS + 1 + LENGTH_CODES; + var D_CODES = 30; + var BL_CODES = 19; + var HEAP_SIZE = 2 * L_CODES + 1; + var MAX_BITS = 15; + var Buf_size = 16; + var MAX_BL_BITS = 7; + var END_BLOCK = 256; + var REP_3_6 = 16; + var REPZ_3_10 = 17; + var REPZ_11_138 = 18; + var extra_lbits = ( + /* extra bits for each length code */ + [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0] + ); + var extra_dbits = ( + /* extra bits for each distance code */ + [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13] + ); + var extra_blbits = ( + /* extra bits for each bit length code */ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7] + ); + var bl_order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + var DIST_CODE_LEN = 512; + var static_ltree = new Array((L_CODES + 2) * 2); + zero(static_ltree); + var static_dtree = new Array(D_CODES * 2); + zero(static_dtree); + var _dist_code = new Array(DIST_CODE_LEN); + zero(_dist_code); + var _length_code = new Array(MAX_MATCH - MIN_MATCH + 1); + zero(_length_code); + var base_length = new Array(LENGTH_CODES); + zero(base_length); + var base_dist = new Array(D_CODES); + zero(base_dist); + function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { + this.static_tree = static_tree; + this.extra_bits = extra_bits; + this.extra_base = extra_base; + this.elems = elems; + this.max_length = max_length; + this.has_stree = static_tree && static_tree.length; + } + var static_l_desc; + var static_d_desc; + var static_bl_desc; + function TreeDesc(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; + this.max_code = 0; + this.stat_desc = stat_desc; + } + function d_code(dist) { + return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; + } + function put_short(s, w) { + s.pending_buf[s.pending++] = w & 255; + s.pending_buf[s.pending++] = w >>> 8 & 255; + } + function send_bits(s, value, length) { + if (s.bi_valid > Buf_size - length) { + s.bi_buf |= value << s.bi_valid & 65535; + put_short(s, s.bi_buf); + s.bi_buf = value >> Buf_size - s.bi_valid; + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= value << s.bi_valid & 65535; + s.bi_valid += length; + } + } + function send_code(s, c, tree) { + send_bits( + s, + tree[c * 2], + tree[c * 2 + 1] + /*.Len*/ + ); + } + function bi_reverse(code, len) { + var res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; + } + function bi_flush(s) { + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 255; + s.bi_buf >>= 8; + s.bi_valid -= 8; + } + } + function gen_bitlen(s, desc) { + var tree = desc.dyn_tree; + var max_code = desc.max_code; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var extra = desc.stat_desc.extra_bits; + var base = desc.stat_desc.extra_base; + var max_length = desc.stat_desc.max_length; + var h; + var n, m; + var bits; + var xbits; + var f; + var overflow = 0; + for (bits = 0; bits <= MAX_BITS; bits++) { + s.bl_count[bits] = 0; + } + tree[s.heap[s.heap_max] * 2 + 1] = 0; + for (h = s.heap_max + 1; h < HEAP_SIZE; h++) { + n = s.heap[h]; + bits = tree[tree[n * 2 + 1] * 2 + 1] + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n * 2 + 1] = bits; + if (n > max_code) { + continue; + } + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n - base]; + } + f = tree[n * 2]; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += f * (stree[n * 2 + 1] + xbits); + } + } + if (overflow === 0) { + return; + } + do { + bits = max_length - 1; + while (s.bl_count[bits] === 0) { + bits--; + } + s.bl_count[bits]--; + s.bl_count[bits + 1] += 2; + s.bl_count[max_length]--; + overflow -= 2; + } while (overflow > 0); + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { + continue; + } + if (tree[m * 2 + 1] !== bits) { + s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2]; + tree[m * 2 + 1] = bits; + } + n--; + } + } + } + function gen_codes(tree, max_code, bl_count) { + var next_code = new Array(MAX_BITS + 1); + var code = 0; + var bits; + var n; + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = code + bl_count[bits - 1] << 1; + } + for (n = 0; n <= max_code; n++) { + var len = tree[n * 2 + 1]; + if (len === 0) { + continue; + } + tree[n * 2] = bi_reverse(next_code[len]++, len); + } + } + function tr_static_init() { + var n; + var bits; + var length; + var code; + var dist; + var bl_count = new Array(MAX_BITS + 1); + length = 0; + for (code = 0; code < LENGTH_CODES - 1; code++) { + base_length[code] = length; + for (n = 0; n < 1 << extra_lbits[code]; n++) { + _length_code[length++] = code; + } + } + _length_code[length - 1] = code; + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < 1 << extra_dbits[code]; n++) { + _dist_code[dist++] = code; + } + } + dist >>= 7; + for (; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < 1 << extra_dbits[code] - 7; n++) { + _dist_code[256 + dist++] = code; + } + } + for (bits = 0; bits <= MAX_BITS; bits++) { + bl_count[bits] = 0; + } + n = 0; + while (n <= 143) { + static_ltree[n * 2 + 1] = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n * 2 + 1] = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n * 2 + 1] = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n * 2 + 1] = 8; + n++; + bl_count[8]++; + } + gen_codes(static_ltree, L_CODES + 1, bl_count); + for (n = 0; n < D_CODES; n++) { + static_dtree[n * 2 + 1] = 5; + static_dtree[n * 2] = bi_reverse(n, 5); + } + static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS); + static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); + static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); + } + function init_block(s) { + var n; + for (n = 0; n < L_CODES; n++) { + s.dyn_ltree[n * 2] = 0; + } + for (n = 0; n < D_CODES; n++) { + s.dyn_dtree[n * 2] = 0; + } + for (n = 0; n < BL_CODES; n++) { + s.bl_tree[n * 2] = 0; + } + s.dyn_ltree[END_BLOCK * 2] = 1; + s.opt_len = s.static_len = 0; + s.last_lit = s.matches = 0; + } + function bi_windup(s) { + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; + } + function copy_block(s, buf, len, header) { + bi_windup(s); + if (header) { + put_short(s, len); + put_short(s, ~len); + } + utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); + s.pending += len; + } + function smaller(tree, n, m, depth) { + var _n2 = n * 2; + var _m2 = m * 2; + return tree[_n2] < tree[_m2] || tree[_n2] === tree[_m2] && depth[n] <= depth[m]; + } + function pqdownheap(s, tree, k) { + var v = s.heap[k]; + var j = k << 1; + while (j <= s.heap_len) { + if (j < s.heap_len && smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { + j++; + } + if (smaller(tree, v, s.heap[j], s.depth)) { + break; + } + s.heap[k] = s.heap[j]; + k = j; + j <<= 1; + } + s.heap[k] = v; + } + function compress_block(s, ltree, dtree) { + var dist; + var lc; + var lx = 0; + var code; + var extra; + if (s.last_lit !== 0) { + do { + dist = s.pending_buf[s.d_buf + lx * 2] << 8 | s.pending_buf[s.d_buf + lx * 2 + 1]; + lc = s.pending_buf[s.l_buf + lx]; + lx++; + if (dist === 0) { + send_code(s, lc, ltree); + } else { + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); + } + dist--; + code = d_code(dist); + send_code(s, code, dtree); + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); + } + } + } while (lx < s.last_lit); + } + send_code(s, END_BLOCK, ltree); + } + function build_tree(s, desc) { + var tree = desc.dyn_tree; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var elems = desc.stat_desc.elems; + var n, m; + var max_code = -1; + var node; + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + for (n = 0; n < elems; n++) { + if (tree[n * 2] !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + } else { + tree[n * 2 + 1] = 0; + } + } + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0; + tree[node * 2] = 1; + s.depth[node] = 0; + s.opt_len--; + if (has_stree) { + s.static_len -= stree[node * 2 + 1]; + } + } + desc.max_code = max_code; + for (n = s.heap_len >> 1; n >= 1; n--) { + pqdownheap(s, tree, n); + } + node = elems; + do { + n = s.heap[ + 1 + /*SMALLEST*/ + ]; + s.heap[ + 1 + /*SMALLEST*/ + ] = s.heap[s.heap_len--]; + pqdownheap( + s, + tree, + 1 + /*SMALLEST*/ + ); + m = s.heap[ + 1 + /*SMALLEST*/ + ]; + s.heap[--s.heap_max] = n; + s.heap[--s.heap_max] = m; + tree[node * 2] = tree[n * 2] + tree[m * 2]; + s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; + tree[n * 2 + 1] = tree[m * 2 + 1] = node; + s.heap[ + 1 + /*SMALLEST*/ + ] = node++; + pqdownheap( + s, + tree, + 1 + /*SMALLEST*/ + ); + } while (s.heap_len >= 2); + s.heap[--s.heap_max] = s.heap[ + 1 + /*SMALLEST*/ + ]; + gen_bitlen(s, desc); + gen_codes(tree, max_code, s.bl_count); + } + function scan_tree(s, tree, max_code) { + var n; + var prevlen = -1; + var curlen; + var nextlen = tree[0 * 2 + 1]; + var count = 0; + var max_count = 7; + var min_count = 4; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + tree[(max_code + 1) * 2 + 1] = 65535; + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]; + if (++count < max_count && curlen === nextlen) { + continue; + } else if (count < min_count) { + s.bl_tree[curlen * 2] += count; + } else if (curlen !== 0) { + if (curlen !== prevlen) { + s.bl_tree[curlen * 2]++; + } + s.bl_tree[REP_3_6 * 2]++; + } else if (count <= 10) { + s.bl_tree[REPZ_3_10 * 2]++; + } else { + s.bl_tree[REPZ_11_138 * 2]++; + } + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } + function send_tree(s, tree, max_code) { + var n; + var prevlen = -1; + var curlen; + var nextlen = tree[0 * 2 + 1]; + var count = 0; + var max_count = 7; + var min_count = 4; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]; + if (++count < max_count && curlen === nextlen) { + continue; + } else if (count < min_count) { + do { + send_code(s, curlen, s.bl_tree); + } while (--count !== 0); + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; + } + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count - 3, 2); + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count - 3, 3); + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count - 11, 7); + } + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } + function build_bl_tree(s) { + var max_blindex; + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + build_tree(s, s.bl_desc); + for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { + if (s.bl_tree[bl_order[max_blindex] * 2 + 1] !== 0) { + break; + } + } + s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + return max_blindex; + } + function send_all_trees(s, lcodes, dcodes, blcodes) { + var rank; + send_bits(s, lcodes - 257, 5); + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); + for (rank = 0; rank < blcodes; rank++) { + send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1], 3); + } + send_tree(s, s.dyn_ltree, lcodes - 1); + send_tree(s, s.dyn_dtree, dcodes - 1); + } + function detect_data_type(s) { + var black_mask = 4093624447; + var n; + for (n = 0; n <= 31; n++, black_mask >>>= 1) { + if (black_mask & 1 && s.dyn_ltree[n * 2] !== 0) { + return Z_BINARY; + } + } + if (s.dyn_ltree[9 * 2] !== 0 || s.dyn_ltree[10 * 2] !== 0 || s.dyn_ltree[13 * 2] !== 0) { + return Z_TEXT; + } + for (n = 32; n < LITERALS; n++) { + if (s.dyn_ltree[n * 2] !== 0) { + return Z_TEXT; + } + } + return Z_BINARY; + } + var static_init_done = false; + function _tr_init(s) { + if (!static_init_done) { + tr_static_init(); + static_init_done = true; + } + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); + s.bi_buf = 0; + s.bi_valid = 0; + init_block(s); + } + function _tr_stored_block(s, buf, stored_len, last2) { + send_bits(s, (STORED_BLOCK << 1) + (last2 ? 1 : 0), 3); + copy_block(s, buf, stored_len, true); + } + function _tr_align(s) { + send_bits(s, STATIC_TREES << 1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); + } + function _tr_flush_block(s, buf, stored_len, last2) { + var opt_lenb, static_lenb; + var max_blindex = 0; + if (s.level > 0) { + if (s.strm.data_type === Z_UNKNOWN) { + s.strm.data_type = detect_data_type(s); + } + build_tree(s, s.l_desc); + build_tree(s, s.d_desc); + max_blindex = build_bl_tree(s); + opt_lenb = s.opt_len + 3 + 7 >>> 3; + static_lenb = s.static_len + 3 + 7 >>> 3; + if (static_lenb <= opt_lenb) { + opt_lenb = static_lenb; + } + } else { + opt_lenb = static_lenb = stored_len + 5; + } + if (stored_len + 4 <= opt_lenb && buf !== -1) { + _tr_stored_block(s, buf, stored_len, last2); + } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { + send_bits(s, (STATIC_TREES << 1) + (last2 ? 1 : 0), 3); + compress_block(s, static_ltree, static_dtree); + } else { + send_bits(s, (DYN_TREES << 1) + (last2 ? 1 : 0), 3); + send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); + compress_block(s, s.dyn_ltree, s.dyn_dtree); + } + init_block(s); + if (last2) { + bi_windup(s); + } + } + function _tr_tally(s, dist, lc) { + s.pending_buf[s.d_buf + s.last_lit * 2] = dist >>> 8 & 255; + s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 255; + s.pending_buf[s.l_buf + s.last_lit] = lc & 255; + s.last_lit++; + if (dist === 0) { + s.dyn_ltree[lc * 2]++; + } else { + s.matches++; + dist--; + s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]++; + s.dyn_dtree[d_code(dist) * 2]++; + } + return s.last_lit === s.lit_bufsize - 1; + } + exports2._tr_init = _tr_init; + exports2._tr_stored_block = _tr_stored_block; + exports2._tr_flush_block = _tr_flush_block; + exports2._tr_tally = _tr_tally; + exports2._tr_align = _tr_align; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/adler32.js +var require_adler32 = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/adler32.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + function adler32(adler, buf, len, pos) { + var s1 = adler & 65535 | 0, s2 = adler >>> 16 & 65535 | 0, n = 0; + while (len !== 0) { + n = len > 2e3 ? 2e3 : len; + len -= n; + do { + s1 = s1 + buf[pos++] | 0; + s2 = s2 + s1 | 0; + } while (--n); + s1 %= 65521; + s2 %= 65521; + } + return s1 | s2 << 16 | 0; + } + module2.exports = adler32; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/crc32.js +var require_crc322 = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/crc32.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + function makeTable() { + var c, table = []; + for (var n = 0; n < 256; n++) { + c = n; + for (var k = 0; k < 8; k++) { + c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1; + } + table[n] = c; + } + return table; + } + var crcTable = makeTable(); + function crc322(crc, buf, len, pos) { + var t = crcTable, end = pos + len; + crc ^= -1; + for (var i = pos; i < end; i++) { + crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 255]; + } + return crc ^ -1; + } + module2.exports = crc322; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/messages.js +var require_messages = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/messages.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + module2.exports = { + 2: "need dictionary", + /* Z_NEED_DICT 2 */ + 1: "stream end", + /* Z_STREAM_END 1 */ + 0: "", + /* Z_OK 0 */ + "-1": "file error", + /* Z_ERRNO (-1) */ + "-2": "stream error", + /* Z_STREAM_ERROR (-2) */ + "-3": "data error", + /* Z_DATA_ERROR (-3) */ + "-4": "insufficient memory", + /* Z_MEM_ERROR (-4) */ + "-5": "buffer error", + /* Z_BUF_ERROR (-5) */ + "-6": "incompatible version" + /* Z_VERSION_ERROR (-6) */ + }; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/deflate.js +var require_deflate = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/deflate.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var utils = require_common(); + var trees = require_trees(); + var adler32 = require_adler32(); + var crc322 = require_crc322(); + var msg = require_messages(); + var Z_NO_FLUSH = 0; + var Z_PARTIAL_FLUSH = 1; + var Z_FULL_FLUSH = 3; + var Z_FINISH = 4; + var Z_BLOCK = 5; + var Z_OK = 0; + var Z_STREAM_END = 1; + var Z_STREAM_ERROR = -2; + var Z_DATA_ERROR = -3; + var Z_BUF_ERROR = -5; + var Z_DEFAULT_COMPRESSION = -1; + var Z_FILTERED = 1; + var Z_HUFFMAN_ONLY = 2; + var Z_RLE = 3; + var Z_FIXED = 4; + var Z_DEFAULT_STRATEGY = 0; + var Z_UNKNOWN = 2; + var Z_DEFLATED = 8; + var MAX_MEM_LEVEL = 9; + var MAX_WBITS = 15; + var DEF_MEM_LEVEL = 8; + var LENGTH_CODES = 29; + var LITERALS = 256; + var L_CODES = LITERALS + 1 + LENGTH_CODES; + var D_CODES = 30; + var BL_CODES = 19; + var HEAP_SIZE = 2 * L_CODES + 1; + var MAX_BITS = 15; + var MIN_MATCH = 3; + var MAX_MATCH = 258; + var MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1; + var PRESET_DICT = 32; + var INIT_STATE = 42; + var EXTRA_STATE = 69; + var NAME_STATE = 73; + var COMMENT_STATE = 91; + var HCRC_STATE = 103; + var BUSY_STATE = 113; + var FINISH_STATE = 666; + var BS_NEED_MORE = 1; + var BS_BLOCK_DONE = 2; + var BS_FINISH_STARTED = 3; + var BS_FINISH_DONE = 4; + var OS_CODE = 3; + function err(strm, errorCode) { + strm.msg = msg[errorCode]; + return errorCode; + } + function rank(f) { + return (f << 1) - (f > 4 ? 9 : 0); + } + function zero(buf) { + var len = buf.length; + while (--len >= 0) { + buf[len] = 0; + } + } + function flush_pending(strm) { + var s = strm.state; + var len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { + return; + } + utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } + } + function flush_block_only(s, last2) { + trees._tr_flush_block(s, s.block_start >= 0 ? s.block_start : -1, s.strstart - s.block_start, last2); + s.block_start = s.strstart; + flush_pending(s.strm); + } + function put_byte(s, b) { + s.pending_buf[s.pending++] = b; + } + function putShortMSB(s, b) { + s.pending_buf[s.pending++] = b >>> 8 & 255; + s.pending_buf[s.pending++] = b & 255; + } + function read_buf(strm, buf, start, size) { + var len = strm.avail_in; + if (len > size) { + len = size; + } + if (len === 0) { + return 0; + } + strm.avail_in -= len; + utils.arraySet(buf, strm.input, strm.next_in, len, start); + if (strm.state.wrap === 1) { + strm.adler = adler32(strm.adler, buf, len, start); + } else if (strm.state.wrap === 2) { + strm.adler = crc322(strm.adler, buf, len, start); + } + strm.next_in += len; + strm.total_in += len; + return len; + } + function longest_match(s, cur_match) { + var chain_length = s.max_chain_length; + var scan = s.strstart; + var match; + var len; + var best_len = s.prev_length; + var nice_match = s.nice_match; + var limit = s.strstart > s.w_size - MIN_LOOKAHEAD ? s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0; + var _win = s.window; + var wmask = s.w_mask; + var prev = s.prev; + var strend = s.strstart + MAX_MATCH; + var scan_end1 = _win[scan + best_len - 1]; + var scan_end = _win[scan + best_len]; + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + if (nice_match > s.lookahead) { + nice_match = s.lookahead; + } + do { + match = cur_match; + if (_win[match + best_len] !== scan_end || _win[match + best_len - 1] !== scan_end1 || _win[match] !== _win[scan] || _win[++match] !== _win[scan + 1]) { + continue; + } + scan += 2; + match++; + do { + } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && scan < strend); + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; + } + function fill_window(s) { + var _w_size = s.w_size; + var p, n, m, more, str; + do { + more = s.window_size - s.lookahead - s.strstart; + if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { + utils.arraySet(s.window, s.window, _w_size, _w_size, 0); + s.match_start -= _w_size; + s.strstart -= _w_size; + s.block_start -= _w_size; + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = m >= _w_size ? m - _w_size : 0; + } while (--n); + n = _w_size; + p = n; + do { + m = s.prev[--p]; + s.prev[p] = m >= _w_size ? m - _w_size : 0; + } while (--n); + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } + n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); + s.lookahead += n; + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + 1]) & s.hash_mask; + while (s.insert) { + s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { + break; + } + } + } + } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); + } + function deflate_stored(s, flush2) { + var max_block_size = 65535; + if (max_block_size > s.pending_buf_size - 5) { + max_block_size = s.pending_buf_size - 5; + } + for (; ; ) { + if (s.lookahead <= 1) { + fill_window(s); + if (s.lookahead === 0 && flush2 === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; + } + } + s.strstart += s.lookahead; + s.lookahead = 0; + var max_start = s.block_start + max_block_size; + if (s.strstart === 0 || s.strstart >= max_start) { + s.lookahead = s.strstart - max_start; + s.strstart = max_start; + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + if (s.strstart - s.block_start >= s.w_size - MIN_LOOKAHEAD) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + } + s.insert = 0; + if (flush2 === Z_FINISH) { + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + return BS_FINISH_DONE; + } + if (s.strstart > s.block_start) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + return BS_NEED_MORE; + } + function deflate_fast(s, flush2) { + var hash_head; + var bflush; + for (; ; ) { + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush2 === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; + } + } + hash_head = 0; + if (s.lookahead >= MIN_MATCH) { + s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + } + if (hash_head !== 0 && s.strstart - hash_head <= s.w_size - MIN_LOOKAHEAD) { + s.match_length = longest_match(s, hash_head); + } + if (s.match_length >= MIN_MATCH) { + bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); + s.lookahead -= s.match_length; + if (s.match_length <= s.max_lazy_match && s.lookahead >= MIN_MATCH) { + s.match_length--; + do { + s.strstart++; + s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + } while (--s.match_length !== 0); + s.strstart++; + } else { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + 1]) & s.hash_mask; + } + } else { + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + } + if (bflush) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + } + s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; + if (flush2 === Z_FINISH) { + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + return BS_FINISH_DONE; + } + if (s.last_lit) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + return BS_BLOCK_DONE; + } + function deflate_slow(s, flush2) { + var hash_head; + var bflush; + var max_insert; + for (; ; ) { + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush2 === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; + } + } + hash_head = 0; + if (s.lookahead >= MIN_MATCH) { + s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + } + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH - 1; + if (hash_head !== 0 && s.prev_length < s.max_lazy_match && s.strstart - hash_head <= s.w_size - MIN_LOOKAHEAD) { + s.match_length = longest_match(s, hash_head); + if (s.match_length <= 5 && (s.strategy === Z_FILTERED || s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096)) { + s.match_length = MIN_MATCH - 1; + } + } + if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { + max_insert = s.strstart + s.lookahead - MIN_MATCH; + bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); + s.lookahead -= s.prev_length - 1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + s.ins_h = (s.ins_h << s.hash_shift ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH - 1; + s.strstart++; + if (bflush) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + } else if (s.match_available) { + bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); + if (bflush) { + flush_block_only(s, false); + } + s.strstart++; + s.lookahead--; + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } else { + s.match_available = 1; + s.strstart++; + s.lookahead--; + } + } + if (s.match_available) { + bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); + s.match_available = 0; + } + s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; + if (flush2 === Z_FINISH) { + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + return BS_FINISH_DONE; + } + if (s.last_lit) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + return BS_BLOCK_DONE; + } + function deflate_rle(s, flush2) { + var bflush; + var prev; + var scan, strend; + var _win = s.window; + for (; ; ) { + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if (s.lookahead <= MAX_MATCH && flush2 === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; + } + } + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { + strend = s.strstart + MAX_MATCH; + do { + } while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && scan < strend); + s.match_length = MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; + } + } + } + if (s.match_length >= MIN_MATCH) { + bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + } + if (bflush) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + } + s.insert = 0; + if (flush2 === Z_FINISH) { + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + return BS_FINISH_DONE; + } + if (s.last_lit) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + return BS_BLOCK_DONE; + } + function deflate_huff(s, flush2) { + var bflush; + for (; ; ) { + if (s.lookahead === 0) { + fill_window(s); + if (s.lookahead === 0) { + if (flush2 === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + break; + } + } + s.match_length = 0; + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + if (bflush) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + } + s.insert = 0; + if (flush2 === Z_FINISH) { + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + return BS_FINISH_DONE; + } + if (s.last_lit) { + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } + return BS_BLOCK_DONE; + } + function Config(good_length, max_lazy, nice_length, max_chain, func) { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; + } + var configuration_table; + configuration_table = [ + /* good lazy nice chain */ + new Config(0, 0, 0, 0, deflate_stored), + /* 0 store only */ + new Config(4, 4, 8, 4, deflate_fast), + /* 1 max speed, no lazy matches */ + new Config(4, 5, 16, 8, deflate_fast), + /* 2 */ + new Config(4, 6, 32, 32, deflate_fast), + /* 3 */ + new Config(4, 4, 16, 16, deflate_slow), + /* 4 lazy matches */ + new Config(8, 16, 32, 32, deflate_slow), + /* 5 */ + new Config(8, 16, 128, 128, deflate_slow), + /* 6 */ + new Config(8, 32, 128, 256, deflate_slow), + /* 7 */ + new Config(32, 128, 258, 1024, deflate_slow), + /* 8 */ + new Config(32, 258, 258, 4096, deflate_slow) + /* 9 max compression */ + ]; + function lm_init(s) { + s.window_size = 2 * s.w_size; + zero(s.head); + s.max_lazy_match = configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = configuration_table[s.level].max_chain; + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; + } + function DeflateState() { + this.strm = null; + this.status = 0; + this.pending_buf = null; + this.pending_buf_size = 0; + this.pending_out = 0; + this.pending = 0; + this.wrap = 0; + this.gzhead = null; + this.gzindex = 0; + this.method = Z_DEFLATED; + this.last_flush = -1; + this.w_size = 0; + this.w_bits = 0; + this.w_mask = 0; + this.window = null; + this.window_size = 0; + this.prev = null; + this.head = null; + this.ins_h = 0; + this.hash_size = 0; + this.hash_bits = 0; + this.hash_mask = 0; + this.hash_shift = 0; + this.block_start = 0; + this.match_length = 0; + this.prev_match = 0; + this.match_available = 0; + this.strstart = 0; + this.match_start = 0; + this.lookahead = 0; + this.prev_length = 0; + this.max_chain_length = 0; + this.max_lazy_match = 0; + this.level = 0; + this.strategy = 0; + this.good_match = 0; + this.nice_match = 0; + this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2); + this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); + this.l_desc = null; + this.d_desc = null; + this.bl_desc = null; + this.bl_count = new utils.Buf16(MAX_BITS + 1); + this.heap = new utils.Buf16(2 * L_CODES + 1); + zero(this.heap); + this.heap_len = 0; + this.heap_max = 0; + this.depth = new utils.Buf16(2 * L_CODES + 1); + zero(this.depth); + this.l_buf = 0; + this.lit_bufsize = 0; + this.last_lit = 0; + this.d_buf = 0; + this.opt_len = 0; + this.static_len = 0; + this.matches = 0; + this.insert = 0; + this.bi_buf = 0; + this.bi_valid = 0; + } + function deflateResetKeep(strm) { + var s; + if (!strm || !strm.state) { + return err(strm, Z_STREAM_ERROR); + } + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; + s = strm.state; + s.pending = 0; + s.pending_out = 0; + if (s.wrap < 0) { + s.wrap = -s.wrap; + } + s.status = s.wrap ? INIT_STATE : BUSY_STATE; + strm.adler = s.wrap === 2 ? 0 : 1; + s.last_flush = Z_NO_FLUSH; + trees._tr_init(s); + return Z_OK; + } + function deflateReset(strm) { + var ret = deflateResetKeep(strm); + if (ret === Z_OK) { + lm_init(strm.state); + } + return ret; + } + function deflateSetHeader(strm, head) { + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + if (strm.state.wrap !== 2) { + return Z_STREAM_ERROR; + } + strm.state.gzhead = head; + return Z_OK; + } + function deflateInit2(strm, level, method2, windowBits, memLevel, strategy) { + if (!strm) { + return Z_STREAM_ERROR; + } + var wrap = 1; + if (level === Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } else if (windowBits > 15) { + wrap = 2; + windowBits -= 16; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method2 !== Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return err(strm, Z_STREAM_ERROR); + } + if (windowBits === 8) { + windowBits = 9; + } + var s = new DeflateState(); + strm.state = s; + s.strm = strm; + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); + s.window = new utils.Buf8(s.w_size * 2); + s.head = new utils.Buf16(s.hash_size); + s.prev = new utils.Buf16(s.w_size); + s.lit_bufsize = 1 << memLevel + 6; + s.pending_buf_size = s.lit_bufsize * 4; + s.pending_buf = new utils.Buf8(s.pending_buf_size); + s.d_buf = 1 * s.lit_bufsize; + s.l_buf = (1 + 2) * s.lit_bufsize; + s.level = level; + s.strategy = strategy; + s.method = method2; + return deflateReset(strm); + } + function deflateInit(strm, level) { + return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); + } + function deflate2(strm, flush2) { + var old_flush, s; + var beg, val; + if (!strm || !strm.state || flush2 > Z_BLOCK || flush2 < 0) { + return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; + } + s = strm.state; + if (!strm.output || !strm.input && strm.avail_in !== 0 || s.status === FINISH_STATE && flush2 !== Z_FINISH) { + return err(strm, strm.avail_out === 0 ? Z_BUF_ERROR : Z_STREAM_ERROR); + } + s.strm = strm; + old_flush = s.last_flush; + s.last_flush = flush2; + if (s.status === INIT_STATE) { + if (s.wrap === 2) { + strm.adler = 0; + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s.level === 9 ? 2 : s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? 4 : 0); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + } else { + put_byte( + s, + (s.gzhead.text ? 1 : 0) + (s.gzhead.hcrc ? 2 : 0) + (!s.gzhead.extra ? 0 : 4) + (!s.gzhead.name ? 0 : 8) + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 255); + put_byte(s, s.gzhead.time >> 8 & 255); + put_byte(s, s.gzhead.time >> 16 & 255); + put_byte(s, s.gzhead.time >> 24 & 255); + put_byte(s, s.level === 9 ? 2 : s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? 4 : 0); + put_byte(s, s.gzhead.os & 255); + if (s.gzhead.extra && s.gzhead.extra.length) { + put_byte(s, s.gzhead.extra.length & 255); + put_byte(s, s.gzhead.extra.length >> 8 & 255); + } + if (s.gzhead.hcrc) { + strm.adler = crc322(strm.adler, s.pending_buf, s.pending, 0); + } + s.gzindex = 0; + s.status = EXTRA_STATE; + } + } else { + var header = Z_DEFLATED + (s.w_bits - 8 << 4) << 8; + var level_flags = -1; + if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= level_flags << 6; + if (s.strstart !== 0) { + header |= PRESET_DICT; + } + header += 31 - header % 31; + s.status = BUSY_STATE; + putShortMSB(s, header); + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 65535); + } + strm.adler = 1; + } + } + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra) { + beg = s.pending; + while (s.gzindex < (s.gzhead.extra.length & 65535)) { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc322(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + break; + } + } + put_byte(s, s.gzhead.extra[s.gzindex] & 255); + s.gzindex++; + } + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc322(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (s.gzindex === s.gzhead.extra.length) { + s.gzindex = 0; + s.status = NAME_STATE; + } + } else { + s.status = NAME_STATE; + } + } + if (s.status === NAME_STATE) { + if (s.gzhead.name) { + beg = s.pending; + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc322(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + if (s.gzindex < s.gzhead.name.length) { + val = s.gzhead.name.charCodeAt(s.gzindex++) & 255; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc322(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.gzindex = 0; + s.status = COMMENT_STATE; + } + } else { + s.status = COMMENT_STATE; + } + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment) { + beg = s.pending; + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc322(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + if (s.gzindex < s.gzhead.comment.length) { + val = s.gzhead.comment.charCodeAt(s.gzindex++) & 255; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc322(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.status = HCRC_STATE; + } + } else { + s.status = HCRC_STATE; + } + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); + } + if (s.pending + 2 <= s.pending_buf_size) { + put_byte(s, strm.adler & 255); + put_byte(s, strm.adler >> 8 & 255); + strm.adler = 0; + s.status = BUSY_STATE; + } + } else { + s.status = BUSY_STATE; + } + } + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; + return Z_OK; + } + } else if (strm.avail_in === 0 && rank(flush2) <= rank(old_flush) && flush2 !== Z_FINISH) { + return err(strm, Z_BUF_ERROR); + } + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR); + } + if (strm.avail_in !== 0 || s.lookahead !== 0 || flush2 !== Z_NO_FLUSH && s.status !== FINISH_STATE) { + var bstate = s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush2) : s.strategy === Z_RLE ? deflate_rle(s, flush2) : configuration_table[s.level].func(s, flush2); + if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { + s.status = FINISH_STATE; + } + if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { + if (strm.avail_out === 0) { + s.last_flush = -1; + } + return Z_OK; + } + if (bstate === BS_BLOCK_DONE) { + if (flush2 === Z_PARTIAL_FLUSH) { + trees._tr_align(s); + } else if (flush2 !== Z_BLOCK) { + trees._tr_stored_block(s, 0, 0, false); + if (flush2 === Z_FULL_FLUSH) { + zero(s.head); + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; + return Z_OK; + } + } + } + if (flush2 !== Z_FINISH) { + return Z_OK; + } + if (s.wrap <= 0) { + return Z_STREAM_END; + } + if (s.wrap === 2) { + put_byte(s, strm.adler & 255); + put_byte(s, strm.adler >> 8 & 255); + put_byte(s, strm.adler >> 16 & 255); + put_byte(s, strm.adler >> 24 & 255); + put_byte(s, strm.total_in & 255); + put_byte(s, strm.total_in >> 8 & 255); + put_byte(s, strm.total_in >> 16 & 255); + put_byte(s, strm.total_in >> 24 & 255); + } else { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 65535); + } + flush_pending(strm); + if (s.wrap > 0) { + s.wrap = -s.wrap; + } + return s.pending !== 0 ? Z_OK : Z_STREAM_END; + } + function deflateEnd(strm) { + var status2; + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + status2 = strm.state.status; + if (status2 !== INIT_STATE && status2 !== EXTRA_STATE && status2 !== NAME_STATE && status2 !== COMMENT_STATE && status2 !== HCRC_STATE && status2 !== BUSY_STATE && status2 !== FINISH_STATE) { + return err(strm, Z_STREAM_ERROR); + } + strm.state = null; + return status2 === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; + } + function deflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + var s; + var str, n; + var wrap; + var avail; + var next; + var input; + var tmpDict; + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + s = strm.state; + wrap = s.wrap; + if (wrap === 2 || wrap === 1 && s.status !== INIT_STATE || s.lookahead) { + return Z_STREAM_ERROR; + } + if (wrap === 1) { + strm.adler = adler32(strm.adler, dictionary, dictLength, 0); + } + s.wrap = 0; + if (dictLength >= s.w_size) { + if (wrap === 0) { + zero(s.head); + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + tmpDict = new utils.Buf8(s.w_size); + utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0); + dictionary = tmpDict; + dictLength = s.w_size; + } + avail = strm.avail_in; + next = strm.next_in; + input = strm.input; + strm.avail_in = dictLength; + strm.next_in = 0; + strm.input = dictionary; + fill_window(s); + while (s.lookahead >= MIN_MATCH) { + str = s.strstart; + n = s.lookahead - (MIN_MATCH - 1); + do { + s.ins_h = (s.ins_h << s.hash_shift ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + } while (--n); + s.strstart = str; + s.lookahead = MIN_MATCH - 1; + fill_window(s); + } + s.strstart += s.lookahead; + s.block_start = s.strstart; + s.insert = s.lookahead; + s.lookahead = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + strm.next_in = next; + strm.input = input; + strm.avail_in = avail; + s.wrap = wrap; + return Z_OK; + } + exports2.deflateInit = deflateInit; + exports2.deflateInit2 = deflateInit2; + exports2.deflateReset = deflateReset; + exports2.deflateResetKeep = deflateResetKeep; + exports2.deflateSetHeader = deflateSetHeader; + exports2.deflate = deflate2; + exports2.deflateEnd = deflateEnd; + exports2.deflateSetDictionary = deflateSetDictionary; + exports2.deflateInfo = "pako deflate (from Nodeca project)"; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/utils/strings.js +var require_strings = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/utils/strings.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var utils = require_common(); + var STR_APPLY_OK = true; + var STR_APPLY_UIA_OK = true; + try { + String.fromCharCode.apply(null, [0]); + } catch (__) { + STR_APPLY_OK = false; + } + try { + String.fromCharCode.apply(null, new Uint8Array(1)); + } catch (__) { + STR_APPLY_UIA_OK = false; + } + var _utf8len = new utils.Buf8(256); + for (q = 0; q < 256; q++) { + _utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1; + } + var q; + _utf8len[254] = _utf8len[254] = 1; + exports2.string2buf = function(str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 64512) === 55296 && m_pos + 1 < str_len) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 64512) === 56320) { + c = 65536 + (c - 55296 << 10) + (c2 - 56320); + m_pos++; + } + } + buf_len += c < 128 ? 1 : c < 2048 ? 2 : c < 65536 ? 3 : 4; + } + buf = new utils.Buf8(buf_len); + for (i = 0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 64512) === 55296 && m_pos + 1 < str_len) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 64512) === 56320) { + c = 65536 + (c - 55296 << 10) + (c2 - 56320); + m_pos++; + } + } + if (c < 128) { + buf[i++] = c; + } else if (c < 2048) { + buf[i++] = 192 | c >>> 6; + buf[i++] = 128 | c & 63; + } else if (c < 65536) { + buf[i++] = 224 | c >>> 12; + buf[i++] = 128 | c >>> 6 & 63; + buf[i++] = 128 | c & 63; + } else { + buf[i++] = 240 | c >>> 18; + buf[i++] = 128 | c >>> 12 & 63; + buf[i++] = 128 | c >>> 6 & 63; + buf[i++] = 128 | c & 63; + } + } + return buf; + }; + function buf2binstring(buf, len) { + if (len < 65534) { + if (buf.subarray && STR_APPLY_UIA_OK || !buf.subarray && STR_APPLY_OK) { + return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len)); + } + } + var result = ""; + for (var i = 0; i < len; i++) { + result += String.fromCharCode(buf[i]); + } + return result; + } + exports2.buf2binstring = function(buf) { + return buf2binstring(buf, buf.length); + }; + exports2.binstring2buf = function(str) { + var buf = new utils.Buf8(str.length); + for (var i = 0, len = buf.length; i < len; i++) { + buf[i] = str.charCodeAt(i); + } + return buf; + }; + exports2.buf2string = function(buf, max) { + var i, out, c, c_len; + var len = max || buf.length; + var utf16buf = new Array(len * 2); + for (out = 0, i = 0; i < len; ) { + c = buf[i++]; + if (c < 128) { + utf16buf[out++] = c; + continue; + } + c_len = _utf8len[c]; + if (c_len > 4) { + utf16buf[out++] = 65533; + i += c_len - 1; + continue; + } + c &= c_len === 2 ? 31 : c_len === 3 ? 15 : 7; + while (c_len > 1 && i < len) { + c = c << 6 | buf[i++] & 63; + c_len--; + } + if (c_len > 1) { + utf16buf[out++] = 65533; + continue; + } + if (c < 65536) { + utf16buf[out++] = c; + } else { + c -= 65536; + utf16buf[out++] = 55296 | c >> 10 & 1023; + utf16buf[out++] = 56320 | c & 1023; + } + } + return buf2binstring(utf16buf, out); + }; + exports2.utf8border = function(buf, max) { + var pos; + max = max || buf.length; + if (max > buf.length) { + max = buf.length; + } + pos = max - 1; + while (pos >= 0 && (buf[pos] & 192) === 128) { + pos--; + } + if (pos < 0) { + return max; + } + if (pos === 0) { + return max; + } + return pos + _utf8len[buf[pos]] > max ? pos : max; + }; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/zstream.js +var require_zstream = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/zstream.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + function ZStream() { + this.input = null; + this.next_in = 0; + this.avail_in = 0; + this.total_in = 0; + this.output = null; + this.next_out = 0; + this.avail_out = 0; + this.total_out = 0; + this.msg = ""; + this.state = null; + this.data_type = 2; + this.adler = 0; + } + module2.exports = ZStream; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/deflate.js +var require_deflate2 = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/deflate.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var zlib_deflate = require_deflate(); + var utils = require_common(); + var strings = require_strings(); + var msg = require_messages(); + var ZStream = require_zstream(); + var toString = Object.prototype.toString; + var Z_NO_FLUSH = 0; + var Z_FINISH = 4; + var Z_OK = 0; + var Z_STREAM_END = 1; + var Z_SYNC_FLUSH = 2; + var Z_DEFAULT_COMPRESSION = -1; + var Z_DEFAULT_STRATEGY = 0; + var Z_DEFLATED = 8; + function Deflate(options) { + if (!(this instanceof Deflate)) + return new Deflate(options); + this.options = utils.assign({ + level: Z_DEFAULT_COMPRESSION, + method: Z_DEFLATED, + chunkSize: 16384, + windowBits: 15, + memLevel: 8, + strategy: Z_DEFAULT_STRATEGY, + to: "" + }, options || {}); + var opt = this.options; + if (opt.raw && opt.windowBits > 0) { + opt.windowBits = -opt.windowBits; + } else if (opt.gzip && opt.windowBits > 0 && opt.windowBits < 16) { + opt.windowBits += 16; + } + this.err = 0; + this.msg = ""; + this.ended = false; + this.chunks = []; + this.strm = new ZStream(); + this.strm.avail_out = 0; + var status2 = zlib_deflate.deflateInit2( + this.strm, + opt.level, + opt.method, + opt.windowBits, + opt.memLevel, + opt.strategy + ); + if (status2 !== Z_OK) { + throw new Error(msg[status2]); + } + if (opt.header) { + zlib_deflate.deflateSetHeader(this.strm, opt.header); + } + if (opt.dictionary) { + var dict; + if (typeof opt.dictionary === "string") { + dict = strings.string2buf(opt.dictionary); + } else if (toString.call(opt.dictionary) === "[object ArrayBuffer]") { + dict = new Uint8Array(opt.dictionary); + } else { + dict = opt.dictionary; + } + status2 = zlib_deflate.deflateSetDictionary(this.strm, dict); + if (status2 !== Z_OK) { + throw new Error(msg[status2]); + } + this._dict_set = true; + } + } + Deflate.prototype.push = function(data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status2, _mode; + if (this.ended) { + return false; + } + _mode = mode === ~~mode ? mode : mode === true ? Z_FINISH : Z_NO_FLUSH; + if (typeof data === "string") { + strm.input = strings.string2buf(data); + } else if (toString.call(data) === "[object ArrayBuffer]") { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } + strm.next_in = 0; + strm.avail_in = strm.input.length; + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + status2 = zlib_deflate.deflate(strm, _mode); + if (status2 !== Z_STREAM_END && status2 !== Z_OK) { + this.onEnd(status2); + this.ended = true; + return false; + } + if (strm.avail_out === 0 || strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH)) { + if (this.options.to === "string") { + this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out))); + } else { + this.onData(utils.shrinkBuf(strm.output, strm.next_out)); + } + } + } while ((strm.avail_in > 0 || strm.avail_out === 0) && status2 !== Z_STREAM_END); + if (_mode === Z_FINISH) { + status2 = zlib_deflate.deflateEnd(this.strm); + this.onEnd(status2); + this.ended = true; + return status2 === Z_OK; + } + if (_mode === Z_SYNC_FLUSH) { + this.onEnd(Z_OK); + strm.avail_out = 0; + return true; + } + return true; + }; + Deflate.prototype.onData = function(chunk) { + this.chunks.push(chunk); + }; + Deflate.prototype.onEnd = function(status2) { + if (status2 === Z_OK) { + if (this.options.to === "string") { + this.result = this.chunks.join(""); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status2; + this.msg = this.strm.msg; + }; + function deflate2(input, options) { + var deflator = new Deflate(options); + deflator.push(input, true); + if (deflator.err) { + throw deflator.msg || msg[deflator.err]; + } + return deflator.result; + } + function deflateRaw(input, options) { + options = options || {}; + options.raw = true; + return deflate2(input, options); + } + function gzip(input, options) { + options = options || {}; + options.gzip = true; + return deflate2(input, options); + } + exports2.Deflate = Deflate; + exports2.deflate = deflate2; + exports2.deflateRaw = deflateRaw; + exports2.gzip = gzip; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inffast.js +var require_inffast = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inffast.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var BAD = 30; + var TYPE = 12; + module2.exports = function inflate_fast(strm, start) { + var state; + var _in; + var last2; + var _out; + var beg; + var end; + var dmax; + var wsize; + var whave; + var wnext; + var s_window; + var hold; + var bits; + var lcode; + var dcode; + var lmask; + var dmask; + var here; + var op; + var len; + var dist; + var from; + var from_source; + var input, output; + state = strm.state; + _in = strm.next_in; + input = strm.input; + last2 = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); + dmax = state.dmax; + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + s_window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + for (; ; ) { + op = here >>> 24; + hold >>>= op; + bits -= op; + op = here >>> 16 & 255; + if (op === 0) { + output[_out++] = here & 65535; + } else if (op & 16) { + len = here & 65535; + op &= 15; + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & (1 << op) - 1; + hold >>>= op; + bits -= op; + } + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + for (; ; ) { + op = here >>> 24; + hold >>>= op; + bits -= op; + op = here >>> 16 & 255; + if (op & 16) { + dist = here & 65535; + op &= 15; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + } + dist += hold & (1 << op) - 1; + if (dist > dmax) { + strm.msg = "invalid distance too far back"; + state.mode = BAD; + break top; + } + hold >>>= op; + bits -= op; + op = _out - beg; + if (dist > op) { + op = dist - op; + if (op > whave) { + if (state.sane) { + strm.msg = "invalid distance too far back"; + state.mode = BAD; + break top; + } + } + from = 0; + from_source = s_window; + if (wnext === 0) { + from += wsize - op; + if (op < len) { + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; + from_source = output; + } + } else if (wnext < op) { + from += wsize + wnext - op; + op -= wnext; + if (op < len) { + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = 0; + if (wnext < len) { + op = wnext; + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; + from_source = output; + } + } + } else { + from += wnext - op; + if (op < len) { + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; + from_source = output; + } + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { + output[_out++] = from_source[from++]; + } + } + } else { + from = _out - dist; + do { + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { + output[_out++] = output[from++]; + } + } + } + } else if ((op & 64) === 0) { + here = dcode[(here & 65535) + (hold & (1 << op) - 1)]; + continue dodist; + } else { + strm.msg = "invalid distance code"; + state.mode = BAD; + break top; + } + break; + } + } else if ((op & 64) === 0) { + here = lcode[(here & 65535) + (hold & (1 << op) - 1)]; + continue dolen; + } else if (op & 32) { + state.mode = TYPE; + break top; + } else { + strm.msg = "invalid literal/length code"; + state.mode = BAD; + break top; + } + break; + } + } while (_in < last2 && _out < end); + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = _in < last2 ? 5 + (last2 - _in) : 5 - (_in - last2); + strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end); + state.hold = hold; + state.bits = bits; + return; + }; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inftrees.js +var require_inftrees = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inftrees.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var utils = require_common(); + var MAXBITS = 15; + var ENOUGH_LENS = 852; + var ENOUGH_DISTS = 592; + var CODES = 0; + var LENS = 1; + var DISTS = 2; + var lbase = [ + /* Length codes 257..285 base */ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 13, + 15, + 17, + 19, + 23, + 27, + 31, + 35, + 43, + 51, + 59, + 67, + 83, + 99, + 115, + 131, + 163, + 195, + 227, + 258, + 0, + 0 + ]; + var lext = [ + /* Length codes 257..285 extra */ + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 17, + 17, + 17, + 17, + 18, + 18, + 18, + 18, + 19, + 19, + 19, + 19, + 20, + 20, + 20, + 20, + 21, + 21, + 21, + 21, + 16, + 72, + 78 + ]; + var dbase = [ + /* Distance codes 0..29 base */ + 1, + 2, + 3, + 4, + 5, + 7, + 9, + 13, + 17, + 25, + 33, + 49, + 65, + 97, + 129, + 193, + 257, + 385, + 513, + 769, + 1025, + 1537, + 2049, + 3073, + 4097, + 6145, + 8193, + 12289, + 16385, + 24577, + 0, + 0 + ]; + var dext = [ + /* Distance codes 0..29 extra */ + 16, + 16, + 16, + 16, + 17, + 17, + 18, + 18, + 19, + 19, + 20, + 20, + 21, + 21, + 22, + 22, + 23, + 23, + 24, + 24, + 25, + 25, + 26, + 26, + 27, + 27, + 28, + 28, + 29, + 29, + 64, + 64 + ]; + module2.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) { + var bits = opts.bits; + var len = 0; + var sym = 0; + var min = 0, max = 0; + var root2 = 0; + var curr = 0; + var drop = 0; + var left = 0; + var used = 0; + var huff = 0; + var incr; + var fill; + var low; + var mask; + var next; + var base = null; + var base_index = 0; + var end; + var count = new utils.Buf16(MAXBITS + 1); + var offs = new utils.Buf16(MAXBITS + 1); + var extra = null; + var extra_index = 0; + var here_bits, here_op, here_val; + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + root2 = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { + break; + } + } + if (root2 > max) { + root2 = max; + } + if (max === 0) { + table[table_index++] = 1 << 24 | 64 << 16 | 0; + table[table_index++] = 1 << 24 | 64 << 16 | 0; + opts.bits = 1; + return 0; + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { + break; + } + } + if (root2 < min) { + root2 = min; + } + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } + } + if (left > 0 && (type === CODES || max !== 1)) { + return -1; + } + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + if (type === CODES) { + base = extra = work; + end = 19; + } else if (type === LENS) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + } else { + base = dbase; + extra = dext; + end = -1; + } + huff = 0; + sym = 0; + len = min; + next = table_index; + curr = root2; + drop = 0; + low = -1; + used = 1 << root2; + mask = used - 1; + if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) { + return 1; + } + for (; ; ) { + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; + } else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } else { + here_op = 32 + 64; + here_val = 0; + } + incr = 1 << len - drop; + fill = 1 << curr; + min = fill; + do { + fill -= incr; + table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0; + } while (fill !== 0); + incr = 1 << len - 1; + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + sym++; + if (--count[len] === 0) { + if (len === max) { + break; + } + len = lens[lens_index + work[sym]]; + } + if (len > root2 && (huff & mask) !== low) { + if (drop === 0) { + drop = root2; + } + next += min; + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { + break; + } + curr++; + left <<= 1; + } + used += 1 << curr; + if (type === LENS && used > ENOUGH_LENS || type === DISTS && used > ENOUGH_DISTS) { + return 1; + } + low = huff & mask; + table[low] = root2 << 24 | curr << 16 | next - table_index | 0; + } + } + if (huff !== 0) { + table[next + huff] = len - drop << 24 | 64 << 16 | 0; + } + opts.bits = root2; + return 0; + }; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inflate.js +var require_inflate = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/inflate.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var utils = require_common(); + var adler32 = require_adler32(); + var crc322 = require_crc322(); + var inflate_fast = require_inffast(); + var inflate_table = require_inftrees(); + var CODES = 0; + var LENS = 1; + var DISTS = 2; + var Z_FINISH = 4; + var Z_BLOCK = 5; + var Z_TREES = 6; + var Z_OK = 0; + var Z_STREAM_END = 1; + var Z_NEED_DICT = 2; + var Z_STREAM_ERROR = -2; + var Z_DATA_ERROR = -3; + var Z_MEM_ERROR = -4; + var Z_BUF_ERROR = -5; + var Z_DEFLATED = 8; + var HEAD = 1; + var FLAGS = 2; + var TIME = 3; + var OS = 4; + var EXLEN = 5; + var EXTRA2 = 6; + var NAME = 7; + var COMMENT = 8; + var HCRC = 9; + var DICTID = 10; + var DICT = 11; + var TYPE = 12; + var TYPEDO = 13; + var STORED = 14; + var COPY_ = 15; + var COPY = 16; + var TABLE = 17; + var LENLENS = 18; + var CODELENS = 19; + var LEN_ = 20; + var LEN = 21; + var LENEXT = 22; + var DIST = 23; + var DISTEXT = 24; + var MATCH = 25; + var LIT = 26; + var CHECK = 27; + var LENGTH = 28; + var DONE = 29; + var BAD = 30; + var MEM = 31; + var SYNC = 32; + var ENOUGH_LENS = 852; + var ENOUGH_DISTS = 592; + var MAX_WBITS = 15; + var DEF_WBITS = MAX_WBITS; + function zswap32(q) { + return (q >>> 24 & 255) + (q >>> 8 & 65280) + ((q & 65280) << 8) + ((q & 255) << 24); + } + function InflateState() { + this.mode = 0; + this.last = false; + this.wrap = 0; + this.havedict = false; + this.flags = 0; + this.dmax = 0; + this.check = 0; + this.total = 0; + this.head = null; + this.wbits = 0; + this.wsize = 0; + this.whave = 0; + this.wnext = 0; + this.window = null; + this.hold = 0; + this.bits = 0; + this.length = 0; + this.offset = 0; + this.extra = 0; + this.lencode = null; + this.distcode = null; + this.lenbits = 0; + this.distbits = 0; + this.ncode = 0; + this.nlen = 0; + this.ndist = 0; + this.have = 0; + this.next = null; + this.lens = new utils.Buf16(320); + this.work = new utils.Buf16(288); + this.lendyn = null; + this.distdyn = null; + this.sane = 0; + this.back = 0; + this.was = 0; + } + function inflateResetKeep(strm) { + var state; + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ""; + if (state.wrap) { + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null; + state.hold = 0; + state.bits = 0; + state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); + state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); + state.sane = 1; + state.back = -1; + return Z_OK; + } + function inflateReset(strm) { + var state; + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + } + function inflateReset2(strm, windowBits) { + var wrap; + var state; + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; + } + } + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; + } + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; + } + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); + } + function inflateInit2(strm, windowBits) { + var ret; + var state; + if (!strm) { + return Z_STREAM_ERROR; + } + state = new InflateState(); + strm.state = state; + state.window = null; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null; + } + return ret; + } + function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); + } + var virgin = true; + var lenfix; + var distfix; + function fixedtables(state) { + if (virgin) { + var sym; + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); + sym = 0; + while (sym < 144) { + state.lens[sym++] = 8; + } + while (sym < 256) { + state.lens[sym++] = 9; + } + while (sym < 280) { + state.lens[sym++] = 7; + } + while (sym < 288) { + state.lens[sym++] = 8; + } + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); + sym = 0; + while (sym < 32) { + state.lens[sym++] = 5; + } + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); + virgin = false; + } + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; + } + function updatewindow(strm, src, end, copy2) { + var dist; + var state = strm.state; + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + state.window = new utils.Buf8(state.wsize); + } + if (copy2 >= state.wsize) { + utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0); + state.wnext = 0; + state.whave = state.wsize; + } else { + dist = state.wsize - state.wnext; + if (dist > copy2) { + dist = copy2; + } + utils.arraySet(state.window, src, end - copy2, dist, state.wnext); + copy2 -= dist; + if (copy2) { + utils.arraySet(state.window, src, end - copy2, copy2, 0); + state.wnext = copy2; + state.whave = state.wsize; + } else { + state.wnext += dist; + if (state.wnext === state.wsize) { + state.wnext = 0; + } + if (state.whave < state.wsize) { + state.whave += dist; + } + } + } + return 0; + } + function inflate2(strm, flush2) { + var state; + var input, output; + var next; + var put; + var have, left; + var hold; + var bits; + var _in, _out; + var copy2; + var from; + var from_source; + var here = 0; + var here_bits, here_op, here_val; + var last_bits, last_op, last_val; + var len; + var ret; + var hbuf = new utils.Buf8(4); + var opts; + var n; + var order = ( + /* permutation of code lengths */ + [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15] + ); + if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) { + return Z_STREAM_ERROR; + } + state = strm.state; + if (state.mode === TYPE) { + state.mode = TYPEDO; + } + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + _in = have; + _out = left; + ret = Z_OK; + inf_leave: + for (; ; ) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if (state.wrap & 2 && hold === 35615) { + state.check = 0; + hbuf[0] = hold & 255; + hbuf[1] = hold >>> 8 & 255; + state.check = crc322(state.check, hbuf, 2, 0); + hold = 0; + bits = 0; + state.mode = FLAGS; + break; + } + state.flags = 0; + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 255) << 8) + (hold >> 8)) % 31) { + strm.msg = "incorrect header check"; + state.mode = BAD; + break; + } + if ((hold & 15) !== Z_DEFLATED) { + strm.msg = "unknown compression method"; + state.mode = BAD; + break; + } + hold >>>= 4; + bits -= 4; + len = (hold & 15) + 8; + if (state.wbits === 0) { + state.wbits = len; + } else if (len > state.wbits) { + strm.msg = "invalid window size"; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + strm.adler = state.check = 1; + state.mode = hold & 512 ? DICTID : TYPE; + hold = 0; + bits = 0; + break; + case FLAGS: + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + state.flags = hold; + if ((state.flags & 255) !== Z_DEFLATED) { + strm.msg = "unknown compression method"; + state.mode = BAD; + break; + } + if (state.flags & 57344) { + strm.msg = "unknown header flags set"; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = hold >> 8 & 1; + } + if (state.flags & 512) { + hbuf[0] = hold & 255; + hbuf[1] = hold >>> 8 & 255; + state.check = crc322(state.check, hbuf, 2, 0); + } + hold = 0; + bits = 0; + state.mode = TIME; + case TIME: + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if (state.head) { + state.head.time = hold; + } + if (state.flags & 512) { + hbuf[0] = hold & 255; + hbuf[1] = hold >>> 8 & 255; + hbuf[2] = hold >>> 16 & 255; + hbuf[3] = hold >>> 24 & 255; + state.check = crc322(state.check, hbuf, 4, 0); + } + hold = 0; + bits = 0; + state.mode = OS; + case OS: + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if (state.head) { + state.head.xflags = hold & 255; + state.head.os = hold >> 8; + } + if (state.flags & 512) { + hbuf[0] = hold & 255; + hbuf[1] = hold >>> 8 & 255; + state.check = crc322(state.check, hbuf, 2, 0); + } + hold = 0; + bits = 0; + state.mode = EXLEN; + case EXLEN: + if (state.flags & 1024) { + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if (state.flags & 512) { + hbuf[0] = hold & 255; + hbuf[1] = hold >>> 8 & 255; + state.check = crc322(state.check, hbuf, 2, 0); + } + hold = 0; + bits = 0; + } else if (state.head) { + state.head.extra = null; + } + state.mode = EXTRA2; + case EXTRA2: + if (state.flags & 1024) { + copy2 = state.length; + if (copy2 > have) { + copy2 = have; + } + if (copy2) { + if (state.head) { + len = state.head.extra_len - state.length; + if (!state.head.extra) { + state.head.extra = new Array(state.head.extra_len); + } + utils.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy2, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + } + if (state.flags & 512) { + state.check = crc322(state.check, input, copy2, next); + } + have -= copy2; + next += copy2; + state.length -= copy2; + } + if (state.length) { + break inf_leave; + } + } + state.length = 0; + state.mode = NAME; + case NAME: + if (state.flags & 2048) { + if (have === 0) { + break inf_leave; + } + copy2 = 0; + do { + len = input[next + copy2++]; + if (state.head && len && state.length < 65536) { + state.head.name += String.fromCharCode(len); + } + } while (len && copy2 < have); + if (state.flags & 512) { + state.check = crc322(state.check, input, copy2, next); + } + have -= copy2; + next += copy2; + if (len) { + break inf_leave; + } + } else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + case COMMENT: + if (state.flags & 4096) { + if (have === 0) { + break inf_leave; + } + copy2 = 0; + do { + len = input[next + copy2++]; + if (state.head && len && state.length < 65536) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy2 < have); + if (state.flags & 512) { + state.check = crc322(state.check, input, copy2, next); + } + have -= copy2; + next += copy2; + if (len) { + break inf_leave; + } + } else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + case HCRC: + if (state.flags & 512) { + while (bits < 16) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if (hold !== (state.check & 65535)) { + strm.msg = "header crc mismatch"; + state.mode = BAD; + break; + } + hold = 0; + bits = 0; + } + if (state.head) { + state.head.hcrc = state.flags >> 9 & 1; + state.head.done = true; + } + strm.adler = state.check = 0; + state.mode = TYPE; + break; + case DICTID: + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + strm.adler = state.check = zswap32(hold); + hold = 0; + bits = 0; + state.mode = DICT; + case DICT: + if (state.havedict === 0) { + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + return Z_NEED_DICT; + } + strm.adler = state.check = 1; + state.mode = TYPE; + case TYPE: + if (flush2 === Z_BLOCK || flush2 === Z_TREES) { + break inf_leave; + } + case TYPEDO: + if (state.last) { + hold >>>= bits & 7; + bits -= bits & 7; + state.mode = CHECK; + break; + } + while (bits < 3) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + state.last = hold & 1; + hold >>>= 1; + bits -= 1; + switch (hold & 3) { + case 0: + state.mode = STORED; + break; + case 1: + fixedtables(state); + state.mode = LEN_; + if (flush2 === Z_TREES) { + hold >>>= 2; + bits -= 2; + break inf_leave; + } + break; + case 2: + state.mode = TABLE; + break; + case 3: + strm.msg = "invalid block type"; + state.mode = BAD; + } + hold >>>= 2; + bits -= 2; + break; + case STORED: + hold >>>= bits & 7; + bits -= bits & 7; + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if ((hold & 65535) !== (hold >>> 16 ^ 65535)) { + strm.msg = "invalid stored block lengths"; + state.mode = BAD; + break; + } + state.length = hold & 65535; + hold = 0; + bits = 0; + state.mode = COPY_; + if (flush2 === Z_TREES) { + break inf_leave; + } + case COPY_: + state.mode = COPY; + case COPY: + copy2 = state.length; + if (copy2) { + if (copy2 > have) { + copy2 = have; + } + if (copy2 > left) { + copy2 = left; + } + if (copy2 === 0) { + break inf_leave; + } + utils.arraySet(output, input, next, copy2, put); + have -= copy2; + next += copy2; + left -= copy2; + put += copy2; + state.length -= copy2; + break; + } + state.mode = TYPE; + break; + case TABLE: + while (bits < 14) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + state.nlen = (hold & 31) + 257; + hold >>>= 5; + bits -= 5; + state.ndist = (hold & 31) + 1; + hold >>>= 5; + bits -= 5; + state.ncode = (hold & 15) + 4; + hold >>>= 4; + bits -= 4; + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = "too many length or distance symbols"; + state.mode = BAD; + break; + } + state.have = 0; + state.mode = LENLENS; + case LENLENS: + while (state.have < state.ncode) { + while (bits < 3) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + state.lens[order[state.have++]] = hold & 7; + hold >>>= 3; + bits -= 3; + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + state.lencode = state.lendyn; + state.lenbits = 7; + opts = { bits: state.lenbits }; + ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + if (ret) { + strm.msg = "invalid code lengths set"; + state.mode = BAD; + break; + } + state.have = 0; + state.mode = CODELENS; + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (; ; ) { + here = state.lencode[hold & (1 << state.lenbits) - 1]; + here_bits = here >>> 24; + here_op = here >>> 16 & 255; + here_val = here & 65535; + if (here_bits <= bits) { + break; + } + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if (here_val < 16) { + hold >>>= here_bits; + bits -= here_bits; + state.lens[state.have++] = here_val; + } else { + if (here_val === 16) { + n = here_bits + 2; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + hold >>>= here_bits; + bits -= here_bits; + if (state.have === 0) { + strm.msg = "invalid bit length repeat"; + state.mode = BAD; + break; + } + len = state.lens[state.have - 1]; + copy2 = 3 + (hold & 3); + hold >>>= 2; + bits -= 2; + } else if (here_val === 17) { + n = here_bits + 3; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + hold >>>= here_bits; + bits -= here_bits; + len = 0; + copy2 = 3 + (hold & 7); + hold >>>= 3; + bits -= 3; + } else { + n = here_bits + 7; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + hold >>>= here_bits; + bits -= here_bits; + len = 0; + copy2 = 11 + (hold & 127); + hold >>>= 7; + bits -= 7; + } + if (state.have + copy2 > state.nlen + state.ndist) { + strm.msg = "invalid bit length repeat"; + state.mode = BAD; + break; + } + while (copy2--) { + state.lens[state.have++] = len; + } + } + } + if (state.mode === BAD) { + break; + } + if (state.lens[256] === 0) { + strm.msg = "invalid code -- missing end-of-block"; + state.mode = BAD; + break; + } + state.lenbits = 9; + opts = { bits: state.lenbits }; + ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + if (ret) { + strm.msg = "invalid literal/lengths set"; + state.mode = BAD; + break; + } + state.distbits = 6; + state.distcode = state.distdyn; + opts = { bits: state.distbits }; + ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + state.distbits = opts.bits; + if (ret) { + strm.msg = "invalid distances set"; + state.mode = BAD; + break; + } + state.mode = LEN_; + if (flush2 === Z_TREES) { + break inf_leave; + } + case LEN_: + state.mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + inflate_fast(strm, _out); + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (; ; ) { + here = state.lencode[hold & (1 << state.lenbits) - 1]; + here_bits = here >>> 24; + here_op = here >>> 16 & 255; + here_val = here & 65535; + if (here_bits <= bits) { + break; + } + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if (here_op && (here_op & 240) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (; ; ) { + here = state.lencode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)]; + here_bits = here >>> 24; + here_op = here >>> 16 & 255; + here_val = here & 65535; + if (last_bits + here_bits <= bits) { + break; + } + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + hold >>>= last_bits; + bits -= last_bits; + state.back += last_bits; + } + hold >>>= here_bits; + bits -= here_bits; + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + state.mode = LIT; + break; + } + if (here_op & 32) { + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = "invalid literal/length code"; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + case LENEXT: + if (state.extra) { + n = state.extra; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + state.length += hold & (1 << state.extra) - 1; + hold >>>= state.extra; + bits -= state.extra; + state.back += state.extra; + } + state.was = state.length; + state.mode = DIST; + case DIST: + for (; ; ) { + here = state.distcode[hold & (1 << state.distbits) - 1]; + here_bits = here >>> 24; + here_op = here >>> 16 & 255; + here_val = here & 65535; + if (here_bits <= bits) { + break; + } + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if ((here_op & 240) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (; ; ) { + here = state.distcode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)]; + here_bits = here >>> 24; + here_op = here >>> 16 & 255; + here_val = here & 65535; + if (last_bits + here_bits <= bits) { + break; + } + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + hold >>>= last_bits; + bits -= last_bits; + state.back += last_bits; + } + hold >>>= here_bits; + bits -= here_bits; + state.back += here_bits; + if (here_op & 64) { + strm.msg = "invalid distance code"; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = here_op & 15; + state.mode = DISTEXT; + case DISTEXT: + if (state.extra) { + n = state.extra; + while (bits < n) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + state.offset += hold & (1 << state.extra) - 1; + hold >>>= state.extra; + bits -= state.extra; + state.back += state.extra; + } + if (state.offset > state.dmax) { + strm.msg = "invalid distance too far back"; + state.mode = BAD; + break; + } + state.mode = MATCH; + case MATCH: + if (left === 0) { + break inf_leave; + } + copy2 = _out - left; + if (state.offset > copy2) { + copy2 = state.offset - copy2; + if (copy2 > state.whave) { + if (state.sane) { + strm.msg = "invalid distance too far back"; + state.mode = BAD; + break; + } + } + if (copy2 > state.wnext) { + copy2 -= state.wnext; + from = state.wsize - copy2; + } else { + from = state.wnext - copy2; + } + if (copy2 > state.length) { + copy2 = state.length; + } + from_source = state.window; + } else { + from_source = output; + from = put - state.offset; + copy2 = state.length; + } + if (copy2 > left) { + copy2 = left; + } + left -= copy2; + state.length -= copy2; + do { + output[put++] = from_source[from++]; + } while (--copy2); + if (state.length === 0) { + state.mode = LEN; + } + break; + case LIT: + if (left === 0) { + break inf_leave; + } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold |= input[next++] << bits; + bits += 8; + } + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = /*UPDATE(state.check, put - _out, _out);*/ + state.flags ? crc322(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out); + } + _out = left; + if ((state.flags ? hold : zswap32(hold)) !== state.check) { + strm.msg = "incorrect data check"; + state.mode = BAD; + break; + } + hold = 0; + bits = 0; + } + state.mode = LENGTH; + case LENGTH: + if (state.wrap && state.flags) { + while (bits < 32) { + if (have === 0) { + break inf_leave; + } + have--; + hold += input[next++] << bits; + bits += 8; + } + if (hold !== (state.total & 4294967295)) { + strm.msg = "incorrect length check"; + state.mode = BAD; + break; + } + hold = 0; + bits = 0; + } + state.mode = DONE; + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + } + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + if (state.wsize || _out !== strm.avail_out && state.mode < BAD && (state.mode < CHECK || flush2 !== Z_FINISH)) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { + state.mode = MEM; + return Z_MEM_ERROR; + } + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ + state.flags ? crc322(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + (state.mode === TYPE ? 128 : 0) + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if ((_in === 0 && _out === 0 || flush2 === Z_FINISH) && ret === Z_OK) { + ret = Z_BUF_ERROR; + } + return ret; + } + function inflateEnd(strm) { + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + var state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK; + } + function inflateGetHeader(strm, head) { + var state; + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + if ((state.wrap & 2) === 0) { + return Z_STREAM_ERROR; + } + state.head = head; + head.done = false; + return Z_OK; + } + function inflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + var state; + var dictid; + var ret; + if (!strm || !strm.state) { + return Z_STREAM_ERROR; + } + state = strm.state; + if (state.wrap !== 0 && state.mode !== DICT) { + return Z_STREAM_ERROR; + } + if (state.mode === DICT) { + dictid = 1; + dictid = adler32(dictid, dictionary, dictLength, 0); + if (dictid !== state.check) { + return Z_DATA_ERROR; + } + } + ret = updatewindow(strm, dictionary, dictLength, dictLength); + if (ret) { + state.mode = MEM; + return Z_MEM_ERROR; + } + state.havedict = 1; + return Z_OK; + } + exports2.inflateReset = inflateReset; + exports2.inflateReset2 = inflateReset2; + exports2.inflateResetKeep = inflateResetKeep; + exports2.inflateInit = inflateInit; + exports2.inflateInit2 = inflateInit2; + exports2.inflate = inflate2; + exports2.inflateEnd = inflateEnd; + exports2.inflateGetHeader = inflateGetHeader; + exports2.inflateSetDictionary = inflateSetDictionary; + exports2.inflateInfo = "pako inflate (from Nodeca project)"; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/constants.js +var require_constants = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/constants.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + module2.exports = { + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + //Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + /* The deflate compression method */ + Z_DEFLATED: 8 + //Z_NULL: null // Use -1 or null inline, depending on var type + }; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/gzheader.js +var require_gzheader = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/zlib/gzheader.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + function GZheader() { + this.text = 0; + this.time = 0; + this.xflags = 0; + this.os = 0; + this.extra = null; + this.extra_len = 0; + this.name = ""; + this.comment = ""; + this.hcrc = 0; + this.done = false; + } + module2.exports = GZheader; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/inflate.js +var require_inflate2 = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/lib/inflate.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var zlib_inflate = require_inflate(); + var utils = require_common(); + var strings = require_strings(); + var c = require_constants(); + var msg = require_messages(); + var ZStream = require_zstream(); + var GZheader = require_gzheader(); + var toString = Object.prototype.toString; + function Inflate(options) { + if (!(this instanceof Inflate)) + return new Inflate(options); + this.options = utils.assign({ + chunkSize: 16384, + windowBits: 0, + to: "" + }, options || {}); + var opt = this.options; + if (opt.raw && opt.windowBits >= 0 && opt.windowBits < 16) { + opt.windowBits = -opt.windowBits; + if (opt.windowBits === 0) { + opt.windowBits = -15; + } + } + if (opt.windowBits >= 0 && opt.windowBits < 16 && !(options && options.windowBits)) { + opt.windowBits += 32; + } + if (opt.windowBits > 15 && opt.windowBits < 48) { + if ((opt.windowBits & 15) === 0) { + opt.windowBits |= 15; + } + } + this.err = 0; + this.msg = ""; + this.ended = false; + this.chunks = []; + this.strm = new ZStream(); + this.strm.avail_out = 0; + var status2 = zlib_inflate.inflateInit2( + this.strm, + opt.windowBits + ); + if (status2 !== c.Z_OK) { + throw new Error(msg[status2]); + } + this.header = new GZheader(); + zlib_inflate.inflateGetHeader(this.strm, this.header); + if (opt.dictionary) { + if (typeof opt.dictionary === "string") { + opt.dictionary = strings.string2buf(opt.dictionary); + } else if (toString.call(opt.dictionary) === "[object ArrayBuffer]") { + opt.dictionary = new Uint8Array(opt.dictionary); + } + if (opt.raw) { + status2 = zlib_inflate.inflateSetDictionary(this.strm, opt.dictionary); + if (status2 !== c.Z_OK) { + throw new Error(msg[status2]); + } + } + } + } + Inflate.prototype.push = function(data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var dictionary = this.options.dictionary; + var status2, _mode; + var next_out_utf8, tail, utf8str; + var allowBufError = false; + if (this.ended) { + return false; + } + _mode = mode === ~~mode ? mode : mode === true ? c.Z_FINISH : c.Z_NO_FLUSH; + if (typeof data === "string") { + strm.input = strings.binstring2buf(data); + } else if (toString.call(data) === "[object ArrayBuffer]") { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } + strm.next_in = 0; + strm.avail_in = strm.input.length; + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + status2 = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); + if (status2 === c.Z_NEED_DICT && dictionary) { + status2 = zlib_inflate.inflateSetDictionary(this.strm, dictionary); + } + if (status2 === c.Z_BUF_ERROR && allowBufError === true) { + status2 = c.Z_OK; + allowBufError = false; + } + if (status2 !== c.Z_STREAM_END && status2 !== c.Z_OK) { + this.onEnd(status2); + this.ended = true; + return false; + } + if (strm.next_out) { + if (strm.avail_out === 0 || status2 === c.Z_STREAM_END || strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH)) { + if (this.options.to === "string") { + next_out_utf8 = strings.utf8border(strm.output, strm.next_out); + tail = strm.next_out - next_out_utf8; + utf8str = strings.buf2string(strm.output, next_out_utf8); + strm.next_out = tail; + strm.avail_out = chunkSize - tail; + if (tail) { + utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); + } + this.onData(utf8str); + } else { + this.onData(utils.shrinkBuf(strm.output, strm.next_out)); + } + } + } + if (strm.avail_in === 0 && strm.avail_out === 0) { + allowBufError = true; + } + } while ((strm.avail_in > 0 || strm.avail_out === 0) && status2 !== c.Z_STREAM_END); + if (status2 === c.Z_STREAM_END) { + _mode = c.Z_FINISH; + } + if (_mode === c.Z_FINISH) { + status2 = zlib_inflate.inflateEnd(this.strm); + this.onEnd(status2); + this.ended = true; + return status2 === c.Z_OK; + } + if (_mode === c.Z_SYNC_FLUSH) { + this.onEnd(c.Z_OK); + strm.avail_out = 0; + return true; + } + return true; + }; + Inflate.prototype.onData = function(chunk) { + this.chunks.push(chunk); + }; + Inflate.prototype.onEnd = function(status2) { + if (status2 === c.Z_OK) { + if (this.options.to === "string") { + this.result = this.chunks.join(""); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status2; + this.msg = this.strm.msg; + }; + function inflate2(input, options) { + var inflator = new Inflate(options); + inflator.push(input, true); + if (inflator.err) { + throw inflator.msg || msg[inflator.err]; + } + return inflator.result; + } + function inflateRaw(input, options) { + options = options || {}; + options.raw = true; + return inflate2(input, options); + } + exports2.Inflate = Inflate; + exports2.inflate = inflate2; + exports2.inflateRaw = inflateRaw; + exports2.ungzip = inflate2; + } +}); + +// node_modules/.pnpm/pako@1.0.11/node_modules/pako/index.js +var require_pako = __commonJS({ + "node_modules/.pnpm/pako@1.0.11/node_modules/pako/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var assign2 = require_common().assign; + var deflate2 = require_deflate2(); + var inflate2 = require_inflate2(); + var constants = require_constants(); + var pako2 = {}; + assign2(pako2, deflate2, inflate2, constants); + module2.exports = pako2; + } +}); + +// node_modules/.pnpm/pify@4.0.1/node_modules/pify/index.js +var require_pify = __commonJS({ + "node_modules/.pnpm/pify@4.0.1/node_modules/pify/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var processFn = (fn, options) => function(...args) { + const P = options.promiseModule; + return new P((resolve, reject) => { + if (options.multiArgs) { + args.push((...result) => { + if (options.errorFirst) { + if (result[0]) { + reject(result); + } else { + result.shift(); + resolve(result); + } + } else { + resolve(result); + } + }); + } else if (options.errorFirst) { + args.push((error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + } else { + args.push(resolve); + } + fn.apply(this, args); + }); + }; + module2.exports = (input, options) => { + options = Object.assign({ + exclude: [/.+(Sync|Stream)$/], + errorFirst: true, + promiseModule: Promise + }, options); + const objType = typeof input; + if (!(input !== null && (objType === "object" || objType === "function"))) { + throw new TypeError(`Expected \`input\` to be a \`Function\` or \`Object\`, got \`${input === null ? "null" : objType}\``); + } + const filter = (key2) => { + const match = (pattern) => typeof pattern === "string" ? key2 === pattern : pattern.test(key2); + return options.include ? options.include.some(match) : !options.exclude.some(match); + }; + let ret; + if (objType === "function") { + ret = function(...args) { + return options.excludeMain ? input(...args) : processFn(input, options).apply(this, args); + }; + } else { + ret = Object.create(Object.getPrototypeOf(input)); + } + for (const key2 in input) { + const property = input[key2]; + ret[key2] = typeof property === "function" && filter(key2) ? processFn(property, options) : property; + } + return ret; + }; + } +}); + +// node_modules/.pnpm/ignore@5.2.4/node_modules/ignore/index.js +var require_ignore = __commonJS({ + "node_modules/.pnpm/ignore@5.2.4/node_modules/ignore/index.js"(exports2, module2) { + init_polyfill_buffer(); + function makeArray(subject) { + return Array.isArray(subject) ? subject : [subject]; + } + var EMPTY = ""; + var SPACE = " "; + var ESCAPE = "\\"; + var REGEX_TEST_BLANK_LINE = /^\s+$/; + var REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/; + var REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/; + var REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/; + var REGEX_SPLITALL_CRLF = /\r?\n/g; + var REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/; + var SLASH = "/"; + var TMP_KEY_IGNORE = "node-ignore"; + if (typeof Symbol !== "undefined") { + TMP_KEY_IGNORE = Symbol.for("node-ignore"); + } + var KEY_IGNORE = TMP_KEY_IGNORE; + var define2 = (object, key2, value) => Object.defineProperty(object, key2, { value }); + var REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g; + var RETURN_FALSE = () => false; + var sanitizeRange = (range) => range.replace( + REGEX_REGEXP_RANGE, + (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) ? match : EMPTY + ); + var cleanRangeBackSlash = (slashes) => { + const { length } = slashes; + return slashes.slice(0, length - length % 2); + }; + var REPLACERS = [ + // > Trailing spaces are ignored unless they are quoted with backslash ("\") + [ + // (a\ ) -> (a ) + // (a ) -> (a) + // (a \ ) -> (a ) + /\\?\s+$/, + (match) => match.indexOf("\\") === 0 ? SPACE : EMPTY + ], + // replace (\ ) with ' ' + [ + /\\\s/g, + () => SPACE + ], + // Escape metacharacters + // which is written down by users but means special for regular expressions. + // > There are 12 characters with special meanings: + // > - the backslash \, + // > - the caret ^, + // > - the dollar sign $, + // > - the period or dot ., + // > - the vertical bar or pipe symbol |, + // > - the question mark ?, + // > - the asterisk or star *, + // > - the plus sign +, + // > - the opening parenthesis (, + // > - the closing parenthesis ), + // > - and the opening square bracket [, + // > - the opening curly brace {, + // > These special characters are often called "metacharacters". + [ + /[\\$.|*+(){^]/g, + (match) => `\\${match}` + ], + [ + // > a question mark (?) matches a single character + /(?!\\)\?/g, + () => "[^/]" + ], + // leading slash + [ + // > A leading slash matches the beginning of the pathname. + // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". + // A leading slash matches the beginning of the pathname + /^\//, + () => "^" + ], + // replace special metacharacter slash after the leading slash + [ + /\//g, + () => "\\/" + ], + [ + // > A leading "**" followed by a slash means match in all directories. + // > For example, "**/foo" matches file or directory "foo" anywhere, + // > the same as pattern "foo". + // > "**/foo/bar" matches file or directory "bar" anywhere that is directly + // > under directory "foo". + // Notice that the '*'s have been replaced as '\\*' + /^\^*\\\*\\\*\\\//, + // '**/foo' <-> 'foo' + () => "^(?:.*\\/)?" + ], + // starting + [ + // there will be no leading '/' + // (which has been replaced by section "leading slash") + // If starts with '**', adding a '^' to the regular expression also works + /^(?=[^^])/, + function startingReplacer() { + return !/\/(?!$)/.test(this) ? "(?:^|\\/)" : "^"; + } + ], + // two globstars + [ + // Use lookahead assertions so that we could match more than one `'/**'` + /\\\/\\\*\\\*(?=\\\/|$)/g, + // Zero, one or several directories + // should not use '*', or it will be replaced by the next replacer + // Check if it is not the last `'/**'` + (_, index2, str) => index2 + 6 < str.length ? "(?:\\/[^\\/]+)*" : "\\/.+" + ], + // normal intermediate wildcards + [ + // Never replace escaped '*' + // ignore rule '\*' will match the path '*' + // 'abc.*/' -> go + // 'abc.*' -> skip this rule, + // coz trailing single wildcard will be handed by [trailing wildcard] + /(^|[^\\]+)(\\\*)+(?=.+)/g, + // '*.js' matches '.js' + // '*.js' doesn't match 'abc' + (_, p1, p2) => { + const unescaped = p2.replace(/\\\*/g, "[^\\/]*"); + return p1 + unescaped; + } + ], + [ + // unescape, revert step 3 except for back slash + // For example, if a user escape a '\\*', + // after step 3, the result will be '\\\\\\*' + /\\\\\\(?=[$.|*+(){^])/g, + () => ESCAPE + ], + [ + // '\\\\' -> '\\' + /\\\\/g, + () => ESCAPE + ], + [ + // > The range notation, e.g. [a-zA-Z], + // > can be used to match one of the characters in a range. + // `\` is escaped by step 3 + /(\\)?\[([^\]/]*?)(\\*)($|\])/g, + (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` : close === "]" ? endEscape.length % 2 === 0 ? `[${sanitizeRange(range)}${endEscape}]` : "[]" : "[]" + ], + // ending + [ + // 'js' will not match 'js.' + // 'ab' will not match 'abc' + /(?:[^*])$/, + // WTF! + // https://git-scm.com/docs/gitignore + // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) + // which re-fixes #24, #38 + // > If there is a separator at the end of the pattern then the pattern + // > will only match directories, otherwise the pattern can match both + // > files and directories. + // 'js*' will not match 'a.js' + // 'js/' will not match 'a.js' + // 'js' will match 'a.js' and 'a.js/' + (match) => /\/$/.test(match) ? `${match}$` : `${match}(?=$|\\/$)` + ], + // trailing wildcard + [ + /(\^|\\\/)?\\\*$/, + (_, p1) => { + const prefix = p1 ? `${p1}[^/]+` : "[^/]*"; + return `${prefix}(?=$|\\/$)`; + } + ] + ]; + var regexCache = /* @__PURE__ */ Object.create(null); + var makeRegex = (pattern, ignoreCase) => { + let source = regexCache[pattern]; + if (!source) { + source = REPLACERS.reduce( + (prev, current) => prev.replace(current[0], current[1].bind(pattern)), + pattern + ); + regexCache[pattern] = source; + } + return ignoreCase ? new RegExp(source, "i") : new RegExp(source); + }; + var isString = (subject) => typeof subject === "string"; + var checkPattern = (pattern) => pattern && isString(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern) && pattern.indexOf("#") !== 0; + var splitPattern = (pattern) => pattern.split(REGEX_SPLITALL_CRLF); + var IgnoreRule = class { + constructor(origin, pattern, negative, regex2) { + this.origin = origin; + this.pattern = pattern; + this.negative = negative; + this.regex = regex2; + } + }; + var createRule = (pattern, ignoreCase) => { + const origin = pattern; + let negative = false; + if (pattern.indexOf("!") === 0) { + negative = true; + pattern = pattern.substr(1); + } + pattern = pattern.replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, "!").replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, "#"); + const regex2 = makeRegex(pattern, ignoreCase); + return new IgnoreRule( + origin, + pattern, + negative, + regex2 + ); + }; + var throwError = (message, Ctor) => { + throw new Ctor(message); + }; + var checkPath = (path2, originalPath, doThrow) => { + if (!isString(path2)) { + return doThrow( + `path must be a string, but got \`${originalPath}\``, + TypeError + ); + } + if (!path2) { + return doThrow(`path must not be empty`, TypeError); + } + if (checkPath.isNotRelative(path2)) { + const r = "`path.relative()`d"; + return doThrow( + `path should be a ${r} string, but got "${originalPath}"`, + RangeError + ); + } + return true; + }; + var isNotRelative = (path2) => REGEX_TEST_INVALID_PATH.test(path2); + checkPath.isNotRelative = isNotRelative; + checkPath.convert = (p) => p; + var Ignore = class { + constructor({ + ignorecase = true, + ignoreCase = ignorecase, + allowRelativePaths = false + } = {}) { + define2(this, KEY_IGNORE, true); + this._rules = []; + this._ignoreCase = ignoreCase; + this._allowRelativePaths = allowRelativePaths; + this._initCache(); + } + _initCache() { + this._ignoreCache = /* @__PURE__ */ Object.create(null); + this._testCache = /* @__PURE__ */ Object.create(null); + } + _addPattern(pattern) { + if (pattern && pattern[KEY_IGNORE]) { + this._rules = this._rules.concat(pattern._rules); + this._added = true; + return; + } + if (checkPattern(pattern)) { + const rule = createRule(pattern, this._ignoreCase); + this._added = true; + this._rules.push(rule); + } + } + // @param {Array | string | Ignore} pattern + add(pattern) { + this._added = false; + makeArray( + isString(pattern) ? splitPattern(pattern) : pattern + ).forEach(this._addPattern, this); + if (this._added) { + this._initCache(); + } + return this; + } + // legacy + addPattern(pattern) { + return this.add(pattern); + } + // | ignored : unignored + // negative | 0:0 | 0:1 | 1:0 | 1:1 + // -------- | ------- | ------- | ------- | -------- + // 0 | TEST | TEST | SKIP | X + // 1 | TESTIF | SKIP | TEST | X + // - SKIP: always skip + // - TEST: always test + // - TESTIF: only test if checkUnignored + // - X: that never happen + // @param {boolean} whether should check if the path is unignored, + // setting `checkUnignored` to `false` could reduce additional + // path matching. + // @returns {TestResult} true if a file is ignored + _testOne(path2, checkUnignored) { + let ignored = false; + let unignored = false; + this._rules.forEach((rule) => { + const { negative } = rule; + if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) { + return; + } + const matched = rule.regex.test(path2); + if (matched) { + ignored = !negative; + unignored = negative; + } + }); + return { + ignored, + unignored + }; + } + // @returns {TestResult} + _test(originalPath, cache, checkUnignored, slices) { + const path2 = originalPath && checkPath.convert(originalPath); + checkPath( + path2, + originalPath, + this._allowRelativePaths ? RETURN_FALSE : throwError + ); + return this._t(path2, cache, checkUnignored, slices); + } + _t(path2, cache, checkUnignored, slices) { + if (path2 in cache) { + return cache[path2]; + } + if (!slices) { + slices = path2.split(SLASH); + } + slices.pop(); + if (!slices.length) { + return cache[path2] = this._testOne(path2, checkUnignored); + } + const parent = this._t( + slices.join(SLASH) + SLASH, + cache, + checkUnignored, + slices + ); + return cache[path2] = parent.ignored ? parent : this._testOne(path2, checkUnignored); + } + ignores(path2) { + return this._test(path2, this._ignoreCache, false).ignored; + } + createFilter() { + return (path2) => !this.ignores(path2); + } + filter(paths) { + return makeArray(paths).filter(this.createFilter()); + } + // @returns {TestResult} + test(path2) { + return this._test(path2, this._testCache, true); + } + }; + var factory = (options) => new Ignore(options); + var isPathValid = (path2) => checkPath(path2 && checkPath.convert(path2), path2, RETURN_FALSE); + factory.isPathValid = isPathValid; + factory.default = factory; + module2.exports = factory; + if ( + // Detect `process` so that it can run in browsers. + typeof process !== "undefined" && (process.env && process.env.IGNORE_TEST_WIN32 || process.platform === "win32") + ) { + const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/"); + checkPath.convert = makePosix; + const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i; + checkPath.isNotRelative = (path2) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path2) || isNotRelative(path2); + } + } +}); + +// node_modules/.pnpm/clean-git-ref@2.0.1/node_modules/clean-git-ref/lib/index.js +var require_lib2 = __commonJS({ + "node_modules/.pnpm/clean-git-ref@2.0.1/node_modules/clean-git-ref/lib/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + } + function replaceAll(str, search, replacement) { + search = search instanceof RegExp ? search : new RegExp(escapeRegExp(search), "g"); + return str.replace(search, replacement); + } + var CleanGitRef = { + clean: function clean(value) { + if (typeof value !== "string") { + throw new Error("Expected a string, received: " + value); + } + value = replaceAll(value, "./", "/"); + value = replaceAll(value, "..", "."); + value = replaceAll(value, " ", "-"); + value = replaceAll(value, /^[~^:?*\\\-]/g, ""); + value = replaceAll(value, /[~^:?*\\]/g, "-"); + value = replaceAll(value, /[~^:?*\\\-]$/g, ""); + value = replaceAll(value, "@{", "-"); + value = replaceAll(value, /\.$/g, ""); + value = replaceAll(value, /\/$/g, ""); + value = replaceAll(value, /\.lock$/g, ""); + return value; + } + }; + module2.exports = CleanGitRef; + } +}); + +// node_modules/.pnpm/diff3@0.0.3/node_modules/diff3/onp.js +var require_onp = __commonJS({ + "node_modules/.pnpm/diff3@0.0.3/node_modules/diff3/onp.js"(exports2, module2) { + init_polyfill_buffer(); + module2.exports = function(a_, b_) { + var a = a_, b = b_, m = a.length, n = b.length, reverse = false, ed = null, offset = m + 1, path2 = [], pathposi = [], ses = [], lcs = "", SES_DELETE = -1, SES_COMMON = 0, SES_ADD = 1; + var tmp1, tmp2; + var init3 = function() { + if (m >= n) { + tmp1 = a; + tmp2 = m; + a = b; + b = tmp1; + m = n; + n = tmp2; + reverse = true; + offset = m + 1; + } + }; + var P = function(x, y, k) { + return { + "x": x, + "y": y, + "k": k + }; + }; + var seselem = function(elem, t) { + return { + "elem": elem, + "t": t + }; + }; + var snake = function(k, p, pp) { + var r, x, y; + if (p > pp) { + r = path2[k - 1 + offset]; + } else { + r = path2[k + 1 + offset]; + } + y = Math.max(p, pp); + x = y - k; + while (x < m && y < n && a[x] === b[y]) { + ++x; + ++y; + } + path2[k + offset] = pathposi.length; + pathposi[pathposi.length] = new P(x, y, r); + return y; + }; + var recordseq = function(epc) { + var x_idx, y_idx, px_idx, py_idx, i; + x_idx = y_idx = 1; + px_idx = py_idx = 0; + for (i = epc.length - 1; i >= 0; --i) { + while (px_idx < epc[i].x || py_idx < epc[i].y) { + if (epc[i].y - epc[i].x > py_idx - px_idx) { + if (reverse) { + ses[ses.length] = new seselem(b[py_idx], SES_DELETE); + } else { + ses[ses.length] = new seselem(b[py_idx], SES_ADD); + } + ++y_idx; + ++py_idx; + } else if (epc[i].y - epc[i].x < py_idx - px_idx) { + if (reverse) { + ses[ses.length] = new seselem(a[px_idx], SES_ADD); + } else { + ses[ses.length] = new seselem(a[px_idx], SES_DELETE); + } + ++x_idx; + ++px_idx; + } else { + ses[ses.length] = new seselem(a[px_idx], SES_COMMON); + lcs += a[px_idx]; + ++x_idx; + ++y_idx; + ++px_idx; + ++py_idx; + } + } + } + }; + init3(); + return { + SES_DELETE: -1, + SES_COMMON: 0, + SES_ADD: 1, + editdistance: function() { + return ed; + }, + getlcs: function() { + return lcs; + }, + getses: function() { + return ses; + }, + compose: function() { + var delta, size, fp, p, r, epc, i, k; + delta = n - m; + size = m + n + 3; + fp = {}; + for (i = 0; i < size; ++i) { + fp[i] = -1; + path2[i] = -1; + } + p = -1; + do { + ++p; + for (k = -p; k <= delta - 1; ++k) { + fp[k + offset] = snake(k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } + for (k = delta + p; k >= delta + 1; --k) { + fp[k + offset] = snake(k, fp[k - 1 + offset] + 1, fp[k + 1 + offset]); + } + fp[delta + offset] = snake(delta, fp[delta - 1 + offset] + 1, fp[delta + 1 + offset]); + } while (fp[delta + offset] !== n); + ed = delta + 2 * p; + r = path2[delta + offset]; + epc = []; + while (r !== -1) { + epc[epc.length] = new P(pathposi[r].x, pathposi[r].y, null); + r = pathposi[r].k; + } + recordseq(epc); + } + }; + }; + } +}); + +// node_modules/.pnpm/diff3@0.0.3/node_modules/diff3/diff3.js +var require_diff3 = __commonJS({ + "node_modules/.pnpm/diff3@0.0.3/node_modules/diff3/diff3.js"(exports2, module2) { + init_polyfill_buffer(); + var onp = require_onp(); + function longestCommonSubsequence(file1, file2) { + var diff2 = new onp(file1, file2); + diff2.compose(); + var ses = diff2.getses(); + var root2; + var prev; + var file1RevIdx = file1.length - 1, file2RevIdx = file2.length - 1; + for (var i = ses.length - 1; i >= 0; --i) { + if (ses[i].t === diff2.SES_COMMON) { + if (prev) { + prev.chain = { + file1index: file1RevIdx, + file2index: file2RevIdx, + chain: null + }; + prev = prev.chain; + } else { + root2 = { + file1index: file1RevIdx, + file2index: file2RevIdx, + chain: null + }; + prev = root2; + } + file1RevIdx--; + file2RevIdx--; + } else if (ses[i].t === diff2.SES_DELETE) { + file1RevIdx--; + } else if (ses[i].t === diff2.SES_ADD) { + file2RevIdx--; + } + } + var tail = { + file1index: -1, + file2index: -1, + chain: null + }; + if (!prev) { + return tail; + } + prev.chain = tail; + return root2; + } + function diffIndices(file1, file2) { + var result = []; + var tail1 = file1.length; + var tail2 = file2.length; + for (var candidate = longestCommonSubsequence(file1, file2); candidate !== null; candidate = candidate.chain) { + var mismatchLength1 = tail1 - candidate.file1index - 1; + var mismatchLength2 = tail2 - candidate.file2index - 1; + tail1 = candidate.file1index; + tail2 = candidate.file2index; + if (mismatchLength1 || mismatchLength2) { + result.push({ + file1: [tail1 + 1, mismatchLength1], + file2: [tail2 + 1, mismatchLength2] + }); + } + } + result.reverse(); + return result; + } + function diff3MergeIndices(a, o, b) { + var i; + var m1 = diffIndices(o, a); + var m2 = diffIndices(o, b); + var hunks = []; + function addHunk(h, side2) { + hunks.push([h.file1[0], side2, h.file1[1], h.file2[0], h.file2[1]]); + } + for (i = 0; i < m1.length; i++) { + addHunk(m1[i], 0); + } + for (i = 0; i < m2.length; i++) { + addHunk(m2[i], 2); + } + hunks.sort(function(x, y) { + return x[0] - y[0]; + }); + var result = []; + var commonOffset = 0; + function copyCommon(targetOffset) { + if (targetOffset > commonOffset) { + result.push([1, commonOffset, targetOffset - commonOffset]); + commonOffset = targetOffset; + } + } + for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) { + var firstHunkIndex = hunkIndex; + var hunk = hunks[hunkIndex]; + var regionLhs = hunk[0]; + var regionRhs = regionLhs + hunk[2]; + while (hunkIndex < hunks.length - 1) { + var maybeOverlapping = hunks[hunkIndex + 1]; + var maybeLhs = maybeOverlapping[0]; + if (maybeLhs > regionRhs) + break; + regionRhs = Math.max(regionRhs, maybeLhs + maybeOverlapping[2]); + hunkIndex++; + } + copyCommon(regionLhs); + if (firstHunkIndex == hunkIndex) { + if (hunk[4] > 0) { + result.push([hunk[1], hunk[3], hunk[4]]); + } + } else { + var regions = { + 0: [a.length, -1, o.length, -1], + 2: [b.length, -1, o.length, -1] + }; + for (i = firstHunkIndex; i <= hunkIndex; i++) { + hunk = hunks[i]; + var side = hunk[1]; + var r = regions[side]; + var oLhs = hunk[0]; + var oRhs = oLhs + hunk[2]; + var abLhs = hunk[3]; + var abRhs = abLhs + hunk[4]; + r[0] = Math.min(abLhs, r[0]); + r[1] = Math.max(abRhs, r[1]); + r[2] = Math.min(oLhs, r[2]); + r[3] = Math.max(oRhs, r[3]); + } + var aLhs = regions[0][0] + (regionLhs - regions[0][2]); + var aRhs = regions[0][1] + (regionRhs - regions[0][3]); + var bLhs = regions[2][0] + (regionLhs - regions[2][2]); + var bRhs = regions[2][1] + (regionRhs - regions[2][3]); + result.push([ + -1, + aLhs, + aRhs - aLhs, + regionLhs, + regionRhs - regionLhs, + bLhs, + bRhs - bLhs + ]); + } + commonOffset = regionRhs; + } + copyCommon(o.length); + return result; + } + function diff3Merge2(a, o, b) { + var result = []; + var files = [a, o, b]; + var indices = diff3MergeIndices(a, o, b); + var okLines = []; + function flushOk() { + if (okLines.length) { + result.push({ + ok: okLines + }); + } + okLines = []; + } + function pushOk(xs) { + for (var j = 0; j < xs.length; j++) { + okLines.push(xs[j]); + } + } + function isTrueConflict(rec) { + if (rec[2] != rec[6]) + return true; + var aoff = rec[1]; + var boff = rec[5]; + for (var j = 0; j < rec[2]; j++) { + if (a[j + aoff] != b[j + boff]) + return true; + } + return false; + } + for (var i = 0; i < indices.length; i++) { + var x = indices[i]; + var side = x[0]; + if (side == -1) { + if (!isTrueConflict(x)) { + pushOk(files[0].slice(x[1], x[1] + x[2])); + } else { + flushOk(); + result.push({ + conflict: { + a: a.slice(x[1], x[1] + x[2]), + aIndex: x[1], + o: o.slice(x[3], x[3] + x[4]), + oIndex: x[3], + b: b.slice(x[5], x[5] + x[6]), + bIndex: x[5] + } + }); + } + } else { + pushOk(files[side].slice(x[1], x[1] + x[2])); + } + } + flushOk(); + return result; + } + module2.exports = diff3Merge2; + } +}); + +// node_modules/.pnpm/ms@2.1.2/node_modules/ms/index.js +var require_ms = __commonJS({ + "node_modules/.pnpm/ms@2.1.2/node_modules/ms/index.js"(exports2, module2) { + init_polyfill_buffer(); + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var w = d * 7; + var y = d * 365.25; + module2.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse2(val); + } else if (type === "number" && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); + }; + function parse2(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "weeks": + case "week": + case "w": + return n * w; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + "d"; + } + if (msAbs >= h) { + return Math.round(ms / h) + "h"; + } + if (msAbs >= m) { + return Math.round(ms / m) + "m"; + } + if (msAbs >= s) { + return Math.round(ms / s) + "s"; + } + return ms + "ms"; + } + function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, "day"); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, "hour"); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, "minute"); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, "second"); + } + return ms + " ms"; + } + function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + " " + name + (isPlural ? "s" : ""); + } + } +}); + +// node_modules/.pnpm/debug@4.3.4_supports-color@7.2.0/node_modules/debug/src/common.js +var require_common2 = __commonJS({ + "node_modules/.pnpm/debug@4.3.4_supports-color@7.2.0/node_modules/debug/src/common.js"(exports2, module2) { + init_polyfill_buffer(); + function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require_ms(); + createDebug.destroy = destroy; + Object.keys(env).forEach((key2) => { + createDebug[key2] = env[key2]; + }); + createDebug.names = []; + createDebug.skips = []; + createDebug.formatters = {}; + function selectColor(namespace) { + let hash2 = 0; + for (let i = 0; i < namespace.length; i++) { + hash2 = (hash2 << 5) - hash2 + namespace.charCodeAt(i); + hash2 |= 0; + } + return createDebug.colors[Math.abs(hash2) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; + function createDebug(namespace) { + let prevTime; + let enableOverride = null; + let namespacesCache; + let enabledCache; + function debug3(...args) { + if (!debug3.enabled) { + return; + } + const self2 = debug3; + const curr = Number(/* @__PURE__ */ new Date()); + const ms = curr - (prevTime || curr); + self2.diff = ms; + self2.prev = prevTime; + self2.curr = curr; + prevTime = curr; + args[0] = createDebug.coerce(args[0]); + if (typeof args[0] !== "string") { + args.unshift("%O"); + } + let index2 = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + if (match === "%%") { + return "%"; + } + index2++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === "function") { + const val = args[index2]; + match = formatter.call(self2, val); + args.splice(index2, 1); + index2--; + } + return match; + }); + createDebug.formatArgs.call(self2, args); + const logFn = self2.log || createDebug.log; + logFn.apply(self2, args); + } + debug3.namespace = namespace; + debug3.useColors = createDebug.useColors(); + debug3.color = createDebug.selectColor(namespace); + debug3.extend = extend; + debug3.destroy = createDebug.destroy; + Object.defineProperty(debug3, "enabled", { + enumerable: true, + configurable: false, + get: () => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + return enabledCache; + }, + set: (v) => { + enableOverride = v; + } + }); + if (typeof createDebug.init === "function") { + createDebug.init(debug3); + } + return debug3; + } + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.namespaces = namespaces; + createDebug.names = []; + createDebug.skips = []; + let i; + const split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/); + const len = split.length; + for (i = 0; i < len; i++) { + if (!split[i]) { + continue; + } + namespaces = split[i].replace(/\*/g, ".*?"); + if (namespaces[0] === "-") { + createDebug.skips.push(new RegExp("^" + namespaces.slice(1) + "$")); + } else { + createDebug.names.push(new RegExp("^" + namespaces + "$")); + } + } + } + function disable() { + const namespaces = [ + ...createDebug.names.map(toNamespace), + ...createDebug.skips.map(toNamespace).map((namespace) => "-" + namespace) + ].join(","); + createDebug.enable(""); + return namespaces; + } + function enabled(name) { + if (name[name.length - 1] === "*") { + return true; + } + let i; + let len; + for (i = 0, len = createDebug.skips.length; i < len; i++) { + if (createDebug.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = createDebug.names.length; i < len; i++) { + if (createDebug.names[i].test(name)) { + return true; + } + } + return false; + } + function toNamespace(regexp) { + return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, "*"); + } + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + function destroy() { + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + } + createDebug.enable(createDebug.load()); + return createDebug; + } + module2.exports = setup; + } +}); + +// node_modules/.pnpm/debug@4.3.4_supports-color@7.2.0/node_modules/debug/src/browser.js +var require_browser = __commonJS({ + "node_modules/.pnpm/debug@4.3.4_supports-color@7.2.0/node_modules/debug/src/browser.js"(exports2, module2) { + init_polyfill_buffer(); + exports2.formatArgs = formatArgs; + exports2.save = save; + exports2.load = load; + exports2.useColors = useColors; + exports2.storage = localstorage(); + exports2.destroy = (() => { + let warned = false; + return () => { + if (!warned) { + warned = true; + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + } + }; + })(); + exports2.colors = [ + "#0000CC", + "#0000FF", + "#0033CC", + "#0033FF", + "#0066CC", + "#0066FF", + "#0099CC", + "#0099FF", + "#00CC00", + "#00CC33", + "#00CC66", + "#00CC99", + "#00CCCC", + "#00CCFF", + "#3300CC", + "#3300FF", + "#3333CC", + "#3333FF", + "#3366CC", + "#3366FF", + "#3399CC", + "#3399FF", + "#33CC00", + "#33CC33", + "#33CC66", + "#33CC99", + "#33CCCC", + "#33CCFF", + "#6600CC", + "#6600FF", + "#6633CC", + "#6633FF", + "#66CC00", + "#66CC33", + "#9900CC", + "#9900FF", + "#9933CC", + "#9933FF", + "#99CC00", + "#99CC33", + "#CC0000", + "#CC0033", + "#CC0066", + "#CC0099", + "#CC00CC", + "#CC00FF", + "#CC3300", + "#CC3333", + "#CC3366", + "#CC3399", + "#CC33CC", + "#CC33FF", + "#CC6600", + "#CC6633", + "#CC9900", + "#CC9933", + "#CCCC00", + "#CCCC33", + "#FF0000", + "#FF0033", + "#FF0066", + "#FF0099", + "#FF00CC", + "#FF00FF", + "#FF3300", + "#FF3333", + "#FF3366", + "#FF3399", + "#FF33CC", + "#FF33FF", + "#FF6600", + "#FF6633", + "#FF9900", + "#FF9933", + "#FFCC00", + "#FFCC33" + ]; + function useColors() { + if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) { + return true; + } + if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + function formatArgs(args) { + args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module2.exports.humanize(this.diff); + if (!this.useColors) { + return; + } + const c = "color: " + this.color; + args.splice(1, 0, c, "color: inherit"); + let index2 = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, (match) => { + if (match === "%%") { + return; + } + index2++; + if (match === "%c") { + lastC = index2; + } + }); + args.splice(lastC, 0, c); + } + exports2.log = console.debug || console.log || (() => { + }); + function save(namespaces) { + try { + if (namespaces) { + exports2.storage.setItem("debug", namespaces); + } else { + exports2.storage.removeItem("debug"); + } + } catch (error) { + } + } + function load() { + let r; + try { + r = exports2.storage.getItem("debug"); + } catch (error) { + } + if (!r && typeof process !== "undefined" && "env" in process) { + r = process.env.DEBUG; + } + return r; + } + function localstorage() { + try { + return localStorage; + } catch (error) { + } + } + module2.exports = require_common2()(exports2); + var { formatters } = module2.exports; + formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (error) { + return "[UnexpectedJSONParseError]: " + error.message; + } + }; + } +}); + +// node_modules/.pnpm/@kwsites+file-exists@1.1.1_supports-color@7.2.0/node_modules/@kwsites/file-exists/dist/src/index.js +var require_src = __commonJS({ + "node_modules/.pnpm/@kwsites+file-exists@1.1.1_supports-color@7.2.0/node_modules/@kwsites/file-exists/dist/src/index.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + var __importDefault = exports2 && exports2.__importDefault || function(mod) { + return mod && mod.__esModule ? mod : { "default": mod }; + }; + Object.defineProperty(exports2, "__esModule", { value: true }); + var fs_1 = require("fs"); + var debug_1 = __importDefault(require_browser()); + var log2 = debug_1.default("@kwsites/file-exists"); + function check(path2, isFile, isDirectory) { + log2(`checking %s`, path2); + try { + const stat = fs_1.statSync(path2); + if (stat.isFile() && isFile) { + log2(`[OK] path represents a file`); + return true; + } + if (stat.isDirectory() && isDirectory) { + log2(`[OK] path represents a directory`); + return true; + } + log2(`[FAIL] path represents something other than a file or directory`); + return false; + } catch (e) { + if (e.code === "ENOENT") { + log2(`[FAIL] path is not accessible: %o`, e); + return false; + } + log2(`[FATAL] %o`, e); + throw e; + } + } + function exists2(path2, type = exports2.READABLE) { + return check(path2, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0); + } + exports2.exists = exists2; + exports2.FILE = 1; + exports2.FOLDER = 2; + exports2.READABLE = exports2.FILE + exports2.FOLDER; + } +}); + +// node_modules/.pnpm/@kwsites+file-exists@1.1.1_supports-color@7.2.0/node_modules/@kwsites/file-exists/dist/index.js +var require_dist = __commonJS({ + "node_modules/.pnpm/@kwsites+file-exists@1.1.1_supports-color@7.2.0/node_modules/@kwsites/file-exists/dist/index.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + function __export3(m) { + for (var p in m) + if (!exports2.hasOwnProperty(p)) + exports2[p] = m[p]; + } + Object.defineProperty(exports2, "__esModule", { value: true }); + __export3(require_src()); + } +}); + +// node_modules/.pnpm/@kwsites+promise-deferred@1.1.1/node_modules/@kwsites/promise-deferred/dist/index.js +var require_dist2 = __commonJS({ + "node_modules/.pnpm/@kwsites+promise-deferred@1.1.1/node_modules/@kwsites/promise-deferred/dist/index.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + Object.defineProperty(exports2, "__esModule", { value: true }); + exports2.createDeferred = exports2.deferred = void 0; + function deferred2() { + let done; + let fail; + let status2 = "pending"; + const promise2 = new Promise((_done, _fail) => { + done = _done; + fail = _fail; + }); + return { + promise: promise2, + done(result) { + if (status2 === "pending") { + status2 = "resolved"; + done(result); + } + }, + fail(error) { + if (status2 === "pending") { + status2 = "rejected"; + fail(error); + } + }, + get fulfilled() { + return status2 !== "pending"; + }, + get status() { + return status2; + } + }; + } + exports2.deferred = deferred2; + exports2.createDeferred = deferred2; + exports2.default = deferred2; + } +}); + +// node_modules/.pnpm/color-name@1.1.4/node_modules/color-name/index.js +var require_color_name = __commonJS({ + "node_modules/.pnpm/color-name@1.1.4/node_modules/color-name/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + module2.exports = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] + }; + } +}); + +// node_modules/.pnpm/css-unit-converter@1.1.2/node_modules/css-unit-converter/index.js +var require_css_unit_converter = __commonJS({ + "node_modules/.pnpm/css-unit-converter@1.1.2/node_modules/css-unit-converter/index.js"(exports2, module2) { + init_polyfill_buffer(); + var conversions = { + // length + "px": { + "px": 1, + "cm": 96 / 2.54, + "mm": 96 / 25.4, + "in": 96, + "pt": 96 / 72, + "pc": 16 + }, + "cm": { + "px": 2.54 / 96, + "cm": 1, + "mm": 0.1, + "in": 2.54, + "pt": 2.54 / 72, + "pc": 2.54 / 6 + }, + "mm": { + "px": 25.4 / 96, + "cm": 10, + "mm": 1, + "in": 25.4, + "pt": 25.4 / 72, + "pc": 25.4 / 6 + }, + "in": { + "px": 1 / 96, + "cm": 1 / 2.54, + "mm": 1 / 25.4, + "in": 1, + "pt": 1 / 72, + "pc": 1 / 6 + }, + "pt": { + "px": 0.75, + "cm": 72 / 2.54, + "mm": 72 / 25.4, + "in": 72, + "pt": 1, + "pc": 12 + }, + "pc": { + "px": 6 / 96, + "cm": 6 / 2.54, + "mm": 6 / 25.4, + "in": 6, + "pt": 6 / 72, + "pc": 1 + }, + // angle + "deg": { + "deg": 1, + "grad": 0.9, + "rad": 180 / Math.PI, + "turn": 360 + }, + "grad": { + "deg": 400 / 360, + "grad": 1, + "rad": 200 / Math.PI, + "turn": 400 + }, + "rad": { + "deg": Math.PI / 180, + "grad": Math.PI / 200, + "rad": 1, + "turn": Math.PI * 2 + }, + "turn": { + "deg": 1 / 360, + "grad": 1 / 400, + "rad": 0.5 / Math.PI, + "turn": 1 + }, + // time + "s": { + "s": 1, + "ms": 1 / 1e3 + }, + "ms": { + "s": 1e3, + "ms": 1 + }, + // frequency + "Hz": { + "Hz": 1, + "kHz": 1e3 + }, + "kHz": { + "Hz": 1 / 1e3, + "kHz": 1 + }, + // resolution + "dpi": { + "dpi": 1, + "dpcm": 1 / 2.54, + "dppx": 1 / 96 + }, + "dpcm": { + "dpi": 2.54, + "dpcm": 1, + "dppx": 2.54 / 96 + }, + "dppx": { + "dpi": 96, + "dpcm": 96 / 2.54, + "dppx": 1 + } + }; + module2.exports = function(value, sourceUnit, targetUnit, precision) { + if (!conversions.hasOwnProperty(targetUnit)) + throw new Error("Cannot convert to " + targetUnit); + if (!conversions[targetUnit].hasOwnProperty(sourceUnit)) + throw new Error("Cannot convert from " + sourceUnit + " to " + targetUnit); + var converted = conversions[targetUnit][sourceUnit] * value; + if (precision !== false) { + precision = Math.pow(10, parseInt(precision) || 5); + return Math.round(converted * precision) / precision; + } + return converted; + }; + } +}); + +// node_modules/.pnpm/css-color-converter@2.0.0/node_modules/css-color-converter/lib/index.js +var require_lib3 = __commonJS({ + "node_modules/.pnpm/css-color-converter@2.0.0/node_modules/css-color-converter/lib/index.js"(exports2) { + "use strict"; + init_polyfill_buffer(); + Object.defineProperty(exports2, "__esModule", { + value: true + }); + exports2.fromRgba = fromRgba; + exports2.fromRgb = fromRgb; + exports2.fromHsla = fromHsla; + exports2.fromHsl = fromHsl; + exports2.fromString = fromString2; + exports2["default"] = void 0; + var _colorName = _interopRequireDefault(require_color_name()); + var _cssUnitConverter = _interopRequireDefault(require_css_unit_converter()); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { "default": obj }; + } + function _classCallCheck(instance10, Constructor) { + if (!(instance10 instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) + descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) + _defineProperties(Constructor.prototype, protoProps); + if (staticProps) + _defineProperties(Constructor, staticProps); + return Constructor; + } + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray2(arr, i) || _nonIterableRest(); + } + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + function _unsupportedIterableToArray2(o, minLen) { + if (!o) + return; + if (typeof o === "string") + return _arrayLikeToArray2(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) + n = o.constructor.name; + if (n === "Map" || n === "Set") + return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) + return _arrayLikeToArray2(o, minLen); + } + function _arrayLikeToArray2(arr, len) { + if (len == null || len > arr.length) + len = arr.length; + for (var i = 0, arr2 = new Array(len); i < len; i++) { + arr2[i] = arr[i]; + } + return arr2; + } + function _iterableToArrayLimit(arr, i) { + if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) + return; + var _arr = []; + var _n = true; + var _d = false; + var _e = void 0; + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + if (i && _arr.length === i) + break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) + _i["return"](); + } finally { + if (_d) + throw _e; + } + } + return _arr; + } + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) + return arr; + } + var hex = /^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})?$/; + var shortHex = /^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])?$/; + var rgb = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*(0|1|0?\.\d+|\d+%))?\s*\)$/; + var rgbfn = /^rgba?\(\s*(\d+)\s+(\d+)\s+(\d+)(?:\s*\/\s*(0|1|0?\.\d+|\d+%))?\s*\)$/; + var rgbperc = /^rgba?\(\s*(\d+%)\s*,\s*(\d+%)\s*,\s*(\d+%)(?:\s*,\s*(0|1|0?\.\d+|\d+%))?\s*\)$/; + var rgbpercfn = /^rgba?\(\s*(\d+%)\s+(\d+%)\s+(\d+%)(?:\s*\/\s*(0|1|0?\.\d+|\d+%))?\s*\)$/; + var hsl = /^hsla?\(\s*(\d+)(deg|rad|grad|turn)?\s*,\s*(\d+)%\s*,\s*(\d+)%(?:\s*,\s*(0|1|0?\.\d+|\d+%))?\s*\)$/; + function contains2(haystack, needle) { + return haystack.indexOf(needle) > -1; + } + function rgbToHsl(r, g, b) { + var rprim = r / 255; + var gprim = g / 255; + var bprim = b / 255; + var cmax = Math.max(rprim, gprim, bprim); + var cmin = Math.min(rprim, gprim, bprim); + var delta = cmax - cmin; + var l = (cmax + cmin) / 2; + if (delta === 0) { + return [0, 0, l * 100]; + } + var s = delta / (1 - Math.abs(2 * l - 1)); + var h = function() { + switch (cmax) { + case rprim: { + return (gprim - bprim) / delta % 6; + } + case gprim: { + return (bprim - rprim) / delta + 2; + } + default: { + return (rprim - gprim) / delta + 4; + } + } + }(); + return [h * 60, s * 100, l * 100]; + } + function hslToRgb(h, s, l) { + var hprim = h / 60; + var sprim = s / 100; + var lprim = l / 100; + var c = (1 - Math.abs(2 * lprim - 1)) * sprim; + var x = c * (1 - Math.abs(hprim % 2 - 1)); + var m = lprim - c / 2; + var _ref = function() { + if (hprim < 1) + return [c, x, 0]; + if (hprim < 2) + return [x, c, 0]; + if (hprim < 3) + return [0, c, x]; + if (hprim < 4) + return [0, x, c]; + if (hprim < 5) + return [x, 0, c]; + return [c, 0, x]; + }(), _ref2 = _slicedToArray(_ref, 3), rprim = _ref2[0], gprim = _ref2[1], bprim = _ref2[2]; + return [(rprim + m) * 255, (gprim + m) * 255, (bprim + m) * 255]; + } + var Color = /* @__PURE__ */ function() { + function Color2(_ref3) { + var _ref4 = _slicedToArray(_ref3, 4), r = _ref4[0], g = _ref4[1], b = _ref4[2], a = _ref4[3]; + _classCallCheck(this, Color2); + this.values = [Math.max(Math.min(parseInt(r, 10), 255), 0), Math.max(Math.min(parseInt(g, 10), 255), 0), Math.max(Math.min(parseInt(b, 10), 255), 0), a == null ? 1 : Math.max(Math.min(parseFloat(a), 255), 0)]; + } + _createClass(Color2, [{ + key: "toRgbString", + value: function toRgbString() { + var _this$values = _slicedToArray(this.values, 4), r = _this$values[0], g = _this$values[1], b = _this$values[2], a = _this$values[3]; + if (a === 1) { + return "rgb(".concat(r, ", ").concat(g, ", ").concat(b, ")"); + } + return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(a, ")"); + } + }, { + key: "toHslString", + value: function toHslString() { + var _this$toHslaArray = this.toHslaArray(), _this$toHslaArray2 = _slicedToArray(_this$toHslaArray, 4), h = _this$toHslaArray2[0], s = _this$toHslaArray2[1], l = _this$toHslaArray2[2], a = _this$toHslaArray2[3]; + if (a === 1) { + return "hsl(".concat(h, ", ").concat(s, "%, ").concat(l, "%)"); + } + return "hsla(".concat(h, ", ").concat(s, "%, ").concat(l, "%, ").concat(a, ")"); + } + }, { + key: "toHexString", + value: function toHexString() { + var _this$values2 = _slicedToArray(this.values, 4), r = _this$values2[0], g = _this$values2[1], b = _this$values2[2], a = _this$values2[3]; + r = Number(r).toString(16).padStart(2, "0"); + g = Number(g).toString(16).padStart(2, "0"); + b = Number(b).toString(16).padStart(2, "0"); + a = a < 1 ? parseInt(a * 255, 10).toString(16).padStart(2, "0") : ""; + return "#".concat(r).concat(g).concat(b).concat(a); + } + }, { + key: "toRgbaArray", + value: function toRgbaArray() { + return this.values; + } + }, { + key: "toHslaArray", + value: function toHslaArray() { + var _this$values3 = _slicedToArray(this.values, 4), r = _this$values3[0], g = _this$values3[1], b = _this$values3[2], a = _this$values3[3]; + var _rgbToHsl = rgbToHsl(r, g, b), _rgbToHsl2 = _slicedToArray(_rgbToHsl, 3), h = _rgbToHsl2[0], s = _rgbToHsl2[1], l = _rgbToHsl2[2]; + return [h, s, l, a]; + } + }]); + return Color2; + }(); + function fromRgba(_ref5) { + var _ref6 = _slicedToArray(_ref5, 4), r = _ref6[0], g = _ref6[1], b = _ref6[2], a = _ref6[3]; + return new Color([r, g, b, a]); + } + function fromRgb(_ref7) { + var _ref8 = _slicedToArray(_ref7, 3), r = _ref8[0], g = _ref8[1], b = _ref8[2]; + return fromRgba([r, g, b, 1]); + } + function fromHsla(_ref9) { + var _ref10 = _slicedToArray(_ref9, 4), h = _ref10[0], s = _ref10[1], l = _ref10[2], a = _ref10[3]; + var _hslToRgb = hslToRgb(h, s, l), _hslToRgb2 = _slicedToArray(_hslToRgb, 3), r = _hslToRgb2[0], g = _hslToRgb2[1], b = _hslToRgb2[2]; + return fromRgba([r, g, b, a]); + } + function fromHsl(_ref11) { + var _ref12 = _slicedToArray(_ref11, 3), h = _ref12[0], s = _ref12[1], l = _ref12[2]; + return fromHsla([h, s, l, 1]); + } + function fromHexString(str) { + var _ref13 = hex.exec(str) || shortHex.exec(str), _ref14 = _slicedToArray(_ref13, 5), r = _ref14[1], g = _ref14[2], b = _ref14[3], a = _ref14[4]; + r = parseInt(r.length < 2 ? r.repeat(2) : r, 16); + g = parseInt(g.length < 2 ? g.repeat(2) : g, 16); + b = parseInt(b.length < 2 ? b.repeat(2) : b, 16); + a = a && (parseInt(a.length < 2 ? a.repeat(2) : a, 16) / 255).toPrecision(1) || 1; + return fromRgba([r, g, b, a]); + } + function fromRgbString(str) { + var _ref15 = rgb.exec(str) || rgbperc.exec(str) || rgbfn.exec(str) || rgbpercfn.exec(str), _ref16 = _slicedToArray(_ref15, 5), r = _ref16[1], g = _ref16[2], b = _ref16[3], a = _ref16[4]; + r = contains2(r, "%") ? parseInt(r, 10) * 255 / 100 : parseInt(r, 10); + g = contains2(g, "%") ? parseInt(g, 10) * 255 / 100 : parseInt(g, 10); + b = contains2(b, "%") > 0 ? parseInt(b, 10) * 255 / 100 : parseInt(b, 10); + a = a === void 0 ? 1 : parseFloat(a) / (contains2(a, "%") ? 100 : 1); + return fromRgba([r, g, b, a]); + } + function fromHslString(str) { + var _hsl$exec = hsl.exec(str), _hsl$exec2 = _slicedToArray(_hsl$exec, 6), h = _hsl$exec2[1], unit = _hsl$exec2[2], s = _hsl$exec2[3], l = _hsl$exec2[4], a = _hsl$exec2[5]; + unit = unit || "deg"; + h = (0, _cssUnitConverter["default"])(parseFloat(h), unit, "deg"); + s = parseFloat(s); + l = parseFloat(l); + a = a === void 0 ? 1 : parseFloat(a) / (contains2(a, "%") ? 100 : 1); + return fromHsla([h, s, l, a]); + } + function fromString2(str) { + if (_colorName["default"][str]) { + return fromRgb(_colorName["default"][str]); + } + if (hex.test(str) || shortHex.test(str)) { + return fromHexString(str); + } + if (rgb.test(str) || rgbperc.test(str) || rgbfn.test(str) || rgbpercfn.test(str)) { + return fromRgbString(str); + } + if (hsl.test(str)) { + return fromHslString(str); + } + return null; + } + var _default = { + fromString: fromString2, + fromRgb, + fromRgba, + fromHsl, + fromHsla + }; + exports2["default"] = _default; + } +}); + +// node_modules/.pnpm/object-keys@1.1.1/node_modules/object-keys/isArguments.js +var require_isArguments = __commonJS({ + "node_modules/.pnpm/object-keys@1.1.1/node_modules/object-keys/isArguments.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var toStr = Object.prototype.toString; + module2.exports = function isArguments(value) { + var str = toStr.call(value); + var isArgs = str === "[object Arguments]"; + if (!isArgs) { + isArgs = str !== "[object Array]" && value !== null && typeof value === "object" && typeof value.length === "number" && value.length >= 0 && toStr.call(value.callee) === "[object Function]"; + } + return isArgs; + }; + } +}); + +// node_modules/.pnpm/object-keys@1.1.1/node_modules/object-keys/implementation.js +var require_implementation = __commonJS({ + "node_modules/.pnpm/object-keys@1.1.1/node_modules/object-keys/implementation.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var keysShim; + if (!Object.keys) { + has = Object.prototype.hasOwnProperty; + toStr = Object.prototype.toString; + isArgs = require_isArguments(); + isEnumerable = Object.prototype.propertyIsEnumerable; + hasDontEnumBug = !isEnumerable.call({ toString: null }, "toString"); + hasProtoEnumBug = isEnumerable.call(function() { + }, "prototype"); + dontEnums = [ + "toString", + "toLocaleString", + "valueOf", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor" + ]; + equalsConstructorPrototype = function(o) { + var ctor = o.constructor; + return ctor && ctor.prototype === o; + }; + excludedKeys = { + $applicationCache: true, + $console: true, + $external: true, + $frame: true, + $frameElement: true, + $frames: true, + $innerHeight: true, + $innerWidth: true, + $onmozfullscreenchange: true, + $onmozfullscreenerror: true, + $outerHeight: true, + $outerWidth: true, + $pageXOffset: true, + $pageYOffset: true, + $parent: true, + $scrollLeft: true, + $scrollTop: true, + $scrollX: true, + $scrollY: true, + $self: true, + $webkitIndexedDB: true, + $webkitStorageInfo: true, + $window: true + }; + hasAutomationEqualityBug = function() { + if (typeof window === "undefined") { + return false; + } + for (var k in window) { + try { + if (!excludedKeys["$" + k] && has.call(window, k) && window[k] !== null && typeof window[k] === "object") { + try { + equalsConstructorPrototype(window[k]); + } catch (e) { + return true; + } + } + } catch (e) { + return true; + } + } + return false; + }(); + equalsConstructorPrototypeIfNotBuggy = function(o) { + if (typeof window === "undefined" || !hasAutomationEqualityBug) { + return equalsConstructorPrototype(o); + } + try { + return equalsConstructorPrototype(o); + } catch (e) { + return false; + } + }; + keysShim = function keys(object) { + var isObject = object !== null && typeof object === "object"; + var isFunction = toStr.call(object) === "[object Function]"; + var isArguments = isArgs(object); + var isString = isObject && toStr.call(object) === "[object String]"; + var theKeys = []; + if (!isObject && !isFunction && !isArguments) { + throw new TypeError("Object.keys called on a non-object"); + } + var skipProto = hasProtoEnumBug && isFunction; + if (isString && object.length > 0 && !has.call(object, 0)) { + for (var i = 0; i < object.length; ++i) { + theKeys.push(String(i)); + } + } + if (isArguments && object.length > 0) { + for (var j = 0; j < object.length; ++j) { + theKeys.push(String(j)); + } + } else { + for (var name in object) { + if (!(skipProto && name === "prototype") && has.call(object, name)) { + theKeys.push(String(name)); + } + } + } + if (hasDontEnumBug) { + var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); + for (var k = 0; k < dontEnums.length; ++k) { + if (!(skipConstructor && dontEnums[k] === "constructor") && has.call(object, dontEnums[k])) { + theKeys.push(dontEnums[k]); + } + } + } + return theKeys; + }; + } + var has; + var toStr; + var isArgs; + var isEnumerable; + var hasDontEnumBug; + var hasProtoEnumBug; + var dontEnums; + var equalsConstructorPrototype; + var excludedKeys; + var hasAutomationEqualityBug; + var equalsConstructorPrototypeIfNotBuggy; + module2.exports = keysShim; + } +}); + +// node_modules/.pnpm/object-keys@1.1.1/node_modules/object-keys/index.js +var require_object_keys = __commonJS({ + "node_modules/.pnpm/object-keys@1.1.1/node_modules/object-keys/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var slice = Array.prototype.slice; + var isArgs = require_isArguments(); + var origKeys = Object.keys; + var keysShim = origKeys ? function keys(o) { + return origKeys(o); + } : require_implementation(); + var originalKeys = Object.keys; + keysShim.shim = function shimObjectKeys() { + if (Object.keys) { + var keysWorksWithArguments = function() { + var args = Object.keys(arguments); + return args && args.length === arguments.length; + }(1, 2); + if (!keysWorksWithArguments) { + Object.keys = function keys(object) { + if (isArgs(object)) { + return originalKeys(slice.call(object)); + } + return originalKeys(object); + }; + } + } else { + Object.keys = keysShim; + } + return Object.keys || keysShim; + }; + module2.exports = keysShim; + } +}); + +// node_modules/.pnpm/has-symbols@1.0.3/node_modules/has-symbols/shams.js +var require_shams = __commonJS({ + "node_modules/.pnpm/has-symbols@1.0.3/node_modules/has-symbols/shams.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + module2.exports = function hasSymbols() { + if (typeof Symbol !== "function" || typeof Object.getOwnPropertySymbols !== "function") { + return false; + } + if (typeof Symbol.iterator === "symbol") { + return true; + } + var obj = {}; + var sym = Symbol("test"); + var symObj = Object(sym); + if (typeof sym === "string") { + return false; + } + if (Object.prototype.toString.call(sym) !== "[object Symbol]") { + return false; + } + if (Object.prototype.toString.call(symObj) !== "[object Symbol]") { + return false; + } + var symVal = 42; + obj[sym] = symVal; + for (sym in obj) { + return false; + } + if (typeof Object.keys === "function" && Object.keys(obj).length !== 0) { + return false; + } + if (typeof Object.getOwnPropertyNames === "function" && Object.getOwnPropertyNames(obj).length !== 0) { + return false; + } + var syms = Object.getOwnPropertySymbols(obj); + if (syms.length !== 1 || syms[0] !== sym) { + return false; + } + if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { + return false; + } + if (typeof Object.getOwnPropertyDescriptor === "function") { + var descriptor = Object.getOwnPropertyDescriptor(obj, sym); + if (descriptor.value !== symVal || descriptor.enumerable !== true) { + return false; + } + } + return true; + }; + } +}); + +// node_modules/.pnpm/has-symbols@1.0.3/node_modules/has-symbols/index.js +var require_has_symbols = __commonJS({ + "node_modules/.pnpm/has-symbols@1.0.3/node_modules/has-symbols/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var origSymbol = typeof Symbol !== "undefined" && Symbol; + var hasSymbolSham = require_shams(); + module2.exports = function hasNativeSymbols() { + if (typeof origSymbol !== "function") { + return false; + } + if (typeof Symbol !== "function") { + return false; + } + if (typeof origSymbol("foo") !== "symbol") { + return false; + } + if (typeof Symbol("bar") !== "symbol") { + return false; + } + return hasSymbolSham(); + }; + } +}); + +// node_modules/.pnpm/function-bind@1.1.1/node_modules/function-bind/implementation.js +var require_implementation2 = __commonJS({ + "node_modules/.pnpm/function-bind@1.1.1/node_modules/function-bind/implementation.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var ERROR_MESSAGE = "Function.prototype.bind called on incompatible "; + var slice = Array.prototype.slice; + var toStr = Object.prototype.toString; + var funcType = "[object Function]"; + module2.exports = function bind(that) { + var target = this; + if (typeof target !== "function" || toStr.call(target) !== funcType) { + throw new TypeError(ERROR_MESSAGE + target); + } + var args = slice.call(arguments, 1); + var bound; + var binder = function() { + if (this instanceof bound) { + var result = target.apply( + this, + args.concat(slice.call(arguments)) + ); + if (Object(result) === result) { + return result; + } + return this; + } else { + return target.apply( + that, + args.concat(slice.call(arguments)) + ); + } + }; + var boundLength = Math.max(0, target.length - args.length); + var boundArgs = []; + for (var i = 0; i < boundLength; i++) { + boundArgs.push("$" + i); + } + bound = Function("binder", "return function (" + boundArgs.join(",") + "){ return binder.apply(this,arguments); }")(binder); + if (target.prototype) { + var Empty = function Empty2() { + }; + Empty.prototype = target.prototype; + bound.prototype = new Empty(); + Empty.prototype = null; + } + return bound; + }; + } +}); + +// node_modules/.pnpm/function-bind@1.1.1/node_modules/function-bind/index.js +var require_function_bind = __commonJS({ + "node_modules/.pnpm/function-bind@1.1.1/node_modules/function-bind/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var implementation = require_implementation2(); + module2.exports = Function.prototype.bind || implementation; + } +}); + +// node_modules/.pnpm/has@1.0.3/node_modules/has/src/index.js +var require_src2 = __commonJS({ + "node_modules/.pnpm/has@1.0.3/node_modules/has/src/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var bind = require_function_bind(); + module2.exports = bind.call(Function.call, Object.prototype.hasOwnProperty); + } +}); + +// node_modules/.pnpm/get-intrinsic@1.2.0/node_modules/get-intrinsic/index.js +var require_get_intrinsic = __commonJS({ + "node_modules/.pnpm/get-intrinsic@1.2.0/node_modules/get-intrinsic/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var undefined2; + var $SyntaxError = SyntaxError; + var $Function = Function; + var $TypeError = TypeError; + var getEvalledConstructor = function(expressionSyntax) { + try { + return $Function('"use strict"; return (' + expressionSyntax + ").constructor;")(); + } catch (e) { + } + }; + var $gOPD = Object.getOwnPropertyDescriptor; + if ($gOPD) { + try { + $gOPD({}, ""); + } catch (e) { + $gOPD = null; + } + } + var throwTypeError = function() { + throw new $TypeError(); + }; + var ThrowTypeError = $gOPD ? function() { + try { + arguments.callee; + return throwTypeError; + } catch (calleeThrows) { + try { + return $gOPD(arguments, "callee").get; + } catch (gOPDthrows) { + return throwTypeError; + } + } + }() : throwTypeError; + var hasSymbols = require_has_symbols()(); + var getProto = Object.getPrototypeOf || function(x) { + return x.__proto__; + }; + var needsEval = {}; + var TypedArray = typeof Uint8Array === "undefined" ? undefined2 : getProto(Uint8Array); + var INTRINSICS = { + "%AggregateError%": typeof AggregateError === "undefined" ? undefined2 : AggregateError, + "%Array%": Array, + "%ArrayBuffer%": typeof ArrayBuffer === "undefined" ? undefined2 : ArrayBuffer, + "%ArrayIteratorPrototype%": hasSymbols ? getProto([][Symbol.iterator]()) : undefined2, + "%AsyncFromSyncIteratorPrototype%": undefined2, + "%AsyncFunction%": needsEval, + "%AsyncGenerator%": needsEval, + "%AsyncGeneratorFunction%": needsEval, + "%AsyncIteratorPrototype%": needsEval, + "%Atomics%": typeof Atomics === "undefined" ? undefined2 : Atomics, + "%BigInt%": typeof BigInt === "undefined" ? undefined2 : BigInt, + "%BigInt64Array%": typeof BigInt64Array === "undefined" ? undefined2 : BigInt64Array, + "%BigUint64Array%": typeof BigUint64Array === "undefined" ? undefined2 : BigUint64Array, + "%Boolean%": Boolean, + "%DataView%": typeof DataView === "undefined" ? undefined2 : DataView, + "%Date%": Date, + "%decodeURI%": decodeURI, + "%decodeURIComponent%": decodeURIComponent, + "%encodeURI%": encodeURI, + "%encodeURIComponent%": encodeURIComponent, + "%Error%": Error, + "%eval%": eval, + // eslint-disable-line no-eval + "%EvalError%": EvalError, + "%Float32Array%": typeof Float32Array === "undefined" ? undefined2 : Float32Array, + "%Float64Array%": typeof Float64Array === "undefined" ? undefined2 : Float64Array, + "%FinalizationRegistry%": typeof FinalizationRegistry === "undefined" ? undefined2 : FinalizationRegistry, + "%Function%": $Function, + "%GeneratorFunction%": needsEval, + "%Int8Array%": typeof Int8Array === "undefined" ? undefined2 : Int8Array, + "%Int16Array%": typeof Int16Array === "undefined" ? undefined2 : Int16Array, + "%Int32Array%": typeof Int32Array === "undefined" ? undefined2 : Int32Array, + "%isFinite%": isFinite, + "%isNaN%": isNaN, + "%IteratorPrototype%": hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined2, + "%JSON%": typeof JSON === "object" ? JSON : undefined2, + "%Map%": typeof Map === "undefined" ? undefined2 : Map, + "%MapIteratorPrototype%": typeof Map === "undefined" || !hasSymbols ? undefined2 : getProto((/* @__PURE__ */ new Map())[Symbol.iterator]()), + "%Math%": Math, + "%Number%": Number, + "%Object%": Object, + "%parseFloat%": parseFloat, + "%parseInt%": parseInt, + "%Promise%": typeof Promise === "undefined" ? undefined2 : Promise, + "%Proxy%": typeof Proxy === "undefined" ? undefined2 : Proxy, + "%RangeError%": RangeError, + "%ReferenceError%": ReferenceError, + "%Reflect%": typeof Reflect === "undefined" ? undefined2 : Reflect, + "%RegExp%": RegExp, + "%Set%": typeof Set === "undefined" ? undefined2 : Set, + "%SetIteratorPrototype%": typeof Set === "undefined" || !hasSymbols ? undefined2 : getProto((/* @__PURE__ */ new Set())[Symbol.iterator]()), + "%SharedArrayBuffer%": typeof SharedArrayBuffer === "undefined" ? undefined2 : SharedArrayBuffer, + "%String%": String, + "%StringIteratorPrototype%": hasSymbols ? getProto(""[Symbol.iterator]()) : undefined2, + "%Symbol%": hasSymbols ? Symbol : undefined2, + "%SyntaxError%": $SyntaxError, + "%ThrowTypeError%": ThrowTypeError, + "%TypedArray%": TypedArray, + "%TypeError%": $TypeError, + "%Uint8Array%": typeof Uint8Array === "undefined" ? undefined2 : Uint8Array, + "%Uint8ClampedArray%": typeof Uint8ClampedArray === "undefined" ? undefined2 : Uint8ClampedArray, + "%Uint16Array%": typeof Uint16Array === "undefined" ? undefined2 : Uint16Array, + "%Uint32Array%": typeof Uint32Array === "undefined" ? undefined2 : Uint32Array, + "%URIError%": URIError, + "%WeakMap%": typeof WeakMap === "undefined" ? undefined2 : WeakMap, + "%WeakRef%": typeof WeakRef === "undefined" ? undefined2 : WeakRef, + "%WeakSet%": typeof WeakSet === "undefined" ? undefined2 : WeakSet + }; + try { + null.error; + } catch (e) { + errorProto = getProto(getProto(e)); + INTRINSICS["%Error.prototype%"] = errorProto; + } + var errorProto; + var doEval = function doEval2(name) { + var value; + if (name === "%AsyncFunction%") { + value = getEvalledConstructor("async function () {}"); + } else if (name === "%GeneratorFunction%") { + value = getEvalledConstructor("function* () {}"); + } else if (name === "%AsyncGeneratorFunction%") { + value = getEvalledConstructor("async function* () {}"); + } else if (name === "%AsyncGenerator%") { + var fn = doEval2("%AsyncGeneratorFunction%"); + if (fn) { + value = fn.prototype; + } + } else if (name === "%AsyncIteratorPrototype%") { + var gen = doEval2("%AsyncGenerator%"); + if (gen) { + value = getProto(gen.prototype); + } + } + INTRINSICS[name] = value; + return value; + }; + var LEGACY_ALIASES = { + "%ArrayBufferPrototype%": ["ArrayBuffer", "prototype"], + "%ArrayPrototype%": ["Array", "prototype"], + "%ArrayProto_entries%": ["Array", "prototype", "entries"], + "%ArrayProto_forEach%": ["Array", "prototype", "forEach"], + "%ArrayProto_keys%": ["Array", "prototype", "keys"], + "%ArrayProto_values%": ["Array", "prototype", "values"], + "%AsyncFunctionPrototype%": ["AsyncFunction", "prototype"], + "%AsyncGenerator%": ["AsyncGeneratorFunction", "prototype"], + "%AsyncGeneratorPrototype%": ["AsyncGeneratorFunction", "prototype", "prototype"], + "%BooleanPrototype%": ["Boolean", "prototype"], + "%DataViewPrototype%": ["DataView", "prototype"], + "%DatePrototype%": ["Date", "prototype"], + "%ErrorPrototype%": ["Error", "prototype"], + "%EvalErrorPrototype%": ["EvalError", "prototype"], + "%Float32ArrayPrototype%": ["Float32Array", "prototype"], + "%Float64ArrayPrototype%": ["Float64Array", "prototype"], + "%FunctionPrototype%": ["Function", "prototype"], + "%Generator%": ["GeneratorFunction", "prototype"], + "%GeneratorPrototype%": ["GeneratorFunction", "prototype", "prototype"], + "%Int8ArrayPrototype%": ["Int8Array", "prototype"], + "%Int16ArrayPrototype%": ["Int16Array", "prototype"], + "%Int32ArrayPrototype%": ["Int32Array", "prototype"], + "%JSONParse%": ["JSON", "parse"], + "%JSONStringify%": ["JSON", "stringify"], + "%MapPrototype%": ["Map", "prototype"], + "%NumberPrototype%": ["Number", "prototype"], + "%ObjectPrototype%": ["Object", "prototype"], + "%ObjProto_toString%": ["Object", "prototype", "toString"], + "%ObjProto_valueOf%": ["Object", "prototype", "valueOf"], + "%PromisePrototype%": ["Promise", "prototype"], + "%PromiseProto_then%": ["Promise", "prototype", "then"], + "%Promise_all%": ["Promise", "all"], + "%Promise_reject%": ["Promise", "reject"], + "%Promise_resolve%": ["Promise", "resolve"], + "%RangeErrorPrototype%": ["RangeError", "prototype"], + "%ReferenceErrorPrototype%": ["ReferenceError", "prototype"], + "%RegExpPrototype%": ["RegExp", "prototype"], + "%SetPrototype%": ["Set", "prototype"], + "%SharedArrayBufferPrototype%": ["SharedArrayBuffer", "prototype"], + "%StringPrototype%": ["String", "prototype"], + "%SymbolPrototype%": ["Symbol", "prototype"], + "%SyntaxErrorPrototype%": ["SyntaxError", "prototype"], + "%TypedArrayPrototype%": ["TypedArray", "prototype"], + "%TypeErrorPrototype%": ["TypeError", "prototype"], + "%Uint8ArrayPrototype%": ["Uint8Array", "prototype"], + "%Uint8ClampedArrayPrototype%": ["Uint8ClampedArray", "prototype"], + "%Uint16ArrayPrototype%": ["Uint16Array", "prototype"], + "%Uint32ArrayPrototype%": ["Uint32Array", "prototype"], + "%URIErrorPrototype%": ["URIError", "prototype"], + "%WeakMapPrototype%": ["WeakMap", "prototype"], + "%WeakSetPrototype%": ["WeakSet", "prototype"] + }; + var bind = require_function_bind(); + var hasOwn = require_src2(); + var $concat = bind.call(Function.call, Array.prototype.concat); + var $spliceApply = bind.call(Function.apply, Array.prototype.splice); + var $replace = bind.call(Function.call, String.prototype.replace); + var $strSlice = bind.call(Function.call, String.prototype.slice); + var $exec = bind.call(Function.call, RegExp.prototype.exec); + var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; + var reEscapeChar = /\\(\\)?/g; + var stringToPath = function stringToPath2(string) { + var first2 = $strSlice(string, 0, 1); + var last2 = $strSlice(string, -1); + if (first2 === "%" && last2 !== "%") { + throw new $SyntaxError("invalid intrinsic syntax, expected closing `%`"); + } else if (last2 === "%" && first2 !== "%") { + throw new $SyntaxError("invalid intrinsic syntax, expected opening `%`"); + } + var result = []; + $replace(string, rePropName, function(match, number, quote, subString) { + result[result.length] = quote ? $replace(subString, reEscapeChar, "$1") : number || match; + }); + return result; + }; + var getBaseIntrinsic = function getBaseIntrinsic2(name, allowMissing) { + var intrinsicName = name; + var alias; + if (hasOwn(LEGACY_ALIASES, intrinsicName)) { + alias = LEGACY_ALIASES[intrinsicName]; + intrinsicName = "%" + alias[0] + "%"; + } + if (hasOwn(INTRINSICS, intrinsicName)) { + var value = INTRINSICS[intrinsicName]; + if (value === needsEval) { + value = doEval(intrinsicName); + } + if (typeof value === "undefined" && !allowMissing) { + throw new $TypeError("intrinsic " + name + " exists, but is not available. Please file an issue!"); + } + return { + alias, + name: intrinsicName, + value + }; + } + throw new $SyntaxError("intrinsic " + name + " does not exist!"); + }; + module2.exports = function GetIntrinsic(name, allowMissing) { + if (typeof name !== "string" || name.length === 0) { + throw new $TypeError("intrinsic name must be a non-empty string"); + } + if (arguments.length > 1 && typeof allowMissing !== "boolean") { + throw new $TypeError('"allowMissing" argument must be a boolean'); + } + if ($exec(/^%?[^%]*%?$/, name) === null) { + throw new $SyntaxError("`%` may not be present anywhere but at the beginning and end of the intrinsic name"); + } + var parts = stringToPath(name); + var intrinsicBaseName = parts.length > 0 ? parts[0] : ""; + var intrinsic = getBaseIntrinsic("%" + intrinsicBaseName + "%", allowMissing); + var intrinsicRealName = intrinsic.name; + var value = intrinsic.value; + var skipFurtherCaching = false; + var alias = intrinsic.alias; + if (alias) { + intrinsicBaseName = alias[0]; + $spliceApply(parts, $concat([0, 1], alias)); + } + for (var i = 1, isOwn = true; i < parts.length; i += 1) { + var part = parts[i]; + var first2 = $strSlice(part, 0, 1); + var last2 = $strSlice(part, -1); + if ((first2 === '"' || first2 === "'" || first2 === "`" || (last2 === '"' || last2 === "'" || last2 === "`")) && first2 !== last2) { + throw new $SyntaxError("property names with quotes must have matching quotes"); + } + if (part === "constructor" || !isOwn) { + skipFurtherCaching = true; + } + intrinsicBaseName += "." + part; + intrinsicRealName = "%" + intrinsicBaseName + "%"; + if (hasOwn(INTRINSICS, intrinsicRealName)) { + value = INTRINSICS[intrinsicRealName]; + } else if (value != null) { + if (!(part in value)) { + if (!allowMissing) { + throw new $TypeError("base intrinsic for " + name + " exists, but the property is not available."); + } + return void 0; + } + if ($gOPD && i + 1 >= parts.length) { + var desc = $gOPD(value, part); + isOwn = !!desc; + if (isOwn && "get" in desc && !("originalValue" in desc.get)) { + value = desc.get; + } else { + value = value[part]; + } + } else { + isOwn = hasOwn(value, part); + value = value[part]; + } + if (isOwn && !skipFurtherCaching) { + INTRINSICS[intrinsicRealName] = value; + } + } + } + return value; + }; + } +}); + +// node_modules/.pnpm/has-property-descriptors@1.0.0/node_modules/has-property-descriptors/index.js +var require_has_property_descriptors = __commonJS({ + "node_modules/.pnpm/has-property-descriptors@1.0.0/node_modules/has-property-descriptors/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var GetIntrinsic = require_get_intrinsic(); + var $defineProperty = GetIntrinsic("%Object.defineProperty%", true); + var hasPropertyDescriptors = function hasPropertyDescriptors2() { + if ($defineProperty) { + try { + $defineProperty({}, "a", { value: 1 }); + return true; + } catch (e) { + return false; + } + } + return false; + }; + hasPropertyDescriptors.hasArrayLengthDefineBug = function hasArrayLengthDefineBug() { + if (!hasPropertyDescriptors()) { + return null; + } + try { + return $defineProperty([], "length", { value: 1 }).length !== 1; + } catch (e) { + return true; + } + }; + module2.exports = hasPropertyDescriptors; + } +}); + +// node_modules/.pnpm/define-properties@1.2.0/node_modules/define-properties/index.js +var require_define_properties = __commonJS({ + "node_modules/.pnpm/define-properties@1.2.0/node_modules/define-properties/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var keys = require_object_keys(); + var hasSymbols = typeof Symbol === "function" && typeof Symbol("foo") === "symbol"; + var toStr = Object.prototype.toString; + var concat = Array.prototype.concat; + var origDefineProperty = Object.defineProperty; + var isFunction = function(fn) { + return typeof fn === "function" && toStr.call(fn) === "[object Function]"; + }; + var hasPropertyDescriptors = require_has_property_descriptors()(); + var supportsDescriptors = origDefineProperty && hasPropertyDescriptors; + var defineProperty = function(object, name, value, predicate) { + if (name in object) { + if (predicate === true) { + if (object[name] === value) { + return; + } + } else if (!isFunction(predicate) || !predicate()) { + return; + } + } + if (supportsDescriptors) { + origDefineProperty(object, name, { + configurable: true, + enumerable: false, + value, + writable: true + }); + } else { + object[name] = value; + } + }; + var defineProperties = function(object, map) { + var predicates = arguments.length > 2 ? arguments[2] : {}; + var props = keys(map); + if (hasSymbols) { + props = concat.call(props, Object.getOwnPropertySymbols(map)); + } + for (var i = 0; i < props.length; i += 1) { + defineProperty(object, props[i], map[props[i]], predicates[props[i]]); + } + }; + defineProperties.supportsDescriptors = !!supportsDescriptors; + module2.exports = defineProperties; + } +}); + +// node_modules/.pnpm/call-bind@1.0.2/node_modules/call-bind/index.js +var require_call_bind = __commonJS({ + "node_modules/.pnpm/call-bind@1.0.2/node_modules/call-bind/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var bind = require_function_bind(); + var GetIntrinsic = require_get_intrinsic(); + var $apply = GetIntrinsic("%Function.prototype.apply%"); + var $call = GetIntrinsic("%Function.prototype.call%"); + var $reflectApply = GetIntrinsic("%Reflect.apply%", true) || bind.call($call, $apply); + var $gOPD = GetIntrinsic("%Object.getOwnPropertyDescriptor%", true); + var $defineProperty = GetIntrinsic("%Object.defineProperty%", true); + var $max = GetIntrinsic("%Math.max%"); + if ($defineProperty) { + try { + $defineProperty({}, "a", { value: 1 }); + } catch (e) { + $defineProperty = null; + } + } + module2.exports = function callBind(originalFunction) { + var func = $reflectApply(bind, $call, arguments); + if ($gOPD && $defineProperty) { + var desc = $gOPD(func, "length"); + if (desc.configurable) { + $defineProperty( + func, + "length", + { value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) } + ); + } + } + return func; + }; + var applyBind = function applyBind2() { + return $reflectApply(bind, $apply, arguments); + }; + if ($defineProperty) { + $defineProperty(module2.exports, "apply", { value: applyBind }); + } else { + module2.exports.apply = applyBind; + } + } +}); + +// node_modules/.pnpm/call-bind@1.0.2/node_modules/call-bind/callBound.js +var require_callBound = __commonJS({ + "node_modules/.pnpm/call-bind@1.0.2/node_modules/call-bind/callBound.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var GetIntrinsic = require_get_intrinsic(); + var callBind = require_call_bind(); + var $indexOf = callBind(GetIntrinsic("String.prototype.indexOf")); + module2.exports = function callBoundIntrinsic(name, allowMissing) { + var intrinsic = GetIntrinsic(name, !!allowMissing); + if (typeof intrinsic === "function" && $indexOf(name, ".prototype.") > -1) { + return callBind(intrinsic); + } + return intrinsic; + }; + } +}); + +// node_modules/.pnpm/object.assign@4.1.4/node_modules/object.assign/implementation.js +var require_implementation3 = __commonJS({ + "node_modules/.pnpm/object.assign@4.1.4/node_modules/object.assign/implementation.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var objectKeys = require_object_keys(); + var hasSymbols = require_shams()(); + var callBound = require_callBound(); + var toObject = Object; + var $push = callBound("Array.prototype.push"); + var $propIsEnumerable = callBound("Object.prototype.propertyIsEnumerable"); + var originalGetSymbols = hasSymbols ? Object.getOwnPropertySymbols : null; + module2.exports = function assign2(target, source1) { + if (target == null) { + throw new TypeError("target must be an object"); + } + var to = toObject(target); + if (arguments.length === 1) { + return to; + } + for (var s = 1; s < arguments.length; ++s) { + var from = toObject(arguments[s]); + var keys = objectKeys(from); + var getSymbols = hasSymbols && (Object.getOwnPropertySymbols || originalGetSymbols); + if (getSymbols) { + var syms = getSymbols(from); + for (var j = 0; j < syms.length; ++j) { + var key2 = syms[j]; + if ($propIsEnumerable(from, key2)) { + $push(keys, key2); + } + } + } + for (var i = 0; i < keys.length; ++i) { + var nextKey = keys[i]; + if ($propIsEnumerable(from, nextKey)) { + var propValue = from[nextKey]; + to[nextKey] = propValue; + } + } + } + return to; + }; + } +}); + +// node_modules/.pnpm/object.assign@4.1.4/node_modules/object.assign/polyfill.js +var require_polyfill = __commonJS({ + "node_modules/.pnpm/object.assign@4.1.4/node_modules/object.assign/polyfill.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var implementation = require_implementation3(); + var lacksProperEnumerationOrder = function() { + if (!Object.assign) { + return false; + } + var str = "abcdefghijklmnopqrst"; + var letters = str.split(""); + var map = {}; + for (var i = 0; i < letters.length; ++i) { + map[letters[i]] = letters[i]; + } + var obj = Object.assign({}, map); + var actual = ""; + for (var k in obj) { + actual += k; + } + return str !== actual; + }; + var assignHasPendingExceptions = function() { + if (!Object.assign || !Object.preventExtensions) { + return false; + } + var thrower = Object.preventExtensions({ 1: 2 }); + try { + Object.assign(thrower, "xy"); + } catch (e) { + return thrower[1] === "y"; + } + return false; + }; + module2.exports = function getPolyfill() { + if (!Object.assign) { + return implementation; + } + if (lacksProperEnumerationOrder()) { + return implementation; + } + if (assignHasPendingExceptions()) { + return implementation; + } + return Object.assign; + }; + } +}); + +// node_modules/.pnpm/object.assign@4.1.4/node_modules/object.assign/shim.js +var require_shim = __commonJS({ + "node_modules/.pnpm/object.assign@4.1.4/node_modules/object.assign/shim.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var define2 = require_define_properties(); + var getPolyfill = require_polyfill(); + module2.exports = function shimAssign() { + var polyfill = getPolyfill(); + define2( + Object, + { assign: polyfill }, + { assign: function() { + return Object.assign !== polyfill; + } } + ); + return polyfill; + }; + } +}); + +// node_modules/.pnpm/object.assign@4.1.4/node_modules/object.assign/index.js +var require_object = __commonJS({ + "node_modules/.pnpm/object.assign@4.1.4/node_modules/object.assign/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var defineProperties = require_define_properties(); + var callBind = require_call_bind(); + var implementation = require_implementation3(); + var getPolyfill = require_polyfill(); + var shim = require_shim(); + var polyfill = callBind.apply(getPolyfill()); + var bound = function assign2(target, source1) { + return polyfill(Object, arguments); + }; + defineProperties(bound, { + getPolyfill, + implementation, + shim + }); + module2.exports = bound; + } +}); + +// node_modules/.pnpm/functions-have-names@1.2.3/node_modules/functions-have-names/index.js +var require_functions_have_names = __commonJS({ + "node_modules/.pnpm/functions-have-names@1.2.3/node_modules/functions-have-names/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var functionsHaveNames = function functionsHaveNames2() { + return typeof function f() { + }.name === "string"; + }; + var gOPD = Object.getOwnPropertyDescriptor; + if (gOPD) { + try { + gOPD([], "length"); + } catch (e) { + gOPD = null; + } + } + functionsHaveNames.functionsHaveConfigurableNames = function functionsHaveConfigurableNames() { + if (!functionsHaveNames() || !gOPD) { + return false; + } + var desc = gOPD(function() { + }, "name"); + return !!desc && !!desc.configurable; + }; + var $bind = Function.prototype.bind; + functionsHaveNames.boundFunctionsHaveNames = function boundFunctionsHaveNames() { + return functionsHaveNames() && typeof $bind === "function" && function f() { + }.bind().name !== ""; + }; + module2.exports = functionsHaveNames; + } +}); + +// node_modules/.pnpm/regexp.prototype.flags@1.5.0/node_modules/regexp.prototype.flags/implementation.js +var require_implementation4 = __commonJS({ + "node_modules/.pnpm/regexp.prototype.flags@1.5.0/node_modules/regexp.prototype.flags/implementation.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var functionsHaveConfigurableNames = require_functions_have_names().functionsHaveConfigurableNames(); + var $Object = Object; + var $TypeError = TypeError; + module2.exports = function flags() { + if (this != null && this !== $Object(this)) { + throw new $TypeError("RegExp.prototype.flags getter called on non-object"); + } + var result = ""; + if (this.hasIndices) { + result += "d"; + } + if (this.global) { + result += "g"; + } + if (this.ignoreCase) { + result += "i"; + } + if (this.multiline) { + result += "m"; + } + if (this.dotAll) { + result += "s"; + } + if (this.unicode) { + result += "u"; + } + if (this.unicodeSets) { + result += "v"; + } + if (this.sticky) { + result += "y"; + } + return result; + }; + if (functionsHaveConfigurableNames && Object.defineProperty) { + Object.defineProperty(module2.exports, "name", { value: "get flags" }); + } + } +}); + +// node_modules/.pnpm/regexp.prototype.flags@1.5.0/node_modules/regexp.prototype.flags/polyfill.js +var require_polyfill2 = __commonJS({ + "node_modules/.pnpm/regexp.prototype.flags@1.5.0/node_modules/regexp.prototype.flags/polyfill.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var implementation = require_implementation4(); + var supportsDescriptors = require_define_properties().supportsDescriptors; + var $gOPD = Object.getOwnPropertyDescriptor; + module2.exports = function getPolyfill() { + if (supportsDescriptors && /a/mig.flags === "gim") { + var descriptor = $gOPD(RegExp.prototype, "flags"); + if (descriptor && typeof descriptor.get === "function" && typeof RegExp.prototype.dotAll === "boolean" && typeof RegExp.prototype.hasIndices === "boolean") { + var calls = ""; + var o = {}; + Object.defineProperty(o, "hasIndices", { + get: function() { + calls += "d"; + } + }); + Object.defineProperty(o, "sticky", { + get: function() { + calls += "y"; + } + }); + if (calls === "dy") { + return descriptor.get; + } + } + } + return implementation; + }; + } +}); + +// node_modules/.pnpm/regexp.prototype.flags@1.5.0/node_modules/regexp.prototype.flags/shim.js +var require_shim2 = __commonJS({ + "node_modules/.pnpm/regexp.prototype.flags@1.5.0/node_modules/regexp.prototype.flags/shim.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var supportsDescriptors = require_define_properties().supportsDescriptors; + var getPolyfill = require_polyfill2(); + var gOPD = Object.getOwnPropertyDescriptor; + var defineProperty = Object.defineProperty; + var TypeErr = TypeError; + var getProto = Object.getPrototypeOf; + var regex2 = /a/; + module2.exports = function shimFlags() { + if (!supportsDescriptors || !getProto) { + throw new TypeErr("RegExp.prototype.flags requires a true ES5 environment that supports property descriptors"); + } + var polyfill = getPolyfill(); + var proto = getProto(regex2); + var descriptor = gOPD(proto, "flags"); + if (!descriptor || descriptor.get !== polyfill) { + defineProperty(proto, "flags", { + configurable: true, + enumerable: false, + get: polyfill + }); + } + return polyfill; + }; + } +}); + +// node_modules/.pnpm/regexp.prototype.flags@1.5.0/node_modules/regexp.prototype.flags/index.js +var require_regexp_prototype = __commonJS({ + "node_modules/.pnpm/regexp.prototype.flags@1.5.0/node_modules/regexp.prototype.flags/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var define2 = require_define_properties(); + var callBind = require_call_bind(); + var implementation = require_implementation4(); + var getPolyfill = require_polyfill2(); + var shim = require_shim2(); + var flagsBound = callBind(getPolyfill()); + define2(flagsBound, { + getPolyfill, + implementation, + shim + }); + module2.exports = flagsBound; + } +}); + +// node_modules/.pnpm/has-tostringtag@1.0.0/node_modules/has-tostringtag/shams.js +var require_shams2 = __commonJS({ + "node_modules/.pnpm/has-tostringtag@1.0.0/node_modules/has-tostringtag/shams.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var hasSymbols = require_shams(); + module2.exports = function hasToStringTagShams() { + return hasSymbols() && !!Symbol.toStringTag; + }; + } +}); + +// node_modules/.pnpm/is-arguments@1.1.1/node_modules/is-arguments/index.js +var require_is_arguments = __commonJS({ + "node_modules/.pnpm/is-arguments@1.1.1/node_modules/is-arguments/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var hasToStringTag = require_shams2()(); + var callBound = require_callBound(); + var $toString = callBound("Object.prototype.toString"); + var isStandardArguments = function isArguments(value) { + if (hasToStringTag && value && typeof value === "object" && Symbol.toStringTag in value) { + return false; + } + return $toString(value) === "[object Arguments]"; + }; + var isLegacyArguments = function isArguments(value) { + if (isStandardArguments(value)) { + return true; + } + return value !== null && typeof value === "object" && typeof value.length === "number" && value.length >= 0 && $toString(value) !== "[object Array]" && $toString(value.callee) === "[object Function]"; + }; + var supportsStandardArguments = function() { + return isStandardArguments(arguments); + }(); + isStandardArguments.isLegacyArguments = isLegacyArguments; + module2.exports = supportsStandardArguments ? isStandardArguments : isLegacyArguments; + } +}); + +// (disabled):node_modules/.pnpm/object-inspect@1.12.3/node_modules/object-inspect/util.inspect +var require_util = __commonJS({ + "(disabled):node_modules/.pnpm/object-inspect@1.12.3/node_modules/object-inspect/util.inspect"() { + init_polyfill_buffer(); + } +}); + +// node_modules/.pnpm/object-inspect@1.12.3/node_modules/object-inspect/index.js +var require_object_inspect = __commonJS({ + "node_modules/.pnpm/object-inspect@1.12.3/node_modules/object-inspect/index.js"(exports2, module2) { + init_polyfill_buffer(); + var hasMap = typeof Map === "function" && Map.prototype; + var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, "size") : null; + var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === "function" ? mapSizeDescriptor.get : null; + var mapForEach = hasMap && Map.prototype.forEach; + var hasSet = typeof Set === "function" && Set.prototype; + var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, "size") : null; + var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === "function" ? setSizeDescriptor.get : null; + var setForEach = hasSet && Set.prototype.forEach; + var hasWeakMap = typeof WeakMap === "function" && WeakMap.prototype; + var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null; + var hasWeakSet = typeof WeakSet === "function" && WeakSet.prototype; + var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null; + var hasWeakRef = typeof WeakRef === "function" && WeakRef.prototype; + var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null; + var booleanValueOf = Boolean.prototype.valueOf; + var objectToString2 = Object.prototype.toString; + var functionToString = Function.prototype.toString; + var $match = String.prototype.match; + var $slice = String.prototype.slice; + var $replace = String.prototype.replace; + var $toUpperCase = String.prototype.toUpperCase; + var $toLowerCase = String.prototype.toLowerCase; + var $test = RegExp.prototype.test; + var $concat = Array.prototype.concat; + var $join = Array.prototype.join; + var $arrSlice = Array.prototype.slice; + var $floor = Math.floor; + var bigIntValueOf = typeof BigInt === "function" ? BigInt.prototype.valueOf : null; + var gOPS = Object.getOwnPropertySymbols; + var symToString = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? Symbol.prototype.toString : null; + var hasShammedSymbols = typeof Symbol === "function" && typeof Symbol.iterator === "object"; + var toStringTag = typeof Symbol === "function" && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? "object" : "symbol") ? Symbol.toStringTag : null; + var isEnumerable = Object.prototype.propertyIsEnumerable; + var gPO = (typeof Reflect === "function" ? Reflect.getPrototypeOf : Object.getPrototypeOf) || ([].__proto__ === Array.prototype ? function(O) { + return O.__proto__; + } : null); + function addNumericSeparator(num2, str) { + if (num2 === Infinity || num2 === -Infinity || num2 !== num2 || num2 && num2 > -1e3 && num2 < 1e3 || $test.call(/e/, str)) { + return str; + } + var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g; + if (typeof num2 === "number") { + var int = num2 < 0 ? -$floor(-num2) : $floor(num2); + if (int !== num2) { + var intStr = String(int); + var dec = $slice.call(str, intStr.length + 1); + return $replace.call(intStr, sepRegex, "$&_") + "." + $replace.call($replace.call(dec, /([0-9]{3})/g, "$&_"), /_$/, ""); + } + } + return $replace.call(str, sepRegex, "$&_"); + } + var utilInspect = require_util(); + var inspectCustom = utilInspect.custom; + var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null; + module2.exports = function inspect_(obj, options, depth, seen) { + var opts = options || {}; + if (has(opts, "quoteStyle") && (opts.quoteStyle !== "single" && opts.quoteStyle !== "double")) { + throw new TypeError('option "quoteStyle" must be "single" or "double"'); + } + if (has(opts, "maxStringLength") && (typeof opts.maxStringLength === "number" ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity : opts.maxStringLength !== null)) { + throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`'); + } + var customInspect = has(opts, "customInspect") ? opts.customInspect : true; + if (typeof customInspect !== "boolean" && customInspect !== "symbol") { + throw new TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`"); + } + if (has(opts, "indent") && opts.indent !== null && opts.indent !== " " && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)) { + throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`'); + } + if (has(opts, "numericSeparator") && typeof opts.numericSeparator !== "boolean") { + throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`'); + } + var numericSeparator = opts.numericSeparator; + if (typeof obj === "undefined") { + return "undefined"; + } + if (obj === null) { + return "null"; + } + if (typeof obj === "boolean") { + return obj ? "true" : "false"; + } + if (typeof obj === "string") { + return inspectString(obj, opts); + } + if (typeof obj === "number") { + if (obj === 0) { + return Infinity / obj > 0 ? "0" : "-0"; + } + var str = String(obj); + return numericSeparator ? addNumericSeparator(obj, str) : str; + } + if (typeof obj === "bigint") { + var bigIntStr = String(obj) + "n"; + return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr; + } + var maxDepth = typeof opts.depth === "undefined" ? 5 : opts.depth; + if (typeof depth === "undefined") { + depth = 0; + } + if (depth >= maxDepth && maxDepth > 0 && typeof obj === "object") { + return isArray(obj) ? "[Array]" : "[Object]"; + } + var indent2 = getIndent(opts, depth); + if (typeof seen === "undefined") { + seen = []; + } else if (indexOf(seen, obj) >= 0) { + return "[Circular]"; + } + function inspect(value, from, noIndent) { + if (from) { + seen = $arrSlice.call(seen); + seen.push(from); + } + if (noIndent) { + var newOpts = { + depth: opts.depth + }; + if (has(opts, "quoteStyle")) { + newOpts.quoteStyle = opts.quoteStyle; + } + return inspect_(value, newOpts, depth + 1, seen); + } + return inspect_(value, opts, depth + 1, seen); + } + if (typeof obj === "function" && !isRegExp(obj)) { + var name = nameOf(obj); + var keys = arrObjKeys(obj, inspect); + return "[Function" + (name ? ": " + name : " (anonymous)") + "]" + (keys.length > 0 ? " { " + $join.call(keys, ", ") + " }" : ""); + } + if (isSymbol(obj)) { + var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, "$1") : symToString.call(obj); + return typeof obj === "object" && !hasShammedSymbols ? markBoxed(symString) : symString; + } + if (isElement(obj)) { + var s = "<" + $toLowerCase.call(String(obj.nodeName)); + var attrs = obj.attributes || []; + for (var i = 0; i < attrs.length; i++) { + s += " " + attrs[i].name + "=" + wrapQuotes(quote(attrs[i].value), "double", opts); + } + s += ">"; + if (obj.childNodes && obj.childNodes.length) { + s += "..."; + } + s += ""; + return s; + } + if (isArray(obj)) { + if (obj.length === 0) { + return "[]"; + } + var xs = arrObjKeys(obj, inspect); + if (indent2 && !singleLineValues(xs)) { + return "[" + indentedJoin(xs, indent2) + "]"; + } + return "[ " + $join.call(xs, ", ") + " ]"; + } + if (isError(obj)) { + var parts = arrObjKeys(obj, inspect); + if (!("cause" in Error.prototype) && "cause" in obj && !isEnumerable.call(obj, "cause")) { + return "{ [" + String(obj) + "] " + $join.call($concat.call("[cause]: " + inspect(obj.cause), parts), ", ") + " }"; + } + if (parts.length === 0) { + return "[" + String(obj) + "]"; + } + return "{ [" + String(obj) + "] " + $join.call(parts, ", ") + " }"; + } + if (typeof obj === "object" && customInspect) { + if (inspectSymbol && typeof obj[inspectSymbol] === "function" && utilInspect) { + return utilInspect(obj, { depth: maxDepth - depth }); + } else if (customInspect !== "symbol" && typeof obj.inspect === "function") { + return obj.inspect(); + } + } + if (isMap(obj)) { + var mapParts = []; + if (mapForEach) { + mapForEach.call(obj, function(value, key2) { + mapParts.push(inspect(key2, obj, true) + " => " + inspect(value, obj)); + }); + } + return collectionOf("Map", mapSize.call(obj), mapParts, indent2); + } + if (isSet(obj)) { + var setParts = []; + if (setForEach) { + setForEach.call(obj, function(value) { + setParts.push(inspect(value, obj)); + }); + } + return collectionOf("Set", setSize.call(obj), setParts, indent2); + } + if (isWeakMap(obj)) { + return weakCollectionOf("WeakMap"); + } + if (isWeakSet(obj)) { + return weakCollectionOf("WeakSet"); + } + if (isWeakRef(obj)) { + return weakCollectionOf("WeakRef"); + } + if (isNumber(obj)) { + return markBoxed(inspect(Number(obj))); + } + if (isBigInt(obj)) { + return markBoxed(inspect(bigIntValueOf.call(obj))); + } + if (isBoolean(obj)) { + return markBoxed(booleanValueOf.call(obj)); + } + if (isString(obj)) { + return markBoxed(inspect(String(obj))); + } + if (!isDate(obj) && !isRegExp(obj)) { + var ys = arrObjKeys(obj, inspect); + var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object; + var protoTag = obj instanceof Object ? "" : "null prototype"; + var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? "Object" : ""; + var constructorTag = isPlainObject || typeof obj.constructor !== "function" ? "" : obj.constructor.name ? obj.constructor.name + " " : ""; + var tag2 = constructorTag + (stringTag || protoTag ? "[" + $join.call($concat.call([], stringTag || [], protoTag || []), ": ") + "] " : ""); + if (ys.length === 0) { + return tag2 + "{}"; + } + if (indent2) { + return tag2 + "{" + indentedJoin(ys, indent2) + "}"; + } + return tag2 + "{ " + $join.call(ys, ", ") + " }"; + } + return String(obj); + }; + function wrapQuotes(s, defaultStyle, opts) { + var quoteChar = (opts.quoteStyle || defaultStyle) === "double" ? '"' : "'"; + return quoteChar + s + quoteChar; + } + function quote(s) { + return $replace.call(String(s), /"/g, """); + } + function isArray(obj) { + return toStr(obj) === "[object Array]" && (!toStringTag || !(typeof obj === "object" && toStringTag in obj)); + } + function isDate(obj) { + return toStr(obj) === "[object Date]" && (!toStringTag || !(typeof obj === "object" && toStringTag in obj)); + } + function isRegExp(obj) { + return toStr(obj) === "[object RegExp]" && (!toStringTag || !(typeof obj === "object" && toStringTag in obj)); + } + function isError(obj) { + return toStr(obj) === "[object Error]" && (!toStringTag || !(typeof obj === "object" && toStringTag in obj)); + } + function isString(obj) { + return toStr(obj) === "[object String]" && (!toStringTag || !(typeof obj === "object" && toStringTag in obj)); + } + function isNumber(obj) { + return toStr(obj) === "[object Number]" && (!toStringTag || !(typeof obj === "object" && toStringTag in obj)); + } + function isBoolean(obj) { + return toStr(obj) === "[object Boolean]" && (!toStringTag || !(typeof obj === "object" && toStringTag in obj)); + } + function isSymbol(obj) { + if (hasShammedSymbols) { + return obj && typeof obj === "object" && obj instanceof Symbol; + } + if (typeof obj === "symbol") { + return true; + } + if (!obj || typeof obj !== "object" || !symToString) { + return false; + } + try { + symToString.call(obj); + return true; + } catch (e) { + } + return false; + } + function isBigInt(obj) { + if (!obj || typeof obj !== "object" || !bigIntValueOf) { + return false; + } + try { + bigIntValueOf.call(obj); + return true; + } catch (e) { + } + return false; + } + var hasOwn = Object.prototype.hasOwnProperty || function(key2) { + return key2 in this; + }; + function has(obj, key2) { + return hasOwn.call(obj, key2); + } + function toStr(obj) { + return objectToString2.call(obj); + } + function nameOf(f) { + if (f.name) { + return f.name; + } + var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/); + if (m) { + return m[1]; + } + return null; + } + function indexOf(xs, x) { + if (xs.indexOf) { + return xs.indexOf(x); + } + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) { + return i; + } + } + return -1; + } + function isMap(x) { + if (!mapSize || !x || typeof x !== "object") { + return false; + } + try { + mapSize.call(x); + try { + setSize.call(x); + } catch (s) { + return true; + } + return x instanceof Map; + } catch (e) { + } + return false; + } + function isWeakMap(x) { + if (!weakMapHas || !x || typeof x !== "object") { + return false; + } + try { + weakMapHas.call(x, weakMapHas); + try { + weakSetHas.call(x, weakSetHas); + } catch (s) { + return true; + } + return x instanceof WeakMap; + } catch (e) { + } + return false; + } + function isWeakRef(x) { + if (!weakRefDeref || !x || typeof x !== "object") { + return false; + } + try { + weakRefDeref.call(x); + return true; + } catch (e) { + } + return false; + } + function isSet(x) { + if (!setSize || !x || typeof x !== "object") { + return false; + } + try { + setSize.call(x); + try { + mapSize.call(x); + } catch (m) { + return true; + } + return x instanceof Set; + } catch (e) { + } + return false; + } + function isWeakSet(x) { + if (!weakSetHas || !x || typeof x !== "object") { + return false; + } + try { + weakSetHas.call(x, weakSetHas); + try { + weakMapHas.call(x, weakMapHas); + } catch (s) { + return true; + } + return x instanceof WeakSet; + } catch (e) { + } + return false; + } + function isElement(x) { + if (!x || typeof x !== "object") { + return false; + } + if (typeof HTMLElement !== "undefined" && x instanceof HTMLElement) { + return true; + } + return typeof x.nodeName === "string" && typeof x.getAttribute === "function"; + } + function inspectString(str, opts) { + if (str.length > opts.maxStringLength) { + var remaining = str.length - opts.maxStringLength; + var trailer = "... " + remaining + " more character" + (remaining > 1 ? "s" : ""); + return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer; + } + var s = $replace.call($replace.call(str, /(['\\])/g, "\\$1"), /[\x00-\x1f]/g, lowbyte); + return wrapQuotes(s, "single", opts); + } + function lowbyte(c) { + var n = c.charCodeAt(0); + var x = { + 8: "b", + 9: "t", + 10: "n", + 12: "f", + 13: "r" + }[n]; + if (x) { + return "\\" + x; + } + return "\\x" + (n < 16 ? "0" : "") + $toUpperCase.call(n.toString(16)); + } + function markBoxed(str) { + return "Object(" + str + ")"; + } + function weakCollectionOf(type) { + return type + " { ? }"; + } + function collectionOf(type, size, entries, indent2) { + var joinedEntries = indent2 ? indentedJoin(entries, indent2) : $join.call(entries, ", "); + return type + " (" + size + ") {" + joinedEntries + "}"; + } + function singleLineValues(xs) { + for (var i = 0; i < xs.length; i++) { + if (indexOf(xs[i], "\n") >= 0) { + return false; + } + } + return true; + } + function getIndent(opts, depth) { + var baseIndent; + if (opts.indent === " ") { + baseIndent = " "; + } else if (typeof opts.indent === "number" && opts.indent > 0) { + baseIndent = $join.call(Array(opts.indent + 1), " "); + } else { + return null; + } + return { + base: baseIndent, + prev: $join.call(Array(depth + 1), baseIndent) + }; + } + function indentedJoin(xs, indent2) { + if (xs.length === 0) { + return ""; + } + var lineJoiner = "\n" + indent2.prev + indent2.base; + return lineJoiner + $join.call(xs, "," + lineJoiner) + "\n" + indent2.prev; + } + function arrObjKeys(obj, inspect) { + var isArr = isArray(obj); + var xs = []; + if (isArr) { + xs.length = obj.length; + for (var i = 0; i < obj.length; i++) { + xs[i] = has(obj, i) ? inspect(obj[i], obj) : ""; + } + } + var syms = typeof gOPS === "function" ? gOPS(obj) : []; + var symMap; + if (hasShammedSymbols) { + symMap = {}; + for (var k = 0; k < syms.length; k++) { + symMap["$" + syms[k]] = syms[k]; + } + } + for (var key2 in obj) { + if (!has(obj, key2)) { + continue; + } + if (isArr && String(Number(key2)) === key2 && key2 < obj.length) { + continue; + } + if (hasShammedSymbols && symMap["$" + key2] instanceof Symbol) { + continue; + } else if ($test.call(/[^\w$]/, key2)) { + xs.push(inspect(key2, obj) + ": " + inspect(obj[key2], obj)); + } else { + xs.push(key2 + ": " + inspect(obj[key2], obj)); + } + } + if (typeof gOPS === "function") { + for (var j = 0; j < syms.length; j++) { + if (isEnumerable.call(obj, syms[j])) { + xs.push("[" + inspect(syms[j]) + "]: " + inspect(obj[syms[j]], obj)); + } + } + } + return xs; + } + } +}); + +// node_modules/.pnpm/side-channel@1.0.4/node_modules/side-channel/index.js +var require_side_channel = __commonJS({ + "node_modules/.pnpm/side-channel@1.0.4/node_modules/side-channel/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var GetIntrinsic = require_get_intrinsic(); + var callBound = require_callBound(); + var inspect = require_object_inspect(); + var $TypeError = GetIntrinsic("%TypeError%"); + var $WeakMap = GetIntrinsic("%WeakMap%", true); + var $Map = GetIntrinsic("%Map%", true); + var $weakMapGet = callBound("WeakMap.prototype.get", true); + var $weakMapSet = callBound("WeakMap.prototype.set", true); + var $weakMapHas = callBound("WeakMap.prototype.has", true); + var $mapGet = callBound("Map.prototype.get", true); + var $mapSet = callBound("Map.prototype.set", true); + var $mapHas = callBound("Map.prototype.has", true); + var listGetNode = function(list, key2) { + for (var prev = list, curr; (curr = prev.next) !== null; prev = curr) { + if (curr.key === key2) { + prev.next = curr.next; + curr.next = list.next; + list.next = curr; + return curr; + } + } + }; + var listGet = function(objects, key2) { + var node = listGetNode(objects, key2); + return node && node.value; + }; + var listSet = function(objects, key2, value) { + var node = listGetNode(objects, key2); + if (node) { + node.value = value; + } else { + objects.next = { + // eslint-disable-line no-param-reassign + key: key2, + next: objects.next, + value + }; + } + }; + var listHas = function(objects, key2) { + return !!listGetNode(objects, key2); + }; + module2.exports = function getSideChannel() { + var $wm; + var $m; + var $o; + var channel = { + assert: function(key2) { + if (!channel.has(key2)) { + throw new $TypeError("Side channel does not contain " + inspect(key2)); + } + }, + get: function(key2) { + if ($WeakMap && key2 && (typeof key2 === "object" || typeof key2 === "function")) { + if ($wm) { + return $weakMapGet($wm, key2); + } + } else if ($Map) { + if ($m) { + return $mapGet($m, key2); + } + } else { + if ($o) { + return listGet($o, key2); + } + } + }, + has: function(key2) { + if ($WeakMap && key2 && (typeof key2 === "object" || typeof key2 === "function")) { + if ($wm) { + return $weakMapHas($wm, key2); + } + } else if ($Map) { + if ($m) { + return $mapHas($m, key2); + } + } else { + if ($o) { + return listHas($o, key2); + } + } + return false; + }, + set: function(key2, value) { + if ($WeakMap && key2 && (typeof key2 === "object" || typeof key2 === "function")) { + if (!$wm) { + $wm = new $WeakMap(); + } + $weakMapSet($wm, key2, value); + } else if ($Map) { + if (!$m) { + $m = new $Map(); + } + $mapSet($m, key2, value); + } else { + if (!$o) { + $o = { key: {}, next: null }; + } + listSet($o, key2, value); + } + } + }; + return channel; + }; + } +}); + +// node_modules/.pnpm/internal-slot@1.0.5/node_modules/internal-slot/index.js +var require_internal_slot = __commonJS({ + "node_modules/.pnpm/internal-slot@1.0.5/node_modules/internal-slot/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var GetIntrinsic = require_get_intrinsic(); + var has = require_src2(); + var channel = require_side_channel()(); + var $TypeError = GetIntrinsic("%TypeError%"); + var SLOT = { + assert: function(O, slot) { + if (!O || typeof O !== "object" && typeof O !== "function") { + throw new $TypeError("`O` is not an object"); + } + if (typeof slot !== "string") { + throw new $TypeError("`slot` must be a string"); + } + channel.assert(O); + if (!SLOT.has(O, slot)) { + throw new $TypeError("`" + slot + "` is not present on `O`"); + } + }, + get: function(O, slot) { + if (!O || typeof O !== "object" && typeof O !== "function") { + throw new $TypeError("`O` is not an object"); + } + if (typeof slot !== "string") { + throw new $TypeError("`slot` must be a string"); + } + var slots = channel.get(O); + return slots && slots["$" + slot]; + }, + has: function(O, slot) { + if (!O || typeof O !== "object" && typeof O !== "function") { + throw new $TypeError("`O` is not an object"); + } + if (typeof slot !== "string") { + throw new $TypeError("`slot` must be a string"); + } + var slots = channel.get(O); + return !!slots && has(slots, "$" + slot); + }, + set: function(O, slot, V) { + if (!O || typeof O !== "object" && typeof O !== "function") { + throw new $TypeError("`O` is not an object"); + } + if (typeof slot !== "string") { + throw new $TypeError("`slot` must be a string"); + } + var slots = channel.get(O); + if (!slots) { + slots = {}; + channel.set(O, slots); + } + slots["$" + slot] = V; + } + }; + if (Object.freeze) { + Object.freeze(SLOT); + } + module2.exports = SLOT; + } +}); + +// node_modules/.pnpm/stop-iteration-iterator@1.0.0/node_modules/stop-iteration-iterator/index.js +var require_stop_iteration_iterator = __commonJS({ + "node_modules/.pnpm/stop-iteration-iterator@1.0.0/node_modules/stop-iteration-iterator/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var SLOT = require_internal_slot(); + var $SyntaxError = SyntaxError; + var $StopIteration = typeof StopIteration === "object" ? StopIteration : null; + module2.exports = function getStopIterationIterator(origIterator) { + if (!$StopIteration) { + throw new $SyntaxError("this environment lacks StopIteration"); + } + SLOT.set(origIterator, "[[Done]]", false); + var siIterator = { + next: function next() { + var iterator = SLOT.get(this, "[[Iterator]]"); + var done = SLOT.get(iterator, "[[Done]]"); + try { + return { + done, + value: done ? void 0 : iterator.next() + }; + } catch (e) { + SLOT.set(iterator, "[[Done]]", true); + if (e !== $StopIteration) { + throw e; + } + return { + done: true, + value: void 0 + }; + } + } + }; + SLOT.set(siIterator, "[[Iterator]]", origIterator); + return siIterator; + }; + } +}); + +// node_modules/.pnpm/isarray@2.0.5/node_modules/isarray/index.js +var require_isarray = __commonJS({ + "node_modules/.pnpm/isarray@2.0.5/node_modules/isarray/index.js"(exports2, module2) { + init_polyfill_buffer(); + var toString = {}.toString; + module2.exports = Array.isArray || function(arr) { + return toString.call(arr) == "[object Array]"; + }; + } +}); + +// node_modules/.pnpm/is-string@1.0.7/node_modules/is-string/index.js +var require_is_string = __commonJS({ + "node_modules/.pnpm/is-string@1.0.7/node_modules/is-string/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var strValue = String.prototype.valueOf; + var tryStringObject = function tryStringObject2(value) { + try { + strValue.call(value); + return true; + } catch (e) { + return false; + } + }; + var toStr = Object.prototype.toString; + var strClass = "[object String]"; + var hasToStringTag = require_shams2()(); + module2.exports = function isString(value) { + if (typeof value === "string") { + return true; + } + if (typeof value !== "object") { + return false; + } + return hasToStringTag ? tryStringObject(value) : toStr.call(value) === strClass; + }; + } +}); + +// node_modules/.pnpm/is-map@2.0.2/node_modules/is-map/index.js +var require_is_map = __commonJS({ + "node_modules/.pnpm/is-map@2.0.2/node_modules/is-map/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var $Map = typeof Map === "function" && Map.prototype ? Map : null; + var $Set = typeof Set === "function" && Set.prototype ? Set : null; + var exported; + if (!$Map) { + exported = function isMap(x) { + return false; + }; + } + var $mapHas = $Map ? Map.prototype.has : null; + var $setHas = $Set ? Set.prototype.has : null; + if (!exported && !$mapHas) { + exported = function isMap(x) { + return false; + }; + } + module2.exports = exported || function isMap(x) { + if (!x || typeof x !== "object") { + return false; + } + try { + $mapHas.call(x); + if ($setHas) { + try { + $setHas.call(x); + } catch (e) { + return true; + } + } + return x instanceof $Map; + } catch (e) { + } + return false; + }; + } +}); + +// node_modules/.pnpm/is-set@2.0.2/node_modules/is-set/index.js +var require_is_set = __commonJS({ + "node_modules/.pnpm/is-set@2.0.2/node_modules/is-set/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var $Map = typeof Map === "function" && Map.prototype ? Map : null; + var $Set = typeof Set === "function" && Set.prototype ? Set : null; + var exported; + if (!$Set) { + exported = function isSet(x) { + return false; + }; + } + var $mapHas = $Map ? Map.prototype.has : null; + var $setHas = $Set ? Set.prototype.has : null; + if (!exported && !$setHas) { + exported = function isSet(x) { + return false; + }; + } + module2.exports = exported || function isSet(x) { + if (!x || typeof x !== "object") { + return false; + } + try { + $setHas.call(x); + if ($mapHas) { + try { + $mapHas.call(x); + } catch (e) { + return true; + } + } + return x instanceof $Set; + } catch (e) { + } + return false; + }; + } +}); + +// node_modules/.pnpm/es-get-iterator@1.1.3/node_modules/es-get-iterator/index.js +var require_es_get_iterator = __commonJS({ + "node_modules/.pnpm/es-get-iterator@1.1.3/node_modules/es-get-iterator/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var isArguments = require_is_arguments(); + var getStopIterationIterator = require_stop_iteration_iterator(); + if (require_has_symbols()() || require_shams()()) { + $iterator = Symbol.iterator; + module2.exports = function getIterator3(iterable) { + if (iterable != null && typeof iterable[$iterator] !== "undefined") { + return iterable[$iterator](); + } + if (isArguments(iterable)) { + return Array.prototype[$iterator].call(iterable); + } + }; + } else { + isArray = require_isarray(); + isString = require_is_string(); + GetIntrinsic = require_get_intrinsic(); + $Map = GetIntrinsic("%Map%", true); + $Set = GetIntrinsic("%Set%", true); + callBound = require_callBound(); + $arrayPush = callBound("Array.prototype.push"); + $charCodeAt = callBound("String.prototype.charCodeAt"); + $stringSlice = callBound("String.prototype.slice"); + advanceStringIndex = function advanceStringIndex2(S, index2) { + var length = S.length; + if (index2 + 1 >= length) { + return index2 + 1; + } + var first2 = $charCodeAt(S, index2); + if (first2 < 55296 || first2 > 56319) { + return index2 + 1; + } + var second = $charCodeAt(S, index2 + 1); + if (second < 56320 || second > 57343) { + return index2 + 1; + } + return index2 + 2; + }; + getArrayIterator = function getArrayIterator2(arraylike) { + var i = 0; + return { + next: function next() { + var done = i >= arraylike.length; + var value; + if (!done) { + value = arraylike[i]; + i += 1; + } + return { + done, + value + }; + } + }; + }; + getNonCollectionIterator = function getNonCollectionIterator2(iterable, noPrimordialCollections) { + if (isArray(iterable) || isArguments(iterable)) { + return getArrayIterator(iterable); + } + if (isString(iterable)) { + var i = 0; + return { + next: function next() { + var nextIndex = advanceStringIndex(iterable, i); + var value = $stringSlice(iterable, i, nextIndex); + i = nextIndex; + return { + done: nextIndex > iterable.length, + value + }; + } + }; + } + if (noPrimordialCollections && typeof iterable["_es6-shim iterator_"] !== "undefined") { + return iterable["_es6-shim iterator_"](); + } + }; + if (!$Map && !$Set) { + module2.exports = function getIterator3(iterable) { + if (iterable != null) { + return getNonCollectionIterator(iterable, true); + } + }; + } else { + isMap = require_is_map(); + isSet = require_is_set(); + $mapForEach = callBound("Map.prototype.forEach", true); + $setForEach = callBound("Set.prototype.forEach", true); + if (typeof process === "undefined" || !process.versions || !process.versions.node) { + $mapIterator = callBound("Map.prototype.iterator", true); + $setIterator = callBound("Set.prototype.iterator", true); + } + $mapAtAtIterator = callBound("Map.prototype.@@iterator", true) || callBound("Map.prototype._es6-shim iterator_", true); + $setAtAtIterator = callBound("Set.prototype.@@iterator", true) || callBound("Set.prototype._es6-shim iterator_", true); + getCollectionIterator = function getCollectionIterator2(iterable) { + if (isMap(iterable)) { + if ($mapIterator) { + return getStopIterationIterator($mapIterator(iterable)); + } + if ($mapAtAtIterator) { + return $mapAtAtIterator(iterable); + } + if ($mapForEach) { + var entries = []; + $mapForEach(iterable, function(v, k) { + $arrayPush(entries, [k, v]); + }); + return getArrayIterator(entries); + } + } + if (isSet(iterable)) { + if ($setIterator) { + return getStopIterationIterator($setIterator(iterable)); + } + if ($setAtAtIterator) { + return $setAtAtIterator(iterable); + } + if ($setForEach) { + var values = []; + $setForEach(iterable, function(v) { + $arrayPush(values, v); + }); + return getArrayIterator(values); + } + } + }; + module2.exports = function getIterator3(iterable) { + return getCollectionIterator(iterable) || getNonCollectionIterator(iterable); + }; + } + } + var $iterator; + var isArray; + var isString; + var GetIntrinsic; + var $Map; + var $Set; + var callBound; + var $arrayPush; + var $charCodeAt; + var $stringSlice; + var advanceStringIndex; + var getArrayIterator; + var getNonCollectionIterator; + var isMap; + var isSet; + var $mapForEach; + var $setForEach; + var $mapIterator; + var $setIterator; + var $mapAtAtIterator; + var $setAtAtIterator; + var getCollectionIterator; + } +}); + +// node_modules/.pnpm/object-is@1.1.5/node_modules/object-is/implementation.js +var require_implementation5 = __commonJS({ + "node_modules/.pnpm/object-is@1.1.5/node_modules/object-is/implementation.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var numberIsNaN = function(value) { + return value !== value; + }; + module2.exports = function is(a, b) { + if (a === 0 && b === 0) { + return 1 / a === 1 / b; + } + if (a === b) { + return true; + } + if (numberIsNaN(a) && numberIsNaN(b)) { + return true; + } + return false; + }; + } +}); + +// node_modules/.pnpm/object-is@1.1.5/node_modules/object-is/polyfill.js +var require_polyfill3 = __commonJS({ + "node_modules/.pnpm/object-is@1.1.5/node_modules/object-is/polyfill.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var implementation = require_implementation5(); + module2.exports = function getPolyfill() { + return typeof Object.is === "function" ? Object.is : implementation; + }; + } +}); + +// node_modules/.pnpm/object-is@1.1.5/node_modules/object-is/shim.js +var require_shim3 = __commonJS({ + "node_modules/.pnpm/object-is@1.1.5/node_modules/object-is/shim.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var getPolyfill = require_polyfill3(); + var define2 = require_define_properties(); + module2.exports = function shimObjectIs() { + var polyfill = getPolyfill(); + define2(Object, { is: polyfill }, { + is: function testObjectIs() { + return Object.is !== polyfill; + } + }); + return polyfill; + }; + } +}); + +// node_modules/.pnpm/object-is@1.1.5/node_modules/object-is/index.js +var require_object_is = __commonJS({ + "node_modules/.pnpm/object-is@1.1.5/node_modules/object-is/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var define2 = require_define_properties(); + var callBind = require_call_bind(); + var implementation = require_implementation5(); + var getPolyfill = require_polyfill3(); + var shim = require_shim3(); + var polyfill = callBind(getPolyfill(), Object); + define2(polyfill, { + getPolyfill, + implementation, + shim + }); + module2.exports = polyfill; + } +}); + +// node_modules/.pnpm/is-callable@1.2.7/node_modules/is-callable/index.js +var require_is_callable = __commonJS({ + "node_modules/.pnpm/is-callable@1.2.7/node_modules/is-callable/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var fnToStr = Function.prototype.toString; + var reflectApply = typeof Reflect === "object" && Reflect !== null && Reflect.apply; + var badArrayLike; + var isCallableMarker; + if (typeof reflectApply === "function" && typeof Object.defineProperty === "function") { + try { + badArrayLike = Object.defineProperty({}, "length", { + get: function() { + throw isCallableMarker; + } + }); + isCallableMarker = {}; + reflectApply(function() { + throw 42; + }, null, badArrayLike); + } catch (_) { + if (_ !== isCallableMarker) { + reflectApply = null; + } + } + } else { + reflectApply = null; + } + var constructorRegex = /^\s*class\b/; + var isES6ClassFn = function isES6ClassFunction(value) { + try { + var fnStr = fnToStr.call(value); + return constructorRegex.test(fnStr); + } catch (e) { + return false; + } + }; + var tryFunctionObject = function tryFunctionToStr(value) { + try { + if (isES6ClassFn(value)) { + return false; + } + fnToStr.call(value); + return true; + } catch (e) { + return false; + } + }; + var toStr = Object.prototype.toString; + var objectClass = "[object Object]"; + var fnClass = "[object Function]"; + var genClass = "[object GeneratorFunction]"; + var ddaClass = "[object HTMLAllCollection]"; + var ddaClass2 = "[object HTML document.all class]"; + var ddaClass3 = "[object HTMLCollection]"; + var hasToStringTag = typeof Symbol === "function" && !!Symbol.toStringTag; + var isIE68 = !(0 in [,]); + var isDDA = function isDocumentDotAll() { + return false; + }; + if (typeof document === "object") { + all = document.all; + if (toStr.call(all) === toStr.call(document.all)) { + isDDA = function isDocumentDotAll(value) { + if ((isIE68 || !value) && (typeof value === "undefined" || typeof value === "object")) { + try { + var str = toStr.call(value); + return (str === ddaClass || str === ddaClass2 || str === ddaClass3 || str === objectClass) && value("") == null; + } catch (e) { + } + } + return false; + }; + } + } + var all; + module2.exports = reflectApply ? function isCallable(value) { + if (isDDA(value)) { + return true; + } + if (!value) { + return false; + } + if (typeof value !== "function" && typeof value !== "object") { + return false; + } + try { + reflectApply(value, null, badArrayLike); + } catch (e) { + if (e !== isCallableMarker) { + return false; + } + } + return !isES6ClassFn(value) && tryFunctionObject(value); + } : function isCallable(value) { + if (isDDA(value)) { + return true; + } + if (!value) { + return false; + } + if (typeof value !== "function" && typeof value !== "object") { + return false; + } + if (hasToStringTag) { + return tryFunctionObject(value); + } + if (isES6ClassFn(value)) { + return false; + } + var strClass = toStr.call(value); + if (strClass !== fnClass && strClass !== genClass && !/^\[object HTML/.test(strClass)) { + return false; + } + return tryFunctionObject(value); + }; + } +}); + +// node_modules/.pnpm/for-each@0.3.3/node_modules/for-each/index.js +var require_for_each = __commonJS({ + "node_modules/.pnpm/for-each@0.3.3/node_modules/for-each/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var isCallable = require_is_callable(); + var toStr = Object.prototype.toString; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var forEachArray = function forEachArray2(array, iterator, receiver) { + for (var i = 0, len = array.length; i < len; i++) { + if (hasOwnProperty.call(array, i)) { + if (receiver == null) { + iterator(array[i], i, array); + } else { + iterator.call(receiver, array[i], i, array); + } + } + } + }; + var forEachString = function forEachString2(string, iterator, receiver) { + for (var i = 0, len = string.length; i < len; i++) { + if (receiver == null) { + iterator(string.charAt(i), i, string); + } else { + iterator.call(receiver, string.charAt(i), i, string); + } + } + }; + var forEachObject = function forEachObject2(object, iterator, receiver) { + for (var k in object) { + if (hasOwnProperty.call(object, k)) { + if (receiver == null) { + iterator(object[k], k, object); + } else { + iterator.call(receiver, object[k], k, object); + } + } + } + }; + var forEach2 = function forEach3(list, iterator, thisArg) { + if (!isCallable(iterator)) { + throw new TypeError("iterator must be a function"); + } + var receiver; + if (arguments.length >= 3) { + receiver = thisArg; + } + if (toStr.call(list) === "[object Array]") { + forEachArray(list, iterator, receiver); + } else if (typeof list === "string") { + forEachString(list, iterator, receiver); + } else { + forEachObject(list, iterator, receiver); + } + }; + module2.exports = forEach2; + } +}); + +// node_modules/.pnpm/available-typed-arrays@1.0.5/node_modules/available-typed-arrays/index.js +var require_available_typed_arrays = __commonJS({ + "node_modules/.pnpm/available-typed-arrays@1.0.5/node_modules/available-typed-arrays/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var possibleNames = [ + "BigInt64Array", + "BigUint64Array", + "Float32Array", + "Float64Array", + "Int16Array", + "Int32Array", + "Int8Array", + "Uint16Array", + "Uint32Array", + "Uint8Array", + "Uint8ClampedArray" + ]; + var g = typeof globalThis === "undefined" ? global : globalThis; + module2.exports = function availableTypedArrays() { + var out = []; + for (var i = 0; i < possibleNames.length; i++) { + if (typeof g[possibleNames[i]] === "function") { + out[out.length] = possibleNames[i]; + } + } + return out; + }; + } +}); + +// node_modules/.pnpm/gopd@1.0.1/node_modules/gopd/index.js +var require_gopd = __commonJS({ + "node_modules/.pnpm/gopd@1.0.1/node_modules/gopd/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var GetIntrinsic = require_get_intrinsic(); + var $gOPD = GetIntrinsic("%Object.getOwnPropertyDescriptor%", true); + if ($gOPD) { + try { + $gOPD([], "length"); + } catch (e) { + $gOPD = null; + } + } + module2.exports = $gOPD; + } +}); + +// node_modules/.pnpm/is-typed-array@1.1.10/node_modules/is-typed-array/index.js +var require_is_typed_array = __commonJS({ + "node_modules/.pnpm/is-typed-array@1.1.10/node_modules/is-typed-array/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var forEach2 = require_for_each(); + var availableTypedArrays = require_available_typed_arrays(); + var callBound = require_callBound(); + var $toString = callBound("Object.prototype.toString"); + var hasToStringTag = require_shams2()(); + var gOPD = require_gopd(); + var g = typeof globalThis === "undefined" ? global : globalThis; + var typedArrays = availableTypedArrays(); + var $indexOf = callBound("Array.prototype.indexOf", true) || function indexOf(array, value) { + for (var i = 0; i < array.length; i += 1) { + if (array[i] === value) { + return i; + } + } + return -1; + }; + var $slice = callBound("String.prototype.slice"); + var toStrTags = {}; + var getPrototypeOf = Object.getPrototypeOf; + if (hasToStringTag && gOPD && getPrototypeOf) { + forEach2(typedArrays, function(typedArray) { + var arr = new g[typedArray](); + if (Symbol.toStringTag in arr) { + var proto = getPrototypeOf(arr); + var descriptor = gOPD(proto, Symbol.toStringTag); + if (!descriptor) { + var superProto = getPrototypeOf(proto); + descriptor = gOPD(superProto, Symbol.toStringTag); + } + toStrTags[typedArray] = descriptor.get; + } + }); + } + var tryTypedArrays = function tryAllTypedArrays(value) { + var anyTrue = false; + forEach2(toStrTags, function(getter, typedArray) { + if (!anyTrue) { + try { + anyTrue = getter.call(value) === typedArray; + } catch (e) { + } + } + }); + return anyTrue; + }; + module2.exports = function isTypedArray(value) { + if (!value || typeof value !== "object") { + return false; + } + if (!hasToStringTag || !(Symbol.toStringTag in value)) { + var tag2 = $slice($toString(value), 8, -1); + return $indexOf(typedArrays, tag2) > -1; + } + if (!gOPD) { + return false; + } + return tryTypedArrays(value); + }; + } +}); + +// node_modules/.pnpm/is-array-buffer@3.0.2/node_modules/is-array-buffer/index.js +var require_is_array_buffer = __commonJS({ + "node_modules/.pnpm/is-array-buffer@3.0.2/node_modules/is-array-buffer/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var callBind = require_call_bind(); + var callBound = require_callBound(); + var GetIntrinsic = require_get_intrinsic(); + var isTypedArray = require_is_typed_array(); + var $ArrayBuffer = GetIntrinsic("ArrayBuffer", true); + var $Float32Array = GetIntrinsic("Float32Array", true); + var $byteLength = callBound("ArrayBuffer.prototype.byteLength", true); + var abSlice = $ArrayBuffer && !$byteLength && new $ArrayBuffer().slice; + var $abSlice = abSlice && callBind(abSlice); + module2.exports = $byteLength || $abSlice ? function isArrayBuffer(obj) { + if (!obj || typeof obj !== "object") { + return false; + } + try { + if ($byteLength) { + $byteLength(obj); + } else { + $abSlice(obj, 0); + } + return true; + } catch (e) { + return false; + } + } : $Float32Array ? function IsArrayBuffer(obj) { + try { + return new $Float32Array(obj).buffer === obj && !isTypedArray(obj); + } catch (e) { + return typeof obj === "object" && e.name === "RangeError"; + } + } : function isArrayBuffer(obj) { + return false; + }; + } +}); + +// node_modules/.pnpm/is-date-object@1.0.5/node_modules/is-date-object/index.js +var require_is_date_object = __commonJS({ + "node_modules/.pnpm/is-date-object@1.0.5/node_modules/is-date-object/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var getDay = Date.prototype.getDay; + var tryDateObject = function tryDateGetDayCall(value) { + try { + getDay.call(value); + return true; + } catch (e) { + return false; + } + }; + var toStr = Object.prototype.toString; + var dateClass = "[object Date]"; + var hasToStringTag = require_shams2()(); + module2.exports = function isDateObject(value) { + if (typeof value !== "object" || value === null) { + return false; + } + return hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass; + }; + } +}); + +// node_modules/.pnpm/is-regex@1.1.4/node_modules/is-regex/index.js +var require_is_regex = __commonJS({ + "node_modules/.pnpm/is-regex@1.1.4/node_modules/is-regex/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var callBound = require_callBound(); + var hasToStringTag = require_shams2()(); + var has; + var $exec; + var isRegexMarker; + var badStringifier; + if (hasToStringTag) { + has = callBound("Object.prototype.hasOwnProperty"); + $exec = callBound("RegExp.prototype.exec"); + isRegexMarker = {}; + throwRegexMarker = function() { + throw isRegexMarker; + }; + badStringifier = { + toString: throwRegexMarker, + valueOf: throwRegexMarker + }; + if (typeof Symbol.toPrimitive === "symbol") { + badStringifier[Symbol.toPrimitive] = throwRegexMarker; + } + } + var throwRegexMarker; + var $toString = callBound("Object.prototype.toString"); + var gOPD = Object.getOwnPropertyDescriptor; + var regexClass = "[object RegExp]"; + module2.exports = hasToStringTag ? function isRegex(value) { + if (!value || typeof value !== "object") { + return false; + } + var descriptor = gOPD(value, "lastIndex"); + var hasLastIndexDataProperty = descriptor && has(descriptor, "value"); + if (!hasLastIndexDataProperty) { + return false; + } + try { + $exec(value, badStringifier); + } catch (e) { + return e === isRegexMarker; + } + } : function isRegex(value) { + if (!value || typeof value !== "object" && typeof value !== "function") { + return false; + } + return $toString(value) === regexClass; + }; + } +}); + +// node_modules/.pnpm/is-shared-array-buffer@1.0.2/node_modules/is-shared-array-buffer/index.js +var require_is_shared_array_buffer = __commonJS({ + "node_modules/.pnpm/is-shared-array-buffer@1.0.2/node_modules/is-shared-array-buffer/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var callBound = require_callBound(); + var $byteLength = callBound("SharedArrayBuffer.prototype.byteLength", true); + module2.exports = $byteLength ? function isSharedArrayBuffer(obj) { + if (!obj || typeof obj !== "object") { + return false; + } + try { + $byteLength(obj); + return true; + } catch (e) { + return false; + } + } : function isSharedArrayBuffer(obj) { + return false; + }; + } +}); + +// node_modules/.pnpm/is-number-object@1.0.7/node_modules/is-number-object/index.js +var require_is_number_object = __commonJS({ + "node_modules/.pnpm/is-number-object@1.0.7/node_modules/is-number-object/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var numToStr = Number.prototype.toString; + var tryNumberObject = function tryNumberObject2(value) { + try { + numToStr.call(value); + return true; + } catch (e) { + return false; + } + }; + var toStr = Object.prototype.toString; + var numClass = "[object Number]"; + var hasToStringTag = require_shams2()(); + module2.exports = function isNumberObject(value) { + if (typeof value === "number") { + return true; + } + if (typeof value !== "object") { + return false; + } + return hasToStringTag ? tryNumberObject(value) : toStr.call(value) === numClass; + }; + } +}); + +// node_modules/.pnpm/is-boolean-object@1.1.2/node_modules/is-boolean-object/index.js +var require_is_boolean_object = __commonJS({ + "node_modules/.pnpm/is-boolean-object@1.1.2/node_modules/is-boolean-object/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var callBound = require_callBound(); + var $boolToStr = callBound("Boolean.prototype.toString"); + var $toString = callBound("Object.prototype.toString"); + var tryBooleanObject = function booleanBrandCheck(value) { + try { + $boolToStr(value); + return true; + } catch (e) { + return false; + } + }; + var boolClass = "[object Boolean]"; + var hasToStringTag = require_shams2()(); + module2.exports = function isBoolean(value) { + if (typeof value === "boolean") { + return true; + } + if (value === null || typeof value !== "object") { + return false; + } + return hasToStringTag && Symbol.toStringTag in value ? tryBooleanObject(value) : $toString(value) === boolClass; + }; + } +}); + +// node_modules/.pnpm/is-symbol@1.0.4/node_modules/is-symbol/index.js +var require_is_symbol = __commonJS({ + "node_modules/.pnpm/is-symbol@1.0.4/node_modules/is-symbol/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var toStr = Object.prototype.toString; + var hasSymbols = require_has_symbols()(); + if (hasSymbols) { + symToStr = Symbol.prototype.toString; + symStringRegex = /^Symbol\(.*\)$/; + isSymbolObject = function isRealSymbolObject(value) { + if (typeof value.valueOf() !== "symbol") { + return false; + } + return symStringRegex.test(symToStr.call(value)); + }; + module2.exports = function isSymbol(value) { + if (typeof value === "symbol") { + return true; + } + if (toStr.call(value) !== "[object Symbol]") { + return false; + } + try { + return isSymbolObject(value); + } catch (e) { + return false; + } + }; + } else { + module2.exports = function isSymbol(value) { + return false; + }; + } + var symToStr; + var symStringRegex; + var isSymbolObject; + } +}); + +// node_modules/.pnpm/has-bigints@1.0.2/node_modules/has-bigints/index.js +var require_has_bigints = __commonJS({ + "node_modules/.pnpm/has-bigints@1.0.2/node_modules/has-bigints/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var $BigInt = typeof BigInt !== "undefined" && BigInt; + module2.exports = function hasNativeBigInts() { + return typeof $BigInt === "function" && typeof BigInt === "function" && typeof $BigInt(42) === "bigint" && typeof BigInt(42) === "bigint"; + }; + } +}); + +// node_modules/.pnpm/is-bigint@1.0.4/node_modules/is-bigint/index.js +var require_is_bigint = __commonJS({ + "node_modules/.pnpm/is-bigint@1.0.4/node_modules/is-bigint/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var hasBigInts = require_has_bigints()(); + if (hasBigInts) { + bigIntValueOf = BigInt.prototype.valueOf; + tryBigInt = function tryBigIntObject(value) { + try { + bigIntValueOf.call(value); + return true; + } catch (e) { + } + return false; + }; + module2.exports = function isBigInt(value) { + if (value === null || typeof value === "undefined" || typeof value === "boolean" || typeof value === "string" || typeof value === "number" || typeof value === "symbol" || typeof value === "function") { + return false; + } + if (typeof value === "bigint") { + return true; + } + return tryBigInt(value); + }; + } else { + module2.exports = function isBigInt(value) { + return false; + }; + } + var bigIntValueOf; + var tryBigInt; + } +}); + +// node_modules/.pnpm/which-boxed-primitive@1.0.2/node_modules/which-boxed-primitive/index.js +var require_which_boxed_primitive = __commonJS({ + "node_modules/.pnpm/which-boxed-primitive@1.0.2/node_modules/which-boxed-primitive/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var isString = require_is_string(); + var isNumber = require_is_number_object(); + var isBoolean = require_is_boolean_object(); + var isSymbol = require_is_symbol(); + var isBigInt = require_is_bigint(); + module2.exports = function whichBoxedPrimitive(value) { + if (value == null || typeof value !== "object" && typeof value !== "function") { + return null; + } + if (isString(value)) { + return "String"; + } + if (isNumber(value)) { + return "Number"; + } + if (isBoolean(value)) { + return "Boolean"; + } + if (isSymbol(value)) { + return "Symbol"; + } + if (isBigInt(value)) { + return "BigInt"; + } + }; + } +}); + +// node_modules/.pnpm/is-weakmap@2.0.1/node_modules/is-weakmap/index.js +var require_is_weakmap = __commonJS({ + "node_modules/.pnpm/is-weakmap@2.0.1/node_modules/is-weakmap/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var $WeakMap = typeof WeakMap === "function" && WeakMap.prototype ? WeakMap : null; + var $WeakSet = typeof WeakSet === "function" && WeakSet.prototype ? WeakSet : null; + var exported; + if (!$WeakMap) { + exported = function isWeakMap(x) { + return false; + }; + } + var $mapHas = $WeakMap ? $WeakMap.prototype.has : null; + var $setHas = $WeakSet ? $WeakSet.prototype.has : null; + if (!exported && !$mapHas) { + exported = function isWeakMap(x) { + return false; + }; + } + module2.exports = exported || function isWeakMap(x) { + if (!x || typeof x !== "object") { + return false; + } + try { + $mapHas.call(x, $mapHas); + if ($setHas) { + try { + $setHas.call(x, $setHas); + } catch (e) { + return true; + } + } + return x instanceof $WeakMap; + } catch (e) { + } + return false; + }; + } +}); + +// node_modules/.pnpm/is-weakset@2.0.2/node_modules/is-weakset/index.js +var require_is_weakset = __commonJS({ + "node_modules/.pnpm/is-weakset@2.0.2/node_modules/is-weakset/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var GetIntrinsic = require_get_intrinsic(); + var callBound = require_callBound(); + var $WeakSet = GetIntrinsic("%WeakSet%", true); + var $setHas = callBound("WeakSet.prototype.has", true); + if ($setHas) { + $mapHas = callBound("WeakMap.prototype.has", true); + module2.exports = function isWeakSet(x) { + if (!x || typeof x !== "object") { + return false; + } + try { + $setHas(x, $setHas); + if ($mapHas) { + try { + $mapHas(x, $mapHas); + } catch (e) { + return true; + } + } + return x instanceof $WeakSet; + } catch (e) { + } + return false; + }; + } else { + module2.exports = function isWeakSet(x) { + return false; + }; + } + var $mapHas; + } +}); + +// node_modules/.pnpm/which-collection@1.0.1/node_modules/which-collection/index.js +var require_which_collection = __commonJS({ + "node_modules/.pnpm/which-collection@1.0.1/node_modules/which-collection/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var isMap = require_is_map(); + var isSet = require_is_set(); + var isWeakMap = require_is_weakmap(); + var isWeakSet = require_is_weakset(); + module2.exports = function whichCollection(value) { + if (value && typeof value === "object") { + if (isMap(value)) { + return "Map"; + } + if (isSet(value)) { + return "Set"; + } + if (isWeakMap(value)) { + return "WeakMap"; + } + if (isWeakSet(value)) { + return "WeakSet"; + } + } + return false; + }; + } +}); + +// node_modules/.pnpm/which-typed-array@1.1.9/node_modules/which-typed-array/index.js +var require_which_typed_array = __commonJS({ + "node_modules/.pnpm/which-typed-array@1.1.9/node_modules/which-typed-array/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var forEach2 = require_for_each(); + var availableTypedArrays = require_available_typed_arrays(); + var callBound = require_callBound(); + var gOPD = require_gopd(); + var $toString = callBound("Object.prototype.toString"); + var hasToStringTag = require_shams2()(); + var g = typeof globalThis === "undefined" ? global : globalThis; + var typedArrays = availableTypedArrays(); + var $slice = callBound("String.prototype.slice"); + var toStrTags = {}; + var getPrototypeOf = Object.getPrototypeOf; + if (hasToStringTag && gOPD && getPrototypeOf) { + forEach2(typedArrays, function(typedArray) { + if (typeof g[typedArray] === "function") { + var arr = new g[typedArray](); + if (Symbol.toStringTag in arr) { + var proto = getPrototypeOf(arr); + var descriptor = gOPD(proto, Symbol.toStringTag); + if (!descriptor) { + var superProto = getPrototypeOf(proto); + descriptor = gOPD(superProto, Symbol.toStringTag); + } + toStrTags[typedArray] = descriptor.get; + } + } + }); + } + var tryTypedArrays = function tryAllTypedArrays(value) { + var foundName = false; + forEach2(toStrTags, function(getter, typedArray) { + if (!foundName) { + try { + var name = getter.call(value); + if (name === typedArray) { + foundName = name; + } + } catch (e) { + } + } + }); + return foundName; + }; + var isTypedArray = require_is_typed_array(); + module2.exports = function whichTypedArray(value) { + if (!isTypedArray(value)) { + return false; + } + if (!hasToStringTag || !(Symbol.toStringTag in value)) { + return $slice($toString(value), 8, -1); + } + return tryTypedArrays(value); + }; + } +}); + +// node_modules/.pnpm/array-buffer-byte-length@1.0.0/node_modules/array-buffer-byte-length/index.js +var require_array_buffer_byte_length = __commonJS({ + "node_modules/.pnpm/array-buffer-byte-length@1.0.0/node_modules/array-buffer-byte-length/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var callBound = require_callBound(); + var $byteLength = callBound("ArrayBuffer.prototype.byteLength", true); + var isArrayBuffer = require_is_array_buffer(); + module2.exports = function byteLength(ab) { + if (!isArrayBuffer(ab)) { + return NaN; + } + return $byteLength ? $byteLength(ab) : ab.byteLength; + }; + } +}); + +// node_modules/.pnpm/deep-equal@2.2.1/node_modules/deep-equal/index.js +var require_deep_equal = __commonJS({ + "node_modules/.pnpm/deep-equal@2.2.1/node_modules/deep-equal/index.js"(exports2, module2) { + "use strict"; + init_polyfill_buffer(); + var assign2 = require_object(); + var callBound = require_callBound(); + var flags = require_regexp_prototype(); + var GetIntrinsic = require_get_intrinsic(); + var getIterator3 = require_es_get_iterator(); + var getSideChannel = require_side_channel(); + var is = require_object_is(); + var isArguments = require_is_arguments(); + var isArray = require_isarray(); + var isArrayBuffer = require_is_array_buffer(); + var isDate = require_is_date_object(); + var isRegex = require_is_regex(); + var isSharedArrayBuffer = require_is_shared_array_buffer(); + var objectKeys = require_object_keys(); + var whichBoxedPrimitive = require_which_boxed_primitive(); + var whichCollection = require_which_collection(); + var whichTypedArray = require_which_typed_array(); + var byteLength = require_array_buffer_byte_length(); + var sabByteLength = callBound("SharedArrayBuffer.prototype.byteLength", true); + var $getTime = callBound("Date.prototype.getTime"); + var gPO = Object.getPrototypeOf; + var $objToString = callBound("Object.prototype.toString"); + var $Set = GetIntrinsic("%Set%", true); + var $mapHas = callBound("Map.prototype.has", true); + var $mapGet = callBound("Map.prototype.get", true); + var $mapSize = callBound("Map.prototype.size", true); + var $setAdd = callBound("Set.prototype.add", true); + var $setDelete = callBound("Set.prototype.delete", true); + var $setHas = callBound("Set.prototype.has", true); + var $setSize = callBound("Set.prototype.size", true); + function setHasEqualElement(set, val1, opts, channel) { + var i = getIterator3(set); + var result; + while ((result = i.next()) && !result.done) { + if (internalDeepEqual(val1, result.value, opts, channel)) { + $setDelete(set, result.value); + return true; + } + } + return false; + } + function findLooseMatchingPrimitives(prim) { + if (typeof prim === "undefined") { + return null; + } + if (typeof prim === "object") { + return void 0; + } + if (typeof prim === "symbol") { + return false; + } + if (typeof prim === "string" || typeof prim === "number") { + return +prim === +prim; + } + return true; + } + function mapMightHaveLoosePrim(a, b, prim, item, opts, channel) { + var altValue = findLooseMatchingPrimitives(prim); + if (altValue != null) { + return altValue; + } + var curB = $mapGet(b, altValue); + var looseOpts = assign2({}, opts, { strict: false }); + if (typeof curB === "undefined" && !$mapHas(b, altValue) || !internalDeepEqual(item, curB, looseOpts, channel)) { + return false; + } + return !$mapHas(a, altValue) && internalDeepEqual(item, curB, looseOpts, channel); + } + function setMightHaveLoosePrim(a, b, prim) { + var altValue = findLooseMatchingPrimitives(prim); + if (altValue != null) { + return altValue; + } + return $setHas(b, altValue) && !$setHas(a, altValue); + } + function mapHasEqualEntry(set, map, key1, item1, opts, channel) { + var i = getIterator3(set); + var result; + var key2; + while ((result = i.next()) && !result.done) { + key2 = result.value; + if ( + // eslint-disable-next-line no-use-before-define + internalDeepEqual(key1, key2, opts, channel) && internalDeepEqual(item1, $mapGet(map, key2), opts, channel) + ) { + $setDelete(set, key2); + return true; + } + } + return false; + } + function internalDeepEqual(actual, expected, options, channel) { + var opts = options || {}; + if (opts.strict ? is(actual, expected) : actual === expected) { + return true; + } + var actualBoxed = whichBoxedPrimitive(actual); + var expectedBoxed = whichBoxedPrimitive(expected); + if (actualBoxed !== expectedBoxed) { + return false; + } + if (!actual || !expected || typeof actual !== "object" && typeof expected !== "object") { + return opts.strict ? is(actual, expected) : actual == expected; + } + var hasActual = channel.has(actual); + var hasExpected = channel.has(expected); + var sentinel; + if (hasActual && hasExpected) { + if (channel.get(actual) === channel.get(expected)) { + return true; + } + } else { + sentinel = {}; + } + if (!hasActual) { + channel.set(actual, sentinel); + } + if (!hasExpected) { + channel.set(expected, sentinel); + } + return objEquiv(actual, expected, opts, channel); + } + function isBuffer(x) { + if (!x || typeof x !== "object" || typeof x.length !== "number") { + return false; + } + if (typeof x.copy !== "function" || typeof x.slice !== "function") { + return false; + } + if (x.length > 0 && typeof x[0] !== "number") { + return false; + } + return !!(x.constructor && x.constructor.isBuffer && x.constructor.isBuffer(x)); + } + function setEquiv(a, b, opts, channel) { + if ($setSize(a) !== $setSize(b)) { + return false; + } + var iA = getIterator3(a); + var iB = getIterator3(b); + var resultA; + var resultB; + var set; + while ((resultA = iA.next()) && !resultA.done) { + if (resultA.value && typeof resultA.value === "object") { + if (!set) { + set = new $Set(); + } + $setAdd(set, resultA.value); + } else if (!$setHas(b, resultA.value)) { + if (opts.strict) { + return false; + } + if (!setMightHaveLoosePrim(a, b, resultA.value)) { + return false; + } + if (!set) { + set = new $Set(); + } + $setAdd(set, resultA.value); + } + } + if (set) { + while ((resultB = iB.next()) && !resultB.done) { + if (resultB.value && typeof resultB.value === "object") { + if (!setHasEqualElement(set, resultB.value, opts.strict, channel)) { + return false; + } + } else if (!opts.strict && !$setHas(a, resultB.value) && !setHasEqualElement(set, resultB.value, opts.strict, channel)) { + return false; + } + } + return $setSize(set) === 0; + } + return true; + } + function mapEquiv(a, b, opts, channel) { + if ($mapSize(a) !== $mapSize(b)) { + return false; + } + var iA = getIterator3(a); + var iB = getIterator3(b); + var resultA; + var resultB; + var set; + var key2; + var item1; + var item2; + while ((resultA = iA.next()) && !resultA.done) { + key2 = resultA.value[0]; + item1 = resultA.value[1]; + if (key2 && typeof key2 === "object") { + if (!set) { + set = new $Set(); + } + $setAdd(set, key2); + } else { + item2 = $mapGet(b, key2); + if (typeof item2 === "undefined" && !$mapHas(b, key2) || !internalDeepEqual(item1, item2, opts, channel)) { + if (opts.strict) { + return false; + } + if (!mapMightHaveLoosePrim(a, b, key2, item1, opts, channel)) { + return false; + } + if (!set) { + set = new $Set(); + } + $setAdd(set, key2); + } + } + } + if (set) { + while ((resultB = iB.next()) && !resultB.done) { + key2 = resultB.value[0]; + item2 = resultB.value[1]; + if (key2 && typeof key2 === "object") { + if (!mapHasEqualEntry(set, a, key2, item2, opts, channel)) { + return false; + } + } else if (!opts.strict && (!a.has(key2) || !internalDeepEqual($mapGet(a, key2), item2, opts, channel)) && !mapHasEqualEntry(set, a, key2, item2, assign2({}, opts, { strict: false }), channel)) { + return false; + } + } + return $setSize(set) === 0; + } + return true; + } + function objEquiv(a, b, opts, channel) { + var i, key2; + if (typeof a !== typeof b) { + return false; + } + if (a == null || b == null) { + return false; + } + if ($objToString(a) !== $objToString(b)) { + return false; + } + if (isArguments(a) !== isArguments(b)) { + return false; + } + var aIsArray = isArray(a); + var bIsArray = isArray(b); + if (aIsArray !== bIsArray) { + return false; + } + var aIsError = a instanceof Error; + var bIsError = b instanceof Error; + if (aIsError !== bIsError) { + return false; + } + if (aIsError || bIsError) { + if (a.name !== b.name || a.message !== b.message) { + return false; + } + } + var aIsRegex = isRegex(a); + var bIsRegex = isRegex(b); + if (aIsRegex !== bIsRegex) { + return false; + } + if ((aIsRegex || bIsRegex) && (a.source !== b.source || flags(a) !== flags(b))) { + return false; + } + var aIsDate = isDate(a); + var bIsDate = isDate(b); + if (aIsDate !== bIsDate) { + return false; + } + if (aIsDate || bIsDate) { + if ($getTime(a) !== $getTime(b)) { + return false; + } + } + if (opts.strict && gPO && gPO(a) !== gPO(b)) { + return false; + } + var aWhich = whichTypedArray(a); + var bWhich = whichTypedArray(b); + if ((aWhich || bWhich) && aWhich !== bWhich) { + return false; + } + var aIsBuffer = isBuffer(a); + var bIsBuffer = isBuffer(b); + if (aIsBuffer !== bIsBuffer) { + return false; + } + if (aIsBuffer || bIsBuffer) { + if (a.length !== b.length) { + return false; + } + for (i = 0; i < a.length; i++) { + if (a[i] !== b[i]) { + return false; + } + } + return true; + } + var aIsArrayBuffer = isArrayBuffer(a); + var bIsArrayBuffer = isArrayBuffer(b); + if (aIsArrayBuffer !== bIsArrayBuffer) { + return false; + } + if (aIsArrayBuffer || bIsArrayBuffer) { + if (byteLength(a) !== byteLength(b)) { + return false; + } + return typeof Uint8Array === "function" && internalDeepEqual(new Uint8Array(a), new Uint8Array(b), opts, channel); + } + var aIsSAB = isSharedArrayBuffer(a); + var bIsSAB = isSharedArrayBuffer(b); + if (aIsSAB !== bIsSAB) { + return false; + } + if (aIsSAB || bIsSAB) { + if (sabByteLength(a) !== sabByteLength(b)) { + return false; + } + return typeof Uint8Array === "function" && internalDeepEqual(new Uint8Array(a), new Uint8Array(b), opts, channel); + } + if (typeof a !== typeof b) { + return false; + } + var ka = objectKeys(a); + var kb = objectKeys(b); + if (ka.length !== kb.length) { + return false; + } + ka.sort(); + kb.sort(); + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) { + return false; + } + } + for (i = ka.length - 1; i >= 0; i--) { + key2 = ka[i]; + if (!internalDeepEqual(a[key2], b[key2], opts, channel)) { + return false; + } + } + var aCollection = whichCollection(a); + var bCollection = whichCollection(b); + if (aCollection !== bCollection) { + return false; + } + if (aCollection === "Set" || bCollection === "Set") { + return setEquiv(a, b, opts, channel); + } + if (aCollection === "Map") { + return mapEquiv(a, b, opts, channel); + } + return true; + } + module2.exports = function deepEqual2(a, b, opts) { + return internalDeepEqual(a, b, opts, getSideChannel()); + }; + } +}); + +// node_modules/.pnpm/js-sha256@0.9.0/node_modules/js-sha256/src/sha256.js +var require_sha256 = __commonJS({ + "node_modules/.pnpm/js-sha256@0.9.0/node_modules/js-sha256/src/sha256.js"(exports, module) { + init_polyfill_buffer(); + (function() { + "use strict"; + var ERROR = "input is invalid type"; + var WINDOW = typeof window === "object"; + var root = WINDOW ? window : {}; + if (root.JS_SHA256_NO_WINDOW) { + WINDOW = false; + } + var WEB_WORKER = !WINDOW && typeof self === "object"; + var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === "object" && process.versions && process.versions.node; + if (NODE_JS) { + root = global; + } else if (WEB_WORKER) { + root = self; + } + var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === "object" && module.exports; + var AMD = typeof define === "function" && define.amd; + var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== "undefined"; + var HEX_CHARS = "0123456789abcdef".split(""); + var EXTRA = [-2147483648, 8388608, 32768, 128]; + var SHIFT = [24, 16, 8, 0]; + var K = [ + 1116352408, + 1899447441, + 3049323471, + 3921009573, + 961987163, + 1508970993, + 2453635748, + 2870763221, + 3624381080, + 310598401, + 607225278, + 1426881987, + 1925078388, + 2162078206, + 2614888103, + 3248222580, + 3835390401, + 4022224774, + 264347078, + 604807628, + 770255983, + 1249150122, + 1555081692, + 1996064986, + 2554220882, + 2821834349, + 2952996808, + 3210313671, + 3336571891, + 3584528711, + 113926993, + 338241895, + 666307205, + 773529912, + 1294757372, + 1396182291, + 1695183700, + 1986661051, + 2177026350, + 2456956037, + 2730485921, + 2820302411, + 3259730800, + 3345764771, + 3516065817, + 3600352804, + 4094571909, + 275423344, + 430227734, + 506948616, + 659060556, + 883997877, + 958139571, + 1322822218, + 1537002063, + 1747873779, + 1955562222, + 2024104815, + 2227730452, + 2361852424, + 2428436474, + 2756734187, + 3204031479, + 3329325298 + ]; + var OUTPUT_TYPES = ["hex", "array", "digest", "arrayBuffer"]; + var blocks = []; + if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) { + Array.isArray = function(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + } + if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) { + ArrayBuffer.isView = function(obj) { + return typeof obj === "object" && obj.buffer && obj.buffer.constructor === ArrayBuffer; + }; + } + var createOutputMethod = function(outputType, is2242) { + return function(message) { + return new Sha256(is2242, true).update(message)[outputType](); + }; + }; + var createMethod = function(is2242) { + var method2 = createOutputMethod("hex", is2242); + if (NODE_JS) { + method2 = nodeWrap(method2, is2242); + } + method2.create = function() { + return new Sha256(is2242); + }; + method2.update = function(message) { + return method2.create().update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method2[type] = createOutputMethod(type, is2242); + } + return method2; + }; + var nodeWrap = function(method, is224) { + var crypto = eval("require('crypto')"); + var Buffer = eval("require('buffer').Buffer"); + var algorithm = is224 ? "sha224" : "sha256"; + var nodeMethod = function(message) { + if (typeof message === "string") { + return crypto.createHash(algorithm).update(message, "utf8").digest("hex"); + } else { + if (message === null || message === void 0) { + throw new Error(ERROR); + } else if (message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } + } + if (Array.isArray(message) || ArrayBuffer.isView(message) || message.constructor === Buffer) { + return crypto.createHash(algorithm).update(new Buffer(message)).digest("hex"); + } else { + return method(message); + } + }; + return nodeMethod; + }; + var createHmacOutputMethod = function(outputType, is2242) { + return function(key2, message) { + return new HmacSha256(key2, is2242, true).update(message)[outputType](); + }; + }; + var createHmacMethod = function(is2242) { + var method2 = createHmacOutputMethod("hex", is2242); + method2.create = function(key2) { + return new HmacSha256(key2, is2242); + }; + method2.update = function(key2, message) { + return method2.create(key2).update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method2[type] = createHmacOutputMethod(type, is2242); + } + return method2; + }; + function Sha256(is2242, sharedMemory) { + if (sharedMemory) { + blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + this.blocks = blocks; + } else { + this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + if (is2242) { + this.h0 = 3238371032; + this.h1 = 914150663; + this.h2 = 812702999; + this.h3 = 4144912697; + this.h4 = 4290775857; + this.h5 = 1750603025; + this.h6 = 1694076839; + this.h7 = 3204075428; + } else { + this.h0 = 1779033703; + this.h1 = 3144134277; + this.h2 = 1013904242; + this.h3 = 2773480762; + this.h4 = 1359893119; + this.h5 = 2600822924; + this.h6 = 528734635; + this.h7 = 1541459225; + } + this.block = this.start = this.bytes = this.hBytes = 0; + this.finalized = this.hashed = false; + this.first = true; + this.is224 = is2242; + } + Sha256.prototype.update = function(message) { + if (this.finalized) { + return; + } + var notString, type = typeof message; + if (type !== "string") { + if (type === "object") { + if (message === null) { + throw new Error(ERROR); + } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } else if (!Array.isArray(message)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { + throw new Error(ERROR); + } + } + } else { + throw new Error(ERROR); + } + notString = true; + } + var code, index2 = 0, i, length = message.length, blocks2 = this.blocks; + while (index2 < length) { + if (this.hashed) { + this.hashed = false; + blocks2[0] = this.block; + blocks2[16] = blocks2[1] = blocks2[2] = blocks2[3] = blocks2[4] = blocks2[5] = blocks2[6] = blocks2[7] = blocks2[8] = blocks2[9] = blocks2[10] = blocks2[11] = blocks2[12] = blocks2[13] = blocks2[14] = blocks2[15] = 0; + } + if (notString) { + for (i = this.start; index2 < length && i < 64; ++index2) { + blocks2[i >> 2] |= message[index2] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start; index2 < length && i < 64; ++index2) { + code = message.charCodeAt(index2); + if (code < 128) { + blocks2[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 2048) { + blocks2[i >> 2] |= (192 | code >> 6) << SHIFT[i++ & 3]; + blocks2[i >> 2] |= (128 | code & 63) << SHIFT[i++ & 3]; + } else if (code < 55296 || code >= 57344) { + blocks2[i >> 2] |= (224 | code >> 12) << SHIFT[i++ & 3]; + blocks2[i >> 2] |= (128 | code >> 6 & 63) << SHIFT[i++ & 3]; + blocks2[i >> 2] |= (128 | code & 63) << SHIFT[i++ & 3]; + } else { + code = 65536 + ((code & 1023) << 10 | message.charCodeAt(++index2) & 1023); + blocks2[i >> 2] |= (240 | code >> 18) << SHIFT[i++ & 3]; + blocks2[i >> 2] |= (128 | code >> 12 & 63) << SHIFT[i++ & 3]; + blocks2[i >> 2] |= (128 | code >> 6 & 63) << SHIFT[i++ & 3]; + blocks2[i >> 2] |= (128 | code & 63) << SHIFT[i++ & 3]; + } + } + } + this.lastByteIndex = i; + this.bytes += i - this.start; + if (i >= 64) { + this.block = blocks2[16]; + this.start = i - 64; + this.hash(); + this.hashed = true; + } else { + this.start = i; + } + } + if (this.bytes > 4294967295) { + this.hBytes += this.bytes / 4294967296 << 0; + this.bytes = this.bytes % 4294967296; + } + return this; + }; + Sha256.prototype.finalize = function() { + if (this.finalized) { + return; + } + this.finalized = true; + var blocks2 = this.blocks, i = this.lastByteIndex; + blocks2[16] = this.block; + blocks2[i >> 2] |= EXTRA[i & 3]; + this.block = blocks2[16]; + if (i >= 56) { + if (!this.hashed) { + this.hash(); + } + blocks2[0] = this.block; + blocks2[16] = blocks2[1] = blocks2[2] = blocks2[3] = blocks2[4] = blocks2[5] = blocks2[6] = blocks2[7] = blocks2[8] = blocks2[9] = blocks2[10] = blocks2[11] = blocks2[12] = blocks2[13] = blocks2[14] = blocks2[15] = 0; + } + blocks2[14] = this.hBytes << 3 | this.bytes >>> 29; + blocks2[15] = this.bytes << 3; + this.hash(); + }; + Sha256.prototype.hash = function() { + var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6, h = this.h7, blocks2 = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc; + for (j = 16; j < 64; ++j) { + t1 = blocks2[j - 15]; + s0 = (t1 >>> 7 | t1 << 25) ^ (t1 >>> 18 | t1 << 14) ^ t1 >>> 3; + t1 = blocks2[j - 2]; + s1 = (t1 >>> 17 | t1 << 15) ^ (t1 >>> 19 | t1 << 13) ^ t1 >>> 10; + blocks2[j] = blocks2[j - 16] + s0 + blocks2[j - 7] + s1 << 0; + } + bc = b & c; + for (j = 0; j < 64; j += 4) { + if (this.first) { + if (this.is224) { + ab = 300032; + t1 = blocks2[0] - 1413257819; + h = t1 - 150054599 << 0; + d = t1 + 24177077 << 0; + } else { + ab = 704751109; + t1 = blocks2[0] - 210244248; + h = t1 - 1521486534 << 0; + d = t1 + 143694565 << 0; + } + this.first = false; + } else { + s0 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10); + s1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7); + ab = a & b; + maj = ab ^ a & c ^ bc; + ch = e & f ^ ~e & g; + t1 = h + s1 + ch + K[j] + blocks2[j]; + t2 = s0 + maj; + h = d + t1 << 0; + d = t1 + t2 << 0; + } + s0 = (d >>> 2 | d << 30) ^ (d >>> 13 | d << 19) ^ (d >>> 22 | d << 10); + s1 = (h >>> 6 | h << 26) ^ (h >>> 11 | h << 21) ^ (h >>> 25 | h << 7); + da = d & a; + maj = da ^ d & b ^ ab; + ch = h & e ^ ~h & f; + t1 = g + s1 + ch + K[j + 1] + blocks2[j + 1]; + t2 = s0 + maj; + g = c + t1 << 0; + c = t1 + t2 << 0; + s0 = (c >>> 2 | c << 30) ^ (c >>> 13 | c << 19) ^ (c >>> 22 | c << 10); + s1 = (g >>> 6 | g << 26) ^ (g >>> 11 | g << 21) ^ (g >>> 25 | g << 7); + cd = c & d; + maj = cd ^ c & a ^ da; + ch = g & h ^ ~g & e; + t1 = f + s1 + ch + K[j + 2] + blocks2[j + 2]; + t2 = s0 + maj; + f = b + t1 << 0; + b = t1 + t2 << 0; + s0 = (b >>> 2 | b << 30) ^ (b >>> 13 | b << 19) ^ (b >>> 22 | b << 10); + s1 = (f >>> 6 | f << 26) ^ (f >>> 11 | f << 21) ^ (f >>> 25 | f << 7); + bc = b & c; + maj = bc ^ b & d ^ cd; + ch = f & g ^ ~f & h; + t1 = e + s1 + ch + K[j + 3] + blocks2[j + 3]; + t2 = s0 + maj; + e = a + t1 << 0; + a = t1 + t2 << 0; + } + this.h0 = this.h0 + a << 0; + this.h1 = this.h1 + b << 0; + this.h2 = this.h2 + c << 0; + this.h3 = this.h3 + d << 0; + this.h4 = this.h4 + e << 0; + this.h5 = this.h5 + f << 0; + this.h6 = this.h6 + g << 0; + this.h7 = this.h7 + h << 0; + }; + Sha256.prototype.hex = function() { + this.finalize(); + var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, h6 = this.h6, h7 = this.h7; + var hex = HEX_CHARS[h0 >> 28 & 15] + HEX_CHARS[h0 >> 24 & 15] + HEX_CHARS[h0 >> 20 & 15] + HEX_CHARS[h0 >> 16 & 15] + HEX_CHARS[h0 >> 12 & 15] + HEX_CHARS[h0 >> 8 & 15] + HEX_CHARS[h0 >> 4 & 15] + HEX_CHARS[h0 & 15] + HEX_CHARS[h1 >> 28 & 15] + HEX_CHARS[h1 >> 24 & 15] + HEX_CHARS[h1 >> 20 & 15] + HEX_CHARS[h1 >> 16 & 15] + HEX_CHARS[h1 >> 12 & 15] + HEX_CHARS[h1 >> 8 & 15] + HEX_CHARS[h1 >> 4 & 15] + HEX_CHARS[h1 & 15] + HEX_CHARS[h2 >> 28 & 15] + HEX_CHARS[h2 >> 24 & 15] + HEX_CHARS[h2 >> 20 & 15] + HEX_CHARS[h2 >> 16 & 15] + HEX_CHARS[h2 >> 12 & 15] + HEX_CHARS[h2 >> 8 & 15] + HEX_CHARS[h2 >> 4 & 15] + HEX_CHARS[h2 & 15] + HEX_CHARS[h3 >> 28 & 15] + HEX_CHARS[h3 >> 24 & 15] + HEX_CHARS[h3 >> 20 & 15] + HEX_CHARS[h3 >> 16 & 15] + HEX_CHARS[h3 >> 12 & 15] + HEX_CHARS[h3 >> 8 & 15] + HEX_CHARS[h3 >> 4 & 15] + HEX_CHARS[h3 & 15] + HEX_CHARS[h4 >> 28 & 15] + HEX_CHARS[h4 >> 24 & 15] + HEX_CHARS[h4 >> 20 & 15] + HEX_CHARS[h4 >> 16 & 15] + HEX_CHARS[h4 >> 12 & 15] + HEX_CHARS[h4 >> 8 & 15] + HEX_CHARS[h4 >> 4 & 15] + HEX_CHARS[h4 & 15] + HEX_CHARS[h5 >> 28 & 15] + HEX_CHARS[h5 >> 24 & 15] + HEX_CHARS[h5 >> 20 & 15] + HEX_CHARS[h5 >> 16 & 15] + HEX_CHARS[h5 >> 12 & 15] + HEX_CHARS[h5 >> 8 & 15] + HEX_CHARS[h5 >> 4 & 15] + HEX_CHARS[h5 & 15] + HEX_CHARS[h6 >> 28 & 15] + HEX_CHARS[h6 >> 24 & 15] + HEX_CHARS[h6 >> 20 & 15] + HEX_CHARS[h6 >> 16 & 15] + HEX_CHARS[h6 >> 12 & 15] + HEX_CHARS[h6 >> 8 & 15] + HEX_CHARS[h6 >> 4 & 15] + HEX_CHARS[h6 & 15]; + if (!this.is224) { + hex += HEX_CHARS[h7 >> 28 & 15] + HEX_CHARS[h7 >> 24 & 15] + HEX_CHARS[h7 >> 20 & 15] + HEX_CHARS[h7 >> 16 & 15] + HEX_CHARS[h7 >> 12 & 15] + HEX_CHARS[h7 >> 8 & 15] + HEX_CHARS[h7 >> 4 & 15] + HEX_CHARS[h7 & 15]; + } + return hex; + }; + Sha256.prototype.toString = Sha256.prototype.hex; + Sha256.prototype.digest = function() { + this.finalize(); + var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, h6 = this.h6, h7 = this.h7; + var arr = [ + h0 >> 24 & 255, + h0 >> 16 & 255, + h0 >> 8 & 255, + h0 & 255, + h1 >> 24 & 255, + h1 >> 16 & 255, + h1 >> 8 & 255, + h1 & 255, + h2 >> 24 & 255, + h2 >> 16 & 255, + h2 >> 8 & 255, + h2 & 255, + h3 >> 24 & 255, + h3 >> 16 & 255, + h3 >> 8 & 255, + h3 & 255, + h4 >> 24 & 255, + h4 >> 16 & 255, + h4 >> 8 & 255, + h4 & 255, + h5 >> 24 & 255, + h5 >> 16 & 255, + h5 >> 8 & 255, + h5 & 255, + h6 >> 24 & 255, + h6 >> 16 & 255, + h6 >> 8 & 255, + h6 & 255 + ]; + if (!this.is224) { + arr.push(h7 >> 24 & 255, h7 >> 16 & 255, h7 >> 8 & 255, h7 & 255); + } + return arr; + }; + Sha256.prototype.array = Sha256.prototype.digest; + Sha256.prototype.arrayBuffer = function() { + this.finalize(); + var buffer2 = new ArrayBuffer(this.is224 ? 28 : 32); + var dataView = new DataView(buffer2); + dataView.setUint32(0, this.h0); + dataView.setUint32(4, this.h1); + dataView.setUint32(8, this.h2); + dataView.setUint32(12, this.h3); + dataView.setUint32(16, this.h4); + dataView.setUint32(20, this.h5); + dataView.setUint32(24, this.h6); + if (!this.is224) { + dataView.setUint32(28, this.h7); + } + return buffer2; + }; + function HmacSha256(key2, is2242, sharedMemory) { + var i, type = typeof key2; + if (type === "string") { + var bytes = [], length = key2.length, index2 = 0, code; + for (i = 0; i < length; ++i) { + code = key2.charCodeAt(i); + if (code < 128) { + bytes[index2++] = code; + } else if (code < 2048) { + bytes[index2++] = 192 | code >> 6; + bytes[index2++] = 128 | code & 63; + } else if (code < 55296 || code >= 57344) { + bytes[index2++] = 224 | code >> 12; + bytes[index2++] = 128 | code >> 6 & 63; + bytes[index2++] = 128 | code & 63; + } else { + code = 65536 + ((code & 1023) << 10 | key2.charCodeAt(++i) & 1023); + bytes[index2++] = 240 | code >> 18; + bytes[index2++] = 128 | code >> 12 & 63; + bytes[index2++] = 128 | code >> 6 & 63; + bytes[index2++] = 128 | code & 63; + } + } + key2 = bytes; + } else { + if (type === "object") { + if (key2 === null) { + throw new Error(ERROR); + } else if (ARRAY_BUFFER && key2.constructor === ArrayBuffer) { + key2 = new Uint8Array(key2); + } else if (!Array.isArray(key2)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(key2)) { + throw new Error(ERROR); + } + } + } else { + throw new Error(ERROR); + } + } + if (key2.length > 64) { + key2 = new Sha256(is2242, true).update(key2).array(); + } + var oKeyPad = [], iKeyPad = []; + for (i = 0; i < 64; ++i) { + var b = key2[i] || 0; + oKeyPad[i] = 92 ^ b; + iKeyPad[i] = 54 ^ b; + } + Sha256.call(this, is2242, sharedMemory); + this.update(iKeyPad); + this.oKeyPad = oKeyPad; + this.inner = true; + this.sharedMemory = sharedMemory; + } + HmacSha256.prototype = new Sha256(); + HmacSha256.prototype.finalize = function() { + Sha256.prototype.finalize.call(this); + if (this.inner) { + this.inner = false; + var innerHash = this.array(); + Sha256.call(this, this.is224, this.sharedMemory); + this.update(this.oKeyPad); + this.update(innerHash); + Sha256.prototype.finalize.call(this); + } + }; + var exports = createMethod(); + exports.sha256 = exports; + exports.sha224 = createMethod(true); + exports.sha256.hmac = createHmacMethod(); + exports.sha224.hmac = createHmacMethod(true); + if (COMMON_JS) { + module.exports = exports; + } else { + root.sha256 = exports.sha256; + root.sha224 = exports.sha224; + if (AMD) { + define(function() { + return exports; + }); + } + } + })(); + } +}); + +// node_modules/.pnpm/hogan.js@3.0.2/node_modules/hogan.js/lib/compiler.js +var require_compiler = __commonJS({ + "node_modules/.pnpm/hogan.js@3.0.2/node_modules/hogan.js/lib/compiler.js"(exports2) { + init_polyfill_buffer(); + (function(Hogan4) { + var rIsWhitespace = /\S/, rQuot = /\"/g, rNewline = /\n/g, rCr = /\r/g, rSlash = /\\/g, rLineSep = /\u2028/, rParagraphSep = /\u2029/; + Hogan4.tags = { + "#": 1, + "^": 2, + "<": 3, + "$": 4, + "/": 5, + "!": 6, + ">": 7, + "=": 8, + "_v": 9, + "{": 10, + "&": 11, + "_t": 12 + }; + Hogan4.scan = function scan(text2, delimiters) { + var len = text2.length, IN_TEXT = 0, IN_TAG_TYPE = 1, IN_TAG = 2, state = IN_TEXT, tagType = null, tag2 = null, buf = "", tokens = [], seenTag = false, i = 0, lineStart = 0, otag = "{{", ctag = "}}"; + function addBuf() { + if (buf.length > 0) { + tokens.push({ tag: "_t", text: new String(buf) }); + buf = ""; + } + } + function lineIsWhitespace() { + var isAllWhitespace = true; + for (var j = lineStart; j < tokens.length; j++) { + isAllWhitespace = Hogan4.tags[tokens[j].tag] < Hogan4.tags["_v"] || tokens[j].tag == "_t" && tokens[j].text.match(rIsWhitespace) === null; + if (!isAllWhitespace) { + return false; + } + } + return isAllWhitespace; + } + function filterLine(haveSeenTag, noNewLine) { + addBuf(); + if (haveSeenTag && lineIsWhitespace()) { + for (var j = lineStart, next; j < tokens.length; j++) { + if (tokens[j].text) { + if ((next = tokens[j + 1]) && next.tag == ">") { + next.indent = tokens[j].text.toString(); + } + tokens.splice(j, 1); + } + } + } else if (!noNewLine) { + tokens.push({ tag: "\n" }); + } + seenTag = false; + lineStart = tokens.length; + } + function changeDelimiters(text3, index2) { + var close = "=" + ctag, closeIndex = text3.indexOf(close, index2), delimiters2 = trim( + text3.substring(text3.indexOf("=", index2) + 1, closeIndex) + ).split(" "); + otag = delimiters2[0]; + ctag = delimiters2[delimiters2.length - 1]; + return closeIndex + close.length - 1; + } + if (delimiters) { + delimiters = delimiters.split(" "); + otag = delimiters[0]; + ctag = delimiters[1]; + } + for (i = 0; i < len; i++) { + if (state == IN_TEXT) { + if (tagChange(otag, text2, i)) { + --i; + addBuf(); + state = IN_TAG_TYPE; + } else { + if (text2.charAt(i) == "\n") { + filterLine(seenTag); + } else { + buf += text2.charAt(i); + } + } + } else if (state == IN_TAG_TYPE) { + i += otag.length - 1; + tag2 = Hogan4.tags[text2.charAt(i + 1)]; + tagType = tag2 ? text2.charAt(i + 1) : "_v"; + if (tagType == "=") { + i = changeDelimiters(text2, i); + state = IN_TEXT; + } else { + if (tag2) { + i++; + } + state = IN_TAG; + } + seenTag = i; + } else { + if (tagChange(ctag, text2, i)) { + tokens.push({ + tag: tagType, + n: trim(buf), + otag, + ctag, + i: tagType == "/" ? seenTag - otag.length : i + ctag.length + }); + buf = ""; + i += ctag.length - 1; + state = IN_TEXT; + if (tagType == "{") { + if (ctag == "}}") { + i++; + } else { + cleanTripleStache(tokens[tokens.length - 1]); + } + } + } else { + buf += text2.charAt(i); + } + } + } + filterLine(seenTag, true); + return tokens; + }; + function cleanTripleStache(token) { + if (token.n.substr(token.n.length - 1) === "}") { + token.n = token.n.substring(0, token.n.length - 1); + } + } + function trim(s) { + if (s.trim) { + return s.trim(); + } + return s.replace(/^\s*|\s*$/g, ""); + } + function tagChange(tag2, text2, index2) { + if (text2.charAt(index2) != tag2.charAt(0)) { + return false; + } + for (var i = 1, l = tag2.length; i < l; i++) { + if (text2.charAt(index2 + i) != tag2.charAt(i)) { + return false; + } + } + return true; + } + var allowedInSuper = { "_t": true, "\n": true, "$": true, "/": true }; + function buildTree(tokens, kind, stack, customTags) { + var instructions = [], opener = null, tail = null, token = null; + tail = stack[stack.length - 1]; + while (tokens.length > 0) { + token = tokens.shift(); + if (tail && tail.tag == "<" && !(token.tag in allowedInSuper)) { + throw new Error("Illegal content in < super tag."); + } + if (Hogan4.tags[token.tag] <= Hogan4.tags["$"] || isOpener(token, customTags)) { + stack.push(token); + token.nodes = buildTree(tokens, token.tag, stack, customTags); + } else if (token.tag == "/") { + if (stack.length === 0) { + throw new Error("Closing tag without opener: /" + token.n); + } + opener = stack.pop(); + if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) { + throw new Error("Nesting error: " + opener.n + " vs. " + token.n); + } + opener.end = token.i; + return instructions; + } else if (token.tag == "\n") { + token.last = tokens.length == 0 || tokens[0].tag == "\n"; + } + instructions.push(token); + } + if (stack.length > 0) { + throw new Error("missing closing tag: " + stack.pop().n); + } + return instructions; + } + function isOpener(token, tags) { + for (var i = 0, l = tags.length; i < l; i++) { + if (tags[i].o == token.n) { + token.tag = "#"; + return true; + } + } + } + function isCloser(close, open, tags) { + for (var i = 0, l = tags.length; i < l; i++) { + if (tags[i].c == close && tags[i].o == open) { + return true; + } + } + } + function stringifySubstitutions(obj) { + var items = []; + for (var key2 in obj) { + items.push('"' + esc(key2) + '": function(c,p,t,i) {' + obj[key2] + "}"); + } + return "{ " + items.join(",") + " }"; + } + function stringifyPartials(codeObj) { + var partials = []; + for (var key2 in codeObj.partials) { + partials.push('"' + esc(key2) + '":{name:"' + esc(codeObj.partials[key2].name) + '", ' + stringifyPartials(codeObj.partials[key2]) + "}"); + } + return "partials: {" + partials.join(",") + "}, subs: " + stringifySubstitutions(codeObj.subs); + } + Hogan4.stringify = function(codeObj, text2, options) { + return "{code: function (c,p,i) { " + Hogan4.wrapMain(codeObj.code) + " }," + stringifyPartials(codeObj) + "}"; + }; + var serialNo = 0; + Hogan4.generate = function(tree, text2, options) { + serialNo = 0; + var context = { code: "", subs: {}, partials: {} }; + Hogan4.walk(tree, context); + if (options.asString) { + return this.stringify(context, text2, options); + } + return this.makeTemplate(context, text2, options); + }; + Hogan4.wrapMain = function(code) { + return 'var t=this;t.b(i=i||"");' + code + "return t.fl();"; + }; + Hogan4.template = Hogan4.Template; + Hogan4.makeTemplate = function(codeObj, text2, options) { + var template = this.makePartials(codeObj); + template.code = new Function("c", "p", "i", this.wrapMain(codeObj.code)); + return new this.template(template, text2, this, options); + }; + Hogan4.makePartials = function(codeObj) { + var key2, template = { subs: {}, partials: codeObj.partials, name: codeObj.name }; + for (key2 in template.partials) { + template.partials[key2] = this.makePartials(template.partials[key2]); + } + for (key2 in codeObj.subs) { + template.subs[key2] = new Function("c", "p", "t", "i", codeObj.subs[key2]); + } + return template; + }; + function esc(s) { + return s.replace(rSlash, "\\\\").replace(rQuot, '\\"').replace(rNewline, "\\n").replace(rCr, "\\r").replace(rLineSep, "\\u2028").replace(rParagraphSep, "\\u2029"); + } + function chooseMethod(s) { + return ~s.indexOf(".") ? "d" : "f"; + } + function createPartial(node, context) { + var prefix = "<" + (context.prefix || ""); + var sym = prefix + node.n + serialNo++; + context.partials[sym] = { name: node.n, partials: {} }; + context.code += 't.b(t.rp("' + esc(sym) + '",c,p,"' + (node.indent || "") + '"));'; + return sym; + } + Hogan4.codegen = { + "#": function(node, context) { + context.code += "if(t.s(t." + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,0,' + node.i + "," + node.end + ',"' + node.otag + " " + node.ctag + '")){t.rs(c,p,function(c,p,t){'; + Hogan4.walk(node.nodes, context); + context.code += "});c.pop();}"; + }, + "^": function(node, context) { + context.code += "if(!t.s(t." + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,1,0,0,"")){'; + Hogan4.walk(node.nodes, context); + context.code += "};"; + }, + ">": createPartial, + "<": function(node, context) { + var ctx = { partials: {}, code: "", subs: {}, inPartial: true }; + Hogan4.walk(node.nodes, ctx); + var template = context.partials[createPartial(node, context)]; + template.subs = ctx.subs; + template.partials = ctx.partials; + }, + "$": function(node, context) { + var ctx = { subs: {}, code: "", partials: context.partials, prefix: node.n }; + Hogan4.walk(node.nodes, ctx); + context.subs[node.n] = ctx.code; + if (!context.inPartial) { + context.code += 't.sub("' + esc(node.n) + '",c,p,i);'; + } + }, + "\n": function(node, context) { + context.code += write('"\\n"' + (node.last ? "" : " + i")); + }, + "_v": function(node, context) { + context.code += "t.b(t.v(t." + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));'; + }, + "_t": function(node, context) { + context.code += write('"' + esc(node.text) + '"'); + }, + "{": tripleStache, + "&": tripleStache + }; + function tripleStache(node, context) { + context.code += "t.b(t.t(t." + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));'; + } + function write(s) { + return "t.b(" + s + ");"; + } + Hogan4.walk = function(nodelist, context) { + var func; + for (var i = 0, l = nodelist.length; i < l; i++) { + func = Hogan4.codegen[nodelist[i].tag]; + func && func(nodelist[i], context); + } + return context; + }; + Hogan4.parse = function(tokens, text2, options) { + options = options || {}; + return buildTree(tokens, "", [], options.sectionTags || []); + }; + Hogan4.cache = {}; + Hogan4.cacheKey = function(text2, options) { + return [text2, !!options.asString, !!options.disableLambda, options.delimiters, !!options.modelGet].join("||"); + }; + Hogan4.compile = function(text2, options) { + options = options || {}; + var key2 = Hogan4.cacheKey(text2, options); + var template = this.cache[key2]; + if (template) { + var partials = template.partials; + for (var name in partials) { + delete partials[name].instance; + } + return template; + } + template = this.generate(this.parse(this.scan(text2, options.delimiters), text2, options), text2, options); + return this.cache[key2] = template; + }; + })(typeof exports2 !== "undefined" ? exports2 : Hogan); + } +}); + +// node_modules/.pnpm/hogan.js@3.0.2/node_modules/hogan.js/lib/template.js +var require_template = __commonJS({ + "node_modules/.pnpm/hogan.js@3.0.2/node_modules/hogan.js/lib/template.js"(exports2) { + init_polyfill_buffer(); + var Hogan4 = {}; + (function(Hogan5) { + Hogan5.Template = function(codeObj, text2, compiler, options) { + codeObj = codeObj || {}; + this.r = codeObj.code || this.r; + this.c = compiler; + this.options = options || {}; + this.text = text2 || ""; + this.partials = codeObj.partials || {}; + this.subs = codeObj.subs || {}; + this.buf = ""; + }; + Hogan5.Template.prototype = { + // render: replaced by generated code. + r: function(context, partials, indent2) { + return ""; + }, + // variable escaping + v: hoganEscape, + // triple stache + t: coerceToString, + render: function render2(context, partials, indent2) { + return this.ri([context], partials || {}, indent2); + }, + // render internal -- a hook for overrides that catches partials too + ri: function(context, partials, indent2) { + return this.r(context, partials, indent2); + }, + // ensurePartial + ep: function(symbol, partials) { + var partial = this.partials[symbol]; + var template = partials[partial.name]; + if (partial.instance && partial.base == template) { + return partial.instance; + } + if (typeof template == "string") { + if (!this.c) { + throw new Error("No compiler available."); + } + template = this.c.compile(template, this.options); + } + if (!template) { + return null; + } + this.partials[symbol].base = template; + if (partial.subs) { + if (!partials.stackText) + partials.stackText = {}; + for (key in partial.subs) { + if (!partials.stackText[key]) { + partials.stackText[key] = this.activeSub !== void 0 && partials.stackText[this.activeSub] ? partials.stackText[this.activeSub] : this.text; + } + } + template = createSpecializedPartial( + template, + partial.subs, + partial.partials, + this.stackSubs, + this.stackPartials, + partials.stackText + ); + } + this.partials[symbol].instance = template; + return template; + }, + // tries to find a partial in the current scope and render it + rp: function(symbol, context, partials, indent2) { + var partial = this.ep(symbol, partials); + if (!partial) { + return ""; + } + return partial.ri(context, partials, indent2); + }, + // render a section + rs: function(context, partials, section) { + var tail = context[context.length - 1]; + if (!isArray(tail)) { + section(context, partials, this); + return; + } + for (var i = 0; i < tail.length; i++) { + context.push(tail[i]); + section(context, partials, this); + context.pop(); + } + }, + // maybe start a section + s: function(val, ctx, partials, inverted, start, end, tags) { + var pass; + if (isArray(val) && val.length === 0) { + return false; + } + if (typeof val == "function") { + val = this.ms(val, ctx, partials, inverted, start, end, tags); + } + pass = !!val; + if (!inverted && pass && ctx) { + ctx.push(typeof val == "object" ? val : ctx[ctx.length - 1]); + } + return pass; + }, + // find values with dotted names + d: function(key2, ctx, partials, returnFound) { + var found, names = key2.split("."), val = this.f(names[0], ctx, partials, returnFound), doModelGet = this.options.modelGet, cx = null; + if (key2 === "." && isArray(ctx[ctx.length - 2])) { + val = ctx[ctx.length - 1]; + } else { + for (var i = 1; i < names.length; i++) { + found = findInScope(names[i], val, doModelGet); + if (found !== void 0) { + cx = val; + val = found; + } else { + val = ""; + } + } + } + if (returnFound && !val) { + return false; + } + if (!returnFound && typeof val == "function") { + ctx.push(cx); + val = this.mv(val, ctx, partials); + ctx.pop(); + } + return val; + }, + // find values with normal names + f: function(key2, ctx, partials, returnFound) { + var val = false, v = null, found = false, doModelGet = this.options.modelGet; + for (var i = ctx.length - 1; i >= 0; i--) { + v = ctx[i]; + val = findInScope(key2, v, doModelGet); + if (val !== void 0) { + found = true; + break; + } + } + if (!found) { + return returnFound ? false : ""; + } + if (!returnFound && typeof val == "function") { + val = this.mv(val, ctx, partials); + } + return val; + }, + // higher order templates + ls: function(func, cx, partials, text2, tags) { + var oldTags = this.options.delimiters; + this.options.delimiters = tags; + this.b(this.ct(coerceToString(func.call(cx, text2)), cx, partials)); + this.options.delimiters = oldTags; + return false; + }, + // compile text + ct: function(text2, cx, partials) { + if (this.options.disableLambda) { + throw new Error("Lambda features disabled."); + } + return this.c.compile(text2, this.options).render(cx, partials); + }, + // template result buffering + b: function(s) { + this.buf += s; + }, + fl: function() { + var r = this.buf; + this.buf = ""; + return r; + }, + // method replace section + ms: function(func, ctx, partials, inverted, start, end, tags) { + var textSource, cx = ctx[ctx.length - 1], result = func.call(cx); + if (typeof result == "function") { + if (inverted) { + return true; + } else { + textSource = this.activeSub && this.subsText && this.subsText[this.activeSub] ? this.subsText[this.activeSub] : this.text; + return this.ls(result, cx, partials, textSource.substring(start, end), tags); + } + } + return result; + }, + // method replace variable + mv: function(func, ctx, partials) { + var cx = ctx[ctx.length - 1]; + var result = func.call(cx); + if (typeof result == "function") { + return this.ct(coerceToString(result.call(cx)), cx, partials); + } + return result; + }, + sub: function(name, context, partials, indent2) { + var f = this.subs[name]; + if (f) { + this.activeSub = name; + f(context, partials, this, indent2); + this.activeSub = false; + } + } + }; + function findInScope(key2, scope, doModelGet) { + var val; + if (scope && typeof scope == "object") { + if (scope[key2] !== void 0) { + val = scope[key2]; + } else if (doModelGet && scope.get && typeof scope.get == "function") { + val = scope.get(key2); + } + } + return val; + } + function createSpecializedPartial(instance10, subs, partials, stackSubs, stackPartials, stackText) { + function PartialTemplate() { + } + ; + PartialTemplate.prototype = instance10; + function Substitutions() { + } + ; + Substitutions.prototype = instance10.subs; + var key2; + var partial = new PartialTemplate(); + partial.subs = new Substitutions(); + partial.subsText = {}; + partial.buf = ""; + stackSubs = stackSubs || {}; + partial.stackSubs = stackSubs; + partial.subsText = stackText; + for (key2 in subs) { + if (!stackSubs[key2]) + stackSubs[key2] = subs[key2]; + } + for (key2 in stackSubs) { + partial.subs[key2] = stackSubs[key2]; + } + stackPartials = stackPartials || {}; + partial.stackPartials = stackPartials; + for (key2 in partials) { + if (!stackPartials[key2]) + stackPartials[key2] = partials[key2]; + } + for (key2 in stackPartials) { + partial.partials[key2] = stackPartials[key2]; + } + return partial; + } + var rAmp = /&/g, rLt = //g, rApos = /\'/g, rQuot = /\"/g, hChars = /[&<>\"\']/; + function coerceToString(val) { + return String(val === null || val === void 0 ? "" : val); + } + function hoganEscape(str) { + str = coerceToString(str); + return hChars.test(str) ? str.replace(rAmp, "&").replace(rLt, "<").replace(rGt, ">").replace(rApos, "'").replace(rQuot, """) : str; + } + var isArray = Array.isArray || function(a) { + return Object.prototype.toString.call(a) === "[object Array]"; + }; + })(typeof exports2 !== "undefined" ? exports2 : Hogan4); + } +}); + +// node_modules/.pnpm/hogan.js@3.0.2/node_modules/hogan.js/lib/hogan.js +var require_hogan = __commonJS({ + "node_modules/.pnpm/hogan.js@3.0.2/node_modules/hogan.js/lib/hogan.js"(exports2, module2) { + init_polyfill_buffer(); + var Hogan4 = require_compiler(); + Hogan4.Template = require_template().Template; + Hogan4.template = Hogan4.Template; + module2.exports = Hogan4; + } +}); + +// node_modules/.pnpm/feather-icons@4.29.0/node_modules/feather-icons/dist/feather.js +var require_feather = __commonJS({ + "node_modules/.pnpm/feather-icons@4.29.0/node_modules/feather-icons/dist/feather.js"(exports2, module2) { + init_polyfill_buffer(); + (function webpackUniversalModuleDefinition(root2, factory) { + if (typeof exports2 === "object" && typeof module2 === "object") + module2.exports = factory(); + else if (typeof define === "function" && define.amd) + define([], factory); + else if (typeof exports2 === "object") + exports2["feather"] = factory(); + else + root2["feather"] = factory(); + })(typeof self !== "undefined" ? self : exports2, function() { + return ( + /******/ + function(modules) { + var installedModules = {}; + function __webpack_require__(moduleId) { + if (installedModules[moduleId]) { + return installedModules[moduleId].exports; + } + var module3 = installedModules[moduleId] = { + /******/ + i: moduleId, + /******/ + l: false, + /******/ + exports: {} + /******/ + }; + modules[moduleId].call(module3.exports, module3, module3.exports, __webpack_require__); + module3.l = true; + return module3.exports; + } + __webpack_require__.m = modules; + __webpack_require__.c = installedModules; + __webpack_require__.d = function(exports3, name, getter) { + if (!__webpack_require__.o(exports3, name)) { + Object.defineProperty(exports3, name, { + /******/ + configurable: false, + /******/ + enumerable: true, + /******/ + get: getter + /******/ + }); + } + }; + __webpack_require__.r = function(exports3) { + Object.defineProperty(exports3, "__esModule", { value: true }); + }; + __webpack_require__.n = function(module3) { + var getter = module3 && module3.__esModule ? ( + /******/ + function getDefault() { + return module3["default"]; + } + ) : ( + /******/ + function getModuleExports() { + return module3; + } + ); + __webpack_require__.d(getter, "a", getter); + return getter; + }; + __webpack_require__.o = function(object, property) { + return Object.prototype.hasOwnProperty.call(object, property); + }; + __webpack_require__.p = ""; + return __webpack_require__(__webpack_require__.s = 0); + }({ + /***/ + "./dist/icons.json": ( + /*!*************************!*\ + !*** ./dist/icons.json ***! + \*************************/ + /*! exports provided: activity, airplay, alert-circle, alert-octagon, alert-triangle, align-center, align-justify, align-left, align-right, anchor, aperture, archive, arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down, arrow-left-circle, arrow-left, arrow-right-circle, arrow-right, arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, award, bar-chart-2, bar-chart, battery-charging, battery, bell-off, bell, bluetooth, bold, book-open, book, bookmark, box, briefcase, calendar, camera-off, camera, cast, check-circle, check-square, check, chevron-down, chevron-left, chevron-right, chevron-up, chevrons-down, chevrons-left, chevrons-right, chevrons-up, chrome, circle, clipboard, clock, cloud-drizzle, cloud-lightning, cloud-off, cloud-rain, cloud-snow, cloud, code, codepen, codesandbox, coffee, columns, command, compass, copy, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, cpu, credit-card, crop, crosshair, database, delete, disc, divide-circle, divide-square, divide, dollar-sign, download-cloud, download, dribbble, droplet, edit-2, edit-3, edit, external-link, eye-off, eye, facebook, fast-forward, feather, figma, file-minus, file-plus, file-text, file, film, filter, flag, folder-minus, folder-plus, folder, framer, frown, gift, git-branch, git-commit, git-merge, git-pull-request, github, gitlab, globe, grid, hard-drive, hash, headphones, heart, help-circle, hexagon, home, image, inbox, info, instagram, italic, key, layers, layout, life-buoy, link-2, link, linkedin, list, loader, lock, log-in, log-out, mail, map-pin, map, maximize-2, maximize, meh, menu, message-circle, message-square, mic-off, mic, minimize-2, minimize, minus-circle, minus-square, minus, monitor, moon, more-horizontal, more-vertical, mouse-pointer, move, music, navigation-2, navigation, octagon, package, paperclip, pause-circle, pause, pen-tool, percent, phone-call, phone-forwarded, phone-incoming, phone-missed, phone-off, phone-outgoing, phone, pie-chart, play-circle, play, plus-circle, plus-square, plus, pocket, power, printer, radio, refresh-ccw, refresh-cw, repeat, rewind, rotate-ccw, rotate-cw, rss, save, scissors, search, send, server, settings, share-2, share, shield-off, shield, shopping-bag, shopping-cart, shuffle, sidebar, skip-back, skip-forward, slack, slash, sliders, smartphone, smile, speaker, square, star, stop-circle, sun, sunrise, sunset, table, tablet, tag, target, terminal, thermometer, thumbs-down, thumbs-up, toggle-left, toggle-right, tool, trash-2, trash, trello, trending-down, trending-up, triangle, truck, tv, twitch, twitter, type, umbrella, underline, unlock, upload-cloud, upload, user-check, user-minus, user-plus, user-x, user, users, video-off, video, voicemail, volume-1, volume-2, volume-x, volume, watch, wifi-off, wifi, wind, x-circle, x-octagon, x-square, x, youtube, zap-off, zap, zoom-in, zoom-out, default */ + /***/ + function(module3) { + module3.exports = { "activity": '', "airplay": '', "alert-circle": '', "alert-octagon": '', "alert-triangle": '', "align-center": '', "align-justify": '', "align-left": '', "align-right": '', "anchor": '', "aperture": '', "archive": '', "arrow-down-circle": '', "arrow-down-left": '', "arrow-down-right": '', "arrow-down": '', "arrow-left-circle": '', "arrow-left": '', "arrow-right-circle": '', "arrow-right": '', "arrow-up-circle": '', "arrow-up-left": '', "arrow-up-right": '', "arrow-up": '', "at-sign": '', "award": '', "bar-chart-2": '', "bar-chart": '', "battery-charging": '', "battery": '', "bell-off": '', "bell": '', "bluetooth": '', "bold": '', "book-open": '', "book": '', "bookmark": '', "box": '', "briefcase": '', "calendar": '', "camera-off": '', "camera": '', "cast": '', "check-circle": '', "check-square": '', "check": '', "chevron-down": '', "chevron-left": '', "chevron-right": '', "chevron-up": '', "chevrons-down": '', "chevrons-left": '', "chevrons-right": '', "chevrons-up": '', "chrome": '', "circle": '', "clipboard": '', "clock": '', "cloud-drizzle": '', "cloud-lightning": '', "cloud-off": '', "cloud-rain": '', "cloud-snow": '', "cloud": '', "code": '', "codepen": '', "codesandbox": '', "coffee": '', "columns": '', "command": '', "compass": '', "copy": '', "corner-down-left": '', "corner-down-right": '', "corner-left-down": '', "corner-left-up": '', "corner-right-down": '', "corner-right-up": '', "corner-up-left": '', "corner-up-right": '', "cpu": '', "credit-card": '', "crop": '', "crosshair": '', "database": '', "delete": '', "disc": '', "divide-circle": '', "divide-square": '', "divide": '', "dollar-sign": '', "download-cloud": '', "download": '', "dribbble": '', "droplet": '', "edit-2": '', "edit-3": '', "edit": '', "external-link": '', "eye-off": '', "eye": '', "facebook": '', "fast-forward": '', "feather": '', "figma": '', "file-minus": '', "file-plus": '', "file-text": '', "file": '', "film": '', "filter": '', "flag": '', "folder-minus": '', "folder-plus": '', "folder": '', "framer": '', "frown": '', "gift": '', "git-branch": '', "git-commit": '', "git-merge": '', "git-pull-request": '', "github": '', "gitlab": '', "globe": '', "grid": '', "hard-drive": '', "hash": '', "headphones": '', "heart": '', "help-circle": '', "hexagon": '', "home": '', "image": '', "inbox": '', "info": '', "instagram": '', "italic": '', "key": '', "layers": '', "layout": '', "life-buoy": '', "link-2": '', "link": '', "linkedin": '', "list": '', "loader": '', "lock": '', "log-in": '', "log-out": '', "mail": '', "map-pin": '', "map": '', "maximize-2": '', "maximize": '', "meh": '', "menu": '', "message-circle": '', "message-square": '', "mic-off": '', "mic": '', "minimize-2": '', "minimize": '', "minus-circle": '', "minus-square": '', "minus": '', "monitor": '', "moon": '', "more-horizontal": '', "more-vertical": '', "mouse-pointer": '', "move": '', "music": '', "navigation-2": '', "navigation": '', "octagon": '', "package": '', "paperclip": '', "pause-circle": '', "pause": '', "pen-tool": '', "percent": '', "phone-call": '', "phone-forwarded": '', "phone-incoming": '', "phone-missed": '', "phone-off": '', "phone-outgoing": '', "phone": '', "pie-chart": '', "play-circle": '', "play": '', "plus-circle": '', "plus-square": '', "plus": '', "pocket": '', "power": '', "printer": '', "radio": '', "refresh-ccw": '', "refresh-cw": '', "repeat": '', "rewind": '', "rotate-ccw": '', "rotate-cw": '', "rss": '', "save": '', "scissors": '', "search": '', "send": '', "server": '', "settings": '', "share-2": '', "share": '', "shield-off": '', "shield": '', "shopping-bag": '', "shopping-cart": '', "shuffle": '', "sidebar": '', "skip-back": '', "skip-forward": '', "slack": '', "slash": '', "sliders": '', "smartphone": '', "smile": '', "speaker": '', "square": '', "star": '', "stop-circle": '', "sun": '', "sunrise": '', "sunset": '', "table": '', "tablet": '', "tag": '', "target": '', "terminal": '', "thermometer": '', "thumbs-down": '', "thumbs-up": '', "toggle-left": '', "toggle-right": '', "tool": '', "trash-2": '', "trash": '', "trello": '', "trending-down": '', "trending-up": '', "triangle": '', "truck": '', "tv": '', "twitch": '', "twitter": '', "type": '', "umbrella": '', "underline": '', "unlock": '', "upload-cloud": '', "upload": '', "user-check": '', "user-minus": '', "user-plus": '', "user-x": '', "user": '', "users": '', "video-off": '', "video": '', "voicemail": '', "volume-1": '', "volume-2": '', "volume-x": '', "volume": '', "watch": '', "wifi-off": '', "wifi": '', "wind": '', "x-circle": '', "x-octagon": '', "x-square": '', "x": '', "youtube": '', "zap-off": '', "zap": '', "zoom-in": '', "zoom-out": '' }; + } + ), + /***/ + "./node_modules/classnames/dedupe.js": ( + /*!*******************************************!*\ + !*** ./node_modules/classnames/dedupe.js ***! + \*******************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; + (function() { + "use strict"; + var classNames = function() { + function StorageObject() { + } + StorageObject.prototype = /* @__PURE__ */ Object.create(null); + function _parseArray(resultSet, array) { + var length = array.length; + for (var i = 0; i < length; ++i) { + _parse(resultSet, array[i]); + } + } + var hasOwn = {}.hasOwnProperty; + function _parseNumber(resultSet, num2) { + resultSet[num2] = true; + } + function _parseObject(resultSet, object) { + for (var k in object) { + if (hasOwn.call(object, k)) { + resultSet[k] = !!object[k]; + } + } + } + var SPACE = /\s+/; + function _parseString(resultSet, str) { + var array = str.split(SPACE); + var length = array.length; + for (var i = 0; i < length; ++i) { + resultSet[array[i]] = true; + } + } + function _parse(resultSet, arg) { + if (!arg) + return; + var argType = typeof arg; + if (argType === "string") { + _parseString(resultSet, arg); + } else if (Array.isArray(arg)) { + _parseArray(resultSet, arg); + } else if (argType === "object") { + _parseObject(resultSet, arg); + } else if (argType === "number") { + _parseNumber(resultSet, arg); + } + } + function _classNames() { + var len = arguments.length; + var args = Array(len); + for (var i = 0; i < len; i++) { + args[i] = arguments[i]; + } + var classSet = new StorageObject(); + _parseArray(classSet, args); + var list = []; + for (var k in classSet) { + if (classSet[k]) { + list.push(k); + } + } + return list.join(" "); + } + return _classNames; + }(); + if (typeof module3 !== "undefined" && module3.exports) { + module3.exports = classNames; + } else if (true) { + !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() { + return classNames; + }.apply(exports3, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== void 0 && (module3.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else { + } + })(); + } + ), + /***/ + "./node_modules/core-js/es/array/from.js": ( + /*!***********************************************!*\ + !*** ./node_modules/core-js/es/array/from.js ***! + \***********************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + __webpack_require__( + /*! ../../modules/es.string.iterator */ + "./node_modules/core-js/modules/es.string.iterator.js" + ); + __webpack_require__( + /*! ../../modules/es.array.from */ + "./node_modules/core-js/modules/es.array.from.js" + ); + var path2 = __webpack_require__( + /*! ../../internals/path */ + "./node_modules/core-js/internals/path.js" + ); + module3.exports = path2.Array.from; + } + ), + /***/ + "./node_modules/core-js/internals/a-function.js": ( + /*!******************************************************!*\ + !*** ./node_modules/core-js/internals/a-function.js ***! + \******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = function(it) { + if (typeof it != "function") { + throw TypeError(String(it) + " is not a function"); + } + return it; + }; + } + ), + /***/ + "./node_modules/core-js/internals/an-object.js": ( + /*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/an-object.js ***! + \*****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var isObject = __webpack_require__( + /*! ../internals/is-object */ + "./node_modules/core-js/internals/is-object.js" + ); + module3.exports = function(it) { + if (!isObject(it)) { + throw TypeError(String(it) + " is not an object"); + } + return it; + }; + } + ), + /***/ + "./node_modules/core-js/internals/array-from.js": ( + /*!******************************************************!*\ + !*** ./node_modules/core-js/internals/array-from.js ***! + \******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + var bind = __webpack_require__( + /*! ../internals/bind-context */ + "./node_modules/core-js/internals/bind-context.js" + ); + var toObject = __webpack_require__( + /*! ../internals/to-object */ + "./node_modules/core-js/internals/to-object.js" + ); + var callWithSafeIterationClosing = __webpack_require__( + /*! ../internals/call-with-safe-iteration-closing */ + "./node_modules/core-js/internals/call-with-safe-iteration-closing.js" + ); + var isArrayIteratorMethod = __webpack_require__( + /*! ../internals/is-array-iterator-method */ + "./node_modules/core-js/internals/is-array-iterator-method.js" + ); + var toLength = __webpack_require__( + /*! ../internals/to-length */ + "./node_modules/core-js/internals/to-length.js" + ); + var createProperty = __webpack_require__( + /*! ../internals/create-property */ + "./node_modules/core-js/internals/create-property.js" + ); + var getIteratorMethod = __webpack_require__( + /*! ../internals/get-iterator-method */ + "./node_modules/core-js/internals/get-iterator-method.js" + ); + module3.exports = function from(arrayLike) { + var O = toObject(arrayLike); + var C = typeof this == "function" ? this : Array; + var argumentsLength = arguments.length; + var mapfn = argumentsLength > 1 ? arguments[1] : void 0; + var mapping = mapfn !== void 0; + var index2 = 0; + var iteratorMethod = getIteratorMethod(O); + var length, result, step, iterator; + if (mapping) + mapfn = bind(mapfn, argumentsLength > 2 ? arguments[2] : void 0, 2); + if (iteratorMethod != void 0 && !(C == Array && isArrayIteratorMethod(iteratorMethod))) { + iterator = iteratorMethod.call(O); + result = new C(); + for (; !(step = iterator.next()).done; index2++) { + createProperty( + result, + index2, + mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index2], true) : step.value + ); + } + } else { + length = toLength(O.length); + result = new C(length); + for (; length > index2; index2++) { + createProperty(result, index2, mapping ? mapfn(O[index2], index2) : O[index2]); + } + } + result.length = index2; + return result; + }; + } + ), + /***/ + "./node_modules/core-js/internals/array-includes.js": ( + /*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/array-includes.js ***! + \**********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var toIndexedObject = __webpack_require__( + /*! ../internals/to-indexed-object */ + "./node_modules/core-js/internals/to-indexed-object.js" + ); + var toLength = __webpack_require__( + /*! ../internals/to-length */ + "./node_modules/core-js/internals/to-length.js" + ); + var toAbsoluteIndex = __webpack_require__( + /*! ../internals/to-absolute-index */ + "./node_modules/core-js/internals/to-absolute-index.js" + ); + module3.exports = function(IS_INCLUDES) { + return function($this, el, fromIndex) { + var O = toIndexedObject($this); + var length = toLength(O.length); + var index2 = toAbsoluteIndex(fromIndex, length); + var value; + if (IS_INCLUDES && el != el) + while (length > index2) { + value = O[index2++]; + if (value != value) + return true; + } + else + for (; length > index2; index2++) + if (IS_INCLUDES || index2 in O) { + if (O[index2] === el) + return IS_INCLUDES || index2 || 0; + } + return !IS_INCLUDES && -1; + }; + }; + } + ), + /***/ + "./node_modules/core-js/internals/bind-context.js": ( + /*!********************************************************!*\ + !*** ./node_modules/core-js/internals/bind-context.js ***! + \********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var aFunction = __webpack_require__( + /*! ../internals/a-function */ + "./node_modules/core-js/internals/a-function.js" + ); + module3.exports = function(fn, that, length) { + aFunction(fn); + if (that === void 0) + return fn; + switch (length) { + case 0: + return function() { + return fn.call(that); + }; + case 1: + return function(a) { + return fn.call(that, a); + }; + case 2: + return function(a, b) { + return fn.call(that, a, b); + }; + case 3: + return function(a, b, c) { + return fn.call(that, a, b, c); + }; + } + return function() { + return fn.apply(that, arguments); + }; + }; + } + ), + /***/ + "./node_modules/core-js/internals/call-with-safe-iteration-closing.js": ( + /*!****************************************************************************!*\ + !*** ./node_modules/core-js/internals/call-with-safe-iteration-closing.js ***! + \****************************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var anObject = __webpack_require__( + /*! ../internals/an-object */ + "./node_modules/core-js/internals/an-object.js" + ); + module3.exports = function(iterator, fn, value, ENTRIES) { + try { + return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value); + } catch (error) { + var returnMethod = iterator["return"]; + if (returnMethod !== void 0) + anObject(returnMethod.call(iterator)); + throw error; + } + }; + } + ), + /***/ + "./node_modules/core-js/internals/check-correctness-of-iteration.js": ( + /*!**************************************************************************!*\ + !*** ./node_modules/core-js/internals/check-correctness-of-iteration.js ***! + \**************************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var wellKnownSymbol = __webpack_require__( + /*! ../internals/well-known-symbol */ + "./node_modules/core-js/internals/well-known-symbol.js" + ); + var ITERATOR = wellKnownSymbol("iterator"); + var SAFE_CLOSING = false; + try { + var called = 0; + var iteratorWithReturn = { + next: function() { + return { done: !!called++ }; + }, + "return": function() { + SAFE_CLOSING = true; + } + }; + iteratorWithReturn[ITERATOR] = function() { + return this; + }; + Array.from(iteratorWithReturn, function() { + throw 2; + }); + } catch (error) { + } + module3.exports = function(exec, SKIP_CLOSING) { + if (!SKIP_CLOSING && !SAFE_CLOSING) + return false; + var ITERATION_SUPPORT = false; + try { + var object = {}; + object[ITERATOR] = function() { + return { + next: function() { + return { done: ITERATION_SUPPORT = true }; + } + }; + }; + exec(object); + } catch (error) { + } + return ITERATION_SUPPORT; + }; + } + ), + /***/ + "./node_modules/core-js/internals/classof-raw.js": ( + /*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/classof-raw.js ***! + \*******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + var toString = {}.toString; + module3.exports = function(it) { + return toString.call(it).slice(8, -1); + }; + } + ), + /***/ + "./node_modules/core-js/internals/classof.js": ( + /*!***************************************************!*\ + !*** ./node_modules/core-js/internals/classof.js ***! + \***************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var classofRaw = __webpack_require__( + /*! ../internals/classof-raw */ + "./node_modules/core-js/internals/classof-raw.js" + ); + var wellKnownSymbol = __webpack_require__( + /*! ../internals/well-known-symbol */ + "./node_modules/core-js/internals/well-known-symbol.js" + ); + var TO_STRING_TAG = wellKnownSymbol("toStringTag"); + var CORRECT_ARGUMENTS = classofRaw(function() { + return arguments; + }()) == "Arguments"; + var tryGet = function(it, key2) { + try { + return it[key2]; + } catch (error) { + } + }; + module3.exports = function(it) { + var O, tag2, result; + return it === void 0 ? "Undefined" : it === null ? "Null" : typeof (tag2 = tryGet(O = Object(it), TO_STRING_TAG)) == "string" ? tag2 : CORRECT_ARGUMENTS ? classofRaw(O) : (result = classofRaw(O)) == "Object" && typeof O.callee == "function" ? "Arguments" : result; + }; + } + ), + /***/ + "./node_modules/core-js/internals/copy-constructor-properties.js": ( + /*!***********************************************************************!*\ + !*** ./node_modules/core-js/internals/copy-constructor-properties.js ***! + \***********************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var has = __webpack_require__( + /*! ../internals/has */ + "./node_modules/core-js/internals/has.js" + ); + var ownKeys = __webpack_require__( + /*! ../internals/own-keys */ + "./node_modules/core-js/internals/own-keys.js" + ); + var getOwnPropertyDescriptorModule = __webpack_require__( + /*! ../internals/object-get-own-property-descriptor */ + "./node_modules/core-js/internals/object-get-own-property-descriptor.js" + ); + var definePropertyModule = __webpack_require__( + /*! ../internals/object-define-property */ + "./node_modules/core-js/internals/object-define-property.js" + ); + module3.exports = function(target, source) { + var keys = ownKeys(source); + var defineProperty = definePropertyModule.f; + var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; + for (var i = 0; i < keys.length; i++) { + var key2 = keys[i]; + if (!has(target, key2)) + defineProperty(target, key2, getOwnPropertyDescriptor(source, key2)); + } + }; + } + ), + /***/ + "./node_modules/core-js/internals/correct-prototype-getter.js": ( + /*!********************************************************************!*\ + !*** ./node_modules/core-js/internals/correct-prototype-getter.js ***! + \********************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var fails = __webpack_require__( + /*! ../internals/fails */ + "./node_modules/core-js/internals/fails.js" + ); + module3.exports = !fails(function() { + function F() { + } + F.prototype.constructor = null; + return Object.getPrototypeOf(new F()) !== F.prototype; + }); + } + ), + /***/ + "./node_modules/core-js/internals/create-iterator-constructor.js": ( + /*!***********************************************************************!*\ + !*** ./node_modules/core-js/internals/create-iterator-constructor.js ***! + \***********************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + var IteratorPrototype = __webpack_require__( + /*! ../internals/iterators-core */ + "./node_modules/core-js/internals/iterators-core.js" + ).IteratorPrototype; + var create = __webpack_require__( + /*! ../internals/object-create */ + "./node_modules/core-js/internals/object-create.js" + ); + var createPropertyDescriptor = __webpack_require__( + /*! ../internals/create-property-descriptor */ + "./node_modules/core-js/internals/create-property-descriptor.js" + ); + var setToStringTag = __webpack_require__( + /*! ../internals/set-to-string-tag */ + "./node_modules/core-js/internals/set-to-string-tag.js" + ); + var Iterators = __webpack_require__( + /*! ../internals/iterators */ + "./node_modules/core-js/internals/iterators.js" + ); + var returnThis = function() { + return this; + }; + module3.exports = function(IteratorConstructor, NAME, next) { + var TO_STRING_TAG = NAME + " Iterator"; + IteratorConstructor.prototype = create(IteratorPrototype, { next: createPropertyDescriptor(1, next) }); + setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true); + Iterators[TO_STRING_TAG] = returnThis; + return IteratorConstructor; + }; + } + ), + /***/ + "./node_modules/core-js/internals/create-property-descriptor.js": ( + /*!**********************************************************************!*\ + !*** ./node_modules/core-js/internals/create-property-descriptor.js ***! + \**********************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = function(bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value + }; + }; + } + ), + /***/ + "./node_modules/core-js/internals/create-property.js": ( + /*!***********************************************************!*\ + !*** ./node_modules/core-js/internals/create-property.js ***! + \***********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + var toPrimitive = __webpack_require__( + /*! ../internals/to-primitive */ + "./node_modules/core-js/internals/to-primitive.js" + ); + var definePropertyModule = __webpack_require__( + /*! ../internals/object-define-property */ + "./node_modules/core-js/internals/object-define-property.js" + ); + var createPropertyDescriptor = __webpack_require__( + /*! ../internals/create-property-descriptor */ + "./node_modules/core-js/internals/create-property-descriptor.js" + ); + module3.exports = function(object, key2, value) { + var propertyKey = toPrimitive(key2); + if (propertyKey in object) + definePropertyModule.f(object, propertyKey, createPropertyDescriptor(0, value)); + else + object[propertyKey] = value; + }; + } + ), + /***/ + "./node_modules/core-js/internals/define-iterator.js": ( + /*!***********************************************************!*\ + !*** ./node_modules/core-js/internals/define-iterator.js ***! + \***********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + var $ = __webpack_require__( + /*! ../internals/export */ + "./node_modules/core-js/internals/export.js" + ); + var createIteratorConstructor = __webpack_require__( + /*! ../internals/create-iterator-constructor */ + "./node_modules/core-js/internals/create-iterator-constructor.js" + ); + var getPrototypeOf = __webpack_require__( + /*! ../internals/object-get-prototype-of */ + "./node_modules/core-js/internals/object-get-prototype-of.js" + ); + var setPrototypeOf = __webpack_require__( + /*! ../internals/object-set-prototype-of */ + "./node_modules/core-js/internals/object-set-prototype-of.js" + ); + var setToStringTag = __webpack_require__( + /*! ../internals/set-to-string-tag */ + "./node_modules/core-js/internals/set-to-string-tag.js" + ); + var hide = __webpack_require__( + /*! ../internals/hide */ + "./node_modules/core-js/internals/hide.js" + ); + var redefine = __webpack_require__( + /*! ../internals/redefine */ + "./node_modules/core-js/internals/redefine.js" + ); + var wellKnownSymbol = __webpack_require__( + /*! ../internals/well-known-symbol */ + "./node_modules/core-js/internals/well-known-symbol.js" + ); + var IS_PURE = __webpack_require__( + /*! ../internals/is-pure */ + "./node_modules/core-js/internals/is-pure.js" + ); + var Iterators = __webpack_require__( + /*! ../internals/iterators */ + "./node_modules/core-js/internals/iterators.js" + ); + var IteratorsCore = __webpack_require__( + /*! ../internals/iterators-core */ + "./node_modules/core-js/internals/iterators-core.js" + ); + var IteratorPrototype = IteratorsCore.IteratorPrototype; + var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS; + var ITERATOR = wellKnownSymbol("iterator"); + var KEYS = "keys"; + var VALUES = "values"; + var ENTRIES = "entries"; + var returnThis = function() { + return this; + }; + module3.exports = function(Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) { + createIteratorConstructor(IteratorConstructor, NAME, next); + var getIterationMethod = function(KIND) { + if (KIND === DEFAULT && defaultIterator) + return defaultIterator; + if (!BUGGY_SAFARI_ITERATORS && KIND in IterablePrototype) + return IterablePrototype[KIND]; + switch (KIND) { + case KEYS: + return function keys() { + return new IteratorConstructor(this, KIND); + }; + case VALUES: + return function values() { + return new IteratorConstructor(this, KIND); + }; + case ENTRIES: + return function entries() { + return new IteratorConstructor(this, KIND); + }; + } + return function() { + return new IteratorConstructor(this); + }; + }; + var TO_STRING_TAG = NAME + " Iterator"; + var INCORRECT_VALUES_NAME = false; + var IterablePrototype = Iterable.prototype; + var nativeIterator = IterablePrototype[ITERATOR] || IterablePrototype["@@iterator"] || DEFAULT && IterablePrototype[DEFAULT]; + var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT); + var anyNativeIterator = NAME == "Array" ? IterablePrototype.entries || nativeIterator : nativeIterator; + var CurrentIteratorPrototype, methods, KEY; + if (anyNativeIterator) { + CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable())); + if (IteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) { + if (!IS_PURE && getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) { + if (setPrototypeOf) { + setPrototypeOf(CurrentIteratorPrototype, IteratorPrototype); + } else if (typeof CurrentIteratorPrototype[ITERATOR] != "function") { + hide(CurrentIteratorPrototype, ITERATOR, returnThis); + } + } + setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true); + if (IS_PURE) + Iterators[TO_STRING_TAG] = returnThis; + } + } + if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) { + INCORRECT_VALUES_NAME = true; + defaultIterator = function values() { + return nativeIterator.call(this); + }; + } + if ((!IS_PURE || FORCED) && IterablePrototype[ITERATOR] !== defaultIterator) { + hide(IterablePrototype, ITERATOR, defaultIterator); + } + Iterators[NAME] = defaultIterator; + if (DEFAULT) { + methods = { + values: getIterationMethod(VALUES), + keys: IS_SET ? defaultIterator : getIterationMethod(KEYS), + entries: getIterationMethod(ENTRIES) + }; + if (FORCED) + for (KEY in methods) { + if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) { + redefine(IterablePrototype, KEY, methods[KEY]); + } + } + else + $({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods); + } + return methods; + }; + } + ), + /***/ + "./node_modules/core-js/internals/descriptors.js": ( + /*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/descriptors.js ***! + \*******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var fails = __webpack_require__( + /*! ../internals/fails */ + "./node_modules/core-js/internals/fails.js" + ); + module3.exports = !fails(function() { + return Object.defineProperty({}, "a", { get: function() { + return 7; + } }).a != 7; + }); + } + ), + /***/ + "./node_modules/core-js/internals/document-create-element.js": ( + /*!*******************************************************************!*\ + !*** ./node_modules/core-js/internals/document-create-element.js ***! + \*******************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var isObject = __webpack_require__( + /*! ../internals/is-object */ + "./node_modules/core-js/internals/is-object.js" + ); + var document2 = global2.document; + var exist = isObject(document2) && isObject(document2.createElement); + module3.exports = function(it) { + return exist ? document2.createElement(it) : {}; + }; + } + ), + /***/ + "./node_modules/core-js/internals/enum-bug-keys.js": ( + /*!*********************************************************!*\ + !*** ./node_modules/core-js/internals/enum-bug-keys.js ***! + \*********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = [ + "constructor", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "toLocaleString", + "toString", + "valueOf" + ]; + } + ), + /***/ + "./node_modules/core-js/internals/export.js": ( + /*!**************************************************!*\ + !*** ./node_modules/core-js/internals/export.js ***! + \**************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var getOwnPropertyDescriptor = __webpack_require__( + /*! ../internals/object-get-own-property-descriptor */ + "./node_modules/core-js/internals/object-get-own-property-descriptor.js" + ).f; + var hide = __webpack_require__( + /*! ../internals/hide */ + "./node_modules/core-js/internals/hide.js" + ); + var redefine = __webpack_require__( + /*! ../internals/redefine */ + "./node_modules/core-js/internals/redefine.js" + ); + var setGlobal = __webpack_require__( + /*! ../internals/set-global */ + "./node_modules/core-js/internals/set-global.js" + ); + var copyConstructorProperties = __webpack_require__( + /*! ../internals/copy-constructor-properties */ + "./node_modules/core-js/internals/copy-constructor-properties.js" + ); + var isForced = __webpack_require__( + /*! ../internals/is-forced */ + "./node_modules/core-js/internals/is-forced.js" + ); + module3.exports = function(options, source) { + var TARGET = options.target; + var GLOBAL = options.global; + var STATIC = options.stat; + var FORCED, target, key2, targetProperty, sourceProperty, descriptor; + if (GLOBAL) { + target = global2; + } else if (STATIC) { + target = global2[TARGET] || setGlobal(TARGET, {}); + } else { + target = (global2[TARGET] || {}).prototype; + } + if (target) + for (key2 in source) { + sourceProperty = source[key2]; + if (options.noTargetGet) { + descriptor = getOwnPropertyDescriptor(target, key2); + targetProperty = descriptor && descriptor.value; + } else + targetProperty = target[key2]; + FORCED = isForced(GLOBAL ? key2 : TARGET + (STATIC ? "." : "#") + key2, options.forced); + if (!FORCED && targetProperty !== void 0) { + if (typeof sourceProperty === typeof targetProperty) + continue; + copyConstructorProperties(sourceProperty, targetProperty); + } + if (options.sham || targetProperty && targetProperty.sham) { + hide(sourceProperty, "sham", true); + } + redefine(target, key2, sourceProperty, options); + } + }; + } + ), + /***/ + "./node_modules/core-js/internals/fails.js": ( + /*!*************************************************!*\ + !*** ./node_modules/core-js/internals/fails.js ***! + \*************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = function(exec) { + try { + return !!exec(); + } catch (error) { + return true; + } + }; + } + ), + /***/ + "./node_modules/core-js/internals/function-to-string.js": ( + /*!**************************************************************!*\ + !*** ./node_modules/core-js/internals/function-to-string.js ***! + \**************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var shared = __webpack_require__( + /*! ../internals/shared */ + "./node_modules/core-js/internals/shared.js" + ); + module3.exports = shared("native-function-to-string", Function.toString); + } + ), + /***/ + "./node_modules/core-js/internals/get-iterator-method.js": ( + /*!***************************************************************!*\ + !*** ./node_modules/core-js/internals/get-iterator-method.js ***! + \***************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var classof = __webpack_require__( + /*! ../internals/classof */ + "./node_modules/core-js/internals/classof.js" + ); + var Iterators = __webpack_require__( + /*! ../internals/iterators */ + "./node_modules/core-js/internals/iterators.js" + ); + var wellKnownSymbol = __webpack_require__( + /*! ../internals/well-known-symbol */ + "./node_modules/core-js/internals/well-known-symbol.js" + ); + var ITERATOR = wellKnownSymbol("iterator"); + module3.exports = function(it) { + if (it != void 0) + return it[ITERATOR] || it["@@iterator"] || Iterators[classof(it)]; + }; + } + ), + /***/ + "./node_modules/core-js/internals/global.js": ( + /*!**************************************************!*\ + !*** ./node_modules/core-js/internals/global.js ***! + \**************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + (function(global2) { + var O = "object"; + var check = function(it) { + return it && it.Math == Math && it; + }; + module3.exports = // eslint-disable-next-line no-undef + check(typeof globalThis == O && globalThis) || check(typeof window == O && window) || check(typeof self == O && self) || check(typeof global2 == O && global2) || // eslint-disable-next-line no-new-func + Function("return this")(); + }).call(this, __webpack_require__( + /*! ./../../webpack/buildin/global.js */ + "./node_modules/webpack/buildin/global.js" + )); + } + ), + /***/ + "./node_modules/core-js/internals/has.js": ( + /*!***********************************************!*\ + !*** ./node_modules/core-js/internals/has.js ***! + \***********************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + var hasOwnProperty = {}.hasOwnProperty; + module3.exports = function(it, key2) { + return hasOwnProperty.call(it, key2); + }; + } + ), + /***/ + "./node_modules/core-js/internals/hidden-keys.js": ( + /*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/hidden-keys.js ***! + \*******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = {}; + } + ), + /***/ + "./node_modules/core-js/internals/hide.js": ( + /*!************************************************!*\ + !*** ./node_modules/core-js/internals/hide.js ***! + \************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var DESCRIPTORS = __webpack_require__( + /*! ../internals/descriptors */ + "./node_modules/core-js/internals/descriptors.js" + ); + var definePropertyModule = __webpack_require__( + /*! ../internals/object-define-property */ + "./node_modules/core-js/internals/object-define-property.js" + ); + var createPropertyDescriptor = __webpack_require__( + /*! ../internals/create-property-descriptor */ + "./node_modules/core-js/internals/create-property-descriptor.js" + ); + module3.exports = DESCRIPTORS ? function(object, key2, value) { + return definePropertyModule.f(object, key2, createPropertyDescriptor(1, value)); + } : function(object, key2, value) { + object[key2] = value; + return object; + }; + } + ), + /***/ + "./node_modules/core-js/internals/html.js": ( + /*!************************************************!*\ + !*** ./node_modules/core-js/internals/html.js ***! + \************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var document2 = global2.document; + module3.exports = document2 && document2.documentElement; + } + ), + /***/ + "./node_modules/core-js/internals/ie8-dom-define.js": ( + /*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/ie8-dom-define.js ***! + \**********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var DESCRIPTORS = __webpack_require__( + /*! ../internals/descriptors */ + "./node_modules/core-js/internals/descriptors.js" + ); + var fails = __webpack_require__( + /*! ../internals/fails */ + "./node_modules/core-js/internals/fails.js" + ); + var createElement = __webpack_require__( + /*! ../internals/document-create-element */ + "./node_modules/core-js/internals/document-create-element.js" + ); + module3.exports = !DESCRIPTORS && !fails(function() { + return Object.defineProperty(createElement("div"), "a", { + get: function() { + return 7; + } + }).a != 7; + }); + } + ), + /***/ + "./node_modules/core-js/internals/indexed-object.js": ( + /*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/indexed-object.js ***! + \**********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var fails = __webpack_require__( + /*! ../internals/fails */ + "./node_modules/core-js/internals/fails.js" + ); + var classof = __webpack_require__( + /*! ../internals/classof-raw */ + "./node_modules/core-js/internals/classof-raw.js" + ); + var split = "".split; + module3.exports = fails(function() { + return !Object("z").propertyIsEnumerable(0); + }) ? function(it) { + return classof(it) == "String" ? split.call(it, "") : Object(it); + } : Object; + } + ), + /***/ + "./node_modules/core-js/internals/internal-state.js": ( + /*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/internal-state.js ***! + \**********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var NATIVE_WEAK_MAP = __webpack_require__( + /*! ../internals/native-weak-map */ + "./node_modules/core-js/internals/native-weak-map.js" + ); + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var isObject = __webpack_require__( + /*! ../internals/is-object */ + "./node_modules/core-js/internals/is-object.js" + ); + var hide = __webpack_require__( + /*! ../internals/hide */ + "./node_modules/core-js/internals/hide.js" + ); + var objectHas = __webpack_require__( + /*! ../internals/has */ + "./node_modules/core-js/internals/has.js" + ); + var sharedKey = __webpack_require__( + /*! ../internals/shared-key */ + "./node_modules/core-js/internals/shared-key.js" + ); + var hiddenKeys = __webpack_require__( + /*! ../internals/hidden-keys */ + "./node_modules/core-js/internals/hidden-keys.js" + ); + var WeakMap2 = global2.WeakMap; + var set, get, has; + var enforce = function(it) { + return has(it) ? get(it) : set(it, {}); + }; + var getterFor = function(TYPE) { + return function(it) { + var state; + if (!isObject(it) || (state = get(it)).type !== TYPE) { + throw TypeError("Incompatible receiver, " + TYPE + " required"); + } + return state; + }; + }; + if (NATIVE_WEAK_MAP) { + var store = new WeakMap2(); + var wmget = store.get; + var wmhas = store.has; + var wmset = store.set; + set = function(it, metadata) { + wmset.call(store, it, metadata); + return metadata; + }; + get = function(it) { + return wmget.call(store, it) || {}; + }; + has = function(it) { + return wmhas.call(store, it); + }; + } else { + var STATE = sharedKey("state"); + hiddenKeys[STATE] = true; + set = function(it, metadata) { + hide(it, STATE, metadata); + return metadata; + }; + get = function(it) { + return objectHas(it, STATE) ? it[STATE] : {}; + }; + has = function(it) { + return objectHas(it, STATE); + }; + } + module3.exports = { + set, + get, + has, + enforce, + getterFor + }; + } + ), + /***/ + "./node_modules/core-js/internals/is-array-iterator-method.js": ( + /*!********************************************************************!*\ + !*** ./node_modules/core-js/internals/is-array-iterator-method.js ***! + \********************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var wellKnownSymbol = __webpack_require__( + /*! ../internals/well-known-symbol */ + "./node_modules/core-js/internals/well-known-symbol.js" + ); + var Iterators = __webpack_require__( + /*! ../internals/iterators */ + "./node_modules/core-js/internals/iterators.js" + ); + var ITERATOR = wellKnownSymbol("iterator"); + var ArrayPrototype = Array.prototype; + module3.exports = function(it) { + return it !== void 0 && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it); + }; + } + ), + /***/ + "./node_modules/core-js/internals/is-forced.js": ( + /*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/is-forced.js ***! + \*****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var fails = __webpack_require__( + /*! ../internals/fails */ + "./node_modules/core-js/internals/fails.js" + ); + var replacement = /#|\.prototype\./; + var isForced = function(feature, detection) { + var value = data[normalize2(feature)]; + return value == POLYFILL ? true : value == NATIVE ? false : typeof detection == "function" ? fails(detection) : !!detection; + }; + var normalize2 = isForced.normalize = function(string) { + return String(string).replace(replacement, ".").toLowerCase(); + }; + var data = isForced.data = {}; + var NATIVE = isForced.NATIVE = "N"; + var POLYFILL = isForced.POLYFILL = "P"; + module3.exports = isForced; + } + ), + /***/ + "./node_modules/core-js/internals/is-object.js": ( + /*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/is-object.js ***! + \*****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = function(it) { + return typeof it === "object" ? it !== null : typeof it === "function"; + }; + } + ), + /***/ + "./node_modules/core-js/internals/is-pure.js": ( + /*!***************************************************!*\ + !*** ./node_modules/core-js/internals/is-pure.js ***! + \***************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = false; + } + ), + /***/ + "./node_modules/core-js/internals/iterators-core.js": ( + /*!**********************************************************!*\ + !*** ./node_modules/core-js/internals/iterators-core.js ***! + \**********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + var getPrototypeOf = __webpack_require__( + /*! ../internals/object-get-prototype-of */ + "./node_modules/core-js/internals/object-get-prototype-of.js" + ); + var hide = __webpack_require__( + /*! ../internals/hide */ + "./node_modules/core-js/internals/hide.js" + ); + var has = __webpack_require__( + /*! ../internals/has */ + "./node_modules/core-js/internals/has.js" + ); + var wellKnownSymbol = __webpack_require__( + /*! ../internals/well-known-symbol */ + "./node_modules/core-js/internals/well-known-symbol.js" + ); + var IS_PURE = __webpack_require__( + /*! ../internals/is-pure */ + "./node_modules/core-js/internals/is-pure.js" + ); + var ITERATOR = wellKnownSymbol("iterator"); + var BUGGY_SAFARI_ITERATORS = false; + var returnThis = function() { + return this; + }; + var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator; + if ([].keys) { + arrayIterator = [].keys(); + if (!("next" in arrayIterator)) + BUGGY_SAFARI_ITERATORS = true; + else { + PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator)); + if (PrototypeOfArrayIteratorPrototype !== Object.prototype) + IteratorPrototype = PrototypeOfArrayIteratorPrototype; + } + } + if (IteratorPrototype == void 0) + IteratorPrototype = {}; + if (!IS_PURE && !has(IteratorPrototype, ITERATOR)) + hide(IteratorPrototype, ITERATOR, returnThis); + module3.exports = { + IteratorPrototype, + BUGGY_SAFARI_ITERATORS + }; + } + ), + /***/ + "./node_modules/core-js/internals/iterators.js": ( + /*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/iterators.js ***! + \*****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = {}; + } + ), + /***/ + "./node_modules/core-js/internals/native-symbol.js": ( + /*!*********************************************************!*\ + !*** ./node_modules/core-js/internals/native-symbol.js ***! + \*********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var fails = __webpack_require__( + /*! ../internals/fails */ + "./node_modules/core-js/internals/fails.js" + ); + module3.exports = !!Object.getOwnPropertySymbols && !fails(function() { + return !String(Symbol()); + }); + } + ), + /***/ + "./node_modules/core-js/internals/native-weak-map.js": ( + /*!***********************************************************!*\ + !*** ./node_modules/core-js/internals/native-weak-map.js ***! + \***********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var nativeFunctionToString = __webpack_require__( + /*! ../internals/function-to-string */ + "./node_modules/core-js/internals/function-to-string.js" + ); + var WeakMap2 = global2.WeakMap; + module3.exports = typeof WeakMap2 === "function" && /native code/.test(nativeFunctionToString.call(WeakMap2)); + } + ), + /***/ + "./node_modules/core-js/internals/object-create.js": ( + /*!*********************************************************!*\ + !*** ./node_modules/core-js/internals/object-create.js ***! + \*********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var anObject = __webpack_require__( + /*! ../internals/an-object */ + "./node_modules/core-js/internals/an-object.js" + ); + var defineProperties = __webpack_require__( + /*! ../internals/object-define-properties */ + "./node_modules/core-js/internals/object-define-properties.js" + ); + var enumBugKeys = __webpack_require__( + /*! ../internals/enum-bug-keys */ + "./node_modules/core-js/internals/enum-bug-keys.js" + ); + var hiddenKeys = __webpack_require__( + /*! ../internals/hidden-keys */ + "./node_modules/core-js/internals/hidden-keys.js" + ); + var html2 = __webpack_require__( + /*! ../internals/html */ + "./node_modules/core-js/internals/html.js" + ); + var documentCreateElement = __webpack_require__( + /*! ../internals/document-create-element */ + "./node_modules/core-js/internals/document-create-element.js" + ); + var sharedKey = __webpack_require__( + /*! ../internals/shared-key */ + "./node_modules/core-js/internals/shared-key.js" + ); + var IE_PROTO = sharedKey("IE_PROTO"); + var PROTOTYPE = "prototype"; + var Empty = function() { + }; + var createDict = function() { + var iframe = documentCreateElement("iframe"); + var length = enumBugKeys.length; + var lt = "<"; + var script = "script"; + var gt = ">"; + var js = "java" + script + ":"; + var iframeDocument; + iframe.style.display = "none"; + html2.appendChild(iframe); + iframe.src = String(js); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(lt + script + gt + "document.F=Object" + lt + "/" + script + gt); + iframeDocument.close(); + createDict = iframeDocument.F; + while (length--) + delete createDict[PROTOTYPE][enumBugKeys[length]]; + return createDict(); + }; + module3.exports = Object.create || function create(O, Properties) { + var result; + if (O !== null) { + Empty[PROTOTYPE] = anObject(O); + result = new Empty(); + Empty[PROTOTYPE] = null; + result[IE_PROTO] = O; + } else + result = createDict(); + return Properties === void 0 ? result : defineProperties(result, Properties); + }; + hiddenKeys[IE_PROTO] = true; + } + ), + /***/ + "./node_modules/core-js/internals/object-define-properties.js": ( + /*!********************************************************************!*\ + !*** ./node_modules/core-js/internals/object-define-properties.js ***! + \********************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var DESCRIPTORS = __webpack_require__( + /*! ../internals/descriptors */ + "./node_modules/core-js/internals/descriptors.js" + ); + var definePropertyModule = __webpack_require__( + /*! ../internals/object-define-property */ + "./node_modules/core-js/internals/object-define-property.js" + ); + var anObject = __webpack_require__( + /*! ../internals/an-object */ + "./node_modules/core-js/internals/an-object.js" + ); + var objectKeys = __webpack_require__( + /*! ../internals/object-keys */ + "./node_modules/core-js/internals/object-keys.js" + ); + module3.exports = DESCRIPTORS ? Object.defineProperties : function defineProperties(O, Properties) { + anObject(O); + var keys = objectKeys(Properties); + var length = keys.length; + var i = 0; + var key2; + while (length > i) + definePropertyModule.f(O, key2 = keys[i++], Properties[key2]); + return O; + }; + } + ), + /***/ + "./node_modules/core-js/internals/object-define-property.js": ( + /*!******************************************************************!*\ + !*** ./node_modules/core-js/internals/object-define-property.js ***! + \******************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var DESCRIPTORS = __webpack_require__( + /*! ../internals/descriptors */ + "./node_modules/core-js/internals/descriptors.js" + ); + var IE8_DOM_DEFINE = __webpack_require__( + /*! ../internals/ie8-dom-define */ + "./node_modules/core-js/internals/ie8-dom-define.js" + ); + var anObject = __webpack_require__( + /*! ../internals/an-object */ + "./node_modules/core-js/internals/an-object.js" + ); + var toPrimitive = __webpack_require__( + /*! ../internals/to-primitive */ + "./node_modules/core-js/internals/to-primitive.js" + ); + var nativeDefineProperty = Object.defineProperty; + exports3.f = DESCRIPTORS ? nativeDefineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if (IE8_DOM_DEFINE) + try { + return nativeDefineProperty(O, P, Attributes); + } catch (error) { + } + if ("get" in Attributes || "set" in Attributes) + throw TypeError("Accessors not supported"); + if ("value" in Attributes) + O[P] = Attributes.value; + return O; + }; + } + ), + /***/ + "./node_modules/core-js/internals/object-get-own-property-descriptor.js": ( + /*!******************************************************************************!*\ + !*** ./node_modules/core-js/internals/object-get-own-property-descriptor.js ***! + \******************************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var DESCRIPTORS = __webpack_require__( + /*! ../internals/descriptors */ + "./node_modules/core-js/internals/descriptors.js" + ); + var propertyIsEnumerableModule = __webpack_require__( + /*! ../internals/object-property-is-enumerable */ + "./node_modules/core-js/internals/object-property-is-enumerable.js" + ); + var createPropertyDescriptor = __webpack_require__( + /*! ../internals/create-property-descriptor */ + "./node_modules/core-js/internals/create-property-descriptor.js" + ); + var toIndexedObject = __webpack_require__( + /*! ../internals/to-indexed-object */ + "./node_modules/core-js/internals/to-indexed-object.js" + ); + var toPrimitive = __webpack_require__( + /*! ../internals/to-primitive */ + "./node_modules/core-js/internals/to-primitive.js" + ); + var has = __webpack_require__( + /*! ../internals/has */ + "./node_modules/core-js/internals/has.js" + ); + var IE8_DOM_DEFINE = __webpack_require__( + /*! ../internals/ie8-dom-define */ + "./node_modules/core-js/internals/ie8-dom-define.js" + ); + var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + exports3.f = DESCRIPTORS ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) { + O = toIndexedObject(O); + P = toPrimitive(P, true); + if (IE8_DOM_DEFINE) + try { + return nativeGetOwnPropertyDescriptor(O, P); + } catch (error) { + } + if (has(O, P)) + return createPropertyDescriptor(!propertyIsEnumerableModule.f.call(O, P), O[P]); + }; + } + ), + /***/ + "./node_modules/core-js/internals/object-get-own-property-names.js": ( + /*!*************************************************************************!*\ + !*** ./node_modules/core-js/internals/object-get-own-property-names.js ***! + \*************************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var internalObjectKeys = __webpack_require__( + /*! ../internals/object-keys-internal */ + "./node_modules/core-js/internals/object-keys-internal.js" + ); + var enumBugKeys = __webpack_require__( + /*! ../internals/enum-bug-keys */ + "./node_modules/core-js/internals/enum-bug-keys.js" + ); + var hiddenKeys = enumBugKeys.concat("length", "prototype"); + exports3.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { + return internalObjectKeys(O, hiddenKeys); + }; + } + ), + /***/ + "./node_modules/core-js/internals/object-get-own-property-symbols.js": ( + /*!***************************************************************************!*\ + !*** ./node_modules/core-js/internals/object-get-own-property-symbols.js ***! + \***************************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + exports3.f = Object.getOwnPropertySymbols; + } + ), + /***/ + "./node_modules/core-js/internals/object-get-prototype-of.js": ( + /*!*******************************************************************!*\ + !*** ./node_modules/core-js/internals/object-get-prototype-of.js ***! + \*******************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var has = __webpack_require__( + /*! ../internals/has */ + "./node_modules/core-js/internals/has.js" + ); + var toObject = __webpack_require__( + /*! ../internals/to-object */ + "./node_modules/core-js/internals/to-object.js" + ); + var sharedKey = __webpack_require__( + /*! ../internals/shared-key */ + "./node_modules/core-js/internals/shared-key.js" + ); + var CORRECT_PROTOTYPE_GETTER = __webpack_require__( + /*! ../internals/correct-prototype-getter */ + "./node_modules/core-js/internals/correct-prototype-getter.js" + ); + var IE_PROTO = sharedKey("IE_PROTO"); + var ObjectPrototype = Object.prototype; + module3.exports = CORRECT_PROTOTYPE_GETTER ? Object.getPrototypeOf : function(O) { + O = toObject(O); + if (has(O, IE_PROTO)) + return O[IE_PROTO]; + if (typeof O.constructor == "function" && O instanceof O.constructor) { + return O.constructor.prototype; + } + return O instanceof Object ? ObjectPrototype : null; + }; + } + ), + /***/ + "./node_modules/core-js/internals/object-keys-internal.js": ( + /*!****************************************************************!*\ + !*** ./node_modules/core-js/internals/object-keys-internal.js ***! + \****************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var has = __webpack_require__( + /*! ../internals/has */ + "./node_modules/core-js/internals/has.js" + ); + var toIndexedObject = __webpack_require__( + /*! ../internals/to-indexed-object */ + "./node_modules/core-js/internals/to-indexed-object.js" + ); + var arrayIncludes = __webpack_require__( + /*! ../internals/array-includes */ + "./node_modules/core-js/internals/array-includes.js" + ); + var hiddenKeys = __webpack_require__( + /*! ../internals/hidden-keys */ + "./node_modules/core-js/internals/hidden-keys.js" + ); + var arrayIndexOf = arrayIncludes(false); + module3.exports = function(object, names) { + var O = toIndexedObject(object); + var i = 0; + var result = []; + var key2; + for (key2 in O) + !has(hiddenKeys, key2) && has(O, key2) && result.push(key2); + while (names.length > i) + if (has(O, key2 = names[i++])) { + ~arrayIndexOf(result, key2) || result.push(key2); + } + return result; + }; + } + ), + /***/ + "./node_modules/core-js/internals/object-keys.js": ( + /*!*******************************************************!*\ + !*** ./node_modules/core-js/internals/object-keys.js ***! + \*******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var internalObjectKeys = __webpack_require__( + /*! ../internals/object-keys-internal */ + "./node_modules/core-js/internals/object-keys-internal.js" + ); + var enumBugKeys = __webpack_require__( + /*! ../internals/enum-bug-keys */ + "./node_modules/core-js/internals/enum-bug-keys.js" + ); + module3.exports = Object.keys || function keys(O) { + return internalObjectKeys(O, enumBugKeys); + }; + } + ), + /***/ + "./node_modules/core-js/internals/object-property-is-enumerable.js": ( + /*!*************************************************************************!*\ + !*** ./node_modules/core-js/internals/object-property-is-enumerable.js ***! + \*************************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + var nativePropertyIsEnumerable = {}.propertyIsEnumerable; + var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + var NASHORN_BUG = getOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1); + exports3.f = NASHORN_BUG ? function propertyIsEnumerable(V) { + var descriptor = getOwnPropertyDescriptor(this, V); + return !!descriptor && descriptor.enumerable; + } : nativePropertyIsEnumerable; + } + ), + /***/ + "./node_modules/core-js/internals/object-set-prototype-of.js": ( + /*!*******************************************************************!*\ + !*** ./node_modules/core-js/internals/object-set-prototype-of.js ***! + \*******************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var validateSetPrototypeOfArguments = __webpack_require__( + /*! ../internals/validate-set-prototype-of-arguments */ + "./node_modules/core-js/internals/validate-set-prototype-of-arguments.js" + ); + module3.exports = Object.setPrototypeOf || ("__proto__" in {} ? function() { + var correctSetter = false; + var test = {}; + var setter; + try { + setter = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set; + setter.call(test, []); + correctSetter = test instanceof Array; + } catch (error) { + } + return function setPrototypeOf(O, proto) { + validateSetPrototypeOfArguments(O, proto); + if (correctSetter) + setter.call(O, proto); + else + O.__proto__ = proto; + return O; + }; + }() : void 0); + } + ), + /***/ + "./node_modules/core-js/internals/own-keys.js": ( + /*!****************************************************!*\ + !*** ./node_modules/core-js/internals/own-keys.js ***! + \****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var getOwnPropertyNamesModule = __webpack_require__( + /*! ../internals/object-get-own-property-names */ + "./node_modules/core-js/internals/object-get-own-property-names.js" + ); + var getOwnPropertySymbolsModule = __webpack_require__( + /*! ../internals/object-get-own-property-symbols */ + "./node_modules/core-js/internals/object-get-own-property-symbols.js" + ); + var anObject = __webpack_require__( + /*! ../internals/an-object */ + "./node_modules/core-js/internals/an-object.js" + ); + var Reflect2 = global2.Reflect; + module3.exports = Reflect2 && Reflect2.ownKeys || function ownKeys(it) { + var keys = getOwnPropertyNamesModule.f(anObject(it)); + var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; + return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys; + }; + } + ), + /***/ + "./node_modules/core-js/internals/path.js": ( + /*!************************************************!*\ + !*** ./node_modules/core-js/internals/path.js ***! + \************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + module3.exports = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + } + ), + /***/ + "./node_modules/core-js/internals/redefine.js": ( + /*!****************************************************!*\ + !*** ./node_modules/core-js/internals/redefine.js ***! + \****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var shared = __webpack_require__( + /*! ../internals/shared */ + "./node_modules/core-js/internals/shared.js" + ); + var hide = __webpack_require__( + /*! ../internals/hide */ + "./node_modules/core-js/internals/hide.js" + ); + var has = __webpack_require__( + /*! ../internals/has */ + "./node_modules/core-js/internals/has.js" + ); + var setGlobal = __webpack_require__( + /*! ../internals/set-global */ + "./node_modules/core-js/internals/set-global.js" + ); + var nativeFunctionToString = __webpack_require__( + /*! ../internals/function-to-string */ + "./node_modules/core-js/internals/function-to-string.js" + ); + var InternalStateModule = __webpack_require__( + /*! ../internals/internal-state */ + "./node_modules/core-js/internals/internal-state.js" + ); + var getInternalState = InternalStateModule.get; + var enforceInternalState = InternalStateModule.enforce; + var TEMPLATE = String(nativeFunctionToString).split("toString"); + shared("inspectSource", function(it) { + return nativeFunctionToString.call(it); + }); + (module3.exports = function(O, key2, value, options) { + var unsafe = options ? !!options.unsafe : false; + var simple2 = options ? !!options.enumerable : false; + var noTargetGet = options ? !!options.noTargetGet : false; + if (typeof value == "function") { + if (typeof key2 == "string" && !has(value, "name")) + hide(value, "name", key2); + enforceInternalState(value).source = TEMPLATE.join(typeof key2 == "string" ? key2 : ""); + } + if (O === global2) { + if (simple2) + O[key2] = value; + else + setGlobal(key2, value); + return; + } else if (!unsafe) { + delete O[key2]; + } else if (!noTargetGet && O[key2]) { + simple2 = true; + } + if (simple2) + O[key2] = value; + else + hide(O, key2, value); + })(Function.prototype, "toString", function toString() { + return typeof this == "function" && getInternalState(this).source || nativeFunctionToString.call(this); + }); + } + ), + /***/ + "./node_modules/core-js/internals/require-object-coercible.js": ( + /*!********************************************************************!*\ + !*** ./node_modules/core-js/internals/require-object-coercible.js ***! + \********************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + module3.exports = function(it) { + if (it == void 0) + throw TypeError("Can't call method on " + it); + return it; + }; + } + ), + /***/ + "./node_modules/core-js/internals/set-global.js": ( + /*!******************************************************!*\ + !*** ./node_modules/core-js/internals/set-global.js ***! + \******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var hide = __webpack_require__( + /*! ../internals/hide */ + "./node_modules/core-js/internals/hide.js" + ); + module3.exports = function(key2, value) { + try { + hide(global2, key2, value); + } catch (error) { + global2[key2] = value; + } + return value; + }; + } + ), + /***/ + "./node_modules/core-js/internals/set-to-string-tag.js": ( + /*!*************************************************************!*\ + !*** ./node_modules/core-js/internals/set-to-string-tag.js ***! + \*************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var defineProperty = __webpack_require__( + /*! ../internals/object-define-property */ + "./node_modules/core-js/internals/object-define-property.js" + ).f; + var has = __webpack_require__( + /*! ../internals/has */ + "./node_modules/core-js/internals/has.js" + ); + var wellKnownSymbol = __webpack_require__( + /*! ../internals/well-known-symbol */ + "./node_modules/core-js/internals/well-known-symbol.js" + ); + var TO_STRING_TAG = wellKnownSymbol("toStringTag"); + module3.exports = function(it, TAG, STATIC) { + if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG)) { + defineProperty(it, TO_STRING_TAG, { configurable: true, value: TAG }); + } + }; + } + ), + /***/ + "./node_modules/core-js/internals/shared-key.js": ( + /*!******************************************************!*\ + !*** ./node_modules/core-js/internals/shared-key.js ***! + \******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var shared = __webpack_require__( + /*! ../internals/shared */ + "./node_modules/core-js/internals/shared.js" + ); + var uid = __webpack_require__( + /*! ../internals/uid */ + "./node_modules/core-js/internals/uid.js" + ); + var keys = shared("keys"); + module3.exports = function(key2) { + return keys[key2] || (keys[key2] = uid(key2)); + }; + } + ), + /***/ + "./node_modules/core-js/internals/shared.js": ( + /*!**************************************************!*\ + !*** ./node_modules/core-js/internals/shared.js ***! + \**************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var setGlobal = __webpack_require__( + /*! ../internals/set-global */ + "./node_modules/core-js/internals/set-global.js" + ); + var IS_PURE = __webpack_require__( + /*! ../internals/is-pure */ + "./node_modules/core-js/internals/is-pure.js" + ); + var SHARED = "__core-js_shared__"; + var store = global2[SHARED] || setGlobal(SHARED, {}); + (module3.exports = function(key2, value) { + return store[key2] || (store[key2] = value !== void 0 ? value : {}); + })("versions", []).push({ + version: "3.1.3", + mode: IS_PURE ? "pure" : "global", + copyright: "\xA9 2019 Denis Pushkarev (zloirock.ru)" + }); + } + ), + /***/ + "./node_modules/core-js/internals/string-at.js": ( + /*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/string-at.js ***! + \*****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var toInteger = __webpack_require__( + /*! ../internals/to-integer */ + "./node_modules/core-js/internals/to-integer.js" + ); + var requireObjectCoercible = __webpack_require__( + /*! ../internals/require-object-coercible */ + "./node_modules/core-js/internals/require-object-coercible.js" + ); + module3.exports = function(that, pos, CONVERT_TO_STRING) { + var S = String(requireObjectCoercible(that)); + var position = toInteger(pos); + var size = S.length; + var first2, second; + if (position < 0 || position >= size) + return CONVERT_TO_STRING ? "" : void 0; + first2 = S.charCodeAt(position); + return first2 < 55296 || first2 > 56319 || position + 1 === size || (second = S.charCodeAt(position + 1)) < 56320 || second > 57343 ? CONVERT_TO_STRING ? S.charAt(position) : first2 : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first2 - 55296 << 10) + (second - 56320) + 65536; + }; + } + ), + /***/ + "./node_modules/core-js/internals/to-absolute-index.js": ( + /*!*************************************************************!*\ + !*** ./node_modules/core-js/internals/to-absolute-index.js ***! + \*************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var toInteger = __webpack_require__( + /*! ../internals/to-integer */ + "./node_modules/core-js/internals/to-integer.js" + ); + var max = Math.max; + var min = Math.min; + module3.exports = function(index2, length) { + var integer = toInteger(index2); + return integer < 0 ? max(integer + length, 0) : min(integer, length); + }; + } + ), + /***/ + "./node_modules/core-js/internals/to-indexed-object.js": ( + /*!*************************************************************!*\ + !*** ./node_modules/core-js/internals/to-indexed-object.js ***! + \*************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var IndexedObject = __webpack_require__( + /*! ../internals/indexed-object */ + "./node_modules/core-js/internals/indexed-object.js" + ); + var requireObjectCoercible = __webpack_require__( + /*! ../internals/require-object-coercible */ + "./node_modules/core-js/internals/require-object-coercible.js" + ); + module3.exports = function(it) { + return IndexedObject(requireObjectCoercible(it)); + }; + } + ), + /***/ + "./node_modules/core-js/internals/to-integer.js": ( + /*!******************************************************!*\ + !*** ./node_modules/core-js/internals/to-integer.js ***! + \******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + var ceil = Math.ceil; + var floor = Math.floor; + module3.exports = function(argument) { + return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument); + }; + } + ), + /***/ + "./node_modules/core-js/internals/to-length.js": ( + /*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/to-length.js ***! + \*****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var toInteger = __webpack_require__( + /*! ../internals/to-integer */ + "./node_modules/core-js/internals/to-integer.js" + ); + var min = Math.min; + module3.exports = function(argument) { + return argument > 0 ? min(toInteger(argument), 9007199254740991) : 0; + }; + } + ), + /***/ + "./node_modules/core-js/internals/to-object.js": ( + /*!*****************************************************!*\ + !*** ./node_modules/core-js/internals/to-object.js ***! + \*****************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var requireObjectCoercible = __webpack_require__( + /*! ../internals/require-object-coercible */ + "./node_modules/core-js/internals/require-object-coercible.js" + ); + module3.exports = function(argument) { + return Object(requireObjectCoercible(argument)); + }; + } + ), + /***/ + "./node_modules/core-js/internals/to-primitive.js": ( + /*!********************************************************!*\ + !*** ./node_modules/core-js/internals/to-primitive.js ***! + \********************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var isObject = __webpack_require__( + /*! ../internals/is-object */ + "./node_modules/core-js/internals/is-object.js" + ); + module3.exports = function(it, S) { + if (!isObject(it)) + return it; + var fn, val; + if (S && typeof (fn = it.toString) == "function" && !isObject(val = fn.call(it))) + return val; + if (typeof (fn = it.valueOf) == "function" && !isObject(val = fn.call(it))) + return val; + if (!S && typeof (fn = it.toString) == "function" && !isObject(val = fn.call(it))) + return val; + throw TypeError("Can't convert object to primitive value"); + }; + } + ), + /***/ + "./node_modules/core-js/internals/uid.js": ( + /*!***********************************************!*\ + !*** ./node_modules/core-js/internals/uid.js ***! + \***********************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + var id = 0; + var postfix = Math.random(); + module3.exports = function(key2) { + return "Symbol(".concat(key2 === void 0 ? "" : key2, ")_", (++id + postfix).toString(36)); + }; + } + ), + /***/ + "./node_modules/core-js/internals/validate-set-prototype-of-arguments.js": ( + /*!*******************************************************************************!*\ + !*** ./node_modules/core-js/internals/validate-set-prototype-of-arguments.js ***! + \*******************************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var isObject = __webpack_require__( + /*! ../internals/is-object */ + "./node_modules/core-js/internals/is-object.js" + ); + var anObject = __webpack_require__( + /*! ../internals/an-object */ + "./node_modules/core-js/internals/an-object.js" + ); + module3.exports = function(O, proto) { + anObject(O); + if (!isObject(proto) && proto !== null) { + throw TypeError("Can't set " + String(proto) + " as a prototype"); + } + }; + } + ), + /***/ + "./node_modules/core-js/internals/well-known-symbol.js": ( + /*!*************************************************************!*\ + !*** ./node_modules/core-js/internals/well-known-symbol.js ***! + \*************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var global2 = __webpack_require__( + /*! ../internals/global */ + "./node_modules/core-js/internals/global.js" + ); + var shared = __webpack_require__( + /*! ../internals/shared */ + "./node_modules/core-js/internals/shared.js" + ); + var uid = __webpack_require__( + /*! ../internals/uid */ + "./node_modules/core-js/internals/uid.js" + ); + var NATIVE_SYMBOL = __webpack_require__( + /*! ../internals/native-symbol */ + "./node_modules/core-js/internals/native-symbol.js" + ); + var Symbol2 = global2.Symbol; + var store = shared("wks"); + module3.exports = function(name) { + return store[name] || (store[name] = NATIVE_SYMBOL && Symbol2[name] || (NATIVE_SYMBOL ? Symbol2 : uid)("Symbol." + name)); + }; + } + ), + /***/ + "./node_modules/core-js/modules/es.array.from.js": ( + /*!*******************************************************!*\ + !*** ./node_modules/core-js/modules/es.array.from.js ***! + \*******************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + var $ = __webpack_require__( + /*! ../internals/export */ + "./node_modules/core-js/internals/export.js" + ); + var from = __webpack_require__( + /*! ../internals/array-from */ + "./node_modules/core-js/internals/array-from.js" + ); + var checkCorrectnessOfIteration = __webpack_require__( + /*! ../internals/check-correctness-of-iteration */ + "./node_modules/core-js/internals/check-correctness-of-iteration.js" + ); + var INCORRECT_ITERATION = !checkCorrectnessOfIteration(function(iterable) { + Array.from(iterable); + }); + $({ target: "Array", stat: true, forced: INCORRECT_ITERATION }, { + from + }); + } + ), + /***/ + "./node_modules/core-js/modules/es.string.iterator.js": ( + /*!************************************************************!*\ + !*** ./node_modules/core-js/modules/es.string.iterator.js ***! + \************************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + var codePointAt = __webpack_require__( + /*! ../internals/string-at */ + "./node_modules/core-js/internals/string-at.js" + ); + var InternalStateModule = __webpack_require__( + /*! ../internals/internal-state */ + "./node_modules/core-js/internals/internal-state.js" + ); + var defineIterator = __webpack_require__( + /*! ../internals/define-iterator */ + "./node_modules/core-js/internals/define-iterator.js" + ); + var STRING_ITERATOR = "String Iterator"; + var setInternalState = InternalStateModule.set; + var getInternalState = InternalStateModule.getterFor(STRING_ITERATOR); + defineIterator(String, "String", function(iterated) { + setInternalState(this, { + type: STRING_ITERATOR, + string: String(iterated), + index: 0 + }); + }, function next() { + var state = getInternalState(this); + var string = state.string; + var index2 = state.index; + var point; + if (index2 >= string.length) + return { value: void 0, done: true }; + point = codePointAt(string, index2, true); + state.index += point.length; + return { value: point, done: false }; + }); + } + ), + /***/ + "./node_modules/webpack/buildin/global.js": ( + /*!***********************************!*\ + !*** (webpack)/buildin/global.js ***! + \***********************************/ + /*! no static exports found */ + /***/ + function(module3, exports3) { + var g; + g = function() { + return this; + }(); + try { + g = g || Function("return this")() || (1, eval)("this"); + } catch (e) { + if (typeof window === "object") + g = window; + } + module3.exports = g; + } + ), + /***/ + "./src/default-attrs.json": ( + /*!********************************!*\ + !*** ./src/default-attrs.json ***! + \********************************/ + /*! exports provided: xmlns, width, height, viewBox, fill, stroke, stroke-width, stroke-linecap, stroke-linejoin, default */ + /***/ + function(module3) { + module3.exports = { "xmlns": "http://www.w3.org/2000/svg", "width": 24, "height": 24, "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": 2, "stroke-linecap": "round", "stroke-linejoin": "round" }; + } + ), + /***/ + "./src/icon.js": ( + /*!*********************!*\ + !*** ./src/icon.js ***! + \*********************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + Object.defineProperty(exports3, "__esModule", { + value: true + }); + var _extends = Object.assign || function(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key2 in source) { + if (Object.prototype.hasOwnProperty.call(source, key2)) { + target[key2] = source[key2]; + } + } + } + return target; + }; + var _createClass = function() { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) + descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + return function(Constructor, protoProps, staticProps) { + if (protoProps) + defineProperties(Constructor.prototype, protoProps); + if (staticProps) + defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + var _dedupe = __webpack_require__( + /*! classnames/dedupe */ + "./node_modules/classnames/dedupe.js" + ); + var _dedupe2 = _interopRequireDefault(_dedupe); + var _defaultAttrs = __webpack_require__( + /*! ./default-attrs.json */ + "./src/default-attrs.json" + ); + var _defaultAttrs2 = _interopRequireDefault(_defaultAttrs); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + function _classCallCheck(instance10, Constructor) { + if (!(instance10 instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + var Icon = function() { + function Icon2(name, contents) { + var tags = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : []; + _classCallCheck(this, Icon2); + this.name = name; + this.contents = contents; + this.tags = tags; + this.attrs = _extends({}, _defaultAttrs2.default, { class: "feather feather-" + name }); + } + _createClass(Icon2, [{ + key: "toSvg", + value: function toSvg() { + var attrs = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; + var combinedAttrs = _extends({}, this.attrs, attrs, { class: (0, _dedupe2.default)(this.attrs.class, attrs.class) }); + return "" + this.contents + ""; + } + /** + * Return string representation of an `Icon`. + * + * Added for backward compatibility. If old code expects `feather.icons.` + * to be a string, `toString()` will get implicitly called. + * + * @returns {string} + */ + }, { + key: "toString", + value: function toString() { + return this.contents; + } + }]); + return Icon2; + }(); + function attrsToString(attrs) { + return Object.keys(attrs).map(function(key2) { + return key2 + '="' + attrs[key2] + '"'; + }).join(" "); + } + exports3.default = Icon; + } + ), + /***/ + "./src/icons.js": ( + /*!**********************!*\ + !*** ./src/icons.js ***! + \**********************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + Object.defineProperty(exports3, "__esModule", { + value: true + }); + var _icon = __webpack_require__( + /*! ./icon */ + "./src/icon.js" + ); + var _icon2 = _interopRequireDefault(_icon); + var _icons = __webpack_require__( + /*! ../dist/icons.json */ + "./dist/icons.json" + ); + var _icons2 = _interopRequireDefault(_icons); + var _tags = __webpack_require__( + /*! ./tags.json */ + "./src/tags.json" + ); + var _tags2 = _interopRequireDefault(_tags); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + exports3.default = Object.keys(_icons2.default).map(function(key2) { + return new _icon2.default(key2, _icons2.default[key2], _tags2.default[key2]); + }).reduce(function(object, icon) { + object[icon.name] = icon; + return object; + }, {}); + } + ), + /***/ + "./src/index.js": ( + /*!**********************!*\ + !*** ./src/index.js ***! + \**********************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + var _icons = __webpack_require__( + /*! ./icons */ + "./src/icons.js" + ); + var _icons2 = _interopRequireDefault(_icons); + var _toSvg = __webpack_require__( + /*! ./to-svg */ + "./src/to-svg.js" + ); + var _toSvg2 = _interopRequireDefault(_toSvg); + var _replace = __webpack_require__( + /*! ./replace */ + "./src/replace.js" + ); + var _replace2 = _interopRequireDefault(_replace); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + module3.exports = { icons: _icons2.default, toSvg: _toSvg2.default, replace: _replace2.default }; + } + ), + /***/ + "./src/replace.js": ( + /*!************************!*\ + !*** ./src/replace.js ***! + \************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + Object.defineProperty(exports3, "__esModule", { + value: true + }); + var _extends = Object.assign || function(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key2 in source) { + if (Object.prototype.hasOwnProperty.call(source, key2)) { + target[key2] = source[key2]; + } + } + } + return target; + }; + var _dedupe = __webpack_require__( + /*! classnames/dedupe */ + "./node_modules/classnames/dedupe.js" + ); + var _dedupe2 = _interopRequireDefault(_dedupe); + var _icons = __webpack_require__( + /*! ./icons */ + "./src/icons.js" + ); + var _icons2 = _interopRequireDefault(_icons); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + function replace() { + var attrs = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; + if (typeof document === "undefined") { + throw new Error("`feather.replace()` only works in a browser environment."); + } + var elementsToReplace = document.querySelectorAll("[data-feather]"); + Array.from(elementsToReplace).forEach(function(element2) { + return replaceElement(element2, attrs); + }); + } + function replaceElement(element2) { + var attrs = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; + var elementAttrs = getAttrs(element2); + var name = elementAttrs["data-feather"]; + delete elementAttrs["data-feather"]; + var svgString = _icons2.default[name].toSvg(_extends({}, attrs, elementAttrs, { class: (0, _dedupe2.default)(attrs.class, elementAttrs.class) })); + var svgDocument = new DOMParser().parseFromString(svgString, "image/svg+xml"); + var svgElement = svgDocument.querySelector("svg"); + element2.parentNode.replaceChild(svgElement, element2); + } + function getAttrs(element2) { + return Array.from(element2.attributes).reduce(function(attrs, attr2) { + attrs[attr2.name] = attr2.value; + return attrs; + }, {}); + } + exports3.default = replace; + } + ), + /***/ + "./src/tags.json": ( + /*!***********************!*\ + !*** ./src/tags.json ***! + \***********************/ + /*! exports provided: activity, airplay, alert-circle, alert-octagon, alert-triangle, align-center, align-justify, align-left, align-right, anchor, archive, at-sign, award, aperture, bar-chart, bar-chart-2, battery, battery-charging, bell, bell-off, bluetooth, book-open, book, bookmark, box, briefcase, calendar, camera, cast, chevron-down, chevron-up, circle, clipboard, clock, cloud-drizzle, cloud-lightning, cloud-rain, cloud-snow, cloud, codepen, codesandbox, code, coffee, columns, command, compass, copy, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, cpu, credit-card, crop, crosshair, database, delete, disc, dollar-sign, droplet, edit, edit-2, edit-3, eye, eye-off, external-link, facebook, fast-forward, figma, file-minus, file-plus, file-text, film, filter, flag, folder-minus, folder-plus, folder, framer, frown, gift, git-branch, git-commit, git-merge, git-pull-request, github, gitlab, globe, hard-drive, hash, headphones, heart, help-circle, hexagon, home, image, inbox, instagram, key, layers, layout, life-bouy, link, link-2, linkedin, list, lock, log-in, log-out, mail, map-pin, map, maximize, maximize-2, meh, menu, message-circle, message-square, mic-off, mic, minimize, minimize-2, minus, monitor, moon, more-horizontal, more-vertical, mouse-pointer, move, music, navigation, navigation-2, octagon, package, paperclip, pause, pause-circle, pen-tool, percent, phone-call, phone-forwarded, phone-incoming, phone-missed, phone-off, phone-outgoing, phone, play, pie-chart, play-circle, plus, plus-circle, plus-square, pocket, power, printer, radio, refresh-cw, refresh-ccw, repeat, rewind, rotate-ccw, rotate-cw, rss, save, scissors, search, send, settings, share-2, shield, shield-off, shopping-bag, shopping-cart, shuffle, skip-back, skip-forward, slack, slash, sliders, smartphone, smile, speaker, star, stop-circle, sun, sunrise, sunset, tablet, tag, target, terminal, thermometer, thumbs-down, thumbs-up, toggle-left, toggle-right, tool, trash, trash-2, triangle, truck, tv, twitch, twitter, type, umbrella, unlock, user-check, user-minus, user-plus, user-x, user, users, video-off, video, voicemail, volume, volume-1, volume-2, volume-x, watch, wifi-off, wifi, wind, x-circle, x-octagon, x-square, x, youtube, zap-off, zap, zoom-in, zoom-out, default */ + /***/ + function(module3) { + module3.exports = { "activity": ["pulse", "health", "action", "motion"], "airplay": ["stream", "cast", "mirroring"], "alert-circle": ["warning", "alert", "danger"], "alert-octagon": ["warning", "alert", "danger"], "alert-triangle": ["warning", "alert", "danger"], "align-center": ["text alignment", "center"], "align-justify": ["text alignment", "justified"], "align-left": ["text alignment", "left"], "align-right": ["text alignment", "right"], "anchor": [], "archive": ["index", "box"], "at-sign": ["mention", "at", "email", "message"], "award": ["achievement", "badge"], "aperture": ["camera", "photo"], "bar-chart": ["statistics", "diagram", "graph"], "bar-chart-2": ["statistics", "diagram", "graph"], "battery": ["power", "electricity"], "battery-charging": ["power", "electricity"], "bell": ["alarm", "notification", "sound"], "bell-off": ["alarm", "notification", "silent"], "bluetooth": ["wireless"], "book-open": ["read", "library"], "book": ["read", "dictionary", "booklet", "magazine", "library"], "bookmark": ["read", "clip", "marker", "tag"], "box": ["cube"], "briefcase": ["work", "bag", "baggage", "folder"], "calendar": ["date"], "camera": ["photo"], "cast": ["chromecast", "airplay"], "chevron-down": ["expand"], "chevron-up": ["collapse"], "circle": ["off", "zero", "record"], "clipboard": ["copy"], "clock": ["time", "watch", "alarm"], "cloud-drizzle": ["weather", "shower"], "cloud-lightning": ["weather", "bolt"], "cloud-rain": ["weather"], "cloud-snow": ["weather", "blizzard"], "cloud": ["weather"], "codepen": ["logo"], "codesandbox": ["logo"], "code": ["source", "programming"], "coffee": ["drink", "cup", "mug", "tea", "cafe", "hot", "beverage"], "columns": ["layout"], "command": ["keyboard", "cmd", "terminal", "prompt"], "compass": ["navigation", "safari", "travel", "direction"], "copy": ["clone", "duplicate"], "corner-down-left": ["arrow", "return"], "corner-down-right": ["arrow"], "corner-left-down": ["arrow"], "corner-left-up": ["arrow"], "corner-right-down": ["arrow"], "corner-right-up": ["arrow"], "corner-up-left": ["arrow"], "corner-up-right": ["arrow"], "cpu": ["processor", "technology"], "credit-card": ["purchase", "payment", "cc"], "crop": ["photo", "image"], "crosshair": ["aim", "target"], "database": ["storage", "memory"], "delete": ["remove"], "disc": ["album", "cd", "dvd", "music"], "dollar-sign": ["currency", "money", "payment"], "droplet": ["water"], "edit": ["pencil", "change"], "edit-2": ["pencil", "change"], "edit-3": ["pencil", "change"], "eye": ["view", "watch"], "eye-off": ["view", "watch", "hide", "hidden"], "external-link": ["outbound"], "facebook": ["logo", "social"], "fast-forward": ["music"], "figma": ["logo", "design", "tool"], "file-minus": ["delete", "remove", "erase"], "file-plus": ["add", "create", "new"], "file-text": ["data", "txt", "pdf"], "film": ["movie", "video"], "filter": ["funnel", "hopper"], "flag": ["report"], "folder-minus": ["directory"], "folder-plus": ["directory"], "folder": ["directory"], "framer": ["logo", "design", "tool"], "frown": ["emoji", "face", "bad", "sad", "emotion"], "gift": ["present", "box", "birthday", "party"], "git-branch": ["code", "version control"], "git-commit": ["code", "version control"], "git-merge": ["code", "version control"], "git-pull-request": ["code", "version control"], "github": ["logo", "version control"], "gitlab": ["logo", "version control"], "globe": ["world", "browser", "language", "translate"], "hard-drive": ["computer", "server", "memory", "data"], "hash": ["hashtag", "number", "pound"], "headphones": ["music", "audio", "sound"], "heart": ["like", "love", "emotion"], "help-circle": ["question mark"], "hexagon": ["shape", "node.js", "logo"], "home": ["house", "living"], "image": ["picture"], "inbox": ["email"], "instagram": ["logo", "camera"], "key": ["password", "login", "authentication", "secure"], "layers": ["stack"], "layout": ["window", "webpage"], "life-bouy": ["help", "life ring", "support"], "link": ["chain", "url"], "link-2": ["chain", "url"], "linkedin": ["logo", "social media"], "list": ["options"], "lock": ["security", "password", "secure"], "log-in": ["sign in", "arrow", "enter"], "log-out": ["sign out", "arrow", "exit"], "mail": ["email", "message"], "map-pin": ["location", "navigation", "travel", "marker"], "map": ["location", "navigation", "travel"], "maximize": ["fullscreen"], "maximize-2": ["fullscreen", "arrows", "expand"], "meh": ["emoji", "face", "neutral", "emotion"], "menu": ["bars", "navigation", "hamburger"], "message-circle": ["comment", "chat"], "message-square": ["comment", "chat"], "mic-off": ["record", "sound", "mute"], "mic": ["record", "sound", "listen"], "minimize": ["exit fullscreen", "close"], "minimize-2": ["exit fullscreen", "arrows", "close"], "minus": ["subtract"], "monitor": ["tv", "screen", "display"], "moon": ["dark", "night"], "more-horizontal": ["ellipsis"], "more-vertical": ["ellipsis"], "mouse-pointer": ["arrow", "cursor"], "move": ["arrows"], "music": ["note"], "navigation": ["location", "travel"], "navigation-2": ["location", "travel"], "octagon": ["stop"], "package": ["box", "container"], "paperclip": ["attachment"], "pause": ["music", "stop"], "pause-circle": ["music", "audio", "stop"], "pen-tool": ["vector", "drawing"], "percent": ["discount"], "phone-call": ["ring"], "phone-forwarded": ["call"], "phone-incoming": ["call"], "phone-missed": ["call"], "phone-off": ["call", "mute"], "phone-outgoing": ["call"], "phone": ["call"], "play": ["music", "start"], "pie-chart": ["statistics", "diagram"], "play-circle": ["music", "start"], "plus": ["add", "new"], "plus-circle": ["add", "new"], "plus-square": ["add", "new"], "pocket": ["logo", "save"], "power": ["on", "off"], "printer": ["fax", "office", "device"], "radio": ["signal"], "refresh-cw": ["synchronise", "arrows"], "refresh-ccw": ["arrows"], "repeat": ["loop", "arrows"], "rewind": ["music"], "rotate-ccw": ["arrow"], "rotate-cw": ["arrow"], "rss": ["feed", "subscribe"], "save": ["floppy disk"], "scissors": ["cut"], "search": ["find", "magnifier", "magnifying glass"], "send": ["message", "mail", "email", "paper airplane", "paper aeroplane"], "settings": ["cog", "edit", "gear", "preferences"], "share-2": ["network", "connections"], "shield": ["security", "secure"], "shield-off": ["security", "insecure"], "shopping-bag": ["ecommerce", "cart", "purchase", "store"], "shopping-cart": ["ecommerce", "cart", "purchase", "store"], "shuffle": ["music"], "skip-back": ["music"], "skip-forward": ["music"], "slack": ["logo"], "slash": ["ban", "no"], "sliders": ["settings", "controls"], "smartphone": ["cellphone", "device"], "smile": ["emoji", "face", "happy", "good", "emotion"], "speaker": ["audio", "music"], "star": ["bookmark", "favorite", "like"], "stop-circle": ["media", "music"], "sun": ["brightness", "weather", "light"], "sunrise": ["weather", "time", "morning", "day"], "sunset": ["weather", "time", "evening", "night"], "tablet": ["device"], "tag": ["label"], "target": ["logo", "bullseye"], "terminal": ["code", "command line", "prompt"], "thermometer": ["temperature", "celsius", "fahrenheit", "weather"], "thumbs-down": ["dislike", "bad", "emotion"], "thumbs-up": ["like", "good", "emotion"], "toggle-left": ["on", "off", "switch"], "toggle-right": ["on", "off", "switch"], "tool": ["settings", "spanner"], "trash": ["garbage", "delete", "remove", "bin"], "trash-2": ["garbage", "delete", "remove", "bin"], "triangle": ["delta"], "truck": ["delivery", "van", "shipping", "transport", "lorry"], "tv": ["television", "stream"], "twitch": ["logo"], "twitter": ["logo", "social"], "type": ["text"], "umbrella": ["rain", "weather"], "unlock": ["security"], "user-check": ["followed", "subscribed"], "user-minus": ["delete", "remove", "unfollow", "unsubscribe"], "user-plus": ["new", "add", "create", "follow", "subscribe"], "user-x": ["delete", "remove", "unfollow", "unsubscribe", "unavailable"], "user": ["person", "account"], "users": ["group"], "video-off": ["camera", "movie", "film"], "video": ["camera", "movie", "film"], "voicemail": ["phone"], "volume": ["music", "sound", "mute"], "volume-1": ["music", "sound"], "volume-2": ["music", "sound"], "volume-x": ["music", "sound", "mute"], "watch": ["clock", "time"], "wifi-off": ["disabled"], "wifi": ["connection", "signal", "wireless"], "wind": ["weather", "air"], "x-circle": ["cancel", "close", "delete", "remove", "times", "clear"], "x-octagon": ["delete", "stop", "alert", "warning", "times", "clear"], "x-square": ["cancel", "close", "delete", "remove", "times", "clear"], "x": ["cancel", "close", "delete", "remove", "times", "clear"], "youtube": ["logo", "video", "play"], "zap-off": ["flash", "camera", "lightning"], "zap": ["flash", "camera", "lightning"], "zoom-in": ["magnifying glass"], "zoom-out": ["magnifying glass"] }; + } + ), + /***/ + "./src/to-svg.js": ( + /*!***********************!*\ + !*** ./src/to-svg.js ***! + \***********************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + "use strict"; + Object.defineProperty(exports3, "__esModule", { + value: true + }); + var _icons = __webpack_require__( + /*! ./icons */ + "./src/icons.js" + ); + var _icons2 = _interopRequireDefault(_icons); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + function toSvg(name) { + var attrs = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; + console.warn("feather.toSvg() is deprecated. Please use feather.icons[name].toSvg() instead."); + if (!name) { + throw new Error("The required `key` (icon name) parameter is missing."); + } + if (!_icons2.default[name]) { + throw new Error("No icon matching '" + name + "'. See the complete list of icons at https://feathericons.com"); + } + return _icons2.default[name].toSvg(attrs); + } + exports3.default = toSvg; + } + ), + /***/ + 0: ( + /*!**************************************************!*\ + !*** multi core-js/es/array/from ./src/index.js ***! + \**************************************************/ + /*! no static exports found */ + /***/ + function(module3, exports3, __webpack_require__) { + __webpack_require__( + /*! core-js/es/array/from */ + "./node_modules/core-js/es/array/from.js" + ); + module3.exports = __webpack_require__( + /*! /home/runner/work/feather/feather/src/index.js */ + "./src/index.js" + ); + } + ) + /******/ + }) + ); + }); + } +}); + +// src/main.ts +var main_exports = {}; +__export(main_exports, { + default: () => ObsidianGit +}); +module.exports = __toCommonJS(main_exports); +init_polyfill_buffer(); + +// node_modules/.pnpm/isomorphic-git@1.23.0/node_modules/isomorphic-git/index.js +init_polyfill_buffer(); +var import_async_lock = __toESM(require_async_lock(), 1); +var import_sha1 = __toESM(require_sha1(), 1); +var import_crc_32 = __toESM(require_crc32(), 1); +var import_pako = __toESM(require_pako(), 1); +var import_pify = __toESM(require_pify(), 1); +var import_ignore = __toESM(require_ignore(), 1); +var import_clean_git_ref = __toESM(require_lib2(), 1); +var import_diff3 = __toESM(require_diff3(), 1); +var BaseError = class extends Error { + constructor(message) { + super(message); + this.caller = ""; + } + toJSON() { + return { + code: this.code, + data: this.data, + caller: this.caller, + message: this.message, + stack: this.stack + }; + } + fromJSON(json) { + const e = new BaseError(json.message); + e.code = json.code; + e.data = json.data; + e.caller = json.caller; + e.stack = json.stack; + return e; + } + get isIsomorphicGitError() { + return true; + } +}; +var UnmergedPathsError = class extends BaseError { + /** + * @param {Array} filepaths + */ + constructor(filepaths) { + super( + `Modifying the index is not possible because you have unmerged files: ${filepaths.toString}. Fix them up in the work tree, and then use 'git add/rm as appropriate to mark resolution and make a commit.` + ); + this.code = this.name = UnmergedPathsError.code; + this.data = { filepaths }; + } +}; +UnmergedPathsError.code = "UnmergedPathsError"; +var InternalError = class extends BaseError { + /** + * @param {string} message + */ + constructor(message) { + super( + `An internal error caused this command to fail. Please file a bug report at https://github.com/isomorphic-git/isomorphic-git/issues with this error message: ${message}` + ); + this.code = this.name = InternalError.code; + this.data = { message }; + } +}; +InternalError.code = "InternalError"; +var UnsafeFilepathError = class extends BaseError { + /** + * @param {string} filepath + */ + constructor(filepath) { + super(`The filepath "${filepath}" contains unsafe character sequences`); + this.code = this.name = UnsafeFilepathError.code; + this.data = { filepath }; + } +}; +UnsafeFilepathError.code = "UnsafeFilepathError"; +var BufferCursor = class { + constructor(buffer2) { + this.buffer = buffer2; + this._start = 0; + } + eof() { + return this._start >= this.buffer.length; + } + tell() { + return this._start; + } + seek(n) { + this._start = n; + } + slice(n) { + const r = this.buffer.slice(this._start, this._start + n); + this._start += n; + return r; + } + toString(enc, length) { + const r = this.buffer.toString(enc, this._start, this._start + length); + this._start += length; + return r; + } + write(value, length, enc) { + const r = this.buffer.write(value, this._start, length, enc); + this._start += length; + return r; + } + copy(source, start, end) { + const r = source.copy(this.buffer, this._start, start, end); + this._start += r; + return r; + } + readUInt8() { + const r = this.buffer.readUInt8(this._start); + this._start += 1; + return r; + } + writeUInt8(value) { + const r = this.buffer.writeUInt8(value, this._start); + this._start += 1; + return r; + } + readUInt16BE() { + const r = this.buffer.readUInt16BE(this._start); + this._start += 2; + return r; + } + writeUInt16BE(value) { + const r = this.buffer.writeUInt16BE(value, this._start); + this._start += 2; + return r; + } + readUInt32BE() { + const r = this.buffer.readUInt32BE(this._start); + this._start += 4; + return r; + } + writeUInt32BE(value) { + const r = this.buffer.writeUInt32BE(value, this._start); + this._start += 4; + return r; + } +}; +function compareStrings(a, b) { + return -(a < b) || +(a > b); +} +function comparePath(a, b) { + return compareStrings(a.path, b.path); +} +function normalizeMode(mode) { + let type = mode > 0 ? mode >> 12 : 0; + if (type !== 4 && type !== 8 && type !== 10 && type !== 14) { + type = 8; + } + let permissions = mode & 511; + if (permissions & 73) { + permissions = 493; + } else { + permissions = 420; + } + if (type !== 8) + permissions = 0; + return (type << 12) + permissions; +} +var MAX_UINT32 = 2 ** 32; +function SecondsNanoseconds(givenSeconds, givenNanoseconds, milliseconds, date) { + if (givenSeconds !== void 0 && givenNanoseconds !== void 0) { + return [givenSeconds, givenNanoseconds]; + } + if (milliseconds === void 0) { + milliseconds = date.valueOf(); + } + const seconds = Math.floor(milliseconds / 1e3); + const nanoseconds = (milliseconds - seconds * 1e3) * 1e6; + return [seconds, nanoseconds]; +} +function normalizeStats(e) { + const [ctimeSeconds, ctimeNanoseconds] = SecondsNanoseconds( + e.ctimeSeconds, + e.ctimeNanoseconds, + e.ctimeMs, + e.ctime + ); + const [mtimeSeconds, mtimeNanoseconds] = SecondsNanoseconds( + e.mtimeSeconds, + e.mtimeNanoseconds, + e.mtimeMs, + e.mtime + ); + return { + ctimeSeconds: ctimeSeconds % MAX_UINT32, + ctimeNanoseconds: ctimeNanoseconds % MAX_UINT32, + mtimeSeconds: mtimeSeconds % MAX_UINT32, + mtimeNanoseconds: mtimeNanoseconds % MAX_UINT32, + dev: e.dev % MAX_UINT32, + ino: e.ino % MAX_UINT32, + mode: normalizeMode(e.mode % MAX_UINT32), + uid: e.uid % MAX_UINT32, + gid: e.gid % MAX_UINT32, + // size of -1 happens over a BrowserFS HTTP Backend that doesn't serve Content-Length headers + // (like the Karma webserver) because BrowserFS HTTP Backend uses HTTP HEAD requests to do fs.stat + size: e.size > -1 ? e.size % MAX_UINT32 : 0 + }; +} +function toHex(buffer2) { + let hex = ""; + for (const byte of new Uint8Array(buffer2)) { + if (byte < 16) + hex += "0"; + hex += byte.toString(16); + } + return hex; +} +var supportsSubtleSHA1 = null; +async function shasum(buffer2) { + if (supportsSubtleSHA1 === null) { + supportsSubtleSHA1 = await testSubtleSHA1(); + } + return supportsSubtleSHA1 ? subtleSHA1(buffer2) : shasumSync(buffer2); +} +function shasumSync(buffer2) { + return new import_sha1.default().update(buffer2).digest("hex"); +} +async function subtleSHA1(buffer2) { + const hash2 = await crypto.subtle.digest("SHA-1", buffer2); + return toHex(hash2); +} +async function testSubtleSHA1() { + try { + const hash2 = await subtleSHA1(new Uint8Array([])); + if (hash2 === "da39a3ee5e6b4b0d3255bfef95601890afd80709") + return true; + } catch (_) { + } + return false; +} +function parseCacheEntryFlags(bits) { + return { + assumeValid: Boolean(bits & 32768), + extended: Boolean(bits & 16384), + stage: (bits & 12288) >> 12, + nameLength: bits & 4095 + }; +} +function renderCacheEntryFlags(entry) { + const flags = entry.flags; + flags.extended = false; + flags.nameLength = Math.min(Buffer.from(entry.path).length, 4095); + return (flags.assumeValid ? 32768 : 0) + (flags.extended ? 16384 : 0) + ((flags.stage & 3) << 12) + (flags.nameLength & 4095); +} +var GitIndex = class { + /*:: + _entries: Map + _dirty: boolean // Used to determine if index needs to be saved to filesystem + */ + constructor(entries, unmergedPaths) { + this._dirty = false; + this._unmergedPaths = unmergedPaths || /* @__PURE__ */ new Set(); + this._entries = entries || /* @__PURE__ */ new Map(); + } + _addEntry(entry) { + if (entry.flags.stage === 0) { + entry.stages = [entry]; + this._entries.set(entry.path, entry); + this._unmergedPaths.delete(entry.path); + } else { + let existingEntry = this._entries.get(entry.path); + if (!existingEntry) { + this._entries.set(entry.path, entry); + existingEntry = entry; + } + existingEntry.stages[entry.flags.stage] = entry; + this._unmergedPaths.add(entry.path); + } + } + static async from(buffer2) { + if (Buffer.isBuffer(buffer2)) { + return GitIndex.fromBuffer(buffer2); + } else if (buffer2 === null) { + return new GitIndex(null); + } else { + throw new InternalError("invalid type passed to GitIndex.from"); + } + } + static async fromBuffer(buffer2) { + const shaComputed = await shasum(buffer2.slice(0, -20)); + const shaClaimed = buffer2.slice(-20).toString("hex"); + if (shaClaimed !== shaComputed) { + throw new InternalError( + `Invalid checksum in GitIndex buffer: expected ${shaClaimed} but saw ${shaComputed}` + ); + } + const index2 = new GitIndex(); + const reader = new BufferCursor(buffer2); + const magic = reader.toString("utf8", 4); + if (magic !== "DIRC") { + throw new InternalError(`Inavlid dircache magic file number: ${magic}`); + } + const version2 = reader.readUInt32BE(); + if (version2 !== 2) { + throw new InternalError(`Unsupported dircache version: ${version2}`); + } + const numEntries = reader.readUInt32BE(); + let i = 0; + while (!reader.eof() && i < numEntries) { + const entry = {}; + entry.ctimeSeconds = reader.readUInt32BE(); + entry.ctimeNanoseconds = reader.readUInt32BE(); + entry.mtimeSeconds = reader.readUInt32BE(); + entry.mtimeNanoseconds = reader.readUInt32BE(); + entry.dev = reader.readUInt32BE(); + entry.ino = reader.readUInt32BE(); + entry.mode = reader.readUInt32BE(); + entry.uid = reader.readUInt32BE(); + entry.gid = reader.readUInt32BE(); + entry.size = reader.readUInt32BE(); + entry.oid = reader.slice(20).toString("hex"); + const flags = reader.readUInt16BE(); + entry.flags = parseCacheEntryFlags(flags); + const pathlength = buffer2.indexOf(0, reader.tell() + 1) - reader.tell(); + if (pathlength < 1) { + throw new InternalError(`Got a path length of: ${pathlength}`); + } + entry.path = reader.toString("utf8", pathlength); + if (entry.path.includes("..\\") || entry.path.includes("../")) { + throw new UnsafeFilepathError(entry.path); + } + let padding = 8 - (reader.tell() - 12) % 8; + if (padding === 0) + padding = 8; + while (padding--) { + const tmp = reader.readUInt8(); + if (tmp !== 0) { + throw new InternalError( + `Expected 1-8 null characters but got '${tmp}' after ${entry.path}` + ); + } else if (reader.eof()) { + throw new InternalError("Unexpected end of file"); + } + } + entry.stages = []; + index2._addEntry(entry); + i++; + } + return index2; + } + get unmergedPaths() { + return [...this._unmergedPaths]; + } + get entries() { + return [...this._entries.values()].sort(comparePath); + } + get entriesMap() { + return this._entries; + } + get entriesFlat() { + return [...this.entries].flatMap((entry) => { + return entry.stages.length > 1 ? entry.stages.filter((x) => x) : entry; + }); + } + *[Symbol.iterator]() { + for (const entry of this.entries) { + yield entry; + } + } + insert({ filepath, stats, oid, stage = 0 }) { + if (!stats) { + stats = { + ctimeSeconds: 0, + ctimeNanoseconds: 0, + mtimeSeconds: 0, + mtimeNanoseconds: 0, + dev: 0, + ino: 0, + mode: 0, + uid: 0, + gid: 0, + size: 0 + }; + } + stats = normalizeStats(stats); + const bfilepath = Buffer.from(filepath); + const entry = { + ctimeSeconds: stats.ctimeSeconds, + ctimeNanoseconds: stats.ctimeNanoseconds, + mtimeSeconds: stats.mtimeSeconds, + mtimeNanoseconds: stats.mtimeNanoseconds, + dev: stats.dev, + ino: stats.ino, + // We provide a fallback value for `mode` here because not all fs + // implementations assign it, but we use it in GitTree. + // '100644' is for a "regular non-executable file" + mode: stats.mode || 33188, + uid: stats.uid, + gid: stats.gid, + size: stats.size, + path: filepath, + oid, + flags: { + assumeValid: false, + extended: false, + stage, + nameLength: bfilepath.length < 4095 ? bfilepath.length : 4095 + }, + stages: [] + }; + this._addEntry(entry); + this._dirty = true; + } + delete({ filepath }) { + if (this._entries.has(filepath)) { + this._entries.delete(filepath); + } else { + for (const key2 of this._entries.keys()) { + if (key2.startsWith(filepath + "/")) { + this._entries.delete(key2); + } + } + } + if (this._unmergedPaths.has(filepath)) { + this._unmergedPaths.delete(filepath); + } + this._dirty = true; + } + clear() { + this._entries.clear(); + this._dirty = true; + } + has({ filepath }) { + return this._entries.has(filepath); + } + render() { + return this.entries.map((entry) => `${entry.mode.toString(8)} ${entry.oid} ${entry.path}`).join("\n"); + } + static async _entryToBuffer(entry) { + const bpath = Buffer.from(entry.path); + const length = Math.ceil((62 + bpath.length + 1) / 8) * 8; + const written = Buffer.alloc(length); + const writer = new BufferCursor(written); + const stat = normalizeStats(entry); + writer.writeUInt32BE(stat.ctimeSeconds); + writer.writeUInt32BE(stat.ctimeNanoseconds); + writer.writeUInt32BE(stat.mtimeSeconds); + writer.writeUInt32BE(stat.mtimeNanoseconds); + writer.writeUInt32BE(stat.dev); + writer.writeUInt32BE(stat.ino); + writer.writeUInt32BE(stat.mode); + writer.writeUInt32BE(stat.uid); + writer.writeUInt32BE(stat.gid); + writer.writeUInt32BE(stat.size); + writer.write(entry.oid, 20, "hex"); + writer.writeUInt16BE(renderCacheEntryFlags(entry)); + writer.write(entry.path, bpath.length, "utf8"); + return written; + } + async toObject() { + const header = Buffer.alloc(12); + const writer = new BufferCursor(header); + writer.write("DIRC", 4, "utf8"); + writer.writeUInt32BE(2); + writer.writeUInt32BE(this.entriesFlat.length); + let entryBuffers = []; + for (const entry of this.entries) { + entryBuffers.push(GitIndex._entryToBuffer(entry)); + if (entry.stages.length > 1) { + for (const stage of entry.stages) { + if (stage && stage !== entry) { + entryBuffers.push(GitIndex._entryToBuffer(stage)); + } + } + } + } + entryBuffers = await Promise.all(entryBuffers); + const body = Buffer.concat(entryBuffers); + const main = Buffer.concat([header, body]); + const sum = await shasum(main); + return Buffer.concat([main, Buffer.from(sum, "hex")]); + } +}; +function compareStats(entry, stats) { + const e = normalizeStats(entry); + const s = normalizeStats(stats); + const staleness = e.mode !== s.mode || e.mtimeSeconds !== s.mtimeSeconds || e.ctimeSeconds !== s.ctimeSeconds || e.uid !== s.uid || e.gid !== s.gid || e.ino !== s.ino || e.size !== s.size; + return staleness; +} +var lock = null; +var IndexCache = Symbol("IndexCache"); +function createCache() { + return { + map: /* @__PURE__ */ new Map(), + stats: /* @__PURE__ */ new Map() + }; +} +async function updateCachedIndexFile(fs, filepath, cache) { + const stat = await fs.lstat(filepath); + const rawIndexFile = await fs.read(filepath); + const index2 = await GitIndex.from(rawIndexFile); + cache.map.set(filepath, index2); + cache.stats.set(filepath, stat); +} +async function isIndexStale(fs, filepath, cache) { + const savedStats = cache.stats.get(filepath); + if (savedStats === void 0) + return true; + const currStats = await fs.lstat(filepath); + if (savedStats === null) + return false; + if (currStats === null) + return false; + return compareStats(savedStats, currStats); +} +var GitIndexManager = class { + /** + * + * @param {object} opts + * @param {import('../models/FileSystem.js').FileSystem} opts.fs + * @param {string} opts.gitdir + * @param {object} opts.cache + * @param {bool} opts.allowUnmerged + * @param {function(GitIndex): any} closure + */ + static async acquire({ fs, gitdir, cache, allowUnmerged = true }, closure) { + if (!cache[IndexCache]) + cache[IndexCache] = createCache(); + const filepath = `${gitdir}/index`; + if (lock === null) + lock = new import_async_lock.default({ maxPending: Infinity }); + let result; + let unmergedPaths = []; + await lock.acquire(filepath, async () => { + if (await isIndexStale(fs, filepath, cache[IndexCache])) { + await updateCachedIndexFile(fs, filepath, cache[IndexCache]); + } + const index2 = cache[IndexCache].map.get(filepath); + unmergedPaths = index2.unmergedPaths; + if (unmergedPaths.length && !allowUnmerged) + throw new UnmergedPathsError(unmergedPaths); + result = await closure(index2); + if (index2._dirty) { + const buffer2 = await index2.toObject(); + await fs.write(filepath, buffer2); + cache[IndexCache].stats.set(filepath, await fs.lstat(filepath)); + index2._dirty = false; + } + }); + return result; + } +}; +function basename(path2) { + const last2 = Math.max(path2.lastIndexOf("/"), path2.lastIndexOf("\\")); + if (last2 > -1) { + path2 = path2.slice(last2 + 1); + } + return path2; +} +function dirname(path2) { + const last2 = Math.max(path2.lastIndexOf("/"), path2.lastIndexOf("\\")); + if (last2 === -1) + return "."; + if (last2 === 0) + return "/"; + return path2.slice(0, last2); +} +function flatFileListToDirectoryStructure(files) { + const inodes = /* @__PURE__ */ new Map(); + const mkdir = function(name) { + if (!inodes.has(name)) { + const dir = { + type: "tree", + fullpath: name, + basename: basename(name), + metadata: {}, + children: [] + }; + inodes.set(name, dir); + dir.parent = mkdir(dirname(name)); + if (dir.parent && dir.parent !== dir) + dir.parent.children.push(dir); + } + return inodes.get(name); + }; + const mkfile = function(name, metadata) { + if (!inodes.has(name)) { + const file = { + type: "blob", + fullpath: name, + basename: basename(name), + metadata, + // This recursively generates any missing parent folders. + parent: mkdir(dirname(name)), + children: [] + }; + if (file.parent) + file.parent.children.push(file); + inodes.set(name, file); + } + return inodes.get(name); + }; + mkdir("."); + for (const file of files) { + mkfile(file.path, file); + } + return inodes; +} +function mode2type(mode) { + switch (mode) { + case 16384: + return "tree"; + case 33188: + return "blob"; + case 33261: + return "blob"; + case 40960: + return "blob"; + case 57344: + return "commit"; + } + throw new InternalError(`Unexpected GitTree entry mode: ${mode.toString(8)}`); +} +var GitWalkerIndex = class { + constructor({ fs, gitdir, cache }) { + this.treePromise = GitIndexManager.acquire( + { fs, gitdir, cache }, + async function(index2) { + return flatFileListToDirectoryStructure(index2.entries); + } + ); + const walker = this; + this.ConstructEntry = class StageEntry { + constructor(fullpath) { + this._fullpath = fullpath; + this._type = false; + this._mode = false; + this._stat = false; + this._oid = false; + } + async type() { + return walker.type(this); + } + async mode() { + return walker.mode(this); + } + async stat() { + return walker.stat(this); + } + async content() { + return walker.content(this); + } + async oid() { + return walker.oid(this); + } + }; + } + async readdir(entry) { + const filepath = entry._fullpath; + const tree = await this.treePromise; + const inode = tree.get(filepath); + if (!inode) + return null; + if (inode.type === "blob") + return null; + if (inode.type !== "tree") { + throw new Error(`ENOTDIR: not a directory, scandir '${filepath}'`); + } + const names = inode.children.map((inode2) => inode2.fullpath); + names.sort(compareStrings); + return names; + } + async type(entry) { + if (entry._type === false) { + await entry.stat(); + } + return entry._type; + } + async mode(entry) { + if (entry._mode === false) { + await entry.stat(); + } + return entry._mode; + } + async stat(entry) { + if (entry._stat === false) { + const tree = await this.treePromise; + const inode = tree.get(entry._fullpath); + if (!inode) { + throw new Error( + `ENOENT: no such file or directory, lstat '${entry._fullpath}'` + ); + } + const stats = inode.type === "tree" ? {} : normalizeStats(inode.metadata); + entry._type = inode.type === "tree" ? "tree" : mode2type(stats.mode); + entry._mode = stats.mode; + if (inode.type === "tree") { + entry._stat = void 0; + } else { + entry._stat = stats; + } + } + return entry._stat; + } + async content(_entry) { + } + async oid(entry) { + if (entry._oid === false) { + const tree = await this.treePromise; + const inode = tree.get(entry._fullpath); + entry._oid = inode.metadata.oid; + } + return entry._oid; + } +}; +var GitWalkSymbol = Symbol("GitWalkSymbol"); +function STAGE() { + const o = /* @__PURE__ */ Object.create(null); + Object.defineProperty(o, GitWalkSymbol, { + value: function({ fs, gitdir, cache }) { + return new GitWalkerIndex({ fs, gitdir, cache }); + } + }); + Object.freeze(o); + return o; +} +var NotFoundError = class extends BaseError { + /** + * @param {string} what + */ + constructor(what) { + super(`Could not find ${what}.`); + this.code = this.name = NotFoundError.code; + this.data = { what }; + } +}; +NotFoundError.code = "NotFoundError"; +var ObjectTypeError = class extends BaseError { + /** + * @param {string} oid + * @param {'blob'|'commit'|'tag'|'tree'} actual + * @param {'blob'|'commit'|'tag'|'tree'} expected + * @param {string} [filepath] + */ + constructor(oid, actual, expected, filepath) { + super( + `Object ${oid} ${filepath ? `at ${filepath}` : ""}was anticipated to be a ${expected} but it is a ${actual}.` + ); + this.code = this.name = ObjectTypeError.code; + this.data = { oid, actual, expected, filepath }; + } +}; +ObjectTypeError.code = "ObjectTypeError"; +var InvalidOidError = class extends BaseError { + /** + * @param {string} value + */ + constructor(value) { + super(`Expected a 40-char hex object id but saw "${value}".`); + this.code = this.name = InvalidOidError.code; + this.data = { value }; + } +}; +InvalidOidError.code = "InvalidOidError"; +var NoRefspecError = class extends BaseError { + /** + * @param {string} remote + */ + constructor(remote) { + super(`Could not find a fetch refspec for remote "${remote}". Make sure the config file has an entry like the following: +[remote "${remote}"] + fetch = +refs/heads/*:refs/remotes/origin/* +`); + this.code = this.name = NoRefspecError.code; + this.data = { remote }; + } +}; +NoRefspecError.code = "NoRefspecError"; +var GitPackedRefs = class { + constructor(text2) { + this.refs = /* @__PURE__ */ new Map(); + this.parsedConfig = []; + if (text2) { + let key2 = null; + this.parsedConfig = text2.trim().split("\n").map((line) => { + if (/^\s*#/.test(line)) { + return { line, comment: true }; + } + const i = line.indexOf(" "); + if (line.startsWith("^")) { + const value = line.slice(1); + this.refs.set(key2 + "^{}", value); + return { line, ref: key2, peeled: value }; + } else { + const value = line.slice(0, i); + key2 = line.slice(i + 1); + this.refs.set(key2, value); + return { line, ref: key2, oid: value }; + } + }); + } + return this; + } + static from(text2) { + return new GitPackedRefs(text2); + } + delete(ref) { + this.parsedConfig = this.parsedConfig.filter((entry) => entry.ref !== ref); + this.refs.delete(ref); + } + toString() { + return this.parsedConfig.map(({ line }) => line).join("\n") + "\n"; + } +}; +var GitRefSpec = class { + constructor({ remotePath, localPath, force, matchPrefix }) { + Object.assign(this, { + remotePath, + localPath, + force, + matchPrefix + }); + } + static from(refspec) { + const [ + forceMatch, + remotePath, + remoteGlobMatch, + localPath, + localGlobMatch + ] = refspec.match(/^(\+?)(.*?)(\*?):(.*?)(\*?)$/).slice(1); + const force = forceMatch === "+"; + const remoteIsGlob = remoteGlobMatch === "*"; + const localIsGlob = localGlobMatch === "*"; + if (remoteIsGlob !== localIsGlob) { + throw new InternalError("Invalid refspec"); + } + return new GitRefSpec({ + remotePath, + localPath, + force, + matchPrefix: remoteIsGlob + }); + } + translate(remoteBranch) { + if (this.matchPrefix) { + if (remoteBranch.startsWith(this.remotePath)) { + return this.localPath + remoteBranch.replace(this.remotePath, ""); + } + } else { + if (remoteBranch === this.remotePath) + return this.localPath; + } + return null; + } + reverseTranslate(localBranch) { + if (this.matchPrefix) { + if (localBranch.startsWith(this.localPath)) { + return this.remotePath + localBranch.replace(this.localPath, ""); + } + } else { + if (localBranch === this.localPath) + return this.remotePath; + } + return null; + } +}; +var GitRefSpecSet = class { + constructor(rules = []) { + this.rules = rules; + } + static from(refspecs) { + const rules = []; + for (const refspec of refspecs) { + rules.push(GitRefSpec.from(refspec)); + } + return new GitRefSpecSet(rules); + } + add(refspec) { + const rule = GitRefSpec.from(refspec); + this.rules.push(rule); + } + translate(remoteRefs) { + const result = []; + for (const rule of this.rules) { + for (const remoteRef of remoteRefs) { + const localRef = rule.translate(remoteRef); + if (localRef) { + result.push([remoteRef, localRef]); + } + } + } + return result; + } + translateOne(remoteRef) { + let result = null; + for (const rule of this.rules) { + const localRef = rule.translate(remoteRef); + if (localRef) { + result = localRef; + } + } + return result; + } + localNamespaces() { + return this.rules.filter((rule) => rule.matchPrefix).map((rule) => rule.localPath.replace(/\/$/, "")); + } +}; +function compareRefNames(a, b) { + const _a2 = a.replace(/\^\{\}$/, ""); + const _b = b.replace(/\^\{\}$/, ""); + const tmp = -(_a2 < _b) || +(_a2 > _b); + if (tmp === 0) { + return a.endsWith("^{}") ? 1 : -1; + } + return tmp; +} +function normalizePath(path2) { + return path2.replace(/\/\.\//g, "/").replace(/\/{2,}/g, "/").replace(/^\/\.$/, "/").replace(/^\.\/$/, ".").replace(/^\.\//, "").replace(/\/\.$/, "").replace(/(.+)\/$/, "$1").replace(/^$/, "."); +} +function join(...parts) { + return normalizePath(parts.map(normalizePath).join("/")); +} +var num = (val) => { + val = val.toLowerCase(); + let n = parseInt(val); + if (val.endsWith("k")) + n *= 1024; + if (val.endsWith("m")) + n *= 1024 * 1024; + if (val.endsWith("g")) + n *= 1024 * 1024 * 1024; + return n; +}; +var bool = (val) => { + val = val.trim().toLowerCase(); + if (val === "true" || val === "yes" || val === "on") + return true; + if (val === "false" || val === "no" || val === "off") + return false; + throw Error( + `Expected 'true', 'false', 'yes', 'no', 'on', or 'off', but got ${val}` + ); +}; +var schema = { + core: { + filemode: bool, + bare: bool, + logallrefupdates: bool, + symlinks: bool, + ignorecase: bool, + bigFileThreshold: num + } +}; +var SECTION_LINE_REGEX = /^\[([A-Za-z0-9-.]+)(?: "(.*)")?\]$/; +var SECTION_REGEX = /^[A-Za-z0-9-.]+$/; +var VARIABLE_LINE_REGEX = /^([A-Za-z][A-Za-z-]*)(?: *= *(.*))?$/; +var VARIABLE_NAME_REGEX = /^[A-Za-z][A-Za-z-]*$/; +var VARIABLE_VALUE_COMMENT_REGEX = /^(.*?)( *[#;].*)$/; +var extractSectionLine = (line) => { + const matches = SECTION_LINE_REGEX.exec(line); + if (matches != null) { + const [section, subsection] = matches.slice(1); + return [section, subsection]; + } + return null; +}; +var extractVariableLine = (line) => { + const matches = VARIABLE_LINE_REGEX.exec(line); + if (matches != null) { + const [name, rawValue = "true"] = matches.slice(1); + const valueWithoutComments = removeComments(rawValue); + const valueWithoutQuotes = removeQuotes(valueWithoutComments); + return [name, valueWithoutQuotes]; + } + return null; +}; +var removeComments = (rawValue) => { + const commentMatches = VARIABLE_VALUE_COMMENT_REGEX.exec(rawValue); + if (commentMatches == null) { + return rawValue; + } + const [valueWithoutComment, comment] = commentMatches.slice(1); + if (hasOddNumberOfQuotes(valueWithoutComment) && hasOddNumberOfQuotes(comment)) { + return `${valueWithoutComment}${comment}`; + } + return valueWithoutComment; +}; +var hasOddNumberOfQuotes = (text2) => { + const numberOfQuotes = (text2.match(/(?:^|[^\\])"/g) || []).length; + return numberOfQuotes % 2 !== 0; +}; +var removeQuotes = (text2) => { + return text2.split("").reduce((newText, c, idx, text3) => { + const isQuote = c === '"' && text3[idx - 1] !== "\\"; + const isEscapeForQuote = c === "\\" && text3[idx + 1] === '"'; + if (isQuote || isEscapeForQuote) { + return newText; + } + return newText + c; + }, ""); +}; +var lower = (text2) => { + return text2 != null ? text2.toLowerCase() : null; +}; +var getPath = (section, subsection, name) => { + return [lower(section), subsection, lower(name)].filter((a) => a != null).join("."); +}; +var normalizePath$1 = (path2) => { + const pathSegments = path2.split("."); + const section = pathSegments.shift(); + const name = pathSegments.pop(); + const subsection = pathSegments.length ? pathSegments.join(".") : void 0; + return { + section, + subsection, + name, + path: getPath(section, subsection, name), + sectionPath: getPath(section, subsection, null) + }; +}; +var findLastIndex = (array, callback) => { + return array.reduce((lastIndex, item, index2) => { + return callback(item) ? index2 : lastIndex; + }, -1); +}; +var GitConfig = class { + constructor(text2) { + let section = null; + let subsection = null; + this.parsedConfig = text2.split("\n").map((line) => { + let name = null; + let value = null; + const trimmedLine = line.trim(); + const extractedSection = extractSectionLine(trimmedLine); + const isSection = extractedSection != null; + if (isSection) { + ; + [section, subsection] = extractedSection; + } else { + const extractedVariable = extractVariableLine(trimmedLine); + const isVariable = extractedVariable != null; + if (isVariable) { + ; + [name, value] = extractedVariable; + } + } + const path2 = getPath(section, subsection, name); + return { line, isSection, section, subsection, name, value, path: path2 }; + }); + } + static from(text2) { + return new GitConfig(text2); + } + async get(path2, getall = false) { + const normalizedPath = normalizePath$1(path2).path; + const allValues = this.parsedConfig.filter((config) => config.path === normalizedPath).map(({ section, name, value }) => { + const fn = schema[section] && schema[section][name]; + return fn ? fn(value) : value; + }); + return getall ? allValues : allValues.pop(); + } + async getall(path2) { + return this.get(path2, true); + } + async getSubsections(section) { + return this.parsedConfig.filter((config) => config.section === section && config.isSection).map((config) => config.subsection); + } + async deleteSection(section, subsection) { + this.parsedConfig = this.parsedConfig.filter( + (config) => !(config.section === section && config.subsection === subsection) + ); + } + async append(path2, value) { + return this.set(path2, value, true); + } + async set(path2, value, append3 = false) { + const { + section, + subsection, + name, + path: normalizedPath, + sectionPath + } = normalizePath$1(path2); + const configIndex = findLastIndex( + this.parsedConfig, + (config) => config.path === normalizedPath + ); + if (value == null) { + if (configIndex !== -1) { + this.parsedConfig.splice(configIndex, 1); + } + } else { + if (configIndex !== -1) { + const config = this.parsedConfig[configIndex]; + const modifiedConfig = Object.assign({}, config, { + name, + value, + modified: true + }); + if (append3) { + this.parsedConfig.splice(configIndex + 1, 0, modifiedConfig); + } else { + this.parsedConfig[configIndex] = modifiedConfig; + } + } else { + const sectionIndex = this.parsedConfig.findIndex( + (config) => config.path === sectionPath + ); + const newConfig = { + section, + subsection, + name, + value, + modified: true, + path: normalizedPath + }; + if (SECTION_REGEX.test(section) && VARIABLE_NAME_REGEX.test(name)) { + if (sectionIndex >= 0) { + this.parsedConfig.splice(sectionIndex + 1, 0, newConfig); + } else { + const newSection = { + section, + subsection, + modified: true, + path: sectionPath + }; + this.parsedConfig.push(newSection, newConfig); + } + } + } + } + } + toString() { + return this.parsedConfig.map(({ line, section, subsection, name, value, modified: modified2 = false }) => { + if (!modified2) { + return line; + } + if (name != null && value != null) { + if (typeof value === "string" && /[#;]/.test(value)) { + return ` ${name} = "${value}"`; + } + return ` ${name} = ${value}`; + } + if (subsection != null) { + return `[${section} "${subsection}"]`; + } + return `[${section}]`; + }).join("\n"); + } +}; +var GitConfigManager = class { + static async get({ fs, gitdir }) { + const text2 = await fs.read(`${gitdir}/config`, { encoding: "utf8" }); + return GitConfig.from(text2); + } + static async save({ fs, gitdir, config }) { + await fs.write(`${gitdir}/config`, config.toString(), { + encoding: "utf8" + }); + } +}; +var refpaths = (ref) => [ + `${ref}`, + `refs/${ref}`, + `refs/tags/${ref}`, + `refs/heads/${ref}`, + `refs/remotes/${ref}`, + `refs/remotes/${ref}/HEAD` +]; +var GIT_FILES = ["config", "description", "index", "shallow", "commondir"]; +var GitRefManager = class { + static async updateRemoteRefs({ + fs, + gitdir, + remote, + refs, + symrefs, + tags, + refspecs = void 0, + prune = false, + pruneTags = false + }) { + for (const value of refs.values()) { + if (!value.match(/[0-9a-f]{40}/)) { + throw new InvalidOidError(value); + } + } + const config = await GitConfigManager.get({ fs, gitdir }); + if (!refspecs) { + refspecs = await config.getall(`remote.${remote}.fetch`); + if (refspecs.length === 0) { + throw new NoRefspecError(remote); + } + refspecs.unshift(`+HEAD:refs/remotes/${remote}/HEAD`); + } + const refspec = GitRefSpecSet.from(refspecs); + const actualRefsToWrite = /* @__PURE__ */ new Map(); + if (pruneTags) { + const tags2 = await GitRefManager.listRefs({ + fs, + gitdir, + filepath: "refs/tags" + }); + await GitRefManager.deleteRefs({ + fs, + gitdir, + refs: tags2.map((tag2) => `refs/tags/${tag2}`) + }); + } + if (tags) { + for (const serverRef of refs.keys()) { + if (serverRef.startsWith("refs/tags") && !serverRef.endsWith("^{}")) { + if (!await GitRefManager.exists({ fs, gitdir, ref: serverRef })) { + const oid = refs.get(serverRef); + actualRefsToWrite.set(serverRef, oid); + } + } + } + } + const refTranslations = refspec.translate([...refs.keys()]); + for (const [serverRef, translatedRef] of refTranslations) { + const value = refs.get(serverRef); + actualRefsToWrite.set(translatedRef, value); + } + const symrefTranslations = refspec.translate([...symrefs.keys()]); + for (const [serverRef, translatedRef] of symrefTranslations) { + const value = symrefs.get(serverRef); + const symtarget = refspec.translateOne(value); + if (symtarget) { + actualRefsToWrite.set(translatedRef, `ref: ${symtarget}`); + } + } + const pruned = []; + if (prune) { + for (const filepath of refspec.localNamespaces()) { + const refs2 = (await GitRefManager.listRefs({ + fs, + gitdir, + filepath + })).map((file) => `${filepath}/${file}`); + for (const ref of refs2) { + if (!actualRefsToWrite.has(ref)) { + pruned.push(ref); + } + } + } + if (pruned.length > 0) { + await GitRefManager.deleteRefs({ fs, gitdir, refs: pruned }); + } + } + for (const [key2, value] of actualRefsToWrite) { + await fs.write(join(gitdir, key2), `${value.trim()} +`, "utf8"); + } + return { pruned }; + } + // TODO: make this less crude? + static async writeRef({ fs, gitdir, ref, value }) { + if (!value.match(/[0-9a-f]{40}/)) { + throw new InvalidOidError(value); + } + await fs.write(join(gitdir, ref), `${value.trim()} +`, "utf8"); + } + static async writeSymbolicRef({ fs, gitdir, ref, value }) { + await fs.write(join(gitdir, ref), `ref: ${value.trim()} +`, "utf8"); + } + static async deleteRef({ fs, gitdir, ref }) { + return GitRefManager.deleteRefs({ fs, gitdir, refs: [ref] }); + } + static async deleteRefs({ fs, gitdir, refs }) { + await Promise.all(refs.map((ref) => fs.rm(join(gitdir, ref)))); + let text2 = await fs.read(`${gitdir}/packed-refs`, { encoding: "utf8" }); + const packed = GitPackedRefs.from(text2); + const beforeSize = packed.refs.size; + for (const ref of refs) { + if (packed.refs.has(ref)) { + packed.delete(ref); + } + } + if (packed.refs.size < beforeSize) { + text2 = packed.toString(); + await fs.write(`${gitdir}/packed-refs`, text2, { encoding: "utf8" }); + } + } + /** + * @param {object} args + * @param {import('../models/FileSystem.js').FileSystem} args.fs + * @param {string} args.gitdir + * @param {string} args.ref + * @param {number} [args.depth] + * @returns {Promise} + */ + static async resolve({ fs, gitdir, ref, depth = void 0 }) { + if (depth !== void 0) { + depth--; + if (depth === -1) { + return ref; + } + } + let sha; + if (ref.startsWith("ref: ")) { + ref = ref.slice("ref: ".length); + return GitRefManager.resolve({ fs, gitdir, ref, depth }); + } + if (ref.length === 40 && /[0-9a-f]{40}/.test(ref)) { + return ref; + } + const packedMap = await GitRefManager.packedRefs({ fs, gitdir }); + const allpaths = refpaths(ref).filter((p) => !GIT_FILES.includes(p)); + for (const ref2 of allpaths) { + sha = await fs.read(`${gitdir}/${ref2}`, { encoding: "utf8" }) || packedMap.get(ref2); + if (sha) { + return GitRefManager.resolve({ fs, gitdir, ref: sha.trim(), depth }); + } + } + throw new NotFoundError(ref); + } + static async exists({ fs, gitdir, ref }) { + try { + await GitRefManager.expand({ fs, gitdir, ref }); + return true; + } catch (err) { + return false; + } + } + static async expand({ fs, gitdir, ref }) { + if (ref.length === 40 && /[0-9a-f]{40}/.test(ref)) { + return ref; + } + const packedMap = await GitRefManager.packedRefs({ fs, gitdir }); + const allpaths = refpaths(ref); + for (const ref2 of allpaths) { + if (await fs.exists(`${gitdir}/${ref2}`)) + return ref2; + if (packedMap.has(ref2)) + return ref2; + } + throw new NotFoundError(ref); + } + static async expandAgainstMap({ ref, map }) { + const allpaths = refpaths(ref); + for (const ref2 of allpaths) { + if (await map.has(ref2)) + return ref2; + } + throw new NotFoundError(ref); + } + static resolveAgainstMap({ ref, fullref = ref, depth = void 0, map }) { + if (depth !== void 0) { + depth--; + if (depth === -1) { + return { fullref, oid: ref }; + } + } + if (ref.startsWith("ref: ")) { + ref = ref.slice("ref: ".length); + return GitRefManager.resolveAgainstMap({ ref, fullref, depth, map }); + } + if (ref.length === 40 && /[0-9a-f]{40}/.test(ref)) { + return { fullref, oid: ref }; + } + const allpaths = refpaths(ref); + for (const ref2 of allpaths) { + const sha = map.get(ref2); + if (sha) { + return GitRefManager.resolveAgainstMap({ + ref: sha.trim(), + fullref: ref2, + depth, + map + }); + } + } + throw new NotFoundError(ref); + } + static async packedRefs({ fs, gitdir }) { + const text2 = await fs.read(`${gitdir}/packed-refs`, { encoding: "utf8" }); + const packed = GitPackedRefs.from(text2); + return packed.refs; + } + // List all the refs that match the `filepath` prefix + static async listRefs({ fs, gitdir, filepath }) { + const packedMap = GitRefManager.packedRefs({ fs, gitdir }); + let files = null; + try { + files = await fs.readdirDeep(`${gitdir}/${filepath}`); + files = files.map((x) => x.replace(`${gitdir}/${filepath}/`, "")); + } catch (err) { + files = []; + } + for (let key2 of (await packedMap).keys()) { + if (key2.startsWith(filepath)) { + key2 = key2.replace(filepath + "/", ""); + if (!files.includes(key2)) { + files.push(key2); + } + } + } + files.sort(compareRefNames); + return files; + } + static async listBranches({ fs, gitdir, remote }) { + if (remote) { + return GitRefManager.listRefs({ + fs, + gitdir, + filepath: `refs/remotes/${remote}` + }); + } else { + return GitRefManager.listRefs({ fs, gitdir, filepath: `refs/heads` }); + } + } + static async listTags({ fs, gitdir }) { + const tags = await GitRefManager.listRefs({ + fs, + gitdir, + filepath: `refs/tags` + }); + return tags.filter((x) => !x.endsWith("^{}")); + } +}; +function compareTreeEntryPath(a, b) { + return compareStrings(appendSlashIfDir(a), appendSlashIfDir(b)); +} +function appendSlashIfDir(entry) { + return entry.mode === "040000" ? entry.path + "/" : entry.path; +} +function mode2type$1(mode) { + switch (mode) { + case "040000": + return "tree"; + case "100644": + return "blob"; + case "100755": + return "blob"; + case "120000": + return "blob"; + case "160000": + return "commit"; + } + throw new InternalError(`Unexpected GitTree entry mode: ${mode}`); +} +function parseBuffer(buffer2) { + const _entries = []; + let cursor = 0; + while (cursor < buffer2.length) { + const space2 = buffer2.indexOf(32, cursor); + if (space2 === -1) { + throw new InternalError( + `GitTree: Error parsing buffer at byte location ${cursor}: Could not find the next space character.` + ); + } + const nullchar = buffer2.indexOf(0, cursor); + if (nullchar === -1) { + throw new InternalError( + `GitTree: Error parsing buffer at byte location ${cursor}: Could not find the next null character.` + ); + } + let mode = buffer2.slice(cursor, space2).toString("utf8"); + if (mode === "40000") + mode = "040000"; + const type = mode2type$1(mode); + const path2 = buffer2.slice(space2 + 1, nullchar).toString("utf8"); + if (path2.includes("\\") || path2.includes("/")) { + throw new UnsafeFilepathError(path2); + } + const oid = buffer2.slice(nullchar + 1, nullchar + 21).toString("hex"); + cursor = nullchar + 21; + _entries.push({ mode, path: path2, oid, type }); + } + return _entries; +} +function limitModeToAllowed(mode) { + if (typeof mode === "number") { + mode = mode.toString(8); + } + if (mode.match(/^0?4.*/)) + return "040000"; + if (mode.match(/^1006.*/)) + return "100644"; + if (mode.match(/^1007.*/)) + return "100755"; + if (mode.match(/^120.*/)) + return "120000"; + if (mode.match(/^160.*/)) + return "160000"; + throw new InternalError(`Could not understand file mode: ${mode}`); +} +function nudgeIntoShape(entry) { + if (!entry.oid && entry.sha) { + entry.oid = entry.sha; + } + entry.mode = limitModeToAllowed(entry.mode); + if (!entry.type) { + entry.type = mode2type$1(entry.mode); + } + return entry; +} +var GitTree = class { + constructor(entries) { + if (Buffer.isBuffer(entries)) { + this._entries = parseBuffer(entries); + } else if (Array.isArray(entries)) { + this._entries = entries.map(nudgeIntoShape); + } else { + throw new InternalError("invalid type passed to GitTree constructor"); + } + this._entries.sort(comparePath); + } + static from(tree) { + return new GitTree(tree); + } + render() { + return this._entries.map((entry) => `${entry.mode} ${entry.type} ${entry.oid} ${entry.path}`).join("\n"); + } + toObject() { + const entries = [...this._entries]; + entries.sort(compareTreeEntryPath); + return Buffer.concat( + entries.map((entry) => { + const mode = Buffer.from(entry.mode.replace(/^0/, "")); + const space2 = Buffer.from(" "); + const path2 = Buffer.from(entry.path, "utf8"); + const nullchar = Buffer.from([0]); + const oid = Buffer.from(entry.oid, "hex"); + return Buffer.concat([mode, space2, path2, nullchar, oid]); + }) + ); + } + /** + * @returns {TreeEntry[]} + */ + entries() { + return this._entries; + } + *[Symbol.iterator]() { + for (const entry of this._entries) { + yield entry; + } + } +}; +var GitObject = class { + static wrap({ type, object }) { + return Buffer.concat([ + Buffer.from(`${type} ${object.byteLength.toString()}\0`), + Buffer.from(object) + ]); + } + static unwrap(buffer2) { + const s = buffer2.indexOf(32); + const i = buffer2.indexOf(0); + const type = buffer2.slice(0, s).toString("utf8"); + const length = buffer2.slice(s + 1, i).toString("utf8"); + const actualLength = buffer2.length - (i + 1); + if (parseInt(length) !== actualLength) { + throw new InternalError( + `Length mismatch: expected ${length} bytes but got ${actualLength} instead.` + ); + } + return { + type, + object: Buffer.from(buffer2.slice(i + 1)) + }; + } +}; +async function readObjectLoose({ fs, gitdir, oid }) { + const source = `objects/${oid.slice(0, 2)}/${oid.slice(2)}`; + const file = await fs.read(`${gitdir}/${source}`); + if (!file) { + return null; + } + return { object: file, format: "deflated", source }; +} +function applyDelta(delta, source) { + const reader = new BufferCursor(delta); + const sourceSize = readVarIntLE(reader); + if (sourceSize !== source.byteLength) { + throw new InternalError( + `applyDelta expected source buffer to be ${sourceSize} bytes but the provided buffer was ${source.length} bytes` + ); + } + const targetSize = readVarIntLE(reader); + let target; + const firstOp = readOp(reader, source); + if (firstOp.byteLength === targetSize) { + target = firstOp; + } else { + target = Buffer.alloc(targetSize); + const writer = new BufferCursor(target); + writer.copy(firstOp); + while (!reader.eof()) { + writer.copy(readOp(reader, source)); + } + const tell = writer.tell(); + if (targetSize !== tell) { + throw new InternalError( + `applyDelta expected target buffer to be ${targetSize} bytes but the resulting buffer was ${tell} bytes` + ); + } + } + return target; +} +function readVarIntLE(reader) { + let result = 0; + let shift = 0; + let byte = null; + do { + byte = reader.readUInt8(); + result |= (byte & 127) << shift; + shift += 7; + } while (byte & 128); + return result; +} +function readCompactLE(reader, flags, size) { + let result = 0; + let shift = 0; + while (size--) { + if (flags & 1) { + result |= reader.readUInt8() << shift; + } + flags >>= 1; + shift += 8; + } + return result; +} +function readOp(reader, source) { + const byte = reader.readUInt8(); + const COPY = 128; + const OFFS = 15; + const SIZE = 112; + if (byte & COPY) { + const offset = readCompactLE(reader, byte & OFFS, 4); + let size = readCompactLE(reader, (byte & SIZE) >> 4, 3); + if (size === 0) + size = 65536; + return source.slice(offset, offset + size); + } else { + return reader.slice(byte); + } +} +function fromValue(value) { + let queue = [value]; + return { + next() { + return Promise.resolve({ done: queue.length === 0, value: queue.pop() }); + }, + return() { + queue = []; + return {}; + }, + [Symbol.asyncIterator]() { + return this; + } + }; +} +function getIterator(iterable) { + if (iterable[Symbol.asyncIterator]) { + return iterable[Symbol.asyncIterator](); + } + if (iterable[Symbol.iterator]) { + return iterable[Symbol.iterator](); + } + if (iterable.next) { + return iterable; + } + return fromValue(iterable); +} +var StreamReader = class { + constructor(stream) { + this.stream = getIterator(stream); + this.buffer = null; + this.cursor = 0; + this.undoCursor = 0; + this.started = false; + this._ended = false; + this._discardedBytes = 0; + } + eof() { + return this._ended && this.cursor === this.buffer.length; + } + tell() { + return this._discardedBytes + this.cursor; + } + async byte() { + if (this.eof()) + return; + if (!this.started) + await this._init(); + if (this.cursor === this.buffer.length) { + await this._loadnext(); + if (this._ended) + return; + } + this._moveCursor(1); + return this.buffer[this.undoCursor]; + } + async chunk() { + if (this.eof()) + return; + if (!this.started) + await this._init(); + if (this.cursor === this.buffer.length) { + await this._loadnext(); + if (this._ended) + return; + } + this._moveCursor(this.buffer.length); + return this.buffer.slice(this.undoCursor, this.cursor); + } + async read(n) { + if (this.eof()) + return; + if (!this.started) + await this._init(); + if (this.cursor + n > this.buffer.length) { + this._trim(); + await this._accumulate(n); + } + this._moveCursor(n); + return this.buffer.slice(this.undoCursor, this.cursor); + } + async skip(n) { + if (this.eof()) + return; + if (!this.started) + await this._init(); + if (this.cursor + n > this.buffer.length) { + this._trim(); + await this._accumulate(n); + } + this._moveCursor(n); + } + async undo() { + this.cursor = this.undoCursor; + } + async _next() { + this.started = true; + let { done, value } = await this.stream.next(); + if (done) { + this._ended = true; + } + if (value) { + value = Buffer.from(value); + } + return value; + } + _trim() { + this.buffer = this.buffer.slice(this.undoCursor); + this.cursor -= this.undoCursor; + this._discardedBytes += this.undoCursor; + this.undoCursor = 0; + } + _moveCursor(n) { + this.undoCursor = this.cursor; + this.cursor += n; + if (this.cursor > this.buffer.length) { + this.cursor = this.buffer.length; + } + } + async _accumulate(n) { + if (this._ended) + return; + const buffers = [this.buffer]; + while (this.cursor + n > lengthBuffers(buffers)) { + const nextbuffer = await this._next(); + if (this._ended) + break; + buffers.push(nextbuffer); + } + this.buffer = Buffer.concat(buffers); + } + async _loadnext() { + this._discardedBytes += this.buffer.length; + this.undoCursor = 0; + this.cursor = 0; + this.buffer = await this._next(); + } + async _init() { + this.buffer = await this._next(); + } +}; +function lengthBuffers(buffers) { + return buffers.reduce((acc, buffer2) => acc + buffer2.length, 0); +} +async function listpack(stream, onData) { + const reader = new StreamReader(stream); + let PACK = await reader.read(4); + PACK = PACK.toString("utf8"); + if (PACK !== "PACK") { + throw new InternalError(`Invalid PACK header '${PACK}'`); + } + let version2 = await reader.read(4); + version2 = version2.readUInt32BE(0); + if (version2 !== 2) { + throw new InternalError(`Invalid packfile version: ${version2}`); + } + let numObjects = await reader.read(4); + numObjects = numObjects.readUInt32BE(0); + if (numObjects < 1) + return; + while (!reader.eof() && numObjects--) { + const offset = reader.tell(); + const { type, length, ofs, reference } = await parseHeader(reader); + const inflator = new import_pako.default.Inflate(); + while (!inflator.result) { + const chunk = await reader.chunk(); + if (!chunk) + break; + inflator.push(chunk, false); + if (inflator.err) { + throw new InternalError(`Pako error: ${inflator.msg}`); + } + if (inflator.result) { + if (inflator.result.length !== length) { + throw new InternalError( + `Inflated object size is different from that stated in packfile.` + ); + } + await reader.undo(); + await reader.read(chunk.length - inflator.strm.avail_in); + const end = reader.tell(); + await onData({ + data: inflator.result, + type, + num: numObjects, + offset, + end, + reference, + ofs + }); + } + } + } +} +async function parseHeader(reader) { + let byte = await reader.byte(); + const type = byte >> 4 & 7; + let length = byte & 15; + if (byte & 128) { + let shift = 4; + do { + byte = await reader.byte(); + length |= (byte & 127) << shift; + shift += 7; + } while (byte & 128); + } + let ofs; + let reference; + if (type === 6) { + let shift = 0; + ofs = 0; + const bytes = []; + do { + byte = await reader.byte(); + ofs |= (byte & 127) << shift; + shift += 7; + bytes.push(byte); + } while (byte & 128); + reference = Buffer.from(bytes); + } + if (type === 7) { + const buf = await reader.read(20); + reference = buf; + } + return { type, length, ofs, reference }; +} +var supportsDecompressionStream = false; +async function inflate(buffer2) { + if (supportsDecompressionStream === null) { + supportsDecompressionStream = testDecompressionStream(); + } + return supportsDecompressionStream ? browserInflate(buffer2) : import_pako.default.inflate(buffer2); +} +async function browserInflate(buffer2) { + const ds = new DecompressionStream("deflate"); + const d = new Blob([buffer2]).stream().pipeThrough(ds); + return new Uint8Array(await new Response(d).arrayBuffer()); +} +function testDecompressionStream() { + try { + const ds = new DecompressionStream("deflate"); + if (ds) + return true; + } catch (_) { + } + return false; +} +function decodeVarInt(reader) { + const bytes = []; + let byte = 0; + let multibyte = 0; + do { + byte = reader.readUInt8(); + const lastSeven = byte & 127; + bytes.push(lastSeven); + multibyte = byte & 128; + } while (multibyte); + return bytes.reduce((a, b) => a + 1 << 7 | b, -1); +} +function otherVarIntDecode(reader, startWith) { + let result = startWith; + let shift = 4; + let byte = null; + do { + byte = reader.readUInt8(); + result |= (byte & 127) << shift; + shift += 7; + } while (byte & 128); + return result; +} +var GitPackIndex = class { + constructor(stuff) { + Object.assign(this, stuff); + this.offsetCache = {}; + } + static async fromIdx({ idx, getExternalRefDelta }) { + const reader = new BufferCursor(idx); + const magic = reader.slice(4).toString("hex"); + if (magic !== "ff744f63") { + return; + } + const version2 = reader.readUInt32BE(); + if (version2 !== 2) { + throw new InternalError( + `Unable to read version ${version2} packfile IDX. (Only version 2 supported)` + ); + } + if (idx.byteLength > 2048 * 1024 * 1024) { + throw new InternalError( + `To keep implementation simple, I haven't implemented the layer 5 feature needed to support packfiles > 2GB in size.` + ); + } + reader.seek(reader.tell() + 4 * 255); + const size = reader.readUInt32BE(); + const hashes = []; + for (let i = 0; i < size; i++) { + const hash2 = reader.slice(20).toString("hex"); + hashes[i] = hash2; + } + reader.seek(reader.tell() + 4 * size); + const offsets = /* @__PURE__ */ new Map(); + for (let i = 0; i < size; i++) { + offsets.set(hashes[i], reader.readUInt32BE()); + } + const packfileSha = reader.slice(20).toString("hex"); + return new GitPackIndex({ + hashes, + crcs: {}, + offsets, + packfileSha, + getExternalRefDelta + }); + } + static async fromPack({ pack, getExternalRefDelta, onProgress }) { + const listpackTypes = { + 1: "commit", + 2: "tree", + 3: "blob", + 4: "tag", + 6: "ofs-delta", + 7: "ref-delta" + }; + const offsetToObject = {}; + const packfileSha = pack.slice(-20).toString("hex"); + const hashes = []; + const crcs = {}; + const offsets = /* @__PURE__ */ new Map(); + let totalObjectCount = null; + let lastPercent = null; + await listpack([pack], async ({ data, type, reference, offset, num: num2 }) => { + if (totalObjectCount === null) + totalObjectCount = num2; + const percent = Math.floor( + (totalObjectCount - num2) * 100 / totalObjectCount + ); + if (percent !== lastPercent) { + if (onProgress) { + await onProgress({ + phase: "Receiving objects", + loaded: totalObjectCount - num2, + total: totalObjectCount + }); + } + } + lastPercent = percent; + type = listpackTypes[type]; + if (["commit", "tree", "blob", "tag"].includes(type)) { + offsetToObject[offset] = { + type, + offset + }; + } else if (type === "ofs-delta") { + offsetToObject[offset] = { + type, + offset + }; + } else if (type === "ref-delta") { + offsetToObject[offset] = { + type, + offset + }; + } + }); + const offsetArray = Object.keys(offsetToObject).map(Number); + for (const [i, start] of offsetArray.entries()) { + const end = i + 1 === offsetArray.length ? pack.byteLength - 20 : offsetArray[i + 1]; + const o = offsetToObject[start]; + const crc = import_crc_32.default.buf(pack.slice(start, end)) >>> 0; + o.end = end; + o.crc = crc; + } + const p = new GitPackIndex({ + pack: Promise.resolve(pack), + packfileSha, + crcs, + hashes, + offsets, + getExternalRefDelta + }); + lastPercent = null; + let count = 0; + const objectsByDepth = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (let offset in offsetToObject) { + offset = Number(offset); + const percent = Math.floor(count * 100 / totalObjectCount); + if (percent !== lastPercent) { + if (onProgress) { + await onProgress({ + phase: "Resolving deltas", + loaded: count, + total: totalObjectCount + }); + } + } + count++; + lastPercent = percent; + const o = offsetToObject[offset]; + if (o.oid) + continue; + try { + p.readDepth = 0; + p.externalReadDepth = 0; + const { type, object } = await p.readSlice({ start: offset }); + objectsByDepth[p.readDepth] += 1; + const oid = await shasum(GitObject.wrap({ type, object })); + o.oid = oid; + hashes.push(oid); + offsets.set(oid, offset); + crcs[oid] = o.crc; + } catch (err) { + continue; + } + } + hashes.sort(); + return p; + } + async toBuffer() { + const buffers = []; + const write = (str, encoding) => { + buffers.push(Buffer.from(str, encoding)); + }; + write("ff744f63", "hex"); + write("00000002", "hex"); + const fanoutBuffer = new BufferCursor(Buffer.alloc(256 * 4)); + for (let i = 0; i < 256; i++) { + let count = 0; + for (const hash2 of this.hashes) { + if (parseInt(hash2.slice(0, 2), 16) <= i) + count++; + } + fanoutBuffer.writeUInt32BE(count); + } + buffers.push(fanoutBuffer.buffer); + for (const hash2 of this.hashes) { + write(hash2, "hex"); + } + const crcsBuffer = new BufferCursor(Buffer.alloc(this.hashes.length * 4)); + for (const hash2 of this.hashes) { + crcsBuffer.writeUInt32BE(this.crcs[hash2]); + } + buffers.push(crcsBuffer.buffer); + const offsetsBuffer = new BufferCursor(Buffer.alloc(this.hashes.length * 4)); + for (const hash2 of this.hashes) { + offsetsBuffer.writeUInt32BE(this.offsets.get(hash2)); + } + buffers.push(offsetsBuffer.buffer); + write(this.packfileSha, "hex"); + const totalBuffer = Buffer.concat(buffers); + const sha = await shasum(totalBuffer); + const shaBuffer = Buffer.alloc(20); + shaBuffer.write(sha, "hex"); + return Buffer.concat([totalBuffer, shaBuffer]); + } + async load({ pack }) { + this.pack = pack; + } + async unload() { + this.pack = null; + } + async read({ oid }) { + if (!this.offsets.get(oid)) { + if (this.getExternalRefDelta) { + this.externalReadDepth++; + return this.getExternalRefDelta(oid); + } else { + throw new InternalError(`Could not read object ${oid} from packfile`); + } + } + const start = this.offsets.get(oid); + return this.readSlice({ start }); + } + async readSlice({ start }) { + if (this.offsetCache[start]) { + return Object.assign({}, this.offsetCache[start]); + } + this.readDepth++; + const types2 = { + 16: "commit", + 32: "tree", + 48: "blob", + 64: "tag", + 96: "ofs_delta", + 112: "ref_delta" + }; + if (!this.pack) { + throw new InternalError( + "Tried to read from a GitPackIndex with no packfile loaded into memory" + ); + } + const raw = (await this.pack).slice(start); + const reader = new BufferCursor(raw); + const byte = reader.readUInt8(); + const btype = byte & 112; + let type = types2[btype]; + if (type === void 0) { + throw new InternalError("Unrecognized type: 0b" + btype.toString(2)); + } + const lastFour = byte & 15; + let length = lastFour; + const multibyte = byte & 128; + if (multibyte) { + length = otherVarIntDecode(reader, lastFour); + } + let base = null; + let object = null; + if (type === "ofs_delta") { + const offset = decodeVarInt(reader); + const baseOffset = start - offset; + ({ object: base, type } = await this.readSlice({ start: baseOffset })); + } + if (type === "ref_delta") { + const oid = reader.slice(20).toString("hex"); + ({ object: base, type } = await this.read({ oid })); + } + const buffer2 = raw.slice(reader.tell()); + object = Buffer.from(await inflate(buffer2)); + if (object.byteLength !== length) { + throw new InternalError( + `Packfile told us object would have length ${length} but it had length ${object.byteLength}` + ); + } + if (base) { + object = Buffer.from(applyDelta(object, base)); + } + if (this.readDepth > 3) { + this.offsetCache[start] = { type, object }; + } + return { type, format: "content", object }; + } +}; +var PackfileCache = Symbol("PackfileCache"); +async function loadPackIndex({ + fs, + filename, + getExternalRefDelta, + emitter, + emitterPrefix +}) { + const idx = await fs.read(filename); + return GitPackIndex.fromIdx({ idx, getExternalRefDelta }); +} +function readPackIndex({ + fs, + cache, + filename, + getExternalRefDelta, + emitter, + emitterPrefix +}) { + if (!cache[PackfileCache]) + cache[PackfileCache] = /* @__PURE__ */ new Map(); + let p = cache[PackfileCache].get(filename); + if (!p) { + p = loadPackIndex({ + fs, + filename, + getExternalRefDelta, + emitter, + emitterPrefix + }); + cache[PackfileCache].set(filename, p); + } + return p; +} +async function readObjectPacked({ + fs, + cache, + gitdir, + oid, + format = "content", + getExternalRefDelta +}) { + let list = await fs.readdir(join(gitdir, "objects/pack")); + list = list.filter((x) => x.endsWith(".idx")); + for (const filename of list) { + const indexFile = `${gitdir}/objects/pack/${filename}`; + const p = await readPackIndex({ + fs, + cache, + filename: indexFile, + getExternalRefDelta + }); + if (p.error) + throw new InternalError(p.error); + if (p.offsets.has(oid)) { + if (!p.pack) { + const packFile = indexFile.replace(/idx$/, "pack"); + p.pack = fs.read(packFile); + } + const result = await p.read({ oid, getExternalRefDelta }); + result.format = "content"; + result.source = `objects/pack/${filename.replace(/idx$/, "pack")}`; + return result; + } + } + return null; +} +async function _readObject({ + fs, + cache, + gitdir, + oid, + format = "content" +}) { + const getExternalRefDelta = (oid2) => _readObject({ fs, cache, gitdir, oid: oid2 }); + let result; + if (oid === "4b825dc642cb6eb9a060e54bf8d69288fbee4904") { + result = { format: "wrapped", object: Buffer.from(`tree 0\0`) }; + } + if (!result) { + result = await readObjectLoose({ fs, gitdir, oid }); + } + if (!result) { + result = await readObjectPacked({ + fs, + cache, + gitdir, + oid, + getExternalRefDelta + }); + } + if (!result) { + throw new NotFoundError(oid); + } + if (format === "deflated") { + return result; + } + if (result.format === "deflated") { + result.object = Buffer.from(await inflate(result.object)); + result.format = "wrapped"; + } + if (result.format === "wrapped") { + if (format === "wrapped" && result.format === "wrapped") { + return result; + } + const sha = await shasum(result.object); + if (sha !== oid) { + throw new InternalError( + `SHA check failed! Expected ${oid}, computed ${sha}` + ); + } + const { object, type } = GitObject.unwrap(result.object); + result.type = type; + result.object = object; + result.format = "content"; + } + if (result.format === "content") { + if (format === "content") + return result; + return; + } + throw new InternalError(`invalid format "${result.format}"`); +} +var AlreadyExistsError = class extends BaseError { + /** + * @param {'note'|'remote'|'tag'|'branch'} noun + * @param {string} where + * @param {boolean} canForce + */ + constructor(noun, where, canForce = true) { + super( + `Failed to create ${noun} at ${where} because it already exists.${canForce ? ` (Hint: use 'force: true' parameter to overwrite existing ${noun}.)` : ""}` + ); + this.code = this.name = AlreadyExistsError.code; + this.data = { noun, where, canForce }; + } +}; +AlreadyExistsError.code = "AlreadyExistsError"; +var AmbiguousError = class extends BaseError { + /** + * @param {'oids'|'refs'} nouns + * @param {string} short + * @param {string[]} matches + */ + constructor(nouns, short, matches) { + super( + `Found multiple ${nouns} matching "${short}" (${matches.join( + ", " + )}). Use a longer abbreviation length to disambiguate them.` + ); + this.code = this.name = AmbiguousError.code; + this.data = { nouns, short, matches }; + } +}; +AmbiguousError.code = "AmbiguousError"; +var CheckoutConflictError = class extends BaseError { + /** + * @param {string[]} filepaths + */ + constructor(filepaths) { + super( + `Your local changes to the following files would be overwritten by checkout: ${filepaths.join( + ", " + )}` + ); + this.code = this.name = CheckoutConflictError.code; + this.data = { filepaths }; + } +}; +CheckoutConflictError.code = "CheckoutConflictError"; +var CommitNotFetchedError = class extends BaseError { + /** + * @param {string} ref + * @param {string} oid + */ + constructor(ref, oid) { + super( + `Failed to checkout "${ref}" because commit ${oid} is not available locally. Do a git fetch to make the branch available locally.` + ); + this.code = this.name = CommitNotFetchedError.code; + this.data = { ref, oid }; + } +}; +CommitNotFetchedError.code = "CommitNotFetchedError"; +var EmptyServerResponseError = class extends BaseError { + constructor() { + super(`Empty response from git server.`); + this.code = this.name = EmptyServerResponseError.code; + this.data = {}; + } +}; +EmptyServerResponseError.code = "EmptyServerResponseError"; +var FastForwardError = class extends BaseError { + constructor() { + super(`A simple fast-forward merge was not possible.`); + this.code = this.name = FastForwardError.code; + this.data = {}; + } +}; +FastForwardError.code = "FastForwardError"; +var GitPushError = class extends BaseError { + /** + * @param {string} prettyDetails + * @param {PushResult} result + */ + constructor(prettyDetails, result) { + super(`One or more branches were not updated: ${prettyDetails}`); + this.code = this.name = GitPushError.code; + this.data = { prettyDetails, result }; + } +}; +GitPushError.code = "GitPushError"; +var HttpError = class extends BaseError { + /** + * @param {number} statusCode + * @param {string} statusMessage + * @param {string} response + */ + constructor(statusCode, statusMessage, response) { + super(`HTTP Error: ${statusCode} ${statusMessage}`); + this.code = this.name = HttpError.code; + this.data = { statusCode, statusMessage, response }; + } +}; +HttpError.code = "HttpError"; +var InvalidFilepathError = class extends BaseError { + /** + * @param {'leading-slash'|'trailing-slash'|'directory'} [reason] + */ + constructor(reason) { + let message = "invalid filepath"; + if (reason === "leading-slash" || reason === "trailing-slash") { + message = `"filepath" parameter should not include leading or trailing directory separators because these can cause problems on some platforms.`; + } else if (reason === "directory") { + message = `"filepath" should not be a directory.`; + } + super(message); + this.code = this.name = InvalidFilepathError.code; + this.data = { reason }; + } +}; +InvalidFilepathError.code = "InvalidFilepathError"; +var InvalidRefNameError = class extends BaseError { + /** + * @param {string} ref + * @param {string} suggestion + * @param {boolean} canForce + */ + constructor(ref, suggestion) { + super( + `"${ref}" would be an invalid git reference. (Hint: a valid alternative would be "${suggestion}".)` + ); + this.code = this.name = InvalidRefNameError.code; + this.data = { ref, suggestion }; + } +}; +InvalidRefNameError.code = "InvalidRefNameError"; +var MaxDepthError = class extends BaseError { + /** + * @param {number} depth + */ + constructor(depth) { + super(`Maximum search depth of ${depth} exceeded.`); + this.code = this.name = MaxDepthError.code; + this.data = { depth }; + } +}; +MaxDepthError.code = "MaxDepthError"; +var MergeNotSupportedError = class extends BaseError { + constructor() { + super(`Merges with conflicts are not supported yet.`); + this.code = this.name = MergeNotSupportedError.code; + this.data = {}; + } +}; +MergeNotSupportedError.code = "MergeNotSupportedError"; +var MergeConflictError = class extends BaseError { + /** + * @param {Array} filepaths + */ + constructor(filepaths) { + super( + `Automatic merge failed with one or more merge conflicts in the following files: ${filepaths.toString()}. Fix conflicts then commit the result.` + ); + this.code = this.name = MergeConflictError.code; + this.data = { filepaths }; + } +}; +MergeConflictError.code = "MergeConflictError"; +var MissingNameError = class extends BaseError { + /** + * @param {'author'|'committer'|'tagger'} role + */ + constructor(role) { + super( + `No name was provided for ${role} in the argument or in the .git/config file.` + ); + this.code = this.name = MissingNameError.code; + this.data = { role }; + } +}; +MissingNameError.code = "MissingNameError"; +var MissingParameterError = class extends BaseError { + /** + * @param {string} parameter + */ + constructor(parameter) { + super( + `The function requires a "${parameter}" parameter but none was provided.` + ); + this.code = this.name = MissingParameterError.code; + this.data = { parameter }; + } +}; +MissingParameterError.code = "MissingParameterError"; +var MultipleGitError = class extends BaseError { + /** + * @param {Error[]} errors + * @param {string} message + */ + constructor(errors) { + super( + `There are multiple errors that were thrown by the method. Please refer to the "errors" property to see more` + ); + this.code = this.name = MultipleGitError.code; + this.data = { errors }; + this.errors = errors; + } +}; +MultipleGitError.code = "MultipleGitError"; +var ParseError = class extends BaseError { + /** + * @param {string} expected + * @param {string} actual + */ + constructor(expected, actual) { + super(`Expected "${expected}" but received "${actual}".`); + this.code = this.name = ParseError.code; + this.data = { expected, actual }; + } +}; +ParseError.code = "ParseError"; +var PushRejectedError = class extends BaseError { + /** + * @param {'not-fast-forward'|'tag-exists'} reason + */ + constructor(reason) { + let message = ""; + if (reason === "not-fast-forward") { + message = " because it was not a simple fast-forward"; + } else if (reason === "tag-exists") { + message = " because tag already exists"; + } + super(`Push rejected${message}. Use "force: true" to override.`); + this.code = this.name = PushRejectedError.code; + this.data = { reason }; + } +}; +PushRejectedError.code = "PushRejectedError"; +var RemoteCapabilityError = class extends BaseError { + /** + * @param {'shallow'|'deepen-since'|'deepen-not'|'deepen-relative'} capability + * @param {'depth'|'since'|'exclude'|'relative'} parameter + */ + constructor(capability, parameter) { + super( + `Remote does not support the "${capability}" so the "${parameter}" parameter cannot be used.` + ); + this.code = this.name = RemoteCapabilityError.code; + this.data = { capability, parameter }; + } +}; +RemoteCapabilityError.code = "RemoteCapabilityError"; +var SmartHttpError = class extends BaseError { + /** + * @param {string} preview + * @param {string} response + */ + constructor(preview, response) { + super( + `Remote did not reply using the "smart" HTTP protocol. Expected "001e# service=git-upload-pack" but received: ${preview}` + ); + this.code = this.name = SmartHttpError.code; + this.data = { preview, response }; + } +}; +SmartHttpError.code = "SmartHttpError"; +var UnknownTransportError = class extends BaseError { + /** + * @param {string} url + * @param {string} transport + * @param {string} [suggestion] + */ + constructor(url, transport, suggestion) { + super( + `Git remote "${url}" uses an unrecognized transport protocol: "${transport}"` + ); + this.code = this.name = UnknownTransportError.code; + this.data = { url, transport, suggestion }; + } +}; +UnknownTransportError.code = "UnknownTransportError"; +var UrlParseError = class extends BaseError { + /** + * @param {string} url + */ + constructor(url) { + super(`Cannot parse remote URL: "${url}"`); + this.code = this.name = UrlParseError.code; + this.data = { url }; + } +}; +UrlParseError.code = "UrlParseError"; +var UserCanceledError = class extends BaseError { + constructor() { + super(`The operation was canceled.`); + this.code = this.name = UserCanceledError.code; + this.data = {}; + } +}; +UserCanceledError.code = "UserCanceledError"; +var IndexResetError = class extends BaseError { + /** + * @param {Array} filepaths + */ + constructor(filepath) { + super( + `Could not merge index: Entry for '${filepath}' is not up to date. Either reset the index entry to HEAD, or stage your unstaged chages.` + ); + this.code = this.name = IndexResetError.code; + this.data = { filepath }; + } +}; +IndexResetError.code = "IndexResetError"; +var Errors = /* @__PURE__ */ Object.freeze({ + __proto__: null, + AlreadyExistsError, + AmbiguousError, + CheckoutConflictError, + CommitNotFetchedError, + EmptyServerResponseError, + FastForwardError, + GitPushError, + HttpError, + InternalError, + InvalidFilepathError, + InvalidOidError, + InvalidRefNameError, + MaxDepthError, + MergeNotSupportedError, + MergeConflictError, + MissingNameError, + MissingParameterError, + MultipleGitError, + NoRefspecError, + NotFoundError, + ObjectTypeError, + ParseError, + PushRejectedError, + RemoteCapabilityError, + SmartHttpError, + UnknownTransportError, + UnsafeFilepathError, + UrlParseError, + UserCanceledError, + UnmergedPathsError, + IndexResetError +}); +function formatAuthor({ name, email, timestamp, timezoneOffset }) { + timezoneOffset = formatTimezoneOffset(timezoneOffset); + return `${name} <${email}> ${timestamp} ${timezoneOffset}`; +} +function formatTimezoneOffset(minutes) { + const sign = simpleSign(negateExceptForZero(minutes)); + minutes = Math.abs(minutes); + const hours = Math.floor(minutes / 60); + minutes -= hours * 60; + let strHours = String(hours); + let strMinutes = String(minutes); + if (strHours.length < 2) + strHours = "0" + strHours; + if (strMinutes.length < 2) + strMinutes = "0" + strMinutes; + return (sign === -1 ? "-" : "+") + strHours + strMinutes; +} +function simpleSign(n) { + return Math.sign(n) || (Object.is(n, -0) ? -1 : 1); +} +function negateExceptForZero(n) { + return n === 0 ? n : -n; +} +function normalizeNewlines(str) { + str = str.replace(/\r/g, ""); + str = str.replace(/^\n+/, ""); + str = str.replace(/\n+$/, "") + "\n"; + return str; +} +function parseAuthor(author) { + const [, name, email, timestamp, offset] = author.match( + /^(.*) <(.*)> (.*) (.*)$/ + ); + return { + name, + email, + timestamp: Number(timestamp), + timezoneOffset: parseTimezoneOffset(offset) + }; +} +function parseTimezoneOffset(offset) { + let [, sign, hours, minutes] = offset.match(/(\+|-)(\d\d)(\d\d)/); + minutes = (sign === "+" ? 1 : -1) * (Number(hours) * 60 + Number(minutes)); + return negateExceptForZero$1(minutes); +} +function negateExceptForZero$1(n) { + return n === 0 ? n : -n; +} +var GitAnnotatedTag = class { + constructor(tag2) { + if (typeof tag2 === "string") { + this._tag = tag2; + } else if (Buffer.isBuffer(tag2)) { + this._tag = tag2.toString("utf8"); + } else if (typeof tag2 === "object") { + this._tag = GitAnnotatedTag.render(tag2); + } else { + throw new InternalError( + "invalid type passed to GitAnnotatedTag constructor" + ); + } + } + static from(tag2) { + return new GitAnnotatedTag(tag2); + } + static render(obj) { + return `object ${obj.object} +type ${obj.type} +tag ${obj.tag} +tagger ${formatAuthor(obj.tagger)} + +${obj.message} +${obj.gpgsig ? obj.gpgsig : ""}`; + } + justHeaders() { + return this._tag.slice(0, this._tag.indexOf("\n\n")); + } + message() { + const tag2 = this.withoutSignature(); + return tag2.slice(tag2.indexOf("\n\n") + 2); + } + parse() { + return Object.assign(this.headers(), { + message: this.message(), + gpgsig: this.gpgsig() + }); + } + render() { + return this._tag; + } + headers() { + const headers = this.justHeaders().split("\n"); + const hs = []; + for (const h of headers) { + if (h[0] === " ") { + hs[hs.length - 1] += "\n" + h.slice(1); + } else { + hs.push(h); + } + } + const obj = {}; + for (const h of hs) { + const key2 = h.slice(0, h.indexOf(" ")); + const value = h.slice(h.indexOf(" ") + 1); + if (Array.isArray(obj[key2])) { + obj[key2].push(value); + } else { + obj[key2] = value; + } + } + if (obj.tagger) { + obj.tagger = parseAuthor(obj.tagger); + } + if (obj.committer) { + obj.committer = parseAuthor(obj.committer); + } + return obj; + } + withoutSignature() { + const tag2 = normalizeNewlines(this._tag); + if (tag2.indexOf("\n-----BEGIN PGP SIGNATURE-----") === -1) + return tag2; + return tag2.slice(0, tag2.lastIndexOf("\n-----BEGIN PGP SIGNATURE-----")); + } + gpgsig() { + if (this._tag.indexOf("\n-----BEGIN PGP SIGNATURE-----") === -1) + return; + const signature = this._tag.slice( + this._tag.indexOf("-----BEGIN PGP SIGNATURE-----"), + this._tag.indexOf("-----END PGP SIGNATURE-----") + "-----END PGP SIGNATURE-----".length + ); + return normalizeNewlines(signature); + } + payload() { + return this.withoutSignature() + "\n"; + } + toObject() { + return Buffer.from(this._tag, "utf8"); + } + static async sign(tag2, sign, secretKey) { + const payload = tag2.payload(); + let { signature } = await sign({ payload, secretKey }); + signature = normalizeNewlines(signature); + const signedTag = payload + signature; + return GitAnnotatedTag.from(signedTag); + } +}; +function indent(str) { + return str.trim().split("\n").map((x) => " " + x).join("\n") + "\n"; +} +function outdent(str) { + return str.split("\n").map((x) => x.replace(/^ /, "")).join("\n"); +} +var GitCommit = class { + constructor(commit2) { + if (typeof commit2 === "string") { + this._commit = commit2; + } else if (Buffer.isBuffer(commit2)) { + this._commit = commit2.toString("utf8"); + } else if (typeof commit2 === "object") { + this._commit = GitCommit.render(commit2); + } else { + throw new InternalError("invalid type passed to GitCommit constructor"); + } + } + static fromPayloadSignature({ payload, signature }) { + const headers = GitCommit.justHeaders(payload); + const message = GitCommit.justMessage(payload); + const commit2 = normalizeNewlines( + headers + "\ngpgsig" + indent(signature) + "\n" + message + ); + return new GitCommit(commit2); + } + static from(commit2) { + return new GitCommit(commit2); + } + toObject() { + return Buffer.from(this._commit, "utf8"); + } + // Todo: allow setting the headers and message + headers() { + return this.parseHeaders(); + } + // Todo: allow setting the headers and message + message() { + return GitCommit.justMessage(this._commit); + } + parse() { + return Object.assign({ message: this.message() }, this.headers()); + } + static justMessage(commit2) { + return normalizeNewlines(commit2.slice(commit2.indexOf("\n\n") + 2)); + } + static justHeaders(commit2) { + return commit2.slice(0, commit2.indexOf("\n\n")); + } + parseHeaders() { + const headers = GitCommit.justHeaders(this._commit).split("\n"); + const hs = []; + for (const h of headers) { + if (h[0] === " ") { + hs[hs.length - 1] += "\n" + h.slice(1); + } else { + hs.push(h); + } + } + const obj = { + parent: [] + }; + for (const h of hs) { + const key2 = h.slice(0, h.indexOf(" ")); + const value = h.slice(h.indexOf(" ") + 1); + if (Array.isArray(obj[key2])) { + obj[key2].push(value); + } else { + obj[key2] = value; + } + } + if (obj.author) { + obj.author = parseAuthor(obj.author); + } + if (obj.committer) { + obj.committer = parseAuthor(obj.committer); + } + return obj; + } + static renderHeaders(obj) { + let headers = ""; + if (obj.tree) { + headers += `tree ${obj.tree} +`; + } else { + headers += `tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 +`; + } + if (obj.parent) { + if (obj.parent.length === void 0) { + throw new InternalError(`commit 'parent' property should be an array`); + } + for (const p of obj.parent) { + headers += `parent ${p} +`; + } + } + const author = obj.author; + headers += `author ${formatAuthor(author)} +`; + const committer = obj.committer || obj.author; + headers += `committer ${formatAuthor(committer)} +`; + if (obj.gpgsig) { + headers += "gpgsig" + indent(obj.gpgsig); + } + return headers; + } + static render(obj) { + return GitCommit.renderHeaders(obj) + "\n" + normalizeNewlines(obj.message); + } + render() { + return this._commit; + } + withoutSignature() { + const commit2 = normalizeNewlines(this._commit); + if (commit2.indexOf("\ngpgsig") === -1) + return commit2; + const headers = commit2.slice(0, commit2.indexOf("\ngpgsig")); + const message = commit2.slice( + commit2.indexOf("-----END PGP SIGNATURE-----\n") + "-----END PGP SIGNATURE-----\n".length + ); + return normalizeNewlines(headers + "\n" + message); + } + isolateSignature() { + const signature = this._commit.slice( + this._commit.indexOf("-----BEGIN PGP SIGNATURE-----"), + this._commit.indexOf("-----END PGP SIGNATURE-----") + "-----END PGP SIGNATURE-----".length + ); + return outdent(signature); + } + static async sign(commit2, sign, secretKey) { + const payload = commit2.withoutSignature(); + const message = GitCommit.justMessage(commit2._commit); + let { signature } = await sign({ payload, secretKey }); + signature = normalizeNewlines(signature); + const headers = GitCommit.justHeaders(commit2._commit); + const signedCommit = headers + "\ngpgsig" + indent(signature) + "\n" + message; + return GitCommit.from(signedCommit); + } +}; +async function resolveTree({ fs, cache, gitdir, oid }) { + if (oid === "4b825dc642cb6eb9a060e54bf8d69288fbee4904") { + return { tree: GitTree.from([]), oid }; + } + const { type, object } = await _readObject({ fs, cache, gitdir, oid }); + if (type === "tag") { + oid = GitAnnotatedTag.from(object).parse().object; + return resolveTree({ fs, cache, gitdir, oid }); + } + if (type === "commit") { + oid = GitCommit.from(object).parse().tree; + return resolveTree({ fs, cache, gitdir, oid }); + } + if (type !== "tree") { + throw new ObjectTypeError(oid, type, "tree"); + } + return { tree: GitTree.from(object), oid }; +} +var GitWalkerRepo = class { + constructor({ fs, gitdir, ref, cache }) { + this.fs = fs; + this.cache = cache; + this.gitdir = gitdir; + this.mapPromise = (async () => { + const map = /* @__PURE__ */ new Map(); + let oid; + try { + oid = await GitRefManager.resolve({ fs, gitdir, ref }); + } catch (e) { + if (e instanceof NotFoundError) { + oid = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"; + } + } + const tree = await resolveTree({ fs, cache: this.cache, gitdir, oid }); + tree.type = "tree"; + tree.mode = "40000"; + map.set(".", tree); + return map; + })(); + const walker = this; + this.ConstructEntry = class TreeEntry { + constructor(fullpath) { + this._fullpath = fullpath; + this._type = false; + this._mode = false; + this._stat = false; + this._content = false; + this._oid = false; + } + async type() { + return walker.type(this); + } + async mode() { + return walker.mode(this); + } + async stat() { + return walker.stat(this); + } + async content() { + return walker.content(this); + } + async oid() { + return walker.oid(this); + } + }; + } + async readdir(entry) { + const filepath = entry._fullpath; + const { fs, cache, gitdir } = this; + const map = await this.mapPromise; + const obj = map.get(filepath); + if (!obj) + throw new Error(`No obj for ${filepath}`); + const oid = obj.oid; + if (!oid) + throw new Error(`No oid for obj ${JSON.stringify(obj)}`); + if (obj.type !== "tree") { + return null; + } + const { type, object } = await _readObject({ fs, cache, gitdir, oid }); + if (type !== obj.type) { + throw new ObjectTypeError(oid, type, obj.type); + } + const tree = GitTree.from(object); + for (const entry2 of tree) { + map.set(join(filepath, entry2.path), entry2); + } + return tree.entries().map((entry2) => join(filepath, entry2.path)); + } + async type(entry) { + if (entry._type === false) { + const map = await this.mapPromise; + const { type } = map.get(entry._fullpath); + entry._type = type; + } + return entry._type; + } + async mode(entry) { + if (entry._mode === false) { + const map = await this.mapPromise; + const { mode } = map.get(entry._fullpath); + entry._mode = normalizeMode(parseInt(mode, 8)); + } + return entry._mode; + } + async stat(_entry) { + } + async content(entry) { + if (entry._content === false) { + const map = await this.mapPromise; + const { fs, cache, gitdir } = this; + const obj = map.get(entry._fullpath); + const oid = obj.oid; + const { type, object } = await _readObject({ fs, cache, gitdir, oid }); + if (type !== "blob") { + entry._content = void 0; + } else { + entry._content = new Uint8Array(object); + } + } + return entry._content; + } + async oid(entry) { + if (entry._oid === false) { + const map = await this.mapPromise; + const obj = map.get(entry._fullpath); + entry._oid = obj.oid; + } + return entry._oid; + } +}; +function TREE({ ref = "HEAD" } = {}) { + const o = /* @__PURE__ */ Object.create(null); + Object.defineProperty(o, GitWalkSymbol, { + value: function({ fs, gitdir, cache }) { + return new GitWalkerRepo({ fs, gitdir, ref, cache }); + } + }); + Object.freeze(o); + return o; +} +var GitWalkerFs = class { + constructor({ fs, dir, gitdir, cache }) { + this.fs = fs; + this.cache = cache; + this.dir = dir; + this.gitdir = gitdir; + const walker = this; + this.ConstructEntry = class WorkdirEntry { + constructor(fullpath) { + this._fullpath = fullpath; + this._type = false; + this._mode = false; + this._stat = false; + this._content = false; + this._oid = false; + } + async type() { + return walker.type(this); + } + async mode() { + return walker.mode(this); + } + async stat() { + return walker.stat(this); + } + async content() { + return walker.content(this); + } + async oid() { + return walker.oid(this); + } + }; + } + async readdir(entry) { + const filepath = entry._fullpath; + const { fs, dir } = this; + const names = await fs.readdir(join(dir, filepath)); + if (names === null) + return null; + return names.map((name) => join(filepath, name)); + } + async type(entry) { + if (entry._type === false) { + await entry.stat(); + } + return entry._type; + } + async mode(entry) { + if (entry._mode === false) { + await entry.stat(); + } + return entry._mode; + } + async stat(entry) { + if (entry._stat === false) { + const { fs, dir } = this; + let stat = await fs.lstat(`${dir}/${entry._fullpath}`); + if (!stat) { + throw new Error( + `ENOENT: no such file or directory, lstat '${entry._fullpath}'` + ); + } + let type = stat.isDirectory() ? "tree" : "blob"; + if (type === "blob" && !stat.isFile() && !stat.isSymbolicLink()) { + type = "special"; + } + entry._type = type; + stat = normalizeStats(stat); + entry._mode = stat.mode; + if (stat.size === -1 && entry._actualSize) { + stat.size = entry._actualSize; + } + entry._stat = stat; + } + return entry._stat; + } + async content(entry) { + if (entry._content === false) { + const { fs, dir } = this; + if (await entry.type() === "tree") { + entry._content = void 0; + } else { + const content = await fs.read(`${dir}/${entry._fullpath}`); + entry._actualSize = content.length; + if (entry._stat && entry._stat.size === -1) { + entry._stat.size = entry._actualSize; + } + entry._content = new Uint8Array(content); + } + } + return entry._content; + } + async oid(entry) { + if (entry._oid === false) { + const { fs, gitdir, cache } = this; + let oid; + await GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + const stage = index2.entriesMap.get(entry._fullpath); + const stats = await entry.stat(); + if (!stage || compareStats(stats, stage)) { + const content = await entry.content(); + if (content === void 0) { + oid = void 0; + } else { + oid = await shasum( + GitObject.wrap({ type: "blob", object: await entry.content() }) + ); + if (stage && oid === stage.oid && stats.mode === stage.mode && compareStats(stats, stage)) { + index2.insert({ + filepath: entry._fullpath, + stats, + oid + }); + } + } + } else { + oid = stage.oid; + } + }); + entry._oid = oid; + } + return entry._oid; + } +}; +function WORKDIR() { + const o = /* @__PURE__ */ Object.create(null); + Object.defineProperty(o, GitWalkSymbol, { + value: function({ fs, dir, gitdir, cache }) { + return new GitWalkerFs({ fs, dir, gitdir, cache }); + } + }); + Object.freeze(o); + return o; +} +function arrayRange(start, end) { + const length = end - start; + return Array.from({ length }, (_, i) => start + i); +} +var flat = typeof Array.prototype.flat === "undefined" ? (entries) => entries.reduce((acc, x) => acc.concat(x), []) : (entries) => entries.flat(); +var RunningMinimum = class { + constructor() { + this.value = null; + } + consider(value) { + if (value === null || value === void 0) + return; + if (this.value === null) { + this.value = value; + } else if (value < this.value) { + this.value = value; + } + } + reset() { + this.value = null; + } +}; +function* unionOfIterators(sets) { + const min = new RunningMinimum(); + let minimum; + const heads = []; + const numsets = sets.length; + for (let i = 0; i < numsets; i++) { + heads[i] = sets[i].next().value; + if (heads[i] !== void 0) { + min.consider(heads[i]); + } + } + if (min.value === null) + return; + while (true) { + const result = []; + minimum = min.value; + min.reset(); + for (let i = 0; i < numsets; i++) { + if (heads[i] !== void 0 && heads[i] === minimum) { + result[i] = heads[i]; + heads[i] = sets[i].next().value; + } else { + result[i] = null; + } + if (heads[i] !== void 0) { + min.consider(heads[i]); + } + } + yield result; + if (min.value === null) + return; + } +} +async function _walk({ + fs, + cache, + dir, + gitdir, + trees, + // @ts-ignore + map = async (_, entry) => entry, + // The default reducer is a flatmap that filters out undefineds. + reduce = async (parent, children2) => { + const flatten = flat(children2); + if (parent !== void 0) + flatten.unshift(parent); + return flatten; + }, + // The default iterate function walks all children concurrently + iterate = (walk2, children2) => Promise.all([...children2].map(walk2)) +}) { + const walkers = trees.map( + (proxy) => proxy[GitWalkSymbol]({ fs, dir, gitdir, cache }) + ); + const root2 = new Array(walkers.length).fill("."); + const range = arrayRange(0, walkers.length); + const unionWalkerFromReaddir = async (entries) => { + range.map((i) => { + entries[i] = entries[i] && new walkers[i].ConstructEntry(entries[i]); + }); + const subdirs = await Promise.all( + range.map((i) => entries[i] ? walkers[i].readdir(entries[i]) : []) + ); + const iterators = subdirs.map((array) => array === null ? [] : array).map((array) => array[Symbol.iterator]()); + return { + entries, + children: unionOfIterators(iterators) + }; + }; + const walk2 = async (root3) => { + const { entries, children: children2 } = await unionWalkerFromReaddir(root3); + const fullpath = entries.find((entry) => entry && entry._fullpath)._fullpath; + const parent = await map(fullpath, entries); + if (parent !== null) { + let walkedChildren = await iterate(walk2, children2); + walkedChildren = walkedChildren.filter((x) => x !== void 0); + return reduce(parent, walkedChildren); + } + }; + return walk2(root2); +} +async function rmRecursive(fs, filepath) { + const entries = await fs.readdir(filepath); + if (entries == null) { + await fs.rm(filepath); + } else if (entries.length) { + await Promise.all( + entries.map((entry) => { + const subpath = join(filepath, entry); + return fs.lstat(subpath).then((stat) => { + if (!stat) + return; + return stat.isDirectory() ? rmRecursive(fs, subpath) : fs.rm(subpath); + }); + }) + ).then(() => fs.rmdir(filepath)); + } else { + await fs.rmdir(filepath); + } +} +var FileSystem = class { + constructor(fs) { + if (typeof fs._original_unwrapped_fs !== "undefined") + return fs; + const promises = Object.getOwnPropertyDescriptor(fs, "promises"); + if (promises && promises.enumerable) { + this._readFile = fs.promises.readFile.bind(fs.promises); + this._writeFile = fs.promises.writeFile.bind(fs.promises); + this._mkdir = fs.promises.mkdir.bind(fs.promises); + if (fs.promises.rm) { + this._rm = fs.promises.rm.bind(fs.promises); + } else if (fs.promises.rmdir.length > 1) { + this._rm = fs.promises.rmdir.bind(fs.promises); + } else { + this._rm = rmRecursive.bind(null, this); + } + this._rmdir = fs.promises.rmdir.bind(fs.promises); + this._unlink = fs.promises.unlink.bind(fs.promises); + this._stat = fs.promises.stat.bind(fs.promises); + this._lstat = fs.promises.lstat.bind(fs.promises); + this._readdir = fs.promises.readdir.bind(fs.promises); + this._readlink = fs.promises.readlink.bind(fs.promises); + this._symlink = fs.promises.symlink.bind(fs.promises); + } else { + this._readFile = (0, import_pify.default)(fs.readFile.bind(fs)); + this._writeFile = (0, import_pify.default)(fs.writeFile.bind(fs)); + this._mkdir = (0, import_pify.default)(fs.mkdir.bind(fs)); + if (fs.rm) { + this._rm = (0, import_pify.default)(fs.rm.bind(fs)); + } else if (fs.rmdir.length > 2) { + this._rm = (0, import_pify.default)(fs.rmdir.bind(fs)); + } else { + this._rm = rmRecursive.bind(null, this); + } + this._rmdir = (0, import_pify.default)(fs.rmdir.bind(fs)); + this._unlink = (0, import_pify.default)(fs.unlink.bind(fs)); + this._stat = (0, import_pify.default)(fs.stat.bind(fs)); + this._lstat = (0, import_pify.default)(fs.lstat.bind(fs)); + this._readdir = (0, import_pify.default)(fs.readdir.bind(fs)); + this._readlink = (0, import_pify.default)(fs.readlink.bind(fs)); + this._symlink = (0, import_pify.default)(fs.symlink.bind(fs)); + } + this._original_unwrapped_fs = fs; + } + /** + * Return true if a file exists, false if it doesn't exist. + * Rethrows errors that aren't related to file existance. + */ + async exists(filepath, options = {}) { + try { + await this._stat(filepath); + return true; + } catch (err) { + if (err.code === "ENOENT" || err.code === "ENOTDIR") { + return false; + } else { + console.log('Unhandled error in "FileSystem.exists()" function', err); + throw err; + } + } + } + /** + * Return the contents of a file if it exists, otherwise returns null. + * + * @param {string} filepath + * @param {object} [options] + * + * @returns {Promise} + */ + async read(filepath, options = {}) { + try { + let buffer2 = await this._readFile(filepath, options); + if (typeof buffer2 !== "string") { + buffer2 = Buffer.from(buffer2); + } + return buffer2; + } catch (err) { + return null; + } + } + /** + * Write a file (creating missing directories if need be) without throwing errors. + * + * @param {string} filepath + * @param {Buffer|Uint8Array|string} contents + * @param {object|string} [options] + */ + async write(filepath, contents, options = {}) { + try { + await this._writeFile(filepath, contents, options); + return; + } catch (err) { + await this.mkdir(dirname(filepath)); + await this._writeFile(filepath, contents, options); + } + } + /** + * Make a directory (or series of nested directories) without throwing an error if it already exists. + */ + async mkdir(filepath, _selfCall = false) { + try { + await this._mkdir(filepath); + return; + } catch (err) { + if (err === null) + return; + if (err.code === "EEXIST") + return; + if (_selfCall) + throw err; + if (err.code === "ENOENT") { + const parent = dirname(filepath); + if (parent === "." || parent === "/" || parent === filepath) + throw err; + await this.mkdir(parent); + await this.mkdir(filepath, true); + } + } + } + /** + * Delete a file without throwing an error if it is already deleted. + */ + async rm(filepath) { + try { + await this._unlink(filepath); + } catch (err) { + if (err.code !== "ENOENT") + throw err; + } + } + /** + * Delete a directory without throwing an error if it is already deleted. + */ + async rmdir(filepath, opts) { + try { + if (opts && opts.recursive) { + await this._rm(filepath, opts); + } else { + await this._rmdir(filepath); + } + } catch (err) { + if (err.code !== "ENOENT") + throw err; + } + } + /** + * Read a directory without throwing an error is the directory doesn't exist + */ + async readdir(filepath) { + try { + const names = await this._readdir(filepath); + names.sort(compareStrings); + return names; + } catch (err) { + if (err.code === "ENOTDIR") + return null; + return []; + } + } + /** + * Return a flast list of all the files nested inside a directory + * + * Based on an elegant concurrent recursive solution from SO + * https://stackoverflow.com/a/45130990/2168416 + */ + async readdirDeep(dir) { + const subdirs = await this._readdir(dir); + const files = await Promise.all( + subdirs.map(async (subdir) => { + const res = dir + "/" + subdir; + return (await this._stat(res)).isDirectory() ? this.readdirDeep(res) : res; + }) + ); + return files.reduce((a, f) => a.concat(f), []); + } + /** + * Return the Stats of a file/symlink if it exists, otherwise returns null. + * Rethrows errors that aren't related to file existance. + */ + async lstat(filename) { + try { + const stats = await this._lstat(filename); + return stats; + } catch (err) { + if (err.code === "ENOENT") { + return null; + } + throw err; + } + } + /** + * Reads the contents of a symlink if it exists, otherwise returns null. + * Rethrows errors that aren't related to file existance. + */ + async readlink(filename, opts = { encoding: "buffer" }) { + try { + const link = await this._readlink(filename, opts); + return Buffer.isBuffer(link) ? link : Buffer.from(link); + } catch (err) { + if (err.code === "ENOENT") { + return null; + } + throw err; + } + } + /** + * Write the contents of buffer to a symlink. + */ + async writelink(filename, buffer2) { + return this._symlink(buffer2.toString("utf8"), filename); + } +}; +function assertParameter(name, value) { + if (value === void 0) { + throw new MissingParameterError(name); + } +} +async function modified(entry, base) { + if (!entry && !base) + return false; + if (entry && !base) + return true; + if (!entry && base) + return true; + if (await entry.type() === "tree" && await base.type() === "tree") { + return false; + } + if (await entry.type() === await base.type() && await entry.mode() === await base.mode() && await entry.oid() === await base.oid()) { + return false; + } + return true; +} +async function abortMerge({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + commit: commit2 = "HEAD", + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("dir", dir); + assertParameter("gitdir", gitdir); + const fs = new FileSystem(_fs); + const trees = [TREE({ ref: commit2 }), WORKDIR(), STAGE()]; + let unmergedPaths = []; + await GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + unmergedPaths = index2.unmergedPaths; + }); + const results = await _walk({ + fs, + cache, + dir, + gitdir, + trees, + map: async function(path2, [head, workdir, index2]) { + const staged = !await modified(workdir, index2); + const unmerged = unmergedPaths.includes(path2); + const unmodified = !await modified(index2, head); + if (staged || unmerged) { + return head ? { + path: path2, + mode: await head.mode(), + oid: await head.oid(), + type: await head.type(), + content: await head.content() + } : void 0; + } + if (unmodified) + return false; + else + throw new IndexResetError(path2); + } + }); + await GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + for (const entry of results) { + if (entry === false) + continue; + if (!entry) { + await fs.rmdir(`${dir}/${entry.path}`, { recursive: true }); + index2.delete({ filepath: entry.path }); + continue; + } + if (entry.type === "blob") { + const content = new TextDecoder().decode(entry.content); + await fs.write(`${dir}/${entry.path}`, content, { mode: entry.mode }); + index2.insert({ + filepath: entry.path, + oid: entry.oid, + stage: 0 + }); + } + } + }); + } catch (err) { + err.caller = "git.abortMerge"; + throw err; + } +} +var GitIgnoreManager = class { + static async isIgnored({ fs, dir, gitdir = join(dir, ".git"), filepath }) { + if (basename(filepath) === ".git") + return true; + if (filepath === ".") + return false; + let excludes = ""; + const excludesFile = join(gitdir, "info", "exclude"); + if (await fs.exists(excludesFile)) { + excludes = await fs.read(excludesFile, "utf8"); + } + const pairs = [ + { + gitignore: join(dir, ".gitignore"), + filepath + } + ]; + const pieces = filepath.split("/").filter(Boolean); + for (let i = 1; i < pieces.length; i++) { + const folder = pieces.slice(0, i).join("/"); + const file = pieces.slice(i).join("/"); + pairs.push({ + gitignore: join(dir, folder, ".gitignore"), + filepath: file + }); + } + let ignoredStatus = false; + for (const p of pairs) { + let file; + try { + file = await fs.read(p.gitignore, "utf8"); + } catch (err) { + if (err.code === "NOENT") + continue; + } + const ign = (0, import_ignore.default)().add(excludes); + ign.add(file); + const parentdir = dirname(p.filepath); + if (parentdir !== "." && ign.ignores(parentdir)) + return true; + if (ignoredStatus) { + ignoredStatus = !ign.test(p.filepath).unignored; + } else { + ignoredStatus = ign.test(p.filepath).ignored; + } + } + return ignoredStatus; + } +}; +async function writeObjectLoose({ fs, gitdir, object, format, oid }) { + if (format !== "deflated") { + throw new InternalError( + "GitObjectStoreLoose expects objects to write to be in deflated format" + ); + } + const source = `objects/${oid.slice(0, 2)}/${oid.slice(2)}`; + const filepath = `${gitdir}/${source}`; + if (!await fs.exists(filepath)) + await fs.write(filepath, object); +} +var supportsCompressionStream = null; +async function deflate(buffer2) { + if (supportsCompressionStream === null) { + supportsCompressionStream = testCompressionStream(); + } + return supportsCompressionStream ? browserDeflate(buffer2) : import_pako.default.deflate(buffer2); +} +async function browserDeflate(buffer2) { + const cs = new CompressionStream("deflate"); + const c = new Blob([buffer2]).stream().pipeThrough(cs); + return new Uint8Array(await new Response(c).arrayBuffer()); +} +function testCompressionStream() { + try { + const cs = new CompressionStream("deflate"); + new Blob([]).stream(); + if (cs) + return true; + } catch (_) { + } + return false; +} +async function _writeObject({ + fs, + gitdir, + type, + object, + format = "content", + oid = void 0, + dryRun = false +}) { + if (format !== "deflated") { + if (format !== "wrapped") { + object = GitObject.wrap({ type, object }); + } + oid = await shasum(object); + object = Buffer.from(await deflate(object)); + } + if (!dryRun) { + await writeObjectLoose({ fs, gitdir, object, format: "deflated", oid }); + } + return oid; +} +function posixifyPathBuffer(buffer2) { + let idx; + while (~(idx = buffer2.indexOf(92))) + buffer2[idx] = 47; + return buffer2; +} +async function add({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + filepath, + cache = {}, + force = false +}) { + try { + assertParameter("fs", _fs); + assertParameter("dir", dir); + assertParameter("gitdir", gitdir); + assertParameter("filepath", filepath); + const fs = new FileSystem(_fs); + await GitIndexManager.acquire({ fs, gitdir, cache }, async (index2) => { + return addToIndex({ dir, gitdir, fs, filepath, index: index2, force }); + }); + } catch (err) { + err.caller = "git.add"; + throw err; + } +} +async function addToIndex({ dir, gitdir, fs, filepath, index: index2, force }) { + filepath = Array.isArray(filepath) ? filepath : [filepath]; + const promises = filepath.map(async (currentFilepath) => { + if (!force) { + const ignored = await GitIgnoreManager.isIgnored({ + fs, + dir, + gitdir, + filepath: currentFilepath + }); + if (ignored) + return; + } + const stats = await fs.lstat(join(dir, currentFilepath)); + if (!stats) + throw new NotFoundError(currentFilepath); + if (stats.isDirectory()) { + const children2 = await fs.readdir(join(dir, currentFilepath)); + const promises2 = children2.map( + (child) => addToIndex({ + dir, + gitdir, + fs, + filepath: [join(currentFilepath, child)], + index: index2, + force + }) + ); + await Promise.all(promises2); + } else { + const object = stats.isSymbolicLink() ? await fs.readlink(join(dir, currentFilepath)).then(posixifyPathBuffer) : await fs.read(join(dir, currentFilepath)); + if (object === null) + throw new NotFoundError(currentFilepath); + const oid = await _writeObject({ fs, gitdir, type: "blob", object }); + index2.insert({ filepath: currentFilepath, stats, oid }); + } + }); + const settledPromises = await Promise.allSettled(promises); + const rejectedPromises = settledPromises.filter((settle) => settle.status === "rejected").map((settle) => settle.reason); + if (rejectedPromises.length > 1) { + throw new MultipleGitError(rejectedPromises); + } + if (rejectedPromises.length === 1) { + throw rejectedPromises[0]; + } + const fulfilledPromises = settledPromises.filter((settle) => settle.status === "fulfilled" && settle.value).map((settle) => settle.value); + return fulfilledPromises; +} +async function _commit({ + fs, + cache, + onSign, + gitdir, + message, + author, + committer, + signingKey, + dryRun = false, + noUpdateBranch = false, + ref, + parent, + tree +}) { + if (!ref) { + ref = await GitRefManager.resolve({ + fs, + gitdir, + ref: "HEAD", + depth: 2 + }); + } + return GitIndexManager.acquire( + { fs, gitdir, cache, allowUnmerged: false }, + async function(index2) { + const inodes = flatFileListToDirectoryStructure(index2.entries); + const inode = inodes.get("."); + if (!tree) { + tree = await constructTree({ fs, gitdir, inode, dryRun }); + } + if (!parent) { + try { + parent = [ + await GitRefManager.resolve({ + fs, + gitdir, + ref + }) + ]; + } catch (err) { + parent = []; + } + } else { + parent = await Promise.all( + parent.map((p) => { + return GitRefManager.resolve({ fs, gitdir, ref: p }); + }) + ); + } + let comm = GitCommit.from({ + tree, + parent, + author, + committer, + message + }); + if (signingKey) { + comm = await GitCommit.sign(comm, onSign, signingKey); + } + const oid = await _writeObject({ + fs, + gitdir, + type: "commit", + object: comm.toObject(), + dryRun + }); + if (!noUpdateBranch && !dryRun) { + await GitRefManager.writeRef({ + fs, + gitdir, + ref, + value: oid + }); + } + return oid; + } + ); +} +async function constructTree({ fs, gitdir, inode, dryRun }) { + const children2 = inode.children; + for (const inode2 of children2) { + if (inode2.type === "tree") { + inode2.metadata.mode = "040000"; + inode2.metadata.oid = await constructTree({ fs, gitdir, inode: inode2, dryRun }); + } + } + const entries = children2.map((inode2) => ({ + mode: inode2.metadata.mode, + path: inode2.basename, + oid: inode2.metadata.oid, + type: inode2.type + })); + const tree = GitTree.from(entries); + const oid = await _writeObject({ + fs, + gitdir, + type: "tree", + object: tree.toObject(), + dryRun + }); + return oid; +} +async function resolveFilepath({ fs, cache, gitdir, oid, filepath }) { + if (filepath.startsWith("/")) { + throw new InvalidFilepathError("leading-slash"); + } else if (filepath.endsWith("/")) { + throw new InvalidFilepathError("trailing-slash"); + } + const _oid = oid; + const result = await resolveTree({ fs, cache, gitdir, oid }); + const tree = result.tree; + if (filepath === "") { + oid = result.oid; + } else { + const pathArray = filepath.split("/"); + oid = await _resolveFilepath({ + fs, + cache, + gitdir, + tree, + pathArray, + oid: _oid, + filepath + }); + } + return oid; +} +async function _resolveFilepath({ + fs, + cache, + gitdir, + tree, + pathArray, + oid, + filepath +}) { + const name = pathArray.shift(); + for (const entry of tree) { + if (entry.path === name) { + if (pathArray.length === 0) { + return entry.oid; + } else { + const { type, object } = await _readObject({ + fs, + cache, + gitdir, + oid: entry.oid + }); + if (type !== "tree") { + throw new ObjectTypeError(oid, type, "tree", filepath); + } + tree = GitTree.from(object); + return _resolveFilepath({ + fs, + cache, + gitdir, + tree, + pathArray, + oid, + filepath + }); + } + } + } + throw new NotFoundError(`file or directory found at "${oid}:${filepath}"`); +} +async function _readTree({ + fs, + cache, + gitdir, + oid, + filepath = void 0 +}) { + if (filepath !== void 0) { + oid = await resolveFilepath({ fs, cache, gitdir, oid, filepath }); + } + const { tree, oid: treeOid } = await resolveTree({ fs, cache, gitdir, oid }); + const result = { + oid: treeOid, + tree: tree.entries() + }; + return result; +} +async function _writeTree({ fs, gitdir, tree }) { + const object = GitTree.from(tree).toObject(); + const oid = await _writeObject({ + fs, + gitdir, + type: "tree", + object, + format: "content" + }); + return oid; +} +async function _addNote({ + fs, + cache, + onSign, + gitdir, + ref, + oid, + note, + force, + author, + committer, + signingKey +}) { + let parent; + try { + parent = await GitRefManager.resolve({ gitdir, fs, ref }); + } catch (err) { + if (!(err instanceof NotFoundError)) { + throw err; + } + } + const result = await _readTree({ + fs, + cache, + gitdir, + oid: parent || "4b825dc642cb6eb9a060e54bf8d69288fbee4904" + }); + let tree = result.tree; + if (force) { + tree = tree.filter((entry) => entry.path !== oid); + } else { + for (const entry of tree) { + if (entry.path === oid) { + throw new AlreadyExistsError("note", oid); + } + } + } + if (typeof note === "string") { + note = Buffer.from(note, "utf8"); + } + const noteOid = await _writeObject({ + fs, + gitdir, + type: "blob", + object: note, + format: "content" + }); + tree.push({ mode: "100644", path: oid, oid: noteOid, type: "blob" }); + const treeOid = await _writeTree({ + fs, + gitdir, + tree + }); + const commitOid = await _commit({ + fs, + cache, + onSign, + gitdir, + ref, + tree: treeOid, + parent: parent && [parent], + message: `Note added by 'isomorphic-git addNote' +`, + author, + committer, + signingKey + }); + return commitOid; +} +async function _getConfig({ fs, gitdir, path: path2 }) { + const config = await GitConfigManager.get({ fs, gitdir }); + return config.get(path2); +} +async function normalizeAuthorObject({ fs, gitdir, author = {} }) { + let { name, email, timestamp, timezoneOffset } = author; + name = name || await _getConfig({ fs, gitdir, path: "user.name" }); + email = email || await _getConfig({ fs, gitdir, path: "user.email" }) || ""; + if (name === void 0) { + return void 0; + } + timestamp = timestamp != null ? timestamp : Math.floor(Date.now() / 1e3); + timezoneOffset = timezoneOffset != null ? timezoneOffset : new Date(timestamp * 1e3).getTimezoneOffset(); + return { name, email, timestamp, timezoneOffset }; +} +async function normalizeCommitterObject({ + fs, + gitdir, + author, + committer +}) { + committer = Object.assign({}, committer || author); + if (author) { + committer.timestamp = committer.timestamp || author.timestamp; + committer.timezoneOffset = committer.timezoneOffset || author.timezoneOffset; + } + committer = await normalizeAuthorObject({ fs, gitdir, author: committer }); + return committer; +} +async function addNote({ + fs: _fs, + onSign, + dir, + gitdir = join(dir, ".git"), + ref = "refs/notes/commits", + oid, + note, + force, + author: _author, + committer: _committer, + signingKey, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + assertParameter("note", note); + if (signingKey) { + assertParameter("onSign", onSign); + } + const fs = new FileSystem(_fs); + const author = await normalizeAuthorObject({ fs, gitdir, author: _author }); + if (!author) + throw new MissingNameError("author"); + const committer = await normalizeCommitterObject({ + fs, + gitdir, + author, + committer: _committer + }); + if (!committer) + throw new MissingNameError("committer"); + return await _addNote({ + fs: new FileSystem(fs), + cache, + onSign, + gitdir, + ref, + oid, + note, + force, + author, + committer, + signingKey + }); + } catch (err) { + err.caller = "git.addNote"; + throw err; + } +} +async function _addRemote({ fs, gitdir, remote, url, force }) { + if (remote !== import_clean_git_ref.default.clean(remote)) { + throw new InvalidRefNameError(remote, import_clean_git_ref.default.clean(remote)); + } + const config = await GitConfigManager.get({ fs, gitdir }); + if (!force) { + const remoteNames = await config.getSubsections("remote"); + if (remoteNames.includes(remote)) { + if (url !== await config.get(`remote.${remote}.url`)) { + throw new AlreadyExistsError("remote", remote); + } + } + } + await config.set(`remote.${remote}.url`, url); + await config.set( + `remote.${remote}.fetch`, + `+refs/heads/*:refs/remotes/${remote}/*` + ); + await GitConfigManager.save({ fs, gitdir, config }); +} +async function addRemote({ + fs, + dir, + gitdir = join(dir, ".git"), + remote, + url, + force = false +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("remote", remote); + assertParameter("url", url); + return await _addRemote({ + fs: new FileSystem(fs), + gitdir, + remote, + url, + force + }); + } catch (err) { + err.caller = "git.addRemote"; + throw err; + } +} +async function _annotatedTag({ + fs, + cache, + onSign, + gitdir, + ref, + tagger, + message = ref, + gpgsig, + object, + signingKey, + force = false +}) { + ref = ref.startsWith("refs/tags/") ? ref : `refs/tags/${ref}`; + if (!force && await GitRefManager.exists({ fs, gitdir, ref })) { + throw new AlreadyExistsError("tag", ref); + } + const oid = await GitRefManager.resolve({ + fs, + gitdir, + ref: object || "HEAD" + }); + const { type } = await _readObject({ fs, cache, gitdir, oid }); + let tagObject = GitAnnotatedTag.from({ + object: oid, + type, + tag: ref.replace("refs/tags/", ""), + tagger, + message, + gpgsig + }); + if (signingKey) { + tagObject = await GitAnnotatedTag.sign(tagObject, onSign, signingKey); + } + const value = await _writeObject({ + fs, + gitdir, + type: "tag", + object: tagObject.toObject() + }); + await GitRefManager.writeRef({ fs, gitdir, ref, value }); +} +async function annotatedTag({ + fs: _fs, + onSign, + dir, + gitdir = join(dir, ".git"), + ref, + tagger: _tagger, + message = ref, + gpgsig, + object, + signingKey, + force = false, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + if (signingKey) { + assertParameter("onSign", onSign); + } + const fs = new FileSystem(_fs); + const tagger = await normalizeAuthorObject({ fs, gitdir, author: _tagger }); + if (!tagger) + throw new MissingNameError("tagger"); + return await _annotatedTag({ + fs, + cache, + onSign, + gitdir, + ref, + tagger, + message, + gpgsig, + object, + signingKey, + force + }); + } catch (err) { + err.caller = "git.annotatedTag"; + throw err; + } +} +async function _branch({ + fs, + gitdir, + ref, + object, + checkout: checkout2 = false, + force = false +}) { + if (ref !== import_clean_git_ref.default.clean(ref)) { + throw new InvalidRefNameError(ref, import_clean_git_ref.default.clean(ref)); + } + const fullref = `refs/heads/${ref}`; + if (!force) { + const exist = await GitRefManager.exists({ fs, gitdir, ref: fullref }); + if (exist) { + throw new AlreadyExistsError("branch", ref, false); + } + } + let oid; + try { + oid = await GitRefManager.resolve({ fs, gitdir, ref: object || "HEAD" }); + } catch (e) { + } + if (oid) { + await GitRefManager.writeRef({ fs, gitdir, ref: fullref, value: oid }); + } + if (checkout2) { + await GitRefManager.writeSymbolicRef({ + fs, + gitdir, + ref: "HEAD", + value: fullref + }); + } +} +async function branch({ + fs, + dir, + gitdir = join(dir, ".git"), + ref, + object, + checkout: checkout2 = false, + force = false +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + return await _branch({ + fs: new FileSystem(fs), + gitdir, + ref, + object, + checkout: checkout2, + force + }); + } catch (err) { + err.caller = "git.branch"; + throw err; + } +} +var worthWalking = (filepath, root2) => { + if (filepath === "." || root2 == null || root2.length === 0 || root2 === ".") { + return true; + } + if (root2.length >= filepath.length) { + return root2.startsWith(filepath); + } else { + return filepath.startsWith(root2); + } +}; +async function _checkout({ + fs, + cache, + onProgress, + dir, + gitdir, + remote, + ref, + filepaths, + noCheckout, + noUpdateHead, + dryRun, + force, + track = true +}) { + let oid; + try { + oid = await GitRefManager.resolve({ fs, gitdir, ref }); + } catch (err) { + if (ref === "HEAD") + throw err; + const remoteRef = `${remote}/${ref}`; + oid = await GitRefManager.resolve({ + fs, + gitdir, + ref: remoteRef + }); + if (track) { + const config = await GitConfigManager.get({ fs, gitdir }); + await config.set(`branch.${ref}.remote`, remote); + await config.set(`branch.${ref}.merge`, `refs/heads/${ref}`); + await GitConfigManager.save({ fs, gitdir, config }); + } + await GitRefManager.writeRef({ + fs, + gitdir, + ref: `refs/heads/${ref}`, + value: oid + }); + } + if (!noCheckout) { + let ops; + try { + ops = await analyze({ + fs, + cache, + onProgress, + dir, + gitdir, + ref, + force, + filepaths + }); + } catch (err) { + if (err instanceof NotFoundError && err.data.what === oid) { + throw new CommitNotFetchedError(ref, oid); + } else { + throw err; + } + } + const conflicts2 = ops.filter(([method2]) => method2 === "conflict").map(([method2, fullpath]) => fullpath); + if (conflicts2.length > 0) { + throw new CheckoutConflictError(conflicts2); + } + const errors = ops.filter(([method2]) => method2 === "error").map(([method2, fullpath]) => fullpath); + if (errors.length > 0) { + throw new InternalError(errors.join(", ")); + } + if (dryRun) { + return; + } + let count = 0; + const total = ops.length; + await GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + await Promise.all( + ops.filter( + ([method2]) => method2 === "delete" || method2 === "delete-index" + ).map(async function([method2, fullpath]) { + const filepath = `${dir}/${fullpath}`; + if (method2 === "delete") { + await fs.rm(filepath); + } + index2.delete({ filepath: fullpath }); + if (onProgress) { + await onProgress({ + phase: "Updating workdir", + loaded: ++count, + total + }); + } + }) + ); + }); + await GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + for (const [method2, fullpath] of ops) { + if (method2 === "rmdir" || method2 === "rmdir-index") { + const filepath = `${dir}/${fullpath}`; + try { + if (method2 === "rmdir-index") { + index2.delete({ filepath: fullpath }); + } + await fs.rmdir(filepath); + if (onProgress) { + await onProgress({ + phase: "Updating workdir", + loaded: ++count, + total + }); + } + } catch (e) { + if (e.code === "ENOTEMPTY") { + console.log( + `Did not delete ${fullpath} because directory is not empty` + ); + } else { + throw e; + } + } + } + } + }); + await Promise.all( + ops.filter(([method2]) => method2 === "mkdir" || method2 === "mkdir-index").map(async function([_, fullpath]) { + const filepath = `${dir}/${fullpath}`; + await fs.mkdir(filepath); + if (onProgress) { + await onProgress({ + phase: "Updating workdir", + loaded: ++count, + total + }); + } + }) + ); + await GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + await Promise.all( + ops.filter( + ([method2]) => method2 === "create" || method2 === "create-index" || method2 === "update" || method2 === "mkdir-index" + ).map(async function([method2, fullpath, oid2, mode, chmod]) { + const filepath = `${dir}/${fullpath}`; + try { + if (method2 !== "create-index" && method2 !== "mkdir-index") { + const { object } = await _readObject({ fs, cache, gitdir, oid: oid2 }); + if (chmod) { + await fs.rm(filepath); + } + if (mode === 33188) { + await fs.write(filepath, object); + } else if (mode === 33261) { + await fs.write(filepath, object, { mode: 511 }); + } else if (mode === 40960) { + await fs.writelink(filepath, object); + } else { + throw new InternalError( + `Invalid mode 0o${mode.toString(8)} detected in blob ${oid2}` + ); + } + } + const stats = await fs.lstat(filepath); + if (mode === 33261) { + stats.mode = 493; + } + if (method2 === "mkdir-index") { + stats.mode = 57344; + } + index2.insert({ + filepath: fullpath, + stats, + oid: oid2 + }); + if (onProgress) { + await onProgress({ + phase: "Updating workdir", + loaded: ++count, + total + }); + } + } catch (e) { + console.log(e); + } + }) + ); + }); + } + if (!noUpdateHead) { + const fullRef = await GitRefManager.expand({ fs, gitdir, ref }); + if (fullRef.startsWith("refs/heads")) { + await GitRefManager.writeSymbolicRef({ + fs, + gitdir, + ref: "HEAD", + value: fullRef + }); + } else { + await GitRefManager.writeRef({ fs, gitdir, ref: "HEAD", value: oid }); + } + } +} +async function analyze({ + fs, + cache, + onProgress, + dir, + gitdir, + ref, + force, + filepaths +}) { + let count = 0; + return _walk({ + fs, + cache, + dir, + gitdir, + trees: [TREE({ ref }), WORKDIR(), STAGE()], + map: async function(fullpath, [commit2, workdir, stage]) { + if (fullpath === ".") + return; + if (filepaths && !filepaths.some((base) => worthWalking(fullpath, base))) { + return null; + } + if (onProgress) { + await onProgress({ phase: "Analyzing workdir", loaded: ++count }); + } + const key2 = [!!stage, !!commit2, !!workdir].map(Number).join(""); + switch (key2) { + case "000": + return; + case "001": + if (force && filepaths && filepaths.includes(fullpath)) { + return ["delete", fullpath]; + } + return; + case "010": { + switch (await commit2.type()) { + case "tree": { + return ["mkdir", fullpath]; + } + case "blob": { + return [ + "create", + fullpath, + await commit2.oid(), + await commit2.mode() + ]; + } + case "commit": { + return [ + "mkdir-index", + fullpath, + await commit2.oid(), + await commit2.mode() + ]; + } + default: { + return [ + "error", + `new entry Unhandled type ${await commit2.type()}` + ]; + } + } + } + case "011": { + switch (`${await commit2.type()}-${await workdir.type()}`) { + case "tree-tree": { + return; + } + case "tree-blob": + case "blob-tree": { + return ["conflict", fullpath]; + } + case "blob-blob": { + if (await commit2.oid() !== await workdir.oid()) { + if (force) { + return [ + "update", + fullpath, + await commit2.oid(), + await commit2.mode(), + await commit2.mode() !== await workdir.mode() + ]; + } else { + return ["conflict", fullpath]; + } + } else { + if (await commit2.mode() !== await workdir.mode()) { + if (force) { + return [ + "update", + fullpath, + await commit2.oid(), + await commit2.mode(), + true + ]; + } else { + return ["conflict", fullpath]; + } + } else { + return [ + "create-index", + fullpath, + await commit2.oid(), + await commit2.mode() + ]; + } + } + } + case "commit-tree": { + return; + } + case "commit-blob": { + return ["conflict", fullpath]; + } + default: { + return ["error", `new entry Unhandled type ${commit2.type}`]; + } + } + } + case "100": { + return ["delete-index", fullpath]; + } + case "101": { + switch (await stage.type()) { + case "tree": { + return ["rmdir", fullpath]; + } + case "blob": { + if (await stage.oid() !== await workdir.oid()) { + if (force) { + return ["delete", fullpath]; + } else { + return ["conflict", fullpath]; + } + } else { + return ["delete", fullpath]; + } + } + case "commit": { + return ["rmdir-index", fullpath]; + } + default: { + return [ + "error", + `delete entry Unhandled type ${await stage.type()}` + ]; + } + } + } + case "110": + case "111": { + switch (`${await stage.type()}-${await commit2.type()}`) { + case "tree-tree": { + return; + } + case "blob-blob": { + if (await stage.oid() === await commit2.oid() && await stage.mode() === await commit2.mode() && !force) { + return; + } + if (workdir) { + if (await workdir.oid() !== await stage.oid() && await workdir.oid() !== await commit2.oid()) { + if (force) { + return [ + "update", + fullpath, + await commit2.oid(), + await commit2.mode(), + await commit2.mode() !== await workdir.mode() + ]; + } else { + return ["conflict", fullpath]; + } + } + } else if (force) { + return [ + "update", + fullpath, + await commit2.oid(), + await commit2.mode(), + await commit2.mode() !== await stage.mode() + ]; + } + if (await commit2.mode() !== await stage.mode()) { + return [ + "update", + fullpath, + await commit2.oid(), + await commit2.mode(), + true + ]; + } + if (await commit2.oid() !== await stage.oid()) { + return [ + "update", + fullpath, + await commit2.oid(), + await commit2.mode(), + false + ]; + } else { + return; + } + } + case "tree-blob": { + return ["update-dir-to-blob", fullpath, await commit2.oid()]; + } + case "blob-tree": { + return ["update-blob-to-tree", fullpath]; + } + case "commit-commit": { + return [ + "mkdir-index", + fullpath, + await commit2.oid(), + await commit2.mode() + ]; + } + default: { + return [ + "error", + `update entry Unhandled type ${await stage.type()}-${await commit2.type()}` + ]; + } + } + } + } + }, + // Modify the default flat mapping + reduce: async function(parent, children2) { + children2 = flat(children2); + if (!parent) { + return children2; + } else if (parent && parent[0] === "rmdir") { + children2.push(parent); + return children2; + } else { + children2.unshift(parent); + return children2; + } + } + }); +} +async function checkout({ + fs, + onProgress, + dir, + gitdir = join(dir, ".git"), + remote = "origin", + ref: _ref, + filepaths, + noCheckout = false, + noUpdateHead = _ref === void 0, + dryRun = false, + force = false, + track = true, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("dir", dir); + assertParameter("gitdir", gitdir); + const ref = _ref || "HEAD"; + return await _checkout({ + fs: new FileSystem(fs), + cache, + onProgress, + dir, + gitdir, + remote, + ref, + filepaths, + noCheckout, + noUpdateHead, + dryRun, + force, + track + }); + } catch (err) { + err.caller = "git.checkout"; + throw err; + } +} +var abbreviateRx = new RegExp("^refs/(heads/|tags/|remotes/)?(.*)"); +function abbreviateRef(ref) { + const match = abbreviateRx.exec(ref); + if (match) { + if (match[1] === "remotes/" && ref.endsWith("/HEAD")) { + return match[2].slice(0, -5); + } else { + return match[2]; + } + } + return ref; +} +async function _currentBranch({ + fs, + gitdir, + fullname = false, + test = false +}) { + const ref = await GitRefManager.resolve({ + fs, + gitdir, + ref: "HEAD", + depth: 2 + }); + if (test) { + try { + await GitRefManager.resolve({ fs, gitdir, ref }); + } catch (_) { + return; + } + } + if (!ref.startsWith("refs/")) + return; + return fullname ? ref : abbreviateRef(ref); +} +function translateSSHtoHTTP(url) { + url = url.replace(/^git@([^:]+):/, "https://$1/"); + url = url.replace(/^ssh:\/\//, "https://"); + return url; +} +function calculateBasicAuthHeader({ username = "", password = "" }) { + return `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`; +} +async function forAwait(iterable, cb) { + const iter = getIterator(iterable); + while (true) { + const { value, done } = await iter.next(); + if (value) + await cb(value); + if (done) + break; + } + if (iter.return) + iter.return(); +} +async function collect(iterable) { + let size = 0; + const buffers = []; + await forAwait(iterable, (value) => { + buffers.push(value); + size += value.byteLength; + }); + const result = new Uint8Array(size); + let nextIndex = 0; + for (const buffer2 of buffers) { + result.set(buffer2, nextIndex); + nextIndex += buffer2.byteLength; + } + return result; +} +function extractAuthFromUrl(url) { + let userpass = url.match(/^https?:\/\/([^/]+)@/); + if (userpass == null) + return { url, auth: {} }; + userpass = userpass[1]; + const [username, password] = userpass.split(":"); + url = url.replace(`${userpass}@`, ""); + return { url, auth: { username, password } }; +} +function padHex(b, n) { + const s = n.toString(16); + return "0".repeat(b - s.length) + s; +} +var GitPktLine = class { + static flush() { + return Buffer.from("0000", "utf8"); + } + static delim() { + return Buffer.from("0001", "utf8"); + } + static encode(line) { + if (typeof line === "string") { + line = Buffer.from(line); + } + const length = line.length + 4; + const hexlength = padHex(4, length); + return Buffer.concat([Buffer.from(hexlength, "utf8"), line]); + } + static streamReader(stream) { + const reader = new StreamReader(stream); + return async function read() { + try { + let length = await reader.read(4); + if (length == null) + return true; + length = parseInt(length.toString("utf8"), 16); + if (length === 0) + return null; + if (length === 1) + return null; + const buffer2 = await reader.read(length - 4); + if (buffer2 == null) + return true; + return buffer2; + } catch (err) { + console.log("error", err); + return true; + } + }; + } +}; +async function parseCapabilitiesV2(read) { + const capabilities2 = {}; + let line; + while (true) { + line = await read(); + if (line === true) + break; + if (line === null) + continue; + line = line.toString("utf8").replace(/\n$/, ""); + const i = line.indexOf("="); + if (i > -1) { + const key2 = line.slice(0, i); + const value = line.slice(i + 1); + capabilities2[key2] = value; + } else { + capabilities2[line] = true; + } + } + return { protocolVersion: 2, capabilities2 }; +} +async function parseRefsAdResponse(stream, { service }) { + const capabilities = /* @__PURE__ */ new Set(); + const refs = /* @__PURE__ */ new Map(); + const symrefs = /* @__PURE__ */ new Map(); + const read = GitPktLine.streamReader(stream); + let lineOne = await read(); + while (lineOne === null) + lineOne = await read(); + if (lineOne === true) + throw new EmptyServerResponseError(); + if (lineOne.includes("version 2")) { + return parseCapabilitiesV2(read); + } + if (lineOne.toString("utf8").replace(/\n$/, "") !== `# service=${service}`) { + throw new ParseError(`# service=${service}\\n`, lineOne.toString("utf8")); + } + let lineTwo = await read(); + while (lineTwo === null) + lineTwo = await read(); + if (lineTwo === true) + return { capabilities, refs, symrefs }; + lineTwo = lineTwo.toString("utf8"); + if (lineTwo.includes("version 2")) { + return parseCapabilitiesV2(read); + } + const [firstRef, capabilitiesLine] = splitAndAssert(lineTwo, "\0", "\\x00"); + capabilitiesLine.split(" ").map((x) => capabilities.add(x)); + const [ref, name] = splitAndAssert(firstRef, " ", " "); + refs.set(name, ref); + while (true) { + const line = await read(); + if (line === true) + break; + if (line !== null) { + const [ref2, name2] = splitAndAssert(line.toString("utf8"), " ", " "); + refs.set(name2, ref2); + } + } + for (const cap of capabilities) { + if (cap.startsWith("symref=")) { + const m = cap.match(/symref=([^:]+):(.*)/); + if (m.length === 3) { + symrefs.set(m[1], m[2]); + } + } + } + return { protocolVersion: 1, capabilities, refs, symrefs }; +} +function splitAndAssert(line, sep2, expected) { + const split = line.trim().split(sep2); + if (split.length !== 2) { + throw new ParseError( + `Two strings separated by '${expected}'`, + line.toString("utf8") + ); + } + return split; +} +var corsProxify = (corsProxy, url) => corsProxy.endsWith("?") ? `${corsProxy}${url}` : `${corsProxy}/${url.replace(/^https?:\/\//, "")}`; +var updateHeaders = (headers, auth) => { + if (auth.username || auth.password) { + headers.Authorization = calculateBasicAuthHeader(auth); + } + if (auth.headers) { + Object.assign(headers, auth.headers); + } +}; +var stringifyBody = async (res) => { + try { + const data = Buffer.from(await collect(res.body)); + const response = data.toString("utf8"); + const preview = response.length < 256 ? response : response.slice(0, 256) + "..."; + return { preview, response, data }; + } catch (e) { + return {}; + } +}; +var GitRemoteHTTP = class { + static async capabilities() { + return ["discover", "connect"]; + } + /** + * @param {Object} args + * @param {HttpClient} args.http + * @param {ProgressCallback} [args.onProgress] + * @param {AuthCallback} [args.onAuth] + * @param {AuthFailureCallback} [args.onAuthFailure] + * @param {AuthSuccessCallback} [args.onAuthSuccess] + * @param {string} [args.corsProxy] + * @param {string} args.service + * @param {string} args.url + * @param {Object} args.headers + * @param {1 | 2} args.protocolVersion - Git Protocol Version + */ + static async discover({ + http, + onProgress, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + service, + url: _origUrl, + headers, + protocolVersion + }) { + let { url, auth } = extractAuthFromUrl(_origUrl); + const proxifiedURL = corsProxy ? corsProxify(corsProxy, url) : url; + if (auth.username || auth.password) { + headers.Authorization = calculateBasicAuthHeader(auth); + } + if (protocolVersion === 2) { + headers["Git-Protocol"] = "version=2"; + } + let res; + let tryAgain; + let providedAuthBefore = false; + do { + res = await http.request({ + onProgress, + method: "GET", + url: `${proxifiedURL}/info/refs?service=${service}`, + headers + }); + tryAgain = false; + if (res.statusCode === 401 || res.statusCode === 203) { + const getAuth = providedAuthBefore ? onAuthFailure : onAuth; + if (getAuth) { + auth = await getAuth(url, { + ...auth, + headers: { ...headers } + }); + if (auth && auth.cancel) { + throw new UserCanceledError(); + } else if (auth) { + updateHeaders(headers, auth); + providedAuthBefore = true; + tryAgain = true; + } + } + } else if (res.statusCode === 200 && providedAuthBefore && onAuthSuccess) { + await onAuthSuccess(url, auth); + } + } while (tryAgain); + if (res.statusCode !== 200) { + const { response } = await stringifyBody(res); + throw new HttpError(res.statusCode, res.statusMessage, response); + } + if (res.headers["content-type"] === `application/x-${service}-advertisement`) { + const remoteHTTP = await parseRefsAdResponse(res.body, { service }); + remoteHTTP.auth = auth; + return remoteHTTP; + } else { + const { preview, response, data } = await stringifyBody(res); + try { + const remoteHTTP = await parseRefsAdResponse([data], { service }); + remoteHTTP.auth = auth; + return remoteHTTP; + } catch (e) { + throw new SmartHttpError(preview, response); + } + } + } + /** + * @param {Object} args + * @param {HttpClient} args.http + * @param {ProgressCallback} [args.onProgress] + * @param {string} [args.corsProxy] + * @param {string} args.service + * @param {string} args.url + * @param {Object} [args.headers] + * @param {any} args.body + * @param {any} args.auth + */ + static async connect({ + http, + onProgress, + corsProxy, + service, + url, + auth, + body, + headers + }) { + const urlAuth = extractAuthFromUrl(url); + if (urlAuth) + url = urlAuth.url; + if (corsProxy) + url = corsProxify(corsProxy, url); + headers["content-type"] = `application/x-${service}-request`; + headers.accept = `application/x-${service}-result`; + updateHeaders(headers, auth); + const res = await http.request({ + onProgress, + method: "POST", + url: `${url}/${service}`, + body, + headers + }); + if (res.statusCode !== 200) { + const { response } = stringifyBody(res); + throw new HttpError(res.statusCode, res.statusMessage, response); + } + return res; + } +}; +function parseRemoteUrl({ url }) { + if (url.startsWith("git@")) { + return { + transport: "ssh", + address: url + }; + } + const matches = url.match(/(\w+)(:\/\/|::)(.*)/); + if (matches === null) + return; + if (matches[2] === "://") { + return { + transport: matches[1], + address: matches[0] + }; + } + if (matches[2] === "::") { + return { + transport: matches[1], + address: matches[3] + }; + } +} +var GitRemoteManager = class { + static getRemoteHelperFor({ url }) { + const remoteHelpers = /* @__PURE__ */ new Map(); + remoteHelpers.set("http", GitRemoteHTTP); + remoteHelpers.set("https", GitRemoteHTTP); + const parts = parseRemoteUrl({ url }); + if (!parts) { + throw new UrlParseError(url); + } + if (remoteHelpers.has(parts.transport)) { + return remoteHelpers.get(parts.transport); + } + throw new UnknownTransportError( + url, + parts.transport, + parts.transport === "ssh" ? translateSSHtoHTTP(url) : void 0 + ); + } +}; +var lock$1 = null; +var GitShallowManager = class { + static async read({ fs, gitdir }) { + if (lock$1 === null) + lock$1 = new import_async_lock.default(); + const filepath = join(gitdir, "shallow"); + const oids = /* @__PURE__ */ new Set(); + await lock$1.acquire(filepath, async function() { + const text2 = await fs.read(filepath, { encoding: "utf8" }); + if (text2 === null) + return oids; + if (text2.trim() === "") + return oids; + text2.trim().split("\n").map((oid) => oids.add(oid)); + }); + return oids; + } + static async write({ fs, gitdir, oids }) { + if (lock$1 === null) + lock$1 = new import_async_lock.default(); + const filepath = join(gitdir, "shallow"); + if (oids.size > 0) { + const text2 = [...oids].join("\n") + "\n"; + await lock$1.acquire(filepath, async function() { + await fs.write(filepath, text2, { + encoding: "utf8" + }); + }); + } else { + await lock$1.acquire(filepath, async function() { + await fs.rm(filepath); + }); + } + } +}; +async function hasObjectLoose({ fs, gitdir, oid }) { + const source = `objects/${oid.slice(0, 2)}/${oid.slice(2)}`; + return fs.exists(`${gitdir}/${source}`); +} +async function hasObjectPacked({ + fs, + cache, + gitdir, + oid, + getExternalRefDelta +}) { + let list = await fs.readdir(join(gitdir, "objects/pack")); + list = list.filter((x) => x.endsWith(".idx")); + for (const filename of list) { + const indexFile = `${gitdir}/objects/pack/${filename}`; + const p = await readPackIndex({ + fs, + cache, + filename: indexFile, + getExternalRefDelta + }); + if (p.error) + throw new InternalError(p.error); + if (p.offsets.has(oid)) { + return true; + } + } + return false; +} +async function hasObject({ + fs, + cache, + gitdir, + oid, + format = "content" +}) { + const getExternalRefDelta = (oid2) => _readObject({ fs, cache, gitdir, oid: oid2 }); + let result = await hasObjectLoose({ fs, gitdir, oid }); + if (!result) { + result = await hasObjectPacked({ + fs, + cache, + gitdir, + oid, + getExternalRefDelta + }); + } + return result; +} +function emptyPackfile(pack) { + const pheader = "5041434b"; + const version2 = "00000002"; + const obCount = "00000000"; + const header = pheader + version2 + obCount; + return pack.slice(0, 12).toString("hex") === header; +} +function filterCapabilities(server, client) { + const serverNames = server.map((cap) => cap.split("=", 1)[0]); + return client.filter((cap) => { + const name = cap.split("=", 1)[0]; + return serverNames.includes(name); + }); +} +var pkg = { + name: "isomorphic-git", + version: "1.23.0", + agent: "git/isomorphic-git@1.23.0" +}; +var FIFO = class { + constructor() { + this._queue = []; + } + write(chunk) { + if (this._ended) { + throw Error("You cannot write to a FIFO that has already been ended!"); + } + if (this._waiting) { + const resolve = this._waiting; + this._waiting = null; + resolve({ value: chunk }); + } else { + this._queue.push(chunk); + } + } + end() { + this._ended = true; + if (this._waiting) { + const resolve = this._waiting; + this._waiting = null; + resolve({ done: true }); + } + } + destroy(err) { + this._ended = true; + this.error = err; + } + async next() { + if (this._queue.length > 0) { + return { value: this._queue.shift() }; + } + if (this._ended) { + return { done: true }; + } + if (this._waiting) { + throw Error( + "You cannot call read until the previous call to read has returned!" + ); + } + return new Promise((resolve) => { + this._waiting = resolve; + }); + } +}; +function findSplit(str) { + const r = str.indexOf("\r"); + const n = str.indexOf("\n"); + if (r === -1 && n === -1) + return -1; + if (r === -1) + return n + 1; + if (n === -1) + return r + 1; + if (n === r + 1) + return n + 1; + return Math.min(r, n) + 1; +} +function splitLines(input) { + const output = new FIFO(); + let tmp = ""; + (async () => { + await forAwait(input, (chunk) => { + chunk = chunk.toString("utf8"); + tmp += chunk; + while (true) { + const i = findSplit(tmp); + if (i === -1) + break; + output.write(tmp.slice(0, i)); + tmp = tmp.slice(i); + } + }); + if (tmp.length > 0) { + output.write(tmp); + } + output.end(); + })(); + return output; +} +var GitSideBand = class { + static demux(input) { + const read = GitPktLine.streamReader(input); + const packetlines = new FIFO(); + const packfile = new FIFO(); + const progress = new FIFO(); + const nextBit = async function() { + const line = await read(); + if (line === null) + return nextBit(); + if (line === true) { + packetlines.end(); + progress.end(); + packfile.end(); + return; + } + switch (line[0]) { + case 1: { + packfile.write(line.slice(1)); + break; + } + case 2: { + progress.write(line.slice(1)); + break; + } + case 3: { + const error = line.slice(1); + progress.write(error); + packfile.destroy(new Error(error.toString("utf8"))); + return; + } + default: { + packetlines.write(line.slice(0)); + } + } + nextBit(); + }; + nextBit(); + return { + packetlines, + packfile, + progress + }; + } + // static mux ({ + // protocol, // 'side-band' or 'side-band-64k' + // packetlines, + // packfile, + // progress, + // error + // }) { + // const MAX_PACKET_LENGTH = protocol === 'side-band-64k' ? 999 : 65519 + // let output = new PassThrough() + // packetlines.on('data', data => { + // if (data === null) { + // output.write(GitPktLine.flush()) + // } else { + // output.write(GitPktLine.encode(data)) + // } + // }) + // let packfileWasEmpty = true + // let packfileEnded = false + // let progressEnded = false + // let errorEnded = false + // let goodbye = Buffer.concat([ + // GitPktLine.encode(Buffer.from('010A', 'hex')), + // GitPktLine.flush() + // ]) + // packfile + // .on('data', data => { + // packfileWasEmpty = false + // const buffers = splitBuffer(data, MAX_PACKET_LENGTH) + // for (const buffer of buffers) { + // output.write( + // GitPktLine.encode(Buffer.concat([Buffer.from('01', 'hex'), buffer])) + // ) + // } + // }) + // .on('end', () => { + // packfileEnded = true + // if (!packfileWasEmpty) output.write(goodbye) + // if (progressEnded && errorEnded) output.end() + // }) + // progress + // .on('data', data => { + // const buffers = splitBuffer(data, MAX_PACKET_LENGTH) + // for (const buffer of buffers) { + // output.write( + // GitPktLine.encode(Buffer.concat([Buffer.from('02', 'hex'), buffer])) + // ) + // } + // }) + // .on('end', () => { + // progressEnded = true + // if (packfileEnded && errorEnded) output.end() + // }) + // error + // .on('data', data => { + // const buffers = splitBuffer(data, MAX_PACKET_LENGTH) + // for (const buffer of buffers) { + // output.write( + // GitPktLine.encode(Buffer.concat([Buffer.from('03', 'hex'), buffer])) + // ) + // } + // }) + // .on('end', () => { + // errorEnded = true + // if (progressEnded && packfileEnded) output.end() + // }) + // return output + // } +}; +async function parseUploadPackResponse(stream) { + const { packetlines, packfile, progress } = GitSideBand.demux(stream); + const shallows = []; + const unshallows = []; + const acks = []; + let nak = false; + let done = false; + return new Promise((resolve, reject) => { + forAwait(packetlines, (data) => { + const line = data.toString("utf8").trim(); + if (line.startsWith("shallow")) { + const oid = line.slice(-41).trim(); + if (oid.length !== 40) { + reject(new InvalidOidError(oid)); + } + shallows.push(oid); + } else if (line.startsWith("unshallow")) { + const oid = line.slice(-41).trim(); + if (oid.length !== 40) { + reject(new InvalidOidError(oid)); + } + unshallows.push(oid); + } else if (line.startsWith("ACK")) { + const [, oid, status2] = line.split(" "); + acks.push({ oid, status: status2 }); + if (!status2) + done = true; + } else if (line.startsWith("NAK")) { + nak = true; + done = true; + } + if (done) { + resolve({ shallows, unshallows, acks, nak, packfile, progress }); + } + }); + }); +} +function writeUploadPackRequest({ + capabilities = [], + wants = [], + haves = [], + shallows = [], + depth = null, + since = null, + exclude = [] +}) { + const packstream = []; + wants = [...new Set(wants)]; + let firstLineCapabilities = ` ${capabilities.join(" ")}`; + for (const oid of wants) { + packstream.push(GitPktLine.encode(`want ${oid}${firstLineCapabilities} +`)); + firstLineCapabilities = ""; + } + for (const oid of shallows) { + packstream.push(GitPktLine.encode(`shallow ${oid} +`)); + } + if (depth !== null) { + packstream.push(GitPktLine.encode(`deepen ${depth} +`)); + } + if (since !== null) { + packstream.push( + GitPktLine.encode(`deepen-since ${Math.floor(since.valueOf() / 1e3)} +`) + ); + } + for (const oid of exclude) { + packstream.push(GitPktLine.encode(`deepen-not ${oid} +`)); + } + packstream.push(GitPktLine.flush()); + for (const oid of haves) { + packstream.push(GitPktLine.encode(`have ${oid} +`)); + } + packstream.push(GitPktLine.encode(`done +`)); + return packstream; +} +async function _fetch({ + fs, + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + gitdir, + ref: _ref, + remoteRef: _remoteRef, + remote: _remote, + url: _url, + corsProxy, + depth = null, + since = null, + exclude = [], + relative: relative2 = false, + tags = false, + singleBranch = false, + headers = {}, + prune = false, + pruneTags = false +}) { + const ref = _ref || await _currentBranch({ fs, gitdir, test: true }); + const config = await GitConfigManager.get({ fs, gitdir }); + const remote = _remote || ref && await config.get(`branch.${ref}.remote`) || "origin"; + const url = _url || await config.get(`remote.${remote}.url`); + if (typeof url === "undefined") { + throw new MissingParameterError("remote OR url"); + } + const remoteRef = _remoteRef || ref && await config.get(`branch.${ref}.merge`) || _ref || "HEAD"; + if (corsProxy === void 0) { + corsProxy = await config.get("http.corsProxy"); + } + const GitRemoteHTTP2 = GitRemoteManager.getRemoteHelperFor({ url }); + const remoteHTTP = await GitRemoteHTTP2.discover({ + http, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + service: "git-upload-pack", + url, + headers, + protocolVersion: 1 + }); + const auth = remoteHTTP.auth; + const remoteRefs = remoteHTTP.refs; + if (remoteRefs.size === 0) { + return { + defaultBranch: null, + fetchHead: null, + fetchHeadDescription: null + }; + } + if (depth !== null && !remoteHTTP.capabilities.has("shallow")) { + throw new RemoteCapabilityError("shallow", "depth"); + } + if (since !== null && !remoteHTTP.capabilities.has("deepen-since")) { + throw new RemoteCapabilityError("deepen-since", "since"); + } + if (exclude.length > 0 && !remoteHTTP.capabilities.has("deepen-not")) { + throw new RemoteCapabilityError("deepen-not", "exclude"); + } + if (relative2 === true && !remoteHTTP.capabilities.has("deepen-relative")) { + throw new RemoteCapabilityError("deepen-relative", "relative"); + } + const { oid, fullref } = GitRefManager.resolveAgainstMap({ + ref: remoteRef, + map: remoteRefs + }); + for (const remoteRef2 of remoteRefs.keys()) { + if (remoteRef2 === fullref || remoteRef2 === "HEAD" || remoteRef2.startsWith("refs/heads/") || tags && remoteRef2.startsWith("refs/tags/")) { + continue; + } + remoteRefs.delete(remoteRef2); + } + const capabilities = filterCapabilities( + [...remoteHTTP.capabilities], + [ + "multi_ack_detailed", + "no-done", + "side-band-64k", + // Note: I removed 'thin-pack' option since our code doesn't "fatten" packfiles, + // which is necessary for compatibility with git. It was the cause of mysterious + // 'fatal: pack has [x] unresolved deltas' errors that plagued us for some time. + // isomorphic-git is perfectly happy with thin packfiles in .git/objects/pack but + // canonical git it turns out is NOT. + "ofs-delta", + `agent=${pkg.agent}` + ] + ); + if (relative2) + capabilities.push("deepen-relative"); + const wants = singleBranch ? [oid] : remoteRefs.values(); + const haveRefs = singleBranch ? [ref] : await GitRefManager.listRefs({ + fs, + gitdir, + filepath: `refs` + }); + let haves = []; + for (let ref2 of haveRefs) { + try { + ref2 = await GitRefManager.expand({ fs, gitdir, ref: ref2 }); + const oid2 = await GitRefManager.resolve({ fs, gitdir, ref: ref2 }); + if (await hasObject({ fs, cache, gitdir, oid: oid2 })) { + haves.push(oid2); + } + } catch (err) { + } + } + haves = [...new Set(haves)]; + const oids = await GitShallowManager.read({ fs, gitdir }); + const shallows = remoteHTTP.capabilities.has("shallow") ? [...oids] : []; + const packstream = writeUploadPackRequest({ + capabilities, + wants, + haves, + shallows, + depth, + since, + exclude + }); + const packbuffer = Buffer.from(await collect(packstream)); + const raw = await GitRemoteHTTP2.connect({ + http, + onProgress, + corsProxy, + service: "git-upload-pack", + url, + auth, + body: [packbuffer], + headers + }); + const response = await parseUploadPackResponse(raw.body); + if (raw.headers) { + response.headers = raw.headers; + } + for (const oid2 of response.shallows) { + if (!oids.has(oid2)) { + try { + const { object } = await _readObject({ fs, cache, gitdir, oid: oid2 }); + const commit2 = new GitCommit(object); + const hasParents = await Promise.all( + commit2.headers().parent.map((oid3) => hasObject({ fs, cache, gitdir, oid: oid3 })) + ); + const haveAllParents = hasParents.length === 0 || hasParents.every((has) => has); + if (!haveAllParents) { + oids.add(oid2); + } + } catch (err) { + oids.add(oid2); + } + } + } + for (const oid2 of response.unshallows) { + oids.delete(oid2); + } + await GitShallowManager.write({ fs, gitdir, oids }); + if (singleBranch) { + const refs = /* @__PURE__ */ new Map([[fullref, oid]]); + const symrefs = /* @__PURE__ */ new Map(); + let bail = 10; + let key2 = fullref; + while (bail--) { + const value = remoteHTTP.symrefs.get(key2); + if (value === void 0) + break; + symrefs.set(key2, value); + key2 = value; + } + const realRef = remoteRefs.get(key2); + if (realRef) { + refs.set(key2, realRef); + } + const { pruned } = await GitRefManager.updateRemoteRefs({ + fs, + gitdir, + remote, + refs, + symrefs, + tags, + prune + }); + if (prune) { + response.pruned = pruned; + } + } else { + const { pruned } = await GitRefManager.updateRemoteRefs({ + fs, + gitdir, + remote, + refs: remoteRefs, + symrefs: remoteHTTP.symrefs, + tags, + prune, + pruneTags + }); + if (prune) { + response.pruned = pruned; + } + } + response.HEAD = remoteHTTP.symrefs.get("HEAD"); + if (response.HEAD === void 0) { + const { oid: oid2 } = GitRefManager.resolveAgainstMap({ + ref: "HEAD", + map: remoteRefs + }); + for (const [key2, value] of remoteRefs.entries()) { + if (key2 !== "HEAD" && value === oid2) { + response.HEAD = key2; + break; + } + } + } + const noun = fullref.startsWith("refs/tags") ? "tag" : "branch"; + response.FETCH_HEAD = { + oid, + description: `${noun} '${abbreviateRef(fullref)}' of ${url}` + }; + if (onProgress || onMessage) { + const lines = splitLines(response.progress); + forAwait(lines, async (line) => { + if (onMessage) + await onMessage(line); + if (onProgress) { + const matches = line.match(/([^:]*).*\((\d+?)\/(\d+?)\)/); + if (matches) { + await onProgress({ + phase: matches[1].trim(), + loaded: parseInt(matches[2], 10), + total: parseInt(matches[3], 10) + }); + } + } + }); + } + const packfile = Buffer.from(await collect(response.packfile)); + const packfileSha = packfile.slice(-20).toString("hex"); + const res = { + defaultBranch: response.HEAD, + fetchHead: response.FETCH_HEAD.oid, + fetchHeadDescription: response.FETCH_HEAD.description + }; + if (response.headers) { + res.headers = response.headers; + } + if (prune) { + res.pruned = response.pruned; + } + if (packfileSha !== "" && !emptyPackfile(packfile)) { + res.packfile = `objects/pack/pack-${packfileSha}.pack`; + const fullpath = join(gitdir, res.packfile); + await fs.write(fullpath, packfile); + const getExternalRefDelta = (oid2) => _readObject({ fs, cache, gitdir, oid: oid2 }); + const idx = await GitPackIndex.fromPack({ + pack: packfile, + getExternalRefDelta, + onProgress + }); + await fs.write(fullpath.replace(/\.pack$/, ".idx"), await idx.toBuffer()); + } + return res; +} +async function _init({ + fs, + bare = false, + dir, + gitdir = bare ? dir : join(dir, ".git"), + defaultBranch = "master" +}) { + if (await fs.exists(gitdir + "/config")) + return; + let folders = [ + "hooks", + "info", + "objects/info", + "objects/pack", + "refs/heads", + "refs/tags" + ]; + folders = folders.map((dir2) => gitdir + "/" + dir2); + for (const folder of folders) { + await fs.mkdir(folder); + } + await fs.write( + gitdir + "/config", + `[core] + repositoryformatversion = 0 + filemode = false + bare = ${bare} +` + (bare ? "" : " logallrefupdates = true\n") + " symlinks = false\n ignorecase = true\n" + ); + await fs.write(gitdir + "/HEAD", `ref: refs/heads/${defaultBranch} +`); +} +async function _clone({ + fs, + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir, + url, + corsProxy, + ref, + remote, + depth, + since, + exclude, + relative: relative2, + singleBranch, + noCheckout, + noTags, + headers +}) { + try { + await _init({ fs, gitdir }); + await _addRemote({ fs, gitdir, remote, url, force: false }); + if (corsProxy) { + const config = await GitConfigManager.get({ fs, gitdir }); + await config.set(`http.corsProxy`, corsProxy); + await GitConfigManager.save({ fs, gitdir, config }); + } + const { defaultBranch, fetchHead } = await _fetch({ + fs, + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + gitdir, + ref, + remote, + corsProxy, + depth, + since, + exclude, + relative: relative2, + singleBranch, + headers, + tags: !noTags + }); + if (fetchHead === null) + return; + ref = ref || defaultBranch; + ref = ref.replace("refs/heads/", ""); + await _checkout({ + fs, + cache, + onProgress, + dir, + gitdir, + ref, + remote, + noCheckout + }); + } catch (err) { + await fs.rmdir(gitdir, { recursive: true, maxRetries: 10 }).catch(() => void 0); + throw err; + } +} +async function clone({ + fs, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir = join(dir, ".git"), + url, + corsProxy = void 0, + ref = void 0, + remote = "origin", + depth = void 0, + since = void 0, + exclude = [], + relative: relative2 = false, + singleBranch = false, + noCheckout = false, + noTags = false, + headers = {}, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("http", http); + assertParameter("gitdir", gitdir); + if (!noCheckout) { + assertParameter("dir", dir); + } + assertParameter("url", url); + return await _clone({ + fs: new FileSystem(fs), + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir, + url, + corsProxy, + ref, + remote, + depth, + since, + exclude, + relative: relative2, + singleBranch, + noCheckout, + noTags, + headers + }); + } catch (err) { + err.caller = "git.clone"; + throw err; + } +} +async function commit({ + fs: _fs, + onSign, + dir, + gitdir = join(dir, ".git"), + message, + author: _author, + committer: _committer, + signingKey, + dryRun = false, + noUpdateBranch = false, + ref, + parent, + tree, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("message", message); + if (signingKey) { + assertParameter("onSign", onSign); + } + const fs = new FileSystem(_fs); + const author = await normalizeAuthorObject({ fs, gitdir, author: _author }); + if (!author) + throw new MissingNameError("author"); + const committer = await normalizeCommitterObject({ + fs, + gitdir, + author, + committer: _committer + }); + if (!committer) + throw new MissingNameError("committer"); + return await _commit({ + fs, + cache, + onSign, + gitdir, + message, + author, + committer, + signingKey, + dryRun, + noUpdateBranch, + ref, + parent, + tree + }); + } catch (err) { + err.caller = "git.commit"; + throw err; + } +} +async function currentBranch({ + fs, + dir, + gitdir = join(dir, ".git"), + fullname = false, + test = false +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + return await _currentBranch({ + fs: new FileSystem(fs), + gitdir, + fullname, + test + }); + } catch (err) { + err.caller = "git.currentBranch"; + throw err; + } +} +async function _deleteBranch({ fs, gitdir, ref }) { + const exist = await GitRefManager.exists({ fs, gitdir, ref }); + if (!exist) { + throw new NotFoundError(ref); + } + const fullRef = await GitRefManager.expand({ fs, gitdir, ref }); + const currentRef = await _currentBranch({ fs, gitdir, fullname: true }); + if (fullRef === currentRef) { + const value = await GitRefManager.resolve({ fs, gitdir, ref: fullRef }); + await GitRefManager.writeRef({ fs, gitdir, ref: "HEAD", value }); + } + await GitRefManager.deleteRef({ fs, gitdir, ref: fullRef }); +} +async function deleteBranch({ + fs, + dir, + gitdir = join(dir, ".git"), + ref +}) { + try { + assertParameter("fs", fs); + assertParameter("ref", ref); + return await _deleteBranch({ + fs: new FileSystem(fs), + gitdir, + ref + }); + } catch (err) { + err.caller = "git.deleteBranch"; + throw err; + } +} +async function deleteRef({ fs, dir, gitdir = join(dir, ".git"), ref }) { + try { + assertParameter("fs", fs); + assertParameter("ref", ref); + await GitRefManager.deleteRef({ fs: new FileSystem(fs), gitdir, ref }); + } catch (err) { + err.caller = "git.deleteRef"; + throw err; + } +} +async function _deleteRemote({ fs, gitdir, remote }) { + const config = await GitConfigManager.get({ fs, gitdir }); + await config.deleteSection("remote", remote); + await GitConfigManager.save({ fs, gitdir, config }); +} +async function deleteRemote({ + fs, + dir, + gitdir = join(dir, ".git"), + remote +}) { + try { + assertParameter("fs", fs); + assertParameter("remote", remote); + return await _deleteRemote({ + fs: new FileSystem(fs), + gitdir, + remote + }); + } catch (err) { + err.caller = "git.deleteRemote"; + throw err; + } +} +async function _deleteTag({ fs, gitdir, ref }) { + ref = ref.startsWith("refs/tags/") ? ref : `refs/tags/${ref}`; + await GitRefManager.deleteRef({ fs, gitdir, ref }); +} +async function deleteTag({ fs, dir, gitdir = join(dir, ".git"), ref }) { + try { + assertParameter("fs", fs); + assertParameter("ref", ref); + return await _deleteTag({ + fs: new FileSystem(fs), + gitdir, + ref + }); + } catch (err) { + err.caller = "git.deleteTag"; + throw err; + } +} +async function expandOidLoose({ fs, gitdir, oid: short }) { + const prefix = short.slice(0, 2); + const objectsSuffixes = await fs.readdir(`${gitdir}/objects/${prefix}`); + return objectsSuffixes.map((suffix) => `${prefix}${suffix}`).filter((_oid) => _oid.startsWith(short)); +} +async function expandOidPacked({ + fs, + cache, + gitdir, + oid: short, + getExternalRefDelta +}) { + const results = []; + let list = await fs.readdir(join(gitdir, "objects/pack")); + list = list.filter((x) => x.endsWith(".idx")); + for (const filename of list) { + const indexFile = `${gitdir}/objects/pack/${filename}`; + const p = await readPackIndex({ + fs, + cache, + filename: indexFile, + getExternalRefDelta + }); + if (p.error) + throw new InternalError(p.error); + for (const oid of p.offsets.keys()) { + if (oid.startsWith(short)) + results.push(oid); + } + } + return results; +} +async function _expandOid({ fs, cache, gitdir, oid: short }) { + const getExternalRefDelta = (oid) => _readObject({ fs, cache, gitdir, oid }); + const results1 = await expandOidLoose({ fs, gitdir, oid: short }); + const results2 = await expandOidPacked({ + fs, + cache, + gitdir, + oid: short, + getExternalRefDelta + }); + const results = results1.concat(results2); + if (results.length === 1) { + return results[0]; + } + if (results.length > 1) { + throw new AmbiguousError("oids", short, results); + } + throw new NotFoundError(`an object matching "${short}"`); +} +async function expandOid({ + fs, + dir, + gitdir = join(dir, ".git"), + oid, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + return await _expandOid({ + fs: new FileSystem(fs), + cache, + gitdir, + oid + }); + } catch (err) { + err.caller = "git.expandOid"; + throw err; + } +} +async function expandRef({ fs, dir, gitdir = join(dir, ".git"), ref }) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + return await GitRefManager.expand({ + fs: new FileSystem(fs), + gitdir, + ref + }); + } catch (err) { + err.caller = "git.expandRef"; + throw err; + } +} +async function _findMergeBase({ fs, cache, gitdir, oids }) { + const visits = {}; + const passes = oids.length; + let heads = oids.map((oid, index2) => ({ index: index2, oid })); + while (heads.length) { + const result = /* @__PURE__ */ new Set(); + for (const { oid, index: index2 } of heads) { + if (!visits[oid]) + visits[oid] = /* @__PURE__ */ new Set(); + visits[oid].add(index2); + if (visits[oid].size === passes) { + result.add(oid); + } + } + if (result.size > 0) { + return [...result]; + } + const newheads = /* @__PURE__ */ new Map(); + for (const { oid, index: index2 } of heads) { + try { + const { object } = await _readObject({ fs, cache, gitdir, oid }); + const commit2 = GitCommit.from(object); + const { parent } = commit2.parseHeaders(); + for (const oid2 of parent) { + if (!visits[oid2] || !visits[oid2].has(index2)) { + newheads.set(oid2 + ":" + index2, { oid: oid2, index: index2 }); + } + } + } catch (err) { + } + } + heads = Array.from(newheads.values()); + } + return []; +} +var LINEBREAKS = /^.*(\r?\n|$)/gm; +function mergeFile({ branches, contents }) { + const ourName = branches[1]; + const theirName = branches[2]; + const baseContent = contents[0]; + const ourContent = contents[1]; + const theirContent = contents[2]; + const ours = ourContent.match(LINEBREAKS); + const base = baseContent.match(LINEBREAKS); + const theirs = theirContent.match(LINEBREAKS); + const result = (0, import_diff3.default)(ours, base, theirs); + const markerSize = 7; + let mergedText = ""; + let cleanMerge = true; + for (const item of result) { + if (item.ok) { + mergedText += item.ok.join(""); + } + if (item.conflict) { + cleanMerge = false; + mergedText += `${"<".repeat(markerSize)} ${ourName} +`; + mergedText += item.conflict.a.join(""); + mergedText += `${"=".repeat(markerSize)} +`; + mergedText += item.conflict.b.join(""); + mergedText += `${">".repeat(markerSize)} ${theirName} +`; + } + } + return { cleanMerge, mergedText }; +} +async function mergeTree({ + fs, + cache, + dir, + gitdir = join(dir, ".git"), + index: index2, + ourOid, + baseOid, + theirOid, + ourName = "ours", + baseName = "base", + theirName = "theirs", + dryRun = false, + abortOnConflict = true, + mergeDriver +}) { + const ourTree = TREE({ ref: ourOid }); + const baseTree = TREE({ ref: baseOid }); + const theirTree = TREE({ ref: theirOid }); + const unmergedFiles = []; + const results = await _walk({ + fs, + cache, + dir, + gitdir, + trees: [ourTree, baseTree, theirTree], + map: async function(filepath, [ours, base, theirs]) { + const path2 = basename(filepath); + const ourChange = await modified(ours, base); + const theirChange = await modified(theirs, base); + switch (`${ourChange}-${theirChange}`) { + case "false-false": { + return { + mode: await base.mode(), + path: path2, + oid: await base.oid(), + type: await base.type() + }; + } + case "false-true": { + return theirs ? { + mode: await theirs.mode(), + path: path2, + oid: await theirs.oid(), + type: await theirs.type() + } : void 0; + } + case "true-false": { + return ours ? { + mode: await ours.mode(), + path: path2, + oid: await ours.oid(), + type: await ours.type() + } : void 0; + } + case "true-true": { + if (ours && base && theirs && await ours.type() === "blob" && await base.type() === "blob" && await theirs.type() === "blob") { + return mergeBlobs({ + fs, + gitdir, + path: path2, + ours, + base, + theirs, + ourName, + baseName, + theirName, + mergeDriver + }).then(async (r) => { + if (!r.cleanMerge) { + unmergedFiles.push(filepath); + if (!abortOnConflict) { + const baseOid2 = await base.oid(); + const ourOid2 = await ours.oid(); + const theirOid2 = await theirs.oid(); + index2.delete({ filepath }); + index2.insert({ filepath, oid: baseOid2, stage: 1 }); + index2.insert({ filepath, oid: ourOid2, stage: 2 }); + index2.insert({ filepath, oid: theirOid2, stage: 3 }); + } + } else if (!abortOnConflict) { + index2.insert({ filepath, oid: r.mergeResult.oid, stage: 0 }); + } + return r.mergeResult; + }); + } + throw new MergeNotSupportedError(); + } + } + }, + /** + * @param {TreeEntry} [parent] + * @param {Array} children + */ + reduce: unmergedFiles.length !== 0 && (!dir || abortOnConflict) ? void 0 : async (parent, children2) => { + const entries = children2.filter(Boolean); + if (!parent) + return; + if (parent && parent.type === "tree" && entries.length === 0) + return; + if (entries.length > 0) { + const tree = new GitTree(entries); + const object = tree.toObject(); + const oid = await _writeObject({ + fs, + gitdir, + type: "tree", + object, + dryRun + }); + parent.oid = oid; + } + return parent; + } + }); + if (unmergedFiles.length !== 0) { + if (dir && !abortOnConflict) { + await _walk({ + fs, + cache, + dir, + gitdir, + trees: [TREE({ ref: results.oid })], + map: async function(filepath, [entry]) { + const path2 = `${dir}/${filepath}`; + if (await entry.type() === "blob") { + const mode = await entry.mode(); + const content = new TextDecoder().decode(await entry.content()); + await fs.write(path2, content, { mode }); + } + return true; + } + }); + } + return new MergeConflictError(unmergedFiles); + } + return results.oid; +} +async function mergeBlobs({ + fs, + gitdir, + path: path2, + ours, + base, + theirs, + ourName, + theirName, + baseName, + dryRun, + mergeDriver = mergeFile +}) { + const type = "blob"; + const mode = await base.mode() === await ours.mode() ? await theirs.mode() : await ours.mode(); + if (await ours.oid() === await theirs.oid()) { + return { + cleanMerge: true, + mergeResult: { mode, path: path2, oid: await ours.oid(), type } + }; + } + if (await ours.oid() === await base.oid()) { + return { + cleanMerge: true, + mergeResult: { mode, path: path2, oid: await theirs.oid(), type } + }; + } + if (await theirs.oid() === await base.oid()) { + return { + cleanMerge: true, + mergeResult: { mode, path: path2, oid: await ours.oid(), type } + }; + } + const ourContent = Buffer.from(await ours.content()).toString("utf8"); + const baseContent = Buffer.from(await base.content()).toString("utf8"); + const theirContent = Buffer.from(await theirs.content()).toString("utf8"); + const { mergedText, cleanMerge } = await mergeDriver({ + branches: [baseName, ourName, theirName], + contents: [baseContent, ourContent, theirContent], + path: path2 + }); + const oid = await _writeObject({ + fs, + gitdir, + type: "blob", + object: Buffer.from(mergedText, "utf8"), + dryRun + }); + return { cleanMerge, mergeResult: { mode, path: path2, oid, type } }; +} +async function _merge({ + fs, + cache, + dir, + gitdir, + ours, + theirs, + fastForward: fastForward2 = true, + fastForwardOnly = false, + dryRun = false, + noUpdateBranch = false, + abortOnConflict = true, + message, + author, + committer, + signingKey, + onSign, + mergeDriver +}) { + if (ours === void 0) { + ours = await _currentBranch({ fs, gitdir, fullname: true }); + } + ours = await GitRefManager.expand({ + fs, + gitdir, + ref: ours + }); + theirs = await GitRefManager.expand({ + fs, + gitdir, + ref: theirs + }); + const ourOid = await GitRefManager.resolve({ + fs, + gitdir, + ref: ours + }); + const theirOid = await GitRefManager.resolve({ + fs, + gitdir, + ref: theirs + }); + const baseOids = await _findMergeBase({ + fs, + cache, + gitdir, + oids: [ourOid, theirOid] + }); + if (baseOids.length !== 1) { + throw new MergeNotSupportedError(); + } + const baseOid = baseOids[0]; + if (baseOid === theirOid) { + return { + oid: ourOid, + alreadyMerged: true + }; + } + if (fastForward2 && baseOid === ourOid) { + if (!dryRun && !noUpdateBranch) { + await GitRefManager.writeRef({ fs, gitdir, ref: ours, value: theirOid }); + } + return { + oid: theirOid, + fastForward: true + }; + } else { + if (fastForwardOnly) { + throw new FastForwardError(); + } + const tree = await GitIndexManager.acquire( + { fs, gitdir, cache, allowUnmerged: false }, + async (index2) => { + return mergeTree({ + fs, + cache, + dir, + gitdir, + index: index2, + ourOid, + theirOid, + baseOid, + ourName: abbreviateRef(ours), + baseName: "base", + theirName: abbreviateRef(theirs), + dryRun, + abortOnConflict, + mergeDriver + }); + } + ); + if (tree instanceof MergeConflictError) + throw tree; + if (!message) { + message = `Merge branch '${abbreviateRef(theirs)}' into ${abbreviateRef( + ours + )}`; + } + const oid = await _commit({ + fs, + cache, + gitdir, + message, + ref: ours, + tree, + parent: [ourOid, theirOid], + author, + committer, + signingKey, + onSign, + dryRun, + noUpdateBranch + }); + return { + oid, + tree, + mergeCommit: true + }; + } +} +async function _pull({ + fs, + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir, + ref, + url, + remote, + remoteRef, + prune, + pruneTags, + fastForward: fastForward2, + fastForwardOnly, + corsProxy, + singleBranch, + headers, + author, + committer, + signingKey +}) { + try { + if (!ref) { + const head = await _currentBranch({ fs, gitdir }); + if (!head) { + throw new MissingParameterError("ref"); + } + ref = head; + } + const { fetchHead, fetchHeadDescription } = await _fetch({ + fs, + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + gitdir, + corsProxy, + ref, + url, + remote, + remoteRef, + singleBranch, + headers, + prune, + pruneTags + }); + await _merge({ + fs, + cache, + gitdir, + ours: ref, + theirs: fetchHead, + fastForward: fastForward2, + fastForwardOnly, + message: `Merge ${fetchHeadDescription}`, + author, + committer, + signingKey, + dryRun: false, + noUpdateBranch: false + }); + await _checkout({ + fs, + cache, + onProgress, + dir, + gitdir, + ref, + remote, + noCheckout: false + }); + } catch (err) { + err.caller = "git.pull"; + throw err; + } +} +async function fastForward({ + fs, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir = join(dir, ".git"), + ref, + url, + remote, + remoteRef, + corsProxy, + singleBranch, + headers = {}, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("http", http); + assertParameter("gitdir", gitdir); + const thisWillNotBeUsed = { + name: "", + email: "", + timestamp: Date.now(), + timezoneOffset: 0 + }; + return await _pull({ + fs: new FileSystem(fs), + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir, + ref, + url, + remote, + remoteRef, + fastForwardOnly: true, + corsProxy, + singleBranch, + headers, + author: thisWillNotBeUsed, + committer: thisWillNotBeUsed + }); + } catch (err) { + err.caller = "git.fastForward"; + throw err; + } +} +async function fetch({ + fs, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir = join(dir, ".git"), + ref, + remote, + remoteRef, + url, + corsProxy, + depth = null, + since = null, + exclude = [], + relative: relative2 = false, + tags = false, + singleBranch = false, + headers = {}, + prune = false, + pruneTags = false, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("http", http); + assertParameter("gitdir", gitdir); + return await _fetch({ + fs: new FileSystem(fs), + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + gitdir, + ref, + remote, + remoteRef, + url, + corsProxy, + depth, + since, + exclude, + relative: relative2, + tags, + singleBranch, + headers, + prune, + pruneTags + }); + } catch (err) { + err.caller = "git.fetch"; + throw err; + } +} +async function findMergeBase({ + fs, + dir, + gitdir = join(dir, ".git"), + oids, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("oids", oids); + return await _findMergeBase({ + fs: new FileSystem(fs), + cache, + gitdir, + oids + }); + } catch (err) { + err.caller = "git.findMergeBase"; + throw err; + } +} +async function _findRoot({ fs, filepath }) { + if (await fs.exists(join(filepath, ".git"))) { + return filepath; + } else { + const parent = dirname(filepath); + if (parent === filepath) { + throw new NotFoundError(`git root for ${filepath}`); + } + return _findRoot({ fs, filepath: parent }); + } +} +async function findRoot({ fs, filepath }) { + try { + assertParameter("fs", fs); + assertParameter("filepath", filepath); + return await _findRoot({ fs: new FileSystem(fs), filepath }); + } catch (err) { + err.caller = "git.findRoot"; + throw err; + } +} +async function getConfig({ fs, dir, gitdir = join(dir, ".git"), path: path2 }) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("path", path2); + return await _getConfig({ + fs: new FileSystem(fs), + gitdir, + path: path2 + }); + } catch (err) { + err.caller = "git.getConfig"; + throw err; + } +} +async function _getConfigAll({ fs, gitdir, path: path2 }) { + const config = await GitConfigManager.get({ fs, gitdir }); + return config.getall(path2); +} +async function getConfigAll({ + fs, + dir, + gitdir = join(dir, ".git"), + path: path2 +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("path", path2); + return await _getConfigAll({ + fs: new FileSystem(fs), + gitdir, + path: path2 + }); + } catch (err) { + err.caller = "git.getConfigAll"; + throw err; + } +} +async function getRemoteInfo({ + http, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + url, + headers = {}, + forPush = false +}) { + try { + assertParameter("http", http); + assertParameter("url", url); + const GitRemoteHTTP2 = GitRemoteManager.getRemoteHelperFor({ url }); + const remote = await GitRemoteHTTP2.discover({ + http, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + service: forPush ? "git-receive-pack" : "git-upload-pack", + url, + headers, + protocolVersion: 1 + }); + const result = { + capabilities: [...remote.capabilities] + }; + for (const [ref, oid] of remote.refs) { + const parts = ref.split("/"); + const last2 = parts.pop(); + let o = result; + for (const part of parts) { + o[part] = o[part] || {}; + o = o[part]; + } + o[last2] = oid; + } + for (const [symref, ref] of remote.symrefs) { + const parts = symref.split("/"); + const last2 = parts.pop(); + let o = result; + for (const part of parts) { + o[part] = o[part] || {}; + o = o[part]; + } + o[last2] = ref; + } + return result; + } catch (err) { + err.caller = "git.getRemoteInfo"; + throw err; + } +} +function formatInfoRefs(remote, prefix, symrefs, peelTags) { + const refs = []; + for (const [key2, value] of remote.refs) { + if (prefix && !key2.startsWith(prefix)) + continue; + if (key2.endsWith("^{}")) { + if (peelTags) { + const _key = key2.replace("^{}", ""); + const last2 = refs[refs.length - 1]; + const r = last2.ref === _key ? last2 : refs.find((x) => x.ref === _key); + if (r === void 0) { + throw new Error("I did not expect this to happen"); + } + r.peeled = value; + } + continue; + } + const ref = { ref: key2, oid: value }; + if (symrefs) { + if (remote.symrefs.has(key2)) { + ref.target = remote.symrefs.get(key2); + } + } + refs.push(ref); + } + return refs; +} +async function getRemoteInfo2({ + http, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + url, + headers = {}, + forPush = false, + protocolVersion = 2 +}) { + try { + assertParameter("http", http); + assertParameter("url", url); + const GitRemoteHTTP2 = GitRemoteManager.getRemoteHelperFor({ url }); + const remote = await GitRemoteHTTP2.discover({ + http, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + service: forPush ? "git-receive-pack" : "git-upload-pack", + url, + headers, + protocolVersion + }); + if (remote.protocolVersion === 2) { + return { + protocolVersion: remote.protocolVersion, + capabilities: remote.capabilities2 + }; + } + const capabilities = {}; + for (const cap of remote.capabilities) { + const [key2, value] = cap.split("="); + if (value) { + capabilities[key2] = value; + } else { + capabilities[key2] = true; + } + } + return { + protocolVersion: 1, + capabilities, + refs: formatInfoRefs(remote, void 0, true, true) + }; + } catch (err) { + err.caller = "git.getRemoteInfo2"; + throw err; + } +} +async function hashObject({ + type, + object, + format = "content", + oid = void 0 +}) { + if (format !== "deflated") { + if (format !== "wrapped") { + object = GitObject.wrap({ type, object }); + } + oid = await shasum(object); + } + return { oid, object }; +} +async function hashBlob({ object }) { + try { + assertParameter("object", object); + if (typeof object === "string") { + object = Buffer.from(object, "utf8"); + } else { + object = Buffer.from(object); + } + const type = "blob"; + const { oid, object: _object } = await hashObject({ + type: "blob", + format: "content", + object + }); + return { oid, type, object: new Uint8Array(_object), format: "wrapped" }; + } catch (err) { + err.caller = "git.hashBlob"; + throw err; + } +} +async function _indexPack({ + fs, + cache, + onProgress, + dir, + gitdir, + filepath +}) { + try { + filepath = join(dir, filepath); + const pack = await fs.read(filepath); + const getExternalRefDelta = (oid) => _readObject({ fs, cache, gitdir, oid }); + const idx = await GitPackIndex.fromPack({ + pack, + getExternalRefDelta, + onProgress + }); + await fs.write(filepath.replace(/\.pack$/, ".idx"), await idx.toBuffer()); + return { + oids: [...idx.hashes] + }; + } catch (err) { + err.caller = "git.indexPack"; + throw err; + } +} +async function indexPack({ + fs, + onProgress, + dir, + gitdir = join(dir, ".git"), + filepath, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("dir", dir); + assertParameter("gitdir", dir); + assertParameter("filepath", filepath); + return await _indexPack({ + fs: new FileSystem(fs), + cache, + onProgress, + dir, + gitdir, + filepath + }); + } catch (err) { + err.caller = "git.indexPack"; + throw err; + } +} +async function init({ + fs, + bare = false, + dir, + gitdir = bare ? dir : join(dir, ".git"), + defaultBranch = "master" +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + if (!bare) { + assertParameter("dir", dir); + } + return await _init({ + fs: new FileSystem(fs), + bare, + dir, + gitdir, + defaultBranch + }); + } catch (err) { + err.caller = "git.init"; + throw err; + } +} +async function _isDescendent({ + fs, + cache, + gitdir, + oid, + ancestor, + depth +}) { + const shallows = await GitShallowManager.read({ fs, gitdir }); + if (!oid) { + throw new MissingParameterError("oid"); + } + if (!ancestor) { + throw new MissingParameterError("ancestor"); + } + if (oid === ancestor) + return false; + const queue = [oid]; + const visited = /* @__PURE__ */ new Set(); + let searchdepth = 0; + while (queue.length) { + if (searchdepth++ === depth) { + throw new MaxDepthError(depth); + } + const oid2 = queue.shift(); + const { type, object } = await _readObject({ + fs, + cache, + gitdir, + oid: oid2 + }); + if (type !== "commit") { + throw new ObjectTypeError(oid2, type, "commit"); + } + const commit2 = GitCommit.from(object).parse(); + for (const parent of commit2.parent) { + if (parent === ancestor) + return true; + } + if (!shallows.has(oid2)) { + for (const parent of commit2.parent) { + if (!visited.has(parent)) { + queue.push(parent); + visited.add(parent); + } + } + } + } + return false; +} +async function isDescendent({ + fs, + dir, + gitdir = join(dir, ".git"), + oid, + ancestor, + depth = -1, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + assertParameter("ancestor", ancestor); + return await _isDescendent({ + fs: new FileSystem(fs), + cache, + gitdir, + oid, + ancestor, + depth + }); + } catch (err) { + err.caller = "git.isDescendent"; + throw err; + } +} +async function isIgnored({ + fs, + dir, + gitdir = join(dir, ".git"), + filepath +}) { + try { + assertParameter("fs", fs); + assertParameter("dir", dir); + assertParameter("gitdir", gitdir); + assertParameter("filepath", filepath); + return GitIgnoreManager.isIgnored({ + fs: new FileSystem(fs), + dir, + gitdir, + filepath + }); + } catch (err) { + err.caller = "git.isIgnored"; + throw err; + } +} +async function listBranches({ + fs, + dir, + gitdir = join(dir, ".git"), + remote +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + return GitRefManager.listBranches({ + fs: new FileSystem(fs), + gitdir, + remote + }); + } catch (err) { + err.caller = "git.listBranches"; + throw err; + } +} +async function _listFiles({ fs, gitdir, ref, cache }) { + if (ref) { + const oid = await GitRefManager.resolve({ gitdir, fs, ref }); + const filenames = []; + await accumulateFilesFromOid({ + fs, + cache, + gitdir, + oid, + filenames, + prefix: "" + }); + return filenames; + } else { + return GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + return index2.entries.map((x) => x.path); + }); + } +} +async function accumulateFilesFromOid({ + fs, + cache, + gitdir, + oid, + filenames, + prefix +}) { + const { tree } = await _readTree({ fs, cache, gitdir, oid }); + for (const entry of tree) { + if (entry.type === "tree") { + await accumulateFilesFromOid({ + fs, + cache, + gitdir, + oid: entry.oid, + filenames, + prefix: join(prefix, entry.path) + }); + } else { + filenames.push(join(prefix, entry.path)); + } + } +} +async function listFiles({ + fs, + dir, + gitdir = join(dir, ".git"), + ref, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + return await _listFiles({ + fs: new FileSystem(fs), + cache, + gitdir, + ref + }); + } catch (err) { + err.caller = "git.listFiles"; + throw err; + } +} +async function _listNotes({ fs, cache, gitdir, ref }) { + let parent; + try { + parent = await GitRefManager.resolve({ gitdir, fs, ref }); + } catch (err) { + if (err instanceof NotFoundError) { + return []; + } + } + const result = await _readTree({ + fs, + cache, + gitdir, + oid: parent + }); + const notes = result.tree.map((entry) => ({ + target: entry.path, + note: entry.oid + })); + return notes; +} +async function listNotes({ + fs, + dir, + gitdir = join(dir, ".git"), + ref = "refs/notes/commits", + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + return await _listNotes({ + fs: new FileSystem(fs), + cache, + gitdir, + ref + }); + } catch (err) { + err.caller = "git.listNotes"; + throw err; + } +} +async function _listRemotes({ fs, gitdir }) { + const config = await GitConfigManager.get({ fs, gitdir }); + const remoteNames = await config.getSubsections("remote"); + const remotes = Promise.all( + remoteNames.map(async (remote) => { + const url = await config.get(`remote.${remote}.url`); + return { remote, url }; + }) + ); + return remotes; +} +async function listRemotes({ fs, dir, gitdir = join(dir, ".git") }) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + return await _listRemotes({ + fs: new FileSystem(fs), + gitdir + }); + } catch (err) { + err.caller = "git.listRemotes"; + throw err; + } +} +async function parseListRefsResponse(stream) { + const read = GitPktLine.streamReader(stream); + const refs = []; + let line; + while (true) { + line = await read(); + if (line === true) + break; + if (line === null) + continue; + line = line.toString("utf8").replace(/\n$/, ""); + const [oid, ref, ...attrs] = line.split(" "); + const r = { ref, oid }; + for (const attr2 of attrs) { + const [name, value] = attr2.split(":"); + if (name === "symref-target") { + r.target = value; + } else if (name === "peeled") { + r.peeled = value; + } + } + refs.push(r); + } + return refs; +} +async function writeListRefsRequest({ prefix, symrefs, peelTags }) { + const packstream = []; + packstream.push(GitPktLine.encode("command=ls-refs\n")); + packstream.push(GitPktLine.encode(`agent=${pkg.agent} +`)); + if (peelTags || symrefs || prefix) { + packstream.push(GitPktLine.delim()); + } + if (peelTags) + packstream.push(GitPktLine.encode("peel")); + if (symrefs) + packstream.push(GitPktLine.encode("symrefs")); + if (prefix) + packstream.push(GitPktLine.encode(`ref-prefix ${prefix}`)); + packstream.push(GitPktLine.flush()); + return packstream; +} +async function listServerRefs({ + http, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + url, + headers = {}, + forPush = false, + protocolVersion = 2, + prefix, + symrefs, + peelTags +}) { + try { + assertParameter("http", http); + assertParameter("url", url); + const remote = await GitRemoteHTTP.discover({ + http, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + service: forPush ? "git-receive-pack" : "git-upload-pack", + url, + headers, + protocolVersion + }); + if (remote.protocolVersion === 1) { + return formatInfoRefs(remote, prefix, symrefs, peelTags); + } + const body = await writeListRefsRequest({ prefix, symrefs, peelTags }); + const res = await GitRemoteHTTP.connect({ + http, + auth: remote.auth, + headers, + corsProxy, + service: forPush ? "git-receive-pack" : "git-upload-pack", + url, + body + }); + return parseListRefsResponse(res.body); + } catch (err) { + err.caller = "git.listServerRefs"; + throw err; + } +} +async function listTags({ fs, dir, gitdir = join(dir, ".git") }) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + return GitRefManager.listTags({ fs: new FileSystem(fs), gitdir }); + } catch (err) { + err.caller = "git.listTags"; + throw err; + } +} +async function resolveCommit({ fs, cache, gitdir, oid }) { + const { type, object } = await _readObject({ fs, cache, gitdir, oid }); + if (type === "tag") { + oid = GitAnnotatedTag.from(object).parse().object; + return resolveCommit({ fs, cache, gitdir, oid }); + } + if (type !== "commit") { + throw new ObjectTypeError(oid, type, "commit"); + } + return { commit: GitCommit.from(object), oid }; +} +async function _readCommit({ fs, cache, gitdir, oid }) { + const { commit: commit2, oid: commitOid } = await resolveCommit({ + fs, + cache, + gitdir, + oid + }); + const result = { + oid: commitOid, + commit: commit2.parse(), + payload: commit2.withoutSignature() + }; + return result; +} +function compareAge(a, b) { + return a.committer.timestamp - b.committer.timestamp; +} +var EMPTY_OID = "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"; +async function resolveFileIdInTree({ fs, cache, gitdir, oid, fileId }) { + if (fileId === EMPTY_OID) + return; + const _oid = oid; + let filepath; + const result = await resolveTree({ fs, cache, gitdir, oid }); + const tree = result.tree; + if (fileId === result.oid) { + filepath = result.path; + } else { + filepath = await _resolveFileId({ + fs, + cache, + gitdir, + tree, + fileId, + oid: _oid + }); + if (Array.isArray(filepath)) { + if (filepath.length === 0) + filepath = void 0; + else if (filepath.length === 1) + filepath = filepath[0]; + } + } + return filepath; +} +async function _resolveFileId({ + fs, + cache, + gitdir, + tree, + fileId, + oid, + filepaths = [], + parentPath = "" +}) { + const walks = tree.entries().map(function(entry) { + let result; + if (entry.oid === fileId) { + result = join(parentPath, entry.path); + filepaths.push(result); + } else if (entry.type === "tree") { + result = _readObject({ + fs, + cache, + gitdir, + oid: entry.oid + }).then(function({ object }) { + return _resolveFileId({ + fs, + cache, + gitdir, + tree: GitTree.from(object), + fileId, + oid, + filepaths, + parentPath: join(parentPath, entry.path) + }); + }); + } + return result; + }); + await Promise.all(walks); + return filepaths; +} +async function _log({ + fs, + cache, + gitdir, + filepath, + ref, + depth, + since, + force, + follow +}) { + const sinceTimestamp = typeof since === "undefined" ? void 0 : Math.floor(since.valueOf() / 1e3); + const commits = []; + const shallowCommits = await GitShallowManager.read({ fs, gitdir }); + const oid = await GitRefManager.resolve({ fs, gitdir, ref }); + const tips = [await _readCommit({ fs, cache, gitdir, oid })]; + let lastFileOid; + let lastCommit; + let isOk; + function endCommit(commit2) { + if (isOk && filepath) + commits.push(commit2); + } + while (tips.length > 0) { + const commit2 = tips.pop(); + if (sinceTimestamp !== void 0 && commit2.commit.committer.timestamp <= sinceTimestamp) { + break; + } + if (filepath) { + let vFileOid; + try { + vFileOid = await resolveFilepath({ + fs, + cache, + gitdir, + oid: commit2.commit.tree, + filepath + }); + if (lastCommit && lastFileOid !== vFileOid) { + commits.push(lastCommit); + } + lastFileOid = vFileOid; + lastCommit = commit2; + isOk = true; + } catch (e) { + if (e instanceof NotFoundError) { + let found = follow && lastFileOid; + if (found) { + found = await resolveFileIdInTree({ + fs, + cache, + gitdir, + oid: commit2.commit.tree, + fileId: lastFileOid + }); + if (found) { + if (Array.isArray(found)) { + if (lastCommit) { + const lastFound = await resolveFileIdInTree({ + fs, + cache, + gitdir, + oid: lastCommit.commit.tree, + fileId: lastFileOid + }); + if (Array.isArray(lastFound)) { + found = found.filter((p) => lastFound.indexOf(p) === -1); + if (found.length === 1) { + found = found[0]; + filepath = found; + if (lastCommit) + commits.push(lastCommit); + } else { + found = false; + if (lastCommit) + commits.push(lastCommit); + break; + } + } + } + } else { + filepath = found; + if (lastCommit) + commits.push(lastCommit); + } + } + } + if (!found) { + if (isOk && lastFileOid) { + commits.push(lastCommit); + if (!force) + break; + } + if (!force && !follow) + throw e; + } + lastCommit = commit2; + isOk = false; + } else + throw e; + } + } else { + commits.push(commit2); + } + if (depth !== void 0 && commits.length === depth) { + endCommit(commit2); + break; + } + if (!shallowCommits.has(commit2.oid)) { + for (const oid2 of commit2.commit.parent) { + const commit3 = await _readCommit({ fs, cache, gitdir, oid: oid2 }); + if (!tips.map((commit4) => commit4.oid).includes(commit3.oid)) { + tips.push(commit3); + } + } + } + if (tips.length === 0) { + endCommit(commit2); + } + tips.sort((a, b) => compareAge(a.commit, b.commit)); + } + return commits; +} +async function log({ + fs, + dir, + gitdir = join(dir, ".git"), + filepath, + ref = "HEAD", + depth, + since, + // Date + force, + follow, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + return await _log({ + fs: new FileSystem(fs), + cache, + gitdir, + filepath, + ref, + depth, + since, + force, + follow + }); + } catch (err) { + err.caller = "git.log"; + throw err; + } +} +async function merge({ + fs: _fs, + onSign, + dir, + gitdir = join(dir, ".git"), + ours, + theirs, + fastForward: fastForward2 = true, + fastForwardOnly = false, + dryRun = false, + noUpdateBranch = false, + abortOnConflict = true, + message, + author: _author, + committer: _committer, + signingKey, + cache = {}, + mergeDriver +}) { + try { + assertParameter("fs", _fs); + if (signingKey) { + assertParameter("onSign", onSign); + } + const fs = new FileSystem(_fs); + const author = await normalizeAuthorObject({ fs, gitdir, author: _author }); + if (!author && (!fastForwardOnly || !fastForward2)) { + throw new MissingNameError("author"); + } + const committer = await normalizeCommitterObject({ + fs, + gitdir, + author, + committer: _committer + }); + if (!committer && (!fastForwardOnly || !fastForward2)) { + throw new MissingNameError("committer"); + } + return await _merge({ + fs, + cache, + dir, + gitdir, + ours, + theirs, + fastForward: fastForward2, + fastForwardOnly, + dryRun, + noUpdateBranch, + abortOnConflict, + message, + author, + committer, + signingKey, + onSign, + mergeDriver + }); + } catch (err) { + err.caller = "git.merge"; + throw err; + } +} +var types = { + commit: 16, + tree: 32, + blob: 48, + tag: 64, + ofs_delta: 96, + ref_delta: 112 +}; +async function _pack({ + fs, + cache, + dir, + gitdir = join(dir, ".git"), + oids +}) { + const hash2 = new import_sha1.default(); + const outputStream = []; + function write(chunk, enc) { + const buff = Buffer.from(chunk, enc); + outputStream.push(buff); + hash2.update(buff); + } + async function writeObject2({ stype, object }) { + const type = types[stype]; + let length = object.length; + let multibyte = length > 15 ? 128 : 0; + const lastFour = length & 15; + length = length >>> 4; + let byte = (multibyte | type | lastFour).toString(16); + write(byte, "hex"); + while (multibyte) { + multibyte = length > 127 ? 128 : 0; + byte = multibyte | length & 127; + write(padHex(2, byte), "hex"); + length = length >>> 7; + } + write(Buffer.from(await deflate(object))); + } + write("PACK"); + write("00000002", "hex"); + write(padHex(8, oids.length), "hex"); + for (const oid of oids) { + const { type, object } = await _readObject({ fs, cache, gitdir, oid }); + await writeObject2({ write, object, stype: type }); + } + const digest = hash2.digest(); + outputStream.push(digest); + return outputStream; +} +async function _packObjects({ fs, cache, gitdir, oids, write }) { + const buffers = await _pack({ fs, cache, gitdir, oids }); + const packfile = Buffer.from(await collect(buffers)); + const packfileSha = packfile.slice(-20).toString("hex"); + const filename = `pack-${packfileSha}.pack`; + if (write) { + await fs.write(join(gitdir, `objects/pack/${filename}`), packfile); + return { filename }; + } + return { + filename, + packfile: new Uint8Array(packfile) + }; +} +async function packObjects({ + fs, + dir, + gitdir = join(dir, ".git"), + oids, + write = false, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("oids", oids); + return await _packObjects({ + fs: new FileSystem(fs), + cache, + gitdir, + oids, + write + }); + } catch (err) { + err.caller = "git.packObjects"; + throw err; + } +} +async function pull({ + fs: _fs, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir = join(dir, ".git"), + ref, + url, + remote, + remoteRef, + prune = false, + pruneTags = false, + fastForward: fastForward2 = true, + fastForwardOnly = false, + corsProxy, + singleBranch, + headers = {}, + author: _author, + committer: _committer, + signingKey, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + const fs = new FileSystem(_fs); + const author = await normalizeAuthorObject({ fs, gitdir, author: _author }); + if (!author) + throw new MissingNameError("author"); + const committer = await normalizeCommitterObject({ + fs, + gitdir, + author, + committer: _committer + }); + if (!committer) + throw new MissingNameError("committer"); + return await _pull({ + fs, + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir, + ref, + url, + remote, + remoteRef, + fastForward: fastForward2, + fastForwardOnly, + corsProxy, + singleBranch, + headers, + author, + committer, + signingKey, + prune, + pruneTags + }); + } catch (err) { + err.caller = "git.pull"; + throw err; + } +} +async function listCommitsAndTags({ + fs, + cache, + dir, + gitdir = join(dir, ".git"), + start, + finish +}) { + const shallows = await GitShallowManager.read({ fs, gitdir }); + const startingSet = /* @__PURE__ */ new Set(); + const finishingSet = /* @__PURE__ */ new Set(); + for (const ref of start) { + startingSet.add(await GitRefManager.resolve({ fs, gitdir, ref })); + } + for (const ref of finish) { + try { + const oid = await GitRefManager.resolve({ fs, gitdir, ref }); + finishingSet.add(oid); + } catch (err) { + } + } + const visited = /* @__PURE__ */ new Set(); + async function walk2(oid) { + visited.add(oid); + const { type, object } = await _readObject({ fs, cache, gitdir, oid }); + if (type === "tag") { + const tag2 = GitAnnotatedTag.from(object); + const commit2 = tag2.headers().object; + return walk2(commit2); + } + if (type !== "commit") { + throw new ObjectTypeError(oid, type, "commit"); + } + if (!shallows.has(oid)) { + const commit2 = GitCommit.from(object); + const parents = commit2.headers().parent; + for (oid of parents) { + if (!finishingSet.has(oid) && !visited.has(oid)) { + await walk2(oid); + } + } + } + } + for (const oid of startingSet) { + await walk2(oid); + } + return visited; +} +async function listObjects({ + fs, + cache, + dir, + gitdir = join(dir, ".git"), + oids +}) { + const visited = /* @__PURE__ */ new Set(); + async function walk2(oid) { + if (visited.has(oid)) + return; + visited.add(oid); + const { type, object } = await _readObject({ fs, cache, gitdir, oid }); + if (type === "tag") { + const tag2 = GitAnnotatedTag.from(object); + const obj = tag2.headers().object; + await walk2(obj); + } else if (type === "commit") { + const commit2 = GitCommit.from(object); + const tree = commit2.headers().tree; + await walk2(tree); + } else if (type === "tree") { + const tree = GitTree.from(object); + for (const entry of tree) { + if (entry.type === "blob") { + visited.add(entry.oid); + } + if (entry.type === "tree") { + await walk2(entry.oid); + } + } + } + } + for (const oid of oids) { + await walk2(oid); + } + return visited; +} +async function parseReceivePackResponse(packfile) { + const result = {}; + let response = ""; + const read = GitPktLine.streamReader(packfile); + let line = await read(); + while (line !== true) { + if (line !== null) + response += line.toString("utf8") + "\n"; + line = await read(); + } + const lines = response.toString("utf8").split("\n"); + line = lines.shift(); + if (!line.startsWith("unpack ")) { + throw new ParseError('unpack ok" or "unpack [error message]', line); + } + result.ok = line === "unpack ok"; + if (!result.ok) { + result.error = line.slice("unpack ".length); + } + result.refs = {}; + for (const line2 of lines) { + if (line2.trim() === "") + continue; + const status2 = line2.slice(0, 2); + const refAndMessage = line2.slice(3); + let space2 = refAndMessage.indexOf(" "); + if (space2 === -1) + space2 = refAndMessage.length; + const ref = refAndMessage.slice(0, space2); + const error = refAndMessage.slice(space2 + 1); + result.refs[ref] = { + ok: status2 === "ok", + error + }; + } + return result; +} +async function writeReceivePackRequest({ + capabilities = [], + triplets = [] +}) { + const packstream = []; + let capsFirstLine = `\0 ${capabilities.join(" ")}`; + for (const trip of triplets) { + packstream.push( + GitPktLine.encode( + `${trip.oldoid} ${trip.oid} ${trip.fullRef}${capsFirstLine} +` + ) + ); + capsFirstLine = ""; + } + packstream.push(GitPktLine.flush()); + return packstream; +} +async function _push({ + fs, + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + gitdir, + ref: _ref, + remoteRef: _remoteRef, + remote, + url: _url, + force = false, + delete: _delete = false, + corsProxy, + headers = {} +}) { + const ref = _ref || await _currentBranch({ fs, gitdir }); + if (typeof ref === "undefined") { + throw new MissingParameterError("ref"); + } + const config = await GitConfigManager.get({ fs, gitdir }); + remote = remote || await config.get(`branch.${ref}.pushRemote`) || await config.get("remote.pushDefault") || await config.get(`branch.${ref}.remote`) || "origin"; + const url = _url || await config.get(`remote.${remote}.pushurl`) || await config.get(`remote.${remote}.url`); + if (typeof url === "undefined") { + throw new MissingParameterError("remote OR url"); + } + const remoteRef = _remoteRef || await config.get(`branch.${ref}.merge`); + if (typeof url === "undefined") { + throw new MissingParameterError("remoteRef"); + } + if (corsProxy === void 0) { + corsProxy = await config.get("http.corsProxy"); + } + const fullRef = await GitRefManager.expand({ fs, gitdir, ref }); + const oid = _delete ? "0000000000000000000000000000000000000000" : await GitRefManager.resolve({ fs, gitdir, ref: fullRef }); + const GitRemoteHTTP2 = GitRemoteManager.getRemoteHelperFor({ url }); + const httpRemote = await GitRemoteHTTP2.discover({ + http, + onAuth, + onAuthSuccess, + onAuthFailure, + corsProxy, + service: "git-receive-pack", + url, + headers, + protocolVersion: 1 + }); + const auth = httpRemote.auth; + let fullRemoteRef; + if (!remoteRef) { + fullRemoteRef = fullRef; + } else { + try { + fullRemoteRef = await GitRefManager.expandAgainstMap({ + ref: remoteRef, + map: httpRemote.refs + }); + } catch (err) { + if (err instanceof NotFoundError) { + fullRemoteRef = remoteRef.startsWith("refs/") ? remoteRef : `refs/heads/${remoteRef}`; + } else { + throw err; + } + } + } + const oldoid = httpRemote.refs.get(fullRemoteRef) || "0000000000000000000000000000000000000000"; + const thinPack = !httpRemote.capabilities.has("no-thin"); + let objects = /* @__PURE__ */ new Set(); + if (!_delete) { + const finish = [...httpRemote.refs.values()]; + let skipObjects = /* @__PURE__ */ new Set(); + if (oldoid !== "0000000000000000000000000000000000000000") { + const mergebase = await _findMergeBase({ + fs, + cache, + gitdir, + oids: [oid, oldoid] + }); + for (const oid2 of mergebase) + finish.push(oid2); + if (thinPack) { + skipObjects = await listObjects({ fs, cache, gitdir, oids: mergebase }); + } + } + if (!finish.includes(oid)) { + const commits = await listCommitsAndTags({ + fs, + cache, + gitdir, + start: [oid], + finish + }); + objects = await listObjects({ fs, cache, gitdir, oids: commits }); + } + if (thinPack) { + try { + const ref2 = await GitRefManager.resolve({ + fs, + gitdir, + ref: `refs/remotes/${remote}/HEAD`, + depth: 2 + }); + const { oid: oid2 } = await GitRefManager.resolveAgainstMap({ + ref: ref2.replace(`refs/remotes/${remote}/`, ""), + fullref: ref2, + map: httpRemote.refs + }); + const oids = [oid2]; + for (const oid3 of await listObjects({ fs, cache, gitdir, oids })) { + skipObjects.add(oid3); + } + } catch (e) { + } + for (const oid2 of skipObjects) { + objects.delete(oid2); + } + } + if (oid === oldoid) + force = true; + if (!force) { + if (fullRef.startsWith("refs/tags") && oldoid !== "0000000000000000000000000000000000000000") { + throw new PushRejectedError("tag-exists"); + } + if (oid !== "0000000000000000000000000000000000000000" && oldoid !== "0000000000000000000000000000000000000000" && !await _isDescendent({ + fs, + cache, + gitdir, + oid, + ancestor: oldoid, + depth: -1 + })) { + throw new PushRejectedError("not-fast-forward"); + } + } + } + const capabilities = filterCapabilities( + [...httpRemote.capabilities], + ["report-status", "side-band-64k", `agent=${pkg.agent}`] + ); + const packstream1 = await writeReceivePackRequest({ + capabilities, + triplets: [{ oldoid, oid, fullRef: fullRemoteRef }] + }); + const packstream2 = _delete ? [] : await _pack({ + fs, + cache, + gitdir, + oids: [...objects] + }); + const res = await GitRemoteHTTP2.connect({ + http, + onProgress, + corsProxy, + service: "git-receive-pack", + url, + auth, + headers, + body: [...packstream1, ...packstream2] + }); + const { packfile, progress } = await GitSideBand.demux(res.body); + if (onMessage) { + const lines = splitLines(progress); + forAwait(lines, async (line) => { + await onMessage(line); + }); + } + const result = await parseReceivePackResponse(packfile); + if (res.headers) { + result.headers = res.headers; + } + if (remote && result.ok && result.refs[fullRemoteRef].ok) { + const ref2 = `refs/remotes/${remote}/${fullRemoteRef.replace( + "refs/heads", + "" + )}`; + if (_delete) { + await GitRefManager.deleteRef({ fs, gitdir, ref: ref2 }); + } else { + await GitRefManager.writeRef({ fs, gitdir, ref: ref2, value: oid }); + } + } + if (result.ok && Object.values(result.refs).every((result2) => result2.ok)) { + return result; + } else { + const prettyDetails = Object.entries(result.refs).filter(([k, v]) => !v.ok).map(([k, v]) => ` + - ${k}: ${v.error}`).join(""); + throw new GitPushError(prettyDetails, result); + } +} +async function push({ + fs, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + dir, + gitdir = join(dir, ".git"), + ref, + remoteRef, + remote = "origin", + url, + force = false, + delete: _delete = false, + corsProxy, + headers = {}, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("http", http); + assertParameter("gitdir", gitdir); + return await _push({ + fs: new FileSystem(fs), + cache, + http, + onProgress, + onMessage, + onAuth, + onAuthSuccess, + onAuthFailure, + gitdir, + ref, + remoteRef, + remote, + url, + force, + delete: _delete, + corsProxy, + headers + }); + } catch (err) { + err.caller = "git.push"; + throw err; + } +} +async function resolveBlob({ fs, cache, gitdir, oid }) { + const { type, object } = await _readObject({ fs, cache, gitdir, oid }); + if (type === "tag") { + oid = GitAnnotatedTag.from(object).parse().object; + return resolveBlob({ fs, cache, gitdir, oid }); + } + if (type !== "blob") { + throw new ObjectTypeError(oid, type, "blob"); + } + return { oid, blob: new Uint8Array(object) }; +} +async function _readBlob({ + fs, + cache, + gitdir, + oid, + filepath = void 0 +}) { + if (filepath !== void 0) { + oid = await resolveFilepath({ fs, cache, gitdir, oid, filepath }); + } + const blob = await resolveBlob({ + fs, + cache, + gitdir, + oid + }); + return blob; +} +async function readBlob({ + fs, + dir, + gitdir = join(dir, ".git"), + oid, + filepath, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + return await _readBlob({ + fs: new FileSystem(fs), + cache, + gitdir, + oid, + filepath + }); + } catch (err) { + err.caller = "git.readBlob"; + throw err; + } +} +async function readCommit({ + fs, + dir, + gitdir = join(dir, ".git"), + oid, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + return await _readCommit({ + fs: new FileSystem(fs), + cache, + gitdir, + oid + }); + } catch (err) { + err.caller = "git.readCommit"; + throw err; + } +} +async function _readNote({ + fs, + cache, + gitdir, + ref = "refs/notes/commits", + oid +}) { + const parent = await GitRefManager.resolve({ gitdir, fs, ref }); + const { blob } = await _readBlob({ + fs, + cache, + gitdir, + oid: parent, + filepath: oid + }); + return blob; +} +async function readNote({ + fs, + dir, + gitdir = join(dir, ".git"), + ref = "refs/notes/commits", + oid, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + assertParameter("oid", oid); + return await _readNote({ + fs: new FileSystem(fs), + cache, + gitdir, + ref, + oid + }); + } catch (err) { + err.caller = "git.readNote"; + throw err; + } +} +async function readObject({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + oid, + format = "parsed", + filepath = void 0, + encoding = void 0, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + const fs = new FileSystem(_fs); + if (filepath !== void 0) { + oid = await resolveFilepath({ + fs, + cache, + gitdir, + oid, + filepath + }); + } + const _format = format === "parsed" ? "content" : format; + const result = await _readObject({ + fs, + cache, + gitdir, + oid, + format: _format + }); + result.oid = oid; + if (format === "parsed") { + result.format = "parsed"; + switch (result.type) { + case "commit": + result.object = GitCommit.from(result.object).parse(); + break; + case "tree": + result.object = GitTree.from(result.object).entries(); + break; + case "blob": + if (encoding) { + result.object = result.object.toString(encoding); + } else { + result.object = new Uint8Array(result.object); + result.format = "content"; + } + break; + case "tag": + result.object = GitAnnotatedTag.from(result.object).parse(); + break; + default: + throw new ObjectTypeError( + result.oid, + result.type, + "blob|commit|tag|tree" + ); + } + } else if (result.format === "deflated" || result.format === "wrapped") { + result.type = result.format; + } + return result; + } catch (err) { + err.caller = "git.readObject"; + throw err; + } +} +async function _readTag({ fs, cache, gitdir, oid }) { + const { type, object } = await _readObject({ + fs, + cache, + gitdir, + oid, + format: "content" + }); + if (type !== "tag") { + throw new ObjectTypeError(oid, type, "tag"); + } + const tag2 = GitAnnotatedTag.from(object); + const result = { + oid, + tag: tag2.parse(), + payload: tag2.payload() + }; + return result; +} +async function readTag({ + fs, + dir, + gitdir = join(dir, ".git"), + oid, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + return await _readTag({ + fs: new FileSystem(fs), + cache, + gitdir, + oid + }); + } catch (err) { + err.caller = "git.readTag"; + throw err; + } +} +async function readTree({ + fs, + dir, + gitdir = join(dir, ".git"), + oid, + filepath = void 0, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + return await _readTree({ + fs: new FileSystem(fs), + cache, + gitdir, + oid, + filepath + }); + } catch (err) { + err.caller = "git.readTree"; + throw err; + } +} +async function remove({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + filepath, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("filepath", filepath); + await GitIndexManager.acquire( + { fs: new FileSystem(_fs), gitdir, cache }, + async function(index2) { + index2.delete({ filepath }); + } + ); + } catch (err) { + err.caller = "git.remove"; + throw err; + } +} +async function _removeNote({ + fs, + cache, + onSign, + gitdir, + ref = "refs/notes/commits", + oid, + author, + committer, + signingKey +}) { + let parent; + try { + parent = await GitRefManager.resolve({ gitdir, fs, ref }); + } catch (err) { + if (!(err instanceof NotFoundError)) { + throw err; + } + } + const result = await _readTree({ + fs, + gitdir, + oid: parent || "4b825dc642cb6eb9a060e54bf8d69288fbee4904" + }); + let tree = result.tree; + tree = tree.filter((entry) => entry.path !== oid); + const treeOid = await _writeTree({ + fs, + gitdir, + tree + }); + const commitOid = await _commit({ + fs, + cache, + onSign, + gitdir, + ref, + tree: treeOid, + parent: parent && [parent], + message: `Note removed by 'isomorphic-git removeNote' +`, + author, + committer, + signingKey + }); + return commitOid; +} +async function removeNote({ + fs: _fs, + onSign, + dir, + gitdir = join(dir, ".git"), + ref = "refs/notes/commits", + oid, + author: _author, + committer: _committer, + signingKey, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("oid", oid); + const fs = new FileSystem(_fs); + const author = await normalizeAuthorObject({ fs, gitdir, author: _author }); + if (!author) + throw new MissingNameError("author"); + const committer = await normalizeCommitterObject({ + fs, + gitdir, + author, + committer: _committer + }); + if (!committer) + throw new MissingNameError("committer"); + return await _removeNote({ + fs, + cache, + onSign, + gitdir, + ref, + oid, + author, + committer, + signingKey + }); + } catch (err) { + err.caller = "git.removeNote"; + throw err; + } +} +async function _renameBranch({ + fs, + gitdir, + oldref, + ref, + checkout: checkout2 = false +}) { + if (ref !== import_clean_git_ref.default.clean(ref)) { + throw new InvalidRefNameError(ref, import_clean_git_ref.default.clean(ref)); + } + if (oldref !== import_clean_git_ref.default.clean(oldref)) { + throw new InvalidRefNameError(oldref, import_clean_git_ref.default.clean(oldref)); + } + const fulloldref = `refs/heads/${oldref}`; + const fullnewref = `refs/heads/${ref}`; + const newexist = await GitRefManager.exists({ fs, gitdir, ref: fullnewref }); + if (newexist) { + throw new AlreadyExistsError("branch", ref, false); + } + const value = await GitRefManager.resolve({ + fs, + gitdir, + ref: fulloldref, + depth: 1 + }); + await GitRefManager.writeRef({ fs, gitdir, ref: fullnewref, value }); + await GitRefManager.deleteRef({ fs, gitdir, ref: fulloldref }); + if (checkout2) { + await GitRefManager.writeSymbolicRef({ + fs, + gitdir, + ref: "HEAD", + value: fullnewref + }); + } +} +async function renameBranch({ + fs, + dir, + gitdir = join(dir, ".git"), + ref, + oldref, + checkout: checkout2 = false +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + assertParameter("oldref", oldref); + return await _renameBranch({ + fs: new FileSystem(fs), + gitdir, + ref, + oldref, + checkout: checkout2 + }); + } catch (err) { + err.caller = "git.renameBranch"; + throw err; + } +} +async function hashObject$1({ gitdir, type, object }) { + return shasum(GitObject.wrap({ type, object })); +} +async function resetIndex({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + filepath, + ref, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("filepath", filepath); + const fs = new FileSystem(_fs); + let oid; + let workdirOid; + try { + oid = await GitRefManager.resolve({ fs, gitdir, ref: ref || "HEAD" }); + } catch (e) { + if (ref) { + throw e; + } + } + if (oid) { + try { + oid = await resolveFilepath({ + fs, + cache, + gitdir, + oid, + filepath + }); + } catch (e) { + oid = null; + } + } + let stats = { + ctime: /* @__PURE__ */ new Date(0), + mtime: /* @__PURE__ */ new Date(0), + dev: 0, + ino: 0, + mode: 0, + uid: 0, + gid: 0, + size: 0 + }; + const object = dir && await fs.read(join(dir, filepath)); + if (object) { + workdirOid = await hashObject$1({ + gitdir, + type: "blob", + object + }); + if (oid === workdirOid) { + stats = await fs.lstat(join(dir, filepath)); + } + } + await GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + index2.delete({ filepath }); + if (oid) { + index2.insert({ filepath, stats, oid }); + } + }); + } catch (err) { + err.caller = "git.reset"; + throw err; + } +} +async function resolveRef({ + fs, + dir, + gitdir = join(dir, ".git"), + ref, + depth +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + const oid = await GitRefManager.resolve({ + fs: new FileSystem(fs), + gitdir, + ref, + depth + }); + return oid; + } catch (err) { + err.caller = "git.resolveRef"; + throw err; + } +} +async function setConfig({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + path: path2, + value, + append: append3 = false +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("path", path2); + const fs = new FileSystem(_fs); + const config = await GitConfigManager.get({ fs, gitdir }); + if (append3) { + await config.append(path2, value); + } else { + await config.set(path2, value); + } + await GitConfigManager.save({ fs, gitdir, config }); + } catch (err) { + err.caller = "git.setConfig"; + throw err; + } +} +async function status({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + filepath, + cache = {} +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("filepath", filepath); + const fs = new FileSystem(_fs); + const ignored = await GitIgnoreManager.isIgnored({ + fs, + gitdir, + dir, + filepath + }); + if (ignored) { + return "ignored"; + } + const headTree = await getHeadTree({ fs, cache, gitdir }); + const treeOid = await getOidAtPath({ + fs, + cache, + gitdir, + tree: headTree, + path: filepath + }); + const indexEntry = await GitIndexManager.acquire( + { fs, gitdir, cache }, + async function(index2) { + for (const entry of index2) { + if (entry.path === filepath) + return entry; + } + return null; + } + ); + const stats = await fs.lstat(join(dir, filepath)); + const H = treeOid !== null; + const I = indexEntry !== null; + const W = stats !== null; + const getWorkdirOid = async () => { + if (I && !compareStats(indexEntry, stats)) { + return indexEntry.oid; + } else { + const object = await fs.read(join(dir, filepath)); + const workdirOid = await hashObject$1({ + gitdir, + type: "blob", + object + }); + if (I && indexEntry.oid === workdirOid) { + if (stats.size !== -1) { + GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + index2.insert({ filepath, stats, oid: workdirOid }); + }); + } + } + return workdirOid; + } + }; + if (!H && !W && !I) + return "absent"; + if (!H && !W && I) + return "*absent"; + if (!H && W && !I) + return "*added"; + if (!H && W && I) { + const workdirOid = await getWorkdirOid(); + return workdirOid === indexEntry.oid ? "added" : "*added"; + } + if (H && !W && !I) + return "deleted"; + if (H && !W && I) { + return treeOid === indexEntry.oid ? "*deleted" : "*deleted"; + } + if (H && W && !I) { + const workdirOid = await getWorkdirOid(); + return workdirOid === treeOid ? "*undeleted" : "*undeletemodified"; + } + if (H && W && I) { + const workdirOid = await getWorkdirOid(); + if (workdirOid === treeOid) { + return workdirOid === indexEntry.oid ? "unmodified" : "*unmodified"; + } else { + return workdirOid === indexEntry.oid ? "modified" : "*modified"; + } + } + } catch (err) { + err.caller = "git.status"; + throw err; + } +} +async function getOidAtPath({ fs, cache, gitdir, tree, path: path2 }) { + if (typeof path2 === "string") + path2 = path2.split("/"); + const dirname3 = path2.shift(); + for (const entry of tree) { + if (entry.path === dirname3) { + if (path2.length === 0) { + return entry.oid; + } + const { type, object } = await _readObject({ + fs, + cache, + gitdir, + oid: entry.oid + }); + if (type === "tree") { + const tree2 = GitTree.from(object); + return getOidAtPath({ fs, cache, gitdir, tree: tree2, path: path2 }); + } + if (type === "blob") { + throw new ObjectTypeError(entry.oid, type, "blob", path2.join("/")); + } + } + } + return null; +} +async function getHeadTree({ fs, cache, gitdir }) { + let oid; + try { + oid = await GitRefManager.resolve({ fs, gitdir, ref: "HEAD" }); + } catch (e) { + if (e instanceof NotFoundError) { + return []; + } + } + const { tree } = await _readTree({ fs, cache, gitdir, oid }); + return tree; +} +async function statusMatrix({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + ref = "HEAD", + filepaths = ["."], + filter, + cache = {}, + ignored: shouldIgnore = false +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + const fs = new FileSystem(_fs); + return await _walk({ + fs, + cache, + dir, + gitdir, + trees: [TREE({ ref }), WORKDIR(), STAGE()], + map: async function(filepath, [head, workdir, stage]) { + if (!head && !stage && workdir) { + if (!shouldIgnore) { + const isIgnored2 = await GitIgnoreManager.isIgnored({ + fs, + dir, + filepath + }); + if (isIgnored2) { + return null; + } + } + } + if (!filepaths.some((base) => worthWalking(filepath, base))) { + return null; + } + if (filter) { + if (!filter(filepath)) + return; + } + const [headType, workdirType, stageType] = await Promise.all([ + head && head.type(), + workdir && workdir.type(), + stage && stage.type() + ]); + const isBlob = [headType, workdirType, stageType].includes("blob"); + if ((headType === "tree" || headType === "special") && !isBlob) + return; + if (headType === "commit") + return null; + if ((workdirType === "tree" || workdirType === "special") && !isBlob) + return; + if (stageType === "commit") + return null; + if ((stageType === "tree" || stageType === "special") && !isBlob) + return; + const headOid = headType === "blob" ? await head.oid() : void 0; + const stageOid = stageType === "blob" ? await stage.oid() : void 0; + let workdirOid; + if (headType !== "blob" && workdirType === "blob" && stageType !== "blob") { + workdirOid = "42"; + } else if (workdirType === "blob") { + workdirOid = await workdir.oid(); + } + const entry = [void 0, headOid, workdirOid, stageOid]; + const result = entry.map((value) => entry.indexOf(value)); + result.shift(); + return [filepath, ...result]; + } + }); + } catch (err) { + err.caller = "git.statusMatrix"; + throw err; + } +} +async function tag({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + ref, + object, + force = false +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + const fs = new FileSystem(_fs); + if (ref === void 0) { + throw new MissingParameterError("ref"); + } + ref = ref.startsWith("refs/tags/") ? ref : `refs/tags/${ref}`; + const value = await GitRefManager.resolve({ + fs, + gitdir, + ref: object || "HEAD" + }); + if (!force && await GitRefManager.exists({ fs, gitdir, ref })) { + throw new AlreadyExistsError("tag", ref); + } + await GitRefManager.writeRef({ fs, gitdir, ref, value }); + } catch (err) { + err.caller = "git.tag"; + throw err; + } +} +async function updateIndex({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + cache = {}, + filepath, + oid, + mode, + add: add2, + remove: remove3, + force +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("filepath", filepath); + const fs = new FileSystem(_fs); + if (remove3) { + return await GitIndexManager.acquire( + { fs, gitdir, cache }, + async function(index2) { + let fileStats2; + if (!force) { + fileStats2 = await fs.lstat(join(dir, filepath)); + if (fileStats2) { + if (fileStats2.isDirectory()) { + throw new InvalidFilepathError("directory"); + } + return; + } + } + if (index2.has({ filepath })) { + index2.delete({ + filepath + }); + } + } + ); + } + let fileStats; + if (!oid) { + fileStats = await fs.lstat(join(dir, filepath)); + if (!fileStats) { + throw new NotFoundError( + `file at "${filepath}" on disk and "remove" not set` + ); + } + if (fileStats.isDirectory()) { + throw new InvalidFilepathError("directory"); + } + } + return await GitIndexManager.acquire({ fs, gitdir, cache }, async function(index2) { + if (!add2 && !index2.has({ filepath })) { + throw new NotFoundError( + `file at "${filepath}" in index and "add" not set` + ); + } + let stats = { + ctime: /* @__PURE__ */ new Date(0), + mtime: /* @__PURE__ */ new Date(0), + dev: 0, + ino: 0, + mode, + uid: 0, + gid: 0, + size: 0 + }; + if (!oid) { + stats = fileStats; + const object = stats.isSymbolicLink() ? await fs.readlink(join(dir, filepath)) : await fs.read(join(dir, filepath)); + oid = await _writeObject({ + fs, + gitdir, + type: "blob", + format: "content", + object + }); + } + index2.insert({ + filepath, + oid, + stats + }); + return oid; + }); + } catch (err) { + err.caller = "git.updateIndex"; + throw err; + } +} +function version() { + try { + return pkg.version; + } catch (err) { + err.caller = "git.version"; + throw err; + } +} +async function walk({ + fs, + dir, + gitdir = join(dir, ".git"), + trees, + map, + reduce, + iterate, + cache = {} +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("trees", trees); + return await _walk({ + fs: new FileSystem(fs), + cache, + dir, + gitdir, + trees, + map, + reduce, + iterate + }); + } catch (err) { + err.caller = "git.walk"; + throw err; + } +} +async function writeBlob({ fs, dir, gitdir = join(dir, ".git"), blob }) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("blob", blob); + return await _writeObject({ + fs: new FileSystem(fs), + gitdir, + type: "blob", + object: blob, + format: "content" + }); + } catch (err) { + err.caller = "git.writeBlob"; + throw err; + } +} +async function _writeCommit({ fs, gitdir, commit: commit2 }) { + const object = GitCommit.from(commit2).toObject(); + const oid = await _writeObject({ + fs, + gitdir, + type: "commit", + object, + format: "content" + }); + return oid; +} +async function writeCommit({ + fs, + dir, + gitdir = join(dir, ".git"), + commit: commit2 +}) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("commit", commit2); + return await _writeCommit({ + fs: new FileSystem(fs), + gitdir, + commit: commit2 + }); + } catch (err) { + err.caller = "git.writeCommit"; + throw err; + } +} +async function writeObject({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + type, + object, + format = "parsed", + oid, + encoding = void 0 +}) { + try { + const fs = new FileSystem(_fs); + if (format === "parsed") { + switch (type) { + case "commit": + object = GitCommit.from(object).toObject(); + break; + case "tree": + object = GitTree.from(object).toObject(); + break; + case "blob": + object = Buffer.from(object, encoding); + break; + case "tag": + object = GitAnnotatedTag.from(object).toObject(); + break; + default: + throw new ObjectTypeError(oid || "", type, "blob|commit|tag|tree"); + } + format = "content"; + } + oid = await _writeObject({ + fs, + gitdir, + type, + object, + oid, + format + }); + return oid; + } catch (err) { + err.caller = "git.writeObject"; + throw err; + } +} +async function writeRef({ + fs: _fs, + dir, + gitdir = join(dir, ".git"), + ref, + value, + force = false, + symbolic = false +}) { + try { + assertParameter("fs", _fs); + assertParameter("gitdir", gitdir); + assertParameter("ref", ref); + assertParameter("value", value); + const fs = new FileSystem(_fs); + if (ref !== import_clean_git_ref.default.clean(ref)) { + throw new InvalidRefNameError(ref, import_clean_git_ref.default.clean(ref)); + } + if (!force && await GitRefManager.exists({ fs, gitdir, ref })) { + throw new AlreadyExistsError("ref", ref); + } + if (symbolic) { + await GitRefManager.writeSymbolicRef({ + fs, + gitdir, + ref, + value + }); + } else { + value = await GitRefManager.resolve({ + fs, + gitdir, + ref: value + }); + await GitRefManager.writeRef({ + fs, + gitdir, + ref, + value + }); + } + } catch (err) { + err.caller = "git.writeRef"; + throw err; + } +} +async function _writeTag({ fs, gitdir, tag: tag2 }) { + const object = GitAnnotatedTag.from(tag2).toObject(); + const oid = await _writeObject({ + fs, + gitdir, + type: "tag", + object, + format: "content" + }); + return oid; +} +async function writeTag({ fs, dir, gitdir = join(dir, ".git"), tag: tag2 }) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("tag", tag2); + return await _writeTag({ + fs: new FileSystem(fs), + gitdir, + tag: tag2 + }); + } catch (err) { + err.caller = "git.writeTag"; + throw err; + } +} +async function writeTree({ fs, dir, gitdir = join(dir, ".git"), tree }) { + try { + assertParameter("fs", fs); + assertParameter("gitdir", gitdir); + assertParameter("tree", tree); + return await _writeTree({ + fs: new FileSystem(fs), + gitdir, + tree + }); + } catch (err) { + err.caller = "git.writeTree"; + throw err; + } +} +var index = { + Errors, + STAGE, + TREE, + WORKDIR, + add, + abortMerge, + addNote, + addRemote, + annotatedTag, + branch, + checkout, + clone, + commit, + getConfig, + getConfigAll, + setConfig, + currentBranch, + deleteBranch, + deleteRef, + deleteRemote, + deleteTag, + expandOid, + expandRef, + fastForward, + fetch, + findMergeBase, + findRoot, + getRemoteInfo, + getRemoteInfo2, + hashBlob, + indexPack, + init, + isDescendent, + isIgnored, + listBranches, + listFiles, + listNotes, + listRemotes, + listServerRefs, + listTags, + log, + merge, + packObjects, + pull, + push, + readBlob, + readCommit, + readNote, + readObject, + readTag, + readTree, + remove, + removeNote, + renameBranch, + resetIndex, + updateIndex, + resolveRef, + status, + statusMatrix, + tag, + version, + walk, + writeBlob, + writeCommit, + writeObject, + writeRef, + writeTag, + writeTree +}; +var isomorphic_git_default = index; + +// src/main.ts +var import_obsidian30 = require("obsidian"); + +// src/lineAuthor/lineAuthorIntegration.ts +init_polyfill_buffer(); +var import_obsidian12 = require("obsidian"); + +// src/gitManager/simpleGit.ts +init_polyfill_buffer(); +var import_child_process2 = require("child_process"); +var import_debug2 = __toESM(require_browser()); +var import_obsidian4 = require("obsidian"); +var path = __toESM(require("path")); +var import_path = require("path"); + +// node_modules/.pnpm/github.com+Vinzent03+git-js@6b9a2d899bc8256e38a1d6f0b8a88116ba2bf56a_supports-color@7.2.0/node_modules/simple-git/dist/esm/index.js +init_polyfill_buffer(); +var import_file_exists = __toESM(require_dist(), 1); +var import_debug = __toESM(require_browser(), 1); +var import_child_process = require("child_process"); +var import_promise_deferred = __toESM(require_dist2(), 1); +var import_promise_deferred2 = __toESM(require_dist2(), 1); +var __defProp2 = Object.defineProperty; +var __defProps = Object.defineProperties; +var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; +var __getOwnPropDescs = Object.getOwnPropertyDescriptors; +var __getOwnPropNames2 = Object.getOwnPropertyNames; +var __getOwnPropSymbols = Object.getOwnPropertySymbols; +var __hasOwnProp2 = Object.prototype.hasOwnProperty; +var __propIsEnum = Object.prototype.propertyIsEnumerable; +var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp2(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value; +var __spreadValues = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp2.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + if (__getOwnPropSymbols) + for (var prop of __getOwnPropSymbols(b)) { + if (__propIsEnum.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + } + return a; +}; +var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); +var __markAsModule = (target) => __defProp2(target, "__esModule", { value: true }); +var __esm2 = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames2(fn)[0]])(fn = 0)), res; +}; +var __commonJS2 = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export2 = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); +}; +var __reExport = (target, module2, copyDefault, desc) => { + if (module2 && typeof module2 === "object" || typeof module2 === "function") { + for (let key2 of __getOwnPropNames2(module2)) + if (!__hasOwnProp2.call(target, key2) && (copyDefault || key2 !== "default")) + __defProp2(target, key2, { get: () => module2[key2], enumerable: !(desc = __getOwnPropDesc2(module2, key2)) || desc.enumerable }); + } + return target; +}; +var __toCommonJS2 = /* @__PURE__ */ ((cache) => { + return (module2, temp) => { + return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp); + }; +})(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0); +var __async = (__this, __arguments, generator) => { + return new Promise((resolve, reject) => { + var fulfilled = (value) => { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + }; + var rejected = (value) => { + try { + step(generator.throw(value)); + } catch (e) { + reject(e); + } + }; + var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); + step((generator = generator.apply(__this, __arguments)).next()); + }); +}; +var GitError; +var init_git_error = __esm2({ + "src/lib/errors/git-error.ts"() { + GitError = class extends Error { + constructor(task, message) { + super(message); + this.task = task; + Object.setPrototypeOf(this, new.target.prototype); + } + }; + } +}); +var GitResponseError; +var init_git_response_error = __esm2({ + "src/lib/errors/git-response-error.ts"() { + init_git_error(); + GitResponseError = class extends GitError { + constructor(git, message) { + super(void 0, message || String(git)); + this.git = git; + } + }; + } +}); +var TaskConfigurationError; +var init_task_configuration_error = __esm2({ + "src/lib/errors/task-configuration-error.ts"() { + init_git_error(); + TaskConfigurationError = class extends GitError { + constructor(message) { + super(void 0, message); + } + }; + } +}); +function asFunction(source) { + return typeof source === "function" ? source : NOOP; +} +function isUserFunction(source) { + return typeof source === "function" && source !== NOOP; +} +function splitOn(input, char) { + const index2 = input.indexOf(char); + if (index2 <= 0) { + return [input, ""]; + } + return [input.substr(0, index2), input.substr(index2 + 1)]; +} +function first(input, offset = 0) { + return isArrayLike(input) && input.length > offset ? input[offset] : void 0; +} +function last(input, offset = 0) { + if (isArrayLike(input) && input.length > offset) { + return input[input.length - 1 - offset]; + } +} +function isArrayLike(input) { + return !!(input && typeof input.length === "number"); +} +function toLinesWithContent(input = "", trimmed2 = true, separator2 = "\n") { + return input.split(separator2).reduce((output, line) => { + const lineContent = trimmed2 ? line.trim() : line; + if (lineContent) { + output.push(lineContent); + } + return output; + }, []); +} +function forEachLineWithContent(input, callback) { + return toLinesWithContent(input, true).map((line) => callback(line)); +} +function folderExists(path2) { + return (0, import_file_exists.exists)(path2, import_file_exists.FOLDER); +} +function append(target, item) { + if (Array.isArray(target)) { + if (!target.includes(item)) { + target.push(item); + } + } else { + target.add(item); + } + return item; +} +function including(target, item) { + if (Array.isArray(target) && !target.includes(item)) { + target.push(item); + } + return target; +} +function remove2(target, item) { + if (Array.isArray(target)) { + const index2 = target.indexOf(item); + if (index2 >= 0) { + target.splice(index2, 1); + } + } else { + target.delete(item); + } + return item; +} +function asArray(source) { + return Array.isArray(source) ? source : [source]; +} +function asStringArray(source) { + return asArray(source).map(String); +} +function asNumber(source, onNaN = 0) { + if (source == null) { + return onNaN; + } + const num2 = parseInt(source, 10); + return isNaN(num2) ? onNaN : num2; +} +function prefixedArray(input, prefix) { + const output = []; + for (let i = 0, max = input.length; i < max; i++) { + output.push(prefix, input[i]); + } + return output; +} +function bufferToString(input) { + return (Array.isArray(input) ? Buffer.concat(input) : input).toString("utf-8"); +} +function pick(source, properties) { + return Object.assign({}, ...properties.map((property) => property in source ? { [property]: source[property] } : {})); +} +function delay(duration = 0) { + return new Promise((done) => setTimeout(done, duration)); +} +var NULL; +var NOOP; +var objectToString; +var init_util = __esm2({ + "src/lib/utils/util.ts"() { + NULL = "\0"; + NOOP = () => { + }; + objectToString = Object.prototype.toString.call.bind(Object.prototype.toString); + } +}); +function filterType(input, filter, def) { + if (filter(input)) { + return input; + } + return arguments.length > 2 ? def : void 0; +} +function filterPrimitives(input, omit) { + return /number|string|boolean/.test(typeof input) && (!omit || !omit.includes(typeof input)); +} +function filterPlainObject(input) { + return !!input && objectToString(input) === "[object Object]"; +} +function filterFunction(input) { + return typeof input === "function"; +} +var filterArray; +var filterString; +var filterStringArray; +var filterStringOrStringArray; +var filterHasLength; +var init_argument_filters = __esm2({ + "src/lib/utils/argument-filters.ts"() { + init_util(); + filterArray = (input) => { + return Array.isArray(input); + }; + filterString = (input) => { + return typeof input === "string"; + }; + filterStringArray = (input) => { + return Array.isArray(input) && input.every(filterString); + }; + filterStringOrStringArray = (input) => { + return filterString(input) || Array.isArray(input) && input.every(filterString); + }; + filterHasLength = (input) => { + if (input == null || "number|boolean|function".includes(typeof input)) { + return false; + } + return Array.isArray(input) || typeof input === "string" || typeof input.length === "number"; + }; + } +}); +var ExitCodes; +var init_exit_codes = __esm2({ + "src/lib/utils/exit-codes.ts"() { + ExitCodes = /* @__PURE__ */ ((ExitCodes2) => { + ExitCodes2[ExitCodes2["SUCCESS"] = 0] = "SUCCESS"; + ExitCodes2[ExitCodes2["ERROR"] = 1] = "ERROR"; + ExitCodes2[ExitCodes2["NOT_FOUND"] = -2] = "NOT_FOUND"; + ExitCodes2[ExitCodes2["UNCLEAN"] = 128] = "UNCLEAN"; + return ExitCodes2; + })(ExitCodes || {}); + } +}); +var GitOutputStreams; +var init_git_output_streams = __esm2({ + "src/lib/utils/git-output-streams.ts"() { + GitOutputStreams = class { + constructor(stdOut, stdErr) { + this.stdOut = stdOut; + this.stdErr = stdErr; + } + asStrings() { + return new GitOutputStreams(this.stdOut.toString("utf8"), this.stdErr.toString("utf8")); + } + }; + } +}); +var LineParser; +var RemoteLineParser; +var init_line_parser = __esm2({ + "src/lib/utils/line-parser.ts"() { + LineParser = class { + constructor(regExp, useMatches) { + this.matches = []; + this.parse = (line, target) => { + this.resetMatches(); + if (!this._regExp.every((reg, index2) => this.addMatch(reg, index2, line(index2)))) { + return false; + } + return this.useMatches(target, this.prepareMatches()) !== false; + }; + this._regExp = Array.isArray(regExp) ? regExp : [regExp]; + if (useMatches) { + this.useMatches = useMatches; + } + } + useMatches(target, match) { + throw new Error(`LineParser:useMatches not implemented`); + } + resetMatches() { + this.matches.length = 0; + } + prepareMatches() { + return this.matches; + } + addMatch(reg, index2, line) { + const matched = line && reg.exec(line); + if (matched) { + this.pushMatch(index2, matched); + } + return !!matched; + } + pushMatch(_index, matched) { + this.matches.push(...matched.slice(1)); + } + }; + RemoteLineParser = class extends LineParser { + addMatch(reg, index2, line) { + return /^remote:\s/.test(String(line)) && super.addMatch(reg, index2, line); + } + pushMatch(index2, matched) { + if (index2 > 0 || matched.length > 1) { + super.pushMatch(index2, matched); + } + } + }; + } +}); +function createInstanceConfig(...options) { + const baseDir = process.cwd(); + const config = Object.assign(__spreadValues({ baseDir }, defaultOptions), ...options.filter((o) => typeof o === "object" && o)); + config.baseDir = config.baseDir || baseDir; + config.trimmed = config.trimmed === true; + return config; +} +var defaultOptions; +var init_simple_git_options = __esm2({ + "src/lib/utils/simple-git-options.ts"() { + defaultOptions = { + binary: "git", + maxConcurrentProcesses: 5, + config: [], + trimmed: false + }; + } +}); +function appendTaskOptions(options, commands = []) { + if (!filterPlainObject(options)) { + return commands; + } + return Object.keys(options).reduce((commands2, key2) => { + const value = options[key2]; + if (filterPrimitives(value, ["boolean"])) { + commands2.push(key2 + "=" + value); + } else { + commands2.push(key2); + } + return commands2; + }, commands); +} +function getTrailingOptions(args, initialPrimitive = 0, objectOnly = false) { + const command = []; + for (let i = 0, max = initialPrimitive < 0 ? args.length : initialPrimitive; i < max; i++) { + if ("string|number".includes(typeof args[i])) { + command.push(String(args[i])); + } + } + appendTaskOptions(trailingOptionsArgument(args), command); + if (!objectOnly) { + command.push(...trailingArrayArgument(args)); + } + return command; +} +function trailingArrayArgument(args) { + const hasTrailingCallback = typeof last(args) === "function"; + return filterType(last(args, hasTrailingCallback ? 1 : 0), filterArray, []); +} +function trailingOptionsArgument(args) { + const hasTrailingCallback = filterFunction(last(args)); + return filterType(last(args, hasTrailingCallback ? 1 : 0), filterPlainObject); +} +function trailingFunctionArgument(args, includeNoop = true) { + const callback = asFunction(last(args)); + return includeNoop || isUserFunction(callback) ? callback : void 0; +} +var init_task_options = __esm2({ + "src/lib/utils/task-options.ts"() { + init_argument_filters(); + init_util(); + } +}); +function callTaskParser(parser3, streams) { + return parser3(streams.stdOut, streams.stdErr); +} +function parseStringResponse(result, parsers12, texts, trim = true) { + asArray(texts).forEach((text2) => { + for (let lines = toLinesWithContent(text2, trim), i = 0, max = lines.length; i < max; i++) { + const line = (offset = 0) => { + if (i + offset >= max) { + return; + } + return lines[i + offset]; + }; + parsers12.some(({ parse: parse2 }) => parse2(line, result)); + } + }); + return result; +} +var init_task_parser = __esm2({ + "src/lib/utils/task-parser.ts"() { + init_util(); + } +}); +var utils_exports = {}; +__export2(utils_exports, { + ExitCodes: () => ExitCodes, + GitOutputStreams: () => GitOutputStreams, + LineParser: () => LineParser, + NOOP: () => NOOP, + NULL: () => NULL, + RemoteLineParser: () => RemoteLineParser, + append: () => append, + appendTaskOptions: () => appendTaskOptions, + asArray: () => asArray, + asFunction: () => asFunction, + asNumber: () => asNumber, + asStringArray: () => asStringArray, + bufferToString: () => bufferToString, + callTaskParser: () => callTaskParser, + createInstanceConfig: () => createInstanceConfig, + delay: () => delay, + filterArray: () => filterArray, + filterFunction: () => filterFunction, + filterHasLength: () => filterHasLength, + filterPlainObject: () => filterPlainObject, + filterPrimitives: () => filterPrimitives, + filterString: () => filterString, + filterStringArray: () => filterStringArray, + filterStringOrStringArray: () => filterStringOrStringArray, + filterType: () => filterType, + first: () => first, + folderExists: () => folderExists, + forEachLineWithContent: () => forEachLineWithContent, + getTrailingOptions: () => getTrailingOptions, + including: () => including, + isUserFunction: () => isUserFunction, + last: () => last, + objectToString: () => objectToString, + parseStringResponse: () => parseStringResponse, + pick: () => pick, + prefixedArray: () => prefixedArray, + remove: () => remove2, + splitOn: () => splitOn, + toLinesWithContent: () => toLinesWithContent, + trailingFunctionArgument: () => trailingFunctionArgument, + trailingOptionsArgument: () => trailingOptionsArgument +}); +var init_utils = __esm2({ + "src/lib/utils/index.ts"() { + init_argument_filters(); + init_exit_codes(); + init_git_output_streams(); + init_line_parser(); + init_simple_git_options(); + init_task_options(); + init_task_parser(); + init_util(); + } +}); +var check_is_repo_exports = {}; +__export2(check_is_repo_exports, { + CheckRepoActions: () => CheckRepoActions, + checkIsBareRepoTask: () => checkIsBareRepoTask, + checkIsRepoRootTask: () => checkIsRepoRootTask, + checkIsRepoTask: () => checkIsRepoTask +}); +function checkIsRepoTask(action) { + switch (action) { + case "bare": + return checkIsBareRepoTask(); + case "root": + return checkIsRepoRootTask(); + } + const commands = ["rev-parse", "--is-inside-work-tree"]; + return { + commands, + format: "utf-8", + onError, + parser + }; +} +function checkIsRepoRootTask() { + const commands = ["rev-parse", "--git-dir"]; + return { + commands, + format: "utf-8", + onError, + parser(path2) { + return /^\.(git)?$/.test(path2.trim()); + } + }; +} +function checkIsBareRepoTask() { + const commands = ["rev-parse", "--is-bare-repository"]; + return { + commands, + format: "utf-8", + onError, + parser + }; +} +function isNotRepoMessage(error) { + return /(Not a git repository|Kein Git-Repository)/i.test(String(error)); +} +var CheckRepoActions; +var onError; +var parser; +var init_check_is_repo = __esm2({ + "src/lib/tasks/check-is-repo.ts"() { + init_utils(); + CheckRepoActions = /* @__PURE__ */ ((CheckRepoActions2) => { + CheckRepoActions2["BARE"] = "bare"; + CheckRepoActions2["IN_TREE"] = "tree"; + CheckRepoActions2["IS_REPO_ROOT"] = "root"; + return CheckRepoActions2; + })(CheckRepoActions || {}); + onError = ({ exitCode }, error, done, fail) => { + if (exitCode === 128 && isNotRepoMessage(error)) { + return done(Buffer.from("false")); + } + fail(error); + }; + parser = (text2) => { + return text2.trim() === "true"; + }; + } +}); +function cleanSummaryParser(dryRun, text2) { + const summary = new CleanResponse(dryRun); + const regexp = dryRun ? dryRunRemovalRegexp : removalRegexp; + toLinesWithContent(text2).forEach((line) => { + const removed = line.replace(regexp, ""); + summary.paths.push(removed); + (isFolderRegexp.test(removed) ? summary.folders : summary.files).push(removed); + }); + return summary; +} +var CleanResponse; +var removalRegexp; +var dryRunRemovalRegexp; +var isFolderRegexp; +var init_CleanSummary = __esm2({ + "src/lib/responses/CleanSummary.ts"() { + init_utils(); + CleanResponse = class { + constructor(dryRun) { + this.dryRun = dryRun; + this.paths = []; + this.files = []; + this.folders = []; + } + }; + removalRegexp = /^[a-z]+\s*/i; + dryRunRemovalRegexp = /^[a-z]+\s+[a-z]+\s*/i; + isFolderRegexp = /\/$/; + } +}); +var task_exports = {}; +__export2(task_exports, { + EMPTY_COMMANDS: () => EMPTY_COMMANDS, + adhocExecTask: () => adhocExecTask, + configurationErrorTask: () => configurationErrorTask, + isBufferTask: () => isBufferTask, + isEmptyTask: () => isEmptyTask, + straightThroughBufferTask: () => straightThroughBufferTask, + straightThroughStringTask: () => straightThroughStringTask +}); +function adhocExecTask(parser3) { + return { + commands: EMPTY_COMMANDS, + format: "empty", + parser: parser3 + }; +} +function configurationErrorTask(error) { + return { + commands: EMPTY_COMMANDS, + format: "empty", + parser() { + throw typeof error === "string" ? new TaskConfigurationError(error) : error; + } + }; +} +function straightThroughStringTask(commands, trimmed2 = false) { + return { + commands, + format: "utf-8", + parser(text2) { + return trimmed2 ? String(text2).trim() : text2; + } + }; +} +function straightThroughBufferTask(commands) { + return { + commands, + format: "buffer", + parser(buffer2) { + return buffer2; + } + }; +} +function isBufferTask(task) { + return task.format === "buffer"; +} +function isEmptyTask(task) { + return task.format === "empty" || !task.commands.length; +} +var EMPTY_COMMANDS; +var init_task = __esm2({ + "src/lib/tasks/task.ts"() { + init_task_configuration_error(); + EMPTY_COMMANDS = []; + } +}); +var clean_exports = {}; +__export2(clean_exports, { + CONFIG_ERROR_INTERACTIVE_MODE: () => CONFIG_ERROR_INTERACTIVE_MODE, + CONFIG_ERROR_MODE_REQUIRED: () => CONFIG_ERROR_MODE_REQUIRED, + CONFIG_ERROR_UNKNOWN_OPTION: () => CONFIG_ERROR_UNKNOWN_OPTION, + CleanOptions: () => CleanOptions, + cleanTask: () => cleanTask, + cleanWithOptionsTask: () => cleanWithOptionsTask, + isCleanOptionsArray: () => isCleanOptionsArray +}); +function cleanWithOptionsTask(mode, customArgs) { + const { cleanMode, options, valid } = getCleanOptions(mode); + if (!cleanMode) { + return configurationErrorTask(CONFIG_ERROR_MODE_REQUIRED); + } + if (!valid.options) { + return configurationErrorTask(CONFIG_ERROR_UNKNOWN_OPTION + JSON.stringify(mode)); + } + options.push(...customArgs); + if (options.some(isInteractiveMode)) { + return configurationErrorTask(CONFIG_ERROR_INTERACTIVE_MODE); + } + return cleanTask(cleanMode, options); +} +function cleanTask(mode, customArgs) { + const commands = ["clean", `-${mode}`, ...customArgs]; + return { + commands, + format: "utf-8", + parser(text2) { + return cleanSummaryParser(mode === "n", text2); + } + }; +} +function isCleanOptionsArray(input) { + return Array.isArray(input) && input.every((test) => CleanOptionValues.has(test)); +} +function getCleanOptions(input) { + let cleanMode; + let options = []; + let valid = { cleanMode: false, options: true }; + input.replace(/[^a-z]i/g, "").split("").forEach((char) => { + if (isCleanMode(char)) { + cleanMode = char; + valid.cleanMode = true; + } else { + valid.options = valid.options && isKnownOption(options[options.length] = `-${char}`); + } + }); + return { + cleanMode, + options, + valid + }; +} +function isCleanMode(cleanMode) { + return cleanMode === "f" || cleanMode === "n"; +} +function isKnownOption(option) { + return /^-[a-z]$/i.test(option) && CleanOptionValues.has(option.charAt(1)); +} +function isInteractiveMode(option) { + if (/^-[^\-]/.test(option)) { + return option.indexOf("i") > 0; + } + return option === "--interactive"; +} +var CONFIG_ERROR_INTERACTIVE_MODE; +var CONFIG_ERROR_MODE_REQUIRED; +var CONFIG_ERROR_UNKNOWN_OPTION; +var CleanOptions; +var CleanOptionValues; +var init_clean = __esm2({ + "src/lib/tasks/clean.ts"() { + init_CleanSummary(); + init_utils(); + init_task(); + CONFIG_ERROR_INTERACTIVE_MODE = "Git clean interactive mode is not supported"; + CONFIG_ERROR_MODE_REQUIRED = 'Git clean mode parameter ("n" or "f") is required'; + CONFIG_ERROR_UNKNOWN_OPTION = "Git clean unknown option found in: "; + CleanOptions = /* @__PURE__ */ ((CleanOptions2) => { + CleanOptions2["DRY_RUN"] = "n"; + CleanOptions2["FORCE"] = "f"; + CleanOptions2["IGNORED_INCLUDED"] = "x"; + CleanOptions2["IGNORED_ONLY"] = "X"; + CleanOptions2["EXCLUDING"] = "e"; + CleanOptions2["QUIET"] = "q"; + CleanOptions2["RECURSIVE"] = "d"; + return CleanOptions2; + })(CleanOptions || {}); + CleanOptionValues = /* @__PURE__ */ new Set([ + "i", + ...asStringArray(Object.values(CleanOptions)) + ]); + } +}); +function configListParser(text2) { + const config = new ConfigList(); + for (const item of configParser(text2)) { + config.addValue(item.file, String(item.key), item.value); + } + return config; +} +function configGetParser(text2, key2) { + let value = null; + const values = []; + const scopes = /* @__PURE__ */ new Map(); + for (const item of configParser(text2, key2)) { + if (item.key !== key2) { + continue; + } + values.push(value = item.value); + if (!scopes.has(item.file)) { + scopes.set(item.file, []); + } + scopes.get(item.file).push(value); + } + return { + key: key2, + paths: Array.from(scopes.keys()), + scopes, + value, + values + }; +} +function configFilePath(filePath) { + return filePath.replace(/^(file):/, ""); +} +function* configParser(text2, requestedKey = null) { + const lines = text2.split("\0"); + for (let i = 0, max = lines.length - 1; i < max; ) { + const file = configFilePath(lines[i++]); + let value = lines[i++]; + let key2 = requestedKey; + if (value.includes("\n")) { + const line = splitOn(value, "\n"); + key2 = line[0]; + value = line[1]; + } + yield { file, key: key2, value }; + } +} +var ConfigList; +var init_ConfigList = __esm2({ + "src/lib/responses/ConfigList.ts"() { + init_utils(); + ConfigList = class { + constructor() { + this.files = []; + this.values = /* @__PURE__ */ Object.create(null); + } + get all() { + if (!this._all) { + this._all = this.files.reduce((all, file) => { + return Object.assign(all, this.values[file]); + }, {}); + } + return this._all; + } + addFile(file) { + if (!(file in this.values)) { + const latest = last(this.files); + this.values[file] = latest ? Object.create(this.values[latest]) : {}; + this.files.push(file); + } + return this.values[file]; + } + addValue(file, key2, value) { + const values = this.addFile(file); + if (!values.hasOwnProperty(key2)) { + values[key2] = value; + } else if (Array.isArray(values[key2])) { + values[key2].push(value); + } else { + values[key2] = [values[key2], value]; + } + this._all = void 0; + } + }; + } +}); +function asConfigScope(scope, fallback) { + if (typeof scope === "string" && GitConfigScope.hasOwnProperty(scope)) { + return scope; + } + return fallback; +} +function addConfigTask(key2, value, append22, scope) { + const commands = ["config", `--${scope}`]; + if (append22) { + commands.push("--add"); + } + commands.push(key2, value); + return { + commands, + format: "utf-8", + parser(text2) { + return text2; + } + }; +} +function getConfigTask(key2, scope) { + const commands = ["config", "--null", "--show-origin", "--get-all", key2]; + if (scope) { + commands.splice(1, 0, `--${scope}`); + } + return { + commands, + format: "utf-8", + parser(text2) { + return configGetParser(text2, key2); + } + }; +} +function listConfigTask(scope) { + const commands = ["config", "--list", "--show-origin", "--null"]; + if (scope) { + commands.push(`--${scope}`); + } + return { + commands, + format: "utf-8", + parser(text2) { + return configListParser(text2); + } + }; +} +function config_default() { + return { + addConfig(key2, value, ...rest) { + return this._runTask(addConfigTask(key2, value, rest[0] === true, asConfigScope( + rest[1], + "local" + /* local */ + )), trailingFunctionArgument(arguments)); + }, + getConfig(key2, scope) { + return this._runTask(getConfigTask(key2, asConfigScope(scope, void 0)), trailingFunctionArgument(arguments)); + }, + listConfig(...rest) { + return this._runTask(listConfigTask(asConfigScope(rest[0], void 0)), trailingFunctionArgument(arguments)); + } + }; +} +var GitConfigScope; +var init_config = __esm2({ + "src/lib/tasks/config.ts"() { + init_ConfigList(); + init_utils(); + GitConfigScope = /* @__PURE__ */ ((GitConfigScope2) => { + GitConfigScope2["system"] = "system"; + GitConfigScope2["global"] = "global"; + GitConfigScope2["local"] = "local"; + GitConfigScope2["worktree"] = "worktree"; + return GitConfigScope2; + })(GitConfigScope || {}); + } +}); +function grepQueryBuilder(...params) { + return new GrepQuery().param(...params); +} +function parseGrep(grep) { + const paths = /* @__PURE__ */ new Set(); + const results = {}; + forEachLineWithContent(grep, (input) => { + const [path2, line, preview] = input.split(NULL); + paths.add(path2); + (results[path2] = results[path2] || []).push({ + line: asNumber(line), + path: path2, + preview + }); + }); + return { + paths, + results + }; +} +function grep_default() { + return { + grep(searchTerm) { + const then = trailingFunctionArgument(arguments); + const options = getTrailingOptions(arguments); + for (const option of disallowedOptions) { + if (options.includes(option)) { + return this._runTask(configurationErrorTask(`git.grep: use of "${option}" is not supported.`), then); + } + } + if (typeof searchTerm === "string") { + searchTerm = grepQueryBuilder().param(searchTerm); + } + const commands = ["grep", "--null", "-n", "--full-name", ...options, ...searchTerm]; + return this._runTask({ + commands, + format: "utf-8", + parser(stdOut) { + return parseGrep(stdOut); + } + }, then); + } + }; +} +var disallowedOptions; +var Query; +var _a; +var GrepQuery; +var init_grep = __esm2({ + "src/lib/tasks/grep.ts"() { + init_utils(); + init_task(); + disallowedOptions = ["-h"]; + Query = Symbol("grepQuery"); + GrepQuery = class { + constructor() { + this[_a] = []; + } + *[(_a = Query, Symbol.iterator)]() { + for (const query of this[Query]) { + yield query; + } + } + and(...and) { + and.length && this[Query].push("--and", "(", ...prefixedArray(and, "-e"), ")"); + return this; + } + param(...param) { + this[Query].push(...prefixedArray(param, "-e")); + return this; + } + }; + } +}); +var reset_exports = {}; +__export2(reset_exports, { + ResetMode: () => ResetMode, + getResetMode: () => getResetMode, + resetTask: () => resetTask +}); +function resetTask(mode, customArgs) { + const commands = ["reset"]; + if (isValidResetMode(mode)) { + commands.push(`--${mode}`); + } + commands.push(...customArgs); + return straightThroughStringTask(commands); +} +function getResetMode(mode) { + if (isValidResetMode(mode)) { + return mode; + } + switch (typeof mode) { + case "string": + case "undefined": + return "soft"; + } + return; +} +function isValidResetMode(mode) { + return ResetModes.includes(mode); +} +var ResetMode; +var ResetModes; +var init_reset = __esm2({ + "src/lib/tasks/reset.ts"() { + init_task(); + ResetMode = /* @__PURE__ */ ((ResetMode2) => { + ResetMode2["MIXED"] = "mixed"; + ResetMode2["SOFT"] = "soft"; + ResetMode2["HARD"] = "hard"; + ResetMode2["MERGE"] = "merge"; + ResetMode2["KEEP"] = "keep"; + return ResetMode2; + })(ResetMode || {}); + ResetModes = Array.from(Object.values(ResetMode)); + } +}); +function createLog() { + return (0, import_debug.default)("simple-git"); +} +function prefixedLogger(to, prefix, forward) { + if (!prefix || !String(prefix).replace(/\s*/, "")) { + return !forward ? to : (message, ...args) => { + to(message, ...args); + forward(message, ...args); + }; + } + return (message, ...args) => { + to(`%s ${message}`, prefix, ...args); + if (forward) { + forward(message, ...args); + } + }; +} +function childLoggerName(name, childDebugger, { namespace: parentNamespace }) { + if (typeof name === "string") { + return name; + } + const childNamespace = childDebugger && childDebugger.namespace || ""; + if (childNamespace.startsWith(parentNamespace)) { + return childNamespace.substr(parentNamespace.length + 1); + } + return childNamespace || parentNamespace; +} +function createLogger(label, verbose, initialStep, infoDebugger = createLog()) { + const labelPrefix = label && `[${label}]` || ""; + const spawned = []; + const debugDebugger = typeof verbose === "string" ? infoDebugger.extend(verbose) : verbose; + const key2 = childLoggerName(filterType(verbose, filterString), debugDebugger, infoDebugger); + return step(initialStep); + function sibling(name, initial) { + return append(spawned, createLogger(label, key2.replace(/^[^:]+/, name), initial, infoDebugger)); + } + function step(phase) { + const stepPrefix = phase && `[${phase}]` || ""; + const debug22 = debugDebugger && prefixedLogger(debugDebugger, stepPrefix) || NOOP; + const info = prefixedLogger(infoDebugger, `${labelPrefix} ${stepPrefix}`, debug22); + return Object.assign(debugDebugger ? debug22 : info, { + label, + sibling, + info, + step + }); + } +} +var init_git_logger = __esm2({ + "src/lib/git-logger.ts"() { + init_utils(); + import_debug.default.formatters.L = (value) => String(filterHasLength(value) ? value.length : "-"); + import_debug.default.formatters.B = (value) => { + if (Buffer.isBuffer(value)) { + return value.toString("utf8"); + } + return objectToString(value); + }; + } +}); +var _TasksPendingQueue; +var TasksPendingQueue; +var init_tasks_pending_queue = __esm2({ + "src/lib/runners/tasks-pending-queue.ts"() { + init_git_error(); + init_git_logger(); + _TasksPendingQueue = class { + constructor(logLabel = "GitExecutor") { + this.logLabel = logLabel; + this._queue = /* @__PURE__ */ new Map(); + } + withProgress(task) { + return this._queue.get(task); + } + createProgress(task) { + const name = _TasksPendingQueue.getName(task.commands[0]); + const logger = createLogger(this.logLabel, name); + return { + task, + logger, + name + }; + } + push(task) { + const progress = this.createProgress(task); + progress.logger("Adding task to the queue, commands = %o", task.commands); + this._queue.set(task, progress); + return progress; + } + fatal(err) { + for (const [task, { logger }] of Array.from(this._queue.entries())) { + if (task === err.task) { + logger.info(`Failed %o`, err); + logger(`Fatal exception, any as-yet un-started tasks run through this executor will not be attempted`); + } else { + logger.info(`A fatal exception occurred in a previous task, the queue has been purged: %o`, err.message); + } + this.complete(task); + } + if (this._queue.size !== 0) { + throw new Error(`Queue size should be zero after fatal: ${this._queue.size}`); + } + } + complete(task) { + const progress = this.withProgress(task); + if (progress) { + this._queue.delete(task); + } + } + attempt(task) { + const progress = this.withProgress(task); + if (!progress) { + throw new GitError(void 0, "TasksPendingQueue: attempt called for an unknown task"); + } + progress.logger("Starting task"); + return progress; + } + static getName(name = "empty") { + return `task:${name}:${++_TasksPendingQueue.counter}`; + } + }; + TasksPendingQueue = _TasksPendingQueue; + TasksPendingQueue.counter = 0; + } +}); +function pluginContext(task, commands) { + return { + method: first(task.commands) || "", + commands + }; +} +function onErrorReceived(target, logger) { + return (err) => { + logger(`[ERROR] child process exception %o`, err); + target.push(Buffer.from(String(err.stack), "ascii")); + }; +} +function onDataReceived(target, name, logger, output) { + return (buffer2) => { + logger(`%s received %L bytes`, name, buffer2); + output(`%B`, buffer2); + target.push(buffer2); + }; +} +var GitExecutorChain; +var init_git_executor_chain = __esm2({ + "src/lib/runners/git-executor-chain.ts"() { + init_git_error(); + init_task(); + init_utils(); + init_tasks_pending_queue(); + GitExecutorChain = class { + constructor(_executor, _scheduler, _plugins) { + this._executor = _executor; + this._scheduler = _scheduler; + this._plugins = _plugins; + this._chain = Promise.resolve(); + this._queue = new TasksPendingQueue(); + } + get binary() { + return this._executor.binary; + } + get cwd() { + return this._cwd || this._executor.cwd; + } + set cwd(cwd) { + this._cwd = cwd; + } + get env() { + return this._executor.env; + } + get outputHandler() { + return this._executor.outputHandler; + } + chain() { + return this; + } + push(task) { + this._queue.push(task); + return this._chain = this._chain.then(() => this.attemptTask(task)); + } + attemptTask(task) { + return __async(this, null, function* () { + const onScheduleComplete = yield this._scheduler.next(); + const onQueueComplete = () => this._queue.complete(task); + try { + const { logger } = this._queue.attempt(task); + return yield isEmptyTask(task) ? this.attemptEmptyTask(task, logger) : this.attemptRemoteTask(task, logger); + } catch (e) { + throw this.onFatalException(task, e); + } finally { + onQueueComplete(); + onScheduleComplete(); + } + }); + } + onFatalException(task, e) { + const gitError = e instanceof GitError ? Object.assign(e, { task }) : new GitError(task, e && String(e)); + this._chain = Promise.resolve(); + this._queue.fatal(gitError); + return gitError; + } + attemptRemoteTask(task, logger) { + return __async(this, null, function* () { + const args = this._plugins.exec("spawn.args", [...task.commands], pluginContext(task, task.commands)); + const raw = yield this.gitResponse(task, this.binary, args, this.outputHandler, logger.step("SPAWN")); + const outputStreams = yield this.handleTaskData(task, args, raw, logger.step("HANDLE")); + logger(`passing response to task's parser as a %s`, task.format); + if (isBufferTask(task)) { + return callTaskParser(task.parser, outputStreams); + } + return callTaskParser(task.parser, outputStreams.asStrings()); + }); + } + attemptEmptyTask(task, logger) { + return __async(this, null, function* () { + logger(`empty task bypassing child process to call to task's parser`); + return task.parser(this); + }); + } + handleTaskData(task, args, result, logger) { + const { exitCode, rejection, stdOut, stdErr } = result; + return new Promise((done, fail) => { + logger(`Preparing to handle process response exitCode=%d stdOut=`, exitCode); + const { error } = this._plugins.exec("task.error", { error: rejection }, __spreadValues(__spreadValues({}, pluginContext(task, args)), result)); + if (error && task.onError) { + logger.info(`exitCode=%s handling with custom error handler`); + return task.onError(result, error, (newStdOut) => { + logger.info(`custom error handler treated as success`); + logger(`custom error returned a %s`, objectToString(newStdOut)); + done(new GitOutputStreams(Array.isArray(newStdOut) ? Buffer.concat(newStdOut) : newStdOut, Buffer.concat(stdErr))); + }, fail); + } + if (error) { + logger.info(`handling as error: exitCode=%s stdErr=%s rejection=%o`, exitCode, stdErr.length, rejection); + return fail(error); + } + logger.info(`retrieving task output complete`); + done(new GitOutputStreams(Buffer.concat(stdOut), Buffer.concat(stdErr))); + }); + } + gitResponse(task, command, args, outputHandler, logger) { + return __async(this, null, function* () { + const outputLogger = logger.sibling("output"); + const spawnOptions = this._plugins.exec("spawn.options", { + cwd: this.cwd, + env: this.env, + windowsHide: true + }, pluginContext(task, task.commands)); + return new Promise((done) => { + const stdOut = []; + const stdErr = []; + logger.info(`%s %o`, command, args); + logger("%O", spawnOptions); + let rejection = this._beforeSpawn(task, args); + if (rejection) { + return done({ + stdOut, + stdErr, + exitCode: 9901, + rejection + }); + } + this._plugins.exec("spawn.before", void 0, __spreadProps(__spreadValues({}, pluginContext(task, args)), { + kill(reason) { + rejection = reason || rejection; + } + })); + const spawned = (0, import_child_process.spawn)(command, args, spawnOptions); + spawned.stdout.on("data", onDataReceived(stdOut, "stdOut", logger, outputLogger.step("stdOut"))); + spawned.stderr.on("data", onDataReceived(stdErr, "stdErr", logger, outputLogger.step("stdErr"))); + spawned.on("error", onErrorReceived(stdErr, logger)); + if (outputHandler) { + logger(`Passing child process stdOut/stdErr to custom outputHandler`); + outputHandler(command, spawned.stdout, spawned.stderr, [...args]); + } + this._plugins.exec("spawn.after", void 0, __spreadProps(__spreadValues({}, pluginContext(task, args)), { + spawned, + close(exitCode, reason) { + done({ + stdOut, + stdErr, + exitCode, + rejection: rejection || reason + }); + }, + kill(reason) { + if (spawned.killed) { + return; + } + rejection = reason; + spawned.kill("SIGINT"); + } + })); + }); + }); + } + _beforeSpawn(task, args) { + let rejection; + this._plugins.exec("spawn.before", void 0, __spreadProps(__spreadValues({}, pluginContext(task, args)), { + kill(reason) { + rejection = reason || rejection; + } + })); + return rejection; + } + }; + } +}); +var git_executor_exports = {}; +__export2(git_executor_exports, { + GitExecutor: () => GitExecutor +}); +var GitExecutor; +var init_git_executor = __esm2({ + "src/lib/runners/git-executor.ts"() { + init_git_executor_chain(); + GitExecutor = class { + constructor(binary = "git", cwd, _scheduler, _plugins) { + this.binary = binary; + this.cwd = cwd; + this._scheduler = _scheduler; + this._plugins = _plugins; + this._chain = new GitExecutorChain(this, this._scheduler, this._plugins); + } + chain() { + return new GitExecutorChain(this, this._scheduler, this._plugins); + } + push(task) { + return this._chain.push(task); + } + }; + } +}); +function taskCallback(task, response, callback = NOOP) { + const onSuccess = (data) => { + callback(null, data); + }; + const onError2 = (err) => { + if ((err == null ? void 0 : err.task) === task) { + callback(err instanceof GitResponseError ? addDeprecationNoticeToError(err) : err, void 0); + } + }; + response.then(onSuccess, onError2); +} +function addDeprecationNoticeToError(err) { + let log2 = (name) => { + console.warn(`simple-git deprecation notice: accessing GitResponseError.${name} should be GitResponseError.git.${name}, this will no longer be available in version 3`); + log2 = NOOP; + }; + return Object.create(err, Object.getOwnPropertyNames(err.git).reduce(descriptorReducer, {})); + function descriptorReducer(all, name) { + if (name in err) { + return all; + } + all[name] = { + enumerable: false, + configurable: false, + get() { + log2(name); + return err.git[name]; + } + }; + return all; + } +} +var init_task_callback = __esm2({ + "src/lib/task-callback.ts"() { + init_git_response_error(); + init_utils(); + } +}); +function changeWorkingDirectoryTask(directory, root2) { + return adhocExecTask((instance10) => { + if (!folderExists(directory)) { + throw new Error(`Git.cwd: cannot change to non-directory "${directory}"`); + } + return (root2 || instance10).cwd = directory; + }); +} +var init_change_working_directory = __esm2({ + "src/lib/tasks/change-working-directory.ts"() { + init_utils(); + init_task(); + } +}); +function checkoutTask(args) { + const commands = ["checkout", ...args]; + if (commands[1] === "-b" && commands.includes("-B")) { + commands[1] = remove2(commands, "-B"); + } + return straightThroughStringTask(commands); +} +function checkout_default() { + return { + checkout() { + return this._runTask(checkoutTask(getTrailingOptions(arguments, 1)), trailingFunctionArgument(arguments)); + }, + checkoutBranch(branchName, startPoint) { + return this._runTask(checkoutTask(["-b", branchName, startPoint, ...getTrailingOptions(arguments)]), trailingFunctionArgument(arguments)); + }, + checkoutLocalBranch(branchName) { + return this._runTask(checkoutTask(["-b", branchName, ...getTrailingOptions(arguments)]), trailingFunctionArgument(arguments)); + } + }; +} +var init_checkout = __esm2({ + "src/lib/tasks/checkout.ts"() { + init_utils(); + init_task(); + } +}); +function parseCommitResult(stdOut) { + const result = { + author: null, + branch: "", + commit: "", + root: false, + summary: { + changes: 0, + insertions: 0, + deletions: 0 + } + }; + return parseStringResponse(result, parsers, stdOut); +} +var parsers; +var init_parse_commit = __esm2({ + "src/lib/parsers/parse-commit.ts"() { + init_utils(); + parsers = [ + new LineParser(/^\[([^\s]+)( \([^)]+\))? ([^\]]+)/, (result, [branch2, root2, commit2]) => { + result.branch = branch2; + result.commit = commit2; + result.root = !!root2; + }), + new LineParser(/\s*Author:\s(.+)/i, (result, [author]) => { + const parts = author.split("<"); + const email = parts.pop(); + if (!email || !email.includes("@")) { + return; + } + result.author = { + email: email.substr(0, email.length - 1), + name: parts.join("<").trim() + }; + }), + new LineParser(/(\d+)[^,]*(?:,\s*(\d+)[^,]*)(?:,\s*(\d+))/g, (result, [changes, insertions, deletions]) => { + result.summary.changes = parseInt(changes, 10) || 0; + result.summary.insertions = parseInt(insertions, 10) || 0; + result.summary.deletions = parseInt(deletions, 10) || 0; + }), + new LineParser(/^(\d+)[^,]*(?:,\s*(\d+)[^(]+\(([+-]))?/, (result, [changes, lines, direction]) => { + result.summary.changes = parseInt(changes, 10) || 0; + const count = parseInt(lines, 10) || 0; + if (direction === "-") { + result.summary.deletions = count; + } else if (direction === "+") { + result.summary.insertions = count; + } + }) + ]; + } +}); +function commitTask(message, files, customArgs) { + const commands = [ + "-c", + "core.abbrev=40", + "commit", + ...prefixedArray(message, "-m"), + ...files, + ...customArgs + ]; + return { + commands, + format: "utf-8", + parser: parseCommitResult + }; +} +function commit_default() { + return { + commit(message, ...rest) { + const next = trailingFunctionArgument(arguments); + const task = rejectDeprecatedSignatures(message) || commitTask(asArray(message), asArray(filterType(rest[0], filterStringOrStringArray, [])), [...filterType(rest[1], filterArray, []), ...getTrailingOptions(arguments, 0, true)]); + return this._runTask(task, next); + } + }; + function rejectDeprecatedSignatures(message) { + return !filterStringOrStringArray(message) && configurationErrorTask(`git.commit: requires the commit message to be supplied as a string/string[]`); + } +} +var init_commit = __esm2({ + "src/lib/tasks/commit.ts"() { + init_parse_commit(); + init_utils(); + init_task(); + } +}); +function hashObjectTask(filePath, write) { + const commands = ["hash-object", filePath]; + if (write) { + commands.push("-w"); + } + return straightThroughStringTask(commands, true); +} +var init_hash_object = __esm2({ + "src/lib/tasks/hash-object.ts"() { + init_task(); + } +}); +function parseInit(bare, path2, text2) { + const response = String(text2).trim(); + let result; + if (result = initResponseRegex.exec(response)) { + return new InitSummary(bare, path2, false, result[1]); + } + if (result = reInitResponseRegex.exec(response)) { + return new InitSummary(bare, path2, true, result[1]); + } + let gitDir = ""; + const tokens = response.split(" "); + while (tokens.length) { + const token = tokens.shift(); + if (token === "in") { + gitDir = tokens.join(" "); + break; + } + } + return new InitSummary(bare, path2, /^re/i.test(response), gitDir); +} +var InitSummary; +var initResponseRegex; +var reInitResponseRegex; +var init_InitSummary = __esm2({ + "src/lib/responses/InitSummary.ts"() { + InitSummary = class { + constructor(bare, path2, existing, gitDir) { + this.bare = bare; + this.path = path2; + this.existing = existing; + this.gitDir = gitDir; + } + }; + initResponseRegex = /^Init.+ repository in (.+)$/; + reInitResponseRegex = /^Rein.+ in (.+)$/; + } +}); +function hasBareCommand(command) { + return command.includes(bareCommand); +} +function initTask(bare = false, path2, customArgs) { + const commands = ["init", ...customArgs]; + if (bare && !hasBareCommand(commands)) { + commands.splice(1, 0, bareCommand); + } + return { + commands, + format: "utf-8", + parser(text2) { + return parseInit(commands.includes("--bare"), path2, text2); + } + }; +} +var bareCommand; +var init_init = __esm2({ + "src/lib/tasks/init.ts"() { + init_InitSummary(); + bareCommand = "--bare"; + } +}); +function logFormatFromCommand(customArgs) { + for (let i = 0; i < customArgs.length; i++) { + const format = logFormatRegex.exec(customArgs[i]); + if (format) { + return `--${format[1]}`; + } + } + return ""; +} +function isLogFormat(customArg) { + return logFormatRegex.test(customArg); +} +var logFormatRegex; +var init_log_format = __esm2({ + "src/lib/args/log-format.ts"() { + logFormatRegex = /^--(stat|numstat|name-only|name-status)(=|$)/; + } +}); +var DiffSummary; +var init_DiffSummary = __esm2({ + "src/lib/responses/DiffSummary.ts"() { + DiffSummary = class { + constructor() { + this.changed = 0; + this.deletions = 0; + this.insertions = 0; + this.files = []; + } + }; + } +}); +function getDiffParser(format = "") { + const parser3 = diffSummaryParsers[format]; + return (stdOut) => parseStringResponse(new DiffSummary(), parser3, stdOut, false); +} +var statParser; +var numStatParser; +var nameOnlyParser; +var nameStatusParser; +var diffSummaryParsers; +var init_parse_diff_summary = __esm2({ + "src/lib/parsers/parse-diff-summary.ts"() { + init_log_format(); + init_DiffSummary(); + init_utils(); + statParser = [ + new LineParser(/(.+)\s+\|\s+(\d+)(\s+[+\-]+)?$/, (result, [file, changes, alterations = ""]) => { + result.files.push({ + file: file.trim(), + changes: asNumber(changes), + insertions: alterations.replace(/[^+]/g, "").length, + deletions: alterations.replace(/[^-]/g, "").length, + binary: false + }); + }), + new LineParser(/(.+) \|\s+Bin ([0-9.]+) -> ([0-9.]+) ([a-z]+)/, (result, [file, before, after]) => { + result.files.push({ + file: file.trim(), + before: asNumber(before), + after: asNumber(after), + binary: true + }); + }), + new LineParser(/(\d+) files? changed\s*((?:, \d+ [^,]+){0,2})/, (result, [changed, summary]) => { + const inserted = /(\d+) i/.exec(summary); + const deleted = /(\d+) d/.exec(summary); + result.changed = asNumber(changed); + result.insertions = asNumber(inserted == null ? void 0 : inserted[1]); + result.deletions = asNumber(deleted == null ? void 0 : deleted[1]); + }) + ]; + numStatParser = [ + new LineParser(/(\d+)\t(\d+)\t(.+)$/, (result, [changesInsert, changesDelete, file]) => { + const insertions = asNumber(changesInsert); + const deletions = asNumber(changesDelete); + result.changed++; + result.insertions += insertions; + result.deletions += deletions; + result.files.push({ + file, + changes: insertions + deletions, + insertions, + deletions, + binary: false + }); + }), + new LineParser(/-\t-\t(.+)$/, (result, [file]) => { + result.changed++; + result.files.push({ + file, + after: 0, + before: 0, + binary: true + }); + }) + ]; + nameOnlyParser = [ + new LineParser(/(.+)$/, (result, [file]) => { + result.changed++; + result.files.push({ + file, + changes: 0, + insertions: 0, + deletions: 0, + binary: false + }); + }) + ]; + nameStatusParser = [ + new LineParser(/([ACDMRTUXB])([0-9][0-9][0-9])?\t(.[^\t]+)\t?(.*)?$/, (result, [status2, _similarity, from, to]) => { + result.changed++; + result.files.push({ + file: to != null ? to : from, + changes: 0, + status: status2, + insertions: 0, + deletions: 0, + binary: false + }); + }) + ]; + diffSummaryParsers = { + [ + "" + /* NONE */ + ]: statParser, + [ + "--stat" + /* STAT */ + ]: statParser, + [ + "--numstat" + /* NUM_STAT */ + ]: numStatParser, + [ + "--name-status" + /* NAME_STATUS */ + ]: nameStatusParser, + [ + "--name-only" + /* NAME_ONLY */ + ]: nameOnlyParser + }; + } +}); +function lineBuilder(tokens, fields) { + return fields.reduce((line, field, index2) => { + line[field] = tokens[index2] || ""; + return line; + }, /* @__PURE__ */ Object.create({ diff: null })); +} +function createListLogSummaryParser(splitter = SPLITTER, fields = defaultFieldNames, logFormat = "") { + const parseDiffResult = getDiffParser(logFormat); + return function(stdOut) { + const all = toLinesWithContent(stdOut, true, START_BOUNDARY).map(function(item) { + const lineDetail = item.trim().split(COMMIT_BOUNDARY); + const listLogLine = lineBuilder(lineDetail[0].trim().split(splitter), fields); + if (lineDetail.length > 1 && !!lineDetail[1].trim()) { + listLogLine.diff = parseDiffResult(lineDetail[1]); + } + return listLogLine; + }); + return { + all, + latest: all.length && all[0] || null, + total: all.length + }; + }; +} +var START_BOUNDARY; +var COMMIT_BOUNDARY; +var SPLITTER; +var defaultFieldNames; +var init_parse_list_log_summary = __esm2({ + "src/lib/parsers/parse-list-log-summary.ts"() { + init_utils(); + init_parse_diff_summary(); + init_log_format(); + START_BOUNDARY = "\xF2\xF2\xF2\xF2\xF2\xF2 "; + COMMIT_BOUNDARY = " \xF2\xF2"; + SPLITTER = " \xF2 "; + defaultFieldNames = ["hash", "date", "message", "refs", "author_name", "author_email"]; + } +}); +var diff_exports = {}; +__export2(diff_exports, { + diffSummaryTask: () => diffSummaryTask, + validateLogFormatConfig: () => validateLogFormatConfig +}); +function diffSummaryTask(customArgs) { + let logFormat = logFormatFromCommand(customArgs); + const commands = ["diff"]; + if (logFormat === "") { + logFormat = "--stat"; + commands.push("--stat=4096"); + } + commands.push(...customArgs); + return validateLogFormatConfig(commands) || { + commands, + format: "utf-8", + parser: getDiffParser(logFormat) + }; +} +function validateLogFormatConfig(customArgs) { + const flags = customArgs.filter(isLogFormat); + if (flags.length > 1) { + return configurationErrorTask(`Summary flags are mutually exclusive - pick one of ${flags.join(",")}`); + } + if (flags.length && customArgs.includes("-z")) { + return configurationErrorTask(`Summary flag ${flags} parsing is not compatible with null termination option '-z'`); + } +} +var init_diff = __esm2({ + "src/lib/tasks/diff.ts"() { + init_log_format(); + init_parse_diff_summary(); + init_task(); + } +}); +function prettyFormat(format, splitter) { + const fields = []; + const formatStr = []; + Object.keys(format).forEach((field) => { + fields.push(field); + formatStr.push(String(format[field])); + }); + return [fields, formatStr.join(splitter)]; +} +function userOptions(input) { + return Object.keys(input).reduce((out, key2) => { + if (!(key2 in excludeOptions)) { + out[key2] = input[key2]; + } + return out; + }, {}); +} +function parseLogOptions(opt = {}, customArgs = []) { + const splitter = filterType(opt.splitter, filterString, SPLITTER); + const format = !filterPrimitives(opt.format) && opt.format ? opt.format : { + hash: "%H", + date: opt.strictDate === false ? "%ai" : "%aI", + message: "%s", + refs: "%D", + body: opt.multiLine ? "%B" : "%b", + author_name: opt.mailMap !== false ? "%aN" : "%an", + author_email: opt.mailMap !== false ? "%aE" : "%ae" + }; + const [fields, formatStr] = prettyFormat(format, splitter); + const suffix = []; + const command = [ + `--pretty=format:${START_BOUNDARY}${formatStr}${COMMIT_BOUNDARY}`, + ...customArgs + ]; + const maxCount = opt.n || opt["max-count"] || opt.maxCount; + if (maxCount) { + command.push(`--max-count=${maxCount}`); + } + if (opt.from || opt.to) { + const rangeOperator = opt.symmetric !== false ? "..." : ".."; + suffix.push(`${opt.from || ""}${rangeOperator}${opt.to || ""}`); + } + if (filterString(opt.file)) { + suffix.push("--follow", opt.file); + } + appendTaskOptions(userOptions(opt), command); + return { + fields, + splitter, + commands: [...command, ...suffix] + }; +} +function logTask(splitter, fields, customArgs) { + const parser3 = createListLogSummaryParser(splitter, fields, logFormatFromCommand(customArgs)); + return { + commands: ["log", ...customArgs], + format: "utf-8", + parser: parser3 + }; +} +function log_default() { + return { + log(...rest) { + const next = trailingFunctionArgument(arguments); + const options = parseLogOptions(trailingOptionsArgument(arguments), filterType(arguments[0], filterArray)); + const task = rejectDeprecatedSignatures(...rest) || validateLogFormatConfig(options.commands) || createLogTask(options); + return this._runTask(task, next); + } + }; + function createLogTask(options) { + return logTask(options.splitter, options.fields, options.commands); + } + function rejectDeprecatedSignatures(from, to) { + return filterString(from) && filterString(to) && configurationErrorTask(`git.log(string, string) should be replaced with git.log({ from: string, to: string })`); + } +} +var excludeOptions; +var init_log = __esm2({ + "src/lib/tasks/log.ts"() { + init_log_format(); + init_parse_list_log_summary(); + init_utils(); + init_task(); + init_diff(); + excludeOptions = /* @__PURE__ */ ((excludeOptions2) => { + excludeOptions2[excludeOptions2["--pretty"] = 0] = "--pretty"; + excludeOptions2[excludeOptions2["max-count"] = 1] = "max-count"; + excludeOptions2[excludeOptions2["maxCount"] = 2] = "maxCount"; + excludeOptions2[excludeOptions2["n"] = 3] = "n"; + excludeOptions2[excludeOptions2["file"] = 4] = "file"; + excludeOptions2[excludeOptions2["format"] = 5] = "format"; + excludeOptions2[excludeOptions2["from"] = 6] = "from"; + excludeOptions2[excludeOptions2["to"] = 7] = "to"; + excludeOptions2[excludeOptions2["splitter"] = 8] = "splitter"; + excludeOptions2[excludeOptions2["symmetric"] = 9] = "symmetric"; + excludeOptions2[excludeOptions2["mailMap"] = 10] = "mailMap"; + excludeOptions2[excludeOptions2["multiLine"] = 11] = "multiLine"; + excludeOptions2[excludeOptions2["strictDate"] = 12] = "strictDate"; + return excludeOptions2; + })(excludeOptions || {}); + } +}); +var MergeSummaryConflict; +var MergeSummaryDetail; +var init_MergeSummary = __esm2({ + "src/lib/responses/MergeSummary.ts"() { + MergeSummaryConflict = class { + constructor(reason, file = null, meta) { + this.reason = reason; + this.file = file; + this.meta = meta; + } + toString() { + return `${this.file}:${this.reason}`; + } + }; + MergeSummaryDetail = class { + constructor() { + this.conflicts = []; + this.merges = []; + this.result = "success"; + } + get failed() { + return this.conflicts.length > 0; + } + get reason() { + return this.result; + } + toString() { + if (this.conflicts.length) { + return `CONFLICTS: ${this.conflicts.join(", ")}`; + } + return "OK"; + } + }; + } +}); +var PullSummary; +var PullFailedSummary; +var init_PullSummary = __esm2({ + "src/lib/responses/PullSummary.ts"() { + PullSummary = class { + constructor() { + this.remoteMessages = { + all: [] + }; + this.created = []; + this.deleted = []; + this.files = []; + this.deletions = {}; + this.insertions = {}; + this.summary = { + changes: 0, + deletions: 0, + insertions: 0 + }; + } + }; + PullFailedSummary = class { + constructor() { + this.remote = ""; + this.hash = { + local: "", + remote: "" + }; + this.branch = { + local: "", + remote: "" + }; + this.message = ""; + } + toString() { + return this.message; + } + }; + } +}); +function objectEnumerationResult(remoteMessages) { + return remoteMessages.objects = remoteMessages.objects || { + compressing: 0, + counting: 0, + enumerating: 0, + packReused: 0, + reused: { count: 0, delta: 0 }, + total: { count: 0, delta: 0 } + }; +} +function asObjectCount(source) { + const count = /^\s*(\d+)/.exec(source); + const delta = /delta (\d+)/i.exec(source); + return { + count: asNumber(count && count[1] || "0"), + delta: asNumber(delta && delta[1] || "0") + }; +} +var remoteMessagesObjectParsers; +var init_parse_remote_objects = __esm2({ + "src/lib/parsers/parse-remote-objects.ts"() { + init_utils(); + remoteMessagesObjectParsers = [ + new RemoteLineParser(/^remote:\s*(enumerating|counting|compressing) objects: (\d+),/i, (result, [action, count]) => { + const key2 = action.toLowerCase(); + const enumeration = objectEnumerationResult(result.remoteMessages); + Object.assign(enumeration, { [key2]: asNumber(count) }); + }), + new RemoteLineParser(/^remote:\s*(enumerating|counting|compressing) objects: \d+% \(\d+\/(\d+)\),/i, (result, [action, count]) => { + const key2 = action.toLowerCase(); + const enumeration = objectEnumerationResult(result.remoteMessages); + Object.assign(enumeration, { [key2]: asNumber(count) }); + }), + new RemoteLineParser(/total ([^,]+), reused ([^,]+), pack-reused (\d+)/i, (result, [total, reused, packReused]) => { + const objects = objectEnumerationResult(result.remoteMessages); + objects.total = asObjectCount(total); + objects.reused = asObjectCount(reused); + objects.packReused = asNumber(packReused); + }) + ]; + } +}); +function parseRemoteMessages(_stdOut, stdErr) { + return parseStringResponse({ remoteMessages: new RemoteMessageSummary() }, parsers2, stdErr); +} +var parsers2; +var RemoteMessageSummary; +var init_parse_remote_messages = __esm2({ + "src/lib/parsers/parse-remote-messages.ts"() { + init_utils(); + init_parse_remote_objects(); + parsers2 = [ + new RemoteLineParser(/^remote:\s*(.+)$/, (result, [text2]) => { + result.remoteMessages.all.push(text2.trim()); + return false; + }), + ...remoteMessagesObjectParsers, + new RemoteLineParser([/create a (?:pull|merge) request/i, /\s(https?:\/\/\S+)$/], (result, [pullRequestUrl]) => { + result.remoteMessages.pullRequestUrl = pullRequestUrl; + }), + new RemoteLineParser([/found (\d+) vulnerabilities.+\(([^)]+)\)/i, /\s(https?:\/\/\S+)$/], (result, [count, summary, url]) => { + result.remoteMessages.vulnerabilities = { + count: asNumber(count), + summary, + url + }; + }) + ]; + RemoteMessageSummary = class { + constructor() { + this.all = []; + } + }; + } +}); +function parsePullErrorResult(stdOut, stdErr) { + const pullError = parseStringResponse(new PullFailedSummary(), errorParsers, [stdOut, stdErr]); + return pullError.message && pullError; +} +var FILE_UPDATE_REGEX; +var SUMMARY_REGEX; +var ACTION_REGEX; +var parsers3; +var errorParsers; +var parsePullDetail; +var parsePullResult; +var init_parse_pull = __esm2({ + "src/lib/parsers/parse-pull.ts"() { + init_PullSummary(); + init_utils(); + init_parse_remote_messages(); + FILE_UPDATE_REGEX = /^\s*(.+?)\s+\|\s+\d+\s*(\+*)(-*)/; + SUMMARY_REGEX = /(\d+)\D+((\d+)\D+\(\+\))?(\D+(\d+)\D+\(-\))?/; + ACTION_REGEX = /^(create|delete) mode \d+ (.+)/; + parsers3 = [ + new LineParser(FILE_UPDATE_REGEX, (result, [file, insertions, deletions]) => { + result.files.push(file); + if (insertions) { + result.insertions[file] = insertions.length; + } + if (deletions) { + result.deletions[file] = deletions.length; + } + }), + new LineParser(SUMMARY_REGEX, (result, [changes, , insertions, , deletions]) => { + if (insertions !== void 0 || deletions !== void 0) { + result.summary.changes = +changes || 0; + result.summary.insertions = +insertions || 0; + result.summary.deletions = +deletions || 0; + return true; + } + return false; + }), + new LineParser(ACTION_REGEX, (result, [action, file]) => { + append(result.files, file); + append(action === "create" ? result.created : result.deleted, file); + }) + ]; + errorParsers = [ + new LineParser(/^from\s(.+)$/i, (result, [remote]) => void (result.remote = remote)), + new LineParser(/^fatal:\s(.+)$/, (result, [message]) => void (result.message = message)), + new LineParser(/([a-z0-9]+)\.\.([a-z0-9]+)\s+(\S+)\s+->\s+(\S+)$/, (result, [hashLocal, hashRemote, branchLocal, branchRemote]) => { + result.branch.local = branchLocal; + result.hash.local = hashLocal; + result.branch.remote = branchRemote; + result.hash.remote = hashRemote; + }) + ]; + parsePullDetail = (stdOut, stdErr) => { + return parseStringResponse(new PullSummary(), parsers3, [stdOut, stdErr]); + }; + parsePullResult = (stdOut, stdErr) => { + return Object.assign(new PullSummary(), parsePullDetail(stdOut, stdErr), parseRemoteMessages(stdOut, stdErr)); + }; + } +}); +var parsers4; +var parseMergeResult; +var parseMergeDetail; +var init_parse_merge = __esm2({ + "src/lib/parsers/parse-merge.ts"() { + init_MergeSummary(); + init_utils(); + init_parse_pull(); + parsers4 = [ + new LineParser(/^Auto-merging\s+(.+)$/, (summary, [autoMerge]) => { + summary.merges.push(autoMerge); + }), + new LineParser(/^CONFLICT\s+\((.+)\): Merge conflict in (.+)$/, (summary, [reason, file]) => { + summary.conflicts.push(new MergeSummaryConflict(reason, file)); + }), + new LineParser(/^CONFLICT\s+\((.+\/delete)\): (.+) deleted in (.+) and/, (summary, [reason, file, deleteRef2]) => { + summary.conflicts.push(new MergeSummaryConflict(reason, file, { deleteRef: deleteRef2 })); + }), + new LineParser(/^CONFLICT\s+\((.+)\):/, (summary, [reason]) => { + summary.conflicts.push(new MergeSummaryConflict(reason, null)); + }), + new LineParser(/^Automatic merge failed;\s+(.+)$/, (summary, [result]) => { + summary.result = result; + }) + ]; + parseMergeResult = (stdOut, stdErr) => { + return Object.assign(parseMergeDetail(stdOut, stdErr), parsePullResult(stdOut, stdErr)); + }; + parseMergeDetail = (stdOut) => { + return parseStringResponse(new MergeSummaryDetail(), parsers4, stdOut); + }; + } +}); +function mergeTask(customArgs) { + if (!customArgs.length) { + return configurationErrorTask("Git.merge requires at least one option"); + } + return { + commands: ["merge", ...customArgs], + format: "utf-8", + parser(stdOut, stdErr) { + const merge2 = parseMergeResult(stdOut, stdErr); + if (merge2.failed) { + throw new GitResponseError(merge2); + } + return merge2; + } + }; +} +var init_merge = __esm2({ + "src/lib/tasks/merge.ts"() { + init_git_response_error(); + init_parse_merge(); + init_task(); + } +}); +function pushResultPushedItem(local, remote, status2) { + const deleted = status2.includes("deleted"); + const tag2 = status2.includes("tag") || /^refs\/tags/.test(local); + const alreadyUpdated = !status2.includes("new"); + return { + deleted, + tag: tag2, + branch: !tag2, + new: !alreadyUpdated, + alreadyUpdated, + local, + remote + }; +} +var parsers5; +var parsePushResult; +var parsePushDetail; +var init_parse_push = __esm2({ + "src/lib/parsers/parse-push.ts"() { + init_utils(); + init_parse_remote_messages(); + parsers5 = [ + new LineParser(/^Pushing to (.+)$/, (result, [repo]) => { + result.repo = repo; + }), + new LineParser(/^updating local tracking ref '(.+)'/, (result, [local]) => { + result.ref = __spreadProps(__spreadValues({}, result.ref || {}), { + local + }); + }), + new LineParser(/^[=*-]\s+([^:]+):(\S+)\s+\[(.+)]$/, (result, [local, remote, type]) => { + result.pushed.push(pushResultPushedItem(local, remote, type)); + }), + new LineParser(/^Branch '([^']+)' set up to track remote branch '([^']+)' from '([^']+)'/, (result, [local, remote, remoteName]) => { + result.branch = __spreadProps(__spreadValues({}, result.branch || {}), { + local, + remote, + remoteName + }); + }), + new LineParser(/^([^:]+):(\S+)\s+([a-z0-9]+)\.\.([a-z0-9]+)$/, (result, [local, remote, from, to]) => { + result.update = { + head: { + local, + remote + }, + hash: { + from, + to + } + }; + }) + ]; + parsePushResult = (stdOut, stdErr) => { + const pushDetail = parsePushDetail(stdOut, stdErr); + const responseDetail = parseRemoteMessages(stdOut, stdErr); + return __spreadValues(__spreadValues({}, pushDetail), responseDetail); + }; + parsePushDetail = (stdOut, stdErr) => { + return parseStringResponse({ pushed: [] }, parsers5, [stdOut, stdErr]); + }; + } +}); +var push_exports = {}; +__export2(push_exports, { + pushTagsTask: () => pushTagsTask, + pushTask: () => pushTask +}); +function pushTagsTask(ref = {}, customArgs) { + append(customArgs, "--tags"); + return pushTask(ref, customArgs); +} +function pushTask(ref = {}, customArgs) { + const commands = ["push", ...customArgs]; + if (ref.branch) { + commands.splice(1, 0, ref.branch); + } + if (ref.remote) { + commands.splice(1, 0, ref.remote); + } + remove2(commands, "-v"); + append(commands, "--verbose"); + append(commands, "--porcelain"); + return { + commands, + format: "utf-8", + parser: parsePushResult + }; +} +var init_push = __esm2({ + "src/lib/tasks/push.ts"() { + init_parse_push(); + init_utils(); + } +}); +var fromPathRegex; +var FileStatusSummary; +var init_FileStatusSummary = __esm2({ + "src/lib/responses/FileStatusSummary.ts"() { + fromPathRegex = /^(.+) -> (.+)$/; + FileStatusSummary = class { + constructor(path2, index2, working_dir) { + this.path = path2; + this.index = index2; + this.working_dir = working_dir; + if (index2 + working_dir === "R") { + const detail = fromPathRegex.exec(path2) || [null, path2, path2]; + this.from = detail[1] || ""; + this.path = detail[2] || ""; + } + } + }; + } +}); +function renamedFile(line) { + const [to, from] = line.split(NULL); + return { + from: from || to, + to + }; +} +function parser2(indexX, indexY, handler) { + return [`${indexX}${indexY}`, handler]; +} +function conflicts(indexX, ...indexY) { + return indexY.map((y) => parser2(indexX, y, (result, file) => append(result.conflicted, file))); +} +function splitLine(result, lineStr) { + const trimmed2 = lineStr.trim(); + switch (" ") { + case trimmed2.charAt(2): + return data(trimmed2.charAt(0), trimmed2.charAt(1), trimmed2.substr(3)); + case trimmed2.charAt(1): + return data(" ", trimmed2.charAt(0), trimmed2.substr(2)); + default: + return; + } + function data(index2, workingDir, path2) { + const raw = `${index2}${workingDir}`; + const handler = parsers6.get(raw); + if (handler) { + handler(result, path2); + } + if (raw !== "##" && raw !== "!!") { + result.files.push(new FileStatusSummary(path2.replace(/\0.+$/, ""), index2, workingDir)); + } + } +} +var StatusSummary; +var parsers6; +var parseStatusSummary; +var init_StatusSummary = __esm2({ + "src/lib/responses/StatusSummary.ts"() { + init_utils(); + init_FileStatusSummary(); + StatusSummary = class { + constructor() { + this.not_added = []; + this.conflicted = []; + this.created = []; + this.deleted = []; + this.ignored = void 0; + this.modified = []; + this.renamed = []; + this.files = []; + this.staged = []; + this.ahead = 0; + this.behind = 0; + this.current = null; + this.tracking = null; + this.detached = false; + this.isClean = () => { + return !this.files.length; + }; + } + }; + parsers6 = new Map([ + parser2(" ", "A", (result, file) => append(result.created, file)), + parser2(" ", "D", (result, file) => append(result.deleted, file)), + parser2(" ", "M", (result, file) => append(result.modified, file)), + parser2("A", " ", (result, file) => append(result.created, file) && append(result.staged, file)), + parser2("A", "M", (result, file) => append(result.created, file) && append(result.staged, file) && append(result.modified, file)), + parser2("D", " ", (result, file) => append(result.deleted, file) && append(result.staged, file)), + parser2("M", " ", (result, file) => append(result.modified, file) && append(result.staged, file)), + parser2("M", "M", (result, file) => append(result.modified, file) && append(result.staged, file)), + parser2("R", " ", (result, file) => { + append(result.renamed, renamedFile(file)); + }), + parser2("R", "M", (result, file) => { + const renamed = renamedFile(file); + append(result.renamed, renamed); + append(result.modified, renamed.to); + }), + parser2("!", "!", (_result, _file) => { + append(_result.ignored = _result.ignored || [], _file); + }), + parser2("?", "?", (result, file) => append(result.not_added, file)), + ...conflicts( + "A", + "A", + "U" + /* UNMERGED */ + ), + ...conflicts( + "D", + "D", + "U" + /* UNMERGED */ + ), + ...conflicts( + "U", + "A", + "D", + "U" + /* UNMERGED */ + ), + [ + "##", + (result, line) => { + const aheadReg = /ahead (\d+)/; + const behindReg = /behind (\d+)/; + const currentReg = /^(.+?(?=(?:\.{3}|\s|$)))/; + const trackingReg = /\.{3}(\S*)/; + const onEmptyBranchReg = /\son\s([\S]+)$/; + let regexResult; + regexResult = aheadReg.exec(line); + result.ahead = regexResult && +regexResult[1] || 0; + regexResult = behindReg.exec(line); + result.behind = regexResult && +regexResult[1] || 0; + regexResult = currentReg.exec(line); + result.current = regexResult && regexResult[1]; + regexResult = trackingReg.exec(line); + result.tracking = regexResult && regexResult[1]; + regexResult = onEmptyBranchReg.exec(line); + result.current = regexResult && regexResult[1] || result.current; + result.detached = /\(no branch\)/.test(line); + } + ] + ]); + parseStatusSummary = function(text2) { + const lines = text2.split(NULL); + const status2 = new StatusSummary(); + for (let i = 0, l = lines.length; i < l; ) { + let line = lines[i++].trim(); + if (!line) { + continue; + } + if (line.charAt(0) === "R") { + line += NULL + (lines[i++] || ""); + } + splitLine(status2, line); + } + return status2; + }; + } +}); +function statusTask(customArgs) { + const commands = [ + "status", + "--porcelain", + "-b", + "-u", + "--null", + ...customArgs.filter((arg) => !ignoredOptions.includes(arg)) + ]; + return { + format: "utf-8", + commands, + parser(text2) { + return parseStatusSummary(text2); + } + }; +} +var ignoredOptions; +var init_status = __esm2({ + "src/lib/tasks/status.ts"() { + init_StatusSummary(); + ignoredOptions = ["--null", "-z"]; + } +}); +function versionResponse(major = 0, minor = 0, patch = 0, agent = "", installed = true) { + return Object.defineProperty({ + major, + minor, + patch, + agent, + installed + }, "toString", { + value() { + return `${this.major}.${this.minor}.${this.patch}`; + }, + configurable: false, + enumerable: false + }); +} +function notInstalledResponse() { + return versionResponse(0, 0, 0, "", false); +} +function version_default() { + return { + version() { + return this._runTask({ + commands: ["--version"], + format: "utf-8", + parser: versionParser, + onError(result, error, done, fail) { + if (result.exitCode === -2) { + return done(Buffer.from(NOT_INSTALLED)); + } + fail(error); + } + }); + } + }; +} +function versionParser(stdOut) { + if (stdOut === NOT_INSTALLED) { + return notInstalledResponse(); + } + return parseStringResponse(versionResponse(0, 0, 0, stdOut), parsers7, stdOut); +} +var NOT_INSTALLED; +var parsers7; +var init_version = __esm2({ + "src/lib/tasks/version.ts"() { + init_utils(); + NOT_INSTALLED = "installed=false"; + parsers7 = [ + new LineParser(/version (\d+)\.(\d+)\.(\d+)(?:\s*\((.+)\))?/, (result, [major, minor, patch, agent = ""]) => { + Object.assign(result, versionResponse(asNumber(major), asNumber(minor), asNumber(patch), agent)); + }), + new LineParser(/version (\d+)\.(\d+)\.(\D+)(.+)?$/, (result, [major, minor, patch, agent = ""]) => { + Object.assign(result, versionResponse(asNumber(major), asNumber(minor), patch, agent)); + }) + ]; + } +}); +var simple_git_api_exports = {}; +__export2(simple_git_api_exports, { + SimpleGitApi: () => SimpleGitApi +}); +var SimpleGitApi; +var init_simple_git_api = __esm2({ + "src/lib/simple-git-api.ts"() { + init_task_callback(); + init_change_working_directory(); + init_checkout(); + init_commit(); + init_config(); + init_grep(); + init_hash_object(); + init_init(); + init_log(); + init_merge(); + init_push(); + init_status(); + init_task(); + init_version(); + init_utils(); + SimpleGitApi = class { + constructor(_executor) { + this._executor = _executor; + } + _runTask(task, then) { + const chain = this._executor.chain(); + const promise2 = chain.push(task); + if (then) { + taskCallback(task, promise2, then); + } + return Object.create(this, { + then: { value: promise2.then.bind(promise2) }, + catch: { value: promise2.catch.bind(promise2) }, + _executor: { value: chain } + }); + } + add(files) { + return this._runTask(straightThroughStringTask(["add", ...asArray(files)]), trailingFunctionArgument(arguments)); + } + cwd(directory) { + const next = trailingFunctionArgument(arguments); + if (typeof directory === "string") { + return this._runTask(changeWorkingDirectoryTask(directory, this._executor), next); + } + if (typeof (directory == null ? void 0 : directory.path) === "string") { + return this._runTask(changeWorkingDirectoryTask(directory.path, directory.root && this._executor || void 0), next); + } + return this._runTask(configurationErrorTask("Git.cwd: workingDirectory must be supplied as a string"), next); + } + hashObject(path2, write) { + return this._runTask(hashObjectTask(path2, write === true), trailingFunctionArgument(arguments)); + } + init(bare) { + return this._runTask(initTask(bare === true, this._executor.cwd, getTrailingOptions(arguments)), trailingFunctionArgument(arguments)); + } + merge() { + return this._runTask(mergeTask(getTrailingOptions(arguments)), trailingFunctionArgument(arguments)); + } + mergeFromTo(remote, branch2) { + if (!(filterString(remote) && filterString(branch2))) { + return this._runTask(configurationErrorTask(`Git.mergeFromTo requires that the 'remote' and 'branch' arguments are supplied as strings`)); + } + return this._runTask(mergeTask([remote, branch2, ...getTrailingOptions(arguments)]), trailingFunctionArgument(arguments, false)); + } + outputHandler(handler) { + this._executor.outputHandler = handler; + return this; + } + push() { + const task = pushTask({ + remote: filterType(arguments[0], filterString), + branch: filterType(arguments[1], filterString) + }, getTrailingOptions(arguments)); + return this._runTask(task, trailingFunctionArgument(arguments)); + } + stash() { + return this._runTask(straightThroughStringTask(["stash", ...getTrailingOptions(arguments)]), trailingFunctionArgument(arguments)); + } + status() { + return this._runTask(statusTask(getTrailingOptions(arguments)), trailingFunctionArgument(arguments)); + } + }; + Object.assign(SimpleGitApi.prototype, checkout_default(), commit_default(), config_default(), grep_default(), log_default(), version_default()); + } +}); +var scheduler_exports = {}; +__export2(scheduler_exports, { + Scheduler: () => Scheduler +}); +var createScheduledTask; +var Scheduler; +var init_scheduler = __esm2({ + "src/lib/runners/scheduler.ts"() { + init_utils(); + init_git_logger(); + createScheduledTask = (() => { + let id = 0; + return () => { + id++; + const { promise: promise2, done } = (0, import_promise_deferred.createDeferred)(); + return { + promise: promise2, + done, + id + }; + }; + })(); + Scheduler = class { + constructor(concurrency = 2) { + this.concurrency = concurrency; + this.logger = createLogger("", "scheduler"); + this.pending = []; + this.running = []; + this.logger(`Constructed, concurrency=%s`, concurrency); + } + schedule() { + if (!this.pending.length || this.running.length >= this.concurrency) { + this.logger(`Schedule attempt ignored, pending=%s running=%s concurrency=%s`, this.pending.length, this.running.length, this.concurrency); + return; + } + const task = append(this.running, this.pending.shift()); + this.logger(`Attempting id=%s`, task.id); + task.done(() => { + this.logger(`Completing id=`, task.id); + remove2(this.running, task); + this.schedule(); + }); + } + next() { + const { promise: promise2, id } = append(this.pending, createScheduledTask()); + this.logger(`Scheduling id=%s`, id); + this.schedule(); + return promise2; + } + }; + } +}); +var apply_patch_exports = {}; +__export2(apply_patch_exports, { + applyPatchTask: () => applyPatchTask +}); +function applyPatchTask(patches, customArgs) { + return straightThroughStringTask(["apply", ...customArgs, ...patches]); +} +var init_apply_patch = __esm2({ + "src/lib/tasks/apply-patch.ts"() { + init_task(); + } +}); +function branchDeletionSuccess(branch2, hash2) { + return { + branch: branch2, + hash: hash2, + success: true + }; +} +function branchDeletionFailure(branch2) { + return { + branch: branch2, + hash: null, + success: false + }; +} +var BranchDeletionBatch; +var init_BranchDeleteSummary = __esm2({ + "src/lib/responses/BranchDeleteSummary.ts"() { + BranchDeletionBatch = class { + constructor() { + this.all = []; + this.branches = {}; + this.errors = []; + } + get success() { + return !this.errors.length; + } + }; + } +}); +function hasBranchDeletionError(data, processExitCode) { + return processExitCode === 1 && deleteErrorRegex.test(data); +} +var deleteSuccessRegex; +var deleteErrorRegex; +var parsers8; +var parseBranchDeletions; +var init_parse_branch_delete = __esm2({ + "src/lib/parsers/parse-branch-delete.ts"() { + init_BranchDeleteSummary(); + init_utils(); + deleteSuccessRegex = /(\S+)\s+\(\S+\s([^)]+)\)/; + deleteErrorRegex = /^error[^']+'([^']+)'/m; + parsers8 = [ + new LineParser(deleteSuccessRegex, (result, [branch2, hash2]) => { + const deletion = branchDeletionSuccess(branch2, hash2); + result.all.push(deletion); + result.branches[branch2] = deletion; + }), + new LineParser(deleteErrorRegex, (result, [branch2]) => { + const deletion = branchDeletionFailure(branch2); + result.errors.push(deletion); + result.all.push(deletion); + result.branches[branch2] = deletion; + }) + ]; + parseBranchDeletions = (stdOut, stdErr) => { + return parseStringResponse(new BranchDeletionBatch(), parsers8, [stdOut, stdErr]); + }; + } +}); +var BranchSummaryResult; +var init_BranchSummary = __esm2({ + "src/lib/responses/BranchSummary.ts"() { + BranchSummaryResult = class { + constructor() { + this.all = []; + this.branches = {}; + this.current = ""; + this.detached = false; + } + push(status2, detached, name, commit2, label) { + if (status2 === "*") { + this.detached = detached; + this.current = name; + } + this.all.push(name); + this.branches[name] = { + current: status2 === "*", + linkedWorkTree: status2 === "+", + name, + commit: commit2, + label + }; + } + }; + } +}); +function branchStatus(input) { + return input ? input.charAt(0) : ""; +} +function parseBranchSummary(stdOut) { + return parseStringResponse(new BranchSummaryResult(), parsers9, stdOut); +} +var parsers9; +var init_parse_branch = __esm2({ + "src/lib/parsers/parse-branch.ts"() { + init_BranchSummary(); + init_utils(); + parsers9 = [ + new LineParser(/^([*+]\s)?\((?:HEAD )?detached (?:from|at) (\S+)\)\s+([a-z0-9]+)\s(.*)$/, (result, [current, name, commit2, label]) => { + result.push(branchStatus(current), true, name, commit2, label); + }), + new LineParser(/^([*+]\s)?(\S+)\s+([a-z0-9]+)\s?(.*)$/s, (result, [current, name, commit2, label]) => { + result.push(branchStatus(current), false, name, commit2, label); + }) + ]; + } +}); +var branch_exports = {}; +__export2(branch_exports, { + branchLocalTask: () => branchLocalTask, + branchTask: () => branchTask, + containsDeleteBranchCommand: () => containsDeleteBranchCommand, + deleteBranchTask: () => deleteBranchTask, + deleteBranchesTask: () => deleteBranchesTask +}); +function containsDeleteBranchCommand(commands) { + const deleteCommands = ["-d", "-D", "--delete"]; + return commands.some((command) => deleteCommands.includes(command)); +} +function branchTask(customArgs) { + const isDelete = containsDeleteBranchCommand(customArgs); + const commands = ["branch", ...customArgs]; + if (commands.length === 1) { + commands.push("-a"); + } + if (!commands.includes("-v")) { + commands.splice(1, 0, "-v"); + } + return { + format: "utf-8", + commands, + parser(stdOut, stdErr) { + if (isDelete) { + return parseBranchDeletions(stdOut, stdErr).all[0]; + } + return parseBranchSummary(stdOut); + } + }; +} +function branchLocalTask() { + const parser3 = parseBranchSummary; + return { + format: "utf-8", + commands: ["branch", "-v"], + parser: parser3 + }; +} +function deleteBranchesTask(branches, forceDelete = false) { + return { + format: "utf-8", + commands: ["branch", "-v", forceDelete ? "-D" : "-d", ...branches], + parser(stdOut, stdErr) { + return parseBranchDeletions(stdOut, stdErr); + }, + onError({ exitCode, stdOut }, error, done, fail) { + if (!hasBranchDeletionError(String(error), exitCode)) { + return fail(error); + } + done(stdOut); + } + }; +} +function deleteBranchTask(branch2, forceDelete = false) { + const task = { + format: "utf-8", + commands: ["branch", "-v", forceDelete ? "-D" : "-d", branch2], + parser(stdOut, stdErr) { + return parseBranchDeletions(stdOut, stdErr).branches[branch2]; + }, + onError({ exitCode, stdErr, stdOut }, error, _, fail) { + if (!hasBranchDeletionError(String(error), exitCode)) { + return fail(error); + } + throw new GitResponseError(task.parser(bufferToString(stdOut), bufferToString(stdErr)), String(error)); + } + }; + return task; +} +var init_branch = __esm2({ + "src/lib/tasks/branch.ts"() { + init_git_response_error(); + init_parse_branch_delete(); + init_parse_branch(); + init_utils(); + } +}); +var parseCheckIgnore; +var init_CheckIgnore = __esm2({ + "src/lib/responses/CheckIgnore.ts"() { + parseCheckIgnore = (text2) => { + return text2.split(/\n/g).map((line) => line.trim()).filter((file) => !!file); + }; + } +}); +var check_ignore_exports = {}; +__export2(check_ignore_exports, { + checkIgnoreTask: () => checkIgnoreTask +}); +function checkIgnoreTask(paths) { + return { + commands: ["check-ignore", ...paths], + format: "utf-8", + parser: parseCheckIgnore + }; +} +var init_check_ignore = __esm2({ + "src/lib/tasks/check-ignore.ts"() { + init_CheckIgnore(); + } +}); +var clone_exports = {}; +__export2(clone_exports, { + cloneMirrorTask: () => cloneMirrorTask, + cloneTask: () => cloneTask +}); +function disallowedCommand(command) { + return /^--upload-pack(=|$)/.test(command); +} +function cloneTask(repo, directory, customArgs) { + const commands = ["clone", ...customArgs]; + filterString(repo) && commands.push(repo); + filterString(directory) && commands.push(directory); + const banned = commands.find(disallowedCommand); + if (banned) { + return configurationErrorTask(`git.fetch: potential exploit argument blocked.`); + } + return straightThroughStringTask(commands); +} +function cloneMirrorTask(repo, directory, customArgs) { + append(customArgs, "--mirror"); + return cloneTask(repo, directory, customArgs); +} +var init_clone = __esm2({ + "src/lib/tasks/clone.ts"() { + init_task(); + init_utils(); + } +}); +function parseFetchResult(stdOut, stdErr) { + const result = { + raw: stdOut, + remote: null, + branches: [], + tags: [], + updated: [], + deleted: [] + }; + return parseStringResponse(result, parsers10, [stdOut, stdErr]); +} +var parsers10; +var init_parse_fetch = __esm2({ + "src/lib/parsers/parse-fetch.ts"() { + init_utils(); + parsers10 = [ + new LineParser(/From (.+)$/, (result, [remote]) => { + result.remote = remote; + }), + new LineParser(/\* \[new branch]\s+(\S+)\s*-> (.+)$/, (result, [name, tracking]) => { + result.branches.push({ + name, + tracking + }); + }), + new LineParser(/\* \[new tag]\s+(\S+)\s*-> (.+)$/, (result, [name, tracking]) => { + result.tags.push({ + name, + tracking + }); + }), + new LineParser(/- \[deleted]\s+\S+\s*-> (.+)$/, (result, [tracking]) => { + result.deleted.push({ + tracking + }); + }), + new LineParser(/\s*([^.]+)\.\.(\S+)\s+(\S+)\s*-> (.+)$/, (result, [from, to, name, tracking]) => { + result.updated.push({ + name, + tracking, + to, + from + }); + }) + ]; + } +}); +var fetch_exports = {}; +__export2(fetch_exports, { + fetchTask: () => fetchTask +}); +function disallowedCommand2(command) { + return /^--upload-pack(=|$)/.test(command); +} +function fetchTask(remote, branch2, customArgs) { + const commands = ["fetch", ...customArgs]; + if (remote && branch2) { + commands.push(remote, branch2); + } + const banned = commands.find(disallowedCommand2); + if (banned) { + return configurationErrorTask(`git.fetch: potential exploit argument blocked.`); + } + return { + commands, + format: "utf-8", + parser: parseFetchResult + }; +} +var init_fetch = __esm2({ + "src/lib/tasks/fetch.ts"() { + init_parse_fetch(); + init_task(); + } +}); +function parseMoveResult(stdOut) { + return parseStringResponse({ moves: [] }, parsers11, stdOut); +} +var parsers11; +var init_parse_move = __esm2({ + "src/lib/parsers/parse-move.ts"() { + init_utils(); + parsers11 = [ + new LineParser(/^Renaming (.+) to (.+)$/, (result, [from, to]) => { + result.moves.push({ from, to }); + }) + ]; + } +}); +var move_exports = {}; +__export2(move_exports, { + moveTask: () => moveTask +}); +function moveTask(from, to) { + return { + commands: ["mv", "-v", ...asArray(from), to], + format: "utf-8", + parser: parseMoveResult + }; +} +var init_move = __esm2({ + "src/lib/tasks/move.ts"() { + init_parse_move(); + init_utils(); + } +}); +var pull_exports = {}; +__export2(pull_exports, { + pullTask: () => pullTask +}); +function pullTask(remote, branch2, customArgs) { + const commands = ["pull", ...customArgs]; + if (remote && branch2) { + commands.splice(1, 0, remote, branch2); + } + return { + commands, + format: "utf-8", + parser(stdOut, stdErr) { + return parsePullResult(stdOut, stdErr); + }, + onError(result, _error, _done, fail) { + const pullError = parsePullErrorResult(bufferToString(result.stdOut), bufferToString(result.stdErr)); + if (pullError) { + return fail(new GitResponseError(pullError)); + } + fail(_error); + } + }; +} +var init_pull = __esm2({ + "src/lib/tasks/pull.ts"() { + init_git_response_error(); + init_parse_pull(); + init_utils(); + } +}); +function parseGetRemotes(text2) { + const remotes = {}; + forEach(text2, ([name]) => remotes[name] = { name }); + return Object.values(remotes); +} +function parseGetRemotesVerbose(text2) { + const remotes = {}; + forEach(text2, ([name, url, purpose]) => { + if (!remotes.hasOwnProperty(name)) { + remotes[name] = { + name, + refs: { fetch: "", push: "" } + }; + } + if (purpose && url) { + remotes[name].refs[purpose.replace(/[^a-z]/g, "")] = url; + } + }); + return Object.values(remotes); +} +function forEach(text2, handler) { + forEachLineWithContent(text2, (line) => handler(line.split(/\s+/))); +} +var init_GetRemoteSummary = __esm2({ + "src/lib/responses/GetRemoteSummary.ts"() { + init_utils(); + } +}); +var remote_exports = {}; +__export2(remote_exports, { + addRemoteTask: () => addRemoteTask, + getRemotesTask: () => getRemotesTask, + listRemotesTask: () => listRemotesTask, + remoteTask: () => remoteTask, + removeRemoteTask: () => removeRemoteTask +}); +function addRemoteTask(remoteName, remoteRepo, customArgs = []) { + return straightThroughStringTask(["remote", "add", ...customArgs, remoteName, remoteRepo]); +} +function getRemotesTask(verbose) { + const commands = ["remote"]; + if (verbose) { + commands.push("-v"); + } + return { + commands, + format: "utf-8", + parser: verbose ? parseGetRemotesVerbose : parseGetRemotes + }; +} +function listRemotesTask(customArgs = []) { + const commands = [...customArgs]; + if (commands[0] !== "ls-remote") { + commands.unshift("ls-remote"); + } + return straightThroughStringTask(commands); +} +function remoteTask(customArgs = []) { + const commands = [...customArgs]; + if (commands[0] !== "remote") { + commands.unshift("remote"); + } + return straightThroughStringTask(commands); +} +function removeRemoteTask(remoteName) { + return straightThroughStringTask(["remote", "remove", remoteName]); +} +var init_remote = __esm2({ + "src/lib/tasks/remote.ts"() { + init_GetRemoteSummary(); + init_task(); + } +}); +var stash_list_exports = {}; +__export2(stash_list_exports, { + stashListTask: () => stashListTask +}); +function stashListTask(opt = {}, customArgs) { + const options = parseLogOptions(opt); + const commands = ["stash", "list", ...options.commands, ...customArgs]; + const parser3 = createListLogSummaryParser(options.splitter, options.fields, logFormatFromCommand(commands)); + return validateLogFormatConfig(commands) || { + commands, + format: "utf-8", + parser: parser3 + }; +} +var init_stash_list = __esm2({ + "src/lib/tasks/stash-list.ts"() { + init_log_format(); + init_parse_list_log_summary(); + init_diff(); + init_log(); + } +}); +var sub_module_exports = {}; +__export2(sub_module_exports, { + addSubModuleTask: () => addSubModuleTask, + initSubModuleTask: () => initSubModuleTask, + subModuleTask: () => subModuleTask, + updateSubModuleTask: () => updateSubModuleTask +}); +function addSubModuleTask(repo, path2) { + return subModuleTask(["add", repo, path2]); +} +function initSubModuleTask(customArgs) { + return subModuleTask(["init", ...customArgs]); +} +function subModuleTask(customArgs) { + const commands = [...customArgs]; + if (commands[0] !== "submodule") { + commands.unshift("submodule"); + } + return straightThroughStringTask(commands); +} +function updateSubModuleTask(customArgs) { + return subModuleTask(["update", ...customArgs]); +} +var init_sub_module = __esm2({ + "src/lib/tasks/sub-module.ts"() { + init_task(); + } +}); +function singleSorted(a, b) { + const aIsNum = isNaN(a); + const bIsNum = isNaN(b); + if (aIsNum !== bIsNum) { + return aIsNum ? 1 : -1; + } + return aIsNum ? sorted(a, b) : 0; +} +function sorted(a, b) { + return a === b ? 0 : a > b ? 1 : -1; +} +function trimmed(input) { + return input.trim(); +} +function toNumber(input) { + if (typeof input === "string") { + return parseInt(input.replace(/^\D+/g, ""), 10) || 0; + } + return 0; +} +var TagList; +var parseTagList; +var init_TagList = __esm2({ + "src/lib/responses/TagList.ts"() { + TagList = class { + constructor(all, latest) { + this.all = all; + this.latest = latest; + } + }; + parseTagList = function(data, customSort = false) { + const tags = data.split("\n").map(trimmed).filter(Boolean); + if (!customSort) { + tags.sort(function(tagA, tagB) { + const partsA = tagA.split("."); + const partsB = tagB.split("."); + if (partsA.length === 1 || partsB.length === 1) { + return singleSorted(toNumber(partsA[0]), toNumber(partsB[0])); + } + for (let i = 0, l = Math.max(partsA.length, partsB.length); i < l; i++) { + const diff2 = sorted(toNumber(partsA[i]), toNumber(partsB[i])); + if (diff2) { + return diff2; + } + } + return 0; + }); + } + const latest = customSort ? tags[0] : [...tags].reverse().find((tag2) => tag2.indexOf(".") >= 0); + return new TagList(tags, latest); + }; + } +}); +var tag_exports = {}; +__export2(tag_exports, { + addAnnotatedTagTask: () => addAnnotatedTagTask, + addTagTask: () => addTagTask, + tagListTask: () => tagListTask +}); +function tagListTask(customArgs = []) { + const hasCustomSort = customArgs.some((option) => /^--sort=/.test(option)); + return { + format: "utf-8", + commands: ["tag", "-l", ...customArgs], + parser(text2) { + return parseTagList(text2, hasCustomSort); + } + }; +} +function addTagTask(name) { + return { + format: "utf-8", + commands: ["tag", name], + parser() { + return { name }; + } + }; +} +function addAnnotatedTagTask(name, tagMessage) { + return { + format: "utf-8", + commands: ["tag", "-a", "-m", tagMessage, name], + parser() { + return { name }; + } + }; +} +var init_tag = __esm2({ + "src/lib/tasks/tag.ts"() { + init_TagList(); + } +}); +var require_git = __commonJS2({ + "src/git.js"(exports2, module2) { + var { GitExecutor: GitExecutor2 } = (init_git_executor(), __toCommonJS2(git_executor_exports)); + var { SimpleGitApi: SimpleGitApi2 } = (init_simple_git_api(), __toCommonJS2(simple_git_api_exports)); + var { Scheduler: Scheduler2 } = (init_scheduler(), __toCommonJS2(scheduler_exports)); + var { configurationErrorTask: configurationErrorTask2 } = (init_task(), __toCommonJS2(task_exports)); + var { + asArray: asArray2, + filterArray: filterArray2, + filterPrimitives: filterPrimitives2, + filterString: filterString2, + filterStringOrStringArray: filterStringOrStringArray2, + filterType: filterType2, + getTrailingOptions: getTrailingOptions2, + trailingFunctionArgument: trailingFunctionArgument2, + trailingOptionsArgument: trailingOptionsArgument2 + } = (init_utils(), __toCommonJS2(utils_exports)); + var { applyPatchTask: applyPatchTask2 } = (init_apply_patch(), __toCommonJS2(apply_patch_exports)); + var { + branchTask: branchTask2, + branchLocalTask: branchLocalTask2, + deleteBranchesTask: deleteBranchesTask2, + deleteBranchTask: deleteBranchTask2 + } = (init_branch(), __toCommonJS2(branch_exports)); + var { checkIgnoreTask: checkIgnoreTask2 } = (init_check_ignore(), __toCommonJS2(check_ignore_exports)); + var { checkIsRepoTask: checkIsRepoTask2 } = (init_check_is_repo(), __toCommonJS2(check_is_repo_exports)); + var { cloneTask: cloneTask2, cloneMirrorTask: cloneMirrorTask2 } = (init_clone(), __toCommonJS2(clone_exports)); + var { cleanWithOptionsTask: cleanWithOptionsTask2, isCleanOptionsArray: isCleanOptionsArray2 } = (init_clean(), __toCommonJS2(clean_exports)); + var { diffSummaryTask: diffSummaryTask2 } = (init_diff(), __toCommonJS2(diff_exports)); + var { fetchTask: fetchTask2 } = (init_fetch(), __toCommonJS2(fetch_exports)); + var { moveTask: moveTask2 } = (init_move(), __toCommonJS2(move_exports)); + var { pullTask: pullTask2 } = (init_pull(), __toCommonJS2(pull_exports)); + var { pushTagsTask: pushTagsTask2 } = (init_push(), __toCommonJS2(push_exports)); + var { + addRemoteTask: addRemoteTask2, + getRemotesTask: getRemotesTask2, + listRemotesTask: listRemotesTask2, + remoteTask: remoteTask2, + removeRemoteTask: removeRemoteTask2 + } = (init_remote(), __toCommonJS2(remote_exports)); + var { getResetMode: getResetMode2, resetTask: resetTask2 } = (init_reset(), __toCommonJS2(reset_exports)); + var { stashListTask: stashListTask2 } = (init_stash_list(), __toCommonJS2(stash_list_exports)); + var { + addSubModuleTask: addSubModuleTask2, + initSubModuleTask: initSubModuleTask2, + subModuleTask: subModuleTask2, + updateSubModuleTask: updateSubModuleTask2 + } = (init_sub_module(), __toCommonJS2(sub_module_exports)); + var { addAnnotatedTagTask: addAnnotatedTagTask2, addTagTask: addTagTask2, tagListTask: tagListTask2 } = (init_tag(), __toCommonJS2(tag_exports)); + var { straightThroughBufferTask: straightThroughBufferTask2, straightThroughStringTask: straightThroughStringTask2 } = (init_task(), __toCommonJS2(task_exports)); + function Git2(options, plugins) { + this._executor = new GitExecutor2(options.binary, options.baseDir, new Scheduler2(options.maxConcurrentProcesses), plugins); + this._trimmed = options.trimmed; + } + (Git2.prototype = Object.create(SimpleGitApi2.prototype)).constructor = Git2; + Git2.prototype.customBinary = function(command) { + this._executor.binary = command; + return this; + }; + Git2.prototype.env = function(name, value) { + if (arguments.length === 1 && typeof name === "object") { + this._executor.env = name; + } else { + (this._executor.env = this._executor.env || {})[name] = value; + } + return this; + }; + Git2.prototype.stashList = function(options) { + return this._runTask(stashListTask2(trailingOptionsArgument2(arguments) || {}, filterArray2(options) && options || []), trailingFunctionArgument2(arguments)); + }; + function createCloneTask(api, task, repoPath, localPath) { + if (typeof repoPath !== "string") { + return configurationErrorTask2(`git.${api}() requires a string 'repoPath'`); + } + return task(repoPath, filterType2(localPath, filterString2), getTrailingOptions2(arguments)); + } + Git2.prototype.clone = function() { + return this._runTask(createCloneTask("clone", cloneTask2, ...arguments), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.mirror = function() { + return this._runTask(createCloneTask("mirror", cloneMirrorTask2, ...arguments), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.mv = function(from, to) { + return this._runTask(moveTask2(from, to), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.checkoutLatestTag = function(then) { + var git = this; + return this.pull(function() { + git.tags(function(err, tags) { + git.checkout(tags.latest, then); + }); + }); + }; + Git2.prototype.pull = function(remote, branch2, options, then) { + return this._runTask(pullTask2(filterType2(remote, filterString2), filterType2(branch2, filterString2), getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.fetch = function(remote, branch2) { + return this._runTask(fetchTask2(filterType2(remote, filterString2), filterType2(branch2, filterString2), getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.silent = function(silence) { + console.warn("simple-git deprecation notice: git.silent: logging should be configured using the `debug` library / `DEBUG` environment variable, this will be an error in version 3"); + return this; + }; + Git2.prototype.tags = function(options, then) { + return this._runTask(tagListTask2(getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.rebase = function() { + return this._runTask(straightThroughStringTask2(["rebase", ...getTrailingOptions2(arguments)]), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.reset = function(mode) { + return this._runTask(resetTask2(getResetMode2(mode), getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.revert = function(commit2) { + const next = trailingFunctionArgument2(arguments); + if (typeof commit2 !== "string") { + return this._runTask(configurationErrorTask2("Commit must be a string"), next); + } + return this._runTask(straightThroughStringTask2(["revert", ...getTrailingOptions2(arguments, 0, true), commit2]), next); + }; + Git2.prototype.addTag = function(name) { + const task = typeof name === "string" ? addTagTask2(name) : configurationErrorTask2("Git.addTag requires a tag name"); + return this._runTask(task, trailingFunctionArgument2(arguments)); + }; + Git2.prototype.addAnnotatedTag = function(tagName, tagMessage) { + return this._runTask(addAnnotatedTagTask2(tagName, tagMessage), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.deleteLocalBranch = function(branchName, forceDelete, then) { + return this._runTask(deleteBranchTask2(branchName, typeof forceDelete === "boolean" ? forceDelete : false), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.deleteLocalBranches = function(branchNames, forceDelete, then) { + return this._runTask(deleteBranchesTask2(branchNames, typeof forceDelete === "boolean" ? forceDelete : false), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.branch = function(options, then) { + return this._runTask(branchTask2(getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.branchLocal = function(then) { + return this._runTask(branchLocalTask2(), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.raw = function(commands) { + const createRestCommands = !Array.isArray(commands); + const command = [].slice.call(createRestCommands ? arguments : commands, 0); + for (let i = 0; i < command.length && createRestCommands; i++) { + if (!filterPrimitives2(command[i])) { + command.splice(i, command.length - i); + break; + } + } + command.push(...getTrailingOptions2(arguments, 0, true)); + var next = trailingFunctionArgument2(arguments); + if (!command.length) { + return this._runTask(configurationErrorTask2("Raw: must supply one or more command to execute"), next); + } + return this._runTask(straightThroughStringTask2(command, this._trimmed), next); + }; + Git2.prototype.submoduleAdd = function(repo, path2, then) { + return this._runTask(addSubModuleTask2(repo, path2), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.submoduleUpdate = function(args, then) { + return this._runTask(updateSubModuleTask2(getTrailingOptions2(arguments, true)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.submoduleInit = function(args, then) { + return this._runTask(initSubModuleTask2(getTrailingOptions2(arguments, true)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.subModule = function(options, then) { + return this._runTask(subModuleTask2(getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.listRemote = function() { + return this._runTask(listRemotesTask2(getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.addRemote = function(remoteName, remoteRepo, then) { + return this._runTask(addRemoteTask2(remoteName, remoteRepo, getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.removeRemote = function(remoteName, then) { + return this._runTask(removeRemoteTask2(remoteName), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.getRemotes = function(verbose, then) { + return this._runTask(getRemotesTask2(verbose === true), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.remote = function(options, then) { + return this._runTask(remoteTask2(getTrailingOptions2(arguments)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.tag = function(options, then) { + const command = getTrailingOptions2(arguments); + if (command[0] !== "tag") { + command.unshift("tag"); + } + return this._runTask(straightThroughStringTask2(command), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.updateServerInfo = function(then) { + return this._runTask(straightThroughStringTask2(["update-server-info"]), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.pushTags = function(remote, then) { + const task = pushTagsTask2({ remote: filterType2(remote, filterString2) }, getTrailingOptions2(arguments)); + return this._runTask(task, trailingFunctionArgument2(arguments)); + }; + Git2.prototype.rm = function(files) { + return this._runTask(straightThroughStringTask2(["rm", "-f", ...asArray2(files)]), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.rmKeepLocal = function(files) { + return this._runTask(straightThroughStringTask2(["rm", "--cached", ...asArray2(files)]), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.catFile = function(options, then) { + return this._catFile("utf-8", arguments); + }; + Git2.prototype.binaryCatFile = function() { + return this._catFile("buffer", arguments); + }; + Git2.prototype._catFile = function(format, args) { + var handler = trailingFunctionArgument2(args); + var command = ["cat-file"]; + var options = args[0]; + if (typeof options === "string") { + return this._runTask(configurationErrorTask2("Git.catFile: options must be supplied as an array of strings"), handler); + } + if (Array.isArray(options)) { + command.push.apply(command, options); + } + const task = format === "buffer" ? straightThroughBufferTask2(command) : straightThroughStringTask2(command); + return this._runTask(task, handler); + }; + Git2.prototype.diff = function(options, then) { + const task = filterString2(options) ? configurationErrorTask2("git.diff: supplying options as a single string is no longer supported, switch to an array of strings") : straightThroughStringTask2(["diff", ...getTrailingOptions2(arguments)]); + return this._runTask(task, trailingFunctionArgument2(arguments)); + }; + Git2.prototype.diffSummary = function() { + return this._runTask(diffSummaryTask2(getTrailingOptions2(arguments, 1)), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.applyPatch = function(patches) { + const task = !filterStringOrStringArray2(patches) ? configurationErrorTask2(`git.applyPatch requires one or more string patches as the first argument`) : applyPatchTask2(asArray2(patches), getTrailingOptions2([].slice.call(arguments, 1))); + return this._runTask(task, trailingFunctionArgument2(arguments)); + }; + Git2.prototype.revparse = function() { + const commands = ["rev-parse", ...getTrailingOptions2(arguments, true)]; + return this._runTask(straightThroughStringTask2(commands, true), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.show = function(options, then) { + return this._runTask(straightThroughStringTask2(["show", ...getTrailingOptions2(arguments, 1)]), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.clean = function(mode, options, then) { + const usingCleanOptionsArray = isCleanOptionsArray2(mode); + const cleanMode = usingCleanOptionsArray && mode.join("") || filterType2(mode, filterString2) || ""; + const customArgs = getTrailingOptions2([].slice.call(arguments, usingCleanOptionsArray ? 1 : 0)); + return this._runTask(cleanWithOptionsTask2(cleanMode, customArgs), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.exec = function(then) { + const task = { + commands: [], + format: "utf-8", + parser() { + if (typeof then === "function") { + then(); + } + } + }; + return this._runTask(task); + }; + Git2.prototype.clearQueue = function() { + return this; + }; + Git2.prototype.checkIgnore = function(pathnames, then) { + return this._runTask(checkIgnoreTask2(asArray2(filterType2(pathnames, filterStringOrStringArray2, []))), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.checkIsRepo = function(checkType, then) { + return this._runTask(checkIsRepoTask2(filterType2(checkType, filterString2)), trailingFunctionArgument2(arguments)); + }; + module2.exports = Git2; + } +}); +init_git_error(); +var GitConstructError = class extends GitError { + constructor(config, message) { + super(void 0, message); + this.config = config; + } +}; +init_git_error(); +init_git_error(); +var GitPluginError = class extends GitError { + constructor(task, plugin, message) { + super(task, message); + this.task = task; + this.plugin = plugin; + Object.setPrototypeOf(this, new.target.prototype); + } +}; +init_git_response_error(); +init_task_configuration_error(); +init_check_is_repo(); +init_clean(); +init_config(); +init_grep(); +init_reset(); +function abortPlugin(signal) { + if (!signal) { + return; + } + const onSpawnAfter = { + type: "spawn.after", + action(_data, context) { + function kill() { + context.kill(new GitPluginError(void 0, "abort", "Abort signal received")); + } + signal.addEventListener("abort", kill); + context.spawned.on("close", () => signal.removeEventListener("abort", kill)); + } + }; + const onSpawnBefore = { + type: "spawn.before", + action(_data, context) { + if (signal.aborted) { + context.kill(new GitPluginError(void 0, "abort", "Abort already signaled")); + } + } + }; + return [onSpawnBefore, onSpawnAfter]; +} +function isConfigSwitch(arg) { + return typeof arg === "string" && arg.trim().toLowerCase() === "-c"; +} +function preventProtocolOverride(arg, next) { + if (!isConfigSwitch(arg)) { + return; + } + if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) { + return; + } + throw new GitPluginError(void 0, "unsafe", "Configuring protocol.allow is not permitted without enabling allowUnsafeExtProtocol"); +} +function preventUploadPack(arg, method2) { + if (/^\s*--(upload|receive)-pack/.test(arg)) { + throw new GitPluginError(void 0, "unsafe", `Use of --upload-pack or --receive-pack is not permitted without enabling allowUnsafePack`); + } + if (method2 === "clone" && /^\s*-u\b/.test(arg)) { + throw new GitPluginError(void 0, "unsafe", `Use of clone with option -u is not permitted without enabling allowUnsafePack`); + } + if (method2 === "push" && /^\s*--exec\b/.test(arg)) { + throw new GitPluginError(void 0, "unsafe", `Use of push with option --exec is not permitted without enabling allowUnsafePack`); + } +} +function blockUnsafeOperationsPlugin({ + allowUnsafeProtocolOverride = false, + allowUnsafePack = false +} = {}) { + return { + type: "spawn.args", + action(args, context) { + args.forEach((current, index2) => { + const next = index2 < args.length ? args[index2 + 1] : ""; + allowUnsafeProtocolOverride || preventProtocolOverride(current, next); + allowUnsafePack || preventUploadPack(current, context.method); + }); + return args; + } + }; +} +init_utils(); +function commandConfigPrefixingPlugin(configuration) { + const prefix = prefixedArray(configuration, "-c"); + return { + type: "spawn.args", + action(data) { + return [...prefix, ...data]; + } + }; +} +init_utils(); +var never = (0, import_promise_deferred2.deferred)().promise; +function completionDetectionPlugin({ + onClose = true, + onExit = 50 +} = {}) { + function createEvents() { + let exitCode = -1; + const events = { + close: (0, import_promise_deferred2.deferred)(), + closeTimeout: (0, import_promise_deferred2.deferred)(), + exit: (0, import_promise_deferred2.deferred)(), + exitTimeout: (0, import_promise_deferred2.deferred)() + }; + const result = Promise.race([ + onClose === false ? never : events.closeTimeout.promise, + onExit === false ? never : events.exitTimeout.promise + ]); + configureTimeout(onClose, events.close, events.closeTimeout); + configureTimeout(onExit, events.exit, events.exitTimeout); + return { + close(code) { + exitCode = code; + events.close.done(); + }, + exit(code) { + exitCode = code; + events.exit.done(); + }, + get exitCode() { + return exitCode; + }, + result + }; + } + function configureTimeout(flag, event, timeout) { + if (flag === false) { + return; + } + (flag === true ? event.promise : event.promise.then(() => delay(flag))).then(timeout.done); + } + return { + type: "spawn.after", + action(_0, _1) { + return __async(this, arguments, function* (_data, { spawned, close }) { + var _a2, _b; + const events = createEvents(); + let deferClose = true; + let quickClose = () => void (deferClose = false); + (_a2 = spawned.stdout) == null ? void 0 : _a2.on("data", quickClose); + (_b = spawned.stderr) == null ? void 0 : _b.on("data", quickClose); + spawned.on("error", quickClose); + spawned.on("close", (code) => events.close(code)); + spawned.on("exit", (code) => events.exit(code)); + try { + yield events.result; + if (deferClose) { + yield delay(50); + } + close(events.exitCode); + } catch (err) { + close(events.exitCode, err); + } + }); + } + }; +} +init_git_error(); +function isTaskError(result) { + return !!(result.exitCode && result.stdErr.length); +} +function getErrorMessage(result) { + return Buffer.concat([...result.stdOut, ...result.stdErr]); +} +function errorDetectionHandler(overwrite = false, isError = isTaskError, errorMessage = getErrorMessage) { + return (error, result) => { + if (!overwrite && error || !isError(result)) { + return error; + } + return errorMessage(result); + }; +} +function errorDetectionPlugin(config) { + return { + type: "task.error", + action(data, context) { + const error = config(data.error, { + stdErr: context.stdErr, + stdOut: context.stdOut, + exitCode: context.exitCode + }); + if (Buffer.isBuffer(error)) { + return { error: new GitError(void 0, error.toString("utf-8")) }; + } + return { + error + }; + } + }; +} +init_utils(); +var PluginStore = class { + constructor() { + this.plugins = /* @__PURE__ */ new Set(); + } + add(plugin) { + const plugins = []; + asArray(plugin).forEach((plugin2) => plugin2 && this.plugins.add(append(plugins, plugin2))); + return () => { + plugins.forEach((plugin2) => this.plugins.delete(plugin2)); + }; + } + exec(type, data, context) { + let output = data; + const contextual = Object.freeze(Object.create(context)); + for (const plugin of this.plugins) { + if (plugin.type === type) { + output = plugin.action(output, contextual); + } + } + return output; + } +}; +init_utils(); +function progressMonitorPlugin(progress) { + const progressCommand = "--progress"; + const progressMethods = ["checkout", "clone", "fetch", "pull", "push"]; + const onProgress = { + type: "spawn.after", + action(_data, context) { + var _a2; + if (!context.commands.includes(progressCommand)) { + return; + } + (_a2 = context.spawned.stderr) == null ? void 0 : _a2.on("data", (chunk) => { + const message = /^([\s\S]+?):\s*(\d+)% \((\d+)\/(\d+)\)/.exec(chunk.toString("utf8")); + if (!message) { + return; + } + progress({ + method: context.method, + stage: progressEventStage(message[1]), + progress: asNumber(message[2]), + processed: asNumber(message[3]), + total: asNumber(message[4]) + }); + }); + } + }; + const onArgs = { + type: "spawn.args", + action(args, context) { + if (!progressMethods.includes(context.method)) { + return args; + } + return including(args, progressCommand); + } + }; + return [onArgs, onProgress]; +} +function progressEventStage(input) { + return String(input.toLowerCase().split(" ", 1)) || "unknown"; +} +init_utils(); +function spawnOptionsPlugin(spawnOptions) { + const options = pick(spawnOptions, ["uid", "gid"]); + return { + type: "spawn.options", + action(data) { + return __spreadValues(__spreadValues({}, options), data); + } + }; +} +function timeoutPlugin({ + block, + stdErr = true, + stdOut = true +}) { + if (block > 0) { + return { + type: "spawn.after", + action(_data, context) { + var _a2, _b; + let timeout; + function wait3() { + timeout && clearTimeout(timeout); + timeout = setTimeout(kill, block); + } + function stop() { + var _a3, _b2; + (_a3 = context.spawned.stdout) == null ? void 0 : _a3.off("data", wait3); + (_b2 = context.spawned.stderr) == null ? void 0 : _b2.off("data", wait3); + context.spawned.off("exit", stop); + context.spawned.off("close", stop); + timeout && clearTimeout(timeout); + } + function kill() { + stop(); + context.kill(new GitPluginError(void 0, "timeout", `block timeout reached`)); + } + stdOut && ((_a2 = context.spawned.stdout) == null ? void 0 : _a2.on("data", wait3)); + stdErr && ((_b = context.spawned.stderr) == null ? void 0 : _b.on("data", wait3)); + context.spawned.on("exit", stop); + context.spawned.on("close", stop); + wait3(); + } + }; + } +} +init_utils(); +var Git = require_git(); +function gitInstanceFactory(baseDir, options) { + const plugins = new PluginStore(); + const config = createInstanceConfig(baseDir && (typeof baseDir === "string" ? { baseDir } : baseDir) || {}, options); + if (!folderExists(config.baseDir)) { + throw new GitConstructError(config, `Cannot use simple-git on a directory that does not exist`); + } + if (Array.isArray(config.config)) { + plugins.add(commandConfigPrefixingPlugin(config.config)); + } + plugins.add(blockUnsafeOperationsPlugin(config.unsafe)); + plugins.add(completionDetectionPlugin(config.completion)); + config.abort && plugins.add(abortPlugin(config.abort)); + config.progress && plugins.add(progressMonitorPlugin(config.progress)); + config.timeout && plugins.add(timeoutPlugin(config.timeout)); + config.spawnOptions && plugins.add(spawnOptionsPlugin(config.spawnOptions)); + plugins.add(errorDetectionPlugin(errorDetectionHandler(true))); + config.errors && plugins.add(errorDetectionPlugin(config.errors)); + return new Git(config, plugins); +} +init_git_response_error(); +var esm_default = gitInstanceFactory; + +// src/constants.ts +init_polyfill_buffer(); +var import_obsidian2 = require("obsidian"); +var DATE_FORMAT = "YYYY-MM-DD"; +var DATE_TIME_FORMAT_MINUTES = `${DATE_FORMAT} HH:mm`; +var DATE_TIME_FORMAT_SECONDS = `${DATE_FORMAT} HH:mm:ss`; +var GIT_LINE_AUTHORING_MOVEMENT_DETECTION_MINIMAL_LENGTH = 40; +var DEFAULT_SETTINGS = { + commitMessage: "vault backup: {{date}}", + commitDateFormat: DATE_TIME_FORMAT_SECONDS, + autoSaveInterval: 0, + autoPushInterval: 0, + autoPullInterval: 0, + autoPullOnBoot: false, + disablePush: false, + pullBeforePush: true, + disablePopups: false, + listChangedFilesInMessageBody: false, + showStatusBar: true, + updateSubmodules: false, + syncMethod: "merge", + customMessageOnAutoBackup: false, + autoBackupAfterFileChange: false, + treeStructure: false, + refreshSourceControl: import_obsidian2.Platform.isDesktopApp, + basePath: "", + differentIntervalCommitAndPush: false, + changedFilesInStatusBar: false, + showedMobileNotice: false, + refreshSourceControlTimer: 7e3, + showBranchStatusBar: true, + setLastSaveToLastCommit: false, + submoduleRecurseCheckout: false, + gitDir: "", + showFileMenu: true, + lineAuthor: { + show: false, + followMovement: "inactive", + authorDisplay: "initials", + showCommitHash: false, + dateTimeFormatOptions: "date", + dateTimeFormatCustomString: DATE_TIME_FORMAT_MINUTES, + dateTimeTimezone: "viewer-local", + coloringMaxAge: "1y", + // colors were picked via: + // https://color.adobe.com/de/create/color-accessibility + colorNew: { r: 255, g: 150, b: 150 }, + colorOld: { r: 120, g: 160, b: 255 }, + textColorCss: "var(--text-muted)", + // more pronounced than line numbers, but less than the content text + ignoreWhitespace: false, + gutterSpacingFallbackLength: 5 + } +}; +var SOURCE_CONTROL_VIEW_CONFIG = { + type: "git-view", + name: "Source Control", + icon: "git-pull-request" +}; +var HISTORY_VIEW_CONFIG = { + type: "git-history-view", + name: "History", + icon: "history" +}; +var DIFF_VIEW_CONFIG = { + type: "diff-view", + name: "Diff View", + icon: "git-pull-request" +}; + +// src/types.ts +init_polyfill_buffer(); +function mergeSettingsByPriority(low, high) { + const lineAuthor = Object.assign({}, low.lineAuthor, high.lineAuthor); + return Object.assign({}, low, high, { lineAuthor }); +} + +// src/utils.ts +init_polyfill_buffer(); +var cssColorConverter = __toESM(require_lib3()); +var import_deep_equal = __toESM(require_deep_equal()); +var import_obsidian3 = require("obsidian"); +var worthWalking2 = (filepath, root2) => { + if (filepath === "." || root2 == null || root2.length === 0 || root2 === ".") { + return true; + } + if (root2.length >= filepath.length) { + return root2.startsWith(filepath); + } else { + return filepath.startsWith(root2); + } +}; +function getNewLeaf(event) { + let leaf; + if (event) { + if (event.button === 0 || event.button === 1) { + const type = import_obsidian3.Keymap.isModEvent(event); + leaf = app.workspace.getLeaf(type); + } + } else { + leaf = app.workspace.getLeaf(false); + } + return leaf; +} +function impossibleBranch(x) { + throw new Error("Impossible branch: " + x); +} +function rgbToString(rgb) { + return `rgb(${rgb.r},${rgb.g},${rgb.b})`; +} +function convertToRgb(str) { + var _a2; + const color = (_a2 = cssColorConverter.fromString(str)) == null ? void 0 : _a2.toRgbaArray(); + if (color === void 0) { + return void 0; + } + const [r, g, b] = color; + return { r, g, b }; +} +function momentToEpochSeconds(instant) { + return instant.diff(import_obsidian3.moment.unix(0), "seconds"); +} +function median(array) { + if (array.length === 0) + return void 0; + return array.slice().sort()[Math.floor(array.length / 2)]; +} +function strictDeepEqual(a, b) { + return (0, import_deep_equal.default)(a, b, { strict: true }); +} +function resizeToLength(original, desiredLength, fillChar) { + if (original.length <= desiredLength) { + const prefix = new Array(desiredLength - original.length).fill(fillChar).join(""); + return prefix + original; + } else { + return original.substring(original.length - desiredLength); + } +} +function prefixOfLengthAsWhitespace(toBeRenderedText, whitespacePrefixLength) { + if (whitespacePrefixLength <= 0) + return toBeRenderedText; + const whitespacePrefix = new Array(whitespacePrefixLength).fill(" ").join(""); + const originalSuffix = toBeRenderedText.substring( + whitespacePrefixLength, + toBeRenderedText.length + ); + return whitespacePrefix + originalSuffix; +} +function between(l, x, r) { + return l <= x && x <= r; +} +function splitRemoteBranch(remoteBranch) { + const [remote, ...branch2] = remoteBranch.split("/"); + return [remote, branch2.length === 0 ? void 0 : branch2.join("/")]; +} +function getDisplayPath(path2) { + if (path2.endsWith("/")) + return path2; + return path2.split("/").last().replace(".md", ""); +} + +// src/gitManager/gitManager.ts +init_polyfill_buffer(); +var GitManager = class { + constructor(plugin) { + this.plugin = plugin; + this.app = plugin.app; + } + getVaultPath(path2) { + if (this.plugin.settings.basePath) { + return this.plugin.settings.basePath + "/" + path2; + } else { + return path2; + } + } + asRepositoryRelativePath(path2, relativeToVault) { + return relativeToVault && this.plugin.settings.basePath.length > 0 ? path2.substring(this.plugin.settings.basePath.length + 1) : path2; + } + _getTreeStructure(children2, beginLength = 0) { + const list = []; + children2 = [...children2]; + while (children2.length > 0) { + const first2 = children2.first(); + const restPath = first2.path.substring(beginLength); + if (restPath.contains("/")) { + const title = restPath.substring(0, restPath.indexOf("/")); + const childrenWithSameTitle = children2.filter((item) => { + return item.path.substring(beginLength).startsWith(title + "/"); + }); + childrenWithSameTitle.forEach((item) => children2.remove(item)); + const path2 = first2.path.substring( + 0, + restPath.indexOf("/") + beginLength + ); + list.push({ + title, + path: path2, + vaultPath: this.getVaultPath(path2), + children: this._getTreeStructure( + childrenWithSameTitle, + (beginLength > 0 ? beginLength + title.length : title.length) + 1 + ) + }); + } else { + list.push({ + title: restPath, + data: first2, + path: first2.path, + vaultPath: this.getVaultPath(first2.path) + }); + children2.remove(first2); + } + } + return list; + } + /* + * Sorts the children and simplifies the title + * If a node only contains another subdirectory, that subdirectory is moved up one level and integrated into the parent node + */ + simplify(tree) { + var _a2, _b, _c, _d; + for (const node of tree) { + while (true) { + const singleChild = ((_a2 = node.children) == null ? void 0 : _a2.length) == 1; + const singleChildIsDir = ((_c = (_b = node.children) == null ? void 0 : _b.first()) == null ? void 0 : _c.data) == void 0; + if (!(node.children != void 0 && singleChild && singleChildIsDir)) + break; + const child = node.children.first(); + node.title += "/" + child.title; + node.data = child.data; + node.path = child.path; + node.vaultPath = child.vaultPath; + node.children = child.children; + } + if (node.children != void 0) { + this.simplify(node.children); + } + (_d = node.children) == null ? void 0 : _d.sort((a, b) => { + const dirCompare = (b.data == void 0 ? 1 : 0) - (a.data == void 0 ? 1 : 0); + if (dirCompare != 0) { + return dirCompare; + } else { + return a.title.localeCompare(b.title); + } + }); + } + return tree.sort((a, b) => { + const dirCompare = (b.data == void 0 ? 1 : 0) - (a.data == void 0 ? 1 : 0); + if (dirCompare != 0) { + return dirCompare; + } else { + return a.title.localeCompare(b.title); + } + }); + } + getTreeStructure(children2) { + const tree = this._getTreeStructure(children2); + const res = this.simplify(tree); + return res; + } + async formatCommitMessage(template) { + let status2; + if (template.includes("{{numFiles}}")) { + status2 = await this.status(); + const numFiles = status2.staged.length; + template = template.replace("{{numFiles}}", String(numFiles)); + } + if (template.includes("{{hostname}}")) { + const hostname = this.plugin.localStorage.getHostname() || ""; + template = template.replace("{{hostname}}", hostname); + } + if (template.includes("{{files}}")) { + status2 = status2 != null ? status2 : await this.status(); + const changeset = {}; + status2.staged.forEach((value) => { + if (value.index in changeset) { + changeset[value.index].push(value.path); + } else { + changeset[value.index] = [value.path]; + } + }); + const chunks = []; + for (const [action, files2] of Object.entries(changeset)) { + chunks.push(action + " " + files2.join(" ")); + } + const files = chunks.join(", "); + template = template.replace("{{files}}", files); + } + const moment5 = window.moment; + template = template.replace( + "{{date}}", + moment5().format(this.plugin.settings.commitDateFormat) + ); + if (this.plugin.settings.listChangedFilesInMessageBody) { + template = template + "\n\nAffected files:\n" + (status2 != null ? status2 : await this.status()).staged.map((e) => e.path).join("\n"); + } + return template; + } +}; + +// src/gitManager/simpleGit.ts +var SimpleGit = class extends GitManager { + constructor(plugin) { + super(plugin); + } + async setGitInstance(ignoreError = false) { + if (this.isGitInstalled()) { + const adapter = this.app.vault.adapter; + const path2 = adapter.getBasePath(); + let basePath = path2; + if (this.plugin.settings.basePath) { + const exists2 = await adapter.exists( + (0, import_obsidian4.normalizePath)(this.plugin.settings.basePath) + ); + if (exists2) { + basePath = path2 + import_path.sep + this.plugin.settings.basePath; + } else if (!ignoreError) { + new import_obsidian4.Notice("ObsidianGit: Base path does not exist"); + } + } + this.git = esm_default({ + baseDir: basePath, + binary: this.plugin.localStorage.getGitPath() || void 0, + config: ["core.quotepath=off"] + }); + const pathPaths = this.plugin.localStorage.getPATHPaths(); + const envVars = this.plugin.localStorage.getEnvVars(); + const gitDir = this.plugin.settings.gitDir; + if (pathPaths.length > 0) { + const path3 = process.env["PATH"] + ":" + pathPaths.join(":"); + process.env["PATH"] = path3; + } + if (gitDir) { + process.env["GIT_DIR"] = gitDir; + } + for (const envVar of envVars) { + const [key2, value] = envVar.split("="); + process.env[key2] = value; + } + import_debug2.default.enable("simple-git"); + if (await this.git.checkIsRepo()) { + await this.git.cwd(await this.git.revparse("--show-toplevel")); + } + } + } + async status() { + this.plugin.setState(1 /* status */); + const status2 = await this.git.status((err) => this.onError(err)); + this.plugin.setState(0 /* idle */); + return { + changed: status2.files.filter((e) => e.working_dir !== " ").map((e) => { + const res = this.formatPath(e); + return { + path: res.path, + from: res.from, + working_dir: e.working_dir === "?" ? "U" : e.working_dir, + vault_path: this.getVaultPath(res.path) + }; + }), + staged: status2.files.filter((e) => e.index !== " " && e.index != "?").map((e) => { + const res = this.formatPath(e, e.index === "R"); + return { + path: res.path, + from: res.from, + index: e.index, + vault_path: this.getVaultPath(res.path) + }; + }), + conflicted: status2.conflicted.map( + (path2) => this.formatPath({ path: path2 }).path + ) + }; + } + async submoduleAwareHeadRevisonInContainingDirectory(filepath) { + const repoPath = this.asRepositoryRelativePath(filepath, true); + const containingDirectory = path.dirname(repoPath); + const args = ["-C", containingDirectory, "rev-parse", "HEAD"]; + const result = this.git.raw(args); + result.catch( + (err) => console.warn("obsidian-git: rev-parse error:", err) + ); + return result; + } + async getSubmodulePaths() { + return new Promise(async (resolve) => { + this.git.outputHandler(async (cmd, stdout, stderr, args) => { + if (!(args.contains("submodule") && args.contains("foreach"))) { + return; + } + let body = ""; + const root2 = this.app.vault.adapter.getBasePath() + (this.plugin.settings.basePath ? "/" + this.plugin.settings.basePath : ""); + stdout.on("data", (chunk) => { + body += chunk.toString("utf8"); + }); + stdout.on("end", async () => { + const submods = body.split("\n"); + const strippedSubmods = submods.map((i) => { + const submod = i.match(/'([^']*)'/); + if (submod != void 0) { + return root2 + "/" + submod[1] + import_path.sep; + } + }).filter((i) => !!i); + strippedSubmods.reverse(); + resolve(strippedSubmods); + }); + }); + await this.git.subModule(["foreach", "--recursive", ""]); + this.git.outputHandler(() => { + }); + }); + } + //Remove wrong `"` like "My file.md" + formatPath(path2, renamed = false) { + function format(path3) { + if (path3 == void 0) + return void 0; + if (path3.startsWith('"') && path3.endsWith('"')) { + return path3.substring(1, path3.length - 1); + } else { + return path3; + } + } + if (renamed) { + return { + from: format(path2.from), + path: format(path2.path) + }; + } else { + return { + path: format(path2.path) + }; + } + } + async blame(path2, trackMovement, ignoreWhitespace) { + path2 = this.asRepositoryRelativePath(path2, true); + if (!await this.isTracked(path2)) + return "untracked"; + const inSubmodule = await this.getSubmoduleOfFile(path2); + const args = inSubmodule ? ["-C", inSubmodule.submodule] : []; + const relativePath = inSubmodule ? inSubmodule.relativeFilepath : path2; + args.push("blame", "--porcelain"); + if (ignoreWhitespace) + args.push("-w"); + const trackCArg = `-C${GIT_LINE_AUTHORING_MOVEMENT_DETECTION_MINIMAL_LENGTH}`; + switch (trackMovement) { + case "inactive": + break; + case "same-commit": + args.push("-C", trackCArg); + break; + case "all-commits": + args.push("-C", "-C", trackCArg); + break; + default: + impossibleBranch(trackMovement); + } + args.push("--", relativePath); + const rawBlame = await this.git.raw( + args, + (err) => err && console.warn("git-blame", err) + ); + return parseBlame(rawBlame); + } + async isTracked(path2) { + const inSubmodule = await this.getSubmoduleOfFile(path2); + const args = inSubmodule ? ["-C", inSubmodule.submodule] : []; + const relativePath = inSubmodule ? inSubmodule.relativeFilepath : path2; + args.push("ls-files", "--", relativePath); + return this.git.raw(args, (err) => err && console.warn("ls-files", err)).then((x) => x.trim() !== ""); + } + async commitAll({ message }) { + if (this.plugin.settings.updateSubmodules) { + this.plugin.setState(4 /* commit */); + const submodulePaths = await this.getSubmodulePaths(); + for (const item of submodulePaths) { + await this.git.cwd({ path: item, root: false }).add("-A", (err) => this.onError(err)); + await this.git.cwd({ path: item, root: false }).commit( + await this.formatCommitMessage(message), + (err) => this.onError(err) + ); + } + } + this.plugin.setState(3 /* add */); + await this.git.add("-A", (err) => this.onError(err)); + this.plugin.setState(4 /* commit */); + const res = await this.git.commit( + await this.formatCommitMessage(message), + (err) => this.onError(err) + ); + dispatchEvent(new CustomEvent("git-head-update")); + return res.summary.changes; + } + async commit(message) { + this.plugin.setState(4 /* commit */); + const res = (await this.git.commit( + await this.formatCommitMessage(message), + (err) => this.onError(err) + )).summary.changes; + dispatchEvent(new CustomEvent("git-head-update")); + this.plugin.setState(0 /* idle */); + return res; + } + async stage(path2, relativeToVault) { + this.plugin.setState(3 /* add */); + path2 = this.asRepositoryRelativePath(path2, relativeToVault); + await this.git.add(["--", path2], (err) => this.onError(err)); + this.plugin.setState(0 /* idle */); + } + async stageAll({ dir }) { + this.plugin.setState(3 /* add */); + await this.git.add(dir != null ? dir : "-A", (err) => this.onError(err)); + this.plugin.setState(0 /* idle */); + } + async unstageAll({ dir }) { + this.plugin.setState(3 /* add */); + await this.git.reset( + dir != void 0 ? ["--", dir] : [], + (err) => this.onError(err) + ); + this.plugin.setState(0 /* idle */); + } + async unstage(path2, relativeToVault) { + this.plugin.setState(3 /* add */); + path2 = this.asRepositoryRelativePath(path2, relativeToVault); + await this.git.reset(["--", path2], (err) => this.onError(err)); + this.plugin.setState(0 /* idle */); + } + async discard(filepath) { + this.plugin.setState(3 /* add */); + await this.git.checkout(["--", filepath], (err) => this.onError(err)); + this.plugin.setState(0 /* idle */); + } + async hashObject(filepath) { + filepath = this.asRepositoryRelativePath(filepath, true); + const inSubmodule = await this.getSubmoduleOfFile(filepath); + const args = inSubmodule ? ["-C", inSubmodule.submodule] : []; + const relativeFilepath = inSubmodule ? inSubmodule.relativeFilepath : filepath; + args.push("hash-object", "--", relativeFilepath); + const revision = this.git.raw(args); + revision.catch( + (err) => err && console.warn("obsidian-git. hash-object failed:", err == null ? void 0 : err.message) + ); + return revision; + } + async discardAll({ dir }) { + return this.discard(dir != null ? dir : "."); + } + async pull() { + this.plugin.setState(2 /* pull */); + if (this.plugin.settings.updateSubmodules) + await this.git.subModule( + ["update", "--remote", "--merge", "--recursive"], + (err) => this.onError(err) + ); + const branchInfo = await this.branchInfo(); + const localCommit = await this.git.revparse( + [branchInfo.current], + (err) => this.onError(err) + ); + await this.git.fetch((err) => this.onError(err)); + const upstreamCommit = await this.git.revparse( + [branchInfo.tracking], + (err) => this.onError(err) + ); + if (localCommit !== upstreamCommit) { + if (this.plugin.settings.syncMethod === "merge" || this.plugin.settings.syncMethod === "rebase") { + try { + switch (this.plugin.settings.syncMethod) { + case "merge": + await this.git.merge([branchInfo.tracking]); + break; + case "rebase": + await this.git.rebase([branchInfo.tracking]); + } + } catch (err) { + this.plugin.displayError( + `Pull failed (${this.plugin.settings.syncMethod}): ${err.message}` + ); + return; + } + } else if (this.plugin.settings.syncMethod === "reset") { + try { + await this.git.raw( + [ + "update-ref", + `refs/heads/${branchInfo.current}`, + upstreamCommit + ], + (err) => this.onError(err) + ); + await this.unstageAll({}); + } catch (err) { + this.plugin.displayError( + `Sync failed (${this.plugin.settings.syncMethod}): ${err.message}` + ); + } + } + dispatchEvent(new CustomEvent("git-head-update")); + const afterMergeCommit = await this.git.revparse( + [branchInfo.current], + (err) => this.onError(err) + ); + const filesChanged = await this.git.diff([ + `${localCommit}..${afterMergeCommit}`, + "--name-only" + ]); + return filesChanged.split(/\r\n|\r|\n/).filter((value) => value.length > 0).map((e) => { + return { + path: e, + working_dir: "P", + vault_path: this.getVaultPath(e) + }; + }); + } else { + return []; + } + } + async push() { + this.plugin.setState(1 /* status */); + const status2 = await this.git.status(); + const trackingBranch = status2.tracking; + const currentBranch2 = status2.current; + const remoteChangedFiles = (await this.git.diffSummary( + [currentBranch2, trackingBranch, "--"], + (err) => this.onError(err) + )).changed; + this.plugin.setState(5 /* push */); + if (this.plugin.settings.updateSubmodules) { + await this.git.env({ ...process.env, OBSIDIAN_GIT: 1 }).subModule( + [ + "foreach", + "--recursive", + `tracking=$(git for-each-ref --format='%(upstream:short)' "$(git symbolic-ref -q HEAD)"); echo $tracking; if [ ! -z "$(git diff --shortstat $tracking)" ]; then git push; fi` + ], + (err) => this.onError(err) + ); + } + await this.git.env({ ...process.env, OBSIDIAN_GIT: 1 }).push((err) => this.onError(err)); + return remoteChangedFiles; + } + async getUnpushedCommits() { + const status2 = await this.git.status(); + const trackingBranch = status2.tracking; + const currentBranch2 = status2.current; + if (trackingBranch == null || currentBranch2 == null) { + return 0; + } + const remoteChangedFiles = (await this.git.diffSummary( + [currentBranch2, trackingBranch, "--"], + (err) => this.onError(err) + )).changed; + return remoteChangedFiles; + } + async canPush() { + if (this.plugin.settings.updateSubmodules === true) { + return true; + } + const status2 = await this.git.status((err) => this.onError(err)); + const trackingBranch = status2.tracking; + const currentBranch2 = status2.current; + const remoteChangedFiles = (await this.git.diffSummary([currentBranch2, trackingBranch, "--"])).changed; + return remoteChangedFiles !== 0; + } + async checkRequirements() { + if (!this.isGitInstalled()) { + return "missing-git"; + } + if (!await this.git.checkIsRepo()) { + return "missing-repo"; + } + return "valid"; + } + async branchInfo() { + const status2 = await this.git.status((err) => this.onError(err)); + const branches = await this.git.branch( + ["--no-color"], + (err) => this.onError(err) + ); + return { + current: status2.current || void 0, + tracking: status2.tracking || void 0, + branches: branches.all + }; + } + async getRemoteUrl(remote) { + return await this.git.remote( + ["get-url", remote], + (err, url) => this.onError(err) + ) || void 0; + } + // https://github.com/kometenstaub/obsidian-version-history-diff/issues/3 + async log(file, relativeToVault = true, limit) { + let path2; + if (file) { + path2 = this.asRepositoryRelativePath(file, relativeToVault); + } + const res = await this.git.log( + { + file: path2, + maxCount: limit, + "-m": null, + "--name-status": null + }, + (err) => this.onError(err) + ); + return res.all.map((e) => { + var _a2, _b; + return { + ...e, + refs: e.refs.split(", "), + diff: { + ...e.diff, + files: e.diff.files.map((f) => ({ + ...f, + status: f.status, + path: f.file, + hash: e.hash, + vault_path: this.getVaultPath(f.file) + })) + }, + fileName: (_b = (_a2 = e.diff) == null ? void 0 : _a2.files.first()) == null ? void 0 : _b.file + }; + }); + } + async show(commitHash, file, relativeToVault = true) { + const path2 = this.asRepositoryRelativePath(file, relativeToVault); + return this.git.show( + [commitHash + ":" + path2], + (err) => this.onError(err) + ); + } + async checkout(branch2, remote) { + if (remote) { + branch2 = `${remote}/${branch2}`; + } + await this.git.checkout(branch2, (err) => this.onError(err)); + if (this.plugin.settings.submoduleRecurseCheckout) { + const submodulePaths = await this.getSubmodulePaths(); + for (const submodulePath of submodulePaths) { + const branchSummary = await this.git.cwd({ path: submodulePath, root: false }).branch(); + if (Object.keys(branchSummary.branches).includes(branch2)) { + await this.git.cwd({ path: submodulePath, root: false }).checkout(branch2, (err) => this.onError(err)); + } + } + } + } + async createBranch(branch2) { + await this.git.checkout(["-b", branch2], (err) => this.onError(err)); + } + async deleteBranch(branch2, force) { + await this.git.branch( + [force ? "-D" : "-d", branch2], + (err) => this.onError(err) + ); + } + async branchIsMerged(branch2) { + const notMergedBranches = await this.git.branch( + ["--no-merged"], + (err) => this.onError(err) + ); + return !notMergedBranches.all.contains(branch2); + } + async init() { + await this.git.init(false, (err) => this.onError(err)); + } + async clone(url, dir, depth) { + await this.git.clone( + url, + path.join( + this.app.vault.adapter.getBasePath(), + dir + ), + depth ? ["--depth", `${depth}`] : [], + (err) => this.onError(err) + ); + } + async setConfig(path2, value) { + if (value == void 0) { + await this.git.raw(["config", "--local", "--unset", path2]); + } else { + await this.git.addConfig(path2, value, (err) => this.onError(err)); + } + } + async getConfig(path2) { + const config = await this.git.listConfig( + "local", + (err) => this.onError(err) + ); + return config.all[path2]; + } + async fetch(remote) { + await this.git.fetch( + remote != void 0 ? [remote] : [], + (err) => this.onError(err) + ); + } + async setRemote(name, url) { + if ((await this.getRemotes()).includes(name)) + await this.git.remote( + ["set-url", name, url], + (err) => this.onError(err) + ); + else { + await this.git.remote( + ["add", name, url], + (err) => this.onError(err) + ); + } + } + async getRemoteBranches(remote) { + const res = await this.git.branch( + ["-r", "--list", `${remote}*`], + (err) => this.onError(err) + ); + console.log(remote); + console.log(res); + const list = []; + for (const item in res.branches) { + list.push(res.branches[item].name); + } + return list; + } + async getRemotes() { + const res = await this.git.remote([], (err) => this.onError(err)); + if (res) { + return res.trim().split("\n"); + } else { + return []; + } + } + async removeRemote(remoteName) { + await this.git.removeRemote(remoteName); + } + async updateUpstreamBranch(remoteBranch) { + try { + await this.git.branch(["--set-upstream-to", remoteBranch]); + } catch (e) { + console.error(e); + try { + await this.git.branch(["--set-upstream", remoteBranch]); + } catch (e2) { + console.error(e2); + await this.git.push( + // A type error occurs here because the third element could be undefined. + // However, it is unlikely to be undefined due to the `remoteBranch`'s format, and error handling is in place. + // Therefore, we temporarily ignore the error. + // @ts-ignore + ["--set-upstream", ...splitRemoteBranch(remoteBranch)], + (err) => this.onError(err) + ); + } + } + } + updateGitPath(gitPath) { + this.setGitInstance(); + } + updateBasePath(basePath) { + this.setGitInstance(true); + } + async getDiffString(filePath, stagedChanges = false, hash2) { + if (stagedChanges) + return await this.git.diff(["--cached", "--", filePath]); + if (hash2) + return await this.git.show([`${hash2}`, "--", filePath]); + else + return await this.git.diff(["--", filePath]); + } + async diff(file, commit1, commit2) { + return await this.git.diff([`${commit1}..${commit2}`, "--", file]); + } + async getSubmoduleOfFile(repositoryRelativeFile) { + let submoduleRoot = await this.git.raw( + [ + "-C", + path.dirname(repositoryRelativeFile), + "rev-parse", + "--show-toplevel" + ], + (err) => err && console.warn("get-submodule-of-file", err == null ? void 0 : err.message) + ); + submoduleRoot = submoduleRoot.trim(); + const superProject = await this.git.raw( + [ + "-C", + path.dirname(repositoryRelativeFile), + "rev-parse", + "--show-superproject-working-tree" + ], + (err) => err && console.warn("get-submodule-of-file", err == null ? void 0 : err.message) + ); + if (superProject.trim() === "") { + return void 0; + } + const fsAdapter = this.app.vault.adapter; + const absolutePath = fsAdapter.getFullPath( + path.normalize(repositoryRelativeFile) + ); + const newRelativePath = path.relative(submoduleRoot, absolutePath); + return { submodule: submoduleRoot, relativeFilepath: newRelativePath }; + } + async getLastCommitTime() { + const res = await this.git.log({ n: 1 }, (err) => this.onError(err)); + if (res != null && res.latest != null) { + return new Date(res.latest.date); + } + } + isGitInstalled() { + const command = (0, import_child_process2.spawnSync)( + this.plugin.localStorage.getGitPath() || "git", + ["--version"], + { + stdio: "ignore" + } + ); + if (command.error) { + console.error(command.error); + return false; + } + return true; + } + onError(error) { + if (error) { + const networkFailure = error.message.contains("Could not resolve host") || error.message.match( + /ssh: connect to host .*? port .*?: Operation timed out/ + ) || error.message.match( + /ssh: connect to host .*? port .*?: Network is unreachable/ + ); + if (!networkFailure) { + this.plugin.displayError(error.message); + this.plugin.setState(0 /* idle */); + } else if (!this.plugin.offlineMode) { + this.plugin.displayError( + "Git: Going into offline mode. Future network errors will no longer be displayed.", + 2e3 + ); + } + if (networkFailure) { + this.plugin.offlineMode = true; + this.plugin.setState(0 /* idle */); + } + } + } +}; +var zeroCommit = { + hash: "000000", + isZeroCommit: true, + summary: "" +}; +function parseBlame(blameOutputUnnormalized) { + const blameOutput = blameOutputUnnormalized.replace("\r\n", "\n"); + const blameLines = blameOutput.split("\n"); + const result = { + commits: /* @__PURE__ */ new Map(), + hashPerLine: [void 0], + // one-based indices + originalFileLineNrPerLine: [void 0], + finalFileLineNrPerLine: [void 0], + groupSizePerStartingLine: /* @__PURE__ */ new Map() + }; + let line = 1; + for (let bi = 0; bi < blameLines.length; ) { + if (startsWithNonWhitespace(blameLines[bi])) { + const lineInfo = blameLines[bi].split(" "); + const commitHash = parseLineInfoInto(lineInfo, line, result); + bi++; + for (; startsWithNonWhitespace(blameLines[bi]); bi++) { + const spaceSeparatedHeaderValues = blameLines[bi].split(" "); + parseHeaderInto(spaceSeparatedHeaderValues, result, line); + } + finalizeBlameCommitInfo(result.commits.get(commitHash)); + line += 1; + } else if (blameLines[bi] === "" && bi === blameLines.length - 1) { + } else { + throw Error( + `Expected non-whitespace line or EOF, but found: ${blameLines[bi]}` + ); + } + bi++; + } + return result; +} +function parseLineInfoInto(lineInfo, line, result) { + const hash2 = lineInfo[0]; + result.hashPerLine.push(hash2); + result.originalFileLineNrPerLine.push(parseInt(lineInfo[1])); + result.finalFileLineNrPerLine.push(parseInt(lineInfo[2])); + lineInfo.length >= 4 && result.groupSizePerStartingLine.set(line, parseInt(lineInfo[3])); + if (parseInt(lineInfo[2]) !== line) { + throw Error( + `git-blame output is out of order: ${line} vs ${lineInfo[2]}` + ); + } + return hash2; +} +function parseHeaderInto(header, out, line) { + const key2 = header[0]; + const value = header.slice(1).join(" "); + const commitHash = out.hashPerLine[line]; + const commit2 = out.commits.get(commitHash) || { + hash: commitHash, + author: {}, + committer: {}, + previous: {} + }; + switch (key2) { + case "summary": + commit2.summary = value; + break; + case "author": + commit2.author.name = value; + break; + case "author-mail": + commit2.author.email = removeEmailBrackets(value); + break; + case "author-time": + commit2.author.epochSeconds = parseInt(value); + break; + case "author-tz": + commit2.author.tz = value; + break; + case "committer": + commit2.committer.name = value; + break; + case "committer-mail": + commit2.committer.email = removeEmailBrackets(value); + break; + case "committer-time": + commit2.committer.epochSeconds = parseInt(value); + break; + case "committer-tz": + commit2.committer.tz = value; + break; + case "previous": + commit2.previous.commitHash = value; + break; + case "filename": + commit2.previous.filename = value; + break; + } + out.commits.set(commitHash, commit2); +} +function finalizeBlameCommitInfo(commit2) { + if (commit2.summary === void 0) { + throw Error(`Summary not provided for commit: ${commit2.hash}`); + } + if (isUndefinedOrEmptyObject(commit2.author)) { + commit2.author = void 0; + } + if (isUndefinedOrEmptyObject(commit2.committer)) { + commit2.committer = void 0; + } + if (isUndefinedOrEmptyObject(commit2.previous)) { + commit2.previous = void 0; + } + commit2.isZeroCommit = Boolean(commit2.hash.match(/^0*$/)); +} +function isUndefinedOrEmptyObject(obj) { + return !obj || Object.keys(obj).length === 0; +} +function startsWithNonWhitespace(str) { + return str.length > 0 && str[0].trim() === str[0]; +} +function removeEmailBrackets(gitEmail) { + const prefixCleaned = gitEmail.startsWith("<") ? gitEmail.substring(1) : gitEmail; + return prefixCleaned.endsWith(">") ? prefixCleaned.substring(0, prefixCleaned.length - 1) : prefixCleaned; +} + +// src/lineAuthor/lineAuthorProvider.ts +init_polyfill_buffer(); +var import_state4 = require("@codemirror/state"); + +// src/lineAuthor/control.ts +init_polyfill_buffer(); +var import_state2 = require("@codemirror/state"); +var import_obsidian9 = require("obsidian"); + +// src/lineAuthor/eventsPerFilepath.ts +init_polyfill_buffer(); +var SECONDS = 1e3; +var REMOVE_STALES_FREQUENCY = 60 * SECONDS; +var EventsPerFilePath = class { + constructor() { + this.eventsPerFilepath = /* @__PURE__ */ new Map(); + this.startRemoveStalesSubscribersInterval(); + } + /** + * Run the {@link handler} on the subscribers to {@link filepath}. + */ + ifFilepathDefinedTransformSubscribers(filepath, handler) { + if (!filepath) + return; + this.ensureInitialized(filepath); + return handler(this.eventsPerFilepath.get(filepath)); + } + forEachSubscriber(handler) { + this.eventsPerFilepath.forEach((subs) => subs.forEach(handler)); + } + ensureInitialized(filepath) { + if (!this.eventsPerFilepath.get(filepath)) + this.eventsPerFilepath.set(filepath, /* @__PURE__ */ new Set()); + } + startRemoveStalesSubscribersInterval() { + this.removeStalesSubscribersTimer = window.setInterval( + () => this == null ? void 0 : this.forEachSubscriber((las) => las == null ? void 0 : las.removeIfStale()), + REMOVE_STALES_FREQUENCY + ); + } + clear() { + window.clearInterval(this.removeStalesSubscribersTimer); + this.eventsPerFilepath.clear(); + } +}; +var eventsPerFilePathSingleton = new EventsPerFilePath(); + +// src/lineAuthor/model.ts +init_polyfill_buffer(); +var import_state = require("@codemirror/state"); +var import_js_sha256 = __toESM(require_sha256()); + +// src/setting/settings.ts +init_polyfill_buffer(); +var import_obsidian8 = require("obsidian"); + +// src/gitManager/isomorphicGit.ts +init_polyfill_buffer(); + +// node_modules/.pnpm/diff@5.1.0/node_modules/diff/lib/index.mjs +init_polyfill_buffer(); +function Diff() { +} +Diff.prototype = { + diff: function diff(oldString, newString) { + var options = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}; + var callback = options.callback; + if (typeof options === "function") { + callback = options; + options = {}; + } + this.options = options; + var self2 = this; + function done(value) { + if (callback) { + setTimeout(function() { + callback(void 0, value); + }, 0); + return true; + } else { + return value; + } + } + oldString = this.castInput(oldString); + newString = this.castInput(newString); + oldString = this.removeEmpty(this.tokenize(oldString)); + newString = this.removeEmpty(this.tokenize(newString)); + var newLen = newString.length, oldLen = oldString.length; + var editLength = 1; + var maxEditLength = newLen + oldLen; + if (options.maxEditLength) { + maxEditLength = Math.min(maxEditLength, options.maxEditLength); + } + var bestPath = [{ + newPos: -1, + components: [] + }]; + var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); + if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + return done([{ + value: this.join(newString), + count: newString.length + }]); + } + function execEditLength() { + for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { + var basePath = void 0; + var addPath = bestPath[diagonalPath - 1], removePath = bestPath[diagonalPath + 1], _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; + if (addPath) { + bestPath[diagonalPath - 1] = void 0; + } + var canAdd = addPath && addPath.newPos + 1 < newLen, canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; + if (!canAdd && !canRemove) { + bestPath[diagonalPath] = void 0; + continue; + } + if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { + basePath = clonePath(removePath); + self2.pushComponent(basePath.components, void 0, true); + } else { + basePath = addPath; + basePath.newPos++; + self2.pushComponent(basePath.components, true, void 0); + } + _oldPos = self2.extractCommon(basePath, newString, oldString, diagonalPath); + if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { + return done(buildValues(self2, basePath.components, newString, oldString, self2.useLongestToken)); + } else { + bestPath[diagonalPath] = basePath; + } + } + editLength++; + } + if (callback) { + (function exec() { + setTimeout(function() { + if (editLength > maxEditLength) { + return callback(); + } + if (!execEditLength()) { + exec(); + } + }, 0); + })(); + } else { + while (editLength <= maxEditLength) { + var ret = execEditLength(); + if (ret) { + return ret; + } + } + } + }, + pushComponent: function pushComponent(components, added, removed) { + var last2 = components[components.length - 1]; + if (last2 && last2.added === added && last2.removed === removed) { + components[components.length - 1] = { + count: last2.count + 1, + added, + removed + }; + } else { + components.push({ + count: 1, + added, + removed + }); + } + }, + extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { + var newLen = newString.length, oldLen = oldString.length, newPos = basePath.newPos, oldPos = newPos - diagonalPath, commonCount = 0; + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { + newPos++; + oldPos++; + commonCount++; + } + if (commonCount) { + basePath.components.push({ + count: commonCount + }); + } + basePath.newPos = newPos; + return oldPos; + }, + equals: function equals(left, right) { + if (this.options.comparator) { + return this.options.comparator(left, right); + } else { + return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); + } + }, + removeEmpty: function removeEmpty(array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + if (array[i]) { + ret.push(array[i]); + } + } + return ret; + }, + castInput: function castInput(value) { + return value; + }, + tokenize: function tokenize(value) { + return value.split(""); + }, + join: function join3(chars) { + return chars.join(""); + } +}; +function buildValues(diff2, components, newString, oldString, useLongestToken) { + var componentPos = 0, componentLen = components.length, newPos = 0, oldPos = 0; + for (; componentPos < componentLen; componentPos++) { + var component = components[componentPos]; + if (!component.removed) { + if (!component.added && useLongestToken) { + var value = newString.slice(newPos, newPos + component.count); + value = value.map(function(value2, i) { + var oldValue = oldString[oldPos + i]; + return oldValue.length > value2.length ? oldValue : value2; + }); + component.value = diff2.join(value); + } else { + component.value = diff2.join(newString.slice(newPos, newPos + component.count)); + } + newPos += component.count; + if (!component.added) { + oldPos += component.count; + } + } else { + component.value = diff2.join(oldString.slice(oldPos, oldPos + component.count)); + oldPos += component.count; + if (componentPos && components[componentPos - 1].added) { + var tmp = components[componentPos - 1]; + components[componentPos - 1] = components[componentPos]; + components[componentPos] = tmp; + } + } + } + var lastComponent = components[componentLen - 1]; + if (componentLen > 1 && typeof lastComponent.value === "string" && (lastComponent.added || lastComponent.removed) && diff2.equals("", lastComponent.value)) { + components[componentLen - 2].value += lastComponent.value; + components.pop(); + } + return components; +} +function clonePath(path2) { + return { + newPos: path2.newPos, + components: path2.components.slice(0) + }; +} +var characterDiff = new Diff(); +function diffChars(oldStr, newStr, options) { + return characterDiff.diff(oldStr, newStr, options); +} +var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/; +var reWhitespace = /\S/; +var wordDiff = new Diff(); +wordDiff.equals = function(left, right) { + if (this.options.ignoreCase) { + left = left.toLowerCase(); + right = right.toLowerCase(); + } + return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right); +}; +wordDiff.tokenize = function(value) { + var tokens = value.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/); + for (var i = 0; i < tokens.length - 1; i++) { + if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) { + tokens[i] += tokens[i + 2]; + tokens.splice(i + 1, 2); + i--; + } + } + return tokens; +}; +function diffWordsWithSpace(oldStr, newStr, options) { + return wordDiff.diff(oldStr, newStr, options); +} +var lineDiff = new Diff(); +lineDiff.tokenize = function(value) { + var retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); + } + for (var i = 0; i < linesAndNewlines.length; i++) { + var line = linesAndNewlines[i]; + if (i % 2 && !this.options.newlineIsToken) { + retLines[retLines.length - 1] += line; + } else { + if (this.options.ignoreWhitespace) { + line = line.trim(); + } + retLines.push(line); + } + } + return retLines; +}; +function diffLines(oldStr, newStr, callback) { + return lineDiff.diff(oldStr, newStr, callback); +} +var sentenceDiff = new Diff(); +sentenceDiff.tokenize = function(value) { + return value.split(/(\S.+?[.!?])(?=\s+|$)/); +}; +var cssDiff = new Diff(); +cssDiff.tokenize = function(value) { + return value.split(/([{}:;,]|\s+)/); +}; +function _typeof(obj) { + "@babel/helpers - typeof"; + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function(obj2) { + return typeof obj2; + }; + } else { + _typeof = function(obj2) { + return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; + }; + } + return _typeof(obj); +} +function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); +} +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) + return _arrayLikeToArray(arr); +} +function _iterableToArray(iter) { + if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) + return Array.from(iter); +} +function _unsupportedIterableToArray(o, minLen) { + if (!o) + return; + if (typeof o === "string") + return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) + n = o.constructor.name; + if (n === "Map" || n === "Set") + return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) + return _arrayLikeToArray(o, minLen); +} +function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) + len = arr.length; + for (var i = 0, arr2 = new Array(len); i < len; i++) + arr2[i] = arr[i]; + return arr2; +} +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} +var objectPrototypeToString = Object.prototype.toString; +var jsonDiff = new Diff(); +jsonDiff.useLongestToken = true; +jsonDiff.tokenize = lineDiff.tokenize; +jsonDiff.castInput = function(value) { + var _this$options = this.options, undefinedReplacement = _this$options.undefinedReplacement, _this$options$stringi = _this$options.stringifyReplacer, stringifyReplacer = _this$options$stringi === void 0 ? function(k, v) { + return typeof v === "undefined" ? undefinedReplacement : v; + } : _this$options$stringi; + return typeof value === "string" ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, " "); +}; +jsonDiff.equals = function(left, right) { + return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, "$1"), right.replace(/,([\r\n])/g, "$1")); +}; +function canonicalize(obj, stack, replacementStack, replacer, key2) { + stack = stack || []; + replacementStack = replacementStack || []; + if (replacer) { + obj = replacer(key2, obj); + } + var i; + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; + } + } + var canonicalizedObj; + if ("[object Array]" === objectPrototypeToString.call(obj)) { + stack.push(obj); + canonicalizedObj = new Array(obj.length); + replacementStack.push(canonicalizedObj); + for (i = 0; i < obj.length; i += 1) { + canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key2); + } + stack.pop(); + replacementStack.pop(); + return canonicalizedObj; + } + if (obj && obj.toJSON) { + obj = obj.toJSON(); + } + if (_typeof(obj) === "object" && obj !== null) { + stack.push(obj); + canonicalizedObj = {}; + replacementStack.push(canonicalizedObj); + var sortedKeys = [], _key; + for (_key in obj) { + if (obj.hasOwnProperty(_key)) { + sortedKeys.push(_key); + } + } + sortedKeys.sort(); + for (i = 0; i < sortedKeys.length; i += 1) { + _key = sortedKeys[i]; + canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key); + } + stack.pop(); + replacementStack.pop(); + } else { + canonicalizedObj = obj; + } + return canonicalizedObj; +} +var arrayDiff = new Diff(); +arrayDiff.tokenize = function(value) { + return value.slice(); +}; +arrayDiff.join = arrayDiff.removeEmpty = function(value) { + return value; +}; +function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + if (!options) { + options = {}; + } + if (typeof options.context === "undefined") { + options.context = 4; + } + var diff2 = diffLines(oldStr, newStr, options); + if (!diff2) { + return; + } + diff2.push({ + value: "", + lines: [] + }); + function contextLines(lines) { + return lines.map(function(entry) { + return " " + entry; + }); + } + var hunks = []; + var oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1; + var _loop = function _loop2(i2) { + var current = diff2[i2], lines = current.lines || current.value.replace(/\n$/, "").split("\n"); + current.lines = lines; + if (current.added || current.removed) { + var _curRange; + if (!oldRangeStart) { + var prev = diff2[i2 - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; + if (prev) { + curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : []; + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } + (_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function(entry) { + return (current.added ? "+" : "-") + entry; + }))); + if (current.added) { + newLine += lines.length; + } else { + oldLine += lines.length; + } + } else { + if (oldRangeStart) { + if (lines.length <= options.context * 2 && i2 < diff2.length - 2) { + var _curRange2; + (_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines))); + } else { + var _curRange3; + var contextSize = Math.min(lines.length, options.context); + (_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize)))); + var hunk = { + oldStart: oldRangeStart, + oldLines: oldLine - oldRangeStart + contextSize, + newStart: newRangeStart, + newLines: newLine - newRangeStart + contextSize, + lines: curRange + }; + if (i2 >= diff2.length - 2 && lines.length <= options.context) { + var oldEOFNewline = /\n$/.test(oldStr); + var newEOFNewline = /\n$/.test(newStr); + var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines; + if (!oldEOFNewline && noNlBeforeAdds && oldStr.length > 0) { + curRange.splice(hunk.oldLines, 0, "\\ No newline at end of file"); + } + if (!oldEOFNewline && !noNlBeforeAdds || !newEOFNewline) { + curRange.push("\\ No newline at end of file"); + } + } + hunks.push(hunk); + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + }; + for (var i = 0; i < diff2.length; i++) { + _loop(i); + } + return { + oldFileName, + newFileName, + oldHeader, + newHeader, + hunks + }; +} +function formatPatch(diff2) { + var ret = []; + if (diff2.oldFileName == diff2.newFileName) { + ret.push("Index: " + diff2.oldFileName); + } + ret.push("==================================================================="); + ret.push("--- " + diff2.oldFileName + (typeof diff2.oldHeader === "undefined" ? "" : " " + diff2.oldHeader)); + ret.push("+++ " + diff2.newFileName + (typeof diff2.newHeader === "undefined" ? "" : " " + diff2.newHeader)); + for (var i = 0; i < diff2.hunks.length; i++) { + var hunk = diff2.hunks[i]; + if (hunk.oldLines === 0) { + hunk.oldStart -= 1; + } + if (hunk.newLines === 0) { + hunk.newStart -= 1; + } + ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@"); + ret.push.apply(ret, hunk.lines); + } + return ret.join("\n") + "\n"; +} +function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + return formatPatch(structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options)); +} +function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { + return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); +} + +// src/gitManager/isomorphicGit.ts +var import_obsidian7 = require("obsidian"); + +// src/ui/modals/generalModal.ts +init_polyfill_buffer(); +var import_obsidian5 = require("obsidian"); +var generalModalConfigDefaults = { + options: [], + placeholder: "", + allowEmpty: false, + onlySelection: false, + initialValue: void 0 +}; +var GeneralModal = class extends import_obsidian5.SuggestModal { + constructor(config) { + super(app); + this.config = { ...generalModalConfigDefaults, ...config }; + this.setPlaceholder(this.config.placeholder); + } + open() { + super.open(); + if (this.config.initialValue != void 0) { + this.inputEl.value = this.config.initialValue; + this.inputEl.dispatchEvent(new Event("input")); + } + return new Promise((resolve) => { + this.resolve = resolve; + }); + } + selectSuggestion(value, evt) { + if (this.resolve) { + let res; + if (this.config.allowEmpty && value === " ") + res = ""; + else if (value === "...") + res = void 0; + else + res = value; + this.resolve(res); + } + super.selectSuggestion(value, evt); + } + onClose() { + if (this.resolve) + this.resolve(void 0); + } + getSuggestions(query) { + if (this.config.onlySelection) { + return this.config.options; + } else if (this.config.allowEmpty) { + return [query.length > 0 ? query : " ", ...this.config.options]; + } else { + return [query.length > 0 ? query : "...", ...this.config.options]; + } + } + renderSuggestion(value, el) { + el.setText(value); + } + onChooseSuggestion(item, evt) { + } +}; + +// src/gitManager/myAdapter.ts +init_polyfill_buffer(); +var import_obsidian6 = require("obsidian"); +var MyAdapter = class { + constructor(vault, plugin) { + this.plugin = plugin; + this.promises = {}; + this.adapter = vault.adapter; + this.vault = vault; + this.lastBasePath = this.plugin.settings.basePath; + this.promises.readFile = this.readFile.bind(this); + this.promises.writeFile = this.writeFile.bind(this); + this.promises.readdir = this.readdir.bind(this); + this.promises.mkdir = this.mkdir.bind(this); + this.promises.rmdir = this.rmdir.bind(this); + this.promises.stat = this.stat.bind(this); + this.promises.unlink = this.unlink.bind(this); + this.promises.lstat = this.lstat.bind(this); + this.promises.readlink = this.readlink.bind(this); + this.promises.symlink = this.symlink.bind(this); + } + async readFile(path2, opts) { + var _a2; + this.maybeLog("Read: " + path2 + JSON.stringify(opts)); + if (opts == "utf8" || opts.encoding == "utf8") { + const file = this.vault.getAbstractFileByPath(path2); + if (file instanceof import_obsidian6.TFile) { + this.maybeLog("Reuse"); + return this.vault.read(file); + } else { + return this.adapter.read(path2); + } + } else { + if (path2.endsWith(this.gitDir + "/index")) { + if (this.plugin.settings.basePath != this.lastBasePath) { + this.clearIndex(); + this.lastBasePath = this.plugin.settings.basePath; + return this.adapter.readBinary(path2); + } + return (_a2 = this.index) != null ? _a2 : this.adapter.readBinary(path2); + } + const file = this.vault.getAbstractFileByPath(path2); + if (file instanceof import_obsidian6.TFile) { + this.maybeLog("Reuse"); + return this.vault.readBinary(file); + } else { + return this.adapter.readBinary(path2); + } + } + } + async writeFile(path2, data) { + this.maybeLog("Write: " + path2); + if (typeof data === "string") { + const file = this.vault.getAbstractFileByPath(path2); + if (file instanceof import_obsidian6.TFile) { + return this.vault.modify(file, data); + } else { + return this.adapter.write(path2, data); + } + } else { + if (path2.endsWith(this.gitDir + "/index")) { + this.index = data; + this.indexmtime = Date.now(); + } else { + const file = this.vault.getAbstractFileByPath(path2); + if (file instanceof import_obsidian6.TFile) { + return this.vault.modifyBinary(file, data); + } else { + return this.adapter.writeBinary(path2, data); + } + } + } + } + async readdir(path2) { + if (path2 === ".") + path2 = "/"; + const res = await this.adapter.list(path2); + const all = [...res.files, ...res.folders]; + let formattedAll; + if (path2 !== "/") { + formattedAll = all.map( + (e) => (0, import_obsidian6.normalizePath)(e.substring(path2.length)) + ); + } else { + formattedAll = all; + } + return formattedAll; + } + async mkdir(path2) { + return this.adapter.mkdir(path2); + } + async rmdir(path2, opts) { + var _a2, _b; + return this.adapter.rmdir(path2, (_b = (_a2 = opts == null ? void 0 : opts.options) == null ? void 0 : _a2.recursive) != null ? _b : false); + } + async stat(path2) { + if (path2.endsWith(this.gitDir + "/index")) { + if (this.index !== void 0 && this.indexctime != void 0 && this.indexmtime != void 0) { + return { + isFile: () => true, + isDirectory: () => false, + isSymbolicLink: () => false, + size: this.index.length, + type: "file", + ctimeMs: this.indexctime, + mtimeMs: this.indexmtime + }; + } else { + const stat = await this.adapter.stat(path2); + if (stat == void 0) { + throw { code: "ENOENT" }; + } + this.indexctime = stat.ctime; + this.indexmtime = stat.mtime; + return { + ctimeMs: stat.ctime, + mtimeMs: stat.mtime, + size: stat.size, + type: "file", + isFile: () => true, + isDirectory: () => false, + isSymbolicLink: () => false + }; + } + } + if (path2 === ".") + path2 = "/"; + const file = this.vault.getAbstractFileByPath(path2); + this.maybeLog("Stat: " + path2); + if (file instanceof import_obsidian6.TFile) { + this.maybeLog("Reuse stat"); + return { + ctimeMs: file.stat.ctime, + mtimeMs: file.stat.mtime, + size: file.stat.size, + type: "file", + isFile: () => true, + isDirectory: () => false, + isSymbolicLink: () => false + }; + } else { + const stat = await this.adapter.stat(path2); + if (stat) { + return { + ctimeMs: stat.ctime, + mtimeMs: stat.mtime, + size: stat.size, + type: stat.type === "folder" ? "directory" : stat.type, + isFile: () => stat.type === "file", + isDirectory: () => stat.type === "folder", + isSymbolicLink: () => false + }; + } else { + throw { code: "ENOENT" }; + } + } + } + async unlink(path2) { + return this.adapter.remove(path2); + } + async lstat(path2) { + return this.stat(path2); + } + async readlink(path2) { + throw new Error(`readlink of (${path2}) is not implemented.`); + } + async symlink(path2) { + throw new Error(`symlink of (${path2}) is not implemented.`); + } + async saveAndClear() { + if (this.index !== void 0) { + await this.adapter.writeBinary( + this.plugin.gitManager.getVaultPath(this.gitDir + "/index"), + this.index, + { + ctime: this.indexctime, + mtime: this.indexmtime + } + ); + } + this.clearIndex(); + } + clearIndex() { + this.index = void 0; + this.indexctime = void 0; + this.indexmtime = void 0; + } + get gitDir() { + return this.plugin.settings.gitDir || ".git"; + } + maybeLog(text2) { + } +}; + +// src/gitManager/isomorphicGit.ts +var IsomorphicGit = class extends GitManager { + constructor(plugin) { + super(plugin); + this.FILE = 0; + this.HEAD = 1; + this.WORKDIR = 2; + this.STAGE = 3; + // Mapping from statusMatrix to git status codes based off git status --short + // See: https://isomorphic-git.org/docs/en/statusMatrix + this.status_mapping = { + "000": " ", + "003": "AD", + "020": "??", + "022": "A ", + "023": "AM", + "100": "D ", + "101": " D", + "103": "MD", + "110": "DA", + // Technically, two files: first one is deleted "D " and second one is untracked "??" + "111": " ", + "113": "MM", + "120": "DA", + // Same as "110" + "121": " M", + "122": "M ", + "123": "MM" + }; + this.noticeLength = 999999; + this.fs = new MyAdapter(this.app.vault, this.plugin); + } + getRepo() { + return { + fs: this.fs, + dir: this.plugin.settings.basePath, + gitdir: this.plugin.settings.gitDir || void 0, + onAuth: () => { + var _a2, _b; + return { + username: (_a2 = this.plugin.localStorage.getUsername()) != null ? _a2 : void 0, + password: (_b = this.plugin.localStorage.getPassword()) != null ? _b : void 0 + }; + }, + onAuthFailure: async () => { + new import_obsidian7.Notice( + "Authentication failed. Please try with different credentials" + ); + const username = await new GeneralModal({ + placeholder: "Specify your username" + }).open(); + if (username) { + const password = await new GeneralModal({ + placeholder: "Specify your password/personal access token" + }).open(); + if (password) { + this.plugin.localStorage.setUsername(username); + this.plugin.localStorage.setPassword(password); + return { + username, + password + }; + } + } + return { cancel: true }; + }, + http: { + async request({ + url, + method: method2, + headers, + body + }) { + if (body) { + body = await collect2(body); + body = body.buffer; + } + const res = await (0, import_obsidian7.requestUrl)({ + url, + method: method2, + headers, + body, + throw: false + }); + return { + url, + method: method2, + headers: res.headers, + body: [new Uint8Array(res.arrayBuffer)], + statusCode: res.status, + statusMessage: res.status.toString() + }; + } + } + }; + } + async wrapFS(call) { + try { + const res = await call; + await this.fs.saveAndClear(); + return res; + } catch (error) { + await this.fs.saveAndClear(); + throw error; + } + } + async status() { + let notice; + const timeout = window.setTimeout(function() { + notice = new import_obsidian7.Notice( + "This takes longer: Getting status", + this.noticeLength + ); + }, 2e4); + try { + this.plugin.setState(1 /* status */); + const status2 = (await this.wrapFS(isomorphic_git_default.statusMatrix({ ...this.getRepo() }))).map((row) => this.getFileStatusResult(row)); + const changed = status2.filter( + (fileStatus) => fileStatus.working_dir !== " " + ); + const staged = status2.filter( + (fileStatus) => fileStatus.index !== " " && fileStatus.index !== "U" + ); + const conflicted = []; + window.clearTimeout(timeout); + notice == null ? void 0 : notice.hide(); + return { changed, staged, conflicted }; + } catch (error) { + window.clearTimeout(timeout); + notice == null ? void 0 : notice.hide(); + this.plugin.displayError(error); + throw error; + } + } + async commitAll({ + message, + status: status2, + unstagedFiles + }) { + try { + await this.checkAuthorInfo(); + await this.stageAll({ status: status2, unstagedFiles }); + return this.commit(message); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async commit(message) { + try { + await this.checkAuthorInfo(); + this.plugin.setState(4 /* commit */); + const formatMessage = await this.formatCommitMessage(message); + const hadConflict = this.plugin.localStorage.getConflict() === "true"; + let parent = void 0; + if (hadConflict) { + const branchInfo = await this.branchInfo(); + parent = [branchInfo.current, branchInfo.tracking]; + } + await this.wrapFS( + isomorphic_git_default.commit({ + ...this.getRepo(), + message: formatMessage, + parent + }) + ); + this.plugin.localStorage.setConflict("false"); + return; + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async stage(filepath, relativeToVault) { + const gitPath = this.asRepositoryRelativePath( + filepath, + relativeToVault + ); + let vaultPath; + if (relativeToVault) { + vaultPath = filepath; + } else { + vaultPath = this.getVaultPath(filepath); + } + try { + this.plugin.setState(3 /* add */); + if (await this.app.vault.adapter.exists(vaultPath)) { + await this.wrapFS( + isomorphic_git_default.add({ ...this.getRepo(), filepath: gitPath }) + ); + } else { + await this.wrapFS( + isomorphic_git_default.remove({ ...this.getRepo(), filepath: gitPath }) + ); + } + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async stageAll({ + dir, + status: status2, + unstagedFiles + }) { + try { + if (status2) { + await Promise.all( + status2.changed.map( + (file) => file.working_dir !== "D" ? this.wrapFS( + isomorphic_git_default.add({ + ...this.getRepo(), + filepath: file.path + }) + ) : isomorphic_git_default.remove({ + ...this.getRepo(), + filepath: file.path + }) + ) + ); + } else { + const filesToStage = unstagedFiles != null ? unstagedFiles : await this.getUnstagedFiles(dir != null ? dir : "."); + await Promise.all( + filesToStage.map( + ({ filepath, deleted }) => deleted ? isomorphic_git_default.remove({ ...this.getRepo(), filepath }) : this.wrapFS( + isomorphic_git_default.add({ ...this.getRepo(), filepath }) + ) + ) + ); + } + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async unstage(filepath, relativeToVault) { + try { + this.plugin.setState(3 /* add */); + filepath = this.asRepositoryRelativePath(filepath, relativeToVault); + await this.wrapFS( + isomorphic_git_default.resetIndex({ ...this.getRepo(), filepath }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async unstageAll({ + dir, + status: status2 + }) { + try { + let staged; + if (status2) { + staged = status2.staged.map((file) => file.path); + } else { + const res = await this.getStagedFiles(dir != null ? dir : "."); + staged = res.map(({ filepath }) => filepath); + } + await this.wrapFS( + Promise.all( + staged.map( + (file) => isomorphic_git_default.resetIndex({ ...this.getRepo(), filepath: file }) + ) + ) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async discard(filepath) { + try { + this.plugin.setState(3 /* add */); + await this.wrapFS( + isomorphic_git_default.checkout({ + ...this.getRepo(), + filepaths: [filepath], + force: true + }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async discardAll({ + dir, + status: status2 + }) { + let files = []; + if (status2) { + if (dir != void 0) { + files = status2.changed.filter((file) => file.path.startsWith(dir)).map((file) => file.path); + } else { + files = status2.changed.map((file) => file.path); + } + } else { + files = (await this.getUnstagedFiles(dir)).map( + ({ filepath }) => filepath + ); + } + try { + await this.wrapFS( + isomorphic_git_default.checkout({ + ...this.getRepo(), + filepaths: files, + force: true + }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + getProgressText(action, event) { + let out = `${action} progress:`; + if (event.phase) { + out = `${out} ${event.phase}:`; + } + if (event.loaded) { + out = `${out} ${event.loaded}`; + if (event.total) { + out = `${out} of ${event.total}`; + } + } + return out; + } + resolveRef(ref) { + return this.wrapFS(isomorphic_git_default.resolveRef({ ...this.getRepo(), ref })); + } + async pull() { + const progressNotice = this.showNotice("Initializing pull"); + try { + this.plugin.setState(2 /* pull */); + const localCommit = await this.resolveRef("HEAD"); + await this.fetch(); + const branchInfo = await this.branchInfo(); + await this.checkAuthorInfo(); + const mergeRes = await this.wrapFS( + isomorphic_git_default.merge({ + ...this.getRepo(), + ours: branchInfo.current, + theirs: branchInfo.tracking, + abortOnConflict: false + }) + ); + if (!mergeRes.alreadyMerged) { + await this.wrapFS( + isomorphic_git_default.checkout({ + ...this.getRepo(), + ref: branchInfo.current, + onProgress: (progress) => { + if (progressNotice !== void 0) { + progressNotice.noticeEl.innerText = this.getProgressText("Checkout", progress); + } + }, + remote: branchInfo.remote + }) + ); + } + progressNotice == null ? void 0 : progressNotice.hide(); + const upstreamCommit = await this.resolveRef("HEAD"); + const changedFiles = await this.getFileChangesCount( + localCommit, + upstreamCommit + ); + this.showNotice("Finished pull", false); + return changedFiles.map((file) => ({ + path: file.path, + working_dir: "P", + index: "P", + vault_path: this.getVaultPath(file.path) + })); + } catch (error) { + progressNotice == null ? void 0 : progressNotice.hide(); + if (error instanceof Errors.MergeConflictError) { + this.plugin.handleConflict( + error.data.filepaths.map((file) => this.getVaultPath(file)) + ); + } + this.plugin.displayError(error); + throw error; + } + } + async push() { + if (!await this.canPush()) { + return 0; + } + const progressNotice = this.showNotice("Initializing push"); + try { + this.plugin.setState(1 /* status */); + const status2 = await this.branchInfo(); + const trackingBranch = status2.tracking; + const currentBranch2 = status2.current; + const numChangedFiles = (await this.getFileChangesCount(currentBranch2, trackingBranch)).length; + this.plugin.setState(5 /* push */); + await this.wrapFS( + isomorphic_git_default.push({ + ...this.getRepo(), + onProgress: (progress) => { + if (progressNotice !== void 0) { + progressNotice.noticeEl.innerText = this.getProgressText("Pushing", progress); + } + } + }) + ); + progressNotice == null ? void 0 : progressNotice.hide(); + return numChangedFiles; + } catch (error) { + progressNotice == null ? void 0 : progressNotice.hide(); + this.plugin.displayError(error); + throw error; + } + } + async getUnpushedCommits() { + const status2 = await this.branchInfo(); + const trackingBranch = status2.tracking; + const currentBranch2 = status2.current; + if (trackingBranch == null || currentBranch2 == null) { + return 0; + } + const localCommit = await this.resolveRef(currentBranch2); + const upstreamCommit = await this.resolveRef(trackingBranch); + const changedFiles = await this.getFileChangesCount( + localCommit, + upstreamCommit + ); + return changedFiles.length; + } + async canPush() { + const status2 = await this.branchInfo(); + const trackingBranch = status2.tracking; + const currentBranch2 = status2.current; + const current = await this.resolveRef(currentBranch2); + const tracking = await this.resolveRef(trackingBranch); + return current != tracking; + } + async checkRequirements() { + const headExists = await this.plugin.app.vault.adapter.exists( + `${this.getRepo().dir}/.git/HEAD` + ); + return headExists ? "valid" : "missing-repo"; + } + async branchInfo() { + var _a2, _b; + try { + const current = await isomorphic_git_default.currentBranch(this.getRepo()) || ""; + const branches = await isomorphic_git_default.listBranches(this.getRepo()); + const remote = (_a2 = await this.getConfig(`branch.${current}.remote`)) != null ? _a2 : "origin"; + const trackingBranch = (_b = await this.getConfig(`branch.${current}.merge`)) == null ? void 0 : _b.split("refs/heads")[1]; + const tracking = trackingBranch ? remote + trackingBranch : void 0; + return { + current, + tracking, + branches, + remote + }; + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async getCurrentRemote() { + var _a2; + const current = await isomorphic_git_default.currentBranch(this.getRepo()) || ""; + const remote = (_a2 = await this.getConfig(`branch.${current}.remote`)) != null ? _a2 : "origin"; + return remote; + } + async checkout(branch2, remote) { + try { + return this.wrapFS( + isomorphic_git_default.checkout({ + ...this.getRepo(), + ref: branch2, + force: !!remote, + remote + }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async createBranch(branch2) { + try { + await this.wrapFS( + isomorphic_git_default.branch({ ...this.getRepo(), ref: branch2, checkout: true }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async deleteBranch(branch2) { + try { + await this.wrapFS( + isomorphic_git_default.deleteBranch({ ...this.getRepo(), ref: branch2 }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async branchIsMerged(branch2) { + return true; + } + async init() { + try { + await this.wrapFS(isomorphic_git_default.init(this.getRepo())); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async clone(url, dir, depth) { + const progressNotice = this.showNotice("Initializing clone"); + try { + await this.wrapFS( + isomorphic_git_default.clone({ + ...this.getRepo(), + dir, + url, + depth, + onProgress: (progress) => { + if (progressNotice !== void 0) { + progressNotice.noticeEl.innerText = this.getProgressText("Cloning", progress); + } + } + }) + ); + progressNotice == null ? void 0 : progressNotice.hide(); + } catch (error) { + progressNotice == null ? void 0 : progressNotice.hide(); + this.plugin.displayError(error); + throw error; + } + } + async setConfig(path2, value) { + try { + return this.wrapFS( + isomorphic_git_default.setConfig({ + ...this.getRepo(), + path: path2, + value + }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async getConfig(path2) { + try { + return this.wrapFS( + isomorphic_git_default.getConfig({ + ...this.getRepo(), + path: path2 + }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async fetch(remote) { + const progressNotice = this.showNotice("Initializing fetch"); + try { + const args = { + ...this.getRepo(), + onProgress: (progress) => { + if (progressNotice !== void 0) { + progressNotice.noticeEl.innerText = this.getProgressText("Fetching", progress); + } + }, + remote: remote != null ? remote : await this.getCurrentRemote() + }; + await this.wrapFS(isomorphic_git_default.fetch(args)); + progressNotice == null ? void 0 : progressNotice.hide(); + } catch (error) { + this.plugin.displayError(error); + progressNotice == null ? void 0 : progressNotice.hide(); + throw error; + } + } + async setRemote(name, url) { + try { + await this.wrapFS( + isomorphic_git_default.addRemote({ + ...this.getRepo(), + remote: name, + url, + force: true + }) + ); + } catch (error) { + this.plugin.displayError(error); + throw error; + } + } + async getRemoteBranches(remote) { + let remoteBranches = []; + remoteBranches.push( + ...await this.wrapFS( + isomorphic_git_default.listBranches({ ...this.getRepo(), remote }) + ) + ); + remoteBranches.remove("HEAD"); + remoteBranches = remoteBranches.map((e) => `${remote}/${e}`); + return remoteBranches; + } + async getRemotes() { + return (await this.wrapFS(isomorphic_git_default.listRemotes({ ...this.getRepo() }))).map( + (remoteUrl) => remoteUrl.remote + ); + } + async removeRemote(remoteName) { + await this.wrapFS( + isomorphic_git_default.deleteRemote({ ...this.getRepo(), remote: remoteName }) + ); + } + async getRemoteUrl(remote) { + var _a2; + return (_a2 = (await this.wrapFS(isomorphic_git_default.listRemotes({ ...this.getRepo() }))).filter((item) => item.remote == remote)[0]) == null ? void 0 : _a2.url; + } + async log(_, __ = true, limit) { + const logs = await this.wrapFS( + isomorphic_git_default.log({ ...this.getRepo(), depth: limit }) + ); + return Promise.all( + logs.map(async (log2) => { + const completeMessage = log2.commit.message.split("\n\n"); + return { + message: completeMessage[0], + body: completeMessage.slice(1).join("\n\n"), + date: new Date( + log2.commit.committer.timestamp + ).toDateString(), + diff: { + changed: 0, + files: (await this.getFileChangesCount( + log2.commit.parent.first(), + log2.oid + )).map((item) => { + return { + path: item.path, + status: item.type, + vault_path: this.getVaultPath(item.path), + hash: log2.oid, + binary: void 0 + }; + }) + }, + hash: log2.oid, + refs: [] + }; + }) + ); + } + updateBasePath(basePath) { + this.getRepo().dir = basePath; + } + async updateUpstreamBranch(remoteBranch) { + const [remote, branch2] = splitRemoteBranch(remoteBranch); + const branchInfo = await this.branchInfo(); + await this.setConfig( + `branch.${branchInfo.current}.merge`, + `refs/heads/${branch2}` + ); + await this.setConfig(`branch.${branch2}.remote`, remote); + } + updateGitPath(gitPath) { + return; + } + async getFileChangesCount(commitHash1, commitHash2) { + return this.walkDifference({ + walkers: [ + isomorphic_git_default.TREE({ ref: commitHash1 }), + isomorphic_git_default.TREE({ ref: commitHash2 }) + ] + }); + } + async walkDifference({ + walkers, + dir: base + }) { + const res = await this.wrapFS( + isomorphic_git_default.walk({ + ...this.getRepo(), + trees: walkers, + map: async function(filepath, [A, B]) { + if (!worthWalking2(filepath, base)) { + return null; + } + if (await (A == null ? void 0 : A.type()) === "tree" || await (B == null ? void 0 : B.type()) === "tree") { + return; + } + const Aoid = await (A == null ? void 0 : A.oid()); + const Boid = await (B == null ? void 0 : B.oid()); + let type = "equal"; + if (Aoid !== Boid) { + type = "M"; + } + if (Aoid === void 0) { + type = "A"; + } + if (Boid === void 0) { + type = "D"; + } + if (Aoid === void 0 && Boid === void 0) { + console.log("Something weird happened:"); + console.log(A); + console.log(B); + } + if (type === "equal") { + return; + } + return { + path: filepath, + type + }; + } + }) + ); + return res; + } + async getStagedFiles(dir = ".") { + const res = await this.walkDifference({ + walkers: [isomorphic_git_default.TREE({ ref: "HEAD" }), isomorphic_git_default.STAGE()], + dir + }); + return res.map((file) => { + return { + vault_path: this.getVaultPath(file.path), + filepath: file.path + }; + }); + } + async getUnstagedFiles(base = ".") { + let notice; + const timeout = window.setTimeout(function() { + notice = new import_obsidian7.Notice( + "This takes longer: Getting status", + this.noticeLength + ); + }, 2e4); + try { + const repo = this.getRepo(); + const res = await this.wrapFS( + //Modified from `git.statusMatrix` + isomorphic_git_default.walk({ + ...repo, + trees: [isomorphic_git_default.WORKDIR(), isomorphic_git_default.STAGE()], + map: async function(filepath, [workdir, stage]) { + if (!stage && workdir) { + const isIgnored2 = await isomorphic_git_default.isIgnored({ + ...repo, + filepath + }); + if (isIgnored2) { + return null; + } + } + if (!worthWalking2(filepath, base)) { + return null; + } + const [workdirType, stageType] = await Promise.all([ + workdir && workdir.type(), + stage && stage.type() + ]); + const isBlob = [workdirType, stageType].includes( + "blob" + ); + if ((workdirType === "tree" || workdirType === "special") && !isBlob) + return; + if (stageType === "commit") + return null; + if ((stageType === "tree" || stageType === "special") && !isBlob) + return; + const stageOid = stageType === "blob" ? await stage.oid() : void 0; + let workdirOid; + if (workdirType === "blob" && stageType !== "blob") { + workdirOid = "42"; + } else if (workdirType === "blob") { + workdirOid = await workdir.oid(); + } + if (!workdirOid) { + return { + filepath, + deleted: true + }; + } + if (workdirOid !== stageOid) { + return { + filepath, + deleted: false + }; + } + return null; + } + }) + ); + window.clearTimeout(timeout); + notice == null ? void 0 : notice.hide(); + return res; + } catch (error) { + window.clearTimeout(timeout); + notice == null ? void 0 : notice.hide(); + this.plugin.displayError(error); + throw error; + } + } + async getDiffString(filePath, stagedChanges = false, hash2) { + const vaultPath = this.getVaultPath(filePath); + const map = async (file, [A]) => { + if (filePath == file) { + const oid = await A.oid(); + const contents = await isomorphic_git_default.readBlob({ + ...this.getRepo(), + oid + }); + return contents.blob; + } + }; + if (hash2) { + const commitContent = await readBlob({ + ...this.getRepo(), + filepath: filePath, + oid: hash2 + }).then((headBlob) => new TextDecoder().decode(headBlob.blob)).catch((err) => { + if (err instanceof isomorphic_git_default.Errors.NotFoundError) + return void 0; + throw err; + }); + const commit2 = await isomorphic_git_default.readCommit({ + ...this.getRepo(), + oid: hash2 + }); + const previousContent = await readBlob({ + ...this.getRepo(), + filepath: filePath, + oid: commit2.commit.parent.first() + }).then((headBlob) => new TextDecoder().decode(headBlob.blob)).catch((err) => { + if (err instanceof isomorphic_git_default.Errors.NotFoundError) + return void 0; + throw err; + }); + const diff2 = createPatch( + vaultPath, + previousContent != null ? previousContent : "", + commitContent != null ? commitContent : "" + ); + return diff2; + } + const stagedBlob = (await isomorphic_git_default.walk({ + ...this.getRepo(), + trees: [isomorphic_git_default.STAGE()], + map + })).first(); + const stagedContent = new TextDecoder().decode(stagedBlob); + if (stagedChanges) { + const headContent = await this.resolveRef("HEAD").then( + (oid) => readBlob({ + ...this.getRepo(), + filepath: filePath, + oid + }) + ).then((headBlob) => new TextDecoder().decode(headBlob.blob)).catch((err) => { + if (err instanceof isomorphic_git_default.Errors.NotFoundError) + return void 0; + throw err; + }); + const diff2 = createPatch( + vaultPath, + headContent != null ? headContent : "", + stagedContent + ); + return diff2; + } else { + let workdirContent; + if (await app.vault.adapter.exists(vaultPath)) { + workdirContent = await app.vault.adapter.read(vaultPath); + } else { + workdirContent = ""; + } + const diff2 = createPatch(vaultPath, stagedContent, workdirContent); + return diff2; + } + } + async getLastCommitTime() { + const repo = this.getRepo(); + const oid = await this.resolveRef("HEAD"); + const commit2 = await isomorphic_git_default.readCommit({ ...repo, oid }); + const date = commit2.commit.committer.timestamp; + return new Date(date * 1e3); + } + getFileStatusResult(row) { + const status2 = this.status_mapping[`${row[this.HEAD]}${row[this.WORKDIR]}${row[this.STAGE]}`]; + return { + index: status2[0] == "?" ? "U" : status2[0], + working_dir: status2[1] == "?" ? "U" : status2[1], + path: row[this.FILE], + vault_path: this.getVaultPath(row[this.FILE]) + }; + } + async checkAuthorInfo() { + const name = await this.getConfig("user.name"); + const email = await this.getConfig("user.email"); + if (!name || !email) { + throw "Git author information is not set. Please set it in the settings."; + } + } + showNotice(message, infinity = true) { + if (!this.plugin.settings.disablePopups) { + return new import_obsidian7.Notice( + message, + infinity ? this.noticeLength : void 0 + ); + } + } +}; +function fromValue2(value) { + let queue = [value]; + return { + next() { + return Promise.resolve({ + done: queue.length === 0, + value: queue.pop() + }); + }, + return() { + queue = []; + return {}; + }, + [Symbol.asyncIterator]() { + return this; + } + }; +} +function getIterator2(iterable) { + if (iterable[Symbol.asyncIterator]) { + return iterable[Symbol.asyncIterator](); + } + if (iterable[Symbol.iterator]) { + return iterable[Symbol.iterator](); + } + if (iterable.next) { + return iterable; + } + return fromValue2(iterable); +} +async function forAwait2(iterable, cb) { + const iter = getIterator2(iterable); + while (true) { + const { value, done } = await iter.next(); + if (value) + await cb(value); + if (done) + break; + } + if (iter.return) + iter.return(); +} +async function collect2(iterable) { + let size = 0; + const buffers = []; + await forAwait2(iterable, (value) => { + buffers.push(value); + size += value.byteLength; + }); + const result = new Uint8Array(size); + let nextIndex = 0; + for (const buffer2 of buffers) { + result.set(buffer2, nextIndex); + nextIndex += buffer2.byteLength; + } + return result; +} + +// src/setting/settings.ts +var FORMAT_STRING_REFERENCE_URL = "https://momentjs.com/docs/#/parsing/string-format/"; +var LINE_AUTHOR_FEATURE_WIKI_LINK = "https://publish.obsidian.md/git-doc/Line+Authoring"; +var ObsidianGitSettingsTab = class extends import_obsidian8.PluginSettingTab { + constructor() { + super(...arguments); + this.lineAuthorColorSettings = /* @__PURE__ */ new Map(); + } + // narrow type from PluginSettingTab.plugin + get settings() { + return this.plugin.settings; + } + display() { + const { containerEl } = this; + const plugin = this.plugin; + const commitOrBackup = plugin.settings.differentIntervalCommitAndPush ? "commit" : "backup"; + const gitReady = plugin.gitReady; + containerEl.empty(); + containerEl.createEl("h2", { text: "Git Backup settings" }); + if (!gitReady) { + containerEl.createEl("p", { + text: "Git is not ready. When all settings are correct you can configure auto backup, etc." + }); + } + if (gitReady) { + containerEl.createEl("br"); + containerEl.createEl("h3", { text: "Automatic" }); + new import_obsidian8.Setting(containerEl).setName("Split automatic commit and push").setDesc("Enable to use separate timer for commit and push").addToggle( + (toggle) => toggle.setValue( + plugin.settings.differentIntervalCommitAndPush + ).onChange((value) => { + plugin.settings.differentIntervalCommitAndPush = value; + plugin.saveSettings(); + plugin.clearAutoBackup(); + plugin.clearAutoPush(); + if (plugin.settings.autoSaveInterval > 0) { + plugin.startAutoBackup( + plugin.settings.autoSaveInterval + ); + } + if (value && plugin.settings.autoPushInterval > 0) { + plugin.startAutoPush( + plugin.settings.autoPushInterval + ); + } + this.display(); + }) + ); + new import_obsidian8.Setting(containerEl).setName(`Vault ${commitOrBackup} interval (minutes)`).setDesc( + `${plugin.settings.differentIntervalCommitAndPush ? "Commit" : "Commit and push"} changes every X minutes. Set to 0 (default) to disable. (See below setting for further configuration!)` + ).addText( + (text2) => text2.setValue(String(plugin.settings.autoSaveInterval)).onChange((value) => { + if (!isNaN(Number(value))) { + plugin.settings.autoSaveInterval = Number(value); + plugin.saveSettings(); + if (plugin.settings.autoSaveInterval > 0) { + plugin.clearAutoBackup(); + plugin.startAutoBackup( + plugin.settings.autoSaveInterval + ); + new import_obsidian8.Notice( + `Automatic ${commitOrBackup} enabled! Every ${plugin.settings.autoSaveInterval} minutes.` + ); + } else if (plugin.settings.autoSaveInterval <= 0) { + plugin.clearAutoBackup() && new import_obsidian8.Notice( + `Automatic ${commitOrBackup} disabled!` + ); + } + } else { + new import_obsidian8.Notice("Please specify a valid number."); + } + }) + ); + if (!plugin.settings.setLastSaveToLastCommit) + new import_obsidian8.Setting(containerEl).setName(`Auto Backup after file change`).setDesc( + `If turned on, do auto ${commitOrBackup} every ${plugin.settings.autoSaveInterval} minutes after last change. This also prevents auto ${commitOrBackup} while editing a file. If turned off, it's independent from the last change.` + ).addToggle( + (toggle) => toggle.setValue(plugin.settings.autoBackupAfterFileChange).onChange((value) => { + plugin.settings.autoBackupAfterFileChange = value; + this.display(); + plugin.saveSettings(); + plugin.clearAutoBackup(); + if (plugin.settings.autoSaveInterval > 0) { + plugin.startAutoBackup( + plugin.settings.autoSaveInterval + ); + } + }) + ); + if (!plugin.settings.autoBackupAfterFileChange) + new import_obsidian8.Setting(containerEl).setName(`Auto ${commitOrBackup} after latest commit`).setDesc( + `If turned on, set last auto ${commitOrBackup} time to latest commit` + ).addToggle( + (toggle) => toggle.setValue(plugin.settings.setLastSaveToLastCommit).onChange(async (value) => { + plugin.settings.setLastSaveToLastCommit = value; + plugin.saveSettings(); + this.display(); + plugin.clearAutoBackup(); + await plugin.setUpAutoBackup(); + }) + ); + if (plugin.settings.differentIntervalCommitAndPush) { + new import_obsidian8.Setting(containerEl).setName(`Vault push interval (minutes)`).setDesc( + "Push changes every X minutes. Set to 0 (default) to disable." + ).addText( + (text2) => text2.setValue(String(plugin.settings.autoPushInterval)).onChange((value) => { + if (!isNaN(Number(value))) { + plugin.settings.autoPushInterval = Number(value); + plugin.saveSettings(); + if (plugin.settings.autoPushInterval > 0) { + plugin.clearAutoPush(); + plugin.startAutoPush( + plugin.settings.autoPushInterval + ); + new import_obsidian8.Notice( + `Automatic push enabled! Every ${plugin.settings.autoPushInterval} minutes.` + ); + } else if (plugin.settings.autoPushInterval <= 0) { + plugin.clearAutoPush() && new import_obsidian8.Notice( + "Automatic push disabled!" + ); + } + } else { + new import_obsidian8.Notice( + "Please specify a valid number." + ); + } + }) + ); + } + new import_obsidian8.Setting(containerEl).setName("Auto pull interval (minutes)").setDesc( + "Pull changes every X minutes. Set to 0 (default) to disable." + ).addText( + (text2) => text2.setValue(String(plugin.settings.autoPullInterval)).onChange((value) => { + if (!isNaN(Number(value))) { + plugin.settings.autoPullInterval = Number(value); + plugin.saveSettings(); + if (plugin.settings.autoPullInterval > 0) { + plugin.clearAutoPull(); + plugin.startAutoPull( + plugin.settings.autoPullInterval + ); + new import_obsidian8.Notice( + `Automatic pull enabled! Every ${plugin.settings.autoPullInterval} minutes.` + ); + } else if (plugin.settings.autoPullInterval <= 0) { + plugin.clearAutoPull() && new import_obsidian8.Notice("Automatic pull disabled!"); + } + } else { + new import_obsidian8.Notice("Please specify a valid number."); + } + }) + ); + new import_obsidian8.Setting(containerEl).setName("Specify custom commit message on auto backup").setDesc("You will get a pop up to specify your message").addToggle( + (toggle) => toggle.setValue(plugin.settings.customMessageOnAutoBackup).onChange((value) => { + plugin.settings.customMessageOnAutoBackup = value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Commit message on auto backup/commit").setDesc( + "Available placeholders: {{date}} (see below), {{hostname}} (see below), {{numFiles}} (number of changed files in the commit) and {{files}} (changed files in commit message)" + ).addText( + (text2) => text2.setPlaceholder("vault backup: {{date}}").setValue(plugin.settings.autoCommitMessage).onChange((value) => { + plugin.settings.autoCommitMessage = value; + plugin.saveSettings(); + }) + ); + containerEl.createEl("br"); + containerEl.createEl("h3", { text: "Commit message" }); + new import_obsidian8.Setting(containerEl).setName("Commit message on manual backup/commit").setDesc( + "Available placeholders: {{date}} (see below), {{hostname}} (see below), {{numFiles}} (number of changed files in the commit) and {{files}} (changed files in commit message)" + ).addText( + (text2) => text2.setPlaceholder("vault backup: {{date}}").setValue( + plugin.settings.commitMessage ? plugin.settings.commitMessage : "" + ).onChange((value) => { + plugin.settings.commitMessage = value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("{{date}} placeholder format").setDesc( + `Specify custom date format. E.g. "${DATE_TIME_FORMAT_SECONDS}"` + ).addText( + (text2) => text2.setPlaceholder(plugin.settings.commitDateFormat).setValue(plugin.settings.commitDateFormat).onChange(async (value) => { + plugin.settings.commitDateFormat = value; + await plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("{{hostname}} placeholder replacement").setDesc("Specify custom hostname for every device.").addText( + (text2) => { + var _a2; + return text2.setValue((_a2 = plugin.localStorage.getHostname()) != null ? _a2 : "").onChange(async (value) => { + plugin.localStorage.setHostname(value); + }); + } + ); + new import_obsidian8.Setting(containerEl).setName("Preview commit message").addButton( + (button) => button.setButtonText("Preview").onClick(async () => { + const commitMessagePreview = await plugin.gitManager.formatCommitMessage( + plugin.settings.commitMessage + ); + new import_obsidian8.Notice(`${commitMessagePreview}`); + }) + ); + new import_obsidian8.Setting(containerEl).setName("List filenames affected by commit in the commit body").addToggle( + (toggle) => toggle.setValue(plugin.settings.listChangedFilesInMessageBody).onChange((value) => { + plugin.settings.listChangedFilesInMessageBody = value; + plugin.saveSettings(); + }) + ); + containerEl.createEl("br"); + containerEl.createEl("h3", { text: "Backup" }); + if (plugin.gitManager instanceof SimpleGit) + new import_obsidian8.Setting(containerEl).setName("Sync Method").setDesc( + "Selects the method used for handling new changes found in your remote git repository." + ).addDropdown((dropdown) => { + const options = { + merge: "Merge", + rebase: "Rebase", + reset: "Other sync service (Only updates the HEAD without touching the working directory)" + }; + dropdown.addOptions(options); + dropdown.setValue(plugin.settings.syncMethod); + dropdown.onChange(async (option) => { + plugin.settings.syncMethod = option; + plugin.saveSettings(); + }); + }); + new import_obsidian8.Setting(containerEl).setName("Pull updates on startup").setDesc("Automatically pull updates when Obsidian starts").addToggle( + (toggle) => toggle.setValue(plugin.settings.autoPullOnBoot).onChange((value) => { + plugin.settings.autoPullOnBoot = value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Push on backup").setDesc("Disable to only commit changes").addToggle( + (toggle) => toggle.setValue(!plugin.settings.disablePush).onChange((value) => { + plugin.settings.disablePush = !value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Pull changes before push").setDesc("Commit -> pull -> push (Only if pushing is enabled)").addToggle( + (toggle) => toggle.setValue(plugin.settings.pullBeforePush).onChange((value) => { + plugin.settings.pullBeforePush = value; + plugin.saveSettings(); + }) + ); + if (plugin.gitManager instanceof SimpleGit) { + containerEl.createEl("br"); + containerEl.createEl("h3", { text: "Line author information" }); + this.addLineAuthorInfoSettings(); + } + } + containerEl.createEl("br"); + containerEl.createEl("h3", { text: "Miscellaneous" }); + new import_obsidian8.Setting(containerEl).setName( + "Automatically refresh Source Control View on file changes" + ).setDesc( + "On slower machines this may cause lags. If so, just disable this option" + ).addToggle( + (toggle) => toggle.setValue(plugin.settings.refreshSourceControl).onChange((value) => { + plugin.settings.refreshSourceControl = value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Source Control View refresh interval").setDesc( + "Milliseconds to wait after file change before refreshing the Source Control View" + ).addText( + (toggle) => toggle.setValue( + plugin.settings.refreshSourceControlTimer.toString() + ).setPlaceholder("7000").onChange((value) => { + plugin.settings.refreshSourceControlTimer = Math.max( + parseInt(value), + 500 + ); + plugin.saveSettings(); + plugin.setRefreshDebouncer(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Disable notifications").setDesc( + "Disable notifications for git operations to minimize distraction (refer to status bar for updates). Errors are still shown as notifications even if you enable this setting" + ).addToggle( + (toggle) => toggle.setValue(plugin.settings.disablePopups).onChange((value) => { + plugin.settings.disablePopups = value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Show status bar").setDesc( + "Obsidian must be restarted for the changes to take affect" + ).addToggle( + (toggle) => toggle.setValue(plugin.settings.showStatusBar).onChange((value) => { + plugin.settings.showStatusBar = value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Show stage/unstage button in file menu").addToggle( + (toggle) => toggle.setValue(plugin.settings.showFileMenu).onChange((value) => { + plugin.settings.showFileMenu = value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Show branch status bar").setDesc( + "Obsidian must be restarted for the changes to take affect" + ).addToggle( + (toggle) => toggle.setValue(plugin.settings.showBranchStatusBar).onChange((value) => { + plugin.settings.showBranchStatusBar = value; + plugin.saveSettings(); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Show changes files count in status bar").addToggle( + (toggle) => toggle.setValue(plugin.settings.changedFilesInStatusBar).onChange((value) => { + plugin.settings.changedFilesInStatusBar = value; + plugin.saveSettings(); + }) + ); + containerEl.createEl("br"); + if (plugin.gitManager instanceof IsomorphicGit) { + containerEl.createEl("h3", { + text: "Authentication/Commit Author" + }); + } else { + containerEl.createEl("h3", { text: "Commit Author" }); + } + if (plugin.gitManager instanceof IsomorphicGit) + new import_obsidian8.Setting(containerEl).setName( + "Username on your git server. E.g. your username on GitHub" + ).addText((cb) => { + var _a2; + cb.setValue((_a2 = plugin.localStorage.getUsername()) != null ? _a2 : ""); + cb.onChange((value) => { + plugin.localStorage.setUsername(value); + }); + }); + if (plugin.gitManager instanceof IsomorphicGit) + new import_obsidian8.Setting(containerEl).setName("Password/Personal access token").setDesc( + "Type in your password. You won't be able to see it again." + ).addText((cb) => { + cb.inputEl.autocapitalize = "off"; + cb.inputEl.autocomplete = "off"; + cb.inputEl.spellcheck = false; + cb.onChange((value) => { + plugin.localStorage.setPassword(value); + }); + }); + if (plugin.gitReady) + new import_obsidian8.Setting(containerEl).setName("Author name for commit").addText(async (cb) => { + cb.setValue(await plugin.gitManager.getConfig("user.name")); + cb.onChange((value) => { + plugin.gitManager.setConfig( + "user.name", + value == "" ? void 0 : value + ); + }); + }); + if (plugin.gitReady) + new import_obsidian8.Setting(containerEl).setName("Author email for commit").addText(async (cb) => { + cb.setValue( + await plugin.gitManager.getConfig("user.email") + ); + cb.onChange((value) => { + plugin.gitManager.setConfig( + "user.email", + value == "" ? void 0 : value + ); + }); + }); + containerEl.createEl("br"); + containerEl.createEl("h3", { text: "Advanced" }); + if (plugin.gitManager instanceof SimpleGit) { + new import_obsidian8.Setting(containerEl).setName("Update submodules").setDesc( + '"Create backup" and "pull" takes care of submodules. Missing features: Conflicted files, count of pulled/pushed/committed files. Tracking branch needs to be set for each submodule' + ).addToggle( + (toggle) => toggle.setValue(plugin.settings.updateSubmodules).onChange((value) => { + plugin.settings.updateSubmodules = value; + plugin.saveSettings(); + }) + ); + if (plugin.settings.updateSubmodules) { + new import_obsidian8.Setting(containerEl).setName("Submodule recurse checkout/switch").setDesc( + "Whenever a checkout happens on the root repository, recurse the checkout on the submodules (if the branches exist)." + ).addToggle( + (toggle) => toggle.setValue(plugin.settings.submoduleRecurseCheckout).onChange((value) => { + plugin.settings.submoduleRecurseCheckout = value; + plugin.saveSettings(); + }) + ); + } + } + if (plugin.gitManager instanceof SimpleGit) + new import_obsidian8.Setting(containerEl).setName("Custom Git binary path").addText((cb) => { + var _a2; + cb.setValue((_a2 = plugin.localStorage.getGitPath()) != null ? _a2 : ""); + cb.setPlaceholder("git"); + cb.onChange((value) => { + plugin.localStorage.setGitPath(value); + plugin.gitManager.updateGitPath(value || "git"); + }); + }); + if (plugin.gitManager instanceof SimpleGit) + new import_obsidian8.Setting(containerEl).setName("Additional environment variables").setDesc( + "Use each line for a new environment variable in the format KEY=VALUE" + ).addTextArea((cb) => { + cb.setPlaceholder("GIT_DIR=/path/to/git/dir"); + cb.setValue(plugin.localStorage.getEnvVars().join("\n")); + cb.onChange((value) => { + plugin.localStorage.setEnvVars(value.split("\n")); + }); + }); + if (plugin.gitManager instanceof SimpleGit) + new import_obsidian8.Setting(containerEl).setName("Additional PATH environment variable paths").setDesc("Use each line for one path").addTextArea((cb) => { + cb.setValue(plugin.localStorage.getPATHPaths().join("\n")); + cb.onChange((value) => { + plugin.localStorage.setPATHPaths(value.split("\n")); + }); + }); + if (plugin.gitManager instanceof SimpleGit) + new import_obsidian8.Setting(containerEl).setName("Reload with new environment variables").setDesc( + "Removing previously added environment variables will not take effect until Obsidian is restarted." + ).addButton((cb) => { + cb.setButtonText("Reload"); + cb.setCta(); + cb.onClick(() => { + plugin.gitManager.setGitInstance(); + }); + }); + new import_obsidian8.Setting(containerEl).setName("Custom base path (Git repository path)").setDesc( + ` + Sets the relative path to the vault from which the Git binary should be executed. + Mostly used to set the path to the Git repository, which is only required if the Git repository is below the vault root directory. Use "\\" instead of "/" on Windows. + ` + ).addText((cb) => { + cb.setValue(plugin.settings.basePath); + cb.setPlaceholder("directory/directory-with-git-repo"); + cb.onChange((value) => { + plugin.settings.basePath = value; + plugin.saveSettings(); + plugin.gitManager.updateBasePath(value || ""); + }); + }); + new import_obsidian8.Setting(containerEl).setName("Custom Git directory path (Instead of '.git')").setDesc( + `Requires restart of Obsidian to take effect. Use "\\" instead of "/" on Windows.` + ).addText((cb) => { + cb.setValue(plugin.settings.gitDir); + cb.setPlaceholder(".git"); + cb.onChange((value) => { + plugin.settings.gitDir = value; + plugin.saveSettings(); + }); + }); + new import_obsidian8.Setting(containerEl).setName("Disable on this device").addToggle( + (toggle) => toggle.setValue(plugin.localStorage.getPluginDisabled()).onChange((value) => { + plugin.localStorage.setPluginDisabled(value); + if (value) { + plugin.unloadPlugin(); + } else { + plugin.loadPlugin(); + } + new import_obsidian8.Notice( + "Obsidian must be restarted for the changes to take affect" + ); + }) + ); + new import_obsidian8.Setting(containerEl).setName("Donate").setDesc( + "If you like this Plugin, consider donating to support continued development." + ).addButton((bt) => { + bt.buttonEl.outerHTML = "Buy Me a Coffee at ko-fi.com"; + }); + const info = containerEl.createDiv(); + info.setAttr("align", "center"); + info.setText( + "Debugging and logging:\nYou can always see the logs of this and every other plugin by opening the console with" + ); + const keys = containerEl.createDiv(); + keys.setAttr("align", "center"); + keys.addClass("obsidian-git-shortcuts"); + if (import_obsidian8.Platform.isMacOS === true) { + keys.createEl("kbd", { text: "CMD (\u2318) + OPTION (\u2325) + I" }); + } else { + keys.createEl("kbd", { text: "CTRL + SHIFT + I" }); + } + } + configureLineAuthorShowStatus(show) { + this.settings.lineAuthor.show = show; + this.plugin.saveSettings(); + if (show) + this.plugin.lineAuthoringFeature.activateFeature(); + else + this.plugin.lineAuthoringFeature.deactivateFeature(); + } + /** + * Persists the setting {@link key} with value {@link value} and + * refreshes the line author info views. + */ + lineAuthorSettingHandler(key2, value) { + this.settings.lineAuthor[key2] = value; + this.plugin.saveSettings(); + this.plugin.lineAuthoringFeature.refreshLineAuthorViews(); + } + /** + * Ensure, that certain last shown values are persisten in the settings. + * + * Necessary for the line author info gutter context menus. + */ + beforeSaveSettings() { + const laSettings = this.settings.lineAuthor; + if (laSettings.authorDisplay !== "hide") { + laSettings.lastShownAuthorDisplay = laSettings.authorDisplay; + } + if (laSettings.dateTimeFormatOptions !== "hide") { + laSettings.lastShownDateTimeFormatOptions = laSettings.dateTimeFormatOptions; + } + } + addLineAuthorInfoSettings() { + const baseLineAuthorInfoSetting = new import_obsidian8.Setting(this.containerEl).setName( + "Show commit authoring information next to each line" + ); + if (!this.plugin.lineAuthoringFeature.isAvailableOnCurrentPlatform()) { + baseLineAuthorInfoSetting.setDesc("Only available on desktop currently.").setDisabled(true); + } + baseLineAuthorInfoSetting.descEl.innerHTML = ` + Feature guide and quick examples
+ The commit hash, author name and authoring date can all be individually toggled.
Hide everything, to only show the age-colored sidebar.`; + baseLineAuthorInfoSetting.addToggle( + (toggle) => toggle.setValue(this.settings.lineAuthor.show).onChange((value) => { + this.configureLineAuthorShowStatus(value); + this.display(); + }) + ); + if (this.settings.lineAuthor.show) { + const trackMovement = new import_obsidian8.Setting(this.containerEl).setName("Follow movement and copies across files and commits").setDesc("").addDropdown((dropdown) => { + dropdown.addOptions({ + inactive: "Do not follow (default)", + "same-commit": "Follow within same commit", + "all-commits": "Follow within all commits (maybe slow)" + }); + dropdown.setValue(this.settings.lineAuthor.followMovement); + dropdown.onChange( + (value) => this.lineAuthorSettingHandler("followMovement", value) + ); + }); + trackMovement.descEl.innerHTML = ` + By default (deactivated), each line only shows the newest commit where it was changed. +
+ With same commit, cut-copy-paste-ing of text is followed within the same commit and the original commit of authoring will be shown. +
+ With all commits, cut-copy-paste-ing text inbetween multiple commits will be detected. +
+ It uses git-blame and + for matches (at least ${GIT_LINE_AUTHORING_MOVEMENT_DETECTION_MINIMAL_LENGTH} characters) within the same (or all) commit(s), the originating commit's information is shown.`; + new import_obsidian8.Setting(this.containerEl).setName("Show commit hash").addToggle((tgl) => { + tgl.setValue(this.settings.lineAuthor.showCommitHash); + tgl.onChange( + async (value) => this.lineAuthorSettingHandler("showCommitHash", value) + ); + }); + new import_obsidian8.Setting(this.containerEl).setName("Author name display").setDesc("If and how the author is displayed").addDropdown((dropdown) => { + const options = { + hide: "Hide", + initials: "Initials (default)", + "first name": "First name", + "last name": "Last name", + full: "Full name" + }; + dropdown.addOptions(options); + dropdown.setValue(this.settings.lineAuthor.authorDisplay); + dropdown.onChange( + async (value) => this.lineAuthorSettingHandler("authorDisplay", value) + ); + }); + new import_obsidian8.Setting(this.containerEl).setName("Authoring date display").setDesc( + "If and how the date and time of authoring the line is displayed" + ).addDropdown((dropdown) => { + const options = { + hide: "Hide", + date: "Date (default)", + datetime: "Date and time", + "natural language": "Natural language", + custom: "Custom" + }; + dropdown.addOptions(options); + dropdown.setValue( + this.settings.lineAuthor.dateTimeFormatOptions + ); + dropdown.onChange( + async (value) => { + this.lineAuthorSettingHandler( + "dateTimeFormatOptions", + value + ); + this.display(); + } + ); + }); + if (this.settings.lineAuthor.dateTimeFormatOptions === "custom") { + const dateTimeFormatCustomStringSetting = new import_obsidian8.Setting( + this.containerEl + ); + dateTimeFormatCustomStringSetting.setName("Custom authoring date format").addText((cb) => { + cb.setValue( + this.settings.lineAuthor.dateTimeFormatCustomString + ); + cb.setPlaceholder("YYYY-MM-DD HH:mm"); + cb.onChange((value) => { + this.lineAuthorSettingHandler( + "dateTimeFormatCustomString", + value + ); + dateTimeFormatCustomStringSetting.descEl.innerHTML = this.previewCustomDateTimeDescriptionHtml( + value + ); + }); + }); + dateTimeFormatCustomStringSetting.descEl.innerHTML = this.previewCustomDateTimeDescriptionHtml( + this.settings.lineAuthor.dateTimeFormatCustomString + ); + } + new import_obsidian8.Setting(this.containerEl).setName("Authoring date display timezone").addDropdown((dropdown) => { + const options = { + "viewer-local": "My local (default)", + "author-local": "Author's local", + utc0000: "UTC+0000/Z" + }; + dropdown.addOptions(options); + dropdown.setValue( + this.settings.lineAuthor.dateTimeTimezone + ); + dropdown.onChange( + async (value) => this.lineAuthorSettingHandler("dateTimeTimezone", value) + ); + }).descEl.innerHTML = ` + The time-zone in which the authoring date should be shown. + Either your local time-zone (default), + the author's time-zone during commit creation or + UTC\xB100:00. + `; + const oldestAgeSetting = new import_obsidian8.Setting(this.containerEl).setName( + "Oldest age in coloring" + ); + oldestAgeSetting.descEl.innerHTML = this.previewOldestAgeDescriptionHtml( + this.settings.lineAuthor.coloringMaxAge + )[0]; + oldestAgeSetting.addText((text2) => { + text2.setPlaceholder("1y"); + text2.setValue(this.settings.lineAuthor.coloringMaxAge); + text2.onChange((value) => { + const [preview, valid] = this.previewOldestAgeDescriptionHtml(value); + oldestAgeSetting.descEl.innerHTML = preview; + if (valid) { + this.lineAuthorSettingHandler("coloringMaxAge", value); + this.refreshColorSettingsName("oldest"); + } + }); + }); + this.createColorSetting("newest"); + this.createColorSetting("oldest"); + new import_obsidian8.Setting(this.containerEl).setName("Text color").addText((field) => { + field.setValue(this.settings.lineAuthor.textColorCss); + field.onChange((value) => { + this.lineAuthorSettingHandler("textColorCss", value); + }); + }).descEl.innerHTML = ` + The CSS color of the gutter text.
+ + It is higly recommended to use + + CSS variables + defined by themes + (e.g.
var(--text-muted)
or +
var(--text-on-accent)
, + because they automatically adapt to theme changes.
+ + See: + List of available CSS variables in Obsidian + + `; + new import_obsidian8.Setting(this.containerEl).setName("Ignore whitespace and newlines in changes").addToggle((tgl) => { + tgl.setValue(this.settings.lineAuthor.ignoreWhitespace); + tgl.onChange( + (value) => this.lineAuthorSettingHandler("ignoreWhitespace", value) + ); + }).descEl.innerHTML = ` + Whitespace and newlines are interpreted as + part of the document and in changes + by default (hence not ignored). + This makes the last line being shown as 'changed' + when a new subsequent line is added, + even if the previously last line's text is the same. +
+ If you don't care about purely-whitespace changes + (e.g. list nesting / quote indentation changes), + then activating this will provide more meaningful change detection. + `; + } + } + createColorSetting(which) { + const setting = new import_obsidian8.Setting(this.containerEl).setName("").addText((text2) => { + const color = pickColor(which, this.settings.lineAuthor); + const defaultColor = pickColor( + which, + DEFAULT_SETTINGS.lineAuthor + ); + text2.setPlaceholder(rgbToString(defaultColor)); + text2.setValue(rgbToString(color)); + text2.onChange((colorNew) => { + const rgb = convertToRgb(colorNew); + if (rgb !== void 0) { + const key2 = which === "newest" ? "colorNew" : "colorOld"; + this.lineAuthorSettingHandler(key2, rgb); + } + this.refreshColorSettingsDesc(which, rgb); + }); + }); + this.lineAuthorColorSettings.set(which, setting); + this.refreshColorSettingsName(which); + this.refreshColorSettingsDesc( + which, + pickColor(which, this.settings.lineAuthor) + ); + } + refreshColorSettingsName(which) { + const settingsDom = this.lineAuthorColorSettings.get(which); + if (settingsDom) { + const whichDescriber = which === "oldest" ? `oldest (${this.settings.lineAuthor.coloringMaxAge} or older)` : "newest"; + settingsDom.nameEl.innerText = `Color for ${whichDescriber} commits`; + } + } + refreshColorSettingsDesc(which, rgb) { + const settingsDom = this.lineAuthorColorSettings.get(which); + if (settingsDom) { + settingsDom.descEl.innerHTML = this.colorSettingPreviewDescHtml( + which, + this.settings.lineAuthor, + rgb !== void 0 + ); + } + } + colorSettingPreviewDescHtml(which, laSettings, colorIsValid) { + const rgbStr = colorIsValid ? previewColor(which, laSettings) : `rgba(127,127,127,0.3)`; + const today = import_obsidian8.moment.unix(import_obsidian8.moment.now() / 1e3).format("YYYY-MM-DD"); + const text2 = colorIsValid ? `abcdef Author Name ${today}` : "invalid color"; + const preview = `
${text2}
`; + return `Supports 'rgb(r,g,b)', 'hsl(h,s,l)', hex (#) and + named colors (e.g. 'black', 'purple'). Color preview: ${preview}`; + } + previewCustomDateTimeDescriptionHtml(dateTimeFormatCustomString) { + const formattedDateTime = (0, import_obsidian8.moment)().format(dateTimeFormatCustomString); + return `
Format string to display the authoring date.
Currently: ${formattedDateTime}`; + } + previewOldestAgeDescriptionHtml(coloringMaxAge) { + const duration = parseColoringMaxAgeDuration(coloringMaxAge); + const durationString = duration !== void 0 ? `${duration.asDays()} days` : "invalid!"; + return [ + `The oldest age in the line author coloring. Everything older will have the same color. +
Smallest valid age is "1d". Currently: ${durationString}`, + duration + ]; + } +}; +function pickColor(which, las) { + return which === "oldest" ? las.colorOld : las.colorNew; +} +function parseColoringMaxAgeDuration(durationString) { + const duration = import_obsidian8.moment.duration("P" + durationString.toUpperCase()); + return duration.isValid() && duration.asDays() && duration.asDays() >= 1 ? duration : void 0; +} + +// src/lineAuthor/model.ts +function lineAuthoringId(head, objHash, path2) { + if (head === void 0 || objHash === void 0 || path2 === void 0) { + return void 0; + } + return `head${head}-obj${objHash}-path${path2}`; +} +var LineAuthoringContainerType = import_state.Annotation.define(); +function newComputationResultAsTransaction(key2, la, state) { + return state.update({ + annotations: LineAuthoringContainerType.of({ + key: key2, + la, + lineOffsetsFromUnsavedChanges: /* @__PURE__ */ new Map() + }) + }); +} +function getLineAuthorAnnotation(tr) { + return tr.annotation(LineAuthoringContainerType); +} +var lineAuthorState = import_state.StateField.define({ + create: (_state) => void 0, + /** + * The state can be updated from either an annotated transaction containing + * the newest line authoring (for the saved document) - or from + * unsaved changes of the document as the user is actively typing in the editor. + * + * In the first case, we take the new line authoring and discard anything we had remembered + * from unsaved changes. In the second case, we use the unsaved changes in {@link enrichUnsavedChanges} to pre-compute information to immediately update the + * line author gutter without needing to wait until the document is saved and the + * line authoring is properly computed. + */ + update: (previous, transaction) => { + var _a2; + return (_a2 = getLineAuthorAnnotation(transaction)) != null ? _a2 : enrichUnsavedChanges(transaction, previous); + }, + // compare cache keys. + // equality rate is >= 95% :) + // hence avoids recomputation of views + compare: (l, r) => (l == null ? void 0 : l.key) === (r == null ? void 0 : r.key) +}); +function laStateDigest(laState) { + var _a2; + const digest = import_js_sha256.sha256.create(); + if (!laState) + return digest; + const { la, key: key2, lineOffsetsFromUnsavedChanges } = laState; + digest.update(la === "untracked" ? "t" : "f"); + digest.update(key2); + for (const [k, v] of (_a2 = lineOffsetsFromUnsavedChanges.entries()) != null ? _a2 : []) + digest.update([k, v]); + return digest; +} +var latestSettings = { + get: void 0, + save: void 0 +}; +function provideSettingsAccess(settingsGetter, settingsSetter) { + latestSettings.get = settingsGetter; + latestSettings.save = settingsSetter; +} +function maxAgeInDaysFromSettings(settings) { + var _a2, _b; + return (_b = (_a2 = parseColoringMaxAgeDuration(settings.coloringMaxAge)) == null ? void 0 : _a2.asDays()) != null ? _b : parseColoringMaxAgeDuration( + DEFAULT_SETTINGS.lineAuthor.coloringMaxAge + ).asDays(); +} +function enrichUnsavedChanges(tr, prev) { + if (!prev) + return void 0; + if (!tr.changes.empty) { + tr.changes.iterChanges((fromA, toA, fromB, toB) => { + var _a2; + const oldDoc = tr.startState.doc; + const { newDoc } = tr; + const beforeFrom = oldDoc.lineAt(fromA).number; + const beforeTo = oldDoc.lineAt(toA).number; + const afterFrom = newDoc.lineAt(fromB).number; + const afterTo = newDoc.lineAt(toB).number; + const beforeLen = beforeTo - beforeFrom + 1; + const afterLen = afterTo - afterFrom + 1; + for (let afterI = afterFrom; afterI <= afterTo; afterI++) { + let offset = (_a2 = prev.lineOffsetsFromUnsavedChanges.get(afterI)) != null ? _a2 : 0; + const isLastLine = afterTo === afterI; + const changeInNumberOfLines = afterLen - beforeLen; + if (isLastLine) + offset += changeInNumberOfLines; + prev.lineOffsetsFromUnsavedChanges.set(afterI, offset); + } + }); + } + return prev; +} + +// src/lineAuthor/control.ts +var LineAuthoringSubscriber = class { + // remember path to detect and adapt to renames + constructor(state) { + this.state = state; + this.subscribeMe(); + } + async notifyLineAuthoring(id, la) { + if (this.view === void 0) { + console.warn( + `Obsidian Git: View is not defined for editor cache key. Unforeseen situation. id: ${id}` + ); + return; + } + const state = this.view.state; + const transaction = newComputationResultAsTransaction(id, la, state); + this.view.dispatch(transaction); + } + updateToNewState(state) { + const filepathChanged = this.lastSeenPath && this.filepath != this.lastSeenPath; + this.state = state; + if (filepathChanged) { + this.unsubscribeMe(this.lastSeenPath); + this.subscribeMe(); + } + return this; + } + removeIfStale() { + if (this.view.destroyed) { + this.unsubscribeMe(this.lastSeenPath); + } + } + subscribeMe() { + if (this.filepath === void 0) + return; + eventsPerFilePathSingleton.ifFilepathDefinedTransformSubscribers( + this.filepath, + (subs) => subs.add(this) + ); + this.lastSeenPath = this.filepath; + } + unsubscribeMe(oldFilepath) { + eventsPerFilePathSingleton.ifFilepathDefinedTransformSubscribers( + oldFilepath, + (subs) => subs.delete(this) + ); + } + get filepath() { + var _a2, _b; + return (_b = (_a2 = this.state.field(import_obsidian9.editorViewField)) == null ? void 0 : _a2.file) == null ? void 0 : _b.path; + } + get view() { + return this.state.field(import_obsidian9.editorEditorField); + } +}; +var subscribeNewEditor = import_state2.StateField.define({ + create: (state) => new LineAuthoringSubscriber(state), + update: (v, transaction) => v.updateToNewState(transaction.state), + compare: (a, b) => a === b +}); + +// src/lineAuthor/view/cache.ts +init_polyfill_buffer(); +function clearViewCache() { + longestRenderedGutter = void 0; + renderedAgeInDaysForAdaptiveInitialColoring = []; + ageIdx = 0; + gutterInstances.clear(); + gutterMarkersRangeSet.clear(); + attachedGutterElements.clear(); +} +var longestRenderedGutter = void 0; +var getLongestRenderedGutter = () => longestRenderedGutter; +function conditionallyUpdateLongestRenderedGutter(gutter2, text2) { + var _a2; + const length = text2.length; + if (length < ((_a2 = longestRenderedGutter == null ? void 0 : longestRenderedGutter.length) != null ? _a2 : 0)) + return; + longestRenderedGutter = { gutter: gutter2, length, text: text2 }; + const settings = latestSettings.get(); + if (length !== settings.gutterSpacingFallbackLength) { + settings.gutterSpacingFallbackLength = length; + latestSettings.save(settings); + } +} +var renderedAgeInDaysForAdaptiveInitialColoring = []; +var ADAPTIVE_INITIAL_COLORING_AGE_CACHE_SIZE = 15; +var ageIdx = 0; +function recordRenderedAgeInDays(age) { + renderedAgeInDaysForAdaptiveInitialColoring[ageIdx] = age; + ageIdx = (ageIdx + 1) % ADAPTIVE_INITIAL_COLORING_AGE_CACHE_SIZE; +} +function computeAdaptiveInitialColoringAgeInDays() { + return median(renderedAgeInDaysForAdaptiveInitialColoring); +} +var gutterInstances = /* @__PURE__ */ new Map(); +var gutterMarkersRangeSet = /* @__PURE__ */ new Map(); +var attachedGutterElements = /* @__PURE__ */ new Set(); + +// src/lineAuthor/view/view.ts +init_polyfill_buffer(); +var import_state3 = require("@codemirror/state"); +var import_view2 = require("@codemirror/view"); + +// src/lineAuthor/view/gutter/gutter.ts +init_polyfill_buffer(); +var import_view = require("@codemirror/view"); +var import_js_sha2562 = __toESM(require_sha256()); +var import_obsidian10 = require("obsidian"); + +// src/lineAuthor/view/contextMenu.ts +init_polyfill_buffer(); + +// src/lineAuthor/view/gutter/gutterElementSearch.ts +init_polyfill_buffer(); +var mouseXY = { x: -10, y: -10 }; +function prepareGutterSearchForContextMenuHandling() { + if (mouseXY.x === -10) { + window.addEventListener("mousedown", (e) => { + mouseXY.x = e.clientX; + mouseXY.y = e.clientY; + }); + } +} +function findGutterElementUnderMouse() { + for (const elt of attachedGutterElements) { + if (contains(elt, mouseXY)) + return elt; + } +} +function contains(elt, pt) { + const { x, y, width, height } = elt.getBoundingClientRect(); + return x <= pt.x && pt.x <= x + width && y <= pt.y && pt.y <= y + height; +} + +// src/pluginGlobalRef.ts +init_polyfill_buffer(); +var pluginRef = {}; + +// src/lineAuthor/view/contextMenu.ts +var COMMIT_ATTR = "data-commit"; +function handleContextMenu(menu, editor, _mdv) { + if (editor.hasFocus()) + return; + const gutterElement = findGutterElementUnderMouse(); + if (!gutterElement) + return; + const info = getCommitInfo(gutterElement); + if (!info) + return; + if (!info.isZeroCommit && !info.isWaitingGutter) { + addCopyHashMenuItem(info, menu); + } + addConfigurableLineAuthorSettings("showCommitHash", menu); + addConfigurableLineAuthorSettings("authorDisplay", menu); + addConfigurableLineAuthorSettings("dateTimeFormatOptions", menu); +} +function addCopyHashMenuItem(commit2, menu) { + menu.addItem( + (item) => item.setTitle("Copy commit hash").setIcon("copy").setSection("obs-git-line-author-copy").onClick((_e) => navigator.clipboard.writeText(commit2.hash)) + ); +} +function addConfigurableLineAuthorSettings(key2, menu) { + var _a2, _b; + let title; + let actionNewValue; + const settings = pluginRef.plugin.settings.lineAuthor; + const currentValue = settings[key2]; + const currentlyShown = typeof currentValue === "boolean" ? currentValue : currentValue !== "hide"; + const defaultValue = DEFAULT_SETTINGS.lineAuthor[key2]; + if (key2 === "showCommitHash") { + title = "Show commit hash"; + actionNewValue = !currentValue; + } else if (key2 === "authorDisplay") { + const showOption = (_a2 = settings.lastShownAuthorDisplay) != null ? _a2 : defaultValue; + title = "Show author " + (currentlyShown ? currentValue : showOption); + actionNewValue = currentlyShown ? "hide" : showOption; + } else if (key2 === "dateTimeFormatOptions") { + const showOption = (_b = settings.lastShownDateTimeFormatOptions) != null ? _b : defaultValue; + title = "Show " + (currentlyShown ? currentValue : showOption); + title += !title.contains("date") ? " date" : ""; + actionNewValue = currentlyShown ? "hide" : showOption; + } else { + impossibleBranch(key2); + } + menu.addItem( + (item) => item.setTitle(title).setSection("obs-git-line-author-configure").setChecked(currentlyShown).onClick( + (_e) => { + var _a3, _b2; + return (_b2 = (_a3 = pluginRef.plugin) == null ? void 0 : _a3.settingsTab) == null ? void 0 : _b2.lineAuthorSettingHandler( + key2, + actionNewValue + ); + } + ) + ); +} +function enrichCommitInfoForContextMenu(commit2, isWaitingGutter, elt) { + elt.setAttr( + COMMIT_ATTR, + JSON.stringify({ + hash: commit2.hash, + isZeroCommit: commit2.isZeroCommit, + isWaitingGutter + }) + ); +} +function getCommitInfo(elt) { + const commitInfoStr = elt.getAttr(COMMIT_ATTR); + return commitInfoStr ? JSON.parse(commitInfoStr) : void 0; +} + +// src/lineAuthor/view/gutter/coloring.ts +init_polyfill_buffer(); +function previewColor(which, settings) { + return which === "oldest" ? coloringBasedOnCommitAge(0, false, settings).color : coloringBasedOnCommitAge(void 0, true, settings).color; +} +function coloringBasedOnCommitAge(commitAuthorEpochSeonds, isZeroCommit, settings) { + const maxAgeInDays = maxAgeInDaysFromSettings(settings); + const epochSecondsNow = Date.now() / 1e3; + const authoringEpochSeconds = commitAuthorEpochSeonds != null ? commitAuthorEpochSeonds : 0; + const secondsSinceCommit = isZeroCommit ? 0 : epochSecondsNow - authoringEpochSeconds; + const daysSinceCommit = secondsSinceCommit / 60 / 60 / 24; + const x = Math.pow( + Math.clamp(daysSinceCommit / maxAgeInDays, 0, 1), + 1 / 2.3 + ); + const dark = isDarkMode(); + const color0 = settings.colorNew; + const color1 = settings.colorOld; + const scaling = dark ? 0.4 : 1; + const r = lin(color0.r, color1.r, x) * scaling; + const g = lin(color0.g, color1.g, x) * scaling; + const b = lin(color0.b, color1.b, x) * scaling; + const a = dark ? 0.75 : 0.25; + return { color: `rgba(${r},${g},${b},${a})`, daysSinceCommit }; +} +function lin(z0, z1, x) { + return z0 + (z1 - z0) * x; +} +function isDarkMode() { + const obsidian = window == null ? void 0 : window.app; + return (obsidian == null ? void 0 : obsidian.getTheme()) === "obsidian"; +} +function setTextColorCssBasedOnSetting(settings) { + document.body.style.setProperty( + "--obs-git-gutter-text", + settings.textColorCss + ); +} + +// src/lineAuthor/view/gutter/commitChoice.ts +init_polyfill_buffer(); +function chooseNewestCommit(lineAuthoring, startLine, endLine) { + let newest = void 0; + for (let line = startLine; line <= endLine; line++) { + const currentHash = lineAuthoring.hashPerLine[line]; + const currentCommit = lineAuthoring.commits.get(currentHash); + if (!newest || currentCommit.isZeroCommit || isNewerThan(currentCommit, newest)) { + newest = currentCommit; + } + } + return newest; +} +function isNewerThan(left, right) { + var _a2, _b, _c, _d; + const l = (_b = (_a2 = left.author) == null ? void 0 : _a2.epochSeconds) != null ? _b : 0; + const r = (_d = (_c = right.author) == null ? void 0 : _c.epochSeconds) != null ? _d : 0; + return l > r; +} + +// src/lineAuthor/view/gutter/gutter.ts +var VALUE_NOT_FOUND_FALLBACK = "-"; +var NEW_CHANGE_CHARACTER = "+"; +var NEW_CHANGE_NUMBER_OF_CHARACTERS = 3; +var DIFFERING_AUTHOR_COMMITTER_MARKER = "*"; +var NON_WHITESPACE_REGEXP = /\S/g; +var UNINTRUSIVE_CHARACTER_FOR_WAITING_RENDERING = "%"; +var TextGutter = class extends import_view.GutterMarker { + constructor(text2) { + super(); + this.text = text2; + } + eq(other) { + return this.text === (other == null ? void 0 : other.text); + } + toDOM() { + return document.createTextNode(this.text); + } + destroy(dom) { + if (!document.body.contains(dom)) + dom.remove(); + } +}; +var LineAuthoringGutter = class extends import_view.GutterMarker { + /** + * **This should only be called {@link lineAuthoringGutterMarker}!** + * + * We want to avoid creating the same instance multiple times for improved performance. + */ + constructor(lineAuthoring, startLine, endLine, key2, settings, options) { + super(); + this.lineAuthoring = lineAuthoring; + this.startLine = startLine; + this.endLine = endLine; + this.key = key2; + this.settings = settings; + this.options = options; + this.point = false; + this.elementClass = "obs-git-blame-gutter"; + } + // Equality used by CodeMirror for optimisations + eq(other) { + return this.key === (other == null ? void 0 : other.key) && this.startLine === (other == null ? void 0 : other.startLine) && this.endLine === (other == null ? void 0 : other.endLine) && (this == null ? void 0 : this.options) === (other == null ? void 0 : other.options); + } + /** + * Renders to a Html node. + * + * It choses the newest commit within the line-range, + * renders it, makes adjustments for fake-commits and finally warps + * it into HTML. + * + * The DOM is actually precomputed with {@link computeDom}, + * which provides a finaliser to run before the DOM is handed over to CodeMirror. + * This is done, because this method is called frequently. It is called, + * whenever a gutter gets into the viewport and needs to be rendered. + * + * The age in days is recorded via {@link recordRenderedAgeInDays} to enable adaptive coloring. + */ + toDOM() { + var _a2; + this.precomputedDomProvider = (_a2 = this.precomputedDomProvider) != null ? _a2 : this.computeDom(); + return this.precomputedDomProvider(); + } + destroy(dom) { + if (!document.body.contains(dom)) { + dom.remove(); + attachedGutterElements.delete(dom); + } + } + /** + * Prepares the DOM for this gutter. + */ + computeDom() { + const commit2 = chooseNewestCommit( + this.lineAuthoring, + this.startLine, + this.endLine + ); + let toBeRenderedText = commit2.isZeroCommit ? "" : this.renderNonZeroCommit(commit2); + const isTrueCommit = !commit2.isZeroCommit && this.options !== "waiting-for-result"; + if (isTrueCommit) { + conditionallyUpdateLongestRenderedGutter(this, toBeRenderedText); + } else { + toBeRenderedText = this.adaptTextForFakeCommit( + commit2, + toBeRenderedText, + this.options + ); + } + const domProvider = this.createHtmlNode( + commit2, + toBeRenderedText, + this.options === "waiting-for-result" + ); + return domProvider; + } + createHtmlNode(commit2, text2, isWaitingGutter) { + var _a2; + const templateElt = window.createDiv(); + templateElt.innerText = text2; + const { color, daysSinceCommit } = coloringBasedOnCommitAge( + (_a2 = commit2 == null ? void 0 : commit2.author) == null ? void 0 : _a2.epochSeconds, + commit2 == null ? void 0 : commit2.isZeroCommit, + this.settings + ); + templateElt.style.backgroundColor = color; + enrichCommitInfoForContextMenu(commit2, isWaitingGutter, templateElt); + function prepareForDomAttachment() { + const elt = templateElt.cloneNode(true); + attachedGutterElements.add(elt); + if (!isWaitingGutter) + recordRenderedAgeInDays(daysSinceCommit); + return elt; + } + return prepareForDomAttachment; + } + renderNonZeroCommit(commit2) { + const optionalShortHash = this.settings.showCommitHash ? this.renderHash(commit2) : ""; + const optionalAuthorName = this.settings.authorDisplay === "hide" ? "" : `${this.renderAuthorName( + commit2, + this.settings.authorDisplay + )}`; + const optionalAuthoringDate = this.settings.dateTimeFormatOptions === "hide" ? "" : `${this.renderAuthoringDate( + commit2, + this.settings.dateTimeFormatOptions, + this.settings.dateTimeFormatCustomString, + this.settings.dateTimeTimezone + )}`; + const parts = [ + optionalShortHash, + optionalAuthorName, + optionalAuthoringDate + ]; + return parts.filter((x) => x.length >= 1).join(" "); + } + renderHash(nonZeroCommit) { + return nonZeroCommit.hash.substring(0, 6); + } + renderAuthorName(nonZeroCommit, authorDisplay) { + var _a2, _b, _c, _d; + const name = (_b = (_a2 = nonZeroCommit == null ? void 0 : nonZeroCommit.author) == null ? void 0 : _a2.name) != null ? _b : ""; + const words = name.split(" ").filter((word) => word.length >= 1); + let rendered; + switch (authorDisplay) { + case "initials": + rendered = words.map((word) => word[0].toUpperCase()).join(""); + break; + case "first name": + rendered = (_c = words.first()) != null ? _c : VALUE_NOT_FOUND_FALLBACK; + break; + case "last name": + rendered = (_d = words.last()) != null ? _d : VALUE_NOT_FOUND_FALLBACK; + break; + case "full": + rendered = name; + break; + default: + return impossibleBranch(authorDisplay); + } + if (!strictDeepEqual(nonZeroCommit == null ? void 0 : nonZeroCommit.author, nonZeroCommit == null ? void 0 : nonZeroCommit.committer)) { + rendered = rendered + DIFFERING_AUTHOR_COMMITTER_MARKER; + } + return rendered; + } + renderAuthoringDate(nonZeroCommit, dateTimeFormatOptions, dateTimeFormatCustomString, dateTimeTimezone) { + var _a2; + const FALLBACK_COMMIT_DATE = "?"; + if (((_a2 = nonZeroCommit == null ? void 0 : nonZeroCommit.author) == null ? void 0 : _a2.epochSeconds) === void 0) + return FALLBACK_COMMIT_DATE; + let dateTimeFormatting; + switch (dateTimeFormatOptions) { + case "date": + dateTimeFormatting = DATE_FORMAT; + break; + case "datetime": + dateTimeFormatting = DATE_TIME_FORMAT_MINUTES; + break; + case "custom": + dateTimeFormatting = dateTimeFormatCustomString; + break; + case "natural language": + dateTimeFormatting = (time) => { + const diff2 = time.diff((0, import_obsidian10.moment)()); + const addFluentSuffix = true; + return import_obsidian10.moment.duration(diff2).humanize(addFluentSuffix); + }; + break; + default: + return impossibleBranch(dateTimeFormatOptions); + } + let authoringDate = import_obsidian10.moment.unix( + nonZeroCommit.author.epochSeconds + ); + switch (dateTimeTimezone) { + case "viewer-local": + break; + case "author-local": + authoringDate = authoringDate.utcOffset( + nonZeroCommit.author.tz + ); + dateTimeFormatting += " Z"; + break; + case "utc0000": + authoringDate = authoringDate.utc(); + dateTimeFormatting += "[Z]"; + break; + default: + return impossibleBranch(dateTimeTimezone); + } + if (typeof dateTimeFormatting === "string") { + return authoringDate.format(dateTimeFormatting); + } else { + return dateTimeFormatting(authoringDate); + } + } + adaptTextForFakeCommit(commit2, toBeRenderedText, options) { + var _a2, _b, _c, _d; + const original = (_b = (_a2 = getLongestRenderedGutter()) == null ? void 0 : _a2.text) != null ? _b : toBeRenderedText; + const fillCharacter = options !== "waiting-for-result" && commit2.isZeroCommit ? NEW_CHANGE_CHARACTER : UNINTRUSIVE_CHARACTER_FOR_WAITING_RENDERING; + toBeRenderedText = original.replace( + NON_WHITESPACE_REGEXP, + fillCharacter + ); + const desiredTextLength = (_d = (_c = latestSettings.get()) == null ? void 0 : _c.gutterSpacingFallbackLength) != null ? _d : toBeRenderedText.length; + toBeRenderedText = resizeToLength( + toBeRenderedText, + desiredTextLength, + fillCharacter + ); + if (options !== "waiting-for-result" && commit2.isZeroCommit) { + const numberOfLastCharactersToKeep = Math.min( + desiredTextLength, + NEW_CHANGE_NUMBER_OF_CHARACTERS + ); + toBeRenderedText = prefixOfLengthAsWhitespace( + toBeRenderedText, + desiredTextLength - numberOfLastCharactersToKeep + ); + } + return toBeRenderedText; + } +}; +function lineAuthoringGutterMarker(la, startLine, endLine, key2, settings, options) { + const digest = import_js_sha2562.sha256.create(); + digest.update(Object.values(settings).join(",")); + digest.update(`s${startLine}-e${endLine}-k${key2}-o${options}`); + const cacheKey = digest.hex(); + const cached = gutterInstances.get(cacheKey); + if (cached) + return cached; + const result = new LineAuthoringGutter( + la, + startLine, + endLine, + key2, + settings, + options + ); + gutterInstances.set(cacheKey, result); + return result; +} + +// src/lineAuthor/view/gutter/initial.ts +init_polyfill_buffer(); +var import_obsidian11 = require("obsidian"); +function initialSpacingGutter() { + var _a2, _b; + const length = (_b = (_a2 = latestSettings.get()) == null ? void 0 : _a2.gutterSpacingFallbackLength) != null ? _b : DEFAULT_SETTINGS.lineAuthor.gutterSpacingFallbackLength; + return new TextGutter(Array(length).fill("-").join("")); +} +function initialLineAuthoringGutter(settings) { + const { lineAuthoring, ageForInitialRender } = adaptiveInitialColoredWaitingLineAuthoring(settings); + return lineAuthoringGutterMarker( + lineAuthoring, + 1, + 1, + "initialGutter" + ageForInitialRender, + // use a age coloring based cache key + settings, + "waiting-for-result" + ); +} +function adaptiveInitialColoredWaitingLineAuthoring(settings) { + var _a2; + const ageForInitialRender = (_a2 = computeAdaptiveInitialColoringAgeInDays()) != null ? _a2 : maxAgeInDaysFromSettings(settings) * 0.25; + const slightlyOlderAgeForInitialRender = (0, import_obsidian11.moment)().add( + -ageForInitialRender, + "days" + ); + const dummyAuthor = { + name: "", + epochSeconds: momentToEpochSeconds(slightlyOlderAgeForInitialRender), + tz: "+0000" + }; + const dummyCommit = { + hash: "waiting-for-result", + author: dummyAuthor, + committer: dummyAuthor, + isZeroCommit: false + }; + return { + lineAuthoring: { + hashPerLine: [void 0, "waiting-for-result"], + commits: /* @__PURE__ */ new Map([["waiting-for-result", dummyCommit]]) + }, + ageForInitialRender + }; +} + +// src/lineAuthor/view/gutter/untrackedFile.ts +init_polyfill_buffer(); +function newUntrackedFileGutter(key2, settings) { + const dummyLineAuthoring = { + hashPerLine: [void 0, "000000"], + commits: /* @__PURE__ */ new Map([["000000", zeroCommit]]) + }; + return lineAuthoringGutterMarker(dummyLineAuthoring, 1, 1, key2, settings); +} + +// src/lineAuthor/view/view.ts +var UNDISPLAYED = new TextGutter(""); +var lineAuthorGutter = (0, import_view2.gutter)({ + class: "line-author-gutter-container", + markers(view) { + const lineAuthoring = view.state.field(lineAuthorState, false); + return lineAuthoringGutterMarkersRangeSet(view, lineAuthoring); + }, + lineMarkerChange(update2) { + const newLineAuthoringId = laStateDigest( + update2.state.field(lineAuthorState) + ); + const oldLineAuthoringId = laStateDigest( + update2.startState.field(lineAuthorState) + ); + return oldLineAuthoringId !== newLineAuthoringId; + }, + renderEmptyElements: true, + initialSpacer: (view) => { + temporaryWorkaroundGutterSpacingForRenderedLineAuthoring(view); + return initialSpacingGutter(); + }, + updateSpacer: (_sp, update2) => { + var _a2, _b; + temporaryWorkaroundGutterSpacingForRenderedLineAuthoring(update2.view); + return (_b = (_a2 = getLongestRenderedGutter()) == null ? void 0 : _a2.gutter) != null ? _b : initialSpacingGutter(); + } +}); +function lineAuthoringGutterMarkersRangeSet(view, optLA) { + const digest = laStateDigest(optLA); + const doc = view.state.doc; + const lineBlockEndPos = /* @__PURE__ */ new Map(); + for (let line = 1; line <= doc.lines; line++) { + const from = doc.line(line).from; + const to = view.lineBlockAt(from).to; + lineBlockEndPos.set(line, [from, to]); + digest.update([from, to, 0]); + } + const laSettings = latestSettings.get(); + digest.update("s" + Object.values(latestSettings).join(",")); + const cacheKey = digest.hex(); + const cached = gutterMarkersRangeSet.get(cacheKey); + if (cached) + return cached; + const { result, allowCache } = computeLineAuthoringGutterMarkersRangeSet( + doc, + lineBlockEndPos, + laSettings, + optLA + ); + if (allowCache) + gutterMarkersRangeSet.set(cacheKey, result); + return result; +} +function computeLineAuthoringGutterMarkersRangeSet(doc, blocksPerLine, settings, optLA) { + let allowCache = true; + const docLastLine = doc.lines; + const ranges = []; + function add2(from, to, gutter2) { + return ranges.push(gutter2.range(from, to)); + } + const lineFrom = computeLineMappingForUnsavedChanges(docLastLine, optLA); + const emptyDoc = doc.length === 0; + const lastLineIsEmpty = doc.iterLines(docLastLine, docLastLine + 1).next().value === ""; + for (let startLine = 1; startLine <= docLastLine; startLine++) { + const [from, to] = blocksPerLine.get(startLine); + const endLine = doc.lineAt(to).number; + if (emptyDoc) { + add2(from, to, UNDISPLAYED); + continue; + } + if (startLine === docLastLine && lastLineIsEmpty) { + add2(from, to, UNDISPLAYED); + continue; + } + if (optLA === void 0) { + add2(from, to, initialLineAuthoringGutter(settings)); + allowCache = false; + continue; + } + const { key: key2, la } = optLA; + if (la === "untracked") { + add2(from, to, newUntrackedFileGutter(la, settings)); + continue; + } + const lastAuthorLine = la.hashPerLine.length - 1; + const laStartLine = lineFrom[startLine]; + const laEndLine = lineFrom[endLine]; + if (laEndLine && laEndLine > lastAuthorLine) { + add2(from, to, UNDISPLAYED); + } + if (laStartLine !== void 0 && between(1, laStartLine, lastAuthorLine) && laEndLine !== void 0 && between(1, laEndLine, lastAuthorLine)) { + add2( + from, + to, + lineAuthoringGutterMarker( + la, + laStartLine, + laEndLine, + key2, + settings + ) + ); + continue; + } + if (lastAuthorLine < 1) { + add2(from, to, initialLineAuthoringGutter(settings)); + allowCache = false; + continue; + } + const start = Math.clamp(laStartLine != null ? laStartLine : startLine, 1, lastAuthorLine); + const end = Math.clamp(laEndLine != null ? laEndLine : endLine, 1, lastAuthorLine); + add2( + from, + to, + lineAuthoringGutterMarker( + la, + start, + end, + key2 + "computing", + settings, + "waiting-for-result" + ) + ); + } + return { result: import_state3.RangeSet.of( + ranges, + /* sort = */ + true + ), allowCache }; +} +function computeLineMappingForUnsavedChanges(docLastLine, optLA) { + if (!(optLA == null ? void 0 : optLA.lineOffsetsFromUnsavedChanges)) { + return Array.from(new Array(docLastLine + 1), (ln) => ln); + } + const lineFrom = [void 0]; + let cumulativeLineOffset = 0; + for (let ln = 1; ln <= docLastLine; ln++) { + const unsavedChanges = optLA.lineOffsetsFromUnsavedChanges.get(ln); + cumulativeLineOffset += unsavedChanges != null ? unsavedChanges : 0; + lineFrom[ln] = unsavedChanges === void 0 ? ln - cumulativeLineOffset : void 0; + } + return lineFrom; +} +function temporaryWorkaroundGutterSpacingForRenderedLineAuthoring(view) { + const guttersContainers = view.dom.querySelectorAll( + ".cm-gutters" + ); + guttersContainers.forEach((cont) => { + if (!(cont == null ? void 0 : cont.style)) + return; + if (!cont.style.marginLeft) { + cont.style.marginLeft = "unset"; + } + }); +} + +// src/lineAuthor/lineAuthorProvider.ts +var LineAuthorProvider = class { + constructor(plugin) { + this.plugin = plugin; + /** + * Saves all computed line authoring results. + * + * See {@link LineAuthoringId} + */ + this.lineAuthorings = /* @__PURE__ */ new Map(); + } + async trackChanged(file) { + this.trackChangedHelper(file).catch((reason) => { + console.warn("Obsidian Git: Error in trackChanged." + reason); + return Promise.reject(reason); + }); + } + async trackChangedHelper(file) { + if (!file) + return; + if (file.path === void 0) { + console.warn( + "Obsidian Git: Attempted to track change of undefined filepath. Unforeseen situation." + ); + return; + } + this.computeLineAuthorInfo(file.path); + } + destroy() { + this.lineAuthorings.clear(); + eventsPerFilePathSingleton.clear(); + clearViewCache(); + } + async computeLineAuthorInfo(filepath) { + const gitManager = this.plugin.lineAuthoringFeature.isAvailableOnCurrentPlatform().gitManager; + const headRevision = await gitManager.submoduleAwareHeadRevisonInContainingDirectory( + filepath + ); + const fileHash = await gitManager.hashObject(filepath); + const key2 = lineAuthoringId(headRevision, fileHash, filepath); + if (key2 === void 0) { + return; + } + if (this.lineAuthorings.has(key2)) { + } else { + const gitAuthorResult = await gitManager.blame( + filepath, + this.plugin.settings.lineAuthor.followMovement, + this.plugin.settings.lineAuthor.ignoreWhitespace + ); + this.lineAuthorings.set(key2, gitAuthorResult); + } + this.notifyComputationResultToSubscribers(filepath, key2); + } + notifyComputationResultToSubscribers(filepath, key2) { + eventsPerFilePathSingleton.ifFilepathDefinedTransformSubscribers( + filepath, + async (subs) => subs.forEach( + (sub) => sub.notifyLineAuthoring(key2, this.lineAuthorings.get(key2)) + ) + ); + } +}; +var enabledLineAuthorInfoExtensions = import_state4.Prec.high([ + subscribeNewEditor, + lineAuthorState, + lineAuthorGutter +]); + +// src/lineAuthor/lineAuthorIntegration.ts +var LineAuthoringFeature = class { + constructor(plg) { + this.plg = plg; + this.codeMirrorExtensions = []; + this.handleWorkspaceLeaf = (leaf) => { + const obsView = leaf == null ? void 0 : leaf.view; + const file = obsView == null ? void 0 : obsView.file; + if (!this.lineAuthorInfoProvider) { + console.warn( + "Obsidian Git: undefined lineAuthorInfoProvider. Unexpected situation." + ); + return; + } + if (file === void 0 || (obsView == null ? void 0 : obsView.allowNoFile) === true) + return; + this.lineAuthorInfoProvider.trackChanged(file); + }; + } + // ========================= INIT and DE-INIT ========================== + onLoadPlugin() { + this.plg.registerEditorExtension(this.codeMirrorExtensions); + provideSettingsAccess( + () => this.plg.settings.lineAuthor, + (laSettings) => { + this.plg.settings.lineAuthor = laSettings; + this.plg.saveSettings(); + } + ); + } + conditionallyActivateBySettings() { + if (this.plg.settings.lineAuthor.show) { + this.activateFeature(); + } + } + activateFeature() { + try { + if (!this.isAvailableOnCurrentPlatform()) + return; + setTextColorCssBasedOnSetting(this.plg.settings.lineAuthor); + this.lineAuthorInfoProvider = new LineAuthorProvider(this.plg); + this.createEventHandlers(); + this.activateCodeMirrorExtensions(); + console.log(this.plg.manifest.name + ": Enabled line authoring."); + } catch (e) { + console.warn( + "Obsidian Git: Error while loading line authoring feature.", + e + ); + this.deactivateFeature(); + } + } + /** + * Deactivates the feature. This function is very defensive, as it is also + * called to cleanup, if a critical error in the line authoring has occurred. + */ + deactivateFeature() { + var _a2; + this.destroyEventHandlers(); + this.deactivateCodeMirrorExtensions(); + (_a2 = this.lineAuthorInfoProvider) == null ? void 0 : _a2.destroy(); + this.lineAuthorInfoProvider = void 0; + console.log(this.plg.manifest.name + ": Disabled line authoring."); + } + isAvailableOnCurrentPlatform() { + return { + available: this.plg.useSimpleGit && import_obsidian12.Platform.isDesktopApp, + gitManager: this.plg.gitManager instanceof SimpleGit ? this.plg.gitManager : void 0 + }; + } + // ========================= REFRESH ========================== + refreshLineAuthorViews() { + if (this.plg.settings.lineAuthor.show) { + this.deactivateFeature(); + this.activateFeature(); + } + } + // ========================= CODEMIRROR EXTENSIONS ========================== + activateCodeMirrorExtensions() { + this.codeMirrorExtensions.push(enabledLineAuthorInfoExtensions); + this.plg.app.workspace.updateOptions(); + this.plg.app.workspace.iterateAllLeaves(this.handleWorkspaceLeaf); + } + deactivateCodeMirrorExtensions() { + for (const ext of this.codeMirrorExtensions) { + this.codeMirrorExtensions.remove(ext); + } + this.plg.app.workspace.updateOptions(); + } + // ========================= HANDLERS ========================== + createEventHandlers() { + this.gutterContextMenuEvent = this.createGutterContextMenuHandler(); + this.fileOpenEvent = this.createFileOpenEvent(); + this.workspaceLeafChangeEvent = this.createWorkspaceLeafChangeEvent(); + this.fileModificationEvent = this.createVaultFileModificationHandler(); + this.refreshOnCssChangeEvent = this.createCssRefreshHandler(); + this.fileRenameEvent = this.createFileRenameEvent(); + prepareGutterSearchForContextMenuHandling(); + this.plg.registerEvent(this.gutterContextMenuEvent); + this.plg.registerEvent(this.refreshOnCssChangeEvent); + this.plg.registerEvent(this.fileOpenEvent); + this.plg.registerEvent(this.workspaceLeafChangeEvent); + this.plg.registerEvent(this.fileModificationEvent); + this.plg.registerEvent(this.fileRenameEvent); + } + destroyEventHandlers() { + this.plg.app.workspace.offref(this.refreshOnCssChangeEvent); + this.plg.app.workspace.offref(this.fileOpenEvent); + this.plg.app.workspace.offref(this.workspaceLeafChangeEvent); + this.plg.app.workspace.offref(this.refreshOnCssChangeEvent); + this.plg.app.vault.offref(this.fileRenameEvent); + this.plg.app.workspace.offref(this.gutterContextMenuEvent); + } + createFileOpenEvent() { + return this.plg.app.workspace.on( + "file-open", + (file) => { + var _a2; + return (_a2 = this.lineAuthorInfoProvider) == null ? void 0 : _a2.trackChanged(file); + } + ); + } + createWorkspaceLeafChangeEvent() { + return this.plg.app.workspace.on( + "active-leaf-change", + this.handleWorkspaceLeaf + ); + } + createFileRenameEvent() { + return this.plg.app.vault.on( + "rename", + (file, _old) => { + var _a2; + return file instanceof import_obsidian12.TFile && ((_a2 = this.lineAuthorInfoProvider) == null ? void 0 : _a2.trackChanged(file)); + } + ); + } + createVaultFileModificationHandler() { + return this.plg.app.vault.on( + "modify", + (anyPath) => { + var _a2; + return anyPath instanceof import_obsidian12.TFile && ((_a2 = this.lineAuthorInfoProvider) == null ? void 0 : _a2.trackChanged(anyPath)); + } + ); + } + createCssRefreshHandler() { + return this.plg.app.workspace.on( + "css-change", + () => this.refreshLineAuthorViews() + ); + } + createGutterContextMenuHandler() { + return this.plg.app.workspace.on("editor-menu", handleContextMenu); + } +}; + +// src/promiseQueue.ts +init_polyfill_buffer(); +var PromiseQueue = class { + constructor() { + this.tasks = []; + } + addTask(task) { + this.tasks.push(task); + if (this.tasks.length === 1) { + this.handleTask(); + } + } + async handleTask() { + if (this.tasks.length > 0) { + this.tasks[0]().finally(() => { + this.tasks.shift(); + this.handleTask(); + }); + } + } +}; + +// src/statusBar.ts +init_polyfill_buffer(); +var import_obsidian13 = require("obsidian"); +var StatusBar = class { + constructor(statusBarEl, plugin) { + this.statusBarEl = statusBarEl; + this.plugin = plugin; + this.messages = []; + this.base = "obsidian-git-statusbar-"; + this.statusBarEl.setAttribute("aria-label-position", "top"); + addEventListener("git-refresh", this.refreshCommitTimestamp.bind(this)); + } + displayMessage(message, timeout) { + this.messages.push({ + message: `Git: ${message.slice(0, 100)}`, + timeout + }); + this.display(); + } + display() { + if (this.messages.length > 0 && !this.currentMessage) { + this.currentMessage = this.messages.shift(); + this.statusBarEl.addClass(this.base + "message"); + this.statusBarEl.ariaLabel = ""; + this.statusBarEl.setText(this.currentMessage.message); + this.lastMessageTimestamp = Date.now(); + } else if (this.currentMessage) { + const messageAge = Date.now() - this.lastMessageTimestamp; + if (messageAge >= this.currentMessage.timeout) { + this.currentMessage = null; + this.lastMessageTimestamp = null; + } + } else { + this.displayState(); + } + } + displayState() { + if (this.statusBarEl.getText().length > 3 || !this.statusBarEl.hasChildNodes()) { + this.statusBarEl.empty(); + this.iconEl = this.statusBarEl.createDiv(); + this.textEl = this.statusBarEl.createDiv(); + this.textEl.style.float = "right"; + this.textEl.style.marginLeft = "5px"; + this.iconEl.style.float = "left"; + } + switch (this.plugin.state) { + case 0 /* idle */: + this.displayFromNow(); + break; + case 1 /* status */: + this.statusBarEl.ariaLabel = "Checking repository status..."; + (0, import_obsidian13.setIcon)(this.iconEl, "refresh-cw"); + this.statusBarEl.addClass(this.base + "status"); + break; + case 3 /* add */: + this.statusBarEl.ariaLabel = "Adding files..."; + (0, import_obsidian13.setIcon)(this.iconEl, "refresh-w"); + this.statusBarEl.addClass(this.base + "add"); + break; + case 4 /* commit */: + this.statusBarEl.ariaLabel = "Committing changes..."; + (0, import_obsidian13.setIcon)(this.iconEl, "git-commit"); + this.statusBarEl.addClass(this.base + "commit"); + break; + case 5 /* push */: + this.statusBarEl.ariaLabel = "Pushing changes..."; + (0, import_obsidian13.setIcon)(this.iconEl, "upload"); + this.statusBarEl.addClass(this.base + "push"); + break; + case 2 /* pull */: + this.statusBarEl.ariaLabel = "Pulling changes..."; + (0, import_obsidian13.setIcon)(this.iconEl, "download"); + this.statusBarEl.addClass(this.base + "pull"); + break; + case 6 /* conflicted */: + this.statusBarEl.ariaLabel = "You have conflict files..."; + (0, import_obsidian13.setIcon)(this.iconEl, "alert-circle"); + this.statusBarEl.addClass(this.base + "conflict"); + break; + default: + this.statusBarEl.ariaLabel = "Failed on initialization!"; + (0, import_obsidian13.setIcon)(this.iconEl, "alert-triangle"); + this.statusBarEl.addClass(this.base + "failed-init"); + break; + } + } + displayFromNow() { + var _a2; + const timestamp = this.lastCommitTimestamp; + if (timestamp) { + const moment5 = window.moment; + const fromNow = moment5(timestamp).fromNow(); + this.statusBarEl.ariaLabel = `${this.plugin.offlineMode ? "Offline: " : ""}Last Commit: ${fromNow}`; + if ((_a2 = this.unPushedCommits) != null ? _a2 : 0 > 0) { + this.statusBarEl.ariaLabel += ` +(${this.unPushedCommits} unpushed commits)`; + } + } else { + this.statusBarEl.ariaLabel = this.plugin.offlineMode ? "Git is offline" : "Git is ready"; + } + if (this.plugin.offlineMode) { + (0, import_obsidian13.setIcon)(this.iconEl, "globe"); + } else { + (0, import_obsidian13.setIcon)(this.iconEl, "check"); + } + if (this.plugin.settings.changedFilesInStatusBar && this.plugin.cachedStatus) { + this.textEl.setText( + this.plugin.cachedStatus.changed.length.toString() + ); + } + this.statusBarEl.addClass(this.base + "idle"); + } + async refreshCommitTimestamp() { + this.lastCommitTimestamp = await this.plugin.gitManager.getLastCommitTime(); + this.unPushedCommits = await this.plugin.gitManager.getUnpushedCommits(); + } +}; + +// src/ui/modals/changedFilesModal.ts +init_polyfill_buffer(); +var import_obsidian14 = require("obsidian"); +var ChangedFilesModal = class extends import_obsidian14.FuzzySuggestModal { + constructor(plugin, changedFiles) { + super(plugin.app); + this.plugin = plugin; + this.changedFiles = changedFiles; + this.setPlaceholder( + "Not supported files will be opened by default app!" + ); + } + getItems() { + return this.changedFiles; + } + getItemText(item) { + if (item.index == "U" && item.working_dir == "U") { + return `Untracked | ${item.vault_path}`; + } + let working_dir = ""; + let index2 = ""; + if (item.working_dir != " ") + working_dir = `Working dir: ${item.working_dir} `; + if (item.index != " ") + index2 = `Index: ${item.index}`; + return `${working_dir}${index2} | ${item.vault_path}`; + } + onChooseItem(item, _) { + if (this.plugin.app.metadataCache.getFirstLinkpathDest( + item.vault_path, + "" + ) == null) { + this.app.openWithDefaultApp(item.vault_path); + } else { + this.plugin.app.workspace.openLinkText(item.vault_path, "/"); + } + } +}; + +// src/ui/modals/customMessageModal.ts +init_polyfill_buffer(); +var import_obsidian15 = require("obsidian"); +var CustomMessageModal = class extends import_obsidian15.SuggestModal { + constructor(plugin, fromAutoBackup) { + super(plugin.app); + this.fromAutoBackup = fromAutoBackup; + this.resolve = null; + this.plugin = plugin; + this.setPlaceholder( + "Type your message and select optional the version with the added date." + ); + } + open() { + super.open(); + return new Promise((resolve) => { + this.resolve = resolve; + }); + } + onClose() { + if (this.resolve) + this.resolve(void 0); + } + selectSuggestion(value, evt) { + if (this.resolve) + this.resolve(value); + super.selectSuggestion(value, evt); + } + getSuggestions(query) { + const date = window.moment().format(this.plugin.settings.commitDateFormat); + if (query == "") + query = "..."; + return [query, `${date}: ${query}`, `${query}: ${date}`]; + } + renderSuggestion(value, el) { + el.innerText = value; + } + onChooseSuggestion(item, _) { + } +}; + +// src/openInGitHub.ts +init_polyfill_buffer(); +var import_obsidian16 = require("obsidian"); +async function openLineInGitHub(editor, file, manager) { + const data = await getData(manager); + if (data.result === "failure") { + new import_obsidian16.Notice(data.reason); + return; + } + const { isGitHub, branch: branch2, repo, user } = data; + if (isGitHub) { + const path2 = manager.asRepositoryRelativePath(file.path, true); + const from = editor.getCursor("from").line + 1; + const to = editor.getCursor("to").line + 1; + if (from === to) { + window.open( + `https://github.com/${user}/${repo}/blob/${branch2}/${path2}?plain=1#L${from}` + ); + } else { + window.open( + `https://github.com/${user}/${repo}/blob/${branch2}/${path2}?plain=1#L${from}-L${to}` + ); + } + } else { + new import_obsidian16.Notice("It seems like you are not using GitHub"); + } +} +async function openHistoryInGitHub(file, manager) { + const data = await getData(manager); + if (data.result === "failure") { + new import_obsidian16.Notice(data.reason); + return; + } + const { isGitHub, branch: branch2, repo, user } = data; + const path2 = manager.asRepositoryRelativePath(file.path, true); + if (isGitHub) { + window.open( + `https://github.com/${user}/${repo}/commits/${branch2}/${path2}` + ); + } else { + new import_obsidian16.Notice("It seems like you are not using GitHub"); + } +} +async function getData(manager) { + const branchInfo = await manager.branchInfo(); + const remoteBranch = branchInfo.tracking; + const branch2 = branchInfo.current; + if (remoteBranch == null) { + return { + result: "failure", + reason: "Remote branch is not configured" + }; + } + if (branch2 == null) { + return { + result: "failure", + reason: "Failed to get current branch name" + }; + } + const remote = remoteBranch.substring(0, remoteBranch.indexOf("/")); + const remoteUrl = await manager.getConfig( + `remote.${remote}.url` + ); + const [isGitHub, httpsUser, httpsRepo, sshUser, sshRepo] = remoteUrl.match( + /(?:^https:\/\/github\.com\/(.*)\/(.*)\.git$)|(?:^git@github\.com:(.*)\/(.*)\.git$)/ + ); + return { + result: "success", + isGitHub: !!isGitHub, + repo: httpsRepo || sshRepo, + user: httpsUser || sshUser, + branch: branch2 + }; +} + +// src/setting/localStorageSettings.ts +init_polyfill_buffer(); +var LocalStorageSettings = class { + constructor(plugin) { + this.plugin = plugin; + this.prefix = this.plugin.manifest.id + ":"; + } + migrate() { + const keys = [ + "password", + "hostname", + "conflict", + "lastAutoPull", + "lastAutoBackup", + "lastAutoPush", + "gitPath", + "pluginDisabled" + ]; + for (const key2 of keys) { + const old = localStorage.getItem(this.prefix + key2); + if (app.loadLocalStorage(this.prefix + key2) == null && old != null) { + if (old != null) { + app.saveLocalStorage(this.prefix + key2, old); + localStorage.removeItem(this.prefix + key2); + } + } + } + } + getPassword() { + return app.loadLocalStorage(this.prefix + "password"); + } + setPassword(value) { + return app.saveLocalStorage(this.prefix + "password", value); + } + getUsername() { + return app.loadLocalStorage(this.prefix + "username"); + } + setUsername(value) { + return app.saveLocalStorage(this.prefix + "username", value); + } + getHostname() { + return app.loadLocalStorage(this.prefix + "hostname"); + } + setHostname(value) { + return app.saveLocalStorage(this.prefix + "hostname", value); + } + getConflict() { + return app.loadLocalStorage(this.prefix + "conflict"); + } + setConflict(value) { + return app.saveLocalStorage(this.prefix + "conflict", value); + } + getLastAutoPull() { + return app.loadLocalStorage(this.prefix + "lastAutoPull"); + } + setLastAutoPull(value) { + return app.saveLocalStorage(this.prefix + "lastAutoPull", value); + } + getLastAutoBackup() { + return app.loadLocalStorage(this.prefix + "lastAutoBackup"); + } + setLastAutoBackup(value) { + return app.saveLocalStorage(this.prefix + "lastAutoBackup", value); + } + getLastAutoPush() { + return app.loadLocalStorage(this.prefix + "lastAutoPush"); + } + setLastAutoPush(value) { + return app.saveLocalStorage(this.prefix + "lastAutoPush", value); + } + getGitPath() { + return app.loadLocalStorage(this.prefix + "gitPath"); + } + setGitPath(value) { + return app.saveLocalStorage(this.prefix + "gitPath", value); + } + getPATHPaths() { + var _a2, _b; + return (_b = (_a2 = app.loadLocalStorage(this.prefix + "PATHPaths")) == null ? void 0 : _a2.split(":")) != null ? _b : []; + } + setPATHPaths(value) { + return app.saveLocalStorage(this.prefix + "PATHPaths", value.join(":")); + } + getEnvVars() { + var _a2; + return JSON.parse( + (_a2 = app.loadLocalStorage(this.prefix + "envVars")) != null ? _a2 : "[]" + ); + } + setEnvVars(value) { + return app.saveLocalStorage( + this.prefix + "envVars", + JSON.stringify(value) + ); + } + getPluginDisabled() { + return app.loadLocalStorage(this.prefix + "pluginDisabled") == "true"; + } + setPluginDisabled(value) { + return app.saveLocalStorage(this.prefix + "pluginDisabled", `${value}`); + } +}; + +// src/ui/diff/diffView.ts +init_polyfill_buffer(); + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/diff2html.js +init_polyfill_buffer(); + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/diff-parser.js +init_polyfill_buffer(); + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/types.js +init_polyfill_buffer(); +var LineType; +(function(LineType2) { + LineType2["INSERT"] = "insert"; + LineType2["DELETE"] = "delete"; + LineType2["CONTEXT"] = "context"; +})(LineType || (LineType = {})); +var OutputFormatType = { + LINE_BY_LINE: "line-by-line", + SIDE_BY_SIDE: "side-by-side" +}; +var LineMatchingType = { + LINES: "lines", + WORDS: "words", + NONE: "none" +}; +var DiffStyleType = { + WORD: "word", + CHAR: "char" +}; + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/utils.js +init_polyfill_buffer(); +var specials = [ + "-", + "[", + "]", + "/", + "{", + "}", + "(", + ")", + "*", + "+", + "?", + ".", + "\\", + "^", + "$", + "|" +]; +var regex = RegExp("[" + specials.join("\\") + "]", "g"); +function escapeForRegExp(str) { + return str.replace(regex, "\\$&"); +} +function unifyPath(path2) { + return path2 ? path2.replace(/\\/g, "/") : path2; +} +function hashCode(text2) { + var i, chr, len; + var hash2 = 0; + for (i = 0, len = text2.length; i < len; i++) { + chr = text2.charCodeAt(i); + hash2 = (hash2 << 5) - hash2 + chr; + hash2 |= 0; + } + return hash2; +} + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/diff-parser.js +var __spreadArray = function(to, from, pack) { + if (pack || arguments.length === 2) + for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) + ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +function getExtension(filename, language) { + var filenameParts = filename.split("."); + return filenameParts.length > 1 ? filenameParts[filenameParts.length - 1] : language; +} +function startsWithAny(str, prefixes) { + return prefixes.reduce(function(startsWith, prefix) { + return startsWith || str.startsWith(prefix); + }, false); +} +var baseDiffFilenamePrefixes = ["a/", "b/", "i/", "w/", "c/", "o/"]; +function getFilename(line, linePrefix, extraPrefix) { + var prefixes = extraPrefix !== void 0 ? __spreadArray(__spreadArray([], baseDiffFilenamePrefixes, true), [extraPrefix], false) : baseDiffFilenamePrefixes; + var FilenameRegExp = linePrefix ? new RegExp("^".concat(escapeForRegExp(linePrefix), ' "?(.+?)"?$')) : new RegExp('^"?(.+?)"?$'); + var _a2 = FilenameRegExp.exec(line) || [], _b = _a2[1], filename = _b === void 0 ? "" : _b; + var matchingPrefix = prefixes.find(function(p) { + return filename.indexOf(p) === 0; + }); + var fnameWithoutPrefix = matchingPrefix ? filename.slice(matchingPrefix.length) : filename; + return fnameWithoutPrefix.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [+-]\d{4}.*$/, ""); +} +function getSrcFilename(line, srcPrefix) { + return getFilename(line, "---", srcPrefix); +} +function getDstFilename(line, dstPrefix) { + return getFilename(line, "+++", dstPrefix); +} +function parse(diffInput, config) { + if (config === void 0) { + config = {}; + } + var files = []; + var currentFile = null; + var currentBlock = null; + var oldLine = null; + var oldLine2 = null; + var newLine = null; + var possibleOldName = null; + var possibleNewName = null; + var oldFileNameHeader = "--- "; + var newFileNameHeader = "+++ "; + var hunkHeaderPrefix = "@@"; + var oldMode = /^old mode (\d{6})/; + var newMode = /^new mode (\d{6})/; + var deletedFileMode = /^deleted file mode (\d{6})/; + var newFileMode = /^new file mode (\d{6})/; + var copyFrom = /^copy from "?(.+)"?/; + var copyTo = /^copy to "?(.+)"?/; + var renameFrom = /^rename from "?(.+)"?/; + var renameTo = /^rename to "?(.+)"?/; + var similarityIndex = /^similarity index (\d+)%/; + var dissimilarityIndex = /^dissimilarity index (\d+)%/; + var index2 = /^index ([\da-z]+)\.\.([\da-z]+)\s*(\d{6})?/; + var binaryFiles = /^Binary files (.*) and (.*) differ/; + var binaryDiff = /^GIT binary patch/; + var combinedIndex = /^index ([\da-z]+),([\da-z]+)\.\.([\da-z]+)/; + var combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/; + var combinedNewFile = /^new file mode (\d{6})/; + var combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/; + var diffLines2 = diffInput.replace(/\\ No newline at end of file/g, "").replace(/\r\n?/g, "\n").split("\n"); + function saveBlock() { + if (currentBlock !== null && currentFile !== null) { + currentFile.blocks.push(currentBlock); + currentBlock = null; + } + } + function saveFile() { + if (currentFile !== null) { + if (!currentFile.oldName && possibleOldName !== null) { + currentFile.oldName = possibleOldName; + } + if (!currentFile.newName && possibleNewName !== null) { + currentFile.newName = possibleNewName; + } + if (currentFile.newName) { + files.push(currentFile); + currentFile = null; + } + } + possibleOldName = null; + possibleNewName = null; + } + function startFile() { + saveBlock(); + saveFile(); + currentFile = { + blocks: [], + deletedLines: 0, + addedLines: 0 + }; + } + function startBlock(line) { + saveBlock(); + var values; + if (currentFile !== null) { + if (values = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@.*/.exec(line)) { + currentFile.isCombined = false; + oldLine = parseInt(values[1], 10); + newLine = parseInt(values[2], 10); + } else if (values = /^@@@ -(\d+)(?:,\d+)? -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@@.*/.exec(line)) { + currentFile.isCombined = true; + oldLine = parseInt(values[1], 10); + oldLine2 = parseInt(values[2], 10); + newLine = parseInt(values[3], 10); + } else { + if (line.startsWith(hunkHeaderPrefix)) { + console.error("Failed to parse lines, starting in 0!"); + } + oldLine = 0; + newLine = 0; + currentFile.isCombined = false; + } + } + currentBlock = { + lines: [], + oldStartLine: oldLine, + oldStartLine2: oldLine2, + newStartLine: newLine, + header: line + }; + } + function createLine(line) { + if (currentFile === null || currentBlock === null || oldLine === null || newLine === null) + return; + var currentLine = { + content: line + }; + var addedPrefixes = currentFile.isCombined ? ["+ ", " +", "++"] : ["+"]; + var deletedPrefixes = currentFile.isCombined ? ["- ", " -", "--"] : ["-"]; + if (startsWithAny(line, addedPrefixes)) { + currentFile.addedLines++; + currentLine.type = LineType.INSERT; + currentLine.oldNumber = void 0; + currentLine.newNumber = newLine++; + } else if (startsWithAny(line, deletedPrefixes)) { + currentFile.deletedLines++; + currentLine.type = LineType.DELETE; + currentLine.oldNumber = oldLine++; + currentLine.newNumber = void 0; + } else { + currentLine.type = LineType.CONTEXT; + currentLine.oldNumber = oldLine++; + currentLine.newNumber = newLine++; + } + currentBlock.lines.push(currentLine); + } + function existHunkHeader(line, lineIdx) { + var idx = lineIdx; + while (idx < diffLines2.length - 3) { + if (line.startsWith("diff")) { + return false; + } + if (diffLines2[idx].startsWith(oldFileNameHeader) && diffLines2[idx + 1].startsWith(newFileNameHeader) && diffLines2[idx + 2].startsWith(hunkHeaderPrefix)) { + return true; + } + idx++; + } + return false; + } + diffLines2.forEach(function(line, lineIndex) { + if (!line || line.startsWith("*")) { + return; + } + var values; + var prevLine = diffLines2[lineIndex - 1]; + var nxtLine = diffLines2[lineIndex + 1]; + var afterNxtLine = diffLines2[lineIndex + 2]; + if (line.startsWith("diff --git") || line.startsWith("diff --combined")) { + startFile(); + var gitDiffStart = /^diff --git "?([a-ciow]\/.+)"? "?([a-ciow]\/.+)"?/; + if (values = gitDiffStart.exec(line)) { + possibleOldName = getFilename(values[1], void 0, config.dstPrefix); + possibleNewName = getFilename(values[2], void 0, config.srcPrefix); + } + if (currentFile === null) { + throw new Error("Where is my file !!!"); + } + currentFile.isGitDiff = true; + return; + } + if (line.startsWith("Binary files") && !(currentFile === null || currentFile === void 0 ? void 0 : currentFile.isGitDiff)) { + startFile(); + var unixDiffBinaryStart = /^Binary files "?([a-ciow]\/.+)"? and "?([a-ciow]\/.+)"? differ/; + if (values = unixDiffBinaryStart.exec(line)) { + possibleOldName = getFilename(values[1], void 0, config.dstPrefix); + possibleNewName = getFilename(values[2], void 0, config.srcPrefix); + } + if (currentFile === null) { + throw new Error("Where is my file !!!"); + } + currentFile.isBinary = true; + return; + } + if (!currentFile || !currentFile.isGitDiff && currentFile && line.startsWith(oldFileNameHeader) && nxtLine.startsWith(newFileNameHeader) && afterNxtLine.startsWith(hunkHeaderPrefix)) { + startFile(); + } + if (currentFile === null || currentFile === void 0 ? void 0 : currentFile.isTooBig) { + return; + } + if (currentFile && (typeof config.diffMaxChanges === "number" && currentFile.addedLines + currentFile.deletedLines > config.diffMaxChanges || typeof config.diffMaxLineLength === "number" && line.length > config.diffMaxLineLength)) { + currentFile.isTooBig = true; + currentFile.addedLines = 0; + currentFile.deletedLines = 0; + currentFile.blocks = []; + currentBlock = null; + var message = typeof config.diffTooBigMessage === "function" ? config.diffTooBigMessage(files.length) : "Diff too big to be displayed"; + startBlock(message); + return; + } + if (line.startsWith(oldFileNameHeader) && nxtLine.startsWith(newFileNameHeader) || line.startsWith(newFileNameHeader) && prevLine.startsWith(oldFileNameHeader)) { + if (currentFile && !currentFile.oldName && line.startsWith("--- ") && (values = getSrcFilename(line, config.srcPrefix))) { + currentFile.oldName = values; + currentFile.language = getExtension(currentFile.oldName, currentFile.language); + return; + } + if (currentFile && !currentFile.newName && line.startsWith("+++ ") && (values = getDstFilename(line, config.dstPrefix))) { + currentFile.newName = values; + currentFile.language = getExtension(currentFile.newName, currentFile.language); + return; + } + } + if (currentFile && (line.startsWith(hunkHeaderPrefix) || currentFile.isGitDiff && currentFile.oldName && currentFile.newName && !currentBlock)) { + startBlock(line); + return; + } + if (currentBlock && (line.startsWith("+") || line.startsWith("-") || line.startsWith(" "))) { + createLine(line); + return; + } + var doesNotExistHunkHeader = !existHunkHeader(line, lineIndex); + if (currentFile === null) { + throw new Error("Where is my file !!!"); + } + if (values = oldMode.exec(line)) { + currentFile.oldMode = values[1]; + } else if (values = newMode.exec(line)) { + currentFile.newMode = values[1]; + } else if (values = deletedFileMode.exec(line)) { + currentFile.deletedFileMode = values[1]; + currentFile.isDeleted = true; + } else if (values = newFileMode.exec(line)) { + currentFile.newFileMode = values[1]; + currentFile.isNew = true; + } else if (values = copyFrom.exec(line)) { + if (doesNotExistHunkHeader) { + currentFile.oldName = values[1]; + } + currentFile.isCopy = true; + } else if (values = copyTo.exec(line)) { + if (doesNotExistHunkHeader) { + currentFile.newName = values[1]; + } + currentFile.isCopy = true; + } else if (values = renameFrom.exec(line)) { + if (doesNotExistHunkHeader) { + currentFile.oldName = values[1]; + } + currentFile.isRename = true; + } else if (values = renameTo.exec(line)) { + if (doesNotExistHunkHeader) { + currentFile.newName = values[1]; + } + currentFile.isRename = true; + } else if (values = binaryFiles.exec(line)) { + currentFile.isBinary = true; + currentFile.oldName = getFilename(values[1], void 0, config.srcPrefix); + currentFile.newName = getFilename(values[2], void 0, config.dstPrefix); + startBlock("Binary file"); + } else if (binaryDiff.test(line)) { + currentFile.isBinary = true; + startBlock(line); + } else if (values = similarityIndex.exec(line)) { + currentFile.unchangedPercentage = parseInt(values[1], 10); + } else if (values = dissimilarityIndex.exec(line)) { + currentFile.changedPercentage = parseInt(values[1], 10); + } else if (values = index2.exec(line)) { + currentFile.checksumBefore = values[1]; + currentFile.checksumAfter = values[2]; + values[3] && (currentFile.mode = values[3]); + } else if (values = combinedIndex.exec(line)) { + currentFile.checksumBefore = [values[2], values[3]]; + currentFile.checksumAfter = values[1]; + } else if (values = combinedMode.exec(line)) { + currentFile.oldMode = [values[2], values[3]]; + currentFile.newMode = values[1]; + } else if (values = combinedNewFile.exec(line)) { + currentFile.newFileMode = values[1]; + currentFile.isNew = true; + } else if (values = combinedDeletedFile.exec(line)) { + currentFile.deletedFileMode = values[1]; + currentFile.isDeleted = true; + } + }); + saveBlock(); + saveFile(); + return files; +} + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/file-list-renderer.js +init_polyfill_buffer(); + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/render-utils.js +init_polyfill_buffer(); + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/rematch.js +init_polyfill_buffer(); +function levenshtein(a, b) { + if (a.length === 0) { + return b.length; + } + if (b.length === 0) { + return a.length; + } + var matrix = []; + var i; + for (i = 0; i <= b.length; i++) { + matrix[i] = [i]; + } + var j; + for (j = 0; j <= a.length; j++) { + matrix[0][j] = j; + } + for (i = 1; i <= b.length; i++) { + for (j = 1; j <= a.length; j++) { + if (b.charAt(i - 1) === a.charAt(j - 1)) { + matrix[i][j] = matrix[i - 1][j - 1]; + } else { + matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, Math.min(matrix[i][j - 1] + 1, matrix[i - 1][j] + 1)); + } + } + } + return matrix[b.length][a.length]; +} +function newDistanceFn(str) { + return function(x, y) { + var xValue = str(x).trim(); + var yValue = str(y).trim(); + var lev = levenshtein(xValue, yValue); + return lev / (xValue.length + yValue.length); + }; +} +function newMatcherFn(distance2) { + function findBestMatch(a, b, cache) { + if (cache === void 0) { + cache = /* @__PURE__ */ new Map(); + } + var bestMatchDist = Infinity; + var bestMatch; + for (var i = 0; i < a.length; ++i) { + for (var j = 0; j < b.length; ++j) { + var cacheKey = JSON.stringify([a[i], b[j]]); + var md = void 0; + if (!(cache.has(cacheKey) && (md = cache.get(cacheKey)))) { + md = distance2(a[i], b[j]); + cache.set(cacheKey, md); + } + if (md < bestMatchDist) { + bestMatchDist = md; + bestMatch = { indexA: i, indexB: j, score: bestMatchDist }; + } + } + } + return bestMatch; + } + function group(a, b, level, cache) { + if (level === void 0) { + level = 0; + } + if (cache === void 0) { + cache = /* @__PURE__ */ new Map(); + } + var bm = findBestMatch(a, b, cache); + if (!bm || a.length + b.length < 3) { + return [[a, b]]; + } + var a1 = a.slice(0, bm.indexA); + var b1 = b.slice(0, bm.indexB); + var aMatch = [a[bm.indexA]]; + var bMatch = [b[bm.indexB]]; + var tailA = bm.indexA + 1; + var tailB = bm.indexB + 1; + var a2 = a.slice(tailA); + var b2 = b.slice(tailB); + var group1 = group(a1, b1, level + 1, cache); + var groupMatch = group(aMatch, bMatch, level + 1, cache); + var group2 = group(a2, b2, level + 1, cache); + var result = groupMatch; + if (bm.indexA > 0 || bm.indexB > 0) { + result = group1.concat(result); + } + if (a.length > tailA || b.length > tailB) { + result = result.concat(group2); + } + return result; + } + return group; +} + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/render-utils.js +var __assign = function() { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var CSSLineClass = { + INSERTS: "d2h-ins", + DELETES: "d2h-del", + CONTEXT: "d2h-cntx", + INFO: "d2h-info", + INSERT_CHANGES: "d2h-ins d2h-change", + DELETE_CHANGES: "d2h-del d2h-change" +}; +var defaultRenderConfig = { + matching: LineMatchingType.NONE, + matchWordsThreshold: 0.25, + maxLineLengthHighlight: 1e4, + diffStyle: DiffStyleType.WORD +}; +var separator = "/"; +var distance = newDistanceFn(function(change) { + return change.value; +}); +var matcher = newMatcherFn(distance); +function isDevNullName(name) { + return name.indexOf("dev/null") !== -1; +} +function removeInsElements(line) { + return line.replace(/(]*>((.|\n)*?)<\/ins>)/g, ""); +} +function removeDelElements(line) { + return line.replace(/(]*>((.|\n)*?)<\/del>)/g, ""); +} +function toCSSClass(lineType) { + switch (lineType) { + case LineType.CONTEXT: + return CSSLineClass.CONTEXT; + case LineType.INSERT: + return CSSLineClass.INSERTS; + case LineType.DELETE: + return CSSLineClass.DELETES; + } +} +function prefixLength(isCombined) { + return isCombined ? 2 : 1; +} +function escapeForHtml(str) { + return str.slice(0).replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/"); +} +function deconstructLine(line, isCombined, escape) { + if (escape === void 0) { + escape = true; + } + var indexToSplit = prefixLength(isCombined); + return { + prefix: line.substring(0, indexToSplit), + content: escape ? escapeForHtml(line.substring(indexToSplit)) : line.substring(indexToSplit) + }; +} +function filenameDiff(file) { + var oldFilename = unifyPath(file.oldName); + var newFilename = unifyPath(file.newName); + if (oldFilename !== newFilename && !isDevNullName(oldFilename) && !isDevNullName(newFilename)) { + var prefixPaths = []; + var suffixPaths = []; + var oldFilenameParts = oldFilename.split(separator); + var newFilenameParts = newFilename.split(separator); + var oldFilenamePartsSize = oldFilenameParts.length; + var newFilenamePartsSize = newFilenameParts.length; + var i = 0; + var j = oldFilenamePartsSize - 1; + var k = newFilenamePartsSize - 1; + while (i < j && i < k) { + if (oldFilenameParts[i] === newFilenameParts[i]) { + prefixPaths.push(newFilenameParts[i]); + i += 1; + } else { + break; + } + } + while (j > i && k > i) { + if (oldFilenameParts[j] === newFilenameParts[k]) { + suffixPaths.unshift(newFilenameParts[k]); + j -= 1; + k -= 1; + } else { + break; + } + } + var finalPrefix = prefixPaths.join(separator); + var finalSuffix = suffixPaths.join(separator); + var oldRemainingPath = oldFilenameParts.slice(i, j + 1).join(separator); + var newRemainingPath = newFilenameParts.slice(i, k + 1).join(separator); + if (finalPrefix.length && finalSuffix.length) { + return finalPrefix + separator + "{" + oldRemainingPath + " \u2192 " + newRemainingPath + "}" + separator + finalSuffix; + } else if (finalPrefix.length) { + return finalPrefix + separator + "{" + oldRemainingPath + " \u2192 " + newRemainingPath + "}"; + } else if (finalSuffix.length) { + return "{" + oldRemainingPath + " \u2192 " + newRemainingPath + "}" + separator + finalSuffix; + } + return oldFilename + " \u2192 " + newFilename; + } else if (!isDevNullName(newFilename)) { + return newFilename; + } else { + return oldFilename; + } +} +function getHtmlId(file) { + return "d2h-".concat(hashCode(filenameDiff(file)).toString().slice(-6)); +} +function getFileIcon(file) { + var templateName = "file-changed"; + if (file.isRename) { + templateName = "file-renamed"; + } else if (file.isCopy) { + templateName = "file-renamed"; + } else if (file.isNew) { + templateName = "file-added"; + } else if (file.isDeleted) { + templateName = "file-deleted"; + } else if (file.newName !== file.oldName) { + templateName = "file-renamed"; + } + return templateName; +} +function diffHighlight(diffLine1, diffLine2, isCombined, config) { + if (config === void 0) { + config = {}; + } + var _a2 = __assign(__assign({}, defaultRenderConfig), config), matching = _a2.matching, maxLineLengthHighlight = _a2.maxLineLengthHighlight, matchWordsThreshold = _a2.matchWordsThreshold, diffStyle = _a2.diffStyle; + var line1 = deconstructLine(diffLine1, isCombined, false); + var line2 = deconstructLine(diffLine2, isCombined, false); + if (line1.content.length > maxLineLengthHighlight || line2.content.length > maxLineLengthHighlight) { + return { + oldLine: { + prefix: line1.prefix, + content: escapeForHtml(line1.content) + }, + newLine: { + prefix: line2.prefix, + content: escapeForHtml(line2.content) + } + }; + } + var diff2 = diffStyle === "char" ? diffChars(line1.content, line2.content) : diffWordsWithSpace(line1.content, line2.content); + var changedWords = []; + if (diffStyle === "word" && matching === "words") { + var removed = diff2.filter(function(element2) { + return element2.removed; + }); + var added = diff2.filter(function(element2) { + return element2.added; + }); + var chunks = matcher(added, removed); + chunks.forEach(function(chunk) { + if (chunk[0].length === 1 && chunk[1].length === 1) { + var dist = distance(chunk[0][0], chunk[1][0]); + if (dist < matchWordsThreshold) { + changedWords.push(chunk[0][0]); + changedWords.push(chunk[1][0]); + } + } + }); + } + var highlightedLine = diff2.reduce(function(highlightedLine2, part) { + var elemType = part.added ? "ins" : part.removed ? "del" : null; + var addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : ""; + var escapedValue = escapeForHtml(part.value); + return elemType !== null ? "".concat(highlightedLine2, "<").concat(elemType).concat(addClass, ">").concat(escapedValue, "") : "".concat(highlightedLine2).concat(escapedValue); + }, ""); + return { + oldLine: { + prefix: line1.prefix, + content: removeInsElements(highlightedLine) + }, + newLine: { + prefix: line2.prefix, + content: removeDelElements(highlightedLine) + } + }; +} + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/file-list-renderer.js +var baseTemplatesPath = "file-summary"; +var iconsBaseTemplatesPath = "icon"; +function render(diffFiles, hoganUtils) { + var files = diffFiles.map(function(file) { + return hoganUtils.render(baseTemplatesPath, "line", { + fileHtmlId: getHtmlId(file), + oldName: file.oldName, + newName: file.newName, + fileName: filenameDiff(file), + deletedLines: "-" + file.deletedLines, + addedLines: "+" + file.addedLines + }, { + fileIcon: hoganUtils.template(iconsBaseTemplatesPath, getFileIcon(file)) + }); + }).join("\n"); + return hoganUtils.render(baseTemplatesPath, "wrapper", { + filesNumber: diffFiles.length, + files + }); +} + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/line-by-line-renderer.js +init_polyfill_buffer(); +var __assign2 = function() { + __assign2 = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign2.apply(this, arguments); +}; +var defaultLineByLineRendererConfig = __assign2(__assign2({}, defaultRenderConfig), { renderNothingWhenEmpty: false, matchingMaxComparisons: 2500, maxLineSizeInBlockForComparison: 200 }); +var genericTemplatesPath = "generic"; +var baseTemplatesPath2 = "line-by-line"; +var iconsBaseTemplatesPath2 = "icon"; +var tagsBaseTemplatesPath = "tag"; +var LineByLineRenderer = function() { + function LineByLineRenderer2(hoganUtils, config) { + if (config === void 0) { + config = {}; + } + this.hoganUtils = hoganUtils; + this.config = __assign2(__assign2({}, defaultLineByLineRendererConfig), config); + } + LineByLineRenderer2.prototype.render = function(diffFiles) { + var _this = this; + var diffsHtml = diffFiles.map(function(file) { + var diffs; + if (file.blocks.length) { + diffs = _this.generateFileHtml(file); + } else { + diffs = _this.generateEmptyDiff(); + } + return _this.makeFileDiffHtml(file, diffs); + }).join("\n"); + return this.hoganUtils.render(genericTemplatesPath, "wrapper", { content: diffsHtml }); + }; + LineByLineRenderer2.prototype.makeFileDiffHtml = function(file, diffs) { + if (this.config.renderNothingWhenEmpty && Array.isArray(file.blocks) && file.blocks.length === 0) + return ""; + var fileDiffTemplate = this.hoganUtils.template(baseTemplatesPath2, "file-diff"); + var filePathTemplate = this.hoganUtils.template(genericTemplatesPath, "file-path"); + var fileIconTemplate = this.hoganUtils.template(iconsBaseTemplatesPath2, "file"); + var fileTagTemplate = this.hoganUtils.template(tagsBaseTemplatesPath, getFileIcon(file)); + return fileDiffTemplate.render({ + file, + fileHtmlId: getHtmlId(file), + diffs, + filePath: filePathTemplate.render({ + fileDiffName: filenameDiff(file) + }, { + fileIcon: fileIconTemplate, + fileTag: fileTagTemplate + }) + }); + }; + LineByLineRenderer2.prototype.generateEmptyDiff = function() { + return this.hoganUtils.render(genericTemplatesPath, "empty-diff", { + contentClass: "d2h-code-line", + CSSLineClass + }); + }; + LineByLineRenderer2.prototype.generateFileHtml = function(file) { + var _this = this; + var matcher2 = newMatcherFn(newDistanceFn(function(e) { + return deconstructLine(e.content, file.isCombined).content; + })); + return file.blocks.map(function(block) { + var lines = _this.hoganUtils.render(genericTemplatesPath, "block-header", { + CSSLineClass, + blockHeader: file.isTooBig ? block.header : escapeForHtml(block.header), + lineClass: "d2h-code-linenumber", + contentClass: "d2h-code-line" + }); + _this.applyLineGroupping(block).forEach(function(_a2) { + var contextLines = _a2[0], oldLines = _a2[1], newLines = _a2[2]; + if (oldLines.length && newLines.length && !contextLines.length) { + _this.applyRematchMatching(oldLines, newLines, matcher2).map(function(_a3) { + var oldLines2 = _a3[0], newLines2 = _a3[1]; + var _b2 = _this.processChangedLines(file, file.isCombined, oldLines2, newLines2), left2 = _b2.left, right2 = _b2.right; + lines += left2; + lines += right2; + }); + } else if (contextLines.length) { + contextLines.forEach(function(line) { + var _a3 = deconstructLine(line.content, file.isCombined), prefix = _a3.prefix, content = _a3.content; + lines += _this.generateSingleLineHtml(file, { + type: CSSLineClass.CONTEXT, + prefix, + content, + oldNumber: line.oldNumber, + newNumber: line.newNumber + }); + }); + } else if (oldLines.length || newLines.length) { + var _b = _this.processChangedLines(file, file.isCombined, oldLines, newLines), left = _b.left, right = _b.right; + lines += left; + lines += right; + } else { + console.error("Unknown state reached while processing groups of lines", contextLines, oldLines, newLines); + } + }); + return lines; + }).join("\n"); + }; + LineByLineRenderer2.prototype.applyLineGroupping = function(block) { + var blockLinesGroups = []; + var oldLines = []; + var newLines = []; + for (var i = 0; i < block.lines.length; i++) { + var diffLine = block.lines[i]; + if (diffLine.type !== LineType.INSERT && newLines.length || diffLine.type === LineType.CONTEXT && oldLines.length > 0) { + blockLinesGroups.push([[], oldLines, newLines]); + oldLines = []; + newLines = []; + } + if (diffLine.type === LineType.CONTEXT) { + blockLinesGroups.push([[diffLine], [], []]); + } else if (diffLine.type === LineType.INSERT && oldLines.length === 0) { + blockLinesGroups.push([[], [], [diffLine]]); + } else if (diffLine.type === LineType.INSERT && oldLines.length > 0) { + newLines.push(diffLine); + } else if (diffLine.type === LineType.DELETE) { + oldLines.push(diffLine); + } + } + if (oldLines.length || newLines.length) { + blockLinesGroups.push([[], oldLines, newLines]); + oldLines = []; + newLines = []; + } + return blockLinesGroups; + }; + LineByLineRenderer2.prototype.applyRematchMatching = function(oldLines, newLines, matcher2) { + var comparisons = oldLines.length * newLines.length; + var maxLineSizeInBlock = Math.max.apply(null, [0].concat(oldLines.concat(newLines).map(function(elem) { + return elem.content.length; + }))); + var doMatching = comparisons < this.config.matchingMaxComparisons && maxLineSizeInBlock < this.config.maxLineSizeInBlockForComparison && (this.config.matching === "lines" || this.config.matching === "words"); + return doMatching ? matcher2(oldLines, newLines) : [[oldLines, newLines]]; + }; + LineByLineRenderer2.prototype.processChangedLines = function(file, isCombined, oldLines, newLines) { + var fileHtml = { + right: "", + left: "" + }; + var maxLinesNumber = Math.max(oldLines.length, newLines.length); + for (var i = 0; i < maxLinesNumber; i++) { + var oldLine = oldLines[i]; + var newLine = newLines[i]; + var diff2 = oldLine !== void 0 && newLine !== void 0 ? diffHighlight(oldLine.content, newLine.content, isCombined, this.config) : void 0; + var preparedOldLine = oldLine !== void 0 && oldLine.oldNumber !== void 0 ? __assign2(__assign2({}, diff2 !== void 0 ? { + prefix: diff2.oldLine.prefix, + content: diff2.oldLine.content, + type: CSSLineClass.DELETE_CHANGES + } : __assign2(__assign2({}, deconstructLine(oldLine.content, isCombined)), { type: toCSSClass(oldLine.type) })), { oldNumber: oldLine.oldNumber, newNumber: oldLine.newNumber }) : void 0; + var preparedNewLine = newLine !== void 0 && newLine.newNumber !== void 0 ? __assign2(__assign2({}, diff2 !== void 0 ? { + prefix: diff2.newLine.prefix, + content: diff2.newLine.content, + type: CSSLineClass.INSERT_CHANGES + } : __assign2(__assign2({}, deconstructLine(newLine.content, isCombined)), { type: toCSSClass(newLine.type) })), { oldNumber: newLine.oldNumber, newNumber: newLine.newNumber }) : void 0; + var _a2 = this.generateLineHtml(file, preparedOldLine, preparedNewLine), left = _a2.left, right = _a2.right; + fileHtml.left += left; + fileHtml.right += right; + } + return fileHtml; + }; + LineByLineRenderer2.prototype.generateLineHtml = function(file, oldLine, newLine) { + return { + left: this.generateSingleLineHtml(file, oldLine), + right: this.generateSingleLineHtml(file, newLine) + }; + }; + LineByLineRenderer2.prototype.generateSingleLineHtml = function(file, line) { + if (line === void 0) + return ""; + var lineNumberHtml = this.hoganUtils.render(baseTemplatesPath2, "numbers", { + oldNumber: line.oldNumber || "", + newNumber: line.newNumber || "" + }); + return this.hoganUtils.render(genericTemplatesPath, "line", { + type: line.type, + lineClass: "d2h-code-linenumber", + contentClass: "d2h-code-line", + prefix: line.prefix === " " ? " " : line.prefix, + content: line.content, + lineNumber: lineNumberHtml, + line, + file + }); + }; + return LineByLineRenderer2; +}(); +var line_by_line_renderer_default = LineByLineRenderer; + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/side-by-side-renderer.js +init_polyfill_buffer(); +var __assign3 = function() { + __assign3 = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign3.apply(this, arguments); +}; +var defaultSideBySideRendererConfig = __assign3(__assign3({}, defaultRenderConfig), { renderNothingWhenEmpty: false, matchingMaxComparisons: 2500, maxLineSizeInBlockForComparison: 200 }); +var genericTemplatesPath2 = "generic"; +var baseTemplatesPath3 = "side-by-side"; +var iconsBaseTemplatesPath3 = "icon"; +var tagsBaseTemplatesPath2 = "tag"; +var SideBySideRenderer = function() { + function SideBySideRenderer2(hoganUtils, config) { + if (config === void 0) { + config = {}; + } + this.hoganUtils = hoganUtils; + this.config = __assign3(__assign3({}, defaultSideBySideRendererConfig), config); + } + SideBySideRenderer2.prototype.render = function(diffFiles) { + var _this = this; + var diffsHtml = diffFiles.map(function(file) { + var diffs; + if (file.blocks.length) { + diffs = _this.generateFileHtml(file); + } else { + diffs = _this.generateEmptyDiff(); + } + return _this.makeFileDiffHtml(file, diffs); + }).join("\n"); + return this.hoganUtils.render(genericTemplatesPath2, "wrapper", { content: diffsHtml }); + }; + SideBySideRenderer2.prototype.makeFileDiffHtml = function(file, diffs) { + if (this.config.renderNothingWhenEmpty && Array.isArray(file.blocks) && file.blocks.length === 0) + return ""; + var fileDiffTemplate = this.hoganUtils.template(baseTemplatesPath3, "file-diff"); + var filePathTemplate = this.hoganUtils.template(genericTemplatesPath2, "file-path"); + var fileIconTemplate = this.hoganUtils.template(iconsBaseTemplatesPath3, "file"); + var fileTagTemplate = this.hoganUtils.template(tagsBaseTemplatesPath2, getFileIcon(file)); + return fileDiffTemplate.render({ + file, + fileHtmlId: getHtmlId(file), + diffs, + filePath: filePathTemplate.render({ + fileDiffName: filenameDiff(file) + }, { + fileIcon: fileIconTemplate, + fileTag: fileTagTemplate + }) + }); + }; + SideBySideRenderer2.prototype.generateEmptyDiff = function() { + return { + right: "", + left: this.hoganUtils.render(genericTemplatesPath2, "empty-diff", { + contentClass: "d2h-code-side-line", + CSSLineClass + }) + }; + }; + SideBySideRenderer2.prototype.generateFileHtml = function(file) { + var _this = this; + var matcher2 = newMatcherFn(newDistanceFn(function(e) { + return deconstructLine(e.content, file.isCombined).content; + })); + return file.blocks.map(function(block) { + var fileHtml = { + left: _this.makeHeaderHtml(block.header, file), + right: _this.makeHeaderHtml("") + }; + _this.applyLineGroupping(block).forEach(function(_a2) { + var contextLines = _a2[0], oldLines = _a2[1], newLines = _a2[2]; + if (oldLines.length && newLines.length && !contextLines.length) { + _this.applyRematchMatching(oldLines, newLines, matcher2).map(function(_a3) { + var oldLines2 = _a3[0], newLines2 = _a3[1]; + var _b2 = _this.processChangedLines(file.isCombined, oldLines2, newLines2), left2 = _b2.left, right2 = _b2.right; + fileHtml.left += left2; + fileHtml.right += right2; + }); + } else if (contextLines.length) { + contextLines.forEach(function(line) { + var _a3 = deconstructLine(line.content, file.isCombined), prefix = _a3.prefix, content = _a3.content; + var _b2 = _this.generateLineHtml({ + type: CSSLineClass.CONTEXT, + prefix, + content, + number: line.oldNumber + }, { + type: CSSLineClass.CONTEXT, + prefix, + content, + number: line.newNumber + }), left2 = _b2.left, right2 = _b2.right; + fileHtml.left += left2; + fileHtml.right += right2; + }); + } else if (oldLines.length || newLines.length) { + var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right; + fileHtml.left += left; + fileHtml.right += right; + } else { + console.error("Unknown state reached while processing groups of lines", contextLines, oldLines, newLines); + } + }); + return fileHtml; + }).reduce(function(accomulated, html2) { + return { left: accomulated.left + html2.left, right: accomulated.right + html2.right }; + }, { left: "", right: "" }); + }; + SideBySideRenderer2.prototype.applyLineGroupping = function(block) { + var blockLinesGroups = []; + var oldLines = []; + var newLines = []; + for (var i = 0; i < block.lines.length; i++) { + var diffLine = block.lines[i]; + if (diffLine.type !== LineType.INSERT && newLines.length || diffLine.type === LineType.CONTEXT && oldLines.length > 0) { + blockLinesGroups.push([[], oldLines, newLines]); + oldLines = []; + newLines = []; + } + if (diffLine.type === LineType.CONTEXT) { + blockLinesGroups.push([[diffLine], [], []]); + } else if (diffLine.type === LineType.INSERT && oldLines.length === 0) { + blockLinesGroups.push([[], [], [diffLine]]); + } else if (diffLine.type === LineType.INSERT && oldLines.length > 0) { + newLines.push(diffLine); + } else if (diffLine.type === LineType.DELETE) { + oldLines.push(diffLine); + } + } + if (oldLines.length || newLines.length) { + blockLinesGroups.push([[], oldLines, newLines]); + oldLines = []; + newLines = []; + } + return blockLinesGroups; + }; + SideBySideRenderer2.prototype.applyRematchMatching = function(oldLines, newLines, matcher2) { + var comparisons = oldLines.length * newLines.length; + var maxLineSizeInBlock = Math.max.apply(null, [0].concat(oldLines.concat(newLines).map(function(elem) { + return elem.content.length; + }))); + var doMatching = comparisons < this.config.matchingMaxComparisons && maxLineSizeInBlock < this.config.maxLineSizeInBlockForComparison && (this.config.matching === "lines" || this.config.matching === "words"); + return doMatching ? matcher2(oldLines, newLines) : [[oldLines, newLines]]; + }; + SideBySideRenderer2.prototype.makeHeaderHtml = function(blockHeader, file) { + return this.hoganUtils.render(genericTemplatesPath2, "block-header", { + CSSLineClass, + blockHeader: (file === null || file === void 0 ? void 0 : file.isTooBig) ? blockHeader : escapeForHtml(blockHeader), + lineClass: "d2h-code-side-linenumber", + contentClass: "d2h-code-side-line" + }); + }; + SideBySideRenderer2.prototype.processChangedLines = function(isCombined, oldLines, newLines) { + var fileHtml = { + right: "", + left: "" + }; + var maxLinesNumber = Math.max(oldLines.length, newLines.length); + for (var i = 0; i < maxLinesNumber; i++) { + var oldLine = oldLines[i]; + var newLine = newLines[i]; + var diff2 = oldLine !== void 0 && newLine !== void 0 ? diffHighlight(oldLine.content, newLine.content, isCombined, this.config) : void 0; + var preparedOldLine = oldLine !== void 0 && oldLine.oldNumber !== void 0 ? __assign3(__assign3({}, diff2 !== void 0 ? { + prefix: diff2.oldLine.prefix, + content: diff2.oldLine.content, + type: CSSLineClass.DELETE_CHANGES + } : __assign3(__assign3({}, deconstructLine(oldLine.content, isCombined)), { type: toCSSClass(oldLine.type) })), { number: oldLine.oldNumber }) : void 0; + var preparedNewLine = newLine !== void 0 && newLine.newNumber !== void 0 ? __assign3(__assign3({}, diff2 !== void 0 ? { + prefix: diff2.newLine.prefix, + content: diff2.newLine.content, + type: CSSLineClass.INSERT_CHANGES + } : __assign3(__assign3({}, deconstructLine(newLine.content, isCombined)), { type: toCSSClass(newLine.type) })), { number: newLine.newNumber }) : void 0; + var _a2 = this.generateLineHtml(preparedOldLine, preparedNewLine), left = _a2.left, right = _a2.right; + fileHtml.left += left; + fileHtml.right += right; + } + return fileHtml; + }; + SideBySideRenderer2.prototype.generateLineHtml = function(oldLine, newLine) { + return { + left: this.generateSingleHtml(oldLine), + right: this.generateSingleHtml(newLine) + }; + }; + SideBySideRenderer2.prototype.generateSingleHtml = function(line) { + var lineClass = "d2h-code-side-linenumber"; + var contentClass = "d2h-code-side-line"; + return this.hoganUtils.render(genericTemplatesPath2, "line", { + type: (line === null || line === void 0 ? void 0 : line.type) || "".concat(CSSLineClass.CONTEXT, " d2h-emptyplaceholder"), + lineClass: line !== void 0 ? lineClass : "".concat(lineClass, " d2h-code-side-emptyplaceholder"), + contentClass: line !== void 0 ? contentClass : "".concat(contentClass, " d2h-code-side-emptyplaceholder"), + prefix: (line === null || line === void 0 ? void 0 : line.prefix) === " " ? " " : line === null || line === void 0 ? void 0 : line.prefix, + content: line === null || line === void 0 ? void 0 : line.content, + lineNumber: line === null || line === void 0 ? void 0 : line.number + }); + }; + return SideBySideRenderer2; +}(); +var side_by_side_renderer_default = SideBySideRenderer; + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/hoganjs-utils.js +init_polyfill_buffer(); +var Hogan3 = __toESM(require_hogan()); + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/diff2html-templates.js +init_polyfill_buffer(); +var Hogan2 = __toESM(require_hogan()); +var defaultTemplates = {}; +defaultTemplates["file-summary-line"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('
  • '); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(t.rp("'); + t.b(t.v(t.f("fileName", c, p, 0))); + t.b(""); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(' '); + t.b(t.v(t.f("addedLines", c, p, 0))); + t.b(""); + t.b("\n" + i); + t.b(' '); + t.b(t.v(t.f("deletedLines", c, p, 0))); + t.b(""); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b("
  • "); + return t.fl(); +}, partials: { "'); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b(' Files changed ('); + t.b(t.v(t.f("filesNumber", c, p, 0))); + t.b(")"); + t.b("\n" + i); + t.b(' hide'); + t.b("\n" + i); + t.b(' show'); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b('
      '); + t.b("\n" + i); + t.b(" "); + t.b(t.t(t.f("files", c, p, 0))); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b(""); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["generic-block-header"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b(""); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b('
    '); + if (t.s(t.f("blockHeader", c, p, 1), c, p, 0, 156, 173, "{{ }}")) { + t.rs(c, p, function(c2, p2, t2) { + t2.b(t2.t(t2.f("blockHeader", c2, p2, 0))); + }); + c.pop(); + } + if (!t.s(t.f("blockHeader", c, p, 1), c, p, 1, 0, 0, "")) { + t.b(" "); + } + ; + t.b("
    "); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b(""); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["generic-empty-diff"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b(""); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b(" File without changes"); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b(""); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["generic-file-path"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b(''); + t.b("\n" + i); + t.b(t.rp("'); + t.b(t.v(t.f("fileDiffName", c, p, 0))); + t.b(""); + t.b("\n" + i); + t.b(t.rp(""); + t.b("\n" + i); + t.b('"); + return t.fl(); +}, partials: { ""); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(" "); + t.b(t.t(t.f("lineNumber", c, p, 0))); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + if (t.s(t.f("prefix", c, p, 1), c, p, 0, 162, 238, "{{ }}")) { + t.rs(c, p, function(c2, p2, t2) { + t2.b(' '); + t2.b(t2.t(t2.f("prefix", c2, p2, 0))); + t2.b(""); + t2.b("\n" + i); + }); + c.pop(); + } + if (!t.s(t.f("prefix", c, p, 1), c, p, 1, 0, 0, "")) { + t.b('  '); + t.b("\n" + i); + } + ; + if (t.s(t.f("content", c, p, 1), c, p, 0, 371, 445, "{{ }}")) { + t.rs(c, p, function(c2, p2, t2) { + t2.b(' '); + t2.b(t2.t(t2.f("content", c2, p2, 0))); + t2.b(""); + t2.b("\n" + i); + }); + c.pop(); + } + if (!t.s(t.f("content", c, p, 1), c, p, 1, 0, 0, "")) { + t.b('
    '); + t.b("\n" + i); + } + ; + t.b("
    "); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b(""); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["generic-wrapper"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('
    '); + t.b("\n" + i); + t.b(" "); + t.b(t.t(t.f("content", c, p, 0))); + t.b("\n" + i); + t.b("
    "); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["icon-file-added"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('"); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["icon-file-changed"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('"); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["icon-file-deleted"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('"); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["icon-file-renamed"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('"); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["icon-file"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('"); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["line-by-line-file-diff"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('
    '); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b(" "); + t.b(t.t(t.f("filePath", c, p, 0))); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(" "); + t.b(t.t(t.f("diffs", c, p, 0))); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["line-by-line-numbers"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('
    '); + t.b(t.v(t.f("oldNumber", c, p, 0))); + t.b("
    "); + t.b("\n" + i); + t.b('
    '); + t.b(t.v(t.f("newNumber", c, p, 0))); + t.b("
    "); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["side-by-side-file-diff"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('
    '); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b(" "); + t.b(t.t(t.f("filePath", c, p, 0))); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(" "); + t.b(t.t(t.d("diffs.left", c, p, 0))); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b('
    '); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(' '); + t.b("\n" + i); + t.b(" "); + t.b(t.t(t.d("diffs.right", c, p, 0))); + t.b("\n" + i); + t.b(" "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + t.b("\n" + i); + t.b("
    "); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["tag-file-added"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('ADDED'); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["tag-file-changed"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('CHANGED'); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["tag-file-deleted"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('DELETED'); + return t.fl(); +}, partials: {}, subs: {} }); +defaultTemplates["tag-file-renamed"] = new Hogan2.Template({ code: function(c, p, i) { + var t = this; + t.b(i = i || ""); + t.b('RENAMED'); + return t.fl(); +}, partials: {}, subs: {} }); + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/hoganjs-utils.js +var __assign4 = function() { + __assign4 = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign4.apply(this, arguments); +}; +var HoganJsUtils = function() { + function HoganJsUtils2(_a2) { + var _b = _a2.compiledTemplates, compiledTemplates = _b === void 0 ? {} : _b, _c = _a2.rawTemplates, rawTemplates = _c === void 0 ? {} : _c; + var compiledRawTemplates = Object.entries(rawTemplates).reduce(function(previousTemplates, _a3) { + var _b2; + var name = _a3[0], templateString = _a3[1]; + var compiledTemplate = Hogan3.compile(templateString, { asString: false }); + return __assign4(__assign4({}, previousTemplates), (_b2 = {}, _b2[name] = compiledTemplate, _b2)); + }, {}); + this.preCompiledTemplates = __assign4(__assign4(__assign4({}, defaultTemplates), compiledTemplates), compiledRawTemplates); + } + HoganJsUtils2.compile = function(templateString) { + return Hogan3.compile(templateString, { asString: false }); + }; + HoganJsUtils2.prototype.render = function(namespace, view, params, partials, indent2) { + var templateKey = this.templateKey(namespace, view); + try { + var template = this.preCompiledTemplates[templateKey]; + return template.render(params, partials, indent2); + } catch (e) { + throw new Error("Could not find template to render '".concat(templateKey, "'")); + } + }; + HoganJsUtils2.prototype.template = function(namespace, view) { + return this.preCompiledTemplates[this.templateKey(namespace, view)]; + }; + HoganJsUtils2.prototype.templateKey = function(namespace, view) { + return "".concat(namespace, "-").concat(view); + }; + return HoganJsUtils2; +}(); +var hoganjs_utils_default = HoganJsUtils; + +// node_modules/.pnpm/diff2html@3.4.35/node_modules/diff2html/lib-esm/diff2html.js +var __assign5 = function() { + __assign5 = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign5.apply(this, arguments); +}; +var defaultDiff2HtmlConfig = __assign5(__assign5(__assign5({}, defaultLineByLineRendererConfig), defaultSideBySideRendererConfig), { outputFormat: OutputFormatType.LINE_BY_LINE, drawFileList: true }); +function html(diffInput, configuration) { + if (configuration === void 0) { + configuration = {}; + } + var config = __assign5(__assign5({}, defaultDiff2HtmlConfig), configuration); + var diffJson = typeof diffInput === "string" ? parse(diffInput, config) : diffInput; + var hoganUtils = new hoganjs_utils_default(config); + var fileList = config.drawFileList ? render(diffJson, hoganUtils) : ""; + var diffOutput = config.outputFormat === "side-by-side" ? new side_by_side_renderer_default(hoganUtils, config).render(diffJson) : new line_by_line_renderer_default(hoganUtils, config).render(diffJson); + return fileList + diffOutput; +} + +// src/ui/diff/diffView.ts +var import_obsidian17 = require("obsidian"); +var DiffView = class extends import_obsidian17.ItemView { + constructor(leaf, plugin) { + super(leaf); + this.plugin = plugin; + this.gettingDiff = false; + this.gitRefreshBind = this.refresh.bind(this); + this.gitViewRefreshBind = this.refresh.bind(this); + this.parser = new DOMParser(); + this.navigation = true; + addEventListener("git-refresh", this.gitRefreshBind); + addEventListener("git-view-refresh", this.gitViewRefreshBind); + } + getViewType() { + return DIFF_VIEW_CONFIG.type; + } + getDisplayText() { + var _a2; + if (((_a2 = this.state) == null ? void 0 : _a2.file) != null) { + let fileName = this.state.file.split("/").last(); + if (fileName == null ? void 0 : fileName.endsWith(".md")) + fileName = fileName.slice(0, -3); + return DIFF_VIEW_CONFIG.name + ` (${fileName})`; + } + return DIFF_VIEW_CONFIG.name; + } + getIcon() { + return DIFF_VIEW_CONFIG.icon; + } + async setState(state, result) { + this.state = state; + await this.refresh(); + return; + } + getState() { + return this.state; + } + onClose() { + removeEventListener("git-refresh", this.gitRefreshBind); + removeEventListener("git-view-refresh", this.gitViewRefreshBind); + return super.onClose(); + } + onOpen() { + this.refresh(); + return super.onOpen(); + } + async refresh() { + var _a2; + if (((_a2 = this.state) == null ? void 0 : _a2.file) && !this.gettingDiff && this.plugin.gitManager) { + this.gettingDiff = true; + try { + let diff2 = await this.plugin.gitManager.getDiffString( + this.state.file, + this.state.staged, + this.state.hash + ); + this.contentEl.empty(); + if (!diff2) { + if (this.plugin.gitManager instanceof SimpleGit && await this.plugin.gitManager.isTracked( + this.state.file + )) { + diff2 = [ + `--- ${this.state.file}`, + `+++ ${this.state.file}`, + "" + ].join("\n"); + } else { + const content = await this.app.vault.adapter.read( + this.plugin.gitManager.getVaultPath(this.state.file) + ); + const header = `--- /dev/null ++++ ${this.state.file} +@@ -0,0 +1,${content.split("\n").length} @@`; + diff2 = [ + ...header.split("\n"), + ...content.split("\n").map((line) => `+${line}`) + ].join("\n"); + } + } + const diffEl = this.parser.parseFromString(html(diff2), "text/html").querySelector(".d2h-file-diff"); + this.contentEl.append(diffEl); + } finally { + this.gettingDiff = false; + } + } + } +}; + +// src/ui/history/historyView.ts +init_polyfill_buffer(); +var import_obsidian20 = require("obsidian"); + +// src/ui/history/historyView.svelte +init_polyfill_buffer(); + +// node_modules/.pnpm/svelte@3.59.0/node_modules/svelte/internal/index.mjs +init_polyfill_buffer(); +function noop() { +} +var identity = (x) => x; +function run(fn) { + return fn(); +} +function blank_object() { + return /* @__PURE__ */ Object.create(null); +} +function run_all(fns) { + fns.forEach(run); +} +function is_function(thing) { + return typeof thing === "function"; +} +function safe_not_equal(a, b) { + return a != a ? b == b : a !== b || (a && typeof a === "object" || typeof a === "function"); +} +function is_empty(obj) { + return Object.keys(obj).length === 0; +} +var is_client = typeof window !== "undefined"; +var now = is_client ? () => window.performance.now() : () => Date.now(); +var raf = is_client ? (cb) => requestAnimationFrame(cb) : noop; +var tasks = /* @__PURE__ */ new Set(); +function run_tasks(now2) { + tasks.forEach((task) => { + if (!task.c(now2)) { + tasks.delete(task); + task.f(); + } + }); + if (tasks.size !== 0) + raf(run_tasks); +} +function loop(callback) { + let task; + if (tasks.size === 0) + raf(run_tasks); + return { + promise: new Promise((fulfill) => { + tasks.add(task = { c: callback, f: fulfill }); + }), + abort() { + tasks.delete(task); + } + }; +} +var globals = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : global; +var ResizeObserverSingleton = class { + constructor(options) { + this.options = options; + this._listeners = "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0; + } + observe(element2, listener) { + this._listeners.set(element2, listener); + this._getObserver().observe(element2, this.options); + return () => { + this._listeners.delete(element2); + this._observer.unobserve(element2); + }; + } + _getObserver() { + var _a2; + return (_a2 = this._observer) !== null && _a2 !== void 0 ? _a2 : this._observer = new ResizeObserver((entries) => { + var _a3; + for (const entry of entries) { + ResizeObserverSingleton.entries.set(entry.target, entry); + (_a3 = this._listeners.get(entry.target)) === null || _a3 === void 0 ? void 0 : _a3(entry); + } + }); + } +}; +ResizeObserverSingleton.entries = "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0; +var is_hydrating = false; +function start_hydrating() { + is_hydrating = true; +} +function end_hydrating() { + is_hydrating = false; +} +function append2(target, node) { + target.appendChild(node); +} +function append_styles(target, style_sheet_id, styles) { + const append_styles_to = get_root_for_style(target); + if (!append_styles_to.getElementById(style_sheet_id)) { + const style = element("style"); + style.id = style_sheet_id; + style.textContent = styles; + append_stylesheet(append_styles_to, style); + } +} +function get_root_for_style(node) { + if (!node) + return document; + const root2 = node.getRootNode ? node.getRootNode() : node.ownerDocument; + if (root2 && root2.host) { + return root2; + } + return node.ownerDocument; +} +function append_empty_stylesheet(node) { + const style_element = element("style"); + append_stylesheet(get_root_for_style(node), style_element); + return style_element.sheet; +} +function append_stylesheet(node, style) { + append2(node.head || node, style); + return style.sheet; +} +function insert(target, node, anchor) { + target.insertBefore(node, anchor || null); +} +function detach(node) { + if (node.parentNode) { + node.parentNode.removeChild(node); + } +} +function destroy_each(iterations, detaching) { + for (let i = 0; i < iterations.length; i += 1) { + if (iterations[i]) + iterations[i].d(detaching); + } +} +function element(name) { + return document.createElement(name); +} +function text(data) { + return document.createTextNode(data); +} +function space() { + return text(" "); +} +function empty() { + return text(""); +} +function listen(node, event, handler, options) { + node.addEventListener(event, handler, options); + return () => node.removeEventListener(event, handler, options); +} +function stop_propagation(fn) { + return function(event) { + event.stopPropagation(); + return fn.call(this, event); + }; +} +function attr(node, attribute, value) { + if (value == null) + node.removeAttribute(attribute); + else if (node.getAttribute(attribute) !== value) + node.setAttribute(attribute, value); +} +function children(element2) { + return Array.from(element2.childNodes); +} +function set_data(text2, data) { + data = "" + data; + if (text2.data === data) + return; + text2.data = data; +} +function set_input_value(input, value) { + input.value = value == null ? "" : value; +} +function set_style(node, key2, value, important) { + if (value == null) { + node.style.removeProperty(key2); + } else { + node.style.setProperty(key2, value, important ? "important" : ""); + } +} +function toggle_class(element2, name, toggle) { + element2.classList[toggle ? "add" : "remove"](name); +} +function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) { + const e = document.createEvent("CustomEvent"); + e.initCustomEvent(type, bubbles, cancelable, detail); + return e; +} +var managed_styles = /* @__PURE__ */ new Map(); +var active = 0; +function hash(str) { + let hash2 = 5381; + let i = str.length; + while (i--) + hash2 = (hash2 << 5) - hash2 ^ str.charCodeAt(i); + return hash2 >>> 0; +} +function create_style_information(doc, node) { + const info = { stylesheet: append_empty_stylesheet(node), rules: {} }; + managed_styles.set(doc, info); + return info; +} +function create_rule(node, a, b, duration, delay2, ease, fn, uid = 0) { + const step = 16.666 / duration; + let keyframes = "{\n"; + for (let p = 0; p <= 1; p += step) { + const t = a + (b - a) * ease(p); + keyframes += p * 100 + `%{${fn(t, 1 - t)}} +`; + } + const rule = keyframes + `100% {${fn(b, 1 - b)}} +}`; + const name = `__svelte_${hash(rule)}_${uid}`; + const doc = get_root_for_style(node); + const { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node); + if (!rules[name]) { + rules[name] = true; + stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length); + } + const animation = node.style.animation || ""; + node.style.animation = `${animation ? `${animation}, ` : ""}${name} ${duration}ms linear ${delay2}ms 1 both`; + active += 1; + return name; +} +function delete_rule(node, name) { + const previous = (node.style.animation || "").split(", "); + const next = previous.filter( + name ? (anim) => anim.indexOf(name) < 0 : (anim) => anim.indexOf("__svelte") === -1 + // remove all Svelte animations + ); + const deleted = previous.length - next.length; + if (deleted) { + node.style.animation = next.join(", "); + active -= deleted; + if (!active) + clear_rules(); + } +} +function clear_rules() { + raf(() => { + if (active) + return; + managed_styles.forEach((info) => { + const { ownerNode } = info.stylesheet; + if (ownerNode) + detach(ownerNode); + }); + managed_styles.clear(); + }); +} +var current_component; +function set_current_component(component) { + current_component = component; +} +function get_current_component() { + if (!current_component) + throw new Error("Function called outside component initialization"); + return current_component; +} +function onDestroy(fn) { + get_current_component().$$.on_destroy.push(fn); +} +function bubble(component, event) { + const callbacks = component.$$.callbacks[event.type]; + if (callbacks) { + callbacks.slice().forEach((fn) => fn.call(this, event)); + } +} +var dirty_components = []; +var binding_callbacks = []; +var render_callbacks = []; +var flush_callbacks = []; +var resolved_promise = /* @__PURE__ */ Promise.resolve(); +var update_scheduled = false; +function schedule_update() { + if (!update_scheduled) { + update_scheduled = true; + resolved_promise.then(flush); + } +} +function add_render_callback(fn) { + render_callbacks.push(fn); +} +var seen_callbacks = /* @__PURE__ */ new Set(); +var flushidx = 0; +function flush() { + if (flushidx !== 0) { + return; + } + const saved_component = current_component; + do { + try { + while (flushidx < dirty_components.length) { + const component = dirty_components[flushidx]; + flushidx++; + set_current_component(component); + update(component.$$); + } + } catch (e) { + dirty_components.length = 0; + flushidx = 0; + throw e; + } + set_current_component(null); + dirty_components.length = 0; + flushidx = 0; + while (binding_callbacks.length) + binding_callbacks.pop()(); + for (let i = 0; i < render_callbacks.length; i += 1) { + const callback = render_callbacks[i]; + if (!seen_callbacks.has(callback)) { + seen_callbacks.add(callback); + callback(); + } + } + render_callbacks.length = 0; + } while (dirty_components.length); + while (flush_callbacks.length) { + flush_callbacks.pop()(); + } + update_scheduled = false; + seen_callbacks.clear(); + set_current_component(saved_component); +} +function update($$) { + if ($$.fragment !== null) { + $$.update(); + run_all($$.before_update); + const dirty = $$.dirty; + $$.dirty = [-1]; + $$.fragment && $$.fragment.p($$.ctx, dirty); + $$.after_update.forEach(add_render_callback); + } +} +function flush_render_callbacks(fns) { + const filtered = []; + const targets = []; + render_callbacks.forEach((c) => fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c)); + targets.forEach((c) => c()); + render_callbacks = filtered; +} +var promise; +function wait() { + if (!promise) { + promise = Promise.resolve(); + promise.then(() => { + promise = null; + }); + } + return promise; +} +function dispatch(node, direction, kind) { + node.dispatchEvent(custom_event(`${direction ? "intro" : "outro"}${kind}`)); +} +var outroing = /* @__PURE__ */ new Set(); +var outros; +function group_outros() { + outros = { + r: 0, + c: [], + p: outros + // parent group + }; +} +function check_outros() { + if (!outros.r) { + run_all(outros.c); + } + outros = outros.p; +} +function transition_in(block, local) { + if (block && block.i) { + outroing.delete(block); + block.i(local); + } +} +function transition_out(block, local, detach2, callback) { + if (block && block.o) { + if (outroing.has(block)) + return; + outroing.add(block); + outros.c.push(() => { + outroing.delete(block); + if (callback) { + if (detach2) + block.d(1); + callback(); + } + }); + block.o(local); + } else if (callback) { + callback(); + } +} +var null_transition = { duration: 0 }; +function create_bidirectional_transition(node, fn, params, intro) { + const options = { direction: "both" }; + let config = fn(node, params, options); + let t = intro ? 0 : 1; + let running_program = null; + let pending_program = null; + let animation_name = null; + function clear_animation() { + if (animation_name) + delete_rule(node, animation_name); + } + function init3(program, duration) { + const d = program.b - t; + duration *= Math.abs(d); + return { + a: t, + b: program.b, + d, + duration, + start: program.start, + end: program.start + duration, + group: program.group + }; + } + function go(b) { + const { delay: delay2 = 0, duration = 300, easing = identity, tick: tick2 = noop, css } = config || null_transition; + const program = { + start: now() + delay2, + b + }; + if (!b) { + program.group = outros; + outros.r += 1; + } + if (running_program || pending_program) { + pending_program = program; + } else { + if (css) { + clear_animation(); + animation_name = create_rule(node, t, b, duration, delay2, easing, css); + } + if (b) + tick2(0, 1); + running_program = init3(program, duration); + add_render_callback(() => dispatch(node, b, "start")); + loop((now2) => { + if (pending_program && now2 > pending_program.start) { + running_program = init3(pending_program, duration); + pending_program = null; + dispatch(node, running_program.b, "start"); + if (css) { + clear_animation(); + animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css); + } + } + if (running_program) { + if (now2 >= running_program.end) { + tick2(t = running_program.b, 1 - t); + dispatch(node, running_program.b, "end"); + if (!pending_program) { + if (running_program.b) { + clear_animation(); + } else { + if (!--running_program.group.r) + run_all(running_program.group.c); + } + } + running_program = null; + } else if (now2 >= running_program.start) { + const p = now2 - running_program.start; + t = running_program.a + running_program.d * easing(p / running_program.duration); + tick2(t, 1 - t); + } + } + return !!(running_program || pending_program); + }); + } + } + return { + run(b) { + if (is_function(config)) { + wait().then(() => { + config = config(options); + go(b); + }); + } else { + go(b); + } + }, + end() { + clear_animation(); + running_program = pending_program = null; + } + }; +} +var _boolean_attributes = [ + "allowfullscreen", + "allowpaymentrequest", + "async", + "autofocus", + "autoplay", + "checked", + "controls", + "default", + "defer", + "disabled", + "formnovalidate", + "hidden", + "inert", + "ismap", + "loop", + "multiple", + "muted", + "nomodule", + "novalidate", + "open", + "playsinline", + "readonly", + "required", + "reversed", + "selected" +]; +var boolean_attributes = /* @__PURE__ */ new Set([..._boolean_attributes]); +function create_component(block) { + block && block.c(); +} +function mount_component(component, target, anchor, customElement) { + const { fragment, after_update } = component.$$; + fragment && fragment.m(target, anchor); + if (!customElement) { + add_render_callback(() => { + const new_on_destroy = component.$$.on_mount.map(run).filter(is_function); + if (component.$$.on_destroy) { + component.$$.on_destroy.push(...new_on_destroy); + } else { + run_all(new_on_destroy); + } + component.$$.on_mount = []; + }); + } + after_update.forEach(add_render_callback); +} +function destroy_component(component, detaching) { + const $$ = component.$$; + if ($$.fragment !== null) { + flush_render_callbacks($$.after_update); + run_all($$.on_destroy); + $$.fragment && $$.fragment.d(detaching); + $$.on_destroy = $$.fragment = null; + $$.ctx = []; + } +} +function make_dirty(component, i) { + if (component.$$.dirty[0] === -1) { + dirty_components.push(component); + schedule_update(); + component.$$.dirty.fill(0); + } + component.$$.dirty[i / 31 | 0] |= 1 << i % 31; +} +function init2(component, options, instance10, create_fragment10, not_equal, props, append_styles2, dirty = [-1]) { + const parent_component = current_component; + set_current_component(component); + const $$ = component.$$ = { + fragment: null, + ctx: [], + // state + props, + update: noop, + not_equal, + bound: blank_object(), + // lifecycle + on_mount: [], + on_destroy: [], + on_disconnect: [], + before_update: [], + after_update: [], + context: new Map(options.context || (parent_component ? parent_component.$$.context : [])), + // everything else + callbacks: blank_object(), + dirty, + skip_bound: false, + root: options.target || parent_component.$$.root + }; + append_styles2 && append_styles2($$.root); + let ready = false; + $$.ctx = instance10 ? instance10(component, options.props || {}, (i, ret, ...rest) => { + const value = rest.length ? rest[0] : ret; + if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { + if (!$$.skip_bound && $$.bound[i]) + $$.bound[i](value); + if (ready) + make_dirty(component, i); + } + return ret; + }) : []; + $$.update(); + ready = true; + run_all($$.before_update); + $$.fragment = create_fragment10 ? create_fragment10($$.ctx) : false; + if (options.target) { + if (options.hydrate) { + start_hydrating(); + const nodes = children(options.target); + $$.fragment && $$.fragment.l(nodes); + nodes.forEach(detach); + } else { + $$.fragment && $$.fragment.c(); + } + if (options.intro) + transition_in(component.$$.fragment); + mount_component(component, options.target, options.anchor, options.customElement); + end_hydrating(); + flush(); + } + set_current_component(parent_component); +} +var SvelteElement; +if (typeof HTMLElement === "function") { + SvelteElement = class extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: "open" }); + } + connectedCallback() { + const { on_mount } = this.$$; + this.$$.on_disconnect = on_mount.map(run).filter(is_function); + for (const key2 in this.$$.slotted) { + this.appendChild(this.$$.slotted[key2]); + } + } + attributeChangedCallback(attr2, _oldValue, newValue) { + this[attr2] = newValue; + } + disconnectedCallback() { + run_all(this.$$.on_disconnect); + } + $destroy() { + destroy_component(this, 1); + this.$destroy = noop; + } + $on(type, callback) { + if (!is_function(callback)) { + return noop; + } + const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []); + callbacks.push(callback); + return () => { + const index2 = callbacks.indexOf(callback); + if (index2 !== -1) + callbacks.splice(index2, 1); + }; + } + $set($$props) { + if (this.$$set && !is_empty($$props)) { + this.$$.skip_bound = true; + this.$$set($$props); + this.$$.skip_bound = false; + } + } + }; +} +var SvelteComponent = class { + $destroy() { + destroy_component(this, 1); + this.$destroy = noop; + } + $on(type, callback) { + if (!is_function(callback)) { + return noop; + } + const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []); + callbacks.push(callback); + return () => { + const index2 = callbacks.indexOf(callback); + if (index2 !== -1) + callbacks.splice(index2, 1); + }; + } + $set($$props) { + if (this.$$set && !is_empty($$props)) { + this.$$.skip_bound = true; + this.$$set($$props); + this.$$.skip_bound = false; + } + } +}; + +// node_modules/.pnpm/tslib@2.5.0/node_modules/tslib/tslib.es6.js +init_polyfill_buffer(); +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +// src/ui/history/historyView.svelte +var import_obsidian19 = require("obsidian"); + +// node_modules/.pnpm/svelte@3.59.0/node_modules/svelte/index.mjs +init_polyfill_buffer(); + +// src/ui/history/components/logComponent.svelte +init_polyfill_buffer(); + +// node_modules/.pnpm/svelte@3.59.0/node_modules/svelte/transition/index.mjs +init_polyfill_buffer(); + +// node_modules/.pnpm/svelte@3.59.0/node_modules/svelte/easing/index.mjs +init_polyfill_buffer(); +function cubicOut(t) { + const f = t - 1; + return f * f * f + 1; +} + +// node_modules/.pnpm/svelte@3.59.0/node_modules/svelte/transition/index.mjs +function slide(node, { delay: delay2 = 0, duration = 400, easing = cubicOut, axis = "y" } = {}) { + const style = getComputedStyle(node); + const opacity = +style.opacity; + const primary_property = axis === "y" ? "height" : "width"; + const primary_property_value = parseFloat(style[primary_property]); + const secondary_properties = axis === "y" ? ["top", "bottom"] : ["left", "right"]; + const capitalized_secondary_properties = secondary_properties.map((e) => `${e[0].toUpperCase()}${e.slice(1)}`); + const padding_start_value = parseFloat(style[`padding${capitalized_secondary_properties[0]}`]); + const padding_end_value = parseFloat(style[`padding${capitalized_secondary_properties[1]}`]); + const margin_start_value = parseFloat(style[`margin${capitalized_secondary_properties[0]}`]); + const margin_end_value = parseFloat(style[`margin${capitalized_secondary_properties[1]}`]); + const border_width_start_value = parseFloat(style[`border${capitalized_secondary_properties[0]}Width`]); + const border_width_end_value = parseFloat(style[`border${capitalized_secondary_properties[1]}Width`]); + return { + delay: delay2, + duration, + easing, + css: (t) => `overflow: hidden;opacity: ${Math.min(t * 20, 1) * opacity};${primary_property}: ${t * primary_property_value}px;padding-${secondary_properties[0]}: ${t * padding_start_value}px;padding-${secondary_properties[1]}: ${t * padding_end_value}px;margin-${secondary_properties[0]}: ${t * margin_start_value}px;margin-${secondary_properties[1]}: ${t * margin_end_value}px;border-${secondary_properties[0]}-width: ${t * border_width_start_value}px;border-${secondary_properties[1]}-width: ${t * border_width_end_value}px;` + }; +} + +// src/ui/history/components/logFileComponent.svelte +init_polyfill_buffer(); +var import_obsidian18 = require("obsidian"); +function add_css(target) { + append_styles(target, "svelte-pmbo0n", "main.svelte-pmbo0n .nav-file-title-content.svelte-pmbo0n{display:flex;align-items:center}"); +} +function create_if_block(ctx) { + let div; + let mounted; + let dispose; + return { + c() { + div = element("div"); + attr(div, "data-icon", "go-to-file"); + attr(div, "aria-label", "Open File"); + attr(div, "class", "clickable-icon"); + }, + m(target, anchor) { + insert(target, div, anchor); + ctx[7](div); + if (!mounted) { + dispose = [ + listen(div, "auxclick", stop_propagation( + /*open*/ + ctx[4] + )), + listen(div, "click", stop_propagation( + /*open*/ + ctx[4] + )) + ]; + mounted = true; + } + }, + p: noop, + d(detaching) { + if (detaching) + detach(div); + ctx[7](null); + mounted = false; + run_all(dispose); + } + }; +} +function create_fragment(ctx) { + let main; + let div3; + let div0; + let t0_value = getDisplayPath( + /*diff*/ + ctx[0].vault_path + ) + ""; + let t0; + let t1; + let div2; + let div1; + let show_if = ( + /*view*/ + ctx[1].app.vault.getAbstractFileByPath( + /*diff*/ + ctx[0].vault_path + ) + ); + let t2; + let span; + let t3_value = ( + /*diff*/ + ctx[0].status + "" + ); + let t3; + let span_data_type_value; + let div3_aria_label_value; + let mounted; + let dispose; + let if_block = show_if && create_if_block(ctx); + return { + c() { + main = element("main"); + div3 = element("div"); + div0 = element("div"); + t0 = text(t0_value); + t1 = space(); + div2 = element("div"); + div1 = element("div"); + if (if_block) + if_block.c(); + t2 = space(); + span = element("span"); + t3 = text(t3_value); + attr(div0, "class", "tree-item-inner nav-file-title-content svelte-pmbo0n"); + attr(div1, "class", "buttons"); + attr(span, "class", "type"); + attr(span, "data-type", span_data_type_value = /*diff*/ + ctx[0].status); + attr(div2, "class", "git-tools"); + attr(div3, "class", "tree-item-self is-clickable nav-file-title"); + attr( + div3, + "aria-label-position", + /*side*/ + ctx[3] + ); + attr(div3, "aria-label", div3_aria_label_value = /*diff*/ + ctx[0].vault_path); + attr(main, "class", "tree-item nav-file svelte-pmbo0n"); + }, + m(target, anchor) { + insert(target, main, anchor); + append2(main, div3); + append2(div3, div0); + append2(div0, t0); + append2(div3, t1); + append2(div3, div2); + append2(div2, div1); + if (if_block) + if_block.m(div1, null); + append2(div2, t2); + append2(div2, span); + append2(span, t3); + if (!mounted) { + dispose = [ + listen(main, "click", stop_propagation( + /*showDiff*/ + ctx[5] + )), + listen(main, "auxclick", stop_propagation( + /*showDiff*/ + ctx[5] + )), + listen( + main, + "focus", + /*focus_handler*/ + ctx[6] + ) + ]; + mounted = true; + } + }, + p(ctx2, [dirty]) { + if (dirty & /*diff*/ + 1 && t0_value !== (t0_value = getDisplayPath( + /*diff*/ + ctx2[0].vault_path + ) + "")) + set_data(t0, t0_value); + if (dirty & /*view, diff*/ + 3) + show_if = /*view*/ + ctx2[1].app.vault.getAbstractFileByPath( + /*diff*/ + ctx2[0].vault_path + ); + if (show_if) { + if (if_block) { + if_block.p(ctx2, dirty); + } else { + if_block = create_if_block(ctx2); + if_block.c(); + if_block.m(div1, null); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } + if (dirty & /*diff*/ + 1 && t3_value !== (t3_value = /*diff*/ + ctx2[0].status + "")) + set_data(t3, t3_value); + if (dirty & /*diff*/ + 1 && span_data_type_value !== (span_data_type_value = /*diff*/ + ctx2[0].status)) { + attr(span, "data-type", span_data_type_value); + } + if (dirty & /*side*/ + 8) { + attr( + div3, + "aria-label-position", + /*side*/ + ctx2[3] + ); + } + if (dirty & /*diff*/ + 1 && div3_aria_label_value !== (div3_aria_label_value = /*diff*/ + ctx2[0].vault_path)) { + attr(div3, "aria-label", div3_aria_label_value); + } + }, + i: noop, + o: noop, + d(detaching) { + if (detaching) + detach(main); + if (if_block) + if_block.d(); + mounted = false; + run_all(dispose); + } + }; +} +function instance($$self, $$props, $$invalidate) { + let side; + let { diff: diff2 } = $$props; + let { view } = $$props; + let buttons = []; + window.setTimeout(() => buttons.forEach((b) => (0, import_obsidian18.setIcon)(b, b.getAttr("data-icon"))), 0); + function open(event) { + var _a2; + const file = view.app.vault.getAbstractFileByPath(diff2.vault_path); + if (file instanceof import_obsidian18.TFile) { + (_a2 = getNewLeaf(event)) === null || _a2 === void 0 ? void 0 : _a2.openFile(file); + } + } + function showDiff(event) { + var _a2; + (_a2 = getNewLeaf(event)) === null || _a2 === void 0 ? void 0 : _a2.setViewState({ + type: DIFF_VIEW_CONFIG.type, + active: true, + state: { + file: diff2.path, + staged: false, + hash: diff2.hash + } + }); + } + function focus_handler(event) { + bubble.call(this, $$self, event); + } + function div_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[0] = $$value; + $$invalidate(2, buttons); + }); + } + $$self.$$set = ($$props2) => { + if ("diff" in $$props2) + $$invalidate(0, diff2 = $$props2.diff); + if ("view" in $$props2) + $$invalidate(1, view = $$props2.view); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty & /*view*/ + 2) { + $: + $$invalidate(3, side = view.leaf.getRoot().side == "left" ? "right" : "left"); + } + }; + return [diff2, view, buttons, side, open, showDiff, focus_handler, div_binding]; +} +var LogFileComponent = class extends SvelteComponent { + constructor(options) { + super(); + init2(this, options, instance, create_fragment, safe_not_equal, { diff: 0, view: 1 }, add_css); + } +}; +var logFileComponent_default = LogFileComponent; + +// src/ui/history/components/logTreeComponent.svelte +init_polyfill_buffer(); +function add_css2(target) { + append_styles(target, "svelte-1lnl15d", "main.svelte-1lnl15d .nav-folder-title-content.svelte-1lnl15d{display:flex;align-items:center}"); +} +function get_each_context(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[8] = list[i]; + return child_ctx; +} +function create_else_block(ctx) { + let div4; + let div3; + let div0; + let t0; + let div1; + let t1; + let div2; + let t2_value = ( + /*entity*/ + ctx[8].title + "" + ); + let t2; + let div3_aria_label_value; + let t3; + let t4; + let current; + let mounted; + let dispose; + function click_handler() { + return ( + /*click_handler*/ + ctx[7]( + /*entity*/ + ctx[8] + ) + ); + } + let if_block = !/*closed*/ + ctx[4][ + /*entity*/ + ctx[8].title + ] && create_if_block_1(ctx); + return { + c() { + div4 = element("div"); + div3 = element("div"); + div0 = element("div"); + t0 = space(); + div1 = element("div"); + div1.innerHTML = ``; + t1 = space(); + div2 = element("div"); + t2 = text(t2_value); + t3 = space(); + if (if_block) + if_block.c(); + t4 = space(); + attr(div0, "data-icon", "folder"); + set_style(div0, "padding-right", "5px"); + set_style(div0, "display", "flex"); + attr(div1, "class", "tree-item-icon nav-folder-collapse-indicator collapse-icon"); + attr(div2, "class", "tree-item-inner nav-folder-title-content svelte-1lnl15d"); + attr(div3, "class", "tree-item-self is-clickable nav-folder-title"); + attr( + div3, + "aria-label-position", + /*side*/ + ctx[5] + ); + attr(div3, "aria-label", div3_aria_label_value = /*entity*/ + ctx[8].vaultPath); + attr(div4, "class", "tree-item nav-folder"); + toggle_class( + div4, + "is-collapsed", + /*closed*/ + ctx[4][ + /*entity*/ + ctx[8].title + ] + ); + }, + m(target, anchor) { + insert(target, div4, anchor); + append2(div4, div3); + append2(div3, div0); + append2(div3, t0); + append2(div3, div1); + append2(div3, t1); + append2(div3, div2); + append2(div2, t2); + append2(div4, t3); + if (if_block) + if_block.m(div4, null); + append2(div4, t4); + current = true; + if (!mounted) { + dispose = listen(div3, "click", click_handler); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + if ((!current || dirty & /*hierarchy*/ + 1) && t2_value !== (t2_value = /*entity*/ + ctx[8].title + "")) + set_data(t2, t2_value); + if (!current || dirty & /*side*/ + 32) { + attr( + div3, + "aria-label-position", + /*side*/ + ctx[5] + ); + } + if (!current || dirty & /*hierarchy*/ + 1 && div3_aria_label_value !== (div3_aria_label_value = /*entity*/ + ctx[8].vaultPath)) { + attr(div3, "aria-label", div3_aria_label_value); + } + if (!/*closed*/ + ctx[4][ + /*entity*/ + ctx[8].title + ]) { + if (if_block) { + if_block.p(ctx, dirty); + if (dirty & /*closed, hierarchy*/ + 17) { + transition_in(if_block, 1); + } + } else { + if_block = create_if_block_1(ctx); + if_block.c(); + transition_in(if_block, 1); + if_block.m(div4, t4); + } + } else if (if_block) { + group_outros(); + transition_out(if_block, 1, 1, () => { + if_block = null; + }); + check_outros(); + } + if (!current || dirty & /*closed, hierarchy*/ + 17) { + toggle_class( + div4, + "is-collapsed", + /*closed*/ + ctx[4][ + /*entity*/ + ctx[8].title + ] + ); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + current = true; + }, + o(local) { + transition_out(if_block); + current = false; + }, + d(detaching) { + if (detaching) + detach(div4); + if (if_block) + if_block.d(); + mounted = false; + dispose(); + } + }; +} +function create_if_block2(ctx) { + let div; + let logfilecomponent; + let t; + let current; + logfilecomponent = new logFileComponent_default({ + props: { + diff: ( + /*entity*/ + ctx[8].data + ), + view: ( + /*view*/ + ctx[2] + ) + } + }); + return { + c() { + div = element("div"); + create_component(logfilecomponent.$$.fragment); + t = space(); + }, + m(target, anchor) { + insert(target, div, anchor); + mount_component(logfilecomponent, div, null); + append2(div, t); + current = true; + }, + p(ctx2, dirty) { + const logfilecomponent_changes = {}; + if (dirty & /*hierarchy*/ + 1) + logfilecomponent_changes.diff = /*entity*/ + ctx2[8].data; + if (dirty & /*view*/ + 4) + logfilecomponent_changes.view = /*view*/ + ctx2[2]; + logfilecomponent.$set(logfilecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(logfilecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(logfilecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + if (detaching) + detach(div); + destroy_component(logfilecomponent); + } + }; +} +function create_if_block_1(ctx) { + let div; + let logtreecomponent; + let div_transition; + let current; + logtreecomponent = new LogTreeComponent({ + props: { + hierarchy: ( + /*entity*/ + ctx[8] + ), + plugin: ( + /*plugin*/ + ctx[1] + ), + view: ( + /*view*/ + ctx[2] + ) + } + }); + return { + c() { + div = element("div"); + create_component(logtreecomponent.$$.fragment); + attr(div, "class", "tree-item-children nav-folder-children"); + }, + m(target, anchor) { + insert(target, div, anchor); + mount_component(logtreecomponent, div, null); + current = true; + }, + p(ctx2, dirty) { + const logtreecomponent_changes = {}; + if (dirty & /*hierarchy*/ + 1) + logtreecomponent_changes.hierarchy = /*entity*/ + ctx2[8]; + if (dirty & /*plugin*/ + 2) + logtreecomponent_changes.plugin = /*plugin*/ + ctx2[1]; + if (dirty & /*view*/ + 4) + logtreecomponent_changes.view = /*view*/ + ctx2[2]; + logtreecomponent.$set(logtreecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(logtreecomponent.$$.fragment, local); + if (local) { + add_render_callback(() => { + if (!current) + return; + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, true); + div_transition.run(1); + }); + } + current = true; + }, + o(local) { + transition_out(logtreecomponent.$$.fragment, local); + if (local) { + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, false); + div_transition.run(0); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(div); + destroy_component(logtreecomponent); + if (detaching && div_transition) + div_transition.end(); + } + }; +} +function create_each_block(ctx) { + let current_block_type_index; + let if_block; + let if_block_anchor; + let current; + const if_block_creators = [create_if_block2, create_else_block]; + const if_blocks = []; + function select_block_type(ctx2, dirty) { + if ( + /*entity*/ + ctx2[8].data + ) + return 0; + return 1; + } + current_block_type_index = select_block_type(ctx, -1); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + return { + c() { + if_block.c(); + if_block_anchor = empty(); + }, + m(target, anchor) { + if_blocks[current_block_type_index].m(target, anchor); + insert(target, if_block_anchor, anchor); + current = true; + }, + p(ctx2, dirty) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type(ctx2, dirty); + if (current_block_type_index === previous_block_index) { + if_blocks[current_block_type_index].p(ctx2, dirty); + } else { + group_outros(); + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + check_outros(); + if_block = if_blocks[current_block_type_index]; + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); + if_block.c(); + } else { + if_block.p(ctx2, dirty); + } + transition_in(if_block, 1); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + current = true; + }, + o(local) { + transition_out(if_block); + current = false; + }, + d(detaching) { + if_blocks[current_block_type_index].d(detaching); + if (detaching) + detach(if_block_anchor); + } + }; +} +function create_fragment2(ctx) { + let main; + let current; + let each_value = ( + /*hierarchy*/ + ctx[0].children + ); + let each_blocks = []; + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i)); + } + const out = (i) => transition_out(each_blocks[i], 1, 1, () => { + each_blocks[i] = null; + }); + return { + c() { + main = element("main"); + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + attr(main, "class", "svelte-1lnl15d"); + toggle_class( + main, + "topLevel", + /*topLevel*/ + ctx[3] + ); + }, + m(target, anchor) { + insert(target, main, anchor); + for (let i = 0; i < each_blocks.length; i += 1) { + if (each_blocks[i]) { + each_blocks[i].m(main, null); + } + } + current = true; + }, + p(ctx2, [dirty]) { + if (dirty & /*hierarchy, view, closed, plugin, side, fold*/ + 119) { + each_value = /*hierarchy*/ + ctx2[0].children; + let i; + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context(ctx2, each_value, i); + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + transition_in(each_blocks[i], 1); + } else { + each_blocks[i] = create_each_block(child_ctx); + each_blocks[i].c(); + transition_in(each_blocks[i], 1); + each_blocks[i].m(main, null); + } + } + group_outros(); + for (i = each_value.length; i < each_blocks.length; i += 1) { + out(i); + } + check_outros(); + } + if (!current || dirty & /*topLevel*/ + 8) { + toggle_class( + main, + "topLevel", + /*topLevel*/ + ctx2[3] + ); + } + }, + i(local) { + if (current) + return; + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + current = true; + }, + o(local) { + each_blocks = each_blocks.filter(Boolean); + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(main); + destroy_each(each_blocks, detaching); + } + }; +} +function instance2($$self, $$props, $$invalidate) { + let side; + let { hierarchy } = $$props; + let { plugin } = $$props; + let { view } = $$props; + let { topLevel = false } = $$props; + const closed = {}; + function fold(item) { + $$invalidate(4, closed[item.title] = !closed[item.title], closed); + } + const click_handler = (entity) => fold(entity); + $$self.$$set = ($$props2) => { + if ("hierarchy" in $$props2) + $$invalidate(0, hierarchy = $$props2.hierarchy); + if ("plugin" in $$props2) + $$invalidate(1, plugin = $$props2.plugin); + if ("view" in $$props2) + $$invalidate(2, view = $$props2.view); + if ("topLevel" in $$props2) + $$invalidate(3, topLevel = $$props2.topLevel); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty & /*view*/ + 4) { + $: + $$invalidate(5, side = view.leaf.getRoot().side == "left" ? "right" : "left"); + } + }; + return [hierarchy, plugin, view, topLevel, closed, side, fold, click_handler]; +} +var LogTreeComponent = class extends SvelteComponent { + constructor(options) { + super(); + init2( + this, + options, + instance2, + create_fragment2, + safe_not_equal, + { + hierarchy: 0, + plugin: 1, + view: 2, + topLevel: 3 + }, + add_css2 + ); + } +}; +var logTreeComponent_default = LogTreeComponent; + +// src/ui/history/components/logComponent.svelte +function add_css3(target) { + append_styles(target, "svelte-1t6egnt", ".git-ref.svelte-1t6egnt{color:var(--text-accent)}"); +} +function get_each_context2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[8] = list[i]; + return child_ctx; +} +function create_if_block_2(ctx) { + let div; + let t_value = ( + /*log*/ + ctx[0].refs.join(", ") + "" + ); + let t; + return { + c() { + div = element("div"); + t = text(t_value); + attr(div, "class", "git-ref svelte-1t6egnt"); + }, + m(target, anchor) { + insert(target, div, anchor); + append2(div, t); + }, + p(ctx2, dirty) { + if (dirty & /*log*/ + 1 && t_value !== (t_value = /*log*/ + ctx2[0].refs.join(", ") + "")) + set_data(t, t_value); + }, + d(detaching) { + if (detaching) + detach(div); + } + }; +} +function create_if_block3(ctx) { + let div; + let current_block_type_index; + let if_block; + let div_transition; + let current; + const if_block_creators = [create_if_block_12, create_else_block2]; + const if_blocks = []; + function select_block_type(ctx2, dirty) { + if ( + /*showTree*/ + ctx2[2] + ) + return 0; + return 1; + } + current_block_type_index = select_block_type(ctx, -1); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + return { + c() { + div = element("div"); + if_block.c(); + attr(div, "class", "tree-item-children nav-folder-children"); + }, + m(target, anchor) { + insert(target, div, anchor); + if_blocks[current_block_type_index].m(div, null); + current = true; + }, + p(ctx2, dirty) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type(ctx2, dirty); + if (current_block_type_index === previous_block_index) { + if_blocks[current_block_type_index].p(ctx2, dirty); + } else { + group_outros(); + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + check_outros(); + if_block = if_blocks[current_block_type_index]; + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); + if_block.c(); + } else { + if_block.p(ctx2, dirty); + } + transition_in(if_block, 1); + if_block.m(div, null); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + if (local) { + add_render_callback(() => { + if (!current) + return; + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, true); + div_transition.run(1); + }); + } + current = true; + }, + o(local) { + transition_out(if_block); + if (local) { + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, false); + div_transition.run(0); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(div); + if_blocks[current_block_type_index].d(); + if (detaching && div_transition) + div_transition.end(); + } + }; +} +function create_else_block2(ctx) { + let each_1_anchor; + let current; + let each_value = ( + /*log*/ + ctx[0].diff.files + ); + let each_blocks = []; + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block2(get_each_context2(ctx, each_value, i)); + } + const out = (i) => transition_out(each_blocks[i], 1, 1, () => { + each_blocks[i] = null; + }); + return { + c() { + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + each_1_anchor = empty(); + }, + m(target, anchor) { + for (let i = 0; i < each_blocks.length; i += 1) { + if (each_blocks[i]) { + each_blocks[i].m(target, anchor); + } + } + insert(target, each_1_anchor, anchor); + current = true; + }, + p(ctx2, dirty) { + if (dirty & /*view, log*/ + 3) { + each_value = /*log*/ + ctx2[0].diff.files; + let i; + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context2(ctx2, each_value, i); + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + transition_in(each_blocks[i], 1); + } else { + each_blocks[i] = create_each_block2(child_ctx); + each_blocks[i].c(); + transition_in(each_blocks[i], 1); + each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor); + } + } + group_outros(); + for (i = each_value.length; i < each_blocks.length; i += 1) { + out(i); + } + check_outros(); + } + }, + i(local) { + if (current) + return; + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + current = true; + }, + o(local) { + each_blocks = each_blocks.filter(Boolean); + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + current = false; + }, + d(detaching) { + destroy_each(each_blocks, detaching); + if (detaching) + detach(each_1_anchor); + } + }; +} +function create_if_block_12(ctx) { + let logtreecomponent; + let current; + logtreecomponent = new logTreeComponent_default({ + props: { + hierarchy: ( + /*logsHierarchy*/ + ctx[6] + ), + plugin: ( + /*plugin*/ + ctx[3] + ), + view: ( + /*view*/ + ctx[1] + ), + topLevel: true + } + }); + return { + c() { + create_component(logtreecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(logtreecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const logtreecomponent_changes = {}; + if (dirty & /*logsHierarchy*/ + 64) + logtreecomponent_changes.hierarchy = /*logsHierarchy*/ + ctx2[6]; + if (dirty & /*plugin*/ + 8) + logtreecomponent_changes.plugin = /*plugin*/ + ctx2[3]; + if (dirty & /*view*/ + 2) + logtreecomponent_changes.view = /*view*/ + ctx2[1]; + logtreecomponent.$set(logtreecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(logtreecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(logtreecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(logtreecomponent, detaching); + } + }; +} +function create_each_block2(ctx) { + let logfilecomponent; + let current; + logfilecomponent = new logFileComponent_default({ + props: { + view: ( + /*view*/ + ctx[1] + ), + diff: ( + /*file*/ + ctx[8] + ) + } + }); + return { + c() { + create_component(logfilecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(logfilecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const logfilecomponent_changes = {}; + if (dirty & /*view*/ + 2) + logfilecomponent_changes.view = /*view*/ + ctx2[1]; + if (dirty & /*log*/ + 1) + logfilecomponent_changes.diff = /*file*/ + ctx2[8]; + logfilecomponent.$set(logfilecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(logfilecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(logfilecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(logfilecomponent, detaching); + } + }; +} +function create_fragment3(ctx) { + let main; + let div4; + let div3; + let div0; + let t0; + let div2; + let t1; + let div1; + let t2_value = ( + /*log*/ + ctx[0].message + "" + ); + let t2; + let div1_aria_label_value; + let t3; + let current; + let mounted; + let dispose; + let if_block0 = ( + /*log*/ + ctx[0].refs.length > 0 && create_if_block_2(ctx) + ); + let if_block1 = !/*isCollapsed*/ + ctx[4] && create_if_block3(ctx); + return { + c() { + main = element("main"); + div4 = element("div"); + div3 = element("div"); + div0 = element("div"); + div0.innerHTML = ``; + t0 = space(); + div2 = element("div"); + if (if_block0) + if_block0.c(); + t1 = space(); + div1 = element("div"); + t2 = text(t2_value); + t3 = space(); + if (if_block1) + if_block1.c(); + attr(div0, "class", "tree-item-icon nav-folder-collapse-indicator collapse-icon"); + attr(div1, "class", "tree-item-inner nav-folder-title-content"); + attr(div1, "aria-label", div1_aria_label_value = /*log*/ + ctx[0].message); + attr( + div1, + "aria-label-position", + /*side*/ + ctx[5] + ); + attr(div3, "class", "tree-item-self is-clickable nav-folder-title"); + attr(div4, "class", "tree-item nav-folder"); + toggle_class( + div4, + "is-collapsed", + /*isCollapsed*/ + ctx[4] + ); + }, + m(target, anchor) { + insert(target, main, anchor); + append2(main, div4); + append2(div4, div3); + append2(div3, div0); + append2(div3, t0); + append2(div3, div2); + if (if_block0) + if_block0.m(div2, null); + append2(div2, t1); + append2(div2, div1); + append2(div1, t2); + append2(div4, t3); + if (if_block1) + if_block1.m(div4, null); + current = true; + if (!mounted) { + dispose = listen( + div3, + "click", + /*click_handler*/ + ctx[7] + ); + mounted = true; + } + }, + p(ctx2, [dirty]) { + if ( + /*log*/ + ctx2[0].refs.length > 0 + ) { + if (if_block0) { + if_block0.p(ctx2, dirty); + } else { + if_block0 = create_if_block_2(ctx2); + if_block0.c(); + if_block0.m(div2, t1); + } + } else if (if_block0) { + if_block0.d(1); + if_block0 = null; + } + if ((!current || dirty & /*log*/ + 1) && t2_value !== (t2_value = /*log*/ + ctx2[0].message + "")) + set_data(t2, t2_value); + if (!current || dirty & /*log*/ + 1 && div1_aria_label_value !== (div1_aria_label_value = /*log*/ + ctx2[0].message)) { + attr(div1, "aria-label", div1_aria_label_value); + } + if (!current || dirty & /*side*/ + 32) { + attr( + div1, + "aria-label-position", + /*side*/ + ctx2[5] + ); + } + if (!/*isCollapsed*/ + ctx2[4]) { + if (if_block1) { + if_block1.p(ctx2, dirty); + if (dirty & /*isCollapsed*/ + 16) { + transition_in(if_block1, 1); + } + } else { + if_block1 = create_if_block3(ctx2); + if_block1.c(); + transition_in(if_block1, 1); + if_block1.m(div4, null); + } + } else if (if_block1) { + group_outros(); + transition_out(if_block1, 1, 1, () => { + if_block1 = null; + }); + check_outros(); + } + if (!current || dirty & /*isCollapsed*/ + 16) { + toggle_class( + div4, + "is-collapsed", + /*isCollapsed*/ + ctx2[4] + ); + } + }, + i(local) { + if (current) + return; + transition_in(if_block1); + current = true; + }, + o(local) { + transition_out(if_block1); + current = false; + }, + d(detaching) { + if (detaching) + detach(main); + if (if_block0) + if_block0.d(); + if (if_block1) + if_block1.d(); + mounted = false; + dispose(); + } + }; +} +function instance3($$self, $$props, $$invalidate) { + let logsHierarchy; + let side; + let { log: log2 } = $$props; + let { view } = $$props; + let { showTree } = $$props; + let { plugin } = $$props; + let isCollapsed = true; + const click_handler = () => $$invalidate(4, isCollapsed = !isCollapsed); + $$self.$$set = ($$props2) => { + if ("log" in $$props2) + $$invalidate(0, log2 = $$props2.log); + if ("view" in $$props2) + $$invalidate(1, view = $$props2.view); + if ("showTree" in $$props2) + $$invalidate(2, showTree = $$props2.showTree); + if ("plugin" in $$props2) + $$invalidate(3, plugin = $$props2.plugin); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty & /*plugin, log*/ + 9) { + $: + $$invalidate(6, logsHierarchy = { + title: "", + path: "", + vaultPath: "", + children: plugin.gitManager.getTreeStructure(log2.diff.files) + }); + } + if ($$self.$$.dirty & /*view*/ + 2) { + $: + $$invalidate(5, side = view.leaf.getRoot().side == "left" ? "right" : "left"); + } + }; + return [log2, view, showTree, plugin, isCollapsed, side, logsHierarchy, click_handler]; +} +var LogComponent = class extends SvelteComponent { + constructor(options) { + super(); + init2(this, options, instance3, create_fragment3, safe_not_equal, { log: 0, view: 1, showTree: 2, plugin: 3 }, add_css3); + } +}; +var logComponent_default = LogComponent; + +// src/ui/history/historyView.svelte +function get_each_context3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[11] = list[i]; + return child_ctx; +} +function create_if_block4(ctx) { + let div1; + let div0; + let current; + let each_value = ( + /*logs*/ + ctx[6] + ); + let each_blocks = []; + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block3(get_each_context3(ctx, each_value, i)); + } + const out = (i) => transition_out(each_blocks[i], 1, 1, () => { + each_blocks[i] = null; + }); + return { + c() { + div1 = element("div"); + div0 = element("div"); + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + attr(div0, "class", "tree-item-children nav-folder-children"); + attr(div1, "class", "tree-item nav-folder mod-root"); + }, + m(target, anchor) { + insert(target, div1, anchor); + append2(div1, div0); + for (let i = 0; i < each_blocks.length; i += 1) { + if (each_blocks[i]) { + each_blocks[i].m(div0, null); + } + } + current = true; + }, + p(ctx2, dirty) { + if (dirty & /*view, showTree, logs, plugin*/ + 71) { + each_value = /*logs*/ + ctx2[6]; + let i; + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context3(ctx2, each_value, i); + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + transition_in(each_blocks[i], 1); + } else { + each_blocks[i] = create_each_block3(child_ctx); + each_blocks[i].c(); + transition_in(each_blocks[i], 1); + each_blocks[i].m(div0, null); + } + } + group_outros(); + for (i = each_value.length; i < each_blocks.length; i += 1) { + out(i); + } + check_outros(); + } + }, + i(local) { + if (current) + return; + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + current = true; + }, + o(local) { + each_blocks = each_blocks.filter(Boolean); + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(div1); + destroy_each(each_blocks, detaching); + } + }; +} +function create_each_block3(ctx) { + let logcomponent; + let current; + logcomponent = new logComponent_default({ + props: { + view: ( + /*view*/ + ctx[1] + ), + showTree: ( + /*showTree*/ + ctx[2] + ), + log: ( + /*log*/ + ctx[11] + ), + plugin: ( + /*plugin*/ + ctx[0] + ) + } + }); + return { + c() { + create_component(logcomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(logcomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const logcomponent_changes = {}; + if (dirty & /*view*/ + 2) + logcomponent_changes.view = /*view*/ + ctx2[1]; + if (dirty & /*showTree*/ + 4) + logcomponent_changes.showTree = /*showTree*/ + ctx2[2]; + if (dirty & /*logs*/ + 64) + logcomponent_changes.log = /*log*/ + ctx2[11]; + if (dirty & /*plugin*/ + 1) + logcomponent_changes.plugin = /*plugin*/ + ctx2[0]; + logcomponent.$set(logcomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(logcomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(logcomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(logcomponent, detaching); + } + }; +} +function create_fragment4(ctx) { + let main; + let div3; + let div2; + let div0; + let t0; + let div1; + let t1; + let div4; + let current; + let mounted; + let dispose; + let if_block = ( + /*logs*/ + ctx[6] && create_if_block4(ctx) + ); + return { + c() { + main = element("main"); + div3 = element("div"); + div2 = element("div"); + div0 = element("div"); + t0 = space(); + div1 = element("div"); + t1 = space(); + div4 = element("div"); + if (if_block) + if_block.c(); + attr(div0, "id", "layoutChange"); + attr(div0, "class", "clickable-icon nav-action-button"); + attr(div0, "aria-label", "Change Layout"); + attr(div1, "id", "refresh"); + attr(div1, "class", "clickable-icon nav-action-button"); + attr(div1, "data-icon", "refresh-cw"); + attr(div1, "aria-label", "Refresh"); + set_style(div1, "margin", "1px"); + toggle_class( + div1, + "loading", + /*loading*/ + ctx[4] + ); + attr(div2, "class", "nav-buttons-container"); + attr(div3, "class", "nav-header"); + attr(div4, "class", "nav-files-container"); + set_style(div4, "position", "relative"); + }, + m(target, anchor) { + insert(target, main, anchor); + append2(main, div3); + append2(div3, div2); + append2(div2, div0); + ctx[7](div0); + append2(div2, t0); + append2(div2, div1); + ctx[9](div1); + append2(main, t1); + append2(main, div4); + if (if_block) + if_block.m(div4, null); + current = true; + if (!mounted) { + dispose = [ + listen( + div0, + "click", + /*click_handler*/ + ctx[8] + ), + listen(div1, "click", triggerRefresh) + ]; + mounted = true; + } + }, + p(ctx2, [dirty]) { + if (!current || dirty & /*loading*/ + 16) { + toggle_class( + div1, + "loading", + /*loading*/ + ctx2[4] + ); + } + if ( + /*logs*/ + ctx2[6] + ) { + if (if_block) { + if_block.p(ctx2, dirty); + if (dirty & /*logs*/ + 64) { + transition_in(if_block, 1); + } + } else { + if_block = create_if_block4(ctx2); + if_block.c(); + transition_in(if_block, 1); + if_block.m(div4, null); + } + } else if (if_block) { + group_outros(); + transition_out(if_block, 1, 1, () => { + if_block = null; + }); + check_outros(); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + current = true; + }, + o(local) { + transition_out(if_block); + current = false; + }, + d(detaching) { + if (detaching) + detach(main); + ctx[7](null); + ctx[9](null); + if (if_block) + if_block.d(); + mounted = false; + run_all(dispose); + } + }; +} +function triggerRefresh() { + dispatchEvent(new CustomEvent("git-refresh")); +} +function instance4($$self, $$props, $$invalidate) { + let { plugin } = $$props; + let { view } = $$props; + let loading; + let buttons = []; + let logs; + let showTree = plugin.settings.treeStructure; + let layoutBtn; + addEventListener("git-view-refresh", refresh); + plugin.app.workspace.onLayoutReady(() => { + window.setTimeout( + () => { + buttons.forEach((btn) => (0, import_obsidian19.setIcon)(btn, btn.getAttr("data-icon"), 16)); + (0, import_obsidian19.setIcon)(layoutBtn, showTree ? "list" : "folder", 16); + }, + 0 + ); + }); + onDestroy(() => { + removeEventListener("git-view-refresh", refresh); + }); + function refresh() { + return __awaiter(this, void 0, void 0, function* () { + $$invalidate(4, loading = true); + const isSimpleGit = plugin.gitManager instanceof SimpleGit; + $$invalidate(6, logs = yield plugin.gitManager.log(void 0, false, isSimpleGit ? 50 : 10)); + $$invalidate(4, loading = false); + }); + } + function div0_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + layoutBtn = $$value; + $$invalidate(3, layoutBtn); + }); + } + const click_handler = () => { + $$invalidate(2, showTree = !showTree); + $$invalidate(0, plugin.settings.treeStructure = showTree, plugin); + plugin.saveSettings(); + }; + function div1_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[6] = $$value; + $$invalidate(5, buttons); + }); + } + $$self.$$set = ($$props2) => { + if ("plugin" in $$props2) + $$invalidate(0, plugin = $$props2.plugin); + if ("view" in $$props2) + $$invalidate(1, view = $$props2.view); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty & /*layoutBtn, showTree*/ + 12) { + $: { + if (layoutBtn) { + layoutBtn.empty(); + (0, import_obsidian19.setIcon)(layoutBtn, showTree ? "list" : "folder", 16); + } + } + } + }; + return [ + plugin, + view, + showTree, + layoutBtn, + loading, + buttons, + logs, + div0_binding, + click_handler, + div1_binding + ]; +} +var HistoryView = class extends SvelteComponent { + constructor(options) { + super(); + init2(this, options, instance4, create_fragment4, safe_not_equal, { plugin: 0, view: 1 }); + } +}; +var historyView_default = HistoryView; + +// src/ui/history/historyView.ts +var HistoryView2 = class extends import_obsidian20.ItemView { + constructor(leaf, plugin) { + super(leaf); + this.plugin = plugin; + this.hoverPopover = null; + } + getViewType() { + return HISTORY_VIEW_CONFIG.type; + } + getDisplayText() { + return HISTORY_VIEW_CONFIG.name; + } + getIcon() { + return HISTORY_VIEW_CONFIG.icon; + } + onClose() { + return super.onClose(); + } + onOpen() { + this._view = new historyView_default({ + target: this.contentEl, + props: { + plugin: this.plugin, + view: this + } + }); + return super.onOpen(); + } +}; + +// src/ui/modals/branchModal.ts +init_polyfill_buffer(); +var import_obsidian21 = require("obsidian"); +var BranchModal = class extends import_obsidian21.FuzzySuggestModal { + constructor(branches) { + super(app); + this.branches = branches; + this.setPlaceholder("Select branch to checkout"); + } + getItems() { + return this.branches; + } + getItemText(item) { + return item; + } + onChooseItem(item, evt) { + this.resolve(item); + } + open() { + super.open(); + return new Promise((resolve) => { + this.resolve = resolve; + }); + } + async onClose() { + await new Promise((resolve) => setTimeout(resolve, 10)); + if (this.resolve) + this.resolve(void 0); + } +}; + +// src/ui/modals/ignoreModal.ts +init_polyfill_buffer(); +var import_obsidian22 = require("obsidian"); +var IgnoreModal = class extends import_obsidian22.Modal { + constructor(app2, content) { + super(app2); + this.content = content; + this.resolve = null; + } + open() { + super.open(); + return new Promise((resolve) => { + this.resolve = resolve; + }); + } + onOpen() { + const { contentEl, titleEl } = this; + titleEl.setText("Edit .gitignore"); + const div = contentEl.createDiv(); + const text2 = div.createEl("textarea", { + text: this.content, + cls: ["obsidian-git-textarea"], + attr: { rows: 10, cols: 30, wrap: "off" } + }); + div.createEl("button", { + cls: ["mod-cta", "obsidian-git-center-button"], + text: "Save" + }).addEventListener("click", async () => { + this.resolve(text2.value); + this.close(); + }); + } + onClose() { + const { contentEl } = this; + this.resolve(void 0); + contentEl.empty(); + } +}; + +// src/ui/sourceControl/sourceControl.ts +init_polyfill_buffer(); +var import_obsidian29 = require("obsidian"); + +// src/ui/sourceControl/sourceControl.svelte +init_polyfill_buffer(); +var import_obsidian28 = require("obsidian"); + +// src/ui/modals/discardModal.ts +init_polyfill_buffer(); +var import_obsidian23 = require("obsidian"); +var DiscardModal = class extends import_obsidian23.Modal { + constructor(app2, deletion, filename) { + super(app2); + this.deletion = deletion; + this.filename = filename; + this.resolve = null; + } + myOpen() { + this.open(); + return new Promise((resolve) => { + this.resolve = resolve; + }); + } + onOpen() { + const { contentEl, titleEl } = this; + titleEl.setText(`${this.deletion ? "Delete" : "Discard"} this file?`); + contentEl.createEl("p").setText( + `Do you really want to ${this.deletion ? "delete" : "discard the changes of"} "${this.filename}"` + ); + const div = contentEl.createDiv({ cls: "modal-button-container" }); + const discard = div.createEl("button", { + cls: "mod-warning", + text: this.deletion ? "Delete" : "Discard" + }); + discard.addEventListener("click", async () => { + if (this.resolve) + this.resolve(true); + this.close(); + }); + discard.addEventListener("keypress", async () => { + if (this.resolve) + this.resolve(true); + this.close(); + }); + const close = div.createEl("button", { + text: "Cancel" + }); + close.addEventListener("click", () => { + if (this.resolve) + this.resolve(false); + return this.close(); + }); + close.addEventListener("keypress", () => { + if (this.resolve) + this.resolve(false); + return this.close(); + }); + } + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +}; + +// src/ui/sourceControl/components/fileComponent.svelte +init_polyfill_buffer(); +var import_obsidian25 = require("obsidian"); + +// node_modules/.pnpm/obsidian-community-lib@2.0.2_fbkkrmn4giwwsr5htt45gr2jni/node_modules/obsidian-community-lib/dist/index.js +init_polyfill_buffer(); + +// node_modules/.pnpm/obsidian-community-lib@2.0.2_fbkkrmn4giwwsr5htt45gr2jni/node_modules/obsidian-community-lib/dist/utils.js +init_polyfill_buffer(); +var feather = __toESM(require_feather()); +var import_obsidian24 = require("obsidian"); +function hoverPreview(event, view, to) { + const targetEl = event.target; + app.workspace.trigger("hover-link", { + event, + source: view.getViewType(), + hoverParent: view, + targetEl, + linktext: to + }); +} + +// src/ui/sourceControl/components/fileComponent.svelte +function add_css4(target) { + append_styles(target, "svelte-pmbo0n", "main.svelte-pmbo0n .nav-file-title-content.svelte-pmbo0n{display:flex;align-items:center}"); +} +function create_if_block5(ctx) { + let div; + let mounted; + let dispose; + return { + c() { + div = element("div"); + attr(div, "data-icon", "go-to-file"); + attr(div, "aria-label", "Open File"); + attr(div, "class", "clickable-icon"); + }, + m(target, anchor) { + insert(target, div, anchor); + ctx[11](div); + if (!mounted) { + dispose = [ + listen(div, "auxclick", stop_propagation( + /*open*/ + ctx[5] + )), + listen(div, "click", stop_propagation( + /*open*/ + ctx[5] + )) + ]; + mounted = true; + } + }, + p: noop, + d(detaching) { + if (detaching) + detach(div); + ctx[11](null); + mounted = false; + run_all(dispose); + } + }; +} +function create_fragment5(ctx) { + let main; + let div6; + let div0; + let t0_value = getDisplayPath( + /*change*/ + ctx[0].vault_path + ) + ""; + let t0; + let t1; + let div5; + let div3; + let show_if = ( + /*view*/ + ctx[1].app.vault.getAbstractFileByPath( + /*change*/ + ctx[0].vault_path + ) + ); + let t2; + let div1; + let t3; + let div2; + let t4; + let div4; + let t5_value = ( + /*change*/ + ctx[0].working_dir + "" + ); + let t5; + let div4_data_type_value; + let div6_aria_label_value; + let mounted; + let dispose; + let if_block = show_if && create_if_block5(ctx); + return { + c() { + main = element("main"); + div6 = element("div"); + div0 = element("div"); + t0 = text(t0_value); + t1 = space(); + div5 = element("div"); + div3 = element("div"); + if (if_block) + if_block.c(); + t2 = space(); + div1 = element("div"); + t3 = space(); + div2 = element("div"); + t4 = space(); + div4 = element("div"); + t5 = text(t5_value); + attr(div0, "class", "tree-item-inner nav-file-title-content svelte-pmbo0n"); + attr(div1, "data-icon", "undo"); + attr(div1, "aria-label", "Discard"); + attr(div1, "class", "clickable-icon"); + attr(div2, "data-icon", "plus"); + attr(div2, "aria-label", "Stage"); + attr(div2, "class", "clickable-icon"); + attr(div3, "class", "buttons"); + attr(div4, "class", "type"); + attr(div4, "data-type", div4_data_type_value = /*change*/ + ctx[0].working_dir); + attr(div5, "class", "git-tools"); + attr(div6, "class", "tree-item-self is-clickable nav-file-title"); + attr( + div6, + "aria-label-position", + /*side*/ + ctx[3] + ); + attr(div6, "aria-label", div6_aria_label_value = /*change*/ + ctx[0].vault_path); + attr(main, "class", "tree-item nav-file svelte-pmbo0n"); + }, + m(target, anchor) { + insert(target, main, anchor); + append2(main, div6); + append2(div6, div0); + append2(div0, t0); + append2(div6, t1); + append2(div6, div5); + append2(div5, div3); + if (if_block) + if_block.m(div3, null); + append2(div3, t2); + append2(div3, div1); + ctx[12](div1); + append2(div3, t3); + append2(div3, div2); + ctx[13](div2); + append2(div5, t4); + append2(div5, div4); + append2(div4, t5); + if (!mounted) { + dispose = [ + listen(div1, "click", stop_propagation( + /*discard*/ + ctx[8] + )), + listen(div2, "click", stop_propagation( + /*stage*/ + ctx[6] + )), + listen( + main, + "mouseover", + /*hover*/ + ctx[4] + ), + listen(main, "click", stop_propagation( + /*showDiff*/ + ctx[7] + )), + listen(main, "auxclick", stop_propagation( + /*showDiff*/ + ctx[7] + )), + listen( + main, + "focus", + /*focus_handler*/ + ctx[10] + ) + ]; + mounted = true; + } + }, + p(ctx2, [dirty]) { + if (dirty & /*change*/ + 1 && t0_value !== (t0_value = getDisplayPath( + /*change*/ + ctx2[0].vault_path + ) + "")) + set_data(t0, t0_value); + if (dirty & /*view, change*/ + 3) + show_if = /*view*/ + ctx2[1].app.vault.getAbstractFileByPath( + /*change*/ + ctx2[0].vault_path + ); + if (show_if) { + if (if_block) { + if_block.p(ctx2, dirty); + } else { + if_block = create_if_block5(ctx2); + if_block.c(); + if_block.m(div3, t2); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } + if (dirty & /*change*/ + 1 && t5_value !== (t5_value = /*change*/ + ctx2[0].working_dir + "")) + set_data(t5, t5_value); + if (dirty & /*change*/ + 1 && div4_data_type_value !== (div4_data_type_value = /*change*/ + ctx2[0].working_dir)) { + attr(div4, "data-type", div4_data_type_value); + } + if (dirty & /*side*/ + 8) { + attr( + div6, + "aria-label-position", + /*side*/ + ctx2[3] + ); + } + if (dirty & /*change*/ + 1 && div6_aria_label_value !== (div6_aria_label_value = /*change*/ + ctx2[0].vault_path)) { + attr(div6, "aria-label", div6_aria_label_value); + } + }, + i: noop, + o: noop, + d(detaching) { + if (detaching) + detach(main); + if (if_block) + if_block.d(); + ctx[12](null); + ctx[13](null); + mounted = false; + run_all(dispose); + } + }; +} +function instance5($$self, $$props, $$invalidate) { + let side; + let { change } = $$props; + let { view } = $$props; + let { manager } = $$props; + let buttons = []; + window.setTimeout(() => buttons.forEach((b) => (0, import_obsidian25.setIcon)(b, b.getAttr("data-icon"))), 0); + function hover(event) { + if (app.vault.getAbstractFileByPath(change.vault_path)) { + hoverPreview(event, view, change.vault_path); + } + } + function open(event) { + var _a2; + const file = view.app.vault.getAbstractFileByPath(change.vault_path); + console.log(event); + if (file instanceof import_obsidian25.TFile) { + (_a2 = getNewLeaf(event)) === null || _a2 === void 0 ? void 0 : _a2.openFile(file); + } + } + function stage() { + manager.stage(change.path, false).finally(() => { + dispatchEvent(new CustomEvent("git-refresh")); + }); + } + function showDiff(event) { + var _a2; + (_a2 = getNewLeaf(event)) === null || _a2 === void 0 ? void 0 : _a2.setViewState({ + type: DIFF_VIEW_CONFIG.type, + active: true, + state: { file: change.path, staged: false } + }); + } + function discard() { + const deleteFile = change.working_dir == "U"; + new DiscardModal(view.app, deleteFile, change.vault_path).myOpen().then((shouldDiscard) => { + if (shouldDiscard === true) { + if (deleteFile) { + view.app.vault.adapter.remove(change.vault_path).finally(() => { + dispatchEvent(new CustomEvent("git-refresh")); + }); + } else { + manager.discard(change.path).finally(() => { + dispatchEvent(new CustomEvent("git-refresh")); + }); + } + } + }); + } + function focus_handler(event) { + bubble.call(this, $$self, event); + } + function div_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[1] = $$value; + $$invalidate(2, buttons); + }); + } + function div1_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[0] = $$value; + $$invalidate(2, buttons); + }); + } + function div2_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[2] = $$value; + $$invalidate(2, buttons); + }); + } + $$self.$$set = ($$props2) => { + if ("change" in $$props2) + $$invalidate(0, change = $$props2.change); + if ("view" in $$props2) + $$invalidate(1, view = $$props2.view); + if ("manager" in $$props2) + $$invalidate(9, manager = $$props2.manager); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty & /*view*/ + 2) { + $: + $$invalidate(3, side = view.leaf.getRoot().side == "left" ? "right" : "left"); + } + }; + return [ + change, + view, + buttons, + side, + hover, + open, + stage, + showDiff, + discard, + manager, + focus_handler, + div_binding, + div1_binding, + div2_binding + ]; +} +var FileComponent = class extends SvelteComponent { + constructor(options) { + super(); + init2(this, options, instance5, create_fragment5, safe_not_equal, { change: 0, view: 1, manager: 9 }, add_css4); + } +}; +var fileComponent_default = FileComponent; + +// src/ui/sourceControl/components/pulledFileComponent.svelte +init_polyfill_buffer(); +var import_obsidian26 = require("obsidian"); +function add_css5(target) { + append_styles(target, "svelte-pmbo0n", "main.svelte-pmbo0n .nav-file-title-content.svelte-pmbo0n{display:flex;align-items:center}"); +} +function create_fragment6(ctx) { + let main; + let div2; + let div0; + let t0_value = getDisplayPath( + /*change*/ + ctx[0].vault_path + ) + ""; + let t0; + let t1; + let div1; + let span; + let t2_value = ( + /*change*/ + ctx[0].working_dir + "" + ); + let t2; + let span_data_type_value; + let div2_aria_label_value; + let mounted; + let dispose; + return { + c() { + main = element("main"); + div2 = element("div"); + div0 = element("div"); + t0 = text(t0_value); + t1 = space(); + div1 = element("div"); + span = element("span"); + t2 = text(t2_value); + attr(div0, "class", "tree-item-inner nav-file-title-content svelte-pmbo0n"); + attr(span, "class", "type"); + attr(span, "data-type", span_data_type_value = /*change*/ + ctx[0].working_dir); + attr(div1, "class", "git-tools"); + attr(div2, "class", "tree-item-self is-clickable nav-file-title"); + attr( + div2, + "aria-label-position", + /*side*/ + ctx[1] + ); + attr(div2, "aria-label", div2_aria_label_value = /*change*/ + ctx[0].vault_path); + attr(main, "class", "tree-item nav-file svelte-pmbo0n"); + }, + m(target, anchor) { + insert(target, main, anchor); + append2(main, div2); + append2(div2, div0); + append2(div0, t0); + append2(div2, t1); + append2(div2, div1); + append2(div1, span); + append2(span, t2); + if (!mounted) { + dispose = [ + listen( + main, + "mouseover", + /*hover*/ + ctx[2] + ), + listen(main, "click", stop_propagation( + /*open*/ + ctx[3] + )), + listen(main, "auxclick", stop_propagation( + /*open*/ + ctx[3] + )), + listen( + main, + "focus", + /*focus_handler*/ + ctx[5] + ) + ]; + mounted = true; + } + }, + p(ctx2, [dirty]) { + if (dirty & /*change*/ + 1 && t0_value !== (t0_value = getDisplayPath( + /*change*/ + ctx2[0].vault_path + ) + "")) + set_data(t0, t0_value); + if (dirty & /*change*/ + 1 && t2_value !== (t2_value = /*change*/ + ctx2[0].working_dir + "")) + set_data(t2, t2_value); + if (dirty & /*change*/ + 1 && span_data_type_value !== (span_data_type_value = /*change*/ + ctx2[0].working_dir)) { + attr(span, "data-type", span_data_type_value); + } + if (dirty & /*side*/ + 2) { + attr( + div2, + "aria-label-position", + /*side*/ + ctx2[1] + ); + } + if (dirty & /*change*/ + 1 && div2_aria_label_value !== (div2_aria_label_value = /*change*/ + ctx2[0].vault_path)) { + attr(div2, "aria-label", div2_aria_label_value); + } + }, + i: noop, + o: noop, + d(detaching) { + if (detaching) + detach(main); + mounted = false; + run_all(dispose); + } + }; +} +function instance6($$self, $$props, $$invalidate) { + let side; + let { change } = $$props; + let { view } = $$props; + function hover(event) { + if (app.vault.getAbstractFileByPath(change.vault_path)) { + hoverPreview(event, view, change.vault_path); + } + } + function open(event) { + var _a2; + const file = view.app.vault.getAbstractFileByPath(change.vault_path); + if (file instanceof import_obsidian26.TFile) { + (_a2 = getNewLeaf(event)) === null || _a2 === void 0 ? void 0 : _a2.openFile(file); + } + } + function focus_handler(event) { + bubble.call(this, $$self, event); + } + $$self.$$set = ($$props2) => { + if ("change" in $$props2) + $$invalidate(0, change = $$props2.change); + if ("view" in $$props2) + $$invalidate(4, view = $$props2.view); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty & /*view*/ + 16) { + $: + $$invalidate(1, side = view.leaf.getRoot().side == "left" ? "right" : "left"); + } + }; + return [change, side, hover, open, view, focus_handler]; +} +var PulledFileComponent = class extends SvelteComponent { + constructor(options) { + super(); + init2(this, options, instance6, create_fragment6, safe_not_equal, { change: 0, view: 4 }, add_css5); + } +}; +var pulledFileComponent_default = PulledFileComponent; + +// src/ui/sourceControl/components/stagedFileComponent.svelte +init_polyfill_buffer(); +var import_obsidian27 = require("obsidian"); +function add_css6(target) { + append_styles(target, "svelte-pmbo0n", "main.svelte-pmbo0n .nav-file-title-content.svelte-pmbo0n{display:flex;align-items:center}"); +} +function create_if_block6(ctx) { + let div; + let mounted; + let dispose; + return { + c() { + div = element("div"); + attr(div, "data-icon", "go-to-file"); + attr(div, "aria-label", "Open File"); + attr(div, "class", "clickable-icon"); + }, + m(target, anchor) { + insert(target, div, anchor); + ctx[10](div); + if (!mounted) { + dispose = listen(div, "click", stop_propagation( + /*open*/ + ctx[5] + )); + mounted = true; + } + }, + p: noop, + d(detaching) { + if (detaching) + detach(div); + ctx[10](null); + mounted = false; + dispose(); + } + }; +} +function create_fragment7(ctx) { + let main; + let div5; + let div0; + let t0_value = getDisplayPath( + /*change*/ + ctx[0].vault_path + ) + ""; + let t0; + let t1; + let div4; + let div2; + let show_if = ( + /*view*/ + ctx[1].app.vault.getAbstractFileByPath( + /*change*/ + ctx[0].vault_path + ) + ); + let t2; + let div1; + let t3; + let div3; + let t4_value = ( + /*change*/ + ctx[0].index + "" + ); + let t4; + let div3_data_type_value; + let div5_aria_label_value; + let mounted; + let dispose; + let if_block = show_if && create_if_block6(ctx); + return { + c() { + main = element("main"); + div5 = element("div"); + div0 = element("div"); + t0 = text(t0_value); + t1 = space(); + div4 = element("div"); + div2 = element("div"); + if (if_block) + if_block.c(); + t2 = space(); + div1 = element("div"); + t3 = space(); + div3 = element("div"); + t4 = text(t4_value); + attr(div0, "class", "tree-item-inner nav-file-title-content svelte-pmbo0n"); + attr(div1, "data-icon", "minus"); + attr(div1, "aria-label", "Unstage"); + attr(div1, "class", "clickable-icon"); + attr(div2, "class", "buttons"); + attr(div3, "class", "type"); + attr(div3, "data-type", div3_data_type_value = /*change*/ + ctx[0].index); + attr(div4, "class", "git-tools"); + attr(div5, "class", "tree-item-self is-clickable nav-file-title"); + attr( + div5, + "aria-label-position", + /*side*/ + ctx[3] + ); + attr(div5, "aria-label", div5_aria_label_value = /*change*/ + ctx[0].vault_path); + attr(main, "class", "tree-item nav-file svelte-pmbo0n"); + }, + m(target, anchor) { + insert(target, main, anchor); + append2(main, div5); + append2(div5, div0); + append2(div0, t0); + append2(div5, t1); + append2(div5, div4); + append2(div4, div2); + if (if_block) + if_block.m(div2, null); + append2(div2, t2); + append2(div2, div1); + ctx[11](div1); + append2(div4, t3); + append2(div4, div3); + append2(div3, t4); + if (!mounted) { + dispose = [ + listen(div1, "click", stop_propagation( + /*unstage*/ + ctx[7] + )), + listen( + main, + "mouseover", + /*hover*/ + ctx[4] + ), + listen( + main, + "focus", + /*focus_handler*/ + ctx[9] + ), + listen(main, "click", stop_propagation( + /*showDiff*/ + ctx[6] + )), + listen(main, "auxclick", stop_propagation( + /*showDiff*/ + ctx[6] + )) + ]; + mounted = true; + } + }, + p(ctx2, [dirty]) { + if (dirty & /*change*/ + 1 && t0_value !== (t0_value = getDisplayPath( + /*change*/ + ctx2[0].vault_path + ) + "")) + set_data(t0, t0_value); + if (dirty & /*view, change*/ + 3) + show_if = /*view*/ + ctx2[1].app.vault.getAbstractFileByPath( + /*change*/ + ctx2[0].vault_path + ); + if (show_if) { + if (if_block) { + if_block.p(ctx2, dirty); + } else { + if_block = create_if_block6(ctx2); + if_block.c(); + if_block.m(div2, t2); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } + if (dirty & /*change*/ + 1 && t4_value !== (t4_value = /*change*/ + ctx2[0].index + "")) + set_data(t4, t4_value); + if (dirty & /*change*/ + 1 && div3_data_type_value !== (div3_data_type_value = /*change*/ + ctx2[0].index)) { + attr(div3, "data-type", div3_data_type_value); + } + if (dirty & /*side*/ + 8) { + attr( + div5, + "aria-label-position", + /*side*/ + ctx2[3] + ); + } + if (dirty & /*change*/ + 1 && div5_aria_label_value !== (div5_aria_label_value = /*change*/ + ctx2[0].vault_path)) { + attr(div5, "aria-label", div5_aria_label_value); + } + }, + i: noop, + o: noop, + d(detaching) { + if (detaching) + detach(main); + if (if_block) + if_block.d(); + ctx[11](null); + mounted = false; + run_all(dispose); + } + }; +} +function instance7($$self, $$props, $$invalidate) { + let formattedPath; + let side; + let { change } = $$props; + let { view } = $$props; + let { manager } = $$props; + let buttons = []; + window.setTimeout(() => buttons.forEach((b) => (0, import_obsidian27.setIcon)(b, b.getAttr("data-icon"), 16)), 0); + function hover(event) { + if (app.vault.getAbstractFileByPath(change.vault_path)) { + hoverPreview(event, view, change.vault_path); + } + } + function open(event) { + var _a2; + const file = view.app.vault.getAbstractFileByPath(change.vault_path); + if (file instanceof import_obsidian27.TFile) { + (_a2 = getNewLeaf(event)) === null || _a2 === void 0 ? void 0 : _a2.openFile(file); + } + } + function showDiff(event) { + var _a2; + (_a2 = getNewLeaf(event)) === null || _a2 === void 0 ? void 0 : _a2.setViewState({ + type: DIFF_VIEW_CONFIG.type, + active: true, + state: { file: change.path, staged: true } + }); + } + function unstage() { + manager.unstage(change.path, false).finally(() => { + dispatchEvent(new CustomEvent("git-refresh")); + }); + } + function focus_handler(event) { + bubble.call(this, $$self, event); + } + function div_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[1] = $$value; + $$invalidate(2, buttons); + }); + } + function div1_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[0] = $$value; + $$invalidate(2, buttons); + }); + } + $$self.$$set = ($$props2) => { + if ("change" in $$props2) + $$invalidate(0, change = $$props2.change); + if ("view" in $$props2) + $$invalidate(1, view = $$props2.view); + if ("manager" in $$props2) + $$invalidate(8, manager = $$props2.manager); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty & /*change*/ + 1) { + $: + formattedPath = change.vault_path; + } + if ($$self.$$.dirty & /*view*/ + 2) { + $: + $$invalidate(3, side = view.leaf.getRoot().side == "left" ? "right" : "left"); + } + }; + return [ + change, + view, + buttons, + side, + hover, + open, + showDiff, + unstage, + manager, + focus_handler, + div_binding, + div1_binding + ]; +} +var StagedFileComponent = class extends SvelteComponent { + constructor(options) { + super(); + init2(this, options, instance7, create_fragment7, safe_not_equal, { change: 0, view: 1, manager: 8 }, add_css6); + } +}; +var stagedFileComponent_default = StagedFileComponent; + +// src/ui/sourceControl/components/treeComponent.svelte +init_polyfill_buffer(); +function add_css7(target) { + append_styles(target, "svelte-1lnl15d", "main.svelte-1lnl15d .nav-folder-title-content.svelte-1lnl15d{display:flex;align-items:center}"); +} +function get_each_context4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[15] = list[i]; + return child_ctx; +} +function create_else_block3(ctx) { + let div7; + let div6; + let div0; + let t0; + let div1; + let t1; + let div2; + let t2_value = ( + /*entity*/ + ctx[15].title + "" + ); + let t2; + let t3; + let div5; + let div4; + let t4; + let div3; + let div6_aria_label_value; + let t5; + let t6; + let current; + let mounted; + let dispose; + function select_block_type_2(ctx2, dirty) { + if ( + /*fileType*/ + ctx2[3] == 0 /* staged */ + ) + return create_if_block_5; + return create_else_block_1; + } + let current_block_type = select_block_type_2(ctx, -1); + let if_block0 = current_block_type(ctx); + let if_block1 = !/*closed*/ + ctx[5][ + /*entity*/ + ctx[15].title + ] && create_if_block_4(ctx); + function click_handler_3() { + return ( + /*click_handler_3*/ + ctx[14]( + /*entity*/ + ctx[15] + ) + ); + } + return { + c() { + div7 = element("div"); + div6 = element("div"); + div0 = element("div"); + t0 = space(); + div1 = element("div"); + div1.innerHTML = ``; + t1 = space(); + div2 = element("div"); + t2 = text(t2_value); + t3 = space(); + div5 = element("div"); + div4 = element("div"); + if_block0.c(); + t4 = space(); + div3 = element("div"); + t5 = space(); + if (if_block1) + if_block1.c(); + t6 = space(); + attr(div0, "data-icon", "folder"); + set_style(div0, "padding-right", "5px"); + set_style(div0, "display", "flex"); + attr(div1, "class", "tree-item-icon nav-folder-collapse-indicator collapse-icon"); + attr(div2, "class", "tree-item-inner nav-folder-title-content svelte-1lnl15d"); + set_style(div3, "width", "11px"); + attr(div4, "class", "buttons"); + attr(div5, "class", "git-tools"); + attr(div6, "class", "tree-item-self is-clickable nav-folder-title"); + attr( + div6, + "aria-label-position", + /*side*/ + ctx[6] + ); + attr(div6, "aria-label", div6_aria_label_value = /*entity*/ + ctx[15].vaultPath); + attr(div7, "class", "tree-item nav-folder"); + toggle_class( + div7, + "is-collapsed", + /*closed*/ + ctx[5][ + /*entity*/ + ctx[15].title + ] + ); + }, + m(target, anchor) { + insert(target, div7, anchor); + append2(div7, div6); + append2(div6, div0); + append2(div6, t0); + append2(div6, div1); + append2(div6, t1); + append2(div6, div2); + append2(div2, t2); + append2(div6, t3); + append2(div6, div5); + append2(div5, div4); + if_block0.m(div4, null); + append2(div4, t4); + append2(div4, div3); + append2(div7, t5); + if (if_block1) + if_block1.m(div7, null); + append2(div7, t6); + current = true; + if (!mounted) { + dispose = listen(div7, "click", click_handler_3); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + if ((!current || dirty & /*hierarchy*/ + 1) && t2_value !== (t2_value = /*entity*/ + ctx[15].title + "")) + set_data(t2, t2_value); + if (current_block_type === (current_block_type = select_block_type_2(ctx, dirty)) && if_block0) { + if_block0.p(ctx, dirty); + } else { + if_block0.d(1); + if_block0 = current_block_type(ctx); + if (if_block0) { + if_block0.c(); + if_block0.m(div4, t4); + } + } + if (!current || dirty & /*side*/ + 64) { + attr( + div6, + "aria-label-position", + /*side*/ + ctx[6] + ); + } + if (!current || dirty & /*hierarchy*/ + 1 && div6_aria_label_value !== (div6_aria_label_value = /*entity*/ + ctx[15].vaultPath)) { + attr(div6, "aria-label", div6_aria_label_value); + } + if (!/*closed*/ + ctx[5][ + /*entity*/ + ctx[15].title + ]) { + if (if_block1) { + if_block1.p(ctx, dirty); + if (dirty & /*closed, hierarchy*/ + 33) { + transition_in(if_block1, 1); + } + } else { + if_block1 = create_if_block_4(ctx); + if_block1.c(); + transition_in(if_block1, 1); + if_block1.m(div7, t6); + } + } else if (if_block1) { + group_outros(); + transition_out(if_block1, 1, 1, () => { + if_block1 = null; + }); + check_outros(); + } + if (!current || dirty & /*closed, hierarchy*/ + 33) { + toggle_class( + div7, + "is-collapsed", + /*closed*/ + ctx[5][ + /*entity*/ + ctx[15].title + ] + ); + } + }, + i(local) { + if (current) + return; + transition_in(if_block1); + current = true; + }, + o(local) { + transition_out(if_block1); + current = false; + }, + d(detaching) { + if (detaching) + detach(div7); + if_block0.d(); + if (if_block1) + if_block1.d(); + mounted = false; + dispose(); + } + }; +} +function create_if_block7(ctx) { + let div; + let current_block_type_index; + let if_block; + let t; + let current; + const if_block_creators = [create_if_block_13, create_if_block_22, create_if_block_3]; + const if_blocks = []; + function select_block_type_1(ctx2, dirty) { + if ( + /*fileType*/ + ctx2[3] == 0 /* staged */ + ) + return 0; + if ( + /*fileType*/ + ctx2[3] == 1 /* changed */ + ) + return 1; + if ( + /*fileType*/ + ctx2[3] == 2 /* pulled */ + ) + return 2; + return -1; + } + if (~(current_block_type_index = select_block_type_1(ctx, -1))) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + } + return { + c() { + div = element("div"); + if (if_block) + if_block.c(); + t = space(); + }, + m(target, anchor) { + insert(target, div, anchor); + if (~current_block_type_index) { + if_blocks[current_block_type_index].m(div, null); + } + append2(div, t); + current = true; + }, + p(ctx2, dirty) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type_1(ctx2, dirty); + if (current_block_type_index === previous_block_index) { + if (~current_block_type_index) { + if_blocks[current_block_type_index].p(ctx2, dirty); + } + } else { + if (if_block) { + group_outros(); + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + check_outros(); + } + if (~current_block_type_index) { + if_block = if_blocks[current_block_type_index]; + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); + if_block.c(); + } else { + if_block.p(ctx2, dirty); + } + transition_in(if_block, 1); + if_block.m(div, t); + } else { + if_block = null; + } + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + current = true; + }, + o(local) { + transition_out(if_block); + current = false; + }, + d(detaching) { + if (detaching) + detach(div); + if (~current_block_type_index) { + if_blocks[current_block_type_index].d(); + } + } + }; +} +function create_else_block_1(ctx) { + let div0; + let t; + let div1; + let mounted; + let dispose; + function click_handler_1() { + return ( + /*click_handler_1*/ + ctx[12]( + /*entity*/ + ctx[15] + ) + ); + } + function click_handler_2() { + return ( + /*click_handler_2*/ + ctx[13]( + /*entity*/ + ctx[15] + ) + ); + } + return { + c() { + div0 = element("div"); + div0.innerHTML = ``; + t = space(); + div1 = element("div"); + div1.innerHTML = ``; + attr(div0, "data-icon", "undo"); + attr(div0, "aria-label", "Discard"); + attr(div0, "class", "clickable-icon"); + attr(div1, "data-icon", "plus"); + attr(div1, "aria-label", "Stage"); + attr(div1, "class", "clickable-icon"); + }, + m(target, anchor) { + insert(target, div0, anchor); + insert(target, t, anchor); + insert(target, div1, anchor); + if (!mounted) { + dispose = [ + listen(div0, "click", stop_propagation(click_handler_1)), + listen(div1, "click", stop_propagation(click_handler_2)) + ]; + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) + detach(div0); + if (detaching) + detach(t); + if (detaching) + detach(div1); + mounted = false; + run_all(dispose); + } + }; +} +function create_if_block_5(ctx) { + let div; + let mounted; + let dispose; + function click_handler() { + return ( + /*click_handler*/ + ctx[11]( + /*entity*/ + ctx[15] + ) + ); + } + return { + c() { + div = element("div"); + div.innerHTML = ``; + attr(div, "data-icon", "minus"); + attr(div, "aria-label", "Unstage"); + attr(div, "class", "clickable-icon"); + }, + m(target, anchor) { + insert(target, div, anchor); + if (!mounted) { + dispose = listen(div, "click", stop_propagation(click_handler)); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) + detach(div); + mounted = false; + dispose(); + } + }; +} +function create_if_block_4(ctx) { + let div; + let treecomponent; + let div_transition; + let current; + treecomponent = new TreeComponent({ + props: { + hierarchy: ( + /*entity*/ + ctx[15] + ), + plugin: ( + /*plugin*/ + ctx[1] + ), + view: ( + /*view*/ + ctx[2] + ), + fileType: ( + /*fileType*/ + ctx[3] + ) + } + }); + return { + c() { + div = element("div"); + create_component(treecomponent.$$.fragment); + attr(div, "class", "tree-item-children nav-folder-children"); + }, + m(target, anchor) { + insert(target, div, anchor); + mount_component(treecomponent, div, null); + current = true; + }, + p(ctx2, dirty) { + const treecomponent_changes = {}; + if (dirty & /*hierarchy*/ + 1) + treecomponent_changes.hierarchy = /*entity*/ + ctx2[15]; + if (dirty & /*plugin*/ + 2) + treecomponent_changes.plugin = /*plugin*/ + ctx2[1]; + if (dirty & /*view*/ + 4) + treecomponent_changes.view = /*view*/ + ctx2[2]; + if (dirty & /*fileType*/ + 8) + treecomponent_changes.fileType = /*fileType*/ + ctx2[3]; + treecomponent.$set(treecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(treecomponent.$$.fragment, local); + if (local) { + add_render_callback(() => { + if (!current) + return; + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, true); + div_transition.run(1); + }); + } + current = true; + }, + o(local) { + transition_out(treecomponent.$$.fragment, local); + if (local) { + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, false); + div_transition.run(0); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(div); + destroy_component(treecomponent); + if (detaching && div_transition) + div_transition.end(); + } + }; +} +function create_if_block_3(ctx) { + let pulledfilecomponent; + let current; + pulledfilecomponent = new pulledFileComponent_default({ + props: { + change: ( + /*entity*/ + ctx[15].data + ), + view: ( + /*view*/ + ctx[2] + ) + } + }); + return { + c() { + create_component(pulledfilecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(pulledfilecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const pulledfilecomponent_changes = {}; + if (dirty & /*hierarchy*/ + 1) + pulledfilecomponent_changes.change = /*entity*/ + ctx2[15].data; + if (dirty & /*view*/ + 4) + pulledfilecomponent_changes.view = /*view*/ + ctx2[2]; + pulledfilecomponent.$set(pulledfilecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(pulledfilecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(pulledfilecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(pulledfilecomponent, detaching); + } + }; +} +function create_if_block_22(ctx) { + let filecomponent; + let current; + filecomponent = new fileComponent_default({ + props: { + change: ( + /*entity*/ + ctx[15].data + ), + manager: ( + /*plugin*/ + ctx[1].gitManager + ), + view: ( + /*view*/ + ctx[2] + ) + } + }); + return { + c() { + create_component(filecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(filecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const filecomponent_changes = {}; + if (dirty & /*hierarchy*/ + 1) + filecomponent_changes.change = /*entity*/ + ctx2[15].data; + if (dirty & /*plugin*/ + 2) + filecomponent_changes.manager = /*plugin*/ + ctx2[1].gitManager; + if (dirty & /*view*/ + 4) + filecomponent_changes.view = /*view*/ + ctx2[2]; + filecomponent.$set(filecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(filecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(filecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(filecomponent, detaching); + } + }; +} +function create_if_block_13(ctx) { + let stagedfilecomponent; + let current; + stagedfilecomponent = new stagedFileComponent_default({ + props: { + change: ( + /*entity*/ + ctx[15].data + ), + manager: ( + /*plugin*/ + ctx[1].gitManager + ), + view: ( + /*view*/ + ctx[2] + ) + } + }); + return { + c() { + create_component(stagedfilecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(stagedfilecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const stagedfilecomponent_changes = {}; + if (dirty & /*hierarchy*/ + 1) + stagedfilecomponent_changes.change = /*entity*/ + ctx2[15].data; + if (dirty & /*plugin*/ + 2) + stagedfilecomponent_changes.manager = /*plugin*/ + ctx2[1].gitManager; + if (dirty & /*view*/ + 4) + stagedfilecomponent_changes.view = /*view*/ + ctx2[2]; + stagedfilecomponent.$set(stagedfilecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(stagedfilecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(stagedfilecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(stagedfilecomponent, detaching); + } + }; +} +function create_each_block4(ctx) { + let current_block_type_index; + let if_block; + let if_block_anchor; + let current; + const if_block_creators = [create_if_block7, create_else_block3]; + const if_blocks = []; + function select_block_type(ctx2, dirty) { + if ( + /*entity*/ + ctx2[15].data + ) + return 0; + return 1; + } + current_block_type_index = select_block_type(ctx, -1); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + return { + c() { + if_block.c(); + if_block_anchor = empty(); + }, + m(target, anchor) { + if_blocks[current_block_type_index].m(target, anchor); + insert(target, if_block_anchor, anchor); + current = true; + }, + p(ctx2, dirty) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type(ctx2, dirty); + if (current_block_type_index === previous_block_index) { + if_blocks[current_block_type_index].p(ctx2, dirty); + } else { + group_outros(); + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + check_outros(); + if_block = if_blocks[current_block_type_index]; + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); + if_block.c(); + } else { + if_block.p(ctx2, dirty); + } + transition_in(if_block, 1); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + current = true; + }, + o(local) { + transition_out(if_block); + current = false; + }, + d(detaching) { + if_blocks[current_block_type_index].d(detaching); + if (detaching) + detach(if_block_anchor); + } + }; +} +function create_fragment8(ctx) { + let main; + let current; + let each_value = ( + /*hierarchy*/ + ctx[0].children + ); + let each_blocks = []; + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block4(get_each_context4(ctx, each_value, i)); + } + const out = (i) => transition_out(each_blocks[i], 1, 1, () => { + each_blocks[i] = null; + }); + return { + c() { + main = element("main"); + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + attr(main, "class", "svelte-1lnl15d"); + toggle_class( + main, + "topLevel", + /*topLevel*/ + ctx[4] + ); + }, + m(target, anchor) { + insert(target, main, anchor); + for (let i = 0; i < each_blocks.length; i += 1) { + if (each_blocks[i]) { + each_blocks[i].m(main, null); + } + } + current = true; + }, + p(ctx2, [dirty]) { + if (dirty & /*hierarchy, plugin, view, fileType, FileType, closed, fold, side, unstage, stage, discard*/ + 2031) { + each_value = /*hierarchy*/ + ctx2[0].children; + let i; + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context4(ctx2, each_value, i); + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + transition_in(each_blocks[i], 1); + } else { + each_blocks[i] = create_each_block4(child_ctx); + each_blocks[i].c(); + transition_in(each_blocks[i], 1); + each_blocks[i].m(main, null); + } + } + group_outros(); + for (i = each_value.length; i < each_blocks.length; i += 1) { + out(i); + } + check_outros(); + } + if (!current || dirty & /*topLevel*/ + 16) { + toggle_class( + main, + "topLevel", + /*topLevel*/ + ctx2[4] + ); + } + }, + i(local) { + if (current) + return; + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + current = true; + }, + o(local) { + each_blocks = each_blocks.filter(Boolean); + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(main); + destroy_each(each_blocks, detaching); + } + }; +} +function instance8($$self, $$props, $$invalidate) { + let side; + let { hierarchy } = $$props; + let { plugin } = $$props; + let { view } = $$props; + let { fileType } = $$props; + let { topLevel = false } = $$props; + const closed = {}; + function stage(path2) { + plugin.gitManager.stageAll({ dir: path2 }).finally(() => { + dispatchEvent(new CustomEvent("git-refresh")); + }); + } + function unstage(path2) { + plugin.gitManager.unstageAll({ dir: path2 }).finally(() => { + dispatchEvent(new CustomEvent("git-refresh")); + }); + } + function discard(item) { + new DiscardModal(view.app, false, item.vaultPath).myOpen().then((shouldDiscard) => { + if (shouldDiscard === true) { + plugin.gitManager.discardAll({ + dir: item.path, + status: plugin.cachedStatus + }).finally(() => { + dispatchEvent(new CustomEvent("git-refresh")); + }); + } + }); + } + function fold(item) { + $$invalidate(5, closed[item.title] = !closed[item.title], closed); + } + const click_handler = (entity) => unstage(entity.path); + const click_handler_1 = (entity) => discard(entity); + const click_handler_2 = (entity) => stage(entity.path); + const click_handler_3 = (entity) => fold(entity); + $$self.$$set = ($$props2) => { + if ("hierarchy" in $$props2) + $$invalidate(0, hierarchy = $$props2.hierarchy); + if ("plugin" in $$props2) + $$invalidate(1, plugin = $$props2.plugin); + if ("view" in $$props2) + $$invalidate(2, view = $$props2.view); + if ("fileType" in $$props2) + $$invalidate(3, fileType = $$props2.fileType); + if ("topLevel" in $$props2) + $$invalidate(4, topLevel = $$props2.topLevel); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty & /*view*/ + 4) { + $: + $$invalidate(6, side = view.leaf.getRoot().side == "left" ? "right" : "left"); + } + }; + return [ + hierarchy, + plugin, + view, + fileType, + topLevel, + closed, + side, + stage, + unstage, + discard, + fold, + click_handler, + click_handler_1, + click_handler_2, + click_handler_3 + ]; +} +var TreeComponent = class extends SvelteComponent { + constructor(options) { + super(); + init2( + this, + options, + instance8, + create_fragment8, + safe_not_equal, + { + hierarchy: 0, + plugin: 1, + view: 2, + fileType: 3, + topLevel: 4 + }, + add_css7 + ); + } +}; +var treeComponent_default = TreeComponent; + +// src/ui/sourceControl/sourceControl.svelte +function add_css8(target) { + append_styles(target, "svelte-48bivb", `.commit-msg-input.svelte-48bivb.svelte-48bivb{width:100%;overflow:hidden;resize:none;padding:7px 5px;background-color:var(--background-modifier-form-field)}.git-commit-msg.svelte-48bivb.svelte-48bivb{position:relative;padding:0;width:calc(100% - var(--size-4-8));margin:4px auto}main.svelte-48bivb .git-tools .files-count.svelte-48bivb{padding-left:var(--size-2-1);width:11px;display:flex;align-items:center;justify-content:center}.git-commit-msg-clear-button.svelte-48bivb.svelte-48bivb{position:absolute;background:transparent;border-radius:50%;color:var(--search-clear-button-color);cursor:var(--cursor);top:-4px;right:2px;bottom:0px;line-height:0;height:var(--input-height);width:28px;margin:auto;padding:0 0;text-align:center;display:flex;justify-content:center;align-items:center;transition:color 0.15s ease-in-out}.git-commit-msg-clear-button.svelte-48bivb.svelte-48bivb:after{content:"";height:var(--search-clear-button-size);width:var(--search-clear-button-size);display:block;background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml,");-webkit-mask-repeat:no-repeat}`); +} +function get_each_context5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[40] = list[i]; + return child_ctx; +} +function get_each_context_1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[40] = list[i]; + return child_ctx; +} +function get_each_context_2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[45] = list[i]; + return child_ctx; +} +function create_if_block_8(ctx) { + let div; + let div_aria_label_value; + let mounted; + let dispose; + return { + c() { + div = element("div"); + attr(div, "class", "git-commit-msg-clear-button svelte-48bivb"); + attr(div, "aria-label", div_aria_label_value = "Clear"); + }, + m(target, anchor) { + insert(target, div, anchor); + if (!mounted) { + dispose = listen( + div, + "click", + /*click_handler_1*/ + ctx[33] + ); + mounted = true; + } + }, + p: noop, + d(detaching) { + if (detaching) + detach(div); + mounted = false; + dispose(); + } + }; +} +function create_if_block8(ctx) { + let div18; + let div17; + let div7; + let div6; + let div0; + let t0; + let div1; + let t2; + let div5; + let div3; + let div2; + let t3; + let div4; + let t4_value = ( + /*status*/ + ctx[6].staged.length + "" + ); + let t4; + let t5; + let t6; + let div16; + let div15; + let div8; + let t7; + let div9; + let t9; + let div14; + let div12; + let div10; + let t10; + let div11; + let t11; + let div13; + let t12_value = ( + /*status*/ + ctx[6].changed.length + "" + ); + let t12; + let t13; + let t14; + let current; + let mounted; + let dispose; + let if_block0 = ( + /*stagedOpen*/ + ctx[13] && create_if_block_6(ctx) + ); + let if_block1 = ( + /*changesOpen*/ + ctx[12] && create_if_block_42(ctx) + ); + let if_block2 = ( + /*lastPulledFiles*/ + ctx[7].length > 0 && create_if_block_14(ctx) + ); + return { + c() { + div18 = element("div"); + div17 = element("div"); + div7 = element("div"); + div6 = element("div"); + div0 = element("div"); + div0.innerHTML = ``; + t0 = space(); + div1 = element("div"); + div1.textContent = "Staged Changes"; + t2 = space(); + div5 = element("div"); + div3 = element("div"); + div2 = element("div"); + div2.innerHTML = ``; + t3 = space(); + div4 = element("div"); + t4 = text(t4_value); + t5 = space(); + if (if_block0) + if_block0.c(); + t6 = space(); + div16 = element("div"); + div15 = element("div"); + div8 = element("div"); + div8.innerHTML = ``; + t7 = space(); + div9 = element("div"); + div9.textContent = "Changes"; + t9 = space(); + div14 = element("div"); + div12 = element("div"); + div10 = element("div"); + div10.innerHTML = ``; + t10 = space(); + div11 = element("div"); + div11.innerHTML = ``; + t11 = space(); + div13 = element("div"); + t12 = text(t12_value); + t13 = space(); + if (if_block1) + if_block1.c(); + t14 = space(); + if (if_block2) + if_block2.c(); + attr(div0, "class", "tree-item-icon nav-folder-collapse-indicator collapse-icon"); + attr(div1, "class", "tree-item-inner nav-folder-title-content"); + attr(div2, "data-icon", "minus"); + attr(div2, "aria-label", "Unstage"); + attr(div2, "class", "clickable-icon"); + attr(div3, "class", "buttons"); + attr(div4, "class", "files-count svelte-48bivb"); + attr(div5, "class", "git-tools"); + attr(div6, "class", "tree-item-self is-clickable nav-folder-title"); + attr(div7, "class", "staged tree-item nav-folder"); + toggle_class(div7, "is-collapsed", !/*stagedOpen*/ + ctx[13]); + attr(div8, "class", "tree-item-icon nav-folder-collapse-indicator collapse-icon"); + attr(div9, "class", "tree-item-inner nav-folder-title-content"); + attr(div10, "data-icon", "undo"); + attr(div10, "aria-label", "Discard"); + attr(div10, "class", "clickable-icon"); + attr(div11, "data-icon", "plus"); + attr(div11, "aria-label", "Stage"); + attr(div11, "class", "clickable-icon"); + attr(div12, "class", "buttons"); + attr(div13, "class", "files-count svelte-48bivb"); + attr(div14, "class", "git-tools"); + attr(div15, "class", "tree-item-self is-clickable nav-folder-title"); + attr(div16, "class", "changes nav-folder"); + toggle_class(div16, "is-collapsed", !/*changesOpen*/ + ctx[12]); + attr(div17, "class", "tree-item-children nav-folder-children"); + attr(div18, "class", "tree-item nav-folder mod-root"); + }, + m(target, anchor) { + insert(target, div18, anchor); + append2(div18, div17); + append2(div17, div7); + append2(div7, div6); + append2(div6, div0); + append2(div6, t0); + append2(div6, div1); + append2(div6, t2); + append2(div6, div5); + append2(div5, div3); + append2(div3, div2); + ctx[34](div2); + append2(div5, t3); + append2(div5, div4); + append2(div4, t4); + append2(div7, t5); + if (if_block0) + if_block0.m(div7, null); + append2(div17, t6); + append2(div17, div16); + append2(div16, div15); + append2(div15, div8); + append2(div15, t7); + append2(div15, div9); + append2(div15, t9); + append2(div15, div14); + append2(div14, div12); + append2(div12, div10); + append2(div12, t10); + append2(div12, div11); + ctx[36](div11); + append2(div14, t11); + append2(div14, div13); + append2(div13, t12); + append2(div16, t13); + if (if_block1) + if_block1.m(div16, null); + append2(div17, t14); + if (if_block2) + if_block2.m(div17, null); + current = true; + if (!mounted) { + dispose = [ + listen(div2, "click", stop_propagation( + /*unstageAll*/ + ctx[19] + )), + listen( + div6, + "click", + /*click_handler_2*/ + ctx[35] + ), + listen(div10, "click", stop_propagation( + /*discard*/ + ctx[22] + )), + listen(div11, "click", stop_propagation( + /*stageAll*/ + ctx[18] + )), + listen( + div15, + "click", + /*click_handler_3*/ + ctx[37] + ) + ]; + mounted = true; + } + }, + p(ctx2, dirty) { + if ((!current || dirty[0] & /*status*/ + 64) && t4_value !== (t4_value = /*status*/ + ctx2[6].staged.length + "")) + set_data(t4, t4_value); + if ( + /*stagedOpen*/ + ctx2[13] + ) { + if (if_block0) { + if_block0.p(ctx2, dirty); + if (dirty[0] & /*stagedOpen*/ + 8192) { + transition_in(if_block0, 1); + } + } else { + if_block0 = create_if_block_6(ctx2); + if_block0.c(); + transition_in(if_block0, 1); + if_block0.m(div7, null); + } + } else if (if_block0) { + group_outros(); + transition_out(if_block0, 1, 1, () => { + if_block0 = null; + }); + check_outros(); + } + if (!current || dirty[0] & /*stagedOpen*/ + 8192) { + toggle_class(div7, "is-collapsed", !/*stagedOpen*/ + ctx2[13]); + } + if ((!current || dirty[0] & /*status*/ + 64) && t12_value !== (t12_value = /*status*/ + ctx2[6].changed.length + "")) + set_data(t12, t12_value); + if ( + /*changesOpen*/ + ctx2[12] + ) { + if (if_block1) { + if_block1.p(ctx2, dirty); + if (dirty[0] & /*changesOpen*/ + 4096) { + transition_in(if_block1, 1); + } + } else { + if_block1 = create_if_block_42(ctx2); + if_block1.c(); + transition_in(if_block1, 1); + if_block1.m(div16, null); + } + } else if (if_block1) { + group_outros(); + transition_out(if_block1, 1, 1, () => { + if_block1 = null; + }); + check_outros(); + } + if (!current || dirty[0] & /*changesOpen*/ + 4096) { + toggle_class(div16, "is-collapsed", !/*changesOpen*/ + ctx2[12]); + } + if ( + /*lastPulledFiles*/ + ctx2[7].length > 0 + ) { + if (if_block2) { + if_block2.p(ctx2, dirty); + if (dirty[0] & /*lastPulledFiles*/ + 128) { + transition_in(if_block2, 1); + } + } else { + if_block2 = create_if_block_14(ctx2); + if_block2.c(); + transition_in(if_block2, 1); + if_block2.m(div17, null); + } + } else if (if_block2) { + group_outros(); + transition_out(if_block2, 1, 1, () => { + if_block2 = null; + }); + check_outros(); + } + }, + i(local) { + if (current) + return; + transition_in(if_block0); + transition_in(if_block1); + transition_in(if_block2); + current = true; + }, + o(local) { + transition_out(if_block0); + transition_out(if_block1); + transition_out(if_block2); + current = false; + }, + d(detaching) { + if (detaching) + detach(div18); + ctx[34](null); + if (if_block0) + if_block0.d(); + ctx[36](null); + if (if_block1) + if_block1.d(); + if (if_block2) + if_block2.d(); + mounted = false; + run_all(dispose); + } + }; +} +function create_if_block_6(ctx) { + let div; + let current_block_type_index; + let if_block; + let div_transition; + let current; + const if_block_creators = [create_if_block_7, create_else_block_2]; + const if_blocks = []; + function select_block_type(ctx2, dirty) { + if ( + /*showTree*/ + ctx2[3] + ) + return 0; + return 1; + } + current_block_type_index = select_block_type(ctx, [-1, -1]); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + return { + c() { + div = element("div"); + if_block.c(); + attr(div, "class", "tree-item-children nav-folder-children"); + }, + m(target, anchor) { + insert(target, div, anchor); + if_blocks[current_block_type_index].m(div, null); + current = true; + }, + p(ctx2, dirty) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type(ctx2, dirty); + if (current_block_type_index === previous_block_index) { + if_blocks[current_block_type_index].p(ctx2, dirty); + } else { + group_outros(); + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + check_outros(); + if_block = if_blocks[current_block_type_index]; + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); + if_block.c(); + } else { + if_block.p(ctx2, dirty); + } + transition_in(if_block, 1); + if_block.m(div, null); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + if (local) { + add_render_callback(() => { + if (!current) + return; + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, true); + div_transition.run(1); + }); + } + current = true; + }, + o(local) { + transition_out(if_block); + if (local) { + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, false); + div_transition.run(0); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(div); + if_blocks[current_block_type_index].d(); + if (detaching && div_transition) + div_transition.end(); + } + }; +} +function create_else_block_2(ctx) { + let each_1_anchor; + let current; + let each_value_2 = ( + /*status*/ + ctx[6].staged + ); + let each_blocks = []; + for (let i = 0; i < each_value_2.length; i += 1) { + each_blocks[i] = create_each_block_2(get_each_context_2(ctx, each_value_2, i)); + } + const out = (i) => transition_out(each_blocks[i], 1, 1, () => { + each_blocks[i] = null; + }); + return { + c() { + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + each_1_anchor = empty(); + }, + m(target, anchor) { + for (let i = 0; i < each_blocks.length; i += 1) { + if (each_blocks[i]) { + each_blocks[i].m(target, anchor); + } + } + insert(target, each_1_anchor, anchor); + current = true; + }, + p(ctx2, dirty) { + if (dirty[0] & /*status, view, plugin*/ + 67) { + each_value_2 = /*status*/ + ctx2[6].staged; + let i; + for (i = 0; i < each_value_2.length; i += 1) { + const child_ctx = get_each_context_2(ctx2, each_value_2, i); + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + transition_in(each_blocks[i], 1); + } else { + each_blocks[i] = create_each_block_2(child_ctx); + each_blocks[i].c(); + transition_in(each_blocks[i], 1); + each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor); + } + } + group_outros(); + for (i = each_value_2.length; i < each_blocks.length; i += 1) { + out(i); + } + check_outros(); + } + }, + i(local) { + if (current) + return; + for (let i = 0; i < each_value_2.length; i += 1) { + transition_in(each_blocks[i]); + } + current = true; + }, + o(local) { + each_blocks = each_blocks.filter(Boolean); + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + current = false; + }, + d(detaching) { + destroy_each(each_blocks, detaching); + if (detaching) + detach(each_1_anchor); + } + }; +} +function create_if_block_7(ctx) { + let treecomponent; + let current; + treecomponent = new treeComponent_default({ + props: { + hierarchy: ( + /*stagedHierarchy*/ + ctx[10] + ), + plugin: ( + /*plugin*/ + ctx[0] + ), + view: ( + /*view*/ + ctx[1] + ), + fileType: 0 /* staged */, + topLevel: true + } + }); + return { + c() { + create_component(treecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(treecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const treecomponent_changes = {}; + if (dirty[0] & /*stagedHierarchy*/ + 1024) + treecomponent_changes.hierarchy = /*stagedHierarchy*/ + ctx2[10]; + if (dirty[0] & /*plugin*/ + 1) + treecomponent_changes.plugin = /*plugin*/ + ctx2[0]; + if (dirty[0] & /*view*/ + 2) + treecomponent_changes.view = /*view*/ + ctx2[1]; + treecomponent.$set(treecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(treecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(treecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(treecomponent, detaching); + } + }; +} +function create_each_block_2(ctx) { + let stagedfilecomponent; + let current; + stagedfilecomponent = new stagedFileComponent_default({ + props: { + change: ( + /*stagedFile*/ + ctx[45] + ), + view: ( + /*view*/ + ctx[1] + ), + manager: ( + /*plugin*/ + ctx[0].gitManager + ) + } + }); + return { + c() { + create_component(stagedfilecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(stagedfilecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const stagedfilecomponent_changes = {}; + if (dirty[0] & /*status*/ + 64) + stagedfilecomponent_changes.change = /*stagedFile*/ + ctx2[45]; + if (dirty[0] & /*view*/ + 2) + stagedfilecomponent_changes.view = /*view*/ + ctx2[1]; + if (dirty[0] & /*plugin*/ + 1) + stagedfilecomponent_changes.manager = /*plugin*/ + ctx2[0].gitManager; + stagedfilecomponent.$set(stagedfilecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(stagedfilecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(stagedfilecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(stagedfilecomponent, detaching); + } + }; +} +function create_if_block_42(ctx) { + let div; + let current_block_type_index; + let if_block; + let div_transition; + let current; + const if_block_creators = [create_if_block_52, create_else_block_12]; + const if_blocks = []; + function select_block_type_1(ctx2, dirty) { + if ( + /*showTree*/ + ctx2[3] + ) + return 0; + return 1; + } + current_block_type_index = select_block_type_1(ctx, [-1, -1]); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + return { + c() { + div = element("div"); + if_block.c(); + attr(div, "class", "tree-item-children nav-folder-children"); + }, + m(target, anchor) { + insert(target, div, anchor); + if_blocks[current_block_type_index].m(div, null); + current = true; + }, + p(ctx2, dirty) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type_1(ctx2, dirty); + if (current_block_type_index === previous_block_index) { + if_blocks[current_block_type_index].p(ctx2, dirty); + } else { + group_outros(); + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + check_outros(); + if_block = if_blocks[current_block_type_index]; + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); + if_block.c(); + } else { + if_block.p(ctx2, dirty); + } + transition_in(if_block, 1); + if_block.m(div, null); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + if (local) { + add_render_callback(() => { + if (!current) + return; + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, true); + div_transition.run(1); + }); + } + current = true; + }, + o(local) { + transition_out(if_block); + if (local) { + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, false); + div_transition.run(0); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(div); + if_blocks[current_block_type_index].d(); + if (detaching && div_transition) + div_transition.end(); + } + }; +} +function create_else_block_12(ctx) { + let each_1_anchor; + let current; + let each_value_1 = ( + /*status*/ + ctx[6].changed + ); + let each_blocks = []; + for (let i = 0; i < each_value_1.length; i += 1) { + each_blocks[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i)); + } + const out = (i) => transition_out(each_blocks[i], 1, 1, () => { + each_blocks[i] = null; + }); + return { + c() { + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + each_1_anchor = empty(); + }, + m(target, anchor) { + for (let i = 0; i < each_blocks.length; i += 1) { + if (each_blocks[i]) { + each_blocks[i].m(target, anchor); + } + } + insert(target, each_1_anchor, anchor); + current = true; + }, + p(ctx2, dirty) { + if (dirty[0] & /*status, view, plugin*/ + 67) { + each_value_1 = /*status*/ + ctx2[6].changed; + let i; + for (i = 0; i < each_value_1.length; i += 1) { + const child_ctx = get_each_context_1(ctx2, each_value_1, i); + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + transition_in(each_blocks[i], 1); + } else { + each_blocks[i] = create_each_block_1(child_ctx); + each_blocks[i].c(); + transition_in(each_blocks[i], 1); + each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor); + } + } + group_outros(); + for (i = each_value_1.length; i < each_blocks.length; i += 1) { + out(i); + } + check_outros(); + } + }, + i(local) { + if (current) + return; + for (let i = 0; i < each_value_1.length; i += 1) { + transition_in(each_blocks[i]); + } + current = true; + }, + o(local) { + each_blocks = each_blocks.filter(Boolean); + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + current = false; + }, + d(detaching) { + destroy_each(each_blocks, detaching); + if (detaching) + detach(each_1_anchor); + } + }; +} +function create_if_block_52(ctx) { + let treecomponent; + let current; + treecomponent = new treeComponent_default({ + props: { + hierarchy: ( + /*changeHierarchy*/ + ctx[9] + ), + plugin: ( + /*plugin*/ + ctx[0] + ), + view: ( + /*view*/ + ctx[1] + ), + fileType: 1 /* changed */, + topLevel: true + } + }); + return { + c() { + create_component(treecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(treecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const treecomponent_changes = {}; + if (dirty[0] & /*changeHierarchy*/ + 512) + treecomponent_changes.hierarchy = /*changeHierarchy*/ + ctx2[9]; + if (dirty[0] & /*plugin*/ + 1) + treecomponent_changes.plugin = /*plugin*/ + ctx2[0]; + if (dirty[0] & /*view*/ + 2) + treecomponent_changes.view = /*view*/ + ctx2[1]; + treecomponent.$set(treecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(treecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(treecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(treecomponent, detaching); + } + }; +} +function create_each_block_1(ctx) { + let filecomponent; + let current; + filecomponent = new fileComponent_default({ + props: { + change: ( + /*change*/ + ctx[40] + ), + view: ( + /*view*/ + ctx[1] + ), + manager: ( + /*plugin*/ + ctx[0].gitManager + ) + } + }); + filecomponent.$on("git-refresh", triggerRefresh2); + return { + c() { + create_component(filecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(filecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const filecomponent_changes = {}; + if (dirty[0] & /*status*/ + 64) + filecomponent_changes.change = /*change*/ + ctx2[40]; + if (dirty[0] & /*view*/ + 2) + filecomponent_changes.view = /*view*/ + ctx2[1]; + if (dirty[0] & /*plugin*/ + 1) + filecomponent_changes.manager = /*plugin*/ + ctx2[0].gitManager; + filecomponent.$set(filecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(filecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(filecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(filecomponent, detaching); + } + }; +} +function create_if_block_14(ctx) { + let div3; + let div2; + let div0; + let t0; + let div1; + let t2; + let span; + let t3_value = ( + /*lastPulledFiles*/ + ctx[7].length + "" + ); + let t3; + let t4; + let current; + let mounted; + let dispose; + let if_block = ( + /*lastPulledFilesOpen*/ + ctx[14] && create_if_block_23(ctx) + ); + return { + c() { + div3 = element("div"); + div2 = element("div"); + div0 = element("div"); + div0.innerHTML = ``; + t0 = space(); + div1 = element("div"); + div1.textContent = "Recently Pulled Files"; + t2 = space(); + span = element("span"); + t3 = text(t3_value); + t4 = space(); + if (if_block) + if_block.c(); + attr(div0, "class", "tree-item-icon nav-folder-collapse-indicator collapse-icon"); + attr(div1, "class", "tree-item-inner nav-folder-title-content"); + attr(span, "class", "tree-item-flair"); + attr(div2, "class", "tree-item-self is-clickable nav-folder-title"); + attr(div3, "class", "pulled nav-folder"); + toggle_class(div3, "is-collapsed", !/*lastPulledFilesOpen*/ + ctx[14]); + }, + m(target, anchor) { + insert(target, div3, anchor); + append2(div3, div2); + append2(div2, div0); + append2(div2, t0); + append2(div2, div1); + append2(div2, t2); + append2(div2, span); + append2(span, t3); + append2(div3, t4); + if (if_block) + if_block.m(div3, null); + current = true; + if (!mounted) { + dispose = listen( + div2, + "click", + /*click_handler_4*/ + ctx[38] + ); + mounted = true; + } + }, + p(ctx2, dirty) { + if ((!current || dirty[0] & /*lastPulledFiles*/ + 128) && t3_value !== (t3_value = /*lastPulledFiles*/ + ctx2[7].length + "")) + set_data(t3, t3_value); + if ( + /*lastPulledFilesOpen*/ + ctx2[14] + ) { + if (if_block) { + if_block.p(ctx2, dirty); + if (dirty[0] & /*lastPulledFilesOpen*/ + 16384) { + transition_in(if_block, 1); + } + } else { + if_block = create_if_block_23(ctx2); + if_block.c(); + transition_in(if_block, 1); + if_block.m(div3, null); + } + } else if (if_block) { + group_outros(); + transition_out(if_block, 1, 1, () => { + if_block = null; + }); + check_outros(); + } + if (!current || dirty[0] & /*lastPulledFilesOpen*/ + 16384) { + toggle_class(div3, "is-collapsed", !/*lastPulledFilesOpen*/ + ctx2[14]); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + current = true; + }, + o(local) { + transition_out(if_block); + current = false; + }, + d(detaching) { + if (detaching) + detach(div3); + if (if_block) + if_block.d(); + mounted = false; + dispose(); + } + }; +} +function create_if_block_23(ctx) { + let div; + let current_block_type_index; + let if_block; + let div_transition; + let current; + const if_block_creators = [create_if_block_32, create_else_block4]; + const if_blocks = []; + function select_block_type_2(ctx2, dirty) { + if ( + /*showTree*/ + ctx2[3] + ) + return 0; + return 1; + } + current_block_type_index = select_block_type_2(ctx, [-1, -1]); + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); + return { + c() { + div = element("div"); + if_block.c(); + attr(div, "class", "tree-item-children nav-folder-children"); + }, + m(target, anchor) { + insert(target, div, anchor); + if_blocks[current_block_type_index].m(div, null); + current = true; + }, + p(ctx2, dirty) { + let previous_block_index = current_block_type_index; + current_block_type_index = select_block_type_2(ctx2, dirty); + if (current_block_type_index === previous_block_index) { + if_blocks[current_block_type_index].p(ctx2, dirty); + } else { + group_outros(); + transition_out(if_blocks[previous_block_index], 1, 1, () => { + if_blocks[previous_block_index] = null; + }); + check_outros(); + if_block = if_blocks[current_block_type_index]; + if (!if_block) { + if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); + if_block.c(); + } else { + if_block.p(ctx2, dirty); + } + transition_in(if_block, 1); + if_block.m(div, null); + } + }, + i(local) { + if (current) + return; + transition_in(if_block); + if (local) { + add_render_callback(() => { + if (!current) + return; + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, true); + div_transition.run(1); + }); + } + current = true; + }, + o(local) { + transition_out(if_block); + if (local) { + if (!div_transition) + div_transition = create_bidirectional_transition(div, slide, { duration: 150 }, false); + div_transition.run(0); + } + current = false; + }, + d(detaching) { + if (detaching) + detach(div); + if_blocks[current_block_type_index].d(); + if (detaching && div_transition) + div_transition.end(); + } + }; +} +function create_else_block4(ctx) { + let each_1_anchor; + let current; + let each_value = ( + /*lastPulledFiles*/ + ctx[7] + ); + let each_blocks = []; + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block5(get_each_context5(ctx, each_value, i)); + } + const out = (i) => transition_out(each_blocks[i], 1, 1, () => { + each_blocks[i] = null; + }); + return { + c() { + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + each_1_anchor = empty(); + }, + m(target, anchor) { + for (let i = 0; i < each_blocks.length; i += 1) { + if (each_blocks[i]) { + each_blocks[i].m(target, anchor); + } + } + insert(target, each_1_anchor, anchor); + current = true; + }, + p(ctx2, dirty) { + if (dirty[0] & /*lastPulledFiles, view*/ + 130) { + each_value = /*lastPulledFiles*/ + ctx2[7]; + let i; + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context5(ctx2, each_value, i); + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + transition_in(each_blocks[i], 1); + } else { + each_blocks[i] = create_each_block5(child_ctx); + each_blocks[i].c(); + transition_in(each_blocks[i], 1); + each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor); + } + } + group_outros(); + for (i = each_value.length; i < each_blocks.length; i += 1) { + out(i); + } + check_outros(); + } + }, + i(local) { + if (current) + return; + for (let i = 0; i < each_value.length; i += 1) { + transition_in(each_blocks[i]); + } + current = true; + }, + o(local) { + each_blocks = each_blocks.filter(Boolean); + for (let i = 0; i < each_blocks.length; i += 1) { + transition_out(each_blocks[i]); + } + current = false; + }, + d(detaching) { + destroy_each(each_blocks, detaching); + if (detaching) + detach(each_1_anchor); + } + }; +} +function create_if_block_32(ctx) { + let treecomponent; + let current; + treecomponent = new treeComponent_default({ + props: { + hierarchy: ( + /*lastPulledFilesHierarchy*/ + ctx[11] + ), + plugin: ( + /*plugin*/ + ctx[0] + ), + view: ( + /*view*/ + ctx[1] + ), + fileType: 2 /* pulled */, + topLevel: true + } + }); + return { + c() { + create_component(treecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(treecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const treecomponent_changes = {}; + if (dirty[0] & /*lastPulledFilesHierarchy*/ + 2048) + treecomponent_changes.hierarchy = /*lastPulledFilesHierarchy*/ + ctx2[11]; + if (dirty[0] & /*plugin*/ + 1) + treecomponent_changes.plugin = /*plugin*/ + ctx2[0]; + if (dirty[0] & /*view*/ + 2) + treecomponent_changes.view = /*view*/ + ctx2[1]; + treecomponent.$set(treecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(treecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(treecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(treecomponent, detaching); + } + }; +} +function create_each_block5(ctx) { + let pulledfilecomponent; + let current; + pulledfilecomponent = new pulledFileComponent_default({ + props: { + change: ( + /*change*/ + ctx[40] + ), + view: ( + /*view*/ + ctx[1] + ) + } + }); + pulledfilecomponent.$on("git-refresh", triggerRefresh2); + return { + c() { + create_component(pulledfilecomponent.$$.fragment); + }, + m(target, anchor) { + mount_component(pulledfilecomponent, target, anchor); + current = true; + }, + p(ctx2, dirty) { + const pulledfilecomponent_changes = {}; + if (dirty[0] & /*lastPulledFiles*/ + 128) + pulledfilecomponent_changes.change = /*change*/ + ctx2[40]; + if (dirty[0] & /*view*/ + 2) + pulledfilecomponent_changes.view = /*view*/ + ctx2[1]; + pulledfilecomponent.$set(pulledfilecomponent_changes); + }, + i(local) { + if (current) + return; + transition_in(pulledfilecomponent.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(pulledfilecomponent.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(pulledfilecomponent, detaching); + } + }; +} +function create_fragment9(ctx) { + let main; + let div9; + let div8; + let div0; + let t0; + let div1; + let t1; + let div2; + let t2; + let div3; + let t3; + let div4; + let t4; + let div5; + let t5; + let div6; + let t6; + let div7; + let t7; + let div10; + let textarea; + let t8; + let t9; + let div11; + let current; + let mounted; + let dispose; + let if_block0 = ( + /*commitMessage*/ + ctx[2] && create_if_block_8(ctx) + ); + let if_block1 = ( + /*status*/ + ctx[6] && /*stagedHierarchy*/ + ctx[10] && /*changeHierarchy*/ + ctx[9] && create_if_block8(ctx) + ); + return { + c() { + main = element("main"); + div9 = element("div"); + div8 = element("div"); + div0 = element("div"); + t0 = space(); + div1 = element("div"); + t1 = space(); + div2 = element("div"); + t2 = space(); + div3 = element("div"); + t3 = space(); + div4 = element("div"); + t4 = space(); + div5 = element("div"); + t5 = space(); + div6 = element("div"); + t6 = space(); + div7 = element("div"); + t7 = space(); + div10 = element("div"); + textarea = element("textarea"); + t8 = space(); + if (if_block0) + if_block0.c(); + t9 = space(); + div11 = element("div"); + if (if_block1) + if_block1.c(); + attr(div0, "id", "backup-btn"); + attr(div0, "data-icon", "arrow-up-circle"); + attr(div0, "class", "clickable-icon nav-action-button"); + attr(div0, "aria-label", "Backup"); + attr(div1, "id", "commit-btn"); + attr(div1, "data-icon", "check"); + attr(div1, "class", "clickable-icon nav-action-button"); + attr(div1, "aria-label", "Commit"); + attr(div2, "id", "stage-all"); + attr(div2, "class", "clickable-icon nav-action-button"); + attr(div2, "data-icon", "plus-circle"); + attr(div2, "aria-label", "Stage all"); + attr(div3, "id", "unstage-all"); + attr(div3, "class", "clickable-icon nav-action-button"); + attr(div3, "data-icon", "minus-circle"); + attr(div3, "aria-label", "Unstage all"); + attr(div4, "id", "push"); + attr(div4, "class", "clickable-icon nav-action-button"); + attr(div4, "data-icon", "upload"); + attr(div4, "aria-label", "Push"); + attr(div5, "id", "pull"); + attr(div5, "class", "clickable-icon nav-action-button"); + attr(div5, "data-icon", "download"); + attr(div5, "aria-label", "Pull"); + attr(div6, "id", "layoutChange"); + attr(div6, "class", "clickable-icon nav-action-button"); + attr(div6, "aria-label", "Change Layout"); + attr(div7, "id", "refresh"); + attr(div7, "class", "clickable-icon nav-action-button"); + attr(div7, "data-icon", "refresh-cw"); + attr(div7, "aria-label", "Refresh"); + set_style(div7, "margin", "1px"); + toggle_class( + div7, + "loading", + /*loading*/ + ctx[5] + ); + attr(div8, "class", "nav-buttons-container"); + attr(div9, "class", "nav-header"); + attr( + textarea, + "rows", + /*rows*/ + ctx[15] + ); + attr(textarea, "class", "commit-msg-input svelte-48bivb"); + attr(textarea, "spellcheck", "true"); + attr(textarea, "placeholder", "Commit Message"); + attr(div10, "class", "git-commit-msg svelte-48bivb"); + attr(div11, "class", "nav-files-container"); + set_style(div11, "position", "relative"); + attr(main, "class", "svelte-48bivb"); + }, + m(target, anchor) { + insert(target, main, anchor); + append2(main, div9); + append2(div9, div8); + append2(div8, div0); + ctx[23](div0); + append2(div8, t0); + append2(div8, div1); + ctx[24](div1); + append2(div8, t1); + append2(div8, div2); + ctx[25](div2); + append2(div8, t2); + append2(div8, div3); + ctx[26](div3); + append2(div8, t3); + append2(div8, div4); + ctx[27](div4); + append2(div8, t4); + append2(div8, div5); + ctx[28](div5); + append2(div8, t5); + append2(div8, div6); + ctx[29](div6); + append2(div8, t6); + append2(div8, div7); + ctx[31](div7); + append2(main, t7); + append2(main, div10); + append2(div10, textarea); + set_input_value( + textarea, + /*commitMessage*/ + ctx[2] + ); + append2(div10, t8); + if (if_block0) + if_block0.m(div10, null); + append2(main, t9); + append2(main, div11); + if (if_block1) + if_block1.m(div11, null); + current = true; + if (!mounted) { + dispose = [ + listen( + div0, + "click", + /*backup*/ + ctx[17] + ), + listen( + div1, + "click", + /*commit*/ + ctx[16] + ), + listen( + div2, + "click", + /*stageAll*/ + ctx[18] + ), + listen( + div3, + "click", + /*unstageAll*/ + ctx[19] + ), + listen( + div4, + "click", + /*push*/ + ctx[20] + ), + listen( + div5, + "click", + /*pull*/ + ctx[21] + ), + listen( + div6, + "click", + /*click_handler*/ + ctx[30] + ), + listen(div7, "click", triggerRefresh2), + listen( + textarea, + "input", + /*textarea_input_handler*/ + ctx[32] + ) + ]; + mounted = true; + } + }, + p(ctx2, dirty) { + if (!current || dirty[0] & /*loading*/ + 32) { + toggle_class( + div7, + "loading", + /*loading*/ + ctx2[5] + ); + } + if (!current || dirty[0] & /*rows*/ + 32768) { + attr( + textarea, + "rows", + /*rows*/ + ctx2[15] + ); + } + if (dirty[0] & /*commitMessage*/ + 4) { + set_input_value( + textarea, + /*commitMessage*/ + ctx2[2] + ); + } + if ( + /*commitMessage*/ + ctx2[2] + ) { + if (if_block0) { + if_block0.p(ctx2, dirty); + } else { + if_block0 = create_if_block_8(ctx2); + if_block0.c(); + if_block0.m(div10, null); + } + } else if (if_block0) { + if_block0.d(1); + if_block0 = null; + } + if ( + /*status*/ + ctx2[6] && /*stagedHierarchy*/ + ctx2[10] && /*changeHierarchy*/ + ctx2[9] + ) { + if (if_block1) { + if_block1.p(ctx2, dirty); + if (dirty[0] & /*status, stagedHierarchy, changeHierarchy*/ + 1600) { + transition_in(if_block1, 1); + } + } else { + if_block1 = create_if_block8(ctx2); + if_block1.c(); + transition_in(if_block1, 1); + if_block1.m(div11, null); + } + } else if (if_block1) { + group_outros(); + transition_out(if_block1, 1, 1, () => { + if_block1 = null; + }); + check_outros(); + } + }, + i(local) { + if (current) + return; + transition_in(if_block1); + current = true; + }, + o(local) { + transition_out(if_block1); + current = false; + }, + d(detaching) { + if (detaching) + detach(main); + ctx[23](null); + ctx[24](null); + ctx[25](null); + ctx[26](null); + ctx[27](null); + ctx[28](null); + ctx[29](null); + ctx[31](null); + if (if_block0) + if_block0.d(); + if (if_block1) + if_block1.d(); + mounted = false; + run_all(dispose); + } + }; +} +function triggerRefresh2() { + dispatchEvent(new CustomEvent("git-refresh")); +} +function instance9($$self, $$props, $$invalidate) { + let rows; + let { plugin } = $$props; + let { view } = $$props; + let loading; + let status2; + let lastPulledFiles = []; + let commitMessage = plugin.settings.commitMessage; + let buttons = []; + let changeHierarchy; + let stagedHierarchy; + let lastPulledFilesHierarchy; + let changesOpen = true; + let stagedOpen = true; + let lastPulledFilesOpen = true; + let showTree = plugin.settings.treeStructure; + let layoutBtn; + addEventListener("git-view-refresh", refresh); + plugin.app.workspace.onLayoutReady(() => { + window.setTimeout( + () => { + buttons.forEach((btn) => (0, import_obsidian28.setIcon)(btn, btn.getAttr("data-icon"), 16)); + (0, import_obsidian28.setIcon)(layoutBtn, showTree ? "list" : "folder", 16); + }, + 0 + ); + }); + onDestroy(() => { + removeEventListener("git-view-refresh", refresh); + }); + function commit2() { + return __awaiter(this, void 0, void 0, function* () { + $$invalidate(5, loading = true); + if (status2) { + if (yield plugin.hasTooBigFiles(status2.staged)) { + plugin.setState(0 /* idle */); + return false; + } + plugin.promiseQueue.addTask(() => plugin.gitManager.commit(commitMessage).then(() => { + if (commitMessage !== plugin.settings.commitMessage) { + $$invalidate(2, commitMessage = ""); + } + plugin.setUpAutoBackup(); + }).finally(triggerRefresh2)); + } + }); + } + function backup() { + return __awaiter(this, void 0, void 0, function* () { + $$invalidate(5, loading = true); + if (status2) { + plugin.promiseQueue.addTask(() => plugin.createBackup(false, false, commitMessage).then(() => { + if (commitMessage !== plugin.settings.commitMessage) { + $$invalidate(2, commitMessage = ""); + } + }).finally(triggerRefresh2)); + } + }); + } + function refresh() { + return __awaiter(this, void 0, void 0, function* () { + if (!plugin.gitReady) { + $$invalidate(6, status2 = void 0); + return; + } + $$invalidate(6, status2 = plugin.cachedStatus); + if (plugin.lastPulledFiles && plugin.lastPulledFiles != lastPulledFiles) { + $$invalidate(7, lastPulledFiles = plugin.lastPulledFiles); + $$invalidate(11, lastPulledFilesHierarchy = { + title: "", + path: "", + vaultPath: "", + children: plugin.gitManager.getTreeStructure(lastPulledFiles) + }); + } + if (status2) { + const sort = (a, b) => { + return a.vault_path.split("/").last().localeCompare(getDisplayPath(b.vault_path)); + }; + status2.changed.sort(sort); + status2.staged.sort(sort); + if (status2.changed.length + status2.staged.length > 500) { + $$invalidate(6, status2 = void 0); + if (!plugin.loading) { + plugin.displayError("Too many changes to display"); + } + } else { + $$invalidate(9, changeHierarchy = { + title: "", + path: "", + vaultPath: "", + children: plugin.gitManager.getTreeStructure(status2.changed) + }); + $$invalidate(10, stagedHierarchy = { + title: "", + path: "", + vaultPath: "", + children: plugin.gitManager.getTreeStructure(status2.staged) + }); + } + } else { + $$invalidate(9, changeHierarchy = void 0); + $$invalidate(10, stagedHierarchy = void 0); + } + $$invalidate(5, loading = plugin.loading); + }); + } + function stageAll() { + $$invalidate(5, loading = true); + plugin.promiseQueue.addTask(() => plugin.gitManager.stageAll({ status: status2 }).finally(triggerRefresh2)); + } + function unstageAll() { + $$invalidate(5, loading = true); + plugin.promiseQueue.addTask(() => plugin.gitManager.unstageAll({ status: status2 }).finally(triggerRefresh2)); + } + function push2() { + $$invalidate(5, loading = true); + plugin.promiseQueue.addTask(() => plugin.push().finally(triggerRefresh2)); + } + function pull2() { + $$invalidate(5, loading = true); + plugin.promiseQueue.addTask(() => plugin.pullChangesFromRemote().finally(triggerRefresh2)); + } + function discard() { + new DiscardModal(view.app, false, plugin.gitManager.getVaultPath("/")).myOpen().then((shouldDiscard) => { + if (shouldDiscard === true) { + plugin.promiseQueue.addTask(() => plugin.gitManager.discardAll({ status: plugin.cachedStatus }).finally(() => { + dispatchEvent(new CustomEvent("git-refresh")); + })); + } + }); + } + function div0_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[5] = $$value; + $$invalidate(8, buttons); + }); + } + function div1_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[0] = $$value; + $$invalidate(8, buttons); + }); + } + function div2_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[1] = $$value; + $$invalidate(8, buttons); + }); + } + function div3_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[2] = $$value; + $$invalidate(8, buttons); + }); + } + function div4_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[3] = $$value; + $$invalidate(8, buttons); + }); + } + function div5_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[4] = $$value; + $$invalidate(8, buttons); + }); + } + function div6_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + layoutBtn = $$value; + $$invalidate(4, layoutBtn); + }); + } + const click_handler = () => { + $$invalidate(3, showTree = !showTree); + $$invalidate(0, plugin.settings.treeStructure = showTree, plugin); + plugin.saveSettings(); + }; + function div7_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[6] = $$value; + $$invalidate(8, buttons); + }); + } + function textarea_input_handler() { + commitMessage = this.value; + $$invalidate(2, commitMessage); + } + const click_handler_1 = () => $$invalidate(2, commitMessage = ""); + function div2_binding_1($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[8] = $$value; + $$invalidate(8, buttons); + }); + } + const click_handler_2 = () => $$invalidate(13, stagedOpen = !stagedOpen); + function div11_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + buttons[9] = $$value; + $$invalidate(8, buttons); + }); + } + const click_handler_3 = () => $$invalidate(12, changesOpen = !changesOpen); + const click_handler_4 = () => $$invalidate(14, lastPulledFilesOpen = !lastPulledFilesOpen); + $$self.$$set = ($$props2) => { + if ("plugin" in $$props2) + $$invalidate(0, plugin = $$props2.plugin); + if ("view" in $$props2) + $$invalidate(1, view = $$props2.view); + }; + $$self.$$.update = () => { + if ($$self.$$.dirty[0] & /*layoutBtn, showTree*/ + 24) { + $: { + if (layoutBtn) { + layoutBtn.empty(); + (0, import_obsidian28.setIcon)(layoutBtn, showTree ? "list" : "folder", 16); + } + } + } + if ($$self.$$.dirty[0] & /*commitMessage*/ + 4) { + $: + $$invalidate(15, rows = (commitMessage.match(/\n/g) || []).length + 1 || 1); + } + }; + return [ + plugin, + view, + commitMessage, + showTree, + layoutBtn, + loading, + status2, + lastPulledFiles, + buttons, + changeHierarchy, + stagedHierarchy, + lastPulledFilesHierarchy, + changesOpen, + stagedOpen, + lastPulledFilesOpen, + rows, + commit2, + backup, + stageAll, + unstageAll, + push2, + pull2, + discard, + div0_binding, + div1_binding, + div2_binding, + div3_binding, + div4_binding, + div5_binding, + div6_binding, + click_handler, + div7_binding, + textarea_input_handler, + click_handler_1, + div2_binding_1, + click_handler_2, + div11_binding, + click_handler_3, + click_handler_4 + ]; +} +var SourceControl = class extends SvelteComponent { + constructor(options) { + super(); + init2(this, options, instance9, create_fragment9, safe_not_equal, { plugin: 0, view: 1 }, add_css8, [-1, -1]); + } +}; +var sourceControl_default = SourceControl; + +// src/ui/sourceControl/sourceControl.ts +var GitView = class extends import_obsidian29.ItemView { + constructor(leaf, plugin) { + super(leaf); + this.plugin = plugin; + this.hoverPopover = null; + } + getViewType() { + return SOURCE_CONTROL_VIEW_CONFIG.type; + } + getDisplayText() { + return SOURCE_CONTROL_VIEW_CONFIG.name; + } + getIcon() { + return SOURCE_CONTROL_VIEW_CONFIG.icon; + } + onClose() { + return super.onClose(); + } + onOpen() { + this._view = new sourceControl_default({ + target: this.contentEl, + props: { + plugin: this.plugin, + view: this + } + }); + return super.onOpen(); + } +}; + +// src/ui/statusBar/branchStatusBar.ts +init_polyfill_buffer(); +var BranchStatusBar = class { + constructor(statusBarEl, plugin) { + this.statusBarEl = statusBarEl; + this.plugin = plugin; + this.statusBarEl.addClass("mod-clickable"); + this.statusBarEl.onClickEvent((e) => { + this.plugin.switchBranch(); + }); + } + async display() { + if (this.plugin.gitReady) { + const branchInfo = await this.plugin.gitManager.branchInfo(); + if (branchInfo.current != void 0) { + this.statusBarEl.setText(branchInfo.current); + } else { + this.statusBarEl.empty(); + } + } else { + this.statusBarEl.empty(); + } + } +}; + +// src/main.ts +var ObsidianGit = class extends import_obsidian30.Plugin { + constructor() { + super(...arguments); + this.gitReady = false; + this.promiseQueue = new PromiseQueue(); + this.conflictOutputFile = "conflict-files-obsidian-git.md"; + this.offlineMode = false; + this.loading = false; + this.lineAuthoringFeature = new LineAuthoringFeature(this); + } + setState(state) { + var _a2; + this.state = state; + (_a2 = this.statusBar) == null ? void 0 : _a2.display(); + } + async updateCachedStatus() { + this.cachedStatus = await this.gitManager.status(); + return this.cachedStatus; + } + async refresh() { + const gitView = this.app.workspace.getLeavesOfType( + SOURCE_CONTROL_VIEW_CONFIG.type + ); + const historyView = this.app.workspace.getLeavesOfType( + HISTORY_VIEW_CONFIG.type + ); + if (this.settings.changedFilesInStatusBar || gitView.length > 0 || historyView.length > 0) { + this.loading = true; + dispatchEvent(new CustomEvent("git-view-refresh")); + await this.updateCachedStatus(); + this.loading = false; + dispatchEvent(new CustomEvent("git-view-refresh")); + } + } + async refreshUpdatedHead() { + this.lineAuthoringFeature.refreshLineAuthorViews(); + } + async onload() { + console.log("loading " + this.manifest.name + " plugin"); + pluginRef.plugin = this; + this.localStorage = new LocalStorageSettings(this); + this.localStorage.migrate(); + await this.loadSettings(); + this.migrateSettings(); + this.settingsTab = new ObsidianGitSettingsTab(this.app, this); + this.addSettingTab(this.settingsTab); + if (!this.localStorage.getPluginDisabled()) { + this.loadPlugin(); + } + } + async loadPlugin() { + addEventListener("git-refresh", this.refresh.bind(this)); + addEventListener("git-head-update", this.refreshUpdatedHead.bind(this)); + this.registerView(SOURCE_CONTROL_VIEW_CONFIG.type, (leaf) => { + return new GitView(leaf, this); + }); + this.registerView(HISTORY_VIEW_CONFIG.type, (leaf) => { + return new HistoryView2(leaf, this); + }); + this.registerView(DIFF_VIEW_CONFIG.type, (leaf) => { + return new DiffView(leaf, this); + }); + this.lineAuthoringFeature.onLoadPlugin(); + this.app.workspace.registerHoverLinkSource( + SOURCE_CONTROL_VIEW_CONFIG.type, + { + display: "Git View", + defaultMod: true + } + ); + this.setRefreshDebouncer(); + this.addCommand({ + id: "edit-gitignore", + name: "Edit .gitignore", + callback: async () => { + const path2 = this.gitManager.getVaultPath(".gitignore"); + if (!await this.app.vault.adapter.exists(path2)) { + this.app.vault.adapter.write(path2, ""); + } + const content = await this.app.vault.adapter.read(path2); + const modal = new IgnoreModal(this.app, content); + const res = await modal.open(); + if (res !== void 0) { + await this.app.vault.adapter.write(path2, res); + this.refresh(); + } + } + }); + this.addCommand({ + id: "open-git-view", + name: "Open source control view", + callback: async () => { + const leafs = this.app.workspace.getLeavesOfType( + SOURCE_CONTROL_VIEW_CONFIG.type + ); + let leaf; + if (leafs.length === 0) { + leaf = this.app.workspace.getRightLeaf(false); + await leaf.setViewState({ + type: SOURCE_CONTROL_VIEW_CONFIG.type + }); + } else { + leaf = leafs.first(); + } + this.app.workspace.revealLeaf(leaf); + dispatchEvent(new CustomEvent("git-refresh")); + } + }); + this.addCommand({ + id: "open-history-view", + name: "Open history view", + callback: async () => { + const leafs = this.app.workspace.getLeavesOfType( + HISTORY_VIEW_CONFIG.type + ); + let leaf; + if (leafs.length === 0) { + leaf = this.app.workspace.getRightLeaf(false); + await leaf.setViewState({ + type: HISTORY_VIEW_CONFIG.type + }); + } else { + leaf = leafs.first(); + } + this.app.workspace.revealLeaf(leaf); + dispatchEvent(new CustomEvent("git-refresh")); + } + }); + this.addCommand({ + id: "open-diff-view", + name: "Open diff view", + checkCallback: (checking) => { + var _a2; + const file = this.app.workspace.getActiveFile(); + if (checking) { + return file !== null; + } else { + (_a2 = getNewLeaf()) == null ? void 0 : _a2.setViewState({ + type: DIFF_VIEW_CONFIG.type, + active: true, + state: { + staged: false, + file: this.gitManager.asRepositoryRelativePath( + file.path, + true + ) + } + }); + } + } + }); + this.addCommand({ + id: "view-file-on-github", + name: "Open file on GitHub", + editorCallback: (editor, { file }) => openLineInGitHub(editor, file, this.gitManager) + }); + this.addCommand({ + id: "view-history-on-github", + name: "Open file history on GitHub", + editorCallback: (_, { file }) => openHistoryInGitHub(file, this.gitManager) + }); + this.addCommand({ + id: "pull", + name: "Pull", + callback: () => this.promiseQueue.addTask(() => this.pullChangesFromRemote()) + }); + this.addCommand({ + id: "switch-to-remote-branch", + name: "Switch to remote branch", + callback: () => this.promiseQueue.addTask(() => this.switchRemoteBranch()) + }); + this.addCommand({ + id: "add-to-gitignore", + name: "Add file to gitignore", + checkCallback: (checking) => { + const file = app.workspace.getActiveFile(); + if (checking) { + return file !== null; + } else { + app.vault.adapter.append( + this.gitManager.getVaultPath(".gitignore"), + "\n" + this.gitManager.asRepositoryRelativePath( + file.path, + true + ) + ).then(() => { + this.refresh(); + }); + } + } + }); + this.addCommand({ + id: "push", + name: "Create backup", + callback: () => this.promiseQueue.addTask(() => this.createBackup(false)) + }); + this.addCommand({ + id: "backup-and-close", + name: "Create backup and close", + callback: () => this.promiseQueue.addTask(async () => { + await this.createBackup(false); + window.close(); + }) + }); + this.addCommand({ + id: "commit-push-specified-message", + name: "Create backup with specific message", + callback: () => this.promiseQueue.addTask(() => this.createBackup(false, true)) + }); + this.addCommand({ + id: "commit", + name: "Commit all changes", + callback: () => this.promiseQueue.addTask( + () => this.commit({ fromAutoBackup: false }) + ) + }); + this.addCommand({ + id: "commit-specified-message", + name: "Commit all changes with specific message", + callback: () => this.promiseQueue.addTask( + () => this.commit({ + fromAutoBackup: false, + requestCustomMessage: true + }) + ) + }); + this.addCommand({ + id: "commit-staged", + name: "Commit staged", + callback: () => this.promiseQueue.addTask( + () => this.commit({ + fromAutoBackup: false, + requestCustomMessage: false, + onlyStaged: true + }) + ) + }); + this.addCommand({ + id: "commit-staged-specified-message", + name: "Commit staged with specific message", + callback: () => this.promiseQueue.addTask( + () => this.commit({ + fromAutoBackup: false, + requestCustomMessage: true, + onlyStaged: true + }) + ) + }); + this.addCommand({ + id: "push2", + name: "Push", + callback: () => this.promiseQueue.addTask(() => this.push()) + }); + this.addCommand({ + id: "stage-current-file", + name: "Stage current file", + checkCallback: (checking) => { + const file = this.app.workspace.getActiveFile(); + if (checking) { + return file !== null; + } else { + this.promiseQueue.addTask(() => this.stageFile(file)); + } + } + }); + this.addCommand({ + id: "unstage-current-file", + name: "Unstage current file", + checkCallback: (checking) => { + const file = this.app.workspace.getActiveFile(); + if (checking) { + return file !== null; + } else { + this.promiseQueue.addTask(() => this.unstageFile(file)); + } + } + }); + this.addCommand({ + id: "edit-remotes", + name: "Edit remotes", + callback: async () => this.editRemotes() + }); + this.addCommand({ + id: "remove-remote", + name: "Remove remote", + callback: async () => this.removeRemote() + }); + this.addCommand({ + id: "delete-repo", + name: "CAUTION: Delete repository", + callback: async () => { + const repoExists = await this.app.vault.adapter.exists( + `${this.settings.basePath}/.git` + ); + if (repoExists) { + const modal = new GeneralModal({ + options: ["NO", "YES"], + placeholder: "Do you really want to delete the repository (.git directory)? This action cannot be undone.", + onlySelection: true + }); + const shouldDelete = await modal.open() === "YES"; + if (shouldDelete) { + await this.app.vault.adapter.rmdir( + `${this.settings.basePath}/.git`, + true + ); + new import_obsidian30.Notice( + "Successfully deleted repository. Reloading plugin..." + ); + this.unloadPlugin(); + this.init(); + } + } else { + new import_obsidian30.Notice("No repository found"); + } + } + }); + this.addCommand({ + id: "init-repo", + name: "Initialize a new repo", + callback: async () => this.createNewRepo() + }); + this.addCommand({ + id: "clone-repo", + name: "Clone an existing remote repo", + callback: async () => this.cloneNewRepo() + }); + this.addCommand({ + id: "list-changed-files", + name: "List changed files", + callback: async () => { + if (!await this.isAllInitialized()) + return; + const status2 = await this.gitManager.status(); + this.setState(0 /* idle */); + if (status2.changed.length + status2.staged.length > 500) { + this.displayError("Too many changes to display"); + return; + } + new ChangedFilesModal(this, status2.changed).open(); + } + }); + this.addCommand({ + id: "switch-branch", + name: "Switch branch", + callback: () => { + this.switchBranch(); + } + }); + this.addCommand({ + id: "create-branch", + name: "Create new branch", + callback: () => { + this.createBranch(); + } + }); + this.addCommand({ + id: "delete-branch", + name: "Delete branch", + callback: () => { + this.deleteBranch(); + } + }); + this.addCommand({ + id: "discard-all", + name: "CAUTION: Discard all changes", + callback: async () => { + if (!await this.isAllInitialized()) + return false; + const modal = new GeneralModal({ + options: ["NO", "YES"], + placeholder: "Do you want to discard all changes to tracked files? This action cannot be undone.", + onlySelection: true + }); + const shouldDiscardAll = await modal.open() === "YES"; + if (shouldDiscardAll) { + this.promiseQueue.addTask(() => this.discardAll()); + } + } + }); + this.addCommand({ + id: "toggle-line-author-info", + name: "Toggle line author information", + callback: () => { + var _a2; + return (_a2 = this.settingsTab) == null ? void 0 : _a2.configureLineAuthorShowStatus( + !this.settings.lineAuthor.show + ); + } + }); + this.registerEvent( + this.app.workspace.on("file-menu", (menu, file, source) => { + this.handleFileMenu(menu, file, source); + }) + ); + if (this.settings.showStatusBar) { + const statusBarEl = this.addStatusBarItem(); + this.statusBar = new StatusBar(statusBarEl, this); + this.registerInterval( + window.setInterval(() => { + var _a2; + return (_a2 = this.statusBar) == null ? void 0 : _a2.display(); + }, 1e3) + ); + } + if (import_obsidian30.Platform.isDesktop && this.settings.showBranchStatusBar) { + const branchStatusBarEl = this.addStatusBarItem(); + this.branchBar = new BranchStatusBar(branchStatusBarEl, this); + this.registerInterval( + window.setInterval(() => { + var _a2; + return (_a2 = this.branchBar) == null ? void 0 : _a2.display(); + }, 6e4) + ); + } + this.app.workspace.onLayoutReady(() => this.init()); + } + setRefreshDebouncer() { + var _a2; + (_a2 = this.debRefresh) == null ? void 0 : _a2.cancel(); + this.debRefresh = (0, import_obsidian30.debounce)( + () => { + if (this.settings.refreshSourceControl) { + this.refresh(); + } + }, + this.settings.refreshSourceControlTimer, + true + ); + } + async showNotices() { + const length = 1e4; + if (this.manifest.id === "obsidian-git" && import_obsidian30.Platform.isDesktopApp && !this.settings.showedMobileNotice) { + new import_obsidian30.Notice( + "Obsidian Git is now available on mobile! Please read the plugin's README for more information.", + length + ); + this.settings.showedMobileNotice = true; + await this.saveSettings(); + } + if (this.manifest.id === "obsidian-git-isomorphic") { + new import_obsidian30.Notice( + "Obsidian Git Mobile is now deprecated. Please uninstall it and install Obsidian Git instead.", + length + ); + } + } + handleFileMenu(menu, file, source) { + if (!this.settings.showFileMenu) + return; + if (source !== "file-explorer-context-menu") { + return; + } + if (!file) { + return; + } + if (!this.gitReady) + return; + menu.addItem((item) => { + item.setTitle(`Git: Stage`).setIcon("plus-circle").setSection("action").onClick((_) => { + this.promiseQueue.addTask(async () => { + if (file instanceof import_obsidian30.TFile) { + await this.gitManager.stage(file.path, true); + } else { + await this.gitManager.stageAll({ + dir: this.gitManager.asRepositoryRelativePath( + file.path, + true + ) + }); + } + this.displayMessage(`Staged ${file.path}`); + }); + }); + }); + menu.addItem((item) => { + item.setTitle(`Git: Unstage`).setIcon("minus-circle").setSection("action").onClick((_) => { + this.promiseQueue.addTask(async () => { + if (file instanceof import_obsidian30.TFile) { + await this.gitManager.unstage(file.path, true); + } else { + await this.gitManager.unstageAll({ + dir: this.gitManager.asRepositoryRelativePath( + file.path, + true + ) + }); + } + this.displayMessage(`Unstaged ${file.path}`); + }); + }); + }); + } + async migrateSettings() { + if (this.settings.mergeOnPull != void 0) { + this.settings.syncMethod = this.settings.mergeOnPull ? "merge" : "rebase"; + this.settings.mergeOnPull = void 0; + await this.saveSettings(); + } + if (this.settings.autoCommitMessage === void 0) { + this.settings.autoCommitMessage = this.settings.commitMessage; + await this.saveSettings(); + } + if (this.settings.gitPath != void 0) { + this.localStorage.setGitPath(this.settings.gitPath); + this.settings.gitPath = void 0; + await this.saveSettings(); + } + if (this.settings.username != void 0) { + this.localStorage.setPassword(this.settings.username); + this.settings.username = void 0; + await this.saveSettings(); + } + } + unloadPlugin() { + this.gitReady = false; + dispatchEvent(new CustomEvent("git-refresh")); + this.lineAuthoringFeature.deactivateFeature(); + this.clearAutoPull(); + this.clearAutoPush(); + this.clearAutoBackup(); + removeEventListener("git-refresh", this.refresh.bind(this)); + removeEventListener( + "git-head-update", + this.refreshUpdatedHead.bind(this) + ); + this.app.metadataCache.offref(this.modifyEvent); + this.app.metadataCache.offref(this.deleteEvent); + this.app.metadataCache.offref(this.createEvent); + this.app.metadataCache.offref(this.renameEvent); + this.debRefresh.cancel(); + } + async onunload() { + this.app.workspace.unregisterHoverLinkSource( + SOURCE_CONTROL_VIEW_CONFIG.type + ); + this.unloadPlugin(); + console.log("unloading " + this.manifest.name + " plugin"); + } + async loadSettings() { + let data = await this.loadData(); + if (data == void 0) { + data = { showedMobileNotice: true }; + } + this.settings = mergeSettingsByPriority(DEFAULT_SETTINGS, data); + } + async saveSettings() { + var _a2; + (_a2 = this.settingsTab) == null ? void 0 : _a2.beforeSaveSettings(); + await this.saveData(this.settings); + } + saveLastAuto(date, mode) { + if (mode === "backup") { + this.localStorage.setLastAutoBackup(date.toString()); + } else if (mode === "pull") { + this.localStorage.setLastAutoPull(date.toString()); + } else if (mode === "push") { + this.localStorage.setLastAutoPush(date.toString()); + } + } + loadLastAuto() { + var _a2, _b, _c; + return { + backup: new Date((_a2 = this.localStorage.getLastAutoBackup()) != null ? _a2 : ""), + pull: new Date((_b = this.localStorage.getLastAutoPull()) != null ? _b : ""), + push: new Date((_c = this.localStorage.getLastAutoPush()) != null ? _c : "") + }; + } + get useSimpleGit() { + return import_obsidian30.Platform.isDesktopApp; + } + async init() { + var _a2; + this.showNotices(); + try { + if (this.useSimpleGit) { + this.gitManager = new SimpleGit(this); + await this.gitManager.setGitInstance(); + } else { + this.gitManager = new IsomorphicGit(this); + } + const result = await this.gitManager.checkRequirements(); + switch (result) { + case "missing-git": + this.displayError("Cannot run git command"); + break; + case "missing-repo": + new import_obsidian30.Notice( + "Can't find a valid git repository. Please create one via the given command or clone an existing repo.", + 1e4 + ); + break; + case "valid": + this.gitReady = true; + this.setState(0 /* idle */); + this.modifyEvent = this.app.vault.on("modify", () => { + this.debRefresh(); + }); + this.deleteEvent = this.app.vault.on("delete", () => { + this.debRefresh(); + }); + this.createEvent = this.app.vault.on("create", () => { + this.debRefresh(); + }); + this.renameEvent = this.app.vault.on("rename", () => { + this.debRefresh(); + }); + this.registerEvent(this.modifyEvent); + this.registerEvent(this.deleteEvent); + this.registerEvent(this.createEvent); + this.registerEvent(this.renameEvent); + (_a2 = this.branchBar) == null ? void 0 : _a2.display(); + this.lineAuthoringFeature.conditionallyActivateBySettings(); + dispatchEvent(new CustomEvent("git-refresh")); + if (this.settings.autoPullOnBoot) { + this.promiseQueue.addTask( + () => this.pullChangesFromRemote() + ); + } + this.setUpAutos(); + break; + default: + console.log( + "Something weird happened. The 'checkRequirements' result is " + result + ); + } + } catch (error) { + this.displayError(error); + console.error(error); + } + } + async createNewRepo() { + await this.gitManager.init(); + new import_obsidian30.Notice("Initialized new repo"); + await this.init(); + } + async cloneNewRepo() { + const modal = new GeneralModal({ placeholder: "Enter remote URL" }); + const url = await modal.open(); + if (url) { + const confirmOption = "Vault Root"; + let dir = await new GeneralModal({ + options: [confirmOption], + placeholder: "Enter directory for clone. It needs to be empty or not existent.", + allowEmpty: this.gitManager instanceof IsomorphicGit + }).open(); + if (dir !== void 0) { + if (dir === confirmOption) { + dir = "."; + } + dir = (0, import_obsidian30.normalizePath)(dir); + if (dir === "/") { + dir = "."; + } + if (dir === ".") { + const modal2 = new GeneralModal({ + options: ["NO", "YES"], + placeholder: `Does your remote repo contain a ${app.vault.configDir} directory at the root?`, + onlySelection: true + }); + const containsConflictDir = await modal2.open(); + if (containsConflictDir === void 0) { + new import_obsidian30.Notice("Aborted clone"); + return; + } else if (containsConflictDir === "YES") { + const confirmOption2 = "DELETE ALL YOUR LOCAL CONFIG AND PLUGINS"; + const modal3 = new GeneralModal({ + options: ["Abort clone", confirmOption2], + placeholder: `To avoid conflicts, the local ${app.vault.configDir} directory needs to be deleted.`, + onlySelection: true + }); + const shouldDelete = await modal3.open() === confirmOption2; + if (shouldDelete) { + await this.app.vault.adapter.rmdir( + app.vault.configDir, + true + ); + } else { + new import_obsidian30.Notice("Aborted clone"); + return; + } + } + } + const depth = await new GeneralModal({ + placeholder: "Specify depth of clone. Leave empty for full clone.", + allowEmpty: true + }).open(); + let depthInt = void 0; + if (depth !== "") { + depthInt = parseInt(depth); + if (isNaN(depthInt)) { + new import_obsidian30.Notice("Invalid depth. Aborting clone."); + return; + } + } + new import_obsidian30.Notice(`Cloning new repo into "${dir}"`); + const oldBase = this.settings.basePath; + const customDir = dir && dir !== "."; + if (customDir) { + this.settings.basePath = dir; + } + try { + await this.gitManager.clone(url, dir, depthInt); + } catch (error) { + this.settings.basePath = oldBase; + this.saveSettings(); + throw error; + } + new import_obsidian30.Notice("Cloned new repo."); + new import_obsidian30.Notice("Please restart Obsidian"); + if (customDir) { + this.saveSettings(); + } + } + } + } + /** + * Retries to call `this.init()` if necessary, otherwise returns directly + * @returns true if `this.gitManager` is ready to be used, false if not. + */ + async isAllInitialized() { + if (!this.gitReady) { + await this.init(); + } + return this.gitReady; + } + ///Used for command + async pullChangesFromRemote() { + if (!await this.isAllInitialized()) + return; + const filesUpdated = await this.pull(); + this.setUpAutoBackup(); + if (!filesUpdated) { + this.displayMessage("Everything is up-to-date"); + } + if (this.gitManager instanceof SimpleGit) { + const status2 = await this.gitManager.status(); + if (status2.conflicted.length > 0) { + this.displayError( + `You have conflicts in ${status2.conflicted.length} ${status2.conflicted.length == 1 ? "file" : "files"}` + ); + this.handleConflict(status2.conflicted); + } + } + dispatchEvent(new CustomEvent("git-refresh")); + this.setState(0 /* idle */); + } + async createBackup(fromAutoBackup, requestCustomMessage = false, commitMessage) { + if (!await this.isAllInitialized()) + return; + if (this.settings.syncMethod == "reset" && this.settings.pullBeforePush) { + await this.pull(); + } + if (!await this.commit({ + fromAutoBackup, + requestCustomMessage, + commitMessage + })) + return; + if (!this.settings.disablePush) { + if (await this.gitManager.canPush()) { + if (this.settings.syncMethod != "reset" && this.settings.pullBeforePush) { + await this.pull(); + } + await this.push(); + } else { + this.displayMessage("No changes to push"); + } + } + this.setState(0 /* idle */); + } + // Returns true if commit was successfully + async commit({ + fromAutoBackup, + requestCustomMessage = false, + onlyStaged = false, + commitMessage + }) { + if (!await this.isAllInitialized()) + return false; + let hadConflict = this.localStorage.getConflict() === "true"; + let changedFiles; + let status2; + let unstagedFiles; + if (this.gitManager instanceof SimpleGit) { + this.mayDeleteConflictFile(); + status2 = await this.updateCachedStatus(); + if (status2.conflicted.length == 0) { + this.localStorage.setConflict("false"); + hadConflict = false; + } + if (fromAutoBackup && status2.conflicted.length > 0) { + this.displayError( + `Did not commit, because you have conflicts in ${status2.conflicted.length} ${status2.conflicted.length == 1 ? "file" : "files"}. Please resolve them and commit per command.` + ); + this.handleConflict(status2.conflicted); + return false; + } + changedFiles = [...status2.changed, ...status2.staged]; + } else if (fromAutoBackup && hadConflict) { + this.setState(6 /* conflicted */); + this.displayError( + `Did not commit, because you have conflicts. Please resolve them and commit per command.` + ); + return false; + } else if (hadConflict) { + await this.mayDeleteConflictFile(); + status2 = await this.updateCachedStatus(); + changedFiles = [...status2.changed, ...status2.staged]; + } else { + if (onlyStaged) { + changedFiles = await this.gitManager.getStagedFiles(); + } else { + unstagedFiles = await this.gitManager.getUnstagedFiles(); + changedFiles = unstagedFiles.map(({ filepath }) => ({ + vault_path: this.gitManager.getVaultPath(filepath) + })); + } + } + if (await this.hasTooBigFiles(changedFiles)) { + this.setState(0 /* idle */); + return false; + } + if (changedFiles.length !== 0 || hadConflict) { + let cmtMessage = commitMessage != null ? commitMessage : commitMessage = fromAutoBackup ? this.settings.autoCommitMessage : this.settings.commitMessage; + if (fromAutoBackup && this.settings.customMessageOnAutoBackup || requestCustomMessage) { + if (!this.settings.disablePopups && fromAutoBackup) { + new import_obsidian30.Notice( + "Auto backup: Please enter a custom commit message. Leave empty to abort" + ); + } + const tempMessage = await new CustomMessageModal( + this, + true + ).open(); + if (tempMessage != void 0 && tempMessage != "" && tempMessage != "...") { + cmtMessage = tempMessage; + } else { + this.setState(0 /* idle */); + return false; + } + } + let committedFiles; + if (onlyStaged) { + committedFiles = await this.gitManager.commit(cmtMessage); + } else { + committedFiles = await this.gitManager.commitAll({ + message: cmtMessage, + status: status2, + unstagedFiles + }); + } + if (this.gitManager instanceof SimpleGit) { + if ((await this.updateCachedStatus()).conflicted.length == 0) { + this.localStorage.setConflict("false"); + } + } + let roughly = false; + if (committedFiles === void 0) { + roughly = true; + committedFiles = changedFiles.length; + } + this.setUpAutoBackup(); + this.displayMessage( + `Committed${roughly ? " approx." : ""} ${committedFiles} ${committedFiles == 1 ? "file" : "files"}` + ); + } else { + this.displayMessage("No changes to commit"); + } + dispatchEvent(new CustomEvent("git-refresh")); + this.setState(0 /* idle */); + return true; + } + async hasTooBigFiles(files) { + const branchInfo = await this.gitManager.branchInfo(); + const remote = branchInfo.tracking ? splitRemoteBranch(branchInfo.tracking)[0] : null; + if (remote) { + const remoteUrl = await this.gitManager.getRemoteUrl(remote); + if (remoteUrl == null ? void 0 : remoteUrl.includes("github.com")) { + const tooBigFiles = files.filter((f) => { + const file = this.app.vault.getAbstractFileByPath( + f.vault_path + ); + if (file instanceof import_obsidian30.TFile) { + return file.stat.size >= 1e8; + } + return false; + }); + if (tooBigFiles.length > 0) { + this.displayError( + `Did not commit, because following files are too big: ${tooBigFiles.map( + (e) => e.vault_path + )}. Please remove them.` + ); + return true; + } + } + } + return false; + } + async push() { + if (!await this.isAllInitialized()) + return false; + if (!await this.remotesAreSet()) { + return false; + } + const hadConflict = this.localStorage.getConflict() === "true"; + if (this.gitManager instanceof SimpleGit) + await this.mayDeleteConflictFile(); + let status2; + if (this.gitManager instanceof SimpleGit && (status2 = await this.updateCachedStatus()).conflicted.length > 0) { + this.displayError( + `Cannot push. You have conflicts in ${status2.conflicted.length} ${status2.conflicted.length == 1 ? "file" : "files"}` + ); + this.handleConflict(status2.conflicted); + return false; + } else if (this.gitManager instanceof IsomorphicGit && hadConflict) { + this.displayError(`Cannot push. You have conflicts`); + this.setState(6 /* conflicted */); + return false; + } + { + console.log("Pushing...."); + const pushedFiles = await this.gitManager.push(); + console.log("Pushed!", pushedFiles); + if (pushedFiles > 0) { + this.displayMessage( + `Pushed ${pushedFiles} ${pushedFiles == 1 ? "file" : "files"} to remote` + ); + } else { + this.displayMessage(`No changes to push`); + } + this.offlineMode = false; + this.setState(0 /* idle */); + return true; + } + } + /// Used for internals + /// Returns whether the pull added a commit or not. + async pull() { + if (!await this.remotesAreSet()) { + return false; + } + const pulledFiles = await this.gitManager.pull() || []; + this.offlineMode = false; + if (pulledFiles.length > 0) { + this.displayMessage( + `Pulled ${pulledFiles.length} ${pulledFiles.length == 1 ? "file" : "files"} from remote` + ); + this.lastPulledFiles = pulledFiles; + } + return pulledFiles.length != 0; + } + async mayDeleteConflictFile() { + const file = this.app.vault.getAbstractFileByPath( + this.conflictOutputFile + ); + if (file) { + this.app.workspace.iterateAllLeaves((leaf) => { + if (leaf.view instanceof import_obsidian30.MarkdownView && leaf.view.file.path == file.path) { + leaf.detach(); + } + }); + await this.app.vault.delete(file); + } + } + async stageFile(file) { + if (!await this.isAllInitialized()) + return false; + await this.gitManager.stage(file.path, true); + this.displayMessage(`Staged ${file.path}`); + dispatchEvent(new CustomEvent("git-refresh")); + this.setState(0 /* idle */); + return true; + } + async unstageFile(file) { + if (!await this.isAllInitialized()) + return false; + await this.gitManager.unstage(file.path, true); + this.displayMessage(`Unstaged ${file.path}`); + dispatchEvent(new CustomEvent("git-refresh")); + this.setState(0 /* idle */); + return true; + } + async switchBranch() { + var _a2; + if (!await this.isAllInitialized()) + return; + const branchInfo = await this.gitManager.branchInfo(); + const selectedBranch = await new BranchModal( + branchInfo.branches + ).open(); + if (selectedBranch != void 0) { + await this.gitManager.checkout(selectedBranch); + this.displayMessage(`Switched to ${selectedBranch}`); + (_a2 = this.branchBar) == null ? void 0 : _a2.display(); + return selectedBranch; + } + } + async switchRemoteBranch() { + var _a2; + if (!await this.isAllInitialized()) + return; + const selectedBranch = await this.selectRemoteBranch() || ""; + const [remote, branch2] = splitRemoteBranch(selectedBranch); + if (branch2 != void 0 && remote != void 0) { + await this.gitManager.checkout(branch2, remote); + this.displayMessage(`Switched to ${selectedBranch}`); + (_a2 = this.branchBar) == null ? void 0 : _a2.display(); + return selectedBranch; + } + } + async createBranch() { + var _a2; + if (!await this.isAllInitialized()) + return; + const newBranch = await new GeneralModal({ + placeholder: "Create new branch" + }).open(); + if (newBranch != void 0) { + await this.gitManager.createBranch(newBranch); + this.displayMessage(`Created new branch ${newBranch}`); + (_a2 = this.branchBar) == null ? void 0 : _a2.display(); + return newBranch; + } + } + async deleteBranch() { + var _a2; + if (!await this.isAllInitialized()) + return; + const branchInfo = await this.gitManager.branchInfo(); + if (branchInfo.current) + branchInfo.branches.remove(branchInfo.current); + const branch2 = await new GeneralModal({ + options: branchInfo.branches, + placeholder: "Delete branch", + onlySelection: true + }).open(); + if (branch2 != void 0) { + let force = false; + const merged = await this.gitManager.branchIsMerged(branch2); + if (!merged) { + const forceAnswer = await new GeneralModal({ + options: ["YES", "NO"], + placeholder: "This branch isn't merged into HEAD. Force delete?", + onlySelection: true + }).open(); + if (forceAnswer !== "YES") { + return; + } + force = forceAnswer === "YES"; + } + await this.gitManager.deleteBranch(branch2, force); + this.displayMessage(`Deleted branch ${branch2}`); + (_a2 = this.branchBar) == null ? void 0 : _a2.display(); + return branch2; + } + } + async remotesAreSet() { + if (!(await this.gitManager.branchInfo()).tracking) { + new import_obsidian30.Notice("No upstream branch is set. Please select one."); + const remoteBranch = await this.selectRemoteBranch(); + if (remoteBranch == void 0) { + this.displayError("Aborted. No upstream-branch is set!", 1e4); + this.setState(0 /* idle */); + return false; + } else { + await this.gitManager.updateUpstreamBranch(remoteBranch); + return true; + } + } + return true; + } + async setUpAutoBackup() { + if (this.settings.setLastSaveToLastCommit) { + this.clearAutoBackup(); + const lastCommitDate = await this.gitManager.getLastCommitTime(); + if (lastCommitDate) { + this.localStorage.setLastAutoBackup(lastCommitDate.toString()); + } + } + if (!this.timeoutIDBackup && !this.onFileModifyEventRef) { + const lastAutos = await this.loadLastAuto(); + if (this.settings.autoSaveInterval > 0) { + const now2 = /* @__PURE__ */ new Date(); + const diff2 = this.settings.autoSaveInterval - Math.round( + (now2.getTime() - lastAutos.backup.getTime()) / 1e3 / 60 + ); + this.startAutoBackup(diff2 <= 0 ? 0 : diff2); + } + } + } + async setUpAutos() { + this.setUpAutoBackup(); + const lastAutos = await this.loadLastAuto(); + if (this.settings.differentIntervalCommitAndPush && this.settings.autoPushInterval > 0) { + const now2 = /* @__PURE__ */ new Date(); + const diff2 = this.settings.autoPushInterval - Math.round( + (now2.getTime() - lastAutos.push.getTime()) / 1e3 / 60 + ); + this.startAutoPush(diff2 <= 0 ? 0 : diff2); + } + if (this.settings.autoPullInterval > 0) { + const now2 = /* @__PURE__ */ new Date(); + const diff2 = this.settings.autoPullInterval - Math.round( + (now2.getTime() - lastAutos.pull.getTime()) / 1e3 / 60 + ); + this.startAutoPull(diff2 <= 0 ? 0 : diff2); + } + } + async discardAll() { + await this.gitManager.discardAll({ + status: this.cachedStatus + }); + new import_obsidian30.Notice( + "All local changes have been discarded. New files remain untouched." + ); + } + clearAutos() { + this.clearAutoBackup(); + this.clearAutoPush(); + this.clearAutoPull(); + } + startAutoBackup(minutes) { + let time = (minutes != null ? minutes : this.settings.autoSaveInterval) * 6e4; + if (this.settings.autoBackupAfterFileChange) { + if (minutes === 0) { + this.doAutoBackup(); + } else { + this.onFileModifyEventRef = this.app.vault.on( + "modify", + () => this.autoBackupDebouncer() + ); + this.autoBackupDebouncer = (0, import_obsidian30.debounce)( + () => this.doAutoBackup(), + time, + true + ); + } + } else { + if (time > 2147483647) + time = 2147483647; + this.timeoutIDBackup = window.setTimeout( + () => this.doAutoBackup(), + time + ); + } + } + // This is used for both auto backup and commit + doAutoBackup() { + this.promiseQueue.addTask(() => { + if (this.settings.differentIntervalCommitAndPush) { + return this.commit({ fromAutoBackup: true }); + } else { + return this.createBackup(true); + } + }); + this.saveLastAuto(/* @__PURE__ */ new Date(), "backup"); + this.saveSettings(); + this.startAutoBackup(); + } + startAutoPull(minutes) { + let time = (minutes != null ? minutes : this.settings.autoPullInterval) * 6e4; + if (time > 2147483647) + time = 2147483647; + this.timeoutIDPull = window.setTimeout(() => { + this.promiseQueue.addTask(() => this.pullChangesFromRemote()); + this.saveLastAuto(/* @__PURE__ */ new Date(), "pull"); + this.saveSettings(); + this.startAutoPull(); + }, time); + } + startAutoPush(minutes) { + let time = (minutes != null ? minutes : this.settings.autoPushInterval) * 6e4; + if (time > 2147483647) + time = 2147483647; + this.timeoutIDPush = window.setTimeout(() => { + this.promiseQueue.addTask(() => this.push()); + this.saveLastAuto(/* @__PURE__ */ new Date(), "push"); + this.saveSettings(); + this.startAutoPush(); + }, time); + } + clearAutoBackup() { + var _a2; + let wasActive = false; + if (this.timeoutIDBackup) { + window.clearTimeout(this.timeoutIDBackup); + this.timeoutIDBackup = void 0; + wasActive = true; + } + if (this.onFileModifyEventRef) { + (_a2 = this.autoBackupDebouncer) == null ? void 0 : _a2.cancel(); + this.app.vault.offref(this.onFileModifyEventRef); + this.onFileModifyEventRef = void 0; + wasActive = true; + } + return wasActive; + } + clearAutoPull() { + if (this.timeoutIDPull) { + window.clearTimeout(this.timeoutIDPull); + this.timeoutIDPull = void 0; + return true; + } + return false; + } + clearAutoPush() { + if (this.timeoutIDPush) { + window.clearTimeout(this.timeoutIDPush); + this.timeoutIDPush = void 0; + return true; + } + return false; + } + async handleConflict(conflicted) { + this.setState(6 /* conflicted */); + this.localStorage.setConflict("true"); + let lines; + if (conflicted !== void 0) { + lines = [ + "# Conflicts", + "Please resolve them and commit them using the commands `Obsidian Git: Commit all changes` followed by `Obsidian Git: Push`", + "(This file will automatically be deleted before commit)", + "[[#Additional Instructions]] available below file list", + "", + ...conflicted.map((e) => { + const file = this.app.vault.getAbstractFileByPath(e); + if (file instanceof import_obsidian30.TFile) { + const link = this.app.metadataCache.fileToLinktext( + file, + "/" + ); + return `- [[${link}]]`; + } else { + return `- Not a file: ${e}`; + } + }), + ` +# Additional Instructions +I strongly recommend to use "Source mode" for viewing the conflicted files. For simple conflicts, in each file listed above replace every occurrence of the following text blocks with the desired text. + +\`\`\`diff +<<<<<<< HEAD + File changes in local repository +======= + File changes in remote repository +>>>>>>> origin/main +\`\`\`` + ]; + } + this.writeAndOpenFile(lines == null ? void 0 : lines.join("\n")); + } + async editRemotes() { + if (!await this.isAllInitialized()) + return; + const remotes = await this.gitManager.getRemotes(); + const nameModal = new GeneralModal({ + options: remotes, + placeholder: "Select or create a new remote by typing its name and selecting it" + }); + const remoteName = await nameModal.open(); + if (remoteName) { + const oldUrl = await this.gitManager.getRemoteUrl(remoteName); + const urlModal = new GeneralModal({ initialValue: oldUrl }); + const remoteURL = await urlModal.open(); + if (remoteURL) { + await this.gitManager.setRemote(remoteName, remoteURL); + return remoteName; + } + } + } + async selectRemoteBranch() { + let remotes = await this.gitManager.getRemotes(); + let selectedRemote; + if (remotes.length === 0) { + selectedRemote = await this.editRemotes(); + if (selectedRemote == void 0) { + remotes = await this.gitManager.getRemotes(); + } + } + const nameModal = new GeneralModal({ + options: remotes, + placeholder: "Select or create a new remote by typing its name and selecting it" + }); + const remoteName = selectedRemote != null ? selectedRemote : await nameModal.open(); + if (remoteName) { + this.displayMessage("Fetching remote branches"); + await this.gitManager.fetch(remoteName); + const branches = await this.gitManager.getRemoteBranches( + remoteName + ); + const branchModal = new GeneralModal({ + options: branches, + placeholder: "Select or create a new remote branch by typing its name and selecting it" + }); + return await branchModal.open(); + } + } + async removeRemote() { + if (!await this.isAllInitialized()) + return; + const remotes = await this.gitManager.getRemotes(); + const nameModal = new GeneralModal({ + options: remotes, + placeholder: "Select a remote" + }); + const remoteName = await nameModal.open(); + if (remoteName) { + this.gitManager.removeRemote(remoteName); + } + } + async writeAndOpenFile(text2) { + if (text2 !== void 0) { + await this.app.vault.adapter.write(this.conflictOutputFile, text2); + } + let fileIsAlreadyOpened = false; + this.app.workspace.iterateAllLeaves((leaf) => { + if (leaf.getDisplayText() != "" && this.conflictOutputFile.startsWith(leaf.getDisplayText())) { + fileIsAlreadyOpened = true; + } + }); + if (!fileIsAlreadyOpened) { + this.app.workspace.openLinkText(this.conflictOutputFile, "/", true); + } + } + // region: displaying / formatting messages + displayMessage(message, timeout = 4 * 1e3) { + var _a2; + (_a2 = this.statusBar) == null ? void 0 : _a2.displayMessage(message.toLowerCase(), timeout); + if (!this.settings.disablePopups) { + new import_obsidian30.Notice(message, 5 * 1e3); + } + console.log(`git obsidian message: ${message}`); + } + displayError(message, timeout = 10 * 1e3) { + var _a2; + if (message instanceof Errors.UserCanceledError) { + new import_obsidian30.Notice("Aborted"); + return; + } + message = message.toString(); + new import_obsidian30.Notice(message, timeout); + console.log(`git obsidian error: ${message}`); + (_a2 = this.statusBar) == null ? void 0 : _a2.displayMessage(message.toLowerCase(), timeout); + } +}; +/*! Bundled license information: + +ieee754/index.js: + (*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh *) + +buffer/index.js: + (*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + *) + +safe-buffer/index.js: + (*! safe-buffer. MIT License. Feross Aboukhadijeh *) + +crc-32/crc32.js: + (*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com *) + +js-sha256/src/sha256.js: + (** + * [js-sha256]{@link https://github.com/emn178/js-sha256} + * + * @version 0.9.0 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2014-2017 + * @license MIT + *) + +feather-icons/dist/feather.js: + (*! + Copyright (c) 2016 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames + *) +*/ diff --git a/.obsidian/plugins/obsidian-git/manifest.json b/.obsidian/plugins/obsidian-git/manifest.json new file mode 100644 index 0000000000..3656977381 --- /dev/null +++ b/.obsidian/plugins/obsidian-git/manifest.json @@ -0,0 +1,9 @@ +{ + "id": "obsidian-git", + "name": "Obsidian Git", + "description": "Backup your vault with Git.", + "isDesktopOnly": false, + "fundingUrl": "https://ko-fi.com/vinzent", + "js": "main.js", + "version": "2.20.4" +} diff --git a/.obsidian/plugins/obsidian-git/styles.css b/.obsidian/plugins/obsidian-git/styles.css new file mode 100644 index 0000000000..39cdb13477 --- /dev/null +++ b/.obsidian/plugins/obsidian-git/styles.css @@ -0,0 +1,507 @@ +@keyframes loading { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +.workspace-leaf-content[data-type='git-view'] .view-content { + padding: 0; +} + +.workspace-leaf-content[data-type='git-history-view'] .view-content { + padding: 0; +} + +.loading>svg { + animation: 2s linear infinite loading; + transform-origin: 50% 50%; + display: inline-block; +} + +.obsidian-git-center { + margin: auto; + text-align: center; + width: 50%; +} + +.obsidian-git-textarea { + display: block; + margin-left: auto; + margin-right: auto; +} + +.obsidian-git-center-button { + display: block; + margin: 20px auto; +} + +.tooltip.mod-left { + overflow-wrap: break-word; +} + +.tooltip.mod-right { + overflow-wrap: break-word; +} +.git-tools { + display: flex; + margin-left: auto; +} +.git-tools .type { + padding-left: var(--size-2-1); + display: flex; + align-items: center; + justify-content: center; + width: 11px; +} + +.git-tools .type[data-type="M"] { + color: orange; +} +.git-tools .type[data-type="D"] { + color: red; +} +.git-tools .buttons { + display: flex; +} +.git-tools .buttons > * { + padding: 0 0; + height: auto; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-d-none { + display: none; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-wrapper { + text-align: left; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-header { + background-color: var(--background-primary); + border-bottom: 1px solid var(--interactive-accent); + font-family: var(--font-monospace); + height: 35px; + padding: 5px 10px; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-header, +.workspace-leaf-content[data-type="diff-view"] .d2h-file-stats { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-stats { + font-size: 14px; + margin-left: auto; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-lines-added { + border: 1px solid #b4e2b4; + border-radius: 5px 0 0 5px; + color: #399839; + padding: 2px; + text-align: right; + vertical-align: middle; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-lines-deleted { + border: 1px solid #e9aeae; + border-radius: 0 5px 5px 0; + color: #c33; + margin-left: 1px; + padding: 2px; + text-align: left; + vertical-align: middle; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-name-wrapper { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + font-size: 15px; + width: 100%; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-name { + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-wrapper { + border: 1px solid var(--background-modifier-border); + border-radius: 3px; + margin-bottom: 1em; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse { + -webkit-box-pack: end; + -ms-flex-pack: end; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + border: 1px solid var(--background-modifier-border); + border-radius: 3px; + cursor: pointer; + display: none; + font-size: 12px; + justify-content: flex-end; + padding: 4px 8px; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse.d2h-selected { + background-color: #c8e1ff; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse-input { + margin: 0 4px 0 0; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-diff-table { + border-collapse: collapse; + font-family: Menlo, Consolas, monospace; + font-size: 13px; + width: 100%; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-files-diff { + width: 100%; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-diff { + overflow-y: hidden; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-side-diff { + display: inline-block; + margin-bottom: -8px; + margin-right: -4px; + overflow-x: scroll; + overflow-y: hidden; + width: 50%; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-line { + padding: 0 8em; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-line, +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line { + display: inline-block; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + white-space: nowrap; + width: 100%; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line { + padding: 0 4.5em; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-ctn { + word-wrap: normal; + background: none; + display: inline-block; + padding: 0; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + vertical-align: middle; + white-space: pre; + width: 100%; +} + +.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-code-line del, +.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line del { + background-color: #ffb6ba; +} + +.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-code-line del, +.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line del { + background-color: #8d232881; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-line del, +.workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins, +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line del, +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line ins { + border-radius: 0.2em; + display: inline-block; + margin-top: -1px; + text-decoration: none; + vertical-align: middle; +} + +.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins, +.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line ins { + background-color: #97f295; + text-align: left; +} + +.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins, +.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line ins { + background-color: #1d921996; + text-align: left; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-prefix { + word-wrap: normal; + background: none; + display: inline; + padding: 0; + white-space: pre; +} + +.workspace-leaf-content[data-type="diff-view"] .line-num1 { + float: left; +} + +.workspace-leaf-content[data-type="diff-view"] .line-num1, +.workspace-leaf-content[data-type="diff-view"] .line-num2 { + -webkit-box-sizing: border-box; + box-sizing: border-box; + overflow: hidden; + padding: 0 0.5em; + text-overflow: ellipsis; + width: 3.5em; +} + +.workspace-leaf-content[data-type="diff-view"] .line-num2 { + float: right; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber { + background-color: var(--background-primary); + border: solid var(--background-modifier-border); + border-width: 0 1px; + -webkit-box-sizing: border-box; + box-sizing: border-box; + color: var(--text-muted); + cursor: pointer; + display: inline-block; + position: absolute; + text-align: right; + width: 7.5em; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber:after { + content: "\200b"; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber { + background-color: var(--background-primary); + border: solid var(--background-modifier-border); + border-width: 0 1px; + -webkit-box-sizing: border-box; + box-sizing: border-box; + color: var(--text-muted); + cursor: pointer; + display: inline-block; + overflow: hidden; + padding: 0 0.5em; + position: absolute; + text-align: right; + text-overflow: ellipsis; + width: 4em; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-diff-tbody tr { + position: relative; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber:after { + content: "\200b"; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-emptyplaceholder, +.workspace-leaf-content[data-type="diff-view"] .d2h-emptyplaceholder { + background-color: var(--background-primary); + border-color: var(--background-modifier-border); +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-prefix, +.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber, +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber, +.workspace-leaf-content[data-type="diff-view"] .d2h-emptyplaceholder { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber, +.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber { + direction: rtl; +} + +.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-del { + background-color: #fee8e9; + border-color: #e9aeae; +} + +.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-ins { + background-color: #dfd; + border-color: #b4e2b4; +} + +.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-del { + background-color: #521b1d83; + border-color: #691d1d73; +} + +.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-ins { + background-color: rgba(30, 71, 30, 0.5); + border-color: #13501381; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-info { + background-color: var(--background-primary); + border-color: var(--background-modifier-border); + color: var(--text-normal); +} + +.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-file-diff .d2h-del.d2h-change { + background-color: #fdf2d0; +} + +.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-file-diff .d2h-del.d2h-change { + background-color: #55492480; +} + +.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-file-diff .d2h-ins.d2h-change { + background-color: #ded; +} + +.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-file-diff .d2h-ins.d2h-change { + background-color: rgba(37, 78, 37, 0.418); +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-wrapper { + margin-bottom: 10px; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-wrapper a { + color: #3572b0; + text-decoration: none; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-wrapper a:visited { + color: #3572b0; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-header { + text-align: left; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-title { + font-weight: 700; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-line { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + text-align: left; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list { + display: block; + list-style: none; + margin: 0; + padding: 0; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list>li { + border-bottom: 1px solid var(--background-modifier-border); + margin: 0; + padding: 5px 10px; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-list>li:last-child { + border-bottom: none; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-file-switch { + cursor: pointer; + display: none; + font-size: 10px; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-icon { + fill: currentColor; + margin-right: 10px; + vertical-align: middle; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-deleted { + color: #c33; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-added { + color: #399839; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-changed { + color: #d0b44c; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-moved { + color: #3572b0; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-tag { + background-color: var(--background-primary); + display: -webkit-box; + display: -ms-flexbox; + display: flex; + font-size: 10px; + margin-left: 5px; + padding: 0 2px; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-deleted-tag { + border: 2px solid #c33; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-added-tag { + border: 1px solid #399839; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-changed-tag { + border: 1px solid #d0b44c; +} + +.workspace-leaf-content[data-type="diff-view"] .d2h-moved-tag { + border: 1px solid #3572b0; +} + +/* ====================== Line Authoring Information ====================== */ + +.cm-gutterElement.obs-git-blame-gutter { + /* Add background color to spacing inbetween and around the gutter for better aesthetics */ + border-width: 0px 2px 0.2px 2px; + border-style: solid; + border-color: var(--background-secondary); + background-color: var(--background-secondary); +} + +.cm-gutterElement.obs-git-blame-gutter > div, .line-author-settings-preview { + /* delegate text color to settings */ + color: var(--obs-git-gutter-text); + font-family: monospace; + height: 100%; /* ensure, that age-based background color occupies entire parent */ + text-align: right; + padding: 0px 6px 0px 6px; + white-space: pre; /* Keep spaces and do not collapse them. */ +} diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json new file mode 100644 index 0000000000..ab318b6f63 --- /dev/null +++ b/.obsidian/workspace.json @@ -0,0 +1,204 @@ +{ + "main": { + "id": "959b6129c00a7ae4", + "type": "split", + "children": [ + { + "id": "3fa73868136b4532", + "type": "tabs", + "children": [ + { + "id": "2672355a05b54dec", + "type": "leaf", + "state": { + "type": "markdown", + "state": { + "file": "_pages/Provisioning.md", + "mode": "source", + "source": false + } + } + } + ] + } + ], + "direction": "vertical" + }, + "left": { + "id": "6479f561f1efcfa6", + "type": "split", + "children": [ + { + "id": "00cc1e748905b356", + "type": "tabs", + "children": [ + { + "id": "c7612fa5af166412", + "type": "leaf", + "state": { + "type": "file-explorer", + "state": { + "sortOrder": "alphabetical" + } + } + }, + { + "id": "f108f4661fe85b81", + "type": "leaf", + "state": { + "type": "search", + "state": { + "query": "", + "matchingCase": false, + "explainSearch": false, + "collapseAll": false, + "extraContext": false, + "sortOrder": "alphabetical" + } + } + }, + { + "id": "afb6dbcf62d731ac", + "type": "leaf", + "state": { + "type": "starred", + "state": {} + } + }, + { + "id": "2101a99d9b305e7d", + "type": "leaf", + "state": { + "type": "bookmarks", + "state": {} + } + } + ] + } + ], + "direction": "horizontal", + "width": 300 + }, + "right": { + "id": "162a2ea39a4b5a54", + "type": "split", + "children": [ + { + "id": "82a3438c937c1b24", + "type": "tabs", + "children": [ + { + "id": "9bc4ed7e5225dd8e", + "type": "leaf", + "state": { + "type": "backlink", + "state": { + "file": "_pages/Provisioning.md", + "collapseAll": false, + "extraContext": false, + "sortOrder": "alphabetical", + "showSearch": false, + "searchQuery": "", + "backlinkCollapsed": false, + "unlinkedCollapsed": true + } + } + }, + { + "id": "2bdc5a4a20df43f3", + "type": "leaf", + "state": { + "type": "outgoing-link", + "state": { + "file": "_pages/Provisioning.md", + "linksCollapsed": false, + "unlinkedCollapsed": true + } + } + }, + { + "id": "6d562acf09cd09c8", + "type": "leaf", + "state": { + "type": "tag", + "state": { + "sortOrder": "frequency", + "useHierarchy": true + } + } + }, + { + "id": "a5331ebe04c6c059", + "type": "leaf", + "state": { + "type": "outline", + "state": { + "file": "_pages/Provisioning.md" + } + } + } + ] + } + ], + "direction": "horizontal", + "width": 300, + "collapsed": true + }, + "left-ribbon": { + "hiddenItems": { + "switcher:Open quick switcher": false, + "graph:Open graph view": false, + "canvas:Create new canvas": false, + "daily-notes:Open today's daily note": false, + "templates:Insert template": false, + "command-palette:Open command palette": false + } + }, + "active": "2672355a05b54dec", + "lastOpenFiles": [ + "_pages/Digital.md", + "assets/images/email_copy_debug.gif", + "assets/images/LAB2_email/OneTransaction.png.md", + "assets/images/LAB2_email", + "assets/images/DebugConsole3.png", + "assets/images/OneTransaction.png", + "assets/images/email_paste_debug.gif", + "assets/images/emailConfirmation.png", + "assets/images/CheckPopSetting.png", + "Untitled.md", + "assets/icons/6.png", + "assets/icons/5.png", + "assets/icons/4.png", + "assets/icons/3.png", + "assets/icons", + "_pages/JDS_XM.md", + "_pages/IVR.md", + "_pages/Agent.md", + "assets/images/EM/Contactcenter", + "assets/images/EM", + "assets/images/IVR/Untitled", + "conflict-files-obsidian-git.md", + "customer-journey-data-services-introduction.md", + "_pages/CH.md", + "_pages/Provisioning.md", + "files/RTMS GA Launch.pdf", + "files/RTMS EA Regional Media.pdf", + "assets/files/AnalyzerLab_Flow.json", + "assets/images/mailinator-1.gif.md", + "assets/images/Single.md", + "assets/images/SSO", + "assets/images/OnboardingProcess", + "Untitled.canvas", + "_pages/Supervisor.md", + "files/ESD_default_layout.json.md", + "_pages/Acqueon.md", + "README.md", + "_pages/WxM.md", + "_pages/CRM.md", + "_pages/CCAI.md", + "_pages/Calabrio.md", + "_pages/Analyzer.md", + "assets/images/DC_Lab_12.12._Create_Connect_6.png.md", + "assets/images/DC_Lab_12.8._Verify_1.png.md" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..c4deef0aad --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cSpell.enabled": true +} \ No newline at end of file diff --git a/Backup files/CRM-old_file_backup.md b/Backup files/CRM-old_file_backup.md new file mode 100644 index 0000000000..0d4ce64bfb --- /dev/null +++ b/Backup files/CRM-old_file_backup.md @@ -0,0 +1,678 @@ +--- +title: Lab 6 - CRM Integration +author: Neha Wuthoo & Pawan Kumar & Arunabh Bhattacharjee +date: 2022-06-06 +layout: post +--- + + +# Introduction + +### Lab Objective + +This lab covers Webex Contact Center Agent Desktop integration with the most popular CRM solutions (Salesforce, Microsoft Dynamics 365 and Zendesk) which allows you to launch the Agent Desktop from within the CRM, providing an integrated Agent Experience for inbound and outbound calls. + + +# Table of Contents + +[4.1 Salesforce integration](#41-salesforce-integration) +- [Optional: Create Salesforce Account](#optional-create-salesforce-account) +- [Part 1: Connector Installation](#part-1-connector-installation) + * [1. Connector Installation From Salesforce AppExchange](#1-connector-installation-from-salesforce-appexchange) + * [2. Connector Installation Verification](#2-connector-installation-verification) +- [Part 2: Call Center Configuration](#part-2-call-center-configuration) + * [3. Salesforce Call Center Configuration](#3-salesforce-call-center-configuration) + * [4. Adding Call Center Users To Salesforce Call Center Application](#4-adding-call-center-users-to-salesforce-call-center-application) +- [Part 3: Softphone & Task Layout Configuration](#part-3-softphone-task-layout-configuration) + * [5. Create Salesforce Softphone Layout Configuration](#5-create-salesforce-softphone-layout-configuration) + * [6. Salesforce Softphone Layout Assignment](#6-salesforce-softphone-layout-assignment) + * [7. Salesforce Task Layout Configuration](#7-salesforce-task-layout-configuration) +- [Part 4: Reports](#part-4-reports) + * [8. WebexCC Salesforce Desktop Report View](#8-webexcc-salesforce-desktop-report-view) +- [Part 5: WebexCC Desktop Layout](#part-5-webexcc-dekstop-layout) + * [9. WebexCC Salesforce Desktop Layout Configuration](#9-webexcc-salesforce-desktop-layout-configuration) +- [Login Agent and Make a Test Call](#login-agent-make-call) + +[4.2 Microsoft Dynamics 365 integration](#42-microsoft-dynamics-365-integration) +- [Optional: Start Microsoft Dynamics Trial](#optional-start-microsoft-dynamics-trial) +- [Part 1: Install applications for MS Dynamics 365 environment](#part-1-install-applications-for-ms-dynamics-365-environment) + * [1. Install Channel Integration Framework from AppSource](#1-install-channel-integration-framework-from-appsource) + * [2. Install Cisco Webex Contact Center for Microsoft Dynamics from AppSource](#2-install-cisco-webex-contact-center-for-microsoft-dynamics-from-appsource) +- [Part 2: Configure applications for MS Dynamics 365 environment](#part-2-configure-applications-for-ms-dynamics-365-environment) + * [3. Configure Channel Integration Framework](#3-configure-channel-integration-framework) + * [4. Create Desktop Layout file](#4-create-desktop-layout-file) + * [5. Upload Desktop Layout to Webex Contact Center Mangement Portal](#5-upload-desktop-layout-to-webex-contact-center-management-portal) + * [6. Update Security Policy on Control Hub](#6-update-security-policy-on-control-hub) +- [Part 3: Test Webex Contact Center Agent Desktop for MS Dynamics 365](#part-3-test-webex-contact-center-agent-desktop-for-ms-dynamics-365) + * [7. Sign into Webex Contact Center for Microsoft Dynamics 365](#7-sign-into-webex-contact-center-for-microsoft-dynamics-365) + * [8. Create new contact record in MS Dynamics](#8-create-new-contact-record-in-ms-dynamics) + * [9. Make inbound test calls](#9-make-inbound-test-calls) + +[4.3 Zendesk integration](#43-zendesk-integration) +- [Optional: Start Zendesk Trial](#optional-start-zendesk-trial) +- [Part 1: Install application for Zendesk](#part-1-install-application-for-zendesk) + * [1. Install Cisco Webex Contact Center application for Zendesk from Marketplace](#1-install-cisco-webex-contact-center-application-for-zendesk-from-marketplace) +- [Part 2: Configure Webex Contact Center tenant and Zendesk instance](#part-2-configure-webex-contact-center-tenant-and-zendesk-instance) + * [2. Create Desktop Layout for Zendesk](#2-create-desktop-layout-for-zendesk) + * [3. Create new Organization in Zendesk](#3-create-new-organization-in-zendesk) + * [4. Create new Customer in Zendesk](#4-create-new-customer-in-zendesk) +- [Part 3: Test Webex Contact Center Agent Desktop for Zendesk](#part-3-test-webex-contact-center-agent-desktop-for-zendesk) + * [5. Sign into Webex Contact Center for Zendesk](#5-sign-into-webex-contact-center-for-zendesk) + * [6. Make inbound test calls](#6-make-inbound-test-calls) + + +# 4.1 Salesforce integration + +### Pre-requisites + +1. Administrator/ Supervisor with Salesforce access. +2. Administrator/ Supervisor with WebexCC portal access. +3. New user (Agent) is already created. +4. Agent is able to login to agent desktop. +5. Agent should be part of a team. +6. Basic knowledge of JSON format. +7. Salesforce Custom Desktop Layout. +8. Use any online [JSON validator](https://jsonlint.com/) to validate the file. +9. Lab 2 (IVR and Contact Routing) completed. + + +## Optional: Create Salesforce Account + + + +
    + +- Navigate to [Salesforce Developer](https://developer.salesforce.com) website and click on **Sign Up**. + +- Complete the form with your personal details and click on **Sign me up** to create your account. + +> **Note:** Username needs to be in the form of an e-mail address. This address does not need to be a real e-mail address. + +- Go to your e-mail inbox and wait for the confirmation e-mail regarding your account. Click on **Verify Account**. + +- Enter a **password** as well as an **answer** to the security question. This will successfully create your account and log you in the Salesforce platform. + + +## Part 1: Connector Installation + + + +### 1. Connector Installation From Salesforce AppExchange + +- Login to your [Salesforce](https://login.salesforce.com) instance and go to **Setup**. + +- In the search box, type `AppExchange Marketplace`. + +- In the AppExchange Marketplace type `Cisco Webex Contact Center for Salesforce`. + +- Click on the Cisco Webex Contact Center App and the click on **Get It Now**. + +- On the pop-up window, click on **Open Login Screen**. If prompted, login again with your credentials and **Allow** access to the `appx_api`. + +- After verifying your login, choose the **Intall in This Org** option. + +- Fill in the required fields with your details and accept the Terms and Conditions to be able to proceed with installation. + +- Choose **Install for All Users** option and then click on **Install**. + +- If asked, grant access to third party web site `_cpc.ccone.net_` by clicking on the checkbox and then on **Continue**. + +- After the installation is complete, click **Done**. + +### 2. Connector Installation Verification + +- In Salesforce, navigate to **Setup**. + +- In the search box, type `Installed Packages`. + +- In the Installed Packages list, check for **Webex Contact Center**. + +- If found, then installation was successful. + + +## Part 2: Call Center Configuration + + + +### 3. Salesforce Call Center Configuration + +- In Salesforce, navigate to **Setup**. + +- In the search box, type `Call Centers` and click on **Continue**. + +- Click the **Edit** link corresponding to the **Webex Contact Center Agent Desktop**. + +- Click on **Edit** to set up the CTI settings. + +- Update the **Display Name** field if you want to change the Display name of the call center. + +- Configure the following CTI Adapter URL: https://desktop.wxcc-us1.cisco.com/ . + +- Configure `Softphone Height: 600` and `Softphone Width: 550`. + +- Click **Save** + + +### 4. Adding Call Center Users To Salesforce Call Center Application + +- Click on **Manage Call Center Users** to open the Manage Users page. + +- Click on **Add More Users** button to add users to Call Center application. + +- **Search for New Users** page opens where you can apply filters to find Call Center users. Click on **Find** to list all the available users. + +- Select your user from the list and click on the **Add to Call Center** button. + +- You will be redirected to the **Manage Users** page, where your user should now be listed. + + +## Part 3: Softphone & Task Layouts + + + +### 5. Create Salesforce Softphone Layout Configuration + +- In Salesforce, navigate to **Setup**. + +- In the search box, type `Softphone Layout` and click on **Continue**. + +- Click on the **New** button to open the **Softphone Layout Configuration page** and create a softphone layout to use as `default`. + +- Enter a `Name` for the Softphone Layout Configuration. + +- Select the **Is Default Layout** checkbox to make this Softphone layout default for all the call center application. + +- On the **salesforce.com objects**, remove `Lead` from the selections and add `Opportunity`. + +- On the **Screen Pop Settings**, choose `Pop to new Contact` for **No matching records**, `Pop detail page` for **Single-matching records** and `Pop to search page` for **Multiple-matching records**. + +- Click **Save** to create the Softphone Layout configuration. + +### 6. Salesforce Softphone Layout Assignment + +- If not already there, in the search box type `Softphone Layout` and click on **Continue** to reach the Softphone Layout page. + +- Click on the **Softphone Layout Assignment** Button, it opens the Softphone Layout Assignment page. + +- Assign the Softphone Layout configuration you created to the **System Administrator** profile. + +- Click **Save** to assign the Softphone Layouts. + +### 7. Salesforce Task Layout Configuration + +- In Salesforce, navigate to **Setup**. + +- In the search box, type `Object Manager` and click on it. + +- Filter the list page by typing `Task` in the **Quick Find** search box and click on the **Task button link**. + +- Select **Page Layouts** on the left of the Task details page. + +- Click on **Page Layout Assignment** on top-right and then on **Edit Assignment**. + +- Select the **System Administrator** profile from the displayed list in the Profiles column. + +- Select the **Cisco Webex Contact Center Task Layout** from the **Page Layout To Use** drop-down list on top. + +- Apply the same page layout to **Standard User** and **Standard Platform User** profiles as well. + +- Click **Save** to assign the Task Layout. + + +## Part 4: Reports + + + +### 8. WebexCC Salesforce Desktop Report View + +- In Salesforce, click **App Launcher** on top left and then choose **Webex Contact Center**. + +- From the Navigation Apps drop-down list, select **Reports**. + +> **Note:** If Reports is not listed, click **Edit** > **Add More Items** and add the **Reports**. + +- To see all the existing reports, click **All Reports**. + +> **Note:** There is a default call activity report that installs with Cisco Webex Contact Center for Salesforce client. + + +## Part 5: WebExCC Salesforce Desktop Layout + + + +### 9. WebexCC Salesforce Desktop Layout Configuration + +- Login to [WebexCC Admin Portal](https://portal.wxcc-us1.cisco.com/portal/home.html). + +- Go to **Provisioning** > **Desktop Layout** > **New Layout**. + +- Enter Name and Description for the desktop layout. + +- Status by default will be **Active**. + +- Add the **Teams** to Desktop layout. Agents associated with that team will get the Salesforce Desktop Layout. + +- Upload the custom desktop layout for WebexCC Salesforce Desktop. +[WebexCC_Salesforce_Desktop.zip](https://github.com/wxcctechsummit/wxcclabguides/raw/08fb8082092b2552ec89e1b42dbe84b12214a805/WebexCC_Salesforce_Desktop.zip) + +- Click **Save**. This will create a custom Desktop Layout named Salesforce in WebexCC. + +## Login Agent and Make a Test Call + +- Back on Salesforce page, click on **App Launcher** icon on top left and then click on **Webex Contact Center**. + +- On the bottom left, click on **Phone** and then **Sign In**. + +- Sign in an agent that is part of the team that the Dekstop Layout was associated with previously. You can use the agent, EPs and flow created in Lab 2 Part 2 (IVR and Contact Routing) for the queued to agent scenario. + +- Make sure the agent is in available state and make a test call to your EP. + +- Upon accepting the call, we will see account information populated for this call. A `task activity` should also be created and visible upon accepting the call. + + +# 4.2 Microsoft Dynamics 365 integration + +### Pre-requisites + +1. Administrator access to the organization on [Control Hub](https://admin.webex.com/) and [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/). +2. An agent account with access to [Agent Desktop](https://desktop.wxcc-us1.cisco.com/). +3. An MS Dynamics Sales instance. For the details, refer the next section "Start Microsoft Dynamics Trial" +4. Access to the [Webex Contact Contact Center Desktop Layout for Microsoft Dynamics](https://github.com/CiscoDevNet/webex-contact-center-widget-starter/tree/master/Examples/Layouts/MS Dynamics/) JSON. +5. Lab 2 (IVR and Contact Routing) completed. + + +## Optional: Start Microsoft Dynamics Trial + + + +
    + +- Navigate to [Dynamics 365 Free Trial](https://dynamics.microsoft.com/en-us/dynamics-365-free-trial/) website + +- Scroll down and click on **Try for free** under "Dynamics 365 Sales". + +- Enter your email address at "Let's get started" page and press **Start your free trial** button. + +> **Note:** If there is a notification about using work account, click on **set up** link to create new account. Then follow the wizard. + +- Enter the same email address at the first step of account creation wizard and press **Next**. + +- Complete the form with your personal details and click on **Next** to continue. + +- Verify your account using either SMS or phone call. + +- Enter username, subdomain name under ".onmicrosoft.com" domain and password. Then press **Next** button. + +- Copy and note your username at the last step of the wizard and click on **Get Started** button to create an account. + +- Sing into Power Platform Admin Center under created account by providing username (in the form of an e-mail address) and password. + +- In "New environment" dialog enter "Name", choose "Region" and press **Next**. + +- In "Add database" dialog choose the language if needed and press **Save** to create an environment. + +- Use **Refresh** button at the top of "Environments" page and wait untill the status of new envornment is changed to "Ready". + +- Go to your e-mail inbox and click **Start your trial** link to activate trial. + +- Once you are forwarded to "Microsoft 365 admin center" make sure that "Subscription status" is "Active". + + +## Part 1: Install applications for MS Dynamics 365 environment + + + + +### 1. Install Channel Integration Framework from AppSource + +- Sign into [Microsoft Power Platform Admin Center](https://admin.powerplatform.microsoft.com). + +- Go to "Environments" and click on the environment you created for this lab. + +- Click on **Dynamics 365 apps** link under "Resources" section of your environment. + +- Click on **Open AppSource** at the top of the apps page. + +- Search for "channel" on the AppSource page and choose "Dynamics 365 Channel Integration Framework" from the list. + +- Press **Get it now** button on the app page to install it. + +- Sign into AppSource if needed using your username (in the form of an e-mail address). Then press **Get it now** on the app page one more time. + +- Complete the form by choosing Country/region, tick the checkbox to grant permission and press **Continue** button to proceed. + +- Select an environment, tick both checkboxes and press **Install** button to start the installation. + +- Use **Refresh** button at the top of "Dynamics 365 apps" page and wait untill the status of "Dynamics 365 Channel Integration Framework" app is changed to "Installed". + + +### 2. Install Cisco Webex Contact Center for Microsoft Dynamics from AppSource + +- Click on **Open AppSource** at the top of the apps page one more time in order to navigate to AppSource. + +- Search for "webex" on the AppSource page and choose **Cisco Webex Contact Center for Microsoft Dynamics** from the list. + +- Press **Get it now** button on the app page to install it. + +- Tick the checkbox to grant permission and press **Continue** button to proceed. + +- Select an environment, tick both checkboxes and press **Install** button to start the installation. + +- Use **Refresh** button at the top of "Dynamics 365 apps" page and wait untill the status of "Cisco Webex Contact Center for Microsoft Dynamics" app is changed to "Installed". + + +## Part 2: Configure applications for MS Dynamics 365 environment + + + + +### 3. Configure Channel Integration Framework + +- Sign into [Microsoft Power Platform Admin Center](https://admin.powerplatform.microsoft.com). + +- Go to "Environments" and click on the environment you created for this lab. + +- Click on **Open Environment** at the top of the environment page. + +- Choose **Channel Integration Framework** on the page with published apps. + +- Press **New** button at the top of "Channel Providers" page to create new channel provider. + +- Complete channel provider configuration by providing the following details: + +| Parameter Name | Parameter Value | +| ----- | ----- | +| Name | Cisco Webex Contact Center | +| Label | Cisco Webex Contact Center | +| Channel URL | https://desktop.wxcc-us1.cisco.com | +| Enable Outbound Communication | Yes | +| Channel Order | 1 | +| API version | 1.0 | +| Trusted Domain | https://desktop.wxcc-us1.cisco.com | + +- Select "Customer Services Hub" as Unified Interface Apps for the Channel. + +- Select all roles available for the channel. + +- Press "Save & Close" button at the top of the page to save changes. + + +### 4. Create Desktop Layout file + +- Sign into [Microsoft Power Platform Admin Center](https://admin.powerplatform.microsoft.com). + +- Go to "Environments" and click on the environment you created for this lab. + +- Rigth-click on the link under "Environment URL" and copy link value. For example: **https://org2a50d69e.crm11.dynamics.com/**
    +Then paste this URL into the text editor and save - we will need it later when creating Desktop Layout JSON file. + +- Navigate to [MS Dynamics Layout](https://github.com/CiscoDevNet/webex-contact-center-widget-starter/tree/master/Examples/Layouts/MS%20Dynamics) page. + +- Click to "MSDynamics_Desktop.json" file. Copy the content of the file and paste it into any text editor. + +- Find "hostname" key and replace the value of this key by Environment URL which you noted before. For example: +``` +"hostName":"https://org2a50d69e.crm11.dynamics.com/" +``` + +- Save the file with .json extension. For example, **MSDynamics_Desktop.json** + + +### 5. Upload Desktop Layout to Webex Contact Center Management Portal + +- Sing into [Webex Contact Center Managemnt Portal](https://portal.wxcc-us1.cisco.com/) of your lab pod. + +- Go to **Provisioning** -> **Desktop Layout** and press **New Layout** button. + +- Enter layout name (for example, "MS Dynamics 365"), press "Upload" and choose JSON file with layout you have created above. Once file is uploaded, make sure it is validated successfully. + +- Click on "Teams" row and choose one or more teams. + +> **Note:** The agent you will use to test the integration with Dynamics 365 must be the part of the team chosen above. + +- Press **Save** to create the layout. Once layout is created make sure it is "Active". + + +### 6. Update Security Policy on Control Hub + +- Sign into [Webex Control Hub](https://admin.webex.com/) of your lab pod. + +- Go to **Contact Center** -> **Settings** -> **Security** and scroll down to "Content Secuity Policy Allowed List". + +- If the **\*.dynamics.com** value is not added, paste it into the text field and press **Add** button. Make sure the value has been added. + + +## Part 3: Test Webex Contact Center Agent Desktop for MS Dynamics 365 + + + + +### 7. Sign into Webex Contact Center for Microsoft Dynamics 365 + +- Sign into [Microsoft Power Platform Admin Center](https://admin.powerplatform.microsoft.com). + +- Go to "Environments" and click on the environment you created for this lab. + +- Click on **Open Environment** at the top of the environment page to see the list of published apps on the Apps page. + +> **Note:** If you are forwarded to Channel Integration Framework page intead of Apps page, just click to **Channel Integration Framework** link at the top of the page near "Dynamics 365" title. Then you will see Apps page with the list of published apps. + +- Click on "Customer Service Hub" app and you will be redirected to Dashboards tab of Customer Service Hub. + +- Press **Sign In** button within "Cisco Webex Contact Center" app on the right-hand side and provide agent credentials in new borwser tab. + +- Once authentication is completed, provide "Dialed Number" / "Extension" and choose proper team within "Cisco Webex Contact Center" app. + +> **Note:** This team must have Desktop Layout for Dynamics 365 applied in Webex Contact Center Management Portal in the previous part of this lab. + +- Make agent desktop "Available" by selecting corresponding state. + + +### 8. Create new contact record in MS Dynamics + +> **Note:** You may create new contact record in Dynamics 365 to test the scenario when calling number matches or does not match phone number of the contact. + +- Go to "Contacts" tab of Customer Service Hub and press "New" button at the top to create new account. + +- Complete contact form with the details: + * First Name + * Last name + * Mobile Phone (please enter calling number which you will use to make test call to Webex Contact Center later) + +- Press "Save & Close" button to save the contact. + + +### 9. Make inbound test calls + +- Initiate a call from the calling number which matches the one configured under new contact created on the previous step. + +- Answer the call by the agent and make sure you see screen pop with the details of new contact created above. + +- Answer the call and wait few seconds. Then hang up and wrap-up the call. + +- Make sure you see activity record with call details created within MS Dynamics. "Call From" must be pre-populated with contact name. + +- Initiate one more call from calling number which does not match any contact in MS Dynamics and compare the behavior. + +- Answer the call by the agent and make sure you see screen pop with "No results found" notification. + +- Answer the call and wait few seconds. Then hang up and wrap-up the call. + +- Make sure you see activity record with call details created within MS Dynamics. "Call From" must be empty. + +- Go to "Activities" and make sure you see both records created after the calls. + + +# 4.3 Zendesk integration + +### Pre-requisites + +1. Administrator access to the organization on [Control Hub](https://admin.webex.com/) and [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/). +2. An agent account with access to [Agent Desktop](https://desktop.wxcc-us1.cisco.com/). +3. Zendesk instance. For the details, refer the next section "Start Zendesk Trial". +4. Access to the [Webex Contact Contact Center Desktop Layout for Zendesk](hhttps://github.com/CiscoDevNet/webex-contact-center-widget-starter/tree/master/Examples/Layouts/Zendesk/) JSON. +5. Lab 2 (IVR and Contact Routing) completed. + + +## Optional: Start Zendesk Trial + + + +
    + +> **Note:** Zendesk free trial is valid for 14 days only. So, you need to complete the configuration and all tests within this time frame. + +- Navigate to [Zendesk](https://www.zendesk.com/) website + +- Click on **Free Trial** on the main page of the website. + +- Enter your email address at "Start your free Zendesk trial" page, choose **No** under the option to get occasional emails and press **Next** button. + +- Provide your First Name, Last Name and Phone number on the second step of the wizard and press **Next** button. + +> **Note:** The phone number is mandatory, but it is not used for any kind of verification, authentication or authorization. Thus you may provide any number. + +- On the last step of the wizard fill in the following fields: + * Company Name + * Number of employees (it is recommended to choose **1-9**) + * Purpose of the solution + * Zendesk subdomain +Then choose Language, enter new Password and click on **Complete trial signup**. + +> **Note:** It is recommended to use host part of your eamil as Zendesk subdoamin for simplicity. For example, if your email is testemail@customer.com. try to use **testemail** (user portion of it as a subdomain). In case this subdomain is already occupied, wizard will propose another form of this name to you. + +- Wait few minutes, then check and make sure that you have received 2 emails: + * Welcome to Zendesk: Verify your email + * Welcome to your 14-day Zendesk trial + +- Once free trial provisioning is completed, go to verification email and click on **Verify your account**. + +> **Note:** If you received both emails from Zendesk mentioned above, but free trial provisioning is still not completed in 3-5 minutes (there is spinning circle at the last step of the wizard), please go to verification email and click on **Verify your account**. + +- Once you are redeirected to **Welcome to Zendesk Suite** page, press **Get started** button to proceed. + +- Press **Next** on "Help your customers on any channel". Then click on **Skip tour and go to setup** on "See how ticketing works" page to get to your Zendesk instance. + + +## Part 1: Install application for Zendesk + + + + +### 1. Install Cisco Webex Contact Center application for Zendesk from Marketplace + +- Sign into your Zendesk instance. URL should have format - **https://.zendesk.com** + +> **Note:** You may find URL of your Zendesk trial instance within "Welcome to your 14-day Zendesk trial" email. It is printed next to "Your account:" section. + +- Once, signed into Zendesk, click on "Admin" menu item (gear icon at the botton) of the vertical menu bar on the left. Then click on **Marketplace** under **Apps** section. Zendesk Marketplace will be opened in new tab of the web browser. + +- Search for "webex" on Marketplace and click on **Cisco Webex Contact Center** application. + +- Click on **Install** on the page of "Cisco Webex Contact Center" application. Then choose an account to install this app from drop-down list (if you started free trial, there should be only one item in the list) and click on "Install" one more time. You will be redirected to "Zendesk Admin Center". + +- Check and make sure "AgentDesktopHostUrl" field contains **https://desktop.wxcc-us1.cisco.com** value for Cisco Webex Contact Center app in Zendesk Admin Center. Then scroll donw and press "Install" buttonat the bottom of the page. + +- Wait few seconds untill installation is completed and "Cisco Webex Contact Center" appears in the list of currently installed apps. + + +## Part 2: Configure Webex Contact Center tenant and Zendesk instance + + + + +### 2. Create Desktop Layout for Zendesk + +- Navigate to [Zendesk Layout](https://github.com/CiscoDevNet/webex-contact-center-widget-starter/tree/master/Examples/Layouts/Zendesk) page. + +- Click to "Zendesk_Desktop.json" file. Copy the content of the file, paste it into any text editor and save with .json extension. For example, **Zendesk_Desktop.json** + +- Sing into [Webex Contact Center Managemnt Portal](https://portal.wxcc-us1.cisco.com/) of your lab pod. + +- Go to Provisioning -> Desktop Layout and press **New Layout** button. + +- Enter layout name (for example, "Zendesk Desktop Layout"), press **Upload** and choose JSON file with layout you have created above. Once file is uploaded, make sure it is validated successfully. + +- Click on "Teams" row and choose one or more teams. + +> **Note:** The agent you will use to test the integration with Zendesk must be the part of the team chosen above. + +- Press **Save** to create the layout. Once layout is created make sure it is "Active". + + +### 3. Create new Organization in Zendesk + +- Sign into your Zendesk instance. + +- Click on "Organizations" item of the vertical menu bar on the left. + +- Hover over **+ Add** button and choose **Organization** item from the pop-up menu. + +- Enter organization name and domain, then click **Save**. + +- Go to "Organizations" tab one more time to make sure new organization is successfully added. + + +### 4. Create new Customer in Zendesk + +- In Zendesk instance click on "Customers" item of the vertical menu bar on the left. + +- Hover over **+ Add** button and choose **User** item from the pop-up menu. + +- Enter user name and email. Choose user type "End User" and press **Add** button. + +- Click on **+ add contact** link on the left and enter calling number which you will use to make test call to Webex Contact Center later. + +- Go to "Customers" tab one more time to make sure new user is successfully added. + + +## Part 3: Test Webex Contact Center Agent Desktop for Zendesk + + + + +### 5. Sign into Webex Contact Center for Zendesk + +- Sign into your Zendesk instance. + +- Click to "Cisco Webex Contact Center" icon (grey square with white circle inside) at the top right corner of Zendesk window to see agent desktop. + +- Press **Sign In** button within "Cisco Webex Contact Center" app on the right-hand side and provide agent credentials in new borwser tab. + +- Once authentication is completed, provide "Dialed Number" / "Extension" and choose proper team within "Cisco Webex Contact Center" app. + +> **Note:** This team must have Desktop Layout for Zendesk applied in Webex Contact Center Management Portal in the previous part of this lab. + +- Make agent desktop "Available" by selecting corresponding state. + + +### 6. Make inbound test calls + +- Initiate a call from the calling number which matches the one configured under Zendesk user created in the previous part of this lab. + +- Answer the call by the agent and make sure you see screen pop with the details of the user created in the previous part of this lab and new ticket. "Requester" filed of the ticket must be pre-populated with user's name. + +- Answer the call and wait few seconds. Then hang up and wrap-up the call. + +- Make sure the ticket is completed with call details. + +- Initiate one more call from calling number which does not match any user in Zendesk and compare the behavior. + +- Answer the call by the agent and make sure you see screen pop with the details of new user created just after answering the call and new ticket. "Requester" filed of the ticket must be pre-populated with new user's name. + +- Answer the call and wait few seconds. Then hang up and wrap-up the call. + +- Make sure the ticket is completed with call details. + +- Click on "Views" item of the vertical menu bar on the left. Then click on "All unresolved tickets" and make sure you see both records created after test calls. + + + +--- + + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    + + diff --git a/README.md b/README.md index adc4591eba..1153b09eca 100644 --- a/README.md +++ b/README.md @@ -1,180 +1,33 @@ --- layout: home -title: Jekyll Gitbook Theme +title: 'Webex CC Lab guides' permalink: / +cover: /assets/gitbook/images/Home.jpeg --- -Make Jelly site have a GitBook look! -## Demo +Welcome to the Webex Labs Repository. Here you will find step-by-step guides on how to enable and configure the Webex Contact Center features. -Live demo on Github Pages: [https://sighingnow.github.io/jekyll-gitbook](https://sighingnow.github.io/jekyll-gitbook) -[![Jekyll Themes](https://img.shields.io/badge/featured%20on-JekyllThemes-red.svg)](https://jekyll-themes.com/jekyll-gitbook/) +## Lab Content -## Why Jekyll with GitBook +| Lab ID | Lab Details | Dificulty | Estimated | +|:------:|:-----------------------------------------------------------:|:---------:|:---------:| +| Lab 0 | [Provisioning (Trials & Production) ](/pages/Provisioning/) | EASY | 40 min | +| Lab 1 | [Admin Experience](/pages/CH/) | EASY | 30 min | +| Lab 2 | [IVR Contact Routing](/pages/IVR/) | MID | 60 min | +| Lab 3 | [Agent Desktop](/pages/Agent/) | MID | 55 min | +| Lab 4 | [Supervisor Desktop](/pages/Supervisor/) | EASY | 40 min | +| Lab 5 | [Analyzer Deep Dive](/pages/Analyzer/) | MID | 120 min | +| Lab 6 | [CRM Integration](/pages/CRM/) | HARD | 90 min | +| Lab 7 | [Google CCAI & TTS Integration](/pages/CCAI/) | MID | 90 min | +| Lab 8 | [Feedback and Journey](/pages/JDS_XM/) | EASY | 30 min | +| Lab 9 | [Outbound Campaign - Acqueon](/pages/Acqueon2/) | MID | 30 min | +| Lab 10 | [QM/WFO - Calabrio](/pages/Calabrio/) | TBD | TBD | +| Lab 11 | [Webex CC APIs](/pages/API/) | HARD | 90 min | +| Lab 12 | [Digital Channels](/pages/Digital/) | MID | 560 min | -GitBook is an amazing frontend style to present and organize contents (such as book chapters -and blogs) on Web. The typical to deploy GitBook at [Github Pages][1] -is building HTML files locally and then push to Github repository, usually to the `gh-pages` -branch. It's quite annoying to repeat such workload and make it hard for people do version -control via git for when there are generated HTML files to be staged in and out. -This theme takes style definition out of generated GitBook site and provided the template -for Jekyll to rendering markdown documents to HTML, thus the whole site can be deployed -to [Github Pages][1] without generating and uploading HTML bundle every time when there are -changes to the original repo. -## How to Get Started +
    -This theme can be used just as other [Jekyll themes][1] and support [remote theme][12], -see [the official guide][13] as well. - -You can introduce this jekyll theme into your own site by either - -- [Fork][3] this repository and add your markdown posts to the `_posts` folder. -- Use as a remote theme in your [`_config.yml`][14](just like what we do for this - site itself), - -```yaml -remote_theme: sighingnow/jekyll-gitbook -``` - -### Deploy Locally with Jekyll Serve - -This theme can be ran locally using Ruby and Gemfiles. - -[Testing your GitHub Pages site locally with Jekyll](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/testing-your-github-pages-site-locally-with-jekyll) - GitHub - -## Full-text search - -The search functionality in jekyll-gitbook theme is powered by the [gitbook-plugin-search-pro][5] plugin and is enabled by default. - -[https://sighingnow.github.io/jekyll-gitbook/?q=generated](https://sighingnow.github.io/jekyll-gitbook/?q=generated) - -## Code highlight - -The code highlight style is configurable the following entry in `_config.yaml`: - -```yaml -syntax_highlighter_style: colorful -``` - -The default code highlight style is `colorful`, the full supported styles can be found from [the rouge repository][6]. Customized -style can be added to [./assets/gitbook/rouge/](./assets/gitbook/rouge/). - -## How to generate TOC - -The jekyll-gitbook theme leverages [jekyll-toc][4] to generate the *Contents* for the page. -The TOC feature is not enabled by default. To use the TOC feature, modify the TOC -configuration in `_config.yml`: - -```yaml -toc: - enabled: true - h_min: 1 - h_max: 3 -``` - -## Google Analytics, etc. - -The jekyll-gitboook theme supports embedding the [Google Analytics][7], [CNZZ][8] and [Application Insights][9] website analytical tools with the following -minimal configuration in `_config.yaml`: - -```yaml -tracker: - google_analytics: "" -``` - -Similarly, CNZZ can be added with the following configuration in `_config.yaml` - -```yaml -tracker: - cnzz: "" -``` - -Application Insights can be added with the following configuration in `_config.yaml` - -```yaml -tracker: - application_insights: "" -``` - -## Extra StyleSheet or Javascript elements - -You can add extra CSS or JavaScript references using configuration collections: - -- extra_css: for additional style sheets. If the url does not start by http, the path must be relative to the root of the site, without a starting `/`. -- extra_header_js: for additional scripts to be included in the `` tag, after the `extra_css` has been added. If the url does not start by http, the path must be relative to the root of the site, without a starting `/`. -- extra_footer_js: for additional scripts to be included at the end of the HTML document, just before the site tracking script. If the url does not start by http, the path must be relative to the root of the site, without a starting `/`. - -## Customizing font settings - -The fonts can be customized by modifying the `.book.font-family-0` and `.book.font-family-1` entry in [`./assets/gitbook/custom.css`][10], - -```css -.book.font-family-0 { - font-family: Georgia, serif; -} -.book.font-family-1 { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -} -``` - -## Tips, Warnings and Dangers blocks - -The jekyll-gitbook theme supports customized kramdown attributes (`{: .block-tip }`, `{: .block-warning }`, -`{: .block-danger }`) like that displayed in [the discord.js website][11]. The marker can be used like - -```markdown -> ##### TIP -> -> This guide is last tested with @napi-rs/canvas^0.1.20, so make sure you have -> this or a similar version after installation. -{: .block-tip } -``` - -Rendered page can be previewed from - -[https://sighingnow.github.io/jekyll-gitbook/jekyll/2022-06-30-tips_warnings_dangers.html](https://sighingnow.github.io/jekyll-gitbook/jekyll/2022-06-30-tips_warnings_dangers.html) - -## Cover image inside pages - -The jekyll-gitbook theme supports adding a cover image to a specific page by adding -a `cover` field to the page metadata: - -```diff - --- - title: Page with cover image - author: Tao He - date: 2022-05-24 - category: Jekyll - layout: post -+ cover: /assets/jekyll-gitbook/dinosaur.gif - --- -``` - -The effect can be previewed from - -[https://sighingnow.github.io/jekyll-gitbook/jekyll/2022-05-24-page_cover.html](https://sighingnow.github.io/jekyll-gitbook/jekyll/2022-05-24-page_cover.html) - -## License - -This work is open sourced under the Apache License, Version 2.0. - -Copyright 2019 Tao He. - -[1]: https://pages.github.com -[2]: https://pages.github.com/themes -[3]: https://github.com/sighingnow/jekyll-gitbook/fork -[4]: https://github.com/allejo/jekyll-toc -[5]: https://github.com/gitbook-plugins/gitbook-plugin-search-pro -[6]: https://github.com/rouge-ruby/rouge/tree/master/lib/rouge/themes -[7]: https://analytics.google.com/analytics/web/ -[8]: https://www.cnzz.com/ -[9]: https://docs.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview -[10]: https://github.com/sighingnow/jekyll-gitbook/blob/master/gitbook/custom.css -[11]: https://discordjs.guide/popular-topics/canvas.html#setting-up-napi-rs-canvas -[12]: https://rubygems.org/gems/jekyll-remote-theme -[13]: https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/adding-a-theme-to-your-github-pages-site-using-jekyll -[14]: https://github.com/sighingnow/jekyll-gitbook/blob/master/_config.yml diff --git a/_config.yml b/_config.yml index e61f145489..74c7f9e0a8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,16 +1,17 @@ # Configurations -title: Jekyll Gitbook -longtitle: Jekyll Gitbook -author: HE Tao -email: sighingnow@gmail.com +title: Labs Library +longtitle: Webex CC +email: wxcclabs@cisco.com description: > - Build Jekyll site with the GitBook style. + Lab Guide Library + version: 1.0 gitbook_version: 3.2.3 -url: 'https://sighingnow.github.io' -baseurl: '/jekyll-gitbook' +url: 'https://webexcc.github.io' +baseurl: '' + rss: RSS # bootstrap: use the remote theme for the site itself @@ -19,10 +20,10 @@ remote_theme: sighingnow/jekyll-gitbook toc: enabled: true h_min: 1 - h_max: 3 + h_max: 1 # customize the link favicon in header, will be {{site.baseurl}}/{{site.favicon_path}} -favicon_path: /assets/gitbook/images/favicon.ico +favicon_path: assets/gitbook/images/favicon.ico # markdown render engine. markdown: kramdown @@ -51,12 +52,14 @@ collections: output: true permalink: /:collection/:path/ -page_width: 800px +page_width: 1024px destination: ./_site incremental: false regenerate: true +google_analytics: G-X0KSF40MEY + plugins: - jekyll-feed - jekyll-readme-index diff --git a/_includes/gitbook-sharing.json.tpl b/_includes/gitbook-sharing.json.tpl index f571e15031..aa5491ef86 100644 --- a/_includes/gitbook-sharing.json.tpl +++ b/_includes/gitbook-sharing.json.tpl @@ -1,13 +1,9 @@ - "sharing": { - "all": ["facebook", "google", "twitter", "weibo", "instapaper", "github", "telegram"], - "facebook": true, - "google": false, - "github": true, - "github_link": "https://github.com", - "telegram": false, - "telegram_link": "https://t.me", - "instapaper": false, - "twitter": true, - "vk": false, - "weibo": false - }, + "sharing": { + "facebook": true, + "google": false, + "github": true, + "telegram": false, + "instapaper": false, + "twitter": true, + "vk": false + }, diff --git a/_includes/google-analytics.html b/_includes/google-analytics.html index 623ed00bc9..2ddf718ab3 100644 --- a/_includes/google-analytics.html +++ b/_includes/google-analytics.html @@ -1,9 +1,9 @@ - - + + diff --git a/_includes/toc-date.html b/_includes/toc-date.html index dc7d518bbd..d96d7d3ad3 100644 --- a/_includes/toc-date.html +++ b/_includes/toc-date.html @@ -50,12 +50,12 @@ {% endif %} {% endif %} {% endfor %} -
  • - - Fork it Now! + + Support & Feedback
  • + diff --git a/_layouts/home.html b/_layouts/home.html index 8906a593a4..e9df6c00a5 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -1,6 +1,7 @@ + {%- include google-analytics.html -%} {%- include head.html -%} @@ -50,4 +51,4 @@

    {%- include footer.html -%} - \ No newline at end of file + diff --git a/_layouts/post.html b/_layouts/post.html index df395a92db..d7bc0d8462 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -1,7 +1,7 @@ - + {%- include head.html -%} {% if page.previous %} @@ -64,4 +64,4 @@

    {%- include footer.html -%} - \ No newline at end of file + diff --git a/_pages/API.md b/_pages/API.md new file mode 100644 index 0000000000..d7775280f1 --- /dev/null +++ b/_pages/API.md @@ -0,0 +1,385 @@ +--- +title: Lab 11 - Webex CC APIs +author: Shrishail Doddalinganavar & Kevin Simpson & Krishna Tyagi & Arunabh Bhattacharjee +date: 2022-11-11 +layout: post +--- + +``` +Last modified: Mon, 19 Jun 2023 +``` + +## Table of Contents + + + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Introduction to the New Webex CC APIs](#introduction-to-the-new-webex-cc-apis) | Practical Lab | MID | 25 min | +| [Reporting APIs](#reporting-apis) | Practical Lab | MID | 25 min | +| [Call Recording APIs](#call-recording-apis) | Practical Lab | EASY | 15 min | +| [Configuration APIs](#configuration-apis) | Practical Lab | MID | 20 min | +| [Search API](#search-api) | Practical Lab | MID | 25 min | +| [Agent Desktop APIs](#agent-desktop-apis) | Practical Lab | MID | 25 min | + + + + +## Introduction + +**Important:** Changes to the API Lab. + +- The New Webex Contact Center APIs are now available on **[developer.webex-cx.com](https://developer.webex-cx.com){:target="_blank"}** and use OAuth2 as opposed to One-time API Keys. +- The Legacy APIs (v1) are still available and are documented in the later section of this lab. +- The lab assumes that you will use the All New Webex Contact Center APIs which are documented below. +- For a quick start and overview, refer to the Overview / Quick start section. + + +## All New Webex Contact Center APIs (New Version) + +# Introduction to the New Webex CC APIs +> This is the introduction video. It explains what API we have, what application and authorization mechanisms exist and how to get started. + + + + + + +### 1. Walkthrough of Auth Flow +- To develop applications with the new APIs, you must build an integration with Webex. + +- See **[Contact Center Dev Portal Docs](https://developer.webex-cx.com/documentation/getting-started){:target="_blank"}** for all the details. + + +Here is a summary: + +**API Access- create an Integration** + +- The New Webex Contact Center APIs are accessed by using Webex OAuth2 + +- Watch this **[video](https://app.vidcast.io/share/b8b4de22-7322-45d3-ab9c-070b3a8ec1f3){:target="_blank"}** to create an integration and run APIs on postman. + +- **[Steps](https://www.cisco.com/c/en/us/support/docs/contact-center/webex-contact-center/218418-configure-webex-contact-center-apis-with.html){:target="_blank"}** to create an integration and use on postman + +- OAuth2 by design, requires a client ID, clinet secret, callback URL(Redirect URL) + +- Use the Client ID, Client Secret, Redirect URI (callback URL) to obtain access_token for your Org. Use the Access token to hit the API inside of the Authorization header. + +`Authorization: Bearer yourAccessToken` + +- Use the refresh_token before it expires to renew your access_token - and get a new set of Access and Refresh Tokens. + +`By Default, the access_token is valid for 12 hours and the refresh token is valid for 60 days, however using another call for the refresh token will give you a new set of tokens. Maintaining this access is important for perpetual access. One can write a simple scheduler that performs this background refresh activity.` + +**OAuth2 Mechanism - Implications** + +- With the OAuth2 support- Will require a "One Time Onboarding" User interface to obtain access to an org + +- "Login with Webex" > Button to access an org + +- You will register an App with us and use it for N orgs + +- Have each Org administrator login into your App at least once to obtain the tokens + +- This is a "Required Onboarding " Process + +- Once you obtain an Org's access_token and refresh_token, you can access their data + + + +**OAuth2 Access Token Flow** + +- Your App redirects to authorize with Webex (GET) + +1. GET `https://webexapis.com/v1/authorize?client_id=______&response_type=code&redirect_uri=_https://your-app/auth___&scope=cjp:config_read&state=set_state_here` + +- Admin user COMPLETES login.Redirect back to your App (GET) + +2. GET https://your-app/auth?code=___unique_code_sent + +- Your App usess this code - API Endpoint - and then sends a POST request back to Webex + +- Request Access Token AND/OR Refresh Tokens (POST) + +3. POST https://webexapis.com/v1/access_token` + application/x-www-form-urlencoded + +```javascript +{"access_token":"ZDI3MGEyYzQtNmFlNS00NDNhLWFlNzAtZGVjNjE0MGU1OGZmZWNmZDEwN2ItYTU3", +"expires_in":1209600, +"refresh_token":"MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTEyMzQ1Njc4", +"refresh_token_expires_in":7776000 } +``` + +> Expiry in seconds and required x-www-form-urlencoded values include + +> grant_type = _authorisation_code OR refresh_token_ + +> client_id + +> client_secret + +> code + +> redirect_uri + +### 2. Initial Setup of Sample App + +- Login with the POD admin account to https://developer.webex-cx.com/. + +- Go to > Documentation > API Reference. + +- Follow the instructions in the video to request access to your sample app. + +- The sample app is available here :**[https://github.com/CiscoDevNet/webex-contact-center-api-samples/tree/main/app-auth-sample](https://github.com/CiscoDevNet/webex-contact-center-api-samples/tree/main/app-auth-sample){:target="_blank"}** + +- Follow the instructions in the video to clone the repository and run the app. + + +# Reporting APIs + +> In this video we will go through the developer portal and execute your first API calls through Postman. + + + + +- Login with the POD admin account to https://developer.webex-cx.com/. + +- Go to > Documentation > API Reference. + + + +### 1. Executing "Get Tasks" API + + +- Go to the Tasks section. + +- Click on GET Tasks > Try Out + +- Fetch all the tasks using the "From Date/time" in Epoch milliseconds. + +- To get the Epoch time use [epochconverter](https://www.epochconverter.com) + +- Enter the Org ID and channel type > Press Run + +The same request can be drafted on Postman using your personal Bearer Token. + +Example of a GET Task: https://api.wxcc-us1.cisco.com/v1/tasks + +- Create a new collection in Postman + +- Under that add a request + +- Enter the request URL copied from the developer portal. Make changes to the from and to times and the org ID to refelect your tenant. + +- Under Headers enter the _Key:_ _Authorization_ and _Value _: _Bearer 'Your Bearer token copied from the developer portal'_ + +- Under Parameters enter the values you wil be passing as shown in the video + +- Click on Send + + +### 2. Executing "Get Queue Statistics" API + +- Go to the Queues section. + +- Click on Get Queue Statistics > Try Out + +- Enter the from date, to date and the interval + +- Click on Run + +To try this out in Postman follow the steps outlined in the previous example + + +### 3. Executing "Get Agent Activities" API + +- Go to the Agents section. + +- Click on get Agent Activities > Try Out + +- Enter the required parameters as explained in the video .Click on Run + +To try this out in Postman follow the steps outlined in the previous example + + +### 4. Executing "Get Agent Statistics" API + +- Go to the Agents section. + +- Click on get Agent Statistics > Try Out + +- Enter the required parameters as explained in the video .Click on Run + +To try this out in Postman follow the steps outlined in the previous example + + + +# Call Recording APIs + +> In this video we will concentrate on "Captures" API. Captures are audio recordings that can be downloaded through API. + + + + + + +### Working with "List Captures" API + +- Run the Get Tasks API as explained in the video and get teh required task IDs + +- Go to Captures section + +- Click on List Captures > Try Out + +- Enter the parameters :orgid, taskids,urlexpiration + +- Click on Run + +- Use the Filepath in the response to download and listen to the recording + +- Enter the required parameters as explained in the video .Click on Run + +To try this out in Postman follow the steps outlined in the previous example + + +# Configuration APIs + +> This is the bonus section of New WxCC APIs where you will be able to create/change settings in the Webex Contact Center by using the Configuration APIs. + + + + + +### 1. Creating a Site with "Create Sites" API + +- Go to Sites section + +- Click on Create Sites > Try Out + +- Enter the parameters :active,orgid, multimediaprofileid,name + +- Click on Run + +To try this out in Postman follow the steps outlined in the previous example + + +### 2. Changing the Site name with "Update Site By ID" API + +- Go to Sites section + +- Click on Update Site by ID > Try Out + +- Enter the parameters orgid and the id (The site ID that was created in the previous exercise) + +- In the request body update the orgid,id, multimediaprofileid, name + +- Click on Run + +To try this out in Postman follow the steps outlined in the previous example + + +### 3. Practicing with Bulk Upload + +Follow the instructions in the video to use Postman and create mutiple sites using a csv file + +# Search API + +
    + +
    + +### 1. Search endpoint in developer portal + + - Go to - **[Search endpoint on Developer Portal](https://developer.webex-cx.com/documentation/search){:target="_blank"}** + - Click on -> Try out -> Expand try out window by clicking box icon on right hand side top section. + +### 2. Forming a graphQL query + + - In the interactive editor paste the query from github sample **[link](https://github.com/CiscoDevNet/webex-contact-center-api-samples/blob/main/reporting-samples/graphql-sample/simple.graphql){:target="_blank"}** + - NOTE : To and From should be changed according to your needs, it has to be epoch time in miliseconds, use this **[link](https://www.epochconverter.com/){:target="_blank"}** to convert. + +### 3. Running the query + +- Click on run - notice that you will receive all the interaction ID's between that timeframe. +- Run the query **[https://github.com/CiscoDevNet/webex-contact-center-api-samples/blob/main/reporting-samples/graphql-sample/totalCallsByAni.graphql](https://github.com/CiscoDevNet/webex-contact-center-api-samples/blob/main/reporting-samples/graphql-sample/totalCallsByAni.graphql){:target="_blank"}** to aggregate calls from a specific phone number. +- NOTE : Change the line 11 to the ANI from your tenant. +- Refer to docs section as shown in video to find explaination for each fields in the schema. +- You can also run all the graphQL samples **[here](https://github.com/CiscoDevNet/webex-contact-center-api-samples/tree/main/reporting-samples/graphql-sample){:target="_blank"}** + + NOTE : Change filters and aggregation values according to your tenant. + +# Agent Desktop APIs + +
    + +### 1. Useful links + +- **[Web socket subscription API](https://developer.webex-cx.com/documentation/notification){:target="_blank"}** +- **[Login](https://developer.webex-cx.com/documentation/agents/v1/login){:target="_blank"}** +- **[Logout](https://developer.webex-cx.com/documentation/agents/v1/logout){:target="_blank"}** +- **[Reload](https://developer.webex-cx.com/documentation/agents/v1/reload){:target="_blank"}** +- **[State change](https://developer.webex-cx.com/documentation/agents/v1/state-change){:target="_blank"}** + +### 2. Importing postman collection and setting up oauth2. + +- As shown in the **[video](https://github.com/CiscoDevNet/webex-contact-center-api-samples/blob/main/desktop-api-sample/WebexCC%20Desktop%20APIs%20-%20Sample.postman_collection.json){:target="_blank"}** Import the desktop postman collection. +- Postman -> Import -> Raw Text -> Continue +- Setup Oauth2 connection on postman collection as mentioned in **[section 1](https://app.vidcast.io/share/b8b4de22-7322-45d3-ab9c-070b3a8ec1f3){:target="_blank"}** + + +### 3. Establish a websocket connection + +- Establish a web socket connection from postman as shown in this **[video](https://developer.webex-cx.com/documentation/notification){:target="_blank"}** +- Collection -> Agent -> Register Web socket Subscription. +- Run the request. A websocket URL will be generated. +- Copy the web socket notification URL received in the above step. +- On Postman Click on New -> WebSocket Request -> Paste the URL -> Click connect. +- At this point a WebSocket will be established successfully. + +### 4. Login an agent + +- Collection -> Agent -> Station login. +- Change the request body as mentioned in this **[document](https://developer.webex-cx.com/documentation/agents/v1/login){:target="_blank"}** +- Click on send. +- Agent will be successfully logged in and will be in idle state. +- Click on web socket established in step 5 and notice that an event is received on web socket for successful login. + +### 5. Change state of an agent + +- Collection -> Agent -> Change state. +- Change the request body as mentioned in this (To available) **[document](https://developer.webex-cx.com/documentation/agents/v1/state-change){:target="_blank"}** +- Click on send. +- Agent state will be successfully changed to Available. +- Click on web socket established in step 3 and notice that an event is received on web socket for successful state change. + +### 6. Reload an agent + +- Collection -> Agent -> Reload Agent. +- Reload API **[documentation](https://developer.webex-cx.com/documentation/agents/v1/reload){:target="_blank"}** +- Click on send. +- Agent state data will be successfully received on web socket. this will include the config details aswell as task agent is handling. +- Click on web socket established in step 3 and notice that an event is received on web socket for successful agent reload. + +### 7. Logout an agent + +- Collection -> tasks -> Logout Task. +- Change the request body as in this **[document](https://developer.webex-cx.com/documentation/agents/v1/logout){:target="_blank"}** +- Click on send. +- Agent will be successfully logged out. +- Click on web socket established in step 3 and notice that an event is received on web socket for successful agent reload. + + + + + +--- + + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    + + + + diff --git a/_pages/Acqueon2.md b/_pages/Acqueon2.md new file mode 100644 index 0000000000..f338009afc --- /dev/null +++ b/_pages/Acqueon2.md @@ -0,0 +1,437 @@ +--- +title: Lab 9 - Outbound Campaign (Preview & Progressive) +author: Gagarin Sathiyanarayanan (gasathiy@cisco.com) +date: 2022-09-09 +layout: post +--- + +``` +author: Gagarin Sathiyanarayanan (gasathiy@cisco.com) +Last modified: Wed, 06 Mar 2024 +``` + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------- | ------------- | ---------------- | ---------------- | +| [Lab 9.1 Verify Tenant Provisioning](#verify-tenant-provisioning) | Practical Lab | EASY | 5 min | +| [Lab 9.2 Preview Campaign](#lab-92-preview-campaign) | Practical Lab | EASY | 20 min | +| [Lab 9.3 Progressive Campaign](#lab-93-progressive-campaign) | Practical Lab | EASY | 20 min | +| [Lab 9.4 Predictive Campaign](#lab-94-predictive-campaign) | Coming Soon | Coming Soon | Coming Soon | +| [Lab 9.5 Call Guide](#lab-95-call-guide) | Coming Soon | Coming Soon | Coming Soon | + +## Introduction + +In this lab you will learn about configuring Webex Contact centre to manage outbound voice campaigns using the LCM (List and Campaign Manager) application. + +## Lab Objective + +1. Configure Webex Contact Centre and LCM (List and Campaign Manager) application +2. Verify that the Agents can accept outbound campaign calls from the Webex CC Agent Desktop + +## Lab Pre-requisites + +- In this lab tenant, the tenant provisioning and integration is already completed. If you are using a different tenant, you can configure and use outbound campaigns only if your enterprise has purchased the Acqueon SKU and provisioning, integration is completed. +- You should also be able to login to agent desktop with your respective team created in previous labs +- This step should have been completed as part of previous lab sections. If not already done, please create a team and add your agent to this new team +- Acqueon tenant version should be `v4.2.1.2310 and above` ( instructions in this guide are based on `v4.2.1.2401`) + +## Lab Section + +# Lab 9.1 Verify Tenant Provisioning + +- Login to Control Hub, navigate to Contact Center Settings > Addons and ensure `Campaign Management` option is enabled + +![Outbound](/assets/images/Acqueon/AE_9.1.1.gif) + +- Navigate to `Integrations` option and ensure a custom connector with the name `CampaignManagerCredential` is created + +![Outbound](/assets/images/Acqueon/AE_9.1.2.gif) + +> Note: The steps mentioned above are integral to the Acqueon provisioning and integration process and should have been completed as part of your initial setup. This current step serves merely as a verification to ensure everything is in place before you begin with the lab. This has already been completed for the lab tenant. If you are using a different tenant and discover that any of the necessary steps have not been completed on your tenant, please consult the Webex Contact Center Ordering Guide available at https://www.cisco.com/c/en/us/partners/tools/collaboration-ordering-guides.html. Here, you can find the relevant SKUs and instructions on how to place your order. + +# Lab 9.2 Preview Campaign + +### Step 1: Navigate to Flows > Manage Flows > Create Flows + +![Outbound](/assets/images/Acqueon/AE_9.2.1.png) + +### Step 2: Provide a desired `Flow Name` and click `Start building Flow` + +![Outbound](/assets/images/Acqueon/AE_9.2.2.png) + +### Step 3: Connect the `NewPhoneContact` activity to `EndFlow` activity. Set `Validations` to On and `Publish Flow` + +![Outbound](/assets/images/Acqueon/AE_9.2.3.png) + +> Note: A flow must be configured with each campaign, referenced by the outdial entrypoint. The flow is simple, but dictates which variables are shown on the agent desktop and in which order. This is done via global variables. Configure variables in the flow as required. In this lab exercise, we will not be configuring any variables. + +### Step 4: Create Outdial Queue + +- Navigate to `Queues` and click `Create Queue` + ![Outbound](/assets/images/Acqueon/AE_9.2.4.png) + +- Configure the outdial queue + - **Name:** `Provide any desired Name` + - **Queue Type:** `Outdial Queue` + - **Outbound Campaign:** `ON` + - **Queue Routing Type:** `Longest Available Agent` + - **Call Distribution:** Create Group > Select the team that the agent is part of + - **Service Level Threshold:** `Set a desired value` + - **Maximum Time in Queue:** `Set a desired value` + - **Default Music in Queue:** `Set a desired value` +- Click `Create` + +![Outbound](/assets/images/Acqueon/AE_9.2.5.gif) + +### Step 5: Create Outdial EntryPoint + +- Navigate to `Channels` and click `Create Channel` + ![Outbound](/assets/images/Acqueon/AE_9.2.6.png) + +- Configure the outdial EntryPoint + - **Name:** `Provide any desired Name` + - **Channel Type:** `Outbound Telephony` + - **Service Level Threshold:** `Set a desired value` + - **Routing Flow:** `Select flow created in Step1` + - **Version Label:** `Latest` (or as per your configuration) + - **Outdial Queue:** `Select the Queue created in previous step` +- Click `Create` + +![Outbound](/assets/images/Acqueon/AE_9.2.7.gif) + +### Step 6: Configure Desktop layout for preview + +- Navigate to `Desktop Layouts` and click `Create Desktop Layout` + ![Outbound](/assets/images/Acqueon/AE_9.2.8.png) + +- Provide a desired name and select the team that the agent is part of. Also, download the dekstop layout. + ![Outbound](/assets/images/Acqueon/AE_9.2.9.png) + +- Edit the downloaded layout in any desired text editor and replace `advancedHeader` section with the below content. + +![Outbound](/assets/images/Acqueon/AE_9.2.10.gif) + +```json +"header":{ + "id":"dw-header", + "widgets":{ + "acqueon-component":{ + "comp": "agentx-preview-campaign", + "properties":{ + "isCampaignManagementEnabled": "$STORE.agent.isCampaignManagementEnabled", + "agentDbId": "$STORE.agent.acqueonAgentId", + "lcmUrl": "$STORE.agent.lcmUrl", + "isCallInProgress": "$STORE.agentContact.isActiveCall", + "outdialEntryPointId": "$STORE.agent.outDialEp", + "teamId": "$STORE.agent.getAcqueonTeamId", + "campaignManagerAdditionalInfo": "$STORE.agent.campaignManagerAdditionalInfo", + "orgId": "$STORE.agent.orgId", + "dialerProxyHost": "$STORE.envVaribles.serviceUrls.dialerProxyHost", + "isProgressiveCampaignEnabled": "$STORE.app.featureFlags.isProgressiveCampaignEnabled" + + } + } + }, + "layout":{ + "areas":[["acqueon-component"]], + "size":{"cols":[1], "rows":[1]} + } + }, +``` + +- Save this layout as a new file and upload it to desktop layout configuration. Click `Save` + ![Outbound](/assets/images/Acqueon/AE_9.2.11.png) + +- Login to Agent desktop with the team that is assigned this layout and verify that the campaign management icon is visible on the desktop + ![Outbound](/assets/images/Acqueon/AE_9.2.12.png) + +### Step 7: Create Campaign Group (Preview) + +- Navigate to Contact Center Administration portal + ![Outbound](/assets/images/Acqueon/AE_9.2.13.png) + +- Cross launch into Acqueon administration portal + ![Outbound](/assets/images/Acqueon/AE_9.2.14.png) + +- Navigate to `Group` and click `+` + ![Outbound](/assets/images/Acqueon/AE_9.2.15.png) + +- Select `Voice Campaign Group` option + ![Outbound](/assets/images/Acqueon/AE_9.2.16.png) + +- Configure the below: + - Name: `Enter desired Name` + - Dialer Name: `Select the dialer configured in your tenant` + - Entry POint: `Select the outdial entrypoint created in Step 5` + - Pacing Mode: `Preview` +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.2.17.png) + +- Select ANI based on your requirement +- From the list of available teams, select the respective team that is assigned to agent and move it under `Assigned Teams`. Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.2.18.png) + +- Click `Save` + ![Outbound](/assets/images/Acqueon/AE_9.2.19.png) + +- Verify group status shows as `Executing` + ![Outbound](/assets/images/Acqueon/AE_9.2.20.png) + +### Step 8: Create Campaign (Preview) + +- Navigate to `Campaign` and click `Add Campaign` + ![Outbound](/assets/images/Acqueon/AE_9.2.21.png) + +- Configure the below: + - Name: `Enter desired Name` + - Select Date Range, Time Range, TimeZone as per your requirement +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.2.22.png) + +- Select `Dedicated Campaign Group` and select the group created in previous step +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.2.23.png) + +- Select `Default_Simple_Strategy` as the contact strategy +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.2.24.png) + +- Leave the default values as such and click `Save` + ![Outbound](/assets/images/Acqueon/AE_9.2.25.png) + +### Step 9: Create and upload contact list + +- Create a text file with comma seperated values as shown in the image below +- The first row in the file should be : Firstname,Lastname,Phone +- The second row in the file should be: Test,Agent1,<`Any US phone number of your choice`> +- Save the file + +![Outbound](/assets/images/Acqueon/AE_9.2.31.png) + +- Navigate to "Contact Lists" section. Click on the "+" sign at the bottom right and click "Upload Contacts" + ![Outbound](/assets/images/Acqueon/AE_9.2.27.png) + +- Verify "Source Type" is `Formatted File` +- Verify "File Type" is `Text/CSV` and "Delimiter" is `,` +- Click "Choose File" and select the file created in the previous step + ![Outbound](/assets/images/Acqueon/AE_9.2.28.png) + +- Navigate to "Field Mapping", select "ZoneName" as `Campaign Specific TimeZone` + ![Outbound](/assets/images/Acqueon/AE_9.2.29.png) + +- Navigate to "Modes Mapping", select "Mobile" as `Mobile` +- Click "Upload" + ![Outbound](/assets/images/Acqueon/AE_9.2.30.png) + +- Click "Refresh" and verify that the list shows up under the list of records + ![Outbound](/assets/images/Acqueon/AE_9.2.32.png) + +- Navigate to `Campaign` > `Actions` > `Start` + ![Outbound](/assets/images/Acqueon/AE_9.2.33.png) + +### Step 10: Accept the Campaign Contact from Agent Desktop + +- Login to desktop with agent credentials and select the appropriate team that was selected during the outdial queue creation. +- Click `Campaign Contact` and accept the preview contact + ![Outbound](/assets/images/Acqueon/AE_9.2.34.png) + +# Lab 9.3 Progressive Campaign + +### Step 1: Navigate to Flows > Manage Flows > Create Flows + +![Outbound](/assets/images/Acqueon/AE_9.2.1.png) + +### Step 2: Provide a desired `Flow Name` and click `Start building Flow` + +![Outbound](/assets/images/Acqueon/AE_9.3.2.png) + +### Step 3: Connect the `NewPhoneContact` activity to `EndFlow` activity. Set `Validations` to On and `Publish Flow` + +![Outbound](/assets/images/Acqueon/AE_9.3.3.png) + +> Note: A flow must be configured with each campaign, referenced by the outdial entrypoint. The flow is simple, but dictates which variables are shown on the agent desktop and in which order. This is done via global variables. Configure variables in the flow as required. In this lab exercise, we will not be configuring any variables. + +### Step 4: [Optional] Configure custom messages for Answering Machine or Abandoned Calls + +- Navigate to `Event Flows` + ![Outbound](/assets/images/Acqueon/AE_9.3.9.png) + +> There is a new `OutboundCampaignCallResult` handler event which can be used to trigger a message to be played to the customer when the call has terminated at a voicemail/Answering machine or will be abandoned. In the diaexample below, a message is played for each case and the call is then disconnected. If the handler is not configured, the call will terminate when these two conditions occur. + +- Add the `Case` activity and configure the below 2 cases + - Case1: `AMD` + - Case2: `ABANDONED` + - Select the variable as `OutboundCampaignCallResult.CPAResult` + +![Outbound](/assets/images/Acqueon/AE_9.3.4.gif) + +- Add two `PlayMessage` activity and configure the custom message for both the cases. You can use Text-To-Speech (TTS) or a audio file as required. + +- Case1 (AMD) + ![Outbound](/assets/images/Acqueon/AE_9.3.5.gif) + +- Case2 (ABANDONED) + ![Outbound](/assets/images/Acqueon/AE_9.3.6.gif) + +- Add `DisconnectContact` activity and conenct the output of the `PlayMessage` activity to it +- Also connect the `Default` outcome of the `Case` activity to the `DisconnectContact` activity +- Connect the outcome of `OutboundCampaignCallResult` activity to the `Case` activity +- Connect the `Case` outcome nodes to its respective `PlayMessage` activity + +![Outbound](/assets/images/Acqueon/AE_9.3.7.gif) + +- Set `Validations` to On and `Publish Flow` + ![Outbound](/assets/images/Acqueon/AE_9.3.8.png) + +### Step 5: Create Outdial Queue + +- Navigate to `Queues` and click `Create Queue` + ![Outbound](/assets/images/Acqueon/AE_9.2.4.png) + +- Configure the outdial queue + - **Name:** `Provide any desired Name` + - **Queue Type:** `Outdial Queue` + - **Outbound Campaign:** `ON` + - **Queue Routing Type:** `Longest Available Agent` + - **Call Distribution:** Create Group > Select the team that the agent is part of + - **Service Level Threshold:** `Set a desired value` + - **Maximum Time in Queue:** `Set a desired value` + - **Default Music in Queue:** `Set a desired value` +- Click `Create` + +![Outbound](/assets/images/Acqueon/AE_9.3.1.gif) + +### Step 6: Create Outdial EntryPoint + +- Navigate to `Channels` and click `Create Channel` + ![Outbound](/assets/images/Acqueon/AE_9.2.6.png) + +- Configure the outdial EntryPoint + - **Name:** `Provide any desired Name` + - **Channel Type:** `Outbound Telephony` + - **Service Level Threshold:** `Set a desired value` + - **Routing Flow:** `Select flow created in Step1` + - **Version Label:** `Latest` (or as per your configuration) + - **Outdial Queue:** `Select the Queue created in previous step` +- Click `Create` + +![Outbound](/assets/images/Acqueon/AE_9.3.10.gif) + +### Step 7: Create Campaign Group (Progressive) + +- Navigate to Contact Center Administration portal + ![Outbound](/assets/images/Acqueon/AE_9.2.13.png) + +- Cross launch into Acqueon administration portal + ![Outbound](/assets/images/Acqueon/AE_9.2.14.png) + +- Navigate to `Group` and click `+` + ![Outbound](/assets/images/Acqueon/AE_9.2.15.png) + +- Select `Voice Campaign Group` option + ![Outbound](/assets/images/Acqueon/AE_9.2.16.png) + +- Configure the below: + - Name: `Enter desired Name` + - Dialer Name: `Select the dialer configured in your tenant` + - Entry POint: `Select the outdial entrypoint created in Step 6` + - Pacing Mode: `Progressive` +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.3.11.png) + +- Select ANI based on your requirement +- Configure `Dial Rate` and `No Answer Ring Limit` as required or as shown in the image below +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.3.12.png) + +> The `CPA Parameters` tab of the Campaign Group specifies whether CPA and AMD are needed for the call. The CPA parameters are considered advanced and are not typically modified. CPA is performed on the call by the dialer directly - there is no agent awareness. It has the ability to detect FAX machines, busy signals, invalid numbers, no answer calls and answering machines / voicemails. + +- Enable `CPA` , `AMD Detection`, `Terminating Tone Detection` and click `Next` + +![Outbound](/assets/images/Acqueon/AE_9.3.13.png) + +- Configure `Contact Parameters` values as per the requirement and Click `Save` + ![Outbound](/assets/images/Acqueon/AE_9.3.14.png) + +- Verify group status shows as `Executing` + ![Outbound](/assets/images/Acqueon/AE_9.3.15.png) + +### Step 8: Create Campaign (Progressive) + +- Navigate to `Campaign` and click `Add Campaign` + ![Outbound](/assets/images/Acqueon/AE_9.2.21.png) + +- Configure the below: + - Name: `Enter desired Name` + - Business Outcome Group: `Default group` +- Select Date Range, Time Range, TimeZone as per your requirement +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.3.16.png) + +- Select `Dedicated Campaign Group` and select the group created in previous step +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.3.17.png) + +- Select `Default_Simple_Strategy` as the contact strategy +- Click `Next` + ![Outbound](/assets/images/Acqueon/AE_9.3.18.png) + +- Leave the default values as such and click `Save` + ![Outbound](/assets/images/Acqueon/AE_9.3.18.png) + +### Step 9: Create and upload contact list + +- Create a text file with comma seperated values as shown in the image below +- The first row in the file should be : Firstname,Lastname,Phone +- The second row in the file should be: Test,Agent1,<`Any US phone number of your choice`> +- Save the file + +![Outbound](/assets/images/Acqueon/AE_9.3.20.png) + +- Navigate to `Contact Lists` section. Click on the `+` sign at the bottom right and click `Upload Contacts` + ![Outbound](/assets/images/Acqueon/AE_9.3.21.png) + +- Verify "Source Type" is `Formatted File` +- Verify "File Type" is `Text/CSV` and "Delimiter" is `,` +- Click "Choose File" and select the file created in the previous step + ![Outbound](/assets/images/Acqueon/AE_9.2.28.png) + +- Navigate to "Field Mapping", select "ZoneName" as `Campaign Specific TimeZone` + ![Outbound](/assets/images/Acqueon/AE_9.2.29.png) + +- Navigate to "Modes Mapping", select "Mobile" as `Mobile` +- Click "Upload" + ![Outbound](/assets/images/Acqueon/AE_9.2.30.png) + +- Click "Refresh" and verify that the list shows up under the list of records + ![Outbound](/assets/images/Acqueon/AE_9.3.22.png) + +- Navigate to `Campaign` > `Actions` > `Start` + ![Outbound](/assets/images/Acqueon/AE_9.3.23.png) + +### Step 10: Accept the Campaign Contact from Agent Desktop + +- Login to desktop with agent credentials and select the appropriate team that was selected during the outdial queue creation. +- Change agent status to `Available` + +> The below example/demo covers a progressive 1:N dialer with Call Progress Analysis (CPA). + +- Once an agent is available, the system will place `N` customer calls (This value is configured in Step 7 under `Dial Rate` configuration) + +- For calls which result in live voice, the system will connect the agents + +- If customer call is abandoned or goes to voicemail, our system will invoke the flow to determine how to handle the scenario (Through Configurations done in `Step4`) + +![Outbound](/assets/images/Acqueon/AE_9.3.24.gif) + +- In the `Progressive & Predictive Campaign Realtime Report` we can verify that both the numbers in the contact list were dialed once an agent was available + ![Outbound](/assets/images/Acqueon/AE_9.3.25.png) + +# Lab 9.4 Predictive Campaign + +Stay Tuned. Coming Soon !!! + +# Lab 9.5 Call Guide + +Stay Tuned. Coming Soon !!! diff --git a/_pages/Agent.md b/_pages/Agent.md new file mode 100644 index 0000000000..3d773b5bdd --- /dev/null +++ b/_pages/Agent.md @@ -0,0 +1,643 @@ +--- +title: Lab 3 - Agent Desktop +author: Gorka Antona Santamaria & Neha Wuthoo +date: 2022-03-02 +layout: post +--- + +``` +Last modified: Wed, 27 Sept 2023 +``` + + + +## Overview of the lab: + +In this lab, we will go through the Agents Desktop portal use in their daily basis. We will review how to complete some of the most common tasks and some more advance features will be introduced. + +At the end of the lab, you should be able to handle calls as an agent, perform some useful agent tasks and create your cutomized Agent Desktop. + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| ------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Agent Desktop Overview](#agent-desktop-overview) | Demo | EASY | 10 min | +| [Basic Features](#basic-features) | Practical Lab | EASY | 15 min | +| [Custom Desktop Layouts](#custom-desktop-layout) | Practical Lab | MEDIUM | 30 min | + +## Introduction + +### Lab Objective + +- The objective of this lab is to get an idea about the Agents user journey, to familiarize with the platform they use and to explore some of the most useful new features they offer. + +- In the first part of the lab we will focus on explaining the different parts and and possible functions of Agent Desktop interface + +- In the second part of the lab, you will learn some of the basic functions that a user can perform as an agent: handle Incoming calls, making outdial calls and configure some User Profile setting + +- In the third part of the lab we will customize Horizontal header of the platform and also add some custom widget in the Navigarion bar section. + +### Pre-requisite + +1. You need to have **Webex App** installed in your laptop or mobile phone to place calls. If you prefer, you could also do it from your phone number directly. + + - You will need an extra device (your personal phone for example) to test Consult and Conference functionalities + +2. For doing this lab, you must first complete the **Lab 1: Control Hub and Admin Portal:** + + - You have the administrator's access to the Tenant Management Portal. + - Agent and Supervisor users created and configured + - You have agent's access to the Agent Desktop + - You have the supervisor's access to the Tenant Management Portal. + - Agent is part of 2 Teams. + - Webex Calling extension is assigned to the supervisor user. + +3. You also must complete the **Lab 2: IVR Contact Routing:** + - Simple flow configured and making a call tested + - Global variables created as Agent Editable + +4. For Part 3 - Custom Desktop Layour, you should have a Webex Contact Center Analyzer Report. You can use the Stock Reports created by default or use your own custom Reports + > [How to create Analyzer Report on Webex Contact Center Analyzer](https://github.com/CiscoDevNet/webex-contact-center-api-samples/tree/main/iframe-widget-sample) + +### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com){:target="\_blank"}**\ +> Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal){:target="\_blank"}**\ +> Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com){:target="\_blank"}**\ +> Developer Portal: **[https://developer.webex-cx.com](https://developer.webex-cx.com/){:target="\_blank"}**\ +> API Samples Git Repository: **[https://github.com/CiscoDevNet/webex-contact-center-api-samples](https://github.com/CiscoDevNet/webex-contact-center-api-samples){:target="\_blank"}**\ +> Widgets Samples Git Repository: **[https://github.com/CiscoDevNet/webex-contact-center-widget-starter/tree/master/Examples](https://github.com/CiscoDevNet/webex-contact-center-widget-starter/tree/master/Examples){:target="\_blank"}**\ + +## Lab Section + +> +> Please submit the form with your Attendee ID. All configuration items in the lab guide will be renamed with that prefix. +{: .block-tip } + +
    + + +
    + +
    + + +
    + + +# Agent Desktop Overview + +## Station Login + +- In order to access to the Agent Desktop you can do it either via the Management Portal (Desktop module) or navigating to the direct URL: https://desktop.wxcc-.cisco.com/ + +- Once you're in the login page, enter the agent credentials (username and password) + + + +- Based on the _Voice Channel Options_ set at the _Desktop Profile_ of the agent, the following telephony options can be: + - **Dial Number**: E.164 format phone number where agent will receive incoming and outdial calls. + - If your administrator configures the default Dial Number (DN), the default DN is prepopulated in the Dial Number and Extension fields. + - If your administrator restricts the DN to the default DN, you cannot edit the prepopulated DN when signing in to the Agent Desktop. + - If you check the __International Dialing Format__ box, you can choose the country code based on your geographical location from the drop-down list. You can also enter a country code or country name to filter the list. Dial numbers are validated based on the country code. + + - **Extension**: Internal extension where agent will receive incoming and outdial calls. This option it's just valid in case the agent is using Webex Calling or some other softphone as calling endpoint. + + - **Desktop**: This is the new **WebRTC** option, it allows to receive inbound and make outbound calls through the internet, without the need of any phone or softphone. You can watch a Vidcast with the overview of this feature below. + +
    + +
    + +- Select one of the possible teams from the list. Agents can belong to multiple teams, but they can only receive calls of 1 specific teams + +- Check the **Remember My Credentials** box to save your station credential details for future sign-ins + +- Be aware that agents cannot access the Agent Desktop from multiple browsers or multiple tabs of the same browser window. In that case, a warning message will be displayed + +> The video below shows a demo about the agent login process and the available options: +{: .block-tip } + +
    + +
    + + +## Agent Desktop Interface + +> The Desktop UI language is based on the language preference settings on your browser. Currently, it supports 29 languages: +> Bulgarian, Catalan, Chinese (China), Chinese (Taiwan), Croatian, Czech, Danish, Dutch, English (UK), English (US), Finnish, French, German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish, Portuguese (Brazil), Portuguese (Portugal), Romanian, Russian, Serbian, Slovak, Slovenian, Spanish, Swedish, and Turkish. +{: .block-tip } +
    +
    + +> Watch the following video, where each of the sections and their main options are explained. You will get a better idea of how the Agent Desktop look like and how to use it: +{: .block-tip } + +
    + +
    +
    +![Image1](/assets/images/AgentDesktopOverview.png) + + +The Agent Desktop is divided in **6 sections**. In the image above you can see a general view of the Agent Desktop and where each section is located. We explain them all shortly: + +1. **Task List**: When a request is routed to your queue and you are _Available_, a new request appears in your Task List pane. You must accept the requests to start communication with the customer. + +2. **Horizontal Header**: Basic functionalities such as: Title and logo, Agent availability state, Notification Center, Outdial and User Profile. We will explain more in detail some User Profile options in the next section of the lab. + +3. **Interaction Control**: When you accept a voice call (inbound or outbound), by default, the Interaction Control pane is expanded. This pane includes: customer information (CAD variables), timers (for example: connected and call on hold time) and call control buttons (Record, Hold, Transfer...). + +4. **Auxiliary Information**: The center pane displays details based on your selection of the contact card in the Task List panel. For Voice requests, it will display the customer contacts history. Whereas for any digital channels (email, chat or social messaging), you will see the whole conversation with the customer and you will be able to send new messages. + +5. **Agent Interaction History**: You can view your previous contacts of the agent across all the channels (voice, email, chat, and social) in this pane. The pane displays details for the last 24 hours. Moreover, for Voice channel you can callback to the contact phone number. + +6. **Navigation bar**: By default you can find the following icons here: Home, Agent Performance Statistics and Help. However, you can customize it and add some additional icons and widgets. + +## Calls Handling + +> In the following video you will see how to handle incoming calls and what are the different agent states: +{: .block-tip } + +
    + +
    +
    +#### Agent states: + +- **Available**: Indicates that you are ready to accept and respond to contact requests that are routed to you. After you sign in, you must select Available from the drop-down list to accept voice call, chat, email, and social messaging conversation requests. + +- **Idle**: Indicates that you are signed in but not ready to accept any routed requests. When you sign in to the desktop, your state is set to the default idle reason configured by your administrator. + +- **RONA (Redirection on No Answer)**: Indicates that you have not accepted a voice call, chat, email, or social messaging conversation request within the specified time. Your administrator configures the time available to accept an incoming request from any channel. If you cannot accept the request within the specified time displayed in the timer, the action button on the popover flashes for a few seconds and your state automatically changes to RONA. The request is returned to the queue. When your state changes to RONA, a popover appears and you can select the state that you want to be moved: to Idle or to Available + +- **Engaged**: indicates that you are busy and connected with a customer. When you have accepted the contact request, the Available state changes to the Engaged - Available label. When you're in this state, you can continue to receive active requests on other channels, depending on the channel capacity. If you don't want to receive more requests, you can select any Idle state, so you will be moved to Engaged - Idle label. + +#### Manage Voice Calls + +- **Call Associated Data (CAD) variables**: These variables allow the administrator to collect call data such as a case number or any action code of the customer. In Flow Designer, your administrator configures the variables, labels of the variables, and the order in which they must appear on the Interaction Control panel. While you are on a call, you can edit the CAD variables if your administrator configures the CAD variables as editable. + +- **Hold/Resume**: You can put the customer on hold so that you can consult with another agent or lookup additional information without having the customer listening to you. Click on Resume to take a call off hold. + +- **Pause/Resume Recording**: Your administrator can choose for each Queue either to record all the calls or not. In case the recording is enabled, the agent can Pause and Resume the recording. + +- **End**: After you have helped your customer with queries, it is a good practice to ask the customer to end the voice call. If necessary, you can also end the call. When the customer ends the call, agent will need to select some Wrap Up Reasons from the dialog box appears. + +- **Consult**: You can initiate a consult call with another agent while you are on an active call with a customer. + +- **Transfer**: If you cannot resolve a customer query and want to escalate the active voice call (inbound or outbound), you can transfer the call to another agent or supervisor. + +- Either for **Consult and Transfer** you have the following options: + + - __Agent__: You can either select an agent from the drop-down list, or use the search field to filter the list. The drop-down list displays the names of available agents. + + - __Queue__: You can select a Queue or Entry Point from the drop-down list, or use the search field to filter the list. The drop-down list displays the queues that are available to transfer the call. + + - __DN__: You can enter a name or number; select a name or number from the drop-down list; or use the search field to filter the list. The drop-down list shows the grouped list of contacts in your address book. Names are listed along with the numbers for the contacts in the address book. + +- **Conference**: To start a three-way conference call between you, the customer and another agent. For this option, you (primary agent) must have initiated a consult call. Click Transfer to transfer the call to the consulting agent. The consulted agent can exit the call by clicking Exit Conference, and the call continues between the primary agent and the customer. Only the primary agent can end the Conference. + +- Only when using __WebRTC__: + - **Mute/Unmute**: Agents can silence themself in case they don't want to be heard for a moment. Similar as the function in Webex Calling/Meetings. + + - **Keypad**: In case agent needs to insert some digit or number during a call. Similar as the function in Webex Calling/Meetings. + +# Basic Features + +| **Entity** | **Name** | +| -------------------- | ---------------------------------------------------------------------- | +| Agent 1 | wxcclabs+agent_AttendeeID@gmail.com | +| Supervisor 1 | wxcclabs+supvr_AttendeeID@gmail.com | +| Desktop Profile | AttendeeID_desktopProfile | +| Entry Point | AttendeeID_EP | +| Queue | AttendeeID_Q | +| Team 1 | AttendeeID_team1 | +| Team 2 | AttendeeID_team2 | +| Outdial ANI | AttendeeID_outdialANI | +| Outdial ANI Entry 1 | AttendeeID_outdialANIEntry1 | +| Address Book | AttendeeID_addressBook | +| Address Book Entry 1 | AttendeeID_addressBookEntry1 | +| Multimedia Profile | AttendeeID_MMP | + +> **NOTE:** Please create all the tenant entities following the naming convention mentioned specified in the table above. Your attendeeID is provided in the email in the **"Attendee ID"** line. +{: .block-warning } + +> Be aware that all entities that don't match with attendee IDs will be deleted +{: .block-warning } + + + +## Testing Incoming call + +> In this section, you will will interact as an agent and test an Incoming call. Review the video of the lab section above to understand the different call handling options. +{: .block-tip } + +> If you're using the **shared lab tenant**, we propose to complete the lab using **Desktop (WebRTC)** telephony option. +{: .block-warning } + +> If you're using your **Gold Tenant**, be aware that **WebRTC** option only works with **RTMS** media stack. Firefox browser is still not supported. +{: .block-warning } + + +- In order to test properly an incoming call, first we need to make sure that we have all the call handling options enabled + +- Login with your administrator user in the **Control Hub** and navigate to _Services > Contact Center > Settings > Desktop_ + - Make sure that **`End Call`** and **`End Consult`** are enabled + - You can also configure _Auto Wrapup and RONA timeouts_ + +
    +- Now open the **Management Portal** and navigate to _Provisioning > Desktop Profiles_ and edit _your Desktop Profile_: + - In the **Collaboration** tab: + - Set the **Buddy Teams** to **`All`** + - Enable **`Consult to Queue`** + + - In the **Voice Channel Options** tab: + - Set the options you want to enable: _Dial Number_, _Extension_ or _Desktop_ + +
    + +- Navigate to _Provisioning > Queue_ and edit your Queue + - Enable **`Permit Recording, Record All Calls and Pause/Resume`** + - Make sure that these settings are also enabled at tenant level + - You can also set the _Recording Pause Duration_. This is the maxiumum duration that an agent can pause the recording + +
    +- Now place it's time to test the incoming call + - Login the **Agent Desktop** with _yourAgent1 user_ + - Select **`Desktop`** as telephony option + - Under _User Profile > User Settings_, click on **Speaker and Microphone** to set them + - Click on **Test Your Network** option, under _Help_, to check your internet connectivity speed, latency and jitter + - Move to **`Available`** state + - Make a call to the DN mapped to your EP (You should have mapped your EP in Lab 2) + - We suggest to use the Webex App installed and enabled for your Supervisor user to place the incoming call. If you prefer, you could also do it from your phone number directly. + +
    +- Accept the call from the *Agent Desktop* + - Check the **CAD variables** and try to edit any Global Variable + - Change to **`Engage - Idle`**. This way you will not receive any other digital channel requests + +
    + +- Let's play with the call interaction buttons + - Click on **`Hold`** to pause the conversation with the end-customer and click on **`Resume`** to talk with him again + - Click on **`Pause Recording`**, say some personal infor and click again on **`Resume`** to continue the recording + - Click on **`Transfer`** and select the **`Welcome_EP`** + - End-customer be redirected to a common EP already created + - **End** the call (this can be done from customer or agent perspective) and select any **Wrap-up code** + +> For this part, you will need a third calling device for interacting as a Supervisor +{: .block-warning } +
    +- Now, using a different browser, login in the **Agent Desktop** with _your Supervisor_ user and move to **`Available`** status + - In a separate device (you mobile phone for example), login in Webex App with your _Supervisor_ user + - Place the call from the third calling endpoint (your personal phone for example) + - Try **`Consult, Conference and Transfer`** functions between End Customer, Agent and Supervisor. + +## Exploring User Profile + +> In this section, we will explore what are the available options and settings under the User Profile. +{: .block-tip } + +
    + +
    +
    +- First, we will see how to change from one team to another one + - In order to notice some difference when we make the Team change, we need to modify some setting from _your Team 2_ (created in Lab 1) . For that, we will assign a different **Multimedia Profile** to that team. + +
    +- Navigate to the _Management Portal > Provisioning > Teams_ + - Find _your Team 2_ and click on `Edit` + - Check _your User settings_ and make sure that there is not **Multimedia Profile** assigned. **User settings have preference over Team setting**, so the Multimedia Profile at User level will be applied. + - Change the **Multimedia Profile** of the team from `AttendeeID_MMP` to `Default_Telephony_Profile` + +
    +- Now, login in the **Agent Desktop** selecting AttendeeID_team1 + - Open _your User Profile_ and check that the **Channel Capacity** + - Now, click on _your Team_, you will see a dropdown list with other available Teams + - Click on AttendeeID_team2 + - **`Save Team Selection`** to confirm that you want to change a team + +
    +- You will see notification appeared in the **Notification Center** + - You can change the **Notification settings** to disable the incoming notifications or the sound + - Mark the notification as `Read` + - Go to the **User Profile** and check the **Channel Capacity** again, it's different + +
    +- Test some additional options: + - **Switch to Dark Mode** + - **Keyboard shortcuts** + - **Download error log** + +## Outdial + +> In this section, we will test Outdial calls using different Outdial ANIs and Address Books. +{: .block-tip } + +
    + +
    +
    +- Navigate to _Management Portal > Provisioning > Outdial ANI_ + - Click on **`New Outdial ANI`** + - Name: AttendeeID_outdialANI + - Add Outdial ANI entry + - Name: AttendeeID_outdialANIEntry1 + - Number: Select your mapped DN + +
    +- Navigate to _Management Portal > Provisioning > Address Book_ + - Click on **`New Address Book`** + - Name: AttendeeID_addressBook + - Parent Type: **`Site`** + - Add Address Book entries + - Name: AttendeeID_addressBookEntry1 + - International calls are disabled, **so only US numbers are supported**. For example: +18662293239 (Cisco Helpdesk) + +
    +- Navigate to _Management Portal > Provisioning > Desktop Profiles_ + - Search for _your Desktop Profile_ and make sure that **Outdial is enabled and `Outdial Entry Point-1` (created by the system) selected** + - Select _your Outdial ANI_ + +
    +- Navigate to _Management Portal > Tenant > Settings_ + - See the number of the **Default Outdial ANI** + +> **This is a required setting at tenant level, so PLEASE DON'T EDIT IT** +{: .block-danger } + +
    +- Now, login in the **Agent Desktop** with _your Agent1_ with the Webex Extension of the Agent + - Open the Outdial on the Horizontal Header + - Input your personal phone number + - **Don't select any Outdial ANI** + - Click on the telephone button to place the call + - The call will be delivered to your phone number from the **Default Outdial ANI** defined at Tenant level + - Now repeat the same but **choosing _your Outdial ANI_** configured before. You will see that the call is coming with a different ANI + +
    + +- Finally, let's see how **Adress Book** works + - Open the Outdial window and swith to the Address Book tab + - You will see the the list of entries of AttendeeID_addressBook configured before + - You can search by entry name or DN + - Try to call any of the numbers in the list + + + +# Custom Desktop Layout + +## Basic JSON elements + +The following are the top-level and most important properties to know for JSON layout: + +- **`appTitle`**: To specify a title on the horizontal header of the Desktop. The default title is `Webex Contact Center`. + +- **`logo`**: To specify a URL for the company logo. If you do not provide a URL, then the Webex Contact Center logo appears by default. + +- **`taskPageIllustration`**: To specify a custom illustration for the task page based on organization preferences and brand alignment. When an agent signs in, the task page displays the configured illustration as a background. By default, the task page appears without illustration. + +- **`stopNavigateOnAcceptTask`**: To determine whether to shift the focus to a newly accepted task, when the agent accepts the new task while working on a previous task. The default value is `false`. + +- **`dragDropEnabled`**: To enable the drag-and-drop and resizing of the widgets on the custom pages, set the value to `true`. The default value is `false`. + +- **`notificationTimer`**: To set the duration (in seconds) after which the desktop notifications on the Desktop are automatically dismissed. The notification appears at the top-right corner of the Desktop. The default timeout value is 8 seconds. The valid range for timeout values is 1-10 seconds. For the timeout changes to take effect, the browser must be refreshed after the changes are made. + +- **`maximumNotificationCount`**: To set the number of desktop notifications to be displayed at a time on the Desktop. The default value is 3. The range for desktop notifications is 1-10. The desktop notifications are stacked. If there are many notifications, they appear with a slight delay depending on the `notificationTimer` settings. + +- **`browserNotificationTimer`**: To set the duration (in seconds) after which the browser toaster notifications on the Desktop are automatically dismissed. Toaster is a native browser notification that appears only if the Desktop is not the active browser window or tab. The Desktop browser window or tab is inactive when + +- **`wxmConfigured`**: (Optional) To configure Webex Experience Management, set the value to `true`. The default value is `false`. + +- **`desktopChatApp`**: To configure multiple Cisco-offered chat applications such as Webex App. + +- **`webexConfigured`**: Webex App along with its messaging, calling, and meeting functionalities, can be configured within the Desktop. This configuration allows agents to collaborate with other agents, supervisors, and subject matter experts (SMEs) in their organization without navigating away from the Desktop. + +- **`headerActions`**: To change the order of the icons on the horizontal header of the Desktop. The default order is as follows:  **`["webex", "outdial", "notification"]`**. + +- **`area`**: The `area` property is the core section of the Desktop Layout. You can define the layout as per the area. + +
    + +## Personalize the title and logo + +> In this video, you will learn the desktop layout customization process. After watching this, you will be able to customize the Agent Desktop with a custom logo, custom title. You will also learn how to enable/disbale standard widgets: +{: .block-tip } + + +
    + +
    + +
    + + +- Login to **[https://portal.wxcc-us1.cisco.com](https://portal.wxcc-us1.cisco.com){:target="\_blank"}** with admin credentials. + +- Navigate to **_Provisioning_** –> **_Desktop Layout_**. + +- Click on **_New Layout_** button. + +- Click on **_Download_** button to download the **Default Desktop Layout.json** file. + +- Open the **Default Desktop Layout.json** file with any text editor (e.g. Notepad, Sublime text). + +- Modify the **_appTitle_** key value with your company name in order to change Agent Desktop title. + +- Modify the **_logo_** key value with your company logo URL or use this **https://raw.githubusercontent.com/wxcctechsummit/holcct2100/main/labslive/CiscoLiveLogo.jpg**. + +- Modify the wxmConfigured and webexConfigured key values to **_true_** to enable the standard (out of box) widgets. + +- **_Save As_** JSON file with a distinguishable name. +
    + + +- Login as admin to **_Desktop Layout_** module in the **[Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com){:target="\_blank"}**. + +- Click on **_New Layout_**. + +- Provide the following **name**: AttendeeID_desktopLayout + +- Select AttendeeID_team2 as Team. + +- Click **_Upload_** button to upload the modified JSON file. + +- Click **_Save_** button to apply the layout. +
    + + +- Login to the **[Agent Desktop](https://desktop.wxcc-us1.cisco.com/){:target="\_blank"}**. + +- Open the **_User Profile_** and click on the arrow `>` under **_Team_**. + +- Change the team of the agent to AttendeeID_team2 + +- Click on **_Save Team Selection_**. + +- Confirm the changes by clicking on **_Change Team_**. + +- Wait for few seconds to see the results. + +- Now you should be able to see the new logo, new title and will be able to access the out of box widgets i.e Webex & Custom Experience Analytics. +
    +## Reorder components of Horizontal Header + +> In this section, you will learn how to reorder components of Horizontal Header. +{: .block-tip } + + +
    + +
    + +- Take the same desktop layout file that you used in the last section. + +- Open the desktop layout file with any text editor (e.g. Notepad, Sublime text). + +- Make sure the layout version is 0.0.7 or higher. + +- Under **_advancedHeader_**, change the order of components. + +- **_Save As_** JSON file and upload it on **[Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com){:target="\_blank"}** against your team. + +- Now login to the **[Agent Desktop](https://desktop.wxcc-us1.cisco.com/){:target="\_blank"}** or refresh the browser if you are already logged in. + +- You should be able to see the order of components in the Horizontal header as per your configuration. +
    + +## Create iFrame Widget & change default landing page + +> The iFrame widget is a special widget that can be used to embed a different application. The iFrame widget creates an HTML iFrame and renders your application. +{: .block-warning} + + +> In this section, you will learn how to create a iFrame widget and how to change the default landing page in the Agent Desktop. For this example, we are using Webex Contact Center Analyzer Report as a iFrame widget. +{: .block-tip } + + + +
    + +
    + +- Take the default desktop layout file. + +- Open the desktop layout file with any text editor (e.g. Notepad, Sublime text). + +- Create another section under **_navigation_** similar to that of existing Customer Experience Analytics. + > Check out this sample [Analyzer_iFrame_Widget.json](https://github.com/CiscoDevNet/webex-contact-center-api-samples/blob/main/widget-samples/iframe-widget-sample/Analyzer_iFrame_Widget_Layout.json) + +- In the new section, add the **_label_** key value with your choice. + +- Add the **_icon_** key value with your choice. + +- Add a new key **_isDefaultLandingPage_** and its value should be set as **_true_**. + +- **_src_** key value should be same as URL of your analyzer report. + +- **_Save As_** JSON file and upload it on **[Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com){:target="\_blank"}** against your team. + +- Now login to the **[Agent Desktop](https://desktop.wxcc-us1.cisco.com/){:target="\_blank"}** or refresh the browser if you are already logged in. + +- You should be able to see the new widget you added when you login to the agent desktop as it is set as the default landing page. + +
    + + +## Populate Custom Widget with desktop parameters + +> A Custom Widget is a component with some specific encapsulated functionality, exported as a custom HTML element that is placed within the desktop. +{: .block-warning} + + +> Watch the demo below to understand the ability to pass default Desktop parameters into your Custom widget. This will help developers understand how data is handled in the Desktop STORE and injected into widgets inside of Webex Contact Center desktop. +{: .block-tip } + +
    + +
    + +
    + +
    + +
    +Below, you will find a breakdown of all possible data and type definitions that is available through the STORE key: +- **STORE.agent**: Desktop profile info and settings. +- **STORE.agentContact**: Agent tasks and interactions +- **STORE.app**: Company logo, title and dark mode +- **STORE.auth**: Authentication token used for Single Sign On +- **STORE.generalNotifications**: Application notifications +- **STORE.dynamic**: Connector (smaller) or Desktop (larger) view area + +
    +> +> Check the **[Developer guide](https://developer.webex-cx.com/documentation/guides/desktop/#custom-widgets)** for more details about Custom Widgets. +{: .block-warning} + +> If you want to explore and play around with the possible types of custom widgets you can create, check the below **Git repository with some samples: +> [https://github.com/CiscoDevNet/webex-contact-center-widget-starter/tree/master/Examples](https://github.com/CiscoDevNet/webex-contact-center-widget-starter/tree/master/Examples)** +{: .block-warning} + +
    +## JavaScript SDK and Modules +> Desktop JavaScript SDK is an npm package that allows you to request up-to-date information from the Desktop. Using the SDK, you can request information such as agent details, assigned tasks, details of specific tasks, current browser locale, and the authentication token for Single Sign-On (SSO) integration. +{: .block-warning} + +- To start using the JavaScript SDK, run the following command in your project folder: `npm install @wxcc-desktop/sdk --save` or `yarn add @wxcc-desktop/sdk`. + +- Once you have installed the package in your project, include it in the appropriate component file following the ES6 import pattern: `import {Desktop} from "@wxcc-desktop/sdk";`. + +- `Desktop` is the root module of the JavaScript SDK. The root module provides a reference to the following sub-modules: + - Configuration Module + - Localization Module + - Actions Module + - Logger Module + - Agent State Information Module + - Agent Contact Module + - Dialer Module + - Screen Pop Module + - Shortcut Key Module + - Call Monitoring Module + +- Check the [Developer Guide](https://developer.webex-cx.com/documentation/guides/desktop#javascript-sdk-and-modules) for more details about each module. + + +
    +
    +--- + + + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    diff --git a/_pages/Analyzer.md b/_pages/Analyzer.md new file mode 100644 index 0000000000..2504067046 --- /dev/null +++ b/_pages/Analyzer.md @@ -0,0 +1,1035 @@ +--- +title: Lab 5 - Analyzer Deep Dive +author: Krishna Tyagi & Mike Turnbow & George Kovanis +date: 2022-05-05 +layout: post +--- + +``` +Last modified: Mon, 20 Feb 2023 +``` + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| --------------------------------------------------------------------------------------------------------------- | ----------------- | --------------- | ---------------- | +| [Admin Portal Dashboard and Analyzer User Interfaces](#admin-portal-dashboard-and-analyzer-user-interfaces) | Practical Lab | EASY | 25 min | +| [Getting Data Insight using Stock Visualizations](#getting-data-insight-using-stock-visualizations) | Practical Lab | EASY | 35 min | +| [Understanding Data and Creating Custom Visualizations](#understanding-data-and-creating-custom-visualizations) | Practical Lab | MEDIUM | 60 min | +| [Dashboards](#dashboards) | Practical Lab | EASY | 20 min | +| [New Data Insights](#new-data-insights) | Practical Lab | HARD | 65 min | +| [Agent Data Insights](#agent-data-insights) | Practical Lab | EASY | 25 min | +| [Supplementary Data Capabilities](#supplementary-data-capabilities) | Practical Lab | EASY | 25 min | +| [Using Data APIs](#using-data-apis) | Read & Understand | MEDIUM | 10 min | + +## Overview of the Lab + +This hands-on Lab will provide you fundamental and advanced knowledge of Webex Contact Center Data and Analytics, you will learn about data points and metrics across various existing and new capabilities, you will learn how to use stock reports and dashboards. + +This session will guide you step-by-step on how to design and build analytic Visualizations and Dashboards to capture your business & operational KPIs and Actionable Insights. + +You will also learn about new capabilities developed around the new cloud Data platform. Across the sessions, you will get useful tips and tricks to reap the full benefits of the solution and how easily you can mine your data for key insights. + +## Introduction + +### Define your Attendee ID + +Enter your attendee ID below and click on `SAVE`. This will update any relevant names in this lab with your specific attendee ID as prefix, so that your configuration is unique amongst the other attendees. + +
    +
    + + + +
    + + +> **NOTE:** the **Attendee ID** should be provided with the admin credentionals. You can share your tenant and dial number with your colleagues so they can do the configuration in parallel. In that case, the **Attendee ID** is the same for all of you, but you can add a sub prefix with the number. \_Ex: attendeeID**1**\_MMP, attendeeID**2**\_MMP, etc. +> {: .block-tip } + +### Pre-requisites + +- To complete all the exercises of this lab, you need to have a `Supervisor` user, an `Agent` user as well as an `Administrator` user created. + The administrator user should be already provided to you, while the supervisor and agent users should already be created in Lab 1. + + - If you have not create these users yet, please follow the steps from [Lab 1 - Admin Experience](https://webexcc.github.io/pages/CH/#control-hub-user-management-task) to create both of them. + +- For `Lab 5` exercises, we will need to generate some data that include global variables, callback requests as well as preferred agent routing. To do so, a flow template named `AnalyzerLab_Flow` has been created (If you do not have the flow, you can download it from [here](https://webexcc.github.io/assets/files/AnalyzerLab_Flow.json) ). To create your own flow based on that and generate data, please do the following steps: + + - Go to `Admin Portal -> Routing Strategy -> Flows`. + + - Click on the dots ![Dots](/assets/images/Analyzer/dots.png)icon next to the `AnalyzerLab_Flow` and click on `Copy`. + + - Open the newly copied flow. + + - Make the following changes: + + - Rename the flow as attendee-id\_AnalyzerLab_Flow. + + - In the `Queue Contact` node, update the Queue with your own. + + - Find the `SetAgentEmail` node, update it with the email address of the supervisor user you have created. + + - Save the flow. + + - Map this flow with your Entry Point and make a few test calls. + - Make sure to make at least one normal call (Agent available & Answers), one callback call (Agent idle, press 1 to prompt for callback and then make agent available to receive the callback) and one preferred agent routing (agent idle, press 2, then make agent available). + +- `Lab 5 - Data Reporting for Digital Channels`, we will need digital channel (Chat, Email or Social) data to be generated first. However, as Digital Channels is on a later lab ([Lab 12](https://webexcc.github.io/pages/Digital/)), you can skip this specific exercise until some digital data is generated on your tenant to report on. + +- For `Lab 6 - Embedding the report in the Agent Desktop`, you will need to update the Desktop Layout of your supervisor user, so a unique User Profile needs to be created and linked to your Supervisor user. To achieve this, complete the following steps. + + 1. In [Admin Portal](https://portal.wxcc-us1.cisco.com/), go to `Provisioning -> User Profiles`. + + 2. Fine the profile named `Supervisor_Analyzer`. Click on the dots ![Dots](/assets/images/Analyzer/dots.png) on the left of the line and then click on `Copy` ![Copy](/assets/images/Analyzer/Copy.png). + + 3. Change the `Name` of the User Profile to attendee-idSupervisor_Analyzer (based on your attendee ID) and `Save`. + + 4. Navigate to `Provisioning -> Users`. Search for your **supervisor** user, click on the dots ![Dots](/assets/images/Analyzer/dots.png) on the left of the line and then click on `Edit`. + + 5. Change the `User Profile` of that user to the one you just created and then click on `Save`. + +### Quick Links + +> Admin Portal: **[https://portal.wxcc-us1.cisco.com/](https://portal.wxcc-us1.cisco.com/){:target="\_blank"}**\ +> Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com){:target="\_blank"}**\ +> Analyzer: **[https://analyzer-v2.wxcc-eu1.cisco.com/analyzer/home](https://analyzer-v2.wxcc-eu1.cisco.com/analyzer/home){:target="\_blank"}** + +# Admin Portal Dashboard and Analyzer User Interfaces + +This lab is designed to give you basic understanding of Analyzer, `user interface` features, `access controls` and permissions as well as the `default dashboards` available in the Admin Portal. In the following exercises, the goal is the familiarization with the product, interfaces and terminology. + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| ----------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Portal Dashboards](#1-portal-dashboards) | Practical Lab | EASY | 10 min | +| [Analyzer User Interface](#2-analyzer-user-interface) | Practical Lab | EASY | 5 min | +| [Access Control](#3-access-control) | Practical Lab | EASY | 10 min | + +## 1. Portal Dashboards + +1. Login to the `Webex CC Administration Portal` using the Portal link. Login using your created supervisor user from [Lab 1](https://webexcc.github.io/pages/CH/#control-hub-user-management-task). + +2. Navigate through the various dashboards via the dropdown to see current tenant information and to familiarize yourself with the four different dashboard views. + +3. Search through all the dashboards to find following information: + + - Contacts in Queue + - Total Contacts Handled + - Longest Contact Currently in Queue (Realtime) + - Agent State Data (Listing all logged-in agents with their current state) + - **Team Details Real-Time** from `Contact Centre Overview - Realtime` Dashboard
    + +4. Return to the `Entry Point - Site Level Dashboard` and complete some navigation exercises: + - In `Site Interval Realtime - Chart` report, filter calls for **Inbound Connected Count** (by clicking on profile variable next to the gear icon) + - Click on ![Expand](/assets/images/Analyzer/Expand.png) to open `Entry Point Contact Volume – Chart` report in a separate window. + - Try the **Duration** filter on top right. + - Open `Incoming, Short Contacts - Entry Point` report in separate browser tab and **export** the Data as **_Excel_**. + +## 2. Analyzer User Interface + +1. **Login** to the `Webex CC Analyzer` using the Analyzer link above or cross-launch from the Administration portal by clicking on `Reporting and Analytics`. + +2. Navigate around the home screen learning the different features available on this screen. + +3. Click on the `Visualizations` tab on the left. + +4. On the top in `Search` field, search for keyword **"agent"**: + + - Click on `Agent Realtime` report and note down the path for this report. + - Searched items can be further filtered to show Visualizations or Folders from the “Show” dropdown menu.
    + +5. Then, navigate to the path `Stock Reports > Real-Time Reports > Agent Reports > Interval Reports`. + + - Click ![Grid](/assets/images/Analyzer/grid.png) to change the view to List view. + - Here you can sort the reports based on a specific header by clicking on it. + - Notice the `Temporal Scope`, which can be either Realtime or Historical. + - ID is unique for every report and a report can also be searched by its ID. + +6. Click the ![Dots](/assets/images/Analyzer/dots.png) icon next to the report and then click on Details. + + - Make a note of the `Date Range` and `Scheduled Jobs`. + - Try the same for any Historical stock report.
    + +7. On the top, click on your **username** and then `Help` to open the help manual for Analyzer. + + - This provides you with an online version of the [Analyzer User Guide](https://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cust_contact/contact_center/webexcc/Analyzer_2/b_analyzeronloinehelp/_b_analyzeronloinehelp_chapter_01.html), a great document that provides information about all the available stock reports, variables as well as functionalities of Analyzer. + +8. Click on `Threshold Alerts` next to the username. Check if there are any active alerts. + +9. Click on `Tenant Time zone` option on the header. Set it to the time-zone in which you want to Run Visualizations (Tenant or Browser). + +## 3. Access Control + +The goal of this exercise is to review the access controls and permissions you can apply for Analyzer reporting. + +1. Ensure you are logged into the Admin portal with your supervisor user. + +2. Open Analyzer in a new tab to enable you to switch between tasks in Portal and Analyzer. + +3. You would notice two folders: `Admin` and `Stock` Reports. + +4. Create a folder for yourself under Visualisations with the name Team\_attendee-id, based on your attendee ID. + +5. In Admin Portal, navigate on the left to `Provisioning -> Users`. Use the Search bar to find your user. You can search for your student number to make it easy. Check which `User Profile` is being used by your user. + +6. Edit your User profile by navigating to `User Profiles` and selecting the ellipsis menu next to that profile, then click `Edit`. Then, in your User Profile, navigate to `Access Rights`. + + - Set all folders except yours to “None”. + + **_Note: Stock Folder cannot be modified and is visible to all._** + +7. `Save` the User profile. + +8. **Logout** from the Administrator portal, **close** the Browser and login back with your supervisor user. + +9. Go Back to the `Analyzer -> Visualizations` and check if the applied folder restrictions are visible. You should be able to see only the Stock Reports and your own folder. + +You can always consult the [Analyzer User Guide Access Control](https://www.cisco.com/c/en/us/td/docs/voice_ip_comm/cust_contact/contact_center/webexcc/Analyzer_2/b_analyzeronloinehelp/_b_analyzeronloinehelp_chapter_01.html#topic_38C3FADD09C46F7A0073A1F4452D23F2) chapter on complete information on permissions and access control for each type of user. + +# Getting Data Insight using Stock Visualizations + +This lab is designed to give you a basic understanding of `stock visualizations`, how to execute them and how to use them to create custom visualizations as per your business requirements. + +Reports created in this lab will be used in later labs to create a custom dashboard. + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| ------------------------------------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Execute Stock Reports](#1-execute-stock-reports) | Practical Lab | EASY | 15 min | +| [Execute CCX Transition Reports](#2-execute-ccx-transition-reports) | Practical Lab | EASY | 5 min | +| [Create Custom Visualization using Stock Visualizations](#3-create-custom-visualization-using-stock-visualizations) | Practical Lab | EASY | 15 min | + +## 1. Execute Stock Reports + +1. Go to `Visualizations`. Navigate to `Stock Reports` folder. + +2. Review the below Stock report structure. + +![StockStructure](/assets/images/Analyzer/StockStructure.png) + +3. Search for and execute the `Agent Details` report. + +4. Update the `Filters` to show data for **Today** and at **Hourly** interval. + +5. Click on the hamburger menu to check the `Data summary` and `Details`. Review the following information: + + - Records found + - Time to compute + - Number of Rows and Columns + - Report Duration and Interval +
    + +6. Click on the `Settings` button. The Row segments and report variables are now visible. + +7. Drag all `Row segments` fields except **_Agent name_** and **_Interval_** to the `Hidden Segments` section. + +8. Also, by Clicking the Eye ![eye](/assets/images/Analyzer/eye.png) symbol, hide the `Initial Log In Time` and `Final Log Out Time` fields. + +9. Now, click again the `Settings` to hide Row and Profile variables. + +10. Go to the **Table Summary** on the bottom and review the summary results of each column. + +11. Review the Analyzer URL for the report which shows the `tid` which is the **Tenant ID** and `rid` which is the **report ID**. The tenant ID is unique to every tenant. The report ID allows you to also search in the search box for visualization using the ID for that visualization. + For example, searching –100 will bring up the Agent Details Report. + +12. Search through the stock reports and find below information: + - Historical Agent Details with Staff hours information + - Agent Idle state information + - Realtime Queue Statistics + - Agent Usage Report + - Average service level in Card format + +**_Tips:_** + +1. **_Look in the Stock folder structure to find the type of reports that possibly contain the requested information._** +2. **_Use search functionality with keywords used in the requested data._** + +## 2. Execute CCX Transition Reports + +For customers migrating from CCX over to Contact Center, Cisco has provided nine historical stock reports that have the same look and feel as CCX reports. This provides those customers with the most common CCX reports in Webex CC as prebuilt reports. + +1. From the Analyzer portal, go to `Stock Reports -> Transition Reports`. + +2. All 9 of these reports can be run, copied to be edited or scheduled just like any other historical report. + +3. Execute the `CSQ All Fields Report`. Take note that `CSQ All Fields` is a common CCX report. This stock report mirrors the same column headers contained in the CCX report. Rather than name this report simply a Queue Report, we have used the CCX terminology for queues as well as to map the same fields into the report and make the transition smoother. + +## 3. Create Custom Visualization using Stock Visualizations + +In this exercise we will copy a stock report to create a new custom report. The new report will show the Team Performance from yesterday. As a supervisor, you will be able to use the report to view: + +- Team Name +- Agent name +- Login and logout time +- Total contacts handled + +**Objective** is to create a report to see the following Queue level data insights: + +- % Service Level +- % Abandoned Calls +- Number of Total Calls +- ASA (Average Speed of Answer) +- Telephony only Contacts + +**_Tips:How to search for the right report to match your requirements?_** There are three ways : + +1. Go into the `Stock Report Directory` structure (Step 2 in exercise [2.1](https://webexcc.github.io/pages/Analyzer/#1-execute-stock-reports)) and look for something similar, e.g. we are looking for a `Historical -> Multimedia Report`. +2. Search for keywords matching your desired report data, e.g. search for `Service level`. +3. Search in the `Analyzer User Guide` for the data point and identify the report. + +`Queue Service Level` report comes as a result in all three ways and seems to be covering what we are looking for, so execute that report and validate the data. + +Based on the data inside that report, we need to do the following steps: + +1. Identify what needs to be changed to meet the requirements. + + - `Duration` needs to be updated to **Yesterday**. + - Few field name headers need to be renamed. + - `Channel Type` need to be set to **Telephony**. + - `Not-required` fields to be **removed**. + - `% Abandoned` is missing in this report (needs to be added). + +2. Create a copy of this report by clicking on the `dots` icon and `Create a Copy`. + +3. Complete below changes: + + - Update the `Start Time` to **Today** and `Interval` as **None**. + - Right click on the `Channel type` and add a filter for **Telephony**. + Filters are a very powerful tool that allows us to only extract the data that meet specific criteria. They can be applied on a variable on a report level. In this case, we make sure to only account for the calls that have their Channel Type marked as "telephony". + - Since we created a filter to only show telephony Channel, we can `remove Channel Type` from the Row segment as it is redundant. Filter has been applied on report level from the previous step. + - Right click on the field `In Service Level%`. Click `Edit` and update the name as `%ServiceLevel`. + - Hide unnecessary fields by clicking on `Eye` symbol on the `Profile Variables`. + - Notice that `% Abandoned field` is there in the report, but it’s hidden. `Unhide` it. + +4. You can already see a preview of the report in `Edit` mode. Scroll through it to see if it meets what we are looking for. + +5. If yes, click `Save As`. Name report as `2.3_Queue Service Level`. Select your folder and click `OK`. + +6. Click `Preview`. + +7. Notice that some Fields are taking too much width like the `Avg Speed Of Answer` column. + +8. `Double click` the column lines. This will adjust the width of each column to the size of the values. Any change on the column width is stored and remains on the report even after refresh. You can also adjust the width manually by clicking on the column line and dragging left or right to resize it. + +# Understanding Data and Creating Custom Visualizations + +![DataRepos](/assets/images/Analyzer/DataRepos.png) + +There are 4 key `repositories` that we will learn about in this chapter: + +**Customer** + +- Customer Session Record (CSR) +- Customer Activity Record (CAR) + +**Agent** + +- Agent Session Record (ASR) +- Agent Activity Record (AAR) + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| --------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Understanding the Data](#1-understanding-the-data) | Practical Lab | MEDIUM | 20 min | +| [Create Realtime Agent Visualization](#2-create-realtime-agent-visualization) | Practical Lab | MEDIUM | 20 min | +| [Create Chart Visualization with Interval](#3-create-chart-visualization-with-interval) | Practical Lab | MEDIUM | 20 min | + +## 1. Understanding the Data + +In this exercise, you will spend some time understanding the Webex Contact Center data and schema in which data is stored. + +1. Navigate to Analyzer and click on `Create New` and select `Visualization` to create a new report that will be saved in your attendee folder. + +2. Select the Type as `Customer Session Record`. + +3. Select `Start Time` as **Today**. + +4. Click on `Profile variables`. + +5. Add the following profile variable of type **Fields**: + + - Search for **_session_** and select `Contact Session ID` under fields and drag&drop it into Profile Variables. + - Select the `Value of Contact Session ID` under Formula. + +6. Similarly, add the values of below fields: + + - DNIS + - Entry point + - IVR Script Name + - Final Queue Name + - Team + - Agent + +7. Save the report as `3.1_CSR_Today_ValueReport` in your attendee folder after you have added all of them. + +8. `Preview` the Report. + +9. Next click on any session ID, then click on `Zoom` icon ![Zoom](/assets/images/Analyzer/zoom.png). + +10. Make a note of all the Call Activities during this session (Call Activity Records). + +11. On the Drill Down on the left, search for `Team Name` and click on it. + +12. Team name will be added to Drill-down view. + +13. Launch it in a separate tab. + +14. Move `Contact Start Timestamp` and `Contact End Timestamp` next to `nextState_s` by dragging them. + +15. Click `Export as Excel` and save a copy of Call Activity records. + +16. Now, apply everything you learnt and create a similar report for `Agent Session Record` with below value fields and `Start Time` as **Today**. + + - Agent Session ID + - Agent Name + - Agent Endpoint (DN) + - Team Name + - Current State + - Channel type + +17. Save it as `3.1_ASR_Today_ValueReport` in your folder and Click `Preview`. + +18. Click on `hamburger` menu next to Value of Current State. + +19. Uncheck all the states except `Idle`. + +## 2. Create Realtime Agent Visualization + +In this exercise, we will create a custom visualization to showcase the state of agents on a Realtime basis. While completing this Exercise, you will be able to understand and use some key capabilities like: + +- Fields and Measures +- Enhanced Fields +- Formulas +- Drill-down +- Group Summary +- On the Fly-filter +- Filtering + +**Objective**: Create an Agent Real-time state report with following data insights: + +- State of Agents on real-time basis for Telephony channel +- Capture key metrics + - Agent Team + - Agent Name + - Agent State + - Idle Code + - Total number of agents logged-in + - Number of Agents in Available and idle state for each team + - Duration in the State +- Create a high-level view, based on Line of business (Group or Teams) +- Have Data summarize based on each Line of Business (LOB) +- Have options to filter the data based on LOB and Idle code +- Create some visual indication when certain agents are in Idle state for long duration + +To create a report with all the above requirements, we need to complete the following steps: + +1. Create a new visualization in Analyzer as an `Agent Activity Record`. + +2. Set `Start Time` as **Realtime**. + +3. Set `Duration` as **None (Snapshot)**. + +4. Set `Refresh` duration as **3 Seconds**. + +5. Next, we will begin adding variables to the visualization. Click on `Row Segment` and add: + + - Team Name + - Agent Name + - Activity State + - Idle Code Name + +6. Next, click on `Profile Variables`, search for `Agent Session ID` and add the Count of it under formulas. Rename the name as **_#Total_**. + +7. To capture Available Agent Count, add `Agent Session ID` again. Name it as **_#Available_**. + + - Drag `Activity State` as Filter with value **"available"** and save it. + +8. Repeat step 7 to add Idle Agent count, this time with filter value **"idle”**. Name it as **_#Idle_**. + +9. Next, we need to capture the `State Duration`. We will achieve this by using a **_formula_** to subtract the activity start time from current time, which will give us the activity duration. + + - Search for Profile variable Measure `Activity Start Timestamp`. + - Under formula, select `Minimum Activity Start Timestamp` and save it. + - **Right click** on the field and click `New Formula`. + - Name it `Duration`, swap the fields by clicking ![Swap](/assets/images/Analyzer/swap.png). + - Click on the empty field and select `Current Timestamp`. + - Select `Subtraction` operator ![Substract](/assets/images/Analyzer/substract.png). + - Right click the `Duration` profile variable, and set the `Duration Number Format` as **Duration > MM:SS**. + - `Hide` Minimum Activity Start Timestamp. + +10. Re-order the variables by dragging and dropping the variables in the order that you wish to see them in the report. + +11. Save the report as `3.2_AAR_RT_AgentState` in your folder and click `Preview`. + +12. Notice that the **#Total** count for each agent is “7”. + + - This is because each agent is a multi-channel agent (with total 7 channels, 1 voice, and 6 Digital ones). + - In this case, we want to capture data for `Telephony channel` only so let’s add a Channel Filter for Telephony. + - Go back to the report edit mode and add `Filter` with Channel Type as Telephony. + +13. Save the visualization and click on `Preview` to run it again. + +14. We are still missing below asks: + + - Create a high-level view, based on Line of Business (Groups or Teams) + - Have data summarized based on each Line of Business (LOB) + - Have options to filter the data based on LOB and idle code + - Create some visual indication when certain agents in idle state for long duration. + +15. Update the `Output Type` to **Heatmap**. + +16. To create a LOB group: + + - Right click on the Team name and then `Create Enhanced Field`. + + - Name the Field LOB_Groupingattendee-id, based on your attendee IT. + + - Add 2 groups containing the following teams: + Group1 : Select your Team only + Group2 : Select any other team available. + + - `Save` it. + + - Make this `Enhanced Field` global so it can be used for any other visualizations with need of creating it again. + + - Right click LOB_Groupingattendee-id -> Click Save -> When prompted, click Save again. + + - Field is now saved and can be used in any other report. + + - Optionally, you can verify this by deleting the LOB_Groupingattendee-id. + + - Next, click on `Row Segments`, search for the enhanced field you created under `Enhanced Fields` and drag&drop LOB_Groupingattendee-id + + - Move LOB_Groupingattendee-id as top Row Segment. + +17. To Create a **_Summary_** at LOB level: + + - Click `Show Summary` option and select LOB_Groupingattendee-id + + - Click `Customize`. + + - Go to LOB_Grouping level + + - Select `SUM` for #Total, #Idle, #Avaliable and `Save` it. + +18. Lastly, add the on-the fly filters for the LOB Grouping and Idle Code Name. + + - Click on `Show Filter On Run Mode` on the settings on the left. + - Select `LOB_Grouping` and `Idle Code Name`. + +19. Save visualizations and check the `Preview`. + +## 3. Create Chart Visualization with Interval + +In this exercise, we will create a visualization in chart view of historical data for total calls and abandoned calls. + +1. Create a new `Visualization`. + +2. Set it as a `Customer Session Record`. + +3. Next, set this visualization as a **Monthly** report, select **This Month** as the `Start Time`. Then under `Compute`, we will select `Interval` as **Daily**. + +4. Click on `Profile Variables`. Find `Contact Session ID` and drag and drop that into the report. When prompted, we will select `Count of Session IDs` as formula and rename the field as **Total Calls**. + +5. Next, we will add `Abandoned Calls` to the report. + + - Drag and drop the `Contact Session ID` over to the report again. + - Select `Count of Contact Session ID` under formula and name it **AbandonedCalls**. + - In order to get abandoned calls, we will need to create a `Filter`. + - In this same window, search for `Termination Type` from the drop down menu. Select it and drag and drop as a Filter. + - From the filter select only `Abandoned`. Click `Save`. + +6. Lastly, we want this visualization to render as a `Chart`, so we will change the `Output type` from Table to `Line Chart`. + +7. Click `Hide table` and `Save` the report. + +8. Save this chart as `3.3_CSR_ContactVolume` in your folder and Run the report. + +9. Execute the visualization, you can hover over points of the line chart to see values of total calls and abandoned calls. + +10. Alternatively, we can re-save the report in a Bar chart format. To do this, go back to Edit mode and change the output type to `Bar chart`. Save and refresh the report. + +# Dashboards + +This lab is designed to introduce you to the `dashboards` available in Analyzer. Dashboards are available for Historical, Realtime and Business Metrics. You will learn about and run some useful stock dashboards as well as create a custom one. + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| ----------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Stock Dashboards](#1-stock-dashboards) | Practical Lab | EASY | 10 min | +| [Creating Custom Dashboards](#2-creating-custom-dashboards) | Practical Lab | EASY | 10 min | + +## 1. Stock Dashboards + +1. Start at the `Analyzer` home page. + +2. Navigate to the `Dashboard` folder from the menu icon on the left-hand side. Once there, you will notice that all the same folders created under Visualizations exist in Dashboards as well. + +3. Click on the `Stock Reports` folder. You will notice dashboards are categorized under the following types: Historical, Realtime and Business Metrics. + +4. Under `Business Metrics`, run the `Abandoned Contacts` dashboard by double clicking the dashboard. + +5. This dashboard contains several different types of data reports. Take some time to familiarize yourself with them. + +6. Expand the `Customer Journey` dashboard by clicking on the blue launch button and observe contact distribution across IVR, Queue and Agent. + +7. Navigate back to the main dashboard directory and open a dashboard named `Contact Volume Historical Dashboard` under the **Stock reports > Historical > Multimedia** directory. + +8. `Create a copy` of this dashboard and edit to make some changes. + + - Click the `ellipses` buttons to create a copy. + +9. Remove the `Contact Volume dashboard` table format from the bottom of the dashboard. + +10. Next, we will add another report to this dashboard. Find the report created in Lab 3.2 called `3.2_AAR_RT_AgentState` under your Team folder and drag that into the dashboard on top of the chart. Adjust the height and width of the report. + +11. Update the Dashboard name as `4.1_Contact_Volume_AgentState` below `Save` option. + +12. Save this Dashboard as `4.1_Contact_Volume_AgentState` and execute it. + +## 2. Creating Custom Dashboards + +We will create a new Dashboard using the below visualizations which we have created in previous labs together with some stock visualizations. + +**Objective**: Create a dashboard to provide insights on: + +- How are contacts trending historically around Total vs Abandoned calls? + - Via 3.3_CSR_ContactVolume +- How are Agents performing today? + - Via Team Details Real-Time +- How is the Customer experience right now? + - Via Average Service Level Card Real-Time + - Via Longest Contact Currently in Queue Card Real-Time +- What are agents doing (what is their state) in Realtime? + - Via 3.2_AAR_RT_AgentState + +1. Navigate to the `Dashboards` section of Analyzer and `Create New Dashboard`. + +2. Drag the following created reports from your attendee folder to the dashboard. + + - 3.2_AAR_RT_AgentState + - 3.3_CSR_ContactVolume + +3. Search for the other visualizations and drag them in the panel. + + - Team Details Real-Time + - Average Service Level Card Real-Time + - Longest Contact Currently in Queue Card Real-Time + + **_Tip: If you are having issues with dragging the visualizations, try dragging it next to an already added report instead of a random free space in the dashaboard._** + +4. Arrange them in a presentable view by moving them around and extending. + +5. Name the dashboard as `Lab Custom Dashboard`. + +6. `Save` this dashboard as `4.2_CustomDashboard` inside your student folder. + +7. Run the dashboard by clicking `Preview`. + +8. Recently, we have added the ability to use filters in dashboards as well (this is controlled by a Feature Flag, you need to request this through your PSM/CSM). Depending on the type of reports included in your dashboard, you will have option to filter to customize the information that is displayed on the dashboard. In this screenshot we have Run filter with option for Interval and Duration. + +# New Data Insights + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| ----------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Queue Based Reporting](#1-queue-based-reporting) | Practical Lab | EASY | 15 min | +| [Global Variable Reporting](#2-global-variable-reporting) | Practical Lab | EASY | 10 min | +| [Data Reporting for Digital Channels](#3-data-reporting-for-digital-channels) | Practical Lab | EASY | 10 min | +| [Skill Based Reporting](#4-skill-based-reporting) | Practical Lab | EASY | 15 min | +| [Preferred Agent Reporting](#5-preferred-agent-reporting) | Practical Lab | EASY | 15 min | + +## 1. Queue Based Reporting + +> **NOTE:** Queue Based Reporting feature is still **in development** and not yet GA. Please discuss with your PSM/CSM if you want to enable and test this feature in your own tenant. + +Queue Based Reports offer the standard fields and measures you know but aggregated at Queue level (i.e. Per Queue level & Per Agent Level Metrics). + +- `Call statistics`, such as calls presented, handled, abandoned, and dequeued. +- `Service Level statistics`, such as Average Queue Time, Average Speed of Answer, and Average Abandoned Time. + +There are additionally **3 new stock reports**: + +- Queue Activity by Queue +- Queue All Fields Report +- Queue Call Distribution Summary + +In this exercise, you will see how Queue based data is different from Contact Session and Contact Activity Data and how you can use Queue based reports to capture more precise insights for your contact center at the queue level which help with more accurate and predictive actions. + +Before continuing with this exercise make, sure you have made some test calls and used `Preferred Agent Routing` to handle the calls (Refer to instructions on [Pre-requisites](https://webexcc.github.io/pages/Analyzer/)). + +In this exercise you will notice how data are captured across 3 different types of repositories: Customer Session Record (CSR) , Customer Activity Record (CAR) and Queue Record and how `Queue Record` offers much clear data points for contact center. + +![Queue1](/assets/images/Analyzer/Queue1.png) + +![Queue2](/assets/images/Analyzer/Queue2.png) + +Follow the steps below to complete this exercise: + +1. Edit `3.1_CSR_Today_ValueReport` and add `Preferred Agent Name` as a filter -> Select your user in the field. + +2. Save the visualizations and `Preview`. + +3. Make a Note of Call session along with the Queue Name and capture in this document (For future use). + +4. Next Click on any Session Id and click on Zoom ![Zoom](/assets/images/Analyzer/zoom.png) to drill down into the Session. + +5. Here, makes a note of all the Activities for this session and make a note of the Queue name across various activities (Click on Next page at the bottom if applicable). + +6. Navigate to Analyzer and Create a new report visualization that will be saved in your atendee folder. Create `New Visualization`. + +7. Select the Type as `Queue Record`. + +8. Select `Duration` as **Today**. + +9. Click on `Profile variables`. + +10. Add the Profile variable Fields. + + - Search for session and select `Contact Session ID` and drop it into Profile Variable . + - Select the `Value of Contact Session ID`. + - Next Add below fields and Save the report as `5.1_QBR_Today_ValueReport` in your folder: + - CallLeg ID + - CallLeg Start Timestamp (Set Date/Time Format ) + - CallLeg End Timestamp (Set Date/Time Format ) + - Queue Name + - Agent Name + - Is Within Service Level + - Service Level Threshold (Set Duration format) + - Handle Type + - `Preview` the Report. + +11. Click Hamburger icon next to Customer Session ID + +12. Filter it for the session selected in step-4 above. You will notice all Call legs associated with this Contact session. + +13. Next, Go to `Stock Reports > Historical Reports > Queue Reports`. + - Preview all three Queue Stock reports and make a note of various data points. + +## 2. Global Variable Reporting + +**_Global Variables)_** allow you to save Call associated or Agent entered Data or data from external applications into the reporting. You must mark the Global variable as Reportable (Max 100 Reportable) to report on this data. Variable can be of following types: + +- Boolean +- String: 256-character limit +- Integer +- Decimal +- Date Time + +In this Exercise you see how you can capture the data using Global variable and use in visualizations to capture the key insights. + +- Before continuing with this Lab, make sure you have made some test calls and opted for Callback by keeping your agent in Idle state. +- Next, change your agent state to Available, callback will be established. +- Make a note of your agent desktop call data information. + +You would notice two Global Variables: TODO + +- Global_IsCallback (Integer) +- Global_AttendeeID (String) + +The Data insights we want to capture is two fold: + +- Value of Caller entered digits in IVR +- Number of calls opted for Callback Per Student and SUM total + +1. Create a visualization with the following characteristics: + + - Choose `Start Time` as **Today**. + - Select `Global_StudentID` in `Row Segments`. + - In profile variable under `Measure` select `Sum of Global_IsCallback` (Note: Check Measures as this is an integer variable not string) + - Enable `Run mode filter` for Global_StudentID + +2. Save the visualizations as `5.2_GlobalVariable` in your Folder and `Preview`. + +This will provide you number of callbacks for each Attendee ID. + +## 3. Data Reporting for Digital Channels + +Besides voice data, Analyzer reporting offers similar insights on **_digital channel interactions_** as well, such as conversation statistics (conversations presented, handled, abandoned) and service levels (In Service Level, Average Speed of Answer, Average Abandoned Time). Global variables are also recently available in Webex Connect flows to capture additional data. + +In this Exercise, you will explore the available stock reports for Digital Channel reporting as well as create your own custom visualization, capturing some data from the non-voice conversations. + +- Before continuing with the exercise, make sure to create some test digital interactions. If you do not have any digital interactions created, you can skip this exercise until you complete [Lab 12 - Digital Channels](https://webexcc.github.io/pages/Digital/). + +1. Stock visualizations for multiple channels are available inside the `Multimedia Reports` folders. + +2. Navigate to `Stock Reports > Historical Reports > Multimedia Reports`. + +3. Search for the `Queue Service Level` report, click on the 3 dots and then `Run`. + +4. Make sure to change the Duration filter on the top-right to `This Week`. + +5. Familiarize yourself with the visualization. Feel free to use the Channel Type filter to search for specific channel interactions (e.g. chat, email, social). + +6. After becoming familiar with the report, you can close current tab and search for the `Agent Trace` stock visualization and run it. + +7. Make sure again that Duration filter is for `This Week`. Investigate the report and notice how agent has a different state for each channel their Multimedia Profile includes. + +8. After becoming familiar with the report, you can close current tab and go back to the Visualizations tab in Analyzer. + +9. Create a new CSR visualization, utilizing the knowledge gathered so far, with the following requirements: + + - Set the `Start Time` as **This Week**. + - Value of variables `Channel Type`, `ANI`, `DNIS` and `Contact Start Timestamp` as profile variables. + - Verify that Contact Start Timestamp has the proper Number Format to show Date Time, by right clicking on variable Contact Start Timestamp and selecting the desired format. + - Create a filter on `Channel Type` to only include chat, email & social. + +10. Save the report as `5.3_CSR_Digital_Channels` under your student folder. + +11. Click `Preview` to see the report. + +## 4. Skill Based Reporting + +**_Skill Reporting_** has been launched recently, which offers new data insights into Call and Agent skill assignments, providing information for agents and flows that utilize the Skill-Based Routing logic. + +Fields added for CSR, CAR, ASR and AAR: + +- Agent Skill Profile (ASR and AAR) +- Agent Skills (ASR and AAR) +- Contact Required skills (CSR and CAR) +- Contact Matched skills (CSR and CAR) +- Contact matched Skill profile (CSR and CAR) + +Supported Skill Types: + +- Enum: A named set of predefined values +- Proficiency: 0-10 +- Text: Free-form text, support 40 characters +- Boolean: True, False + +In this Exercise you would try to capture skill information for the caller and Agents. + +The visualization we will create will capture the numbers of agent available for each skill set. + +1. Leverage the learning so far to build a custom report with below characteristics: + + - Data Type: `Agent Session Record` + + - `Realtime` with **5 sec refresh** duration. + + - `Agent Skill` and `Agent Name` as Row Segment. + + - **Count of Agent** as `Profile Variable`. + + - Filter on `Channel Type` **Telephony**. + + - Select `Agent Skills` for Filter on Run Mode. + +2. Save the Visualizations as `5.4_Agent_RT_SkillCount`. + +3. Click `Preview`. + +4. Click on `Agent Skills Filter -> Click Custom Select`. + +## 5. Preferred Agent Reporting + +In this exercise, you will explore key reporting data points when using **_Preferred Agent Routing_**. + +1. Create a new visualization in Analyzer as `Customer Session Record`. + +2. Set `Start Time` as `Today`. + +3. Next, Click on `Row Segments` and add: + + - Routing Type + - Preferred Agent Name + - Final Queue Name + +4. Next, Click on Profile Variables and add `Count of Contact Session ID` and rename the name as `#CallCount`. + +5. Customize the Report Summary: + + - Uncheck `Table level` and check `Routing Type`. + - Click `Customize`, set the `Routing Type` Level to `SUM` and `Save`. + +6. Save the visualization as `5.5_PrefferedAgent_CallToday` in your folder. + +7. `Preview` the visualization. Review the information in the report. + +# Agent Data Insights + +In many cases, it’s not only supervisors or administrators but also agents that need access to some reporting and statistics. Since Analyzer is, by default, not accessible to agents, there are other ways that we can share such data insights with them. In this lab, you will explore some of them, such as the `Agent Personal Statistics (APS)` tab in Agent desktop, the `direct access via URL` as well as `embedding reports on the Agent Desktop` itself. + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| ------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Agent Personal Statistics](#1-agent-personal-statistics) | Practical Lab | EASY | 10 min | +| [Agent Direct URL Access](#2-agent-direct-url-access) | Practical Lab | EASY | 5 min | +| [Embedding the report into Agent Desktop](#3-embedding-the-report-into-agent-desktop) | Practical Lab | EASY | 10 min | + +## 1. Agent Personal Statistics + +1. If not already logged in to the Agent Desktop, open a new window and **login** with your agent user. + +2. On the left-hand side menu, select the `APS` icon ![APS](/assets/images/Analyzer/APS.png). + +3. Within APS, there are multiple tabs of data. Navigate through the APS dashboards available in the Agent Desktop. + +4. Go back to the first tab called `Summary`. While on the Summary report, the agent can filter their view. We now have the ability to **save** these filters in cache so that next time agent logs in, the filters will already be in place. + +5. Choose different options in the `Team Name`, `Queue Name`, `Channel Type` filters. Notice that the data on the screen updates. + +6. The tabs inside the APS reports are **_persistent_**, i.e. the agent desktop will remember the last tab you visited if you navigate away to the home screen or any other page. Select the `Queue Stats – Realtime` tab. Then, click the `Home` tab ![AgentHome](/assets/images/Analyzer/AgentHome.png) on the left side. + +7. Go back to the APS tab. You will notice that the `Queue Stats – Realtime` is the default tab in your APS viewer. + +## 2. Agent Direct URL Access + +Analyzer is a premium functionality which is only accessible for Supervisors or Administrators but there are few use-cases where supervisors would like to share certain visualizations with Agents (Standard or Premium) for sharing the insights they are looking. This is possible with the `Share Browser Links` functionality. + +1. Run the dashboard `4.2_CustomDashboard` you created in [previous exercise 4.2](#2-creating-custom-dashboards) with your **_supervisor user_**. + +2. **_Copy_** the dashboard link from the browser. + +3. Now, **Login** with your **_agent user_** in a separate browser or incognito mode. + +4. **_Paste_** the dashboard link in a new tab on the agent's browser session. You can see that you can now the dashboard as an agent, seeing only the statistics in which you have access. + +## 3. Embedding the report into Agent Desktop + +`Desktops layout` configuration drives the Agent desktop UI. By default, all Agent teams are mapped to a default global Desktop Layout. To **_embed_** a custom report into Agent desktop, follow below instructions: + +1. Run the dashboard `4.2_CustomDashboard` you created in [previous exercise 4.2](#2-creating-custom-dashboards). + +2. Now, download and open the below custom desktop layout file provided to you. + + [Custom Desktop Layout JSON File](/assets/images/Analyzer/CustomDesktopLayout_v1.json) + +3. Go to the Line 114 or look for `src` and paste the dashboard link from step 1 as src value. + +4. `Save` the file. + +5. Go back to the `Admin Portal`. + +6. Go to `Desktop Layout` under Provisioning. + +7. Click on the dots ![Dots](/assets/images/Analyzer/dots.png) and then Copy the layout and name it as attendee-id\_DesktopLayout, based on your attendee ID. + +8. Upload the saved file in step 4 and save the desktop layout. + +9. Now, navigate to `Provisioning -> Team`. + +10. Select your team and edit by clicking 3 dots -> Edit. + +11. Under `Advanced settings -> Desktop Layout`, select your newly created personalized desktop layout and save the Team. + +12. Now refresh the agent desktop, you will notice `Analyzer iFrame Widget` on the agent desktop ![DesktopWidget](/assets/images/Analyzer/DesktopWidget.png). + +13. Click on it and you will see the dashboard loading on agent desktop! + +# Supplementary Data Capabilities + +There are various additional capabilities that Analyzer offers in terms of automating and monitoring the system. In this lab, we will explore how we can `import/export report templates`, how we can `schedule reports` to be run and sent on predefined time periods as well as how we can create `alerts` when specific threshold criteria are surpassed. + +## Table of Contents + +| Topic | Lab Type | Dificulty Level | Estimated length | +| --------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Export/Import Visualizations Template](#1-export/import-visualizations-template) | Practical Lab | EASY | 10 min | +| [Visualization Scheduler](#2-visualization-scheduler) | Practical Lab | EASY | 5 min | +| [Threshold Alerting](#3-threshold-alerting) | Practical Lab | EASY | 10 min | + +## 1. Export/Import Visualizations Template + +You can **_export or import visualizations_** as a single file or as folders containing multiple files. Exporting /Import report templates helps in reusability across multiple tenants. + +**_This is an Administrator only functionality and these options won’t be visible for supervisor role._**
    + +For this exercise, you need to login in the Analyzer portal in a separate browser or incognito window with your **administrator user**. Also, you will need to download the zip file below named **_ImportZIP_**. + +[ImportZIP](/assets/images/Analyzer/Analyzer_Import.zip) + +1. Go to the `Visualizations` tab, click on the ellipsis ![Ellipsis](/assets/images/Analyzer/Ellipsis.png) on the right of your student folder and click `Export Templates`. Confirm by clicking `Export` on the popup window. + +2. Zip file with the templates of all the created visualizations will be downloaded on your computer. **_Note: During export, the filter names are retained but the values are not, thus filter values are blank after export and need to be re-configured._** + +3. To import the downloaded template, first to go your student folder and create a subfolder named **_Import_**. + +4. Go Inside the Import folder, and click on `Import` on the top. + +5. Browse to the Downloads Folder of your computer. + +6. Select the zip file **_ImportZIP.zip_** , and click Import. + +7. You can verify from the new popup window that the templates were imported successfully. + +8. Try to run these reports (e.g. Agent Monitor by State). You will see that most will fail and will ask provide you the details of filters which need to be updated due to the values being blank . + +9. Go inside the report and `fill all the filters`. Once filter values are added, you can run these reports. You can also remove the filter all together, if not required. + +## 2. Visualization Scheduler + +In this exercise we will learn how to **_schedule visualizations_** within Analyzer. In Analyzer, you can schedule any historical visualization to be run and sent in a predefined time period to an email address. This is very handy for admins or supervisors who need to see reports on a scheduled daily, weekly or monthly basis. + +1. Find the report `2.3_Queue Service Level` report that we created previously from your student folder. + +2. Next, in the right-hand corner of the report, select the three ellipsis ![Ellipsis](/assets/images/Analyzer/Ellipsis.png) and, from the dropdown, select the option `Schedule Job`. + +3. Fill in the schedule information for the scheduled report. + + - Start with the `Job Name`. Let’s set this to run daily, so we will give it the name **2.3 Daily**. + - Choose a start date and time. Select today’s date with a time of a few minutes ahead of your current time to give it time to trigger. + - Lastly, complete the details for the email notification by entering in your email address and a subject line. + +4. Once saved, the scheduled job will show up under the `Jobs` list. + +5. If everything was setup correctly, check your email for the report after the trigger time has passed. + +6. If your job was only set to run once, once it runs, that job is deleted from the jobs list. + +7. Close the job scheduling window. Go back to the folder structure and look at the `Details` of the report, it will show the number of jobs scheduled. You should see 1 scheduled job to reflect the job we just scheduled in this exercise. + +## 3. Threshold Alerting + +**_Threshold Rules_** can be set to trigger when specific threshold criteria (e.g. number of calls in Queue) are met. This is another useful feature for administrators, as they can be notified both inside the Analyzer and via email when an undesired condition is met in the tenant in order to take action. + +1. Navigate to the `Admin Portal` and under the Provisioning menu, go to `Threshold Rules`. + +2. Create a `New Threshold Rule`. + +3. Let's setup a Queue threshold alert. Name it attendee-id\_LabQueueThreshold, based on your attendee number. Threshold rules can be set according to Agent or Contact records. + +4. Set the entity type to be `Queue`. + +5. Select the name of your queue. + +6. Next select the `Longest Time in Queue` as the Threshold Metric with the `>=` operand and `Trigger Value` of 10 seconds, as well as `Trigger Interval` of 120 seconds. + +7. Type your email address for the alert. After you entered your email address, you need to hit `Enter` key for the email to save. + +8. Test the new threshold with a call into the queue. Let the call be in the queue for more than 10 seconds. + +9. Check your email after a few minutes to verify that you got the alert. + +10. Next, in Analyzer, check your threshold alerts on the top-right. You should see an alert notification ![ThresholdAlert](/assets/images/Analyzer/ThresholdAlert.png). Click on `Threshold Alerts`. + +11. Next, acknowledge this threshold alert by checking the box next to the alert ![MarkAsRead](/assets/images/Analyzer/MarkAsRead.png) and clicking `Mark as Read`. + +12. Lastly, you will notice that the threshold alert also gives ability to filter on (1) Notification Types (2) Duration and (3) Entity Type as well as the option to turn off the auto refresh function. You can also switch between Realtime and Historical Alerts, to view any past alerts in the system. + +# Using Data APIs + +Webex Contact Center Analyzer utilizes `GraphQL` for its API capabilities. GraphQL endpoint enables users to search for various Contact Center objects, such as tasks (= contacts/calls) or agent sessions, as per the graphQL schema. + +The queries supported by the search graphQL endpoint optionally accept filters and aggregations, whose format, is also defined in the schema. The search results are paginated, with max page size being different across various queries, and a maximum of 10000 results across multiple pages are returned. + +It is important to note that SearchTasks API is not querying the reports we create in Analyzer but the raw data directly, compared to previous versions. + +Additionally to the [Developer Documentation](https://developer.webex-cx.com/documentation/search/v1/search-tasks), Cisco has created various additional Search Task endpoint samples and help videos to get started with Analyzer API, which can be found in [Cisco DevNet Github page](https://github.com/CiscoDevNet/webex-contact-center-api-samples/tree/main/graphql-sample). + +- Navigate through both of these links to familiarize yourself with the Data API capabilities in Webex Contact Center. + +To learn everything about Reporting and Search APIs, you can follow and complete [Lab 11](https://webexcc.github.io/pages/API/#all-new-webex-contact-center-apis-new-version). + +--- + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    diff --git a/_pages/CCAI.md b/_pages/CCAI.md new file mode 100644 index 0000000000..e97e9b92c7 --- /dev/null +++ b/_pages/CCAI.md @@ -0,0 +1,805 @@ +--- +title: Lab 7 - Google Dialogflow & TTS +author: Chandramouli Vaithiyanathan & Kevin Simpson +date: 2022-07-07 +layout: post +--- +``` +Last modified: Thu, 20 Feb 2024 +``` + +### Overview of the lab: + +In this Lab, we will go through the tasks that are required to setup **Contact Center AI with the Voice Bot and Text-to-Speech (TTS) capabilities**. + +## Table of Contents + + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Setup the Google Account](#setup-the-google-account) | Practical Lab | EASY | 20 min | +| [Setup Dialogflow ES Agent \& Google Connector](#setup-dialogflow-es-agent--google-connector) | Practical Lab | MID | 20 min | +| [Configure TTS, EWT \& PIQ](#configure-tts-ewt--piq) | Practical Lab | MID | 20 min | +| [Configure Dialogflow ES Virutal Agent](#configure-dialogflow-es-virutal-agent) | Practical Lab | MID | 15 min | +| [Configure Dialogflow CX Virutal Agent](#configure-dialogflow-cx-virutal-agent) | Practical Lab | MID | 90 min | + + + + +## Introduction + +### Lab Objective + +- This lab is designed to help you configure a Google Dialogflow Agent using CCAI (Contact Center AI) on Webex Contact Center and utilize TTS (Text-to-Speech) capabilities. + +- At the end of this lab, you should have a fully functioning bot front-ending the Webex Contact Center and text to speech prompts. + +### Prerequisites + +- You must have a Google Account created. + +- A credit/debit card (American Express, Mastercard or Visa) is needed to create the Google Billing account. +> **Note:** No card will be automatically billed any cost, but a billing account needs to be setup to be able to utilize TTS. + +- Lab 2 ([IVR Contact Routing Lab](https://wxcctechsummit.github.io/wxcclabguides/TechSummitRoW_2021/IVR.html)) should be completed, as same call flows will be used and expanded upon. + + +### Quick Links + +> Control hub: **[https://admin.webex.com](https://admin.webex.com){:target="_blank"}** + +> Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal){:target="_blank"}** + +> Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/){:target="_blank"}** + +> Google Cloud Console: **[https://console.cloud.google.com](https://console.cloud.google.com/){:target="_blank"}** + +> Dialogflow: **[https://dialogflow.cloud.google.com](https://dialogflow.cloud.google.com/){:target="_blank"}** + + + +## Lab Section + +# Setup the Google Account + + + + +- Login to [Google Cloud Console](https://console.cloud.google.com/) with your Google Account credentials. + +- Click on **Select a project** on top and then on **NEW PROJECT** on the pop-up window. + +- Enter a name for your project, e.g. `TS2021-CCAI` and click on **CREATE**. + +- Make sure you have this project selected. + +- On the navigation bar on the left, click on **Billing**. + +- Click on **LINK A BILLING ACCOUNT** and then on **CREATE BILLING ACCOUNT**. + +- Enter your Account Information (`Country`, `Mobile Phone`), accept the Terms of Service and click on **CONTINUE**. + +- Enter your credit/debit card details and click on **START MY FREE TRIAL**. + +- Click on **CLOSE** on the next pop-up window. + +- On the search bar, type `text to speech` and click on the **Cloud Text-to-Speech API**. + +- Click on **ENABLE**. + +- Click on **CREATE CREDENTIALS** on the top-right. + +- If prompted,choose **Cloud Text-to-Speech API** from the dropdown menu and check the **Application Data** option and **No, I'm not using them** and then click on **NEXT**. + +- On the **Service account details**, enter a name for the service account, e.g. `TS2021_TTS_SA` and then click on **CREATE AND CONTINUE**. + +- On **Grant this service account access to project**, search and choose the **DialogFlow API Admin** role and then click on **CONTINUE** and then on **DONE**. + +- Similarly, now on the search bar type `dialogflow API` and click on the **Dialogflow API**. + +- Click on **ENABLE**. + +- Click on **CREATE CREDENTIALS** on the top-right. + +- If prompted,choose **Dialogflow API** from the dropdown menu and check the **Application Data** option and **No, I'n not using them** and then click on **NEXT**. + +- On the **Service account details**, enter a name for the service account, e.g. `TS2021_CCAI_SA` and then click on **CREATE AND CONTINUE**. + +- On **Grant this service account access to project**, search and choose the **DialogFlow API Admin** role and then click on **CONTINUE** and then on **DONE**. + +- To generate the required .json keys, click on the service account you created (e.g. **ts2021-ccai-sa@ts2021-ccai.iam.gserviceaccount.com**). + +- Click on the **KEYS** tab and then on **ADD KEY** > **Create new key**. + +- Choose the **JSON** key type and click on **CREATE**. Make sure you have the key saved locally. + +- Click on **Service Accounts** on the left and follow the same procedure to download the TTS JSON key as well. + + +# Setup Dialogflow ES Agent & Google Connector + + + + +- Open [Control Hub Admin](https://admin.webex.com/) page. + +- Go to **Contact Center** > **Connectors** and click **Set Up** on **Google connector**. + +- Give a name to the connector, e.g. `techsummit_google_tts` and click on **Upload Authentication Key** to upload the .json file key downloaded before. Click on **Done**. + +- Go to **Features** tab and click on **New** template. + +- Click on **Virtual Agent**. + +- Check only **Use For Voice** and click on **Next**. + +- Choose **Yes, I have a preconfigured Dialogflow agent.** + +- Click on **Download Intents** and save the .zip file with the two intents locally. + +- Open a new tab and go to [Dialogflow page](https://dialogflow.cloud.google.com/) and login with your Google credentials. + +- Click on **Create an Agent**. + +- On the **GOOGLE PROJECT**, give a name to the agent, e.g. `TS_DF_Agent`, choose the project created in the previous step and click on **CREATE**. + +- On the next page, click on the dots on the top right (next to **CREATE INTENT**) and choose **Upload Intent**. + +- Unzip the two intents you downloaded from Control Hub (**escalation.json** & **handled.json**) and upload them here. + +- Go back to the Control Hub tab and click on **Next**. + +- Give a name to your virtual agent, e.g. `TS_CCAI_Agent` and click on **Next**. + +- Upload the CCAI/Dialogflow .json key downloaded in the previous part and click on **Validate**. If all is good, click on **Next**. + +- Skip the avatar step and click **Next**. + +- Click on **Finish** to complete the Virtual Agent creation. + + +# Configure TTS, EWT & PIQ + + + +- Open Flow 3 in the Flow Designer from Lab 2 ([IVR Contact Routing Lab](https://wxcctechsummit.github.io/wxcclabguides/TechSummitRoW_2021/IVR.html)). + +- In the **Success** Play Message block, chose **Enable Text-to-Speech** under Prompt, choose your created connector (e.g. `techsummit_google_tts`) and set language as **en-GB-Standard-A**. + +- Type "Thanks \{\{Customer_Name\}\}, we got your information" as your TTS message. + +- Make a new test call and verify that you get a personalized message with the customer's name based on the PIN provided. + +- For **EWT**, after the **QueueContact1** node, add a **Get Queue info** block. + +- Under **Queue Information**, select **Static Queue** and enter your queue. + +- On success path, add a new **Play Message** block. Name it **EWT_PIQ**. + +- Add the TTS connector to it similar to the step above and type "You Estimated Wait Time is \{\{GetQueueInfo.EWT\}\} and your position in Queue is \{\{GetQueueInfo.PIQ\}\}" as message. + +- Similarly, for the **Insufficient Information** block, add a new **Play Message** block and name it **PIQ**. + +- Again, add the TTS connector and type "Your position in Queue is \{\{GetQueueInfo.PIQ\}\}" as message. + +- Save and publish the flow. Test the call flow and make sure you hear the PIQ prompt. + +> **Note:** Make sure no agent is available to handle the call to be able to listen to the PIQ prompt. + +# Configure Dialogflow ES Virutal Agent + + + +- Create a new call flow in the Flow Designer. + +- Create a flow logic similar to the video guide, i.e. first add a **Virtual Agent** block after the **New Phone Contact**. + +- Under **Conversational Experience**, add the virtual agent you have created (e.g. `TS_CCAI_Agent`) and enable **Make Prompts Interruptible**. + +- For `Handled` output from Virtual Agent, which means that self-service was successful, connect the output to a **Play Message** block and add a "Call successfully handled by virtual agent!" TTS message to it. + +- Connect that Play Message to a **Disconnect Contact** block. + +- Respectively, for `Escalated` output, which means that self-service was not sufficient and we need to escalate this to an agent, connect the output to a **Queue Contact** block and assign your Queue to that block. + +- Add a **Play Music** block with some music on hold and loop it to itself to use as MOH while customer is waiting for an available agent. + +- Map that flow to your entry point to be able to make test calls. + +- Make a test call and when virtual agent greets you and asks you what you would want, answer with `I don't need any more help`. This will trigger the **Handled** output and terminate the call after a message from the bot. + +- Make another test call. This time, answer with `I need help with billing`. This will trigger the **Escalated** output and search for an available agent. + +- Optionally, you can send the transcript of the conversation between the customer and the virtual agent to the agent when connected. To do so, you would need to **Enable Conversation Transcipt** under Advanced Settings in the Virtual Agent block. + +- Also, you would need to create a CAD Variable to save the **TranscriptURL** output variable from the Virtual Agent block and pass it to the desktop. + +- Feel free to play around with various phrases as responses to the virtual agent and see if it is able to handle them properly. + +# Configure Dialogflow CX Virutal Agent + +## Table of Contents + + + + +

    Introduction to Webex Contact Center with Dialogflow CX

    + +The Webex Contact Center with Google CCAI is the integration that allows the use of Google Text-To-Speech, Natural Language Understanding and Virtual Agent technologies with Webex Contact Center. + +Dialogflow CX is designed for building complex, multi-turn conversations that involve multiple steps and decision points. It provides tools for creating conversational flows, managing context, handling user intents and entities, and integrating with other applications. Think of conversations that have many turns and where you want to track the interaction content very deeply. These types of conversations typically happen on the phone line to a Contact Center where people ask all types of questions, and the Virtual Agent needs to listen in and provide the answers. It does not mean that you cannot build complex flow using Dialogflow Essentials, which is another version of Dialogflow, but you would need to use a lot of code around it to build a whole framework to achieve complicated logic. But with Dialogflow CX flow builder interface it is no longer the case as the graphical interface lets developers design and build conversational AI applications without requiring extensive coding skills. + +Webex Contact Center now supports Dialogflow CX integration and using this article, you can configure and test the solution. + +The integration requires you to do configuration in multiple portals: Google Cloud Platform and Google Dialogflow CX, Webex Control Hub, and Webex Contract Center. + +

    Addresses and Credentials

    + +- Webex Control Hub + +- Webex Contact Center Management Portal + +- Google Cloud Portal Console + +- Google Dialogflow CX + + +

    Provisioning

    + +

    Objectives

    + +The objective of this section is to introduce you to Provisioning process which would require to obtain Google CCAI licence for Webex Contact Center. + +

    Introduction to Provisioning

    + +For billing purposes, you need to provision Webex Contact Center with Google CCAI. + +Google provides these APIs for integration of Dialogflow Virtual Agent and Text-to-Speech technologies: + +- Dialogflow API +- Cloud Speech-to-Text API +- Cloud Natural Language API +- Cloud Text-to-Speech API + +These APIs are not necessarily free and can require a billing account on Google Cloud Portal. The main reason of the Provisioning process is to create the billing account between Cisco and Google for the user, so all user billing goes directly through the Cisco Accounting team. It means the user pays to Cisco and Cisco pays to Google. + + + +The process takes a couple of days, so you are not going to complete the Provisioning process in this section. For your information in the next screenshot, you can see the high-level diagram with the required steps to complete the Provisioning. + + + +If you would like to read more about the Provisioning process, refer to Provision Google CCAI for WxCC article. + + +

    Create Dialogflow CX Virtual Agent

    + +

    Objectives

    + +This section describes how to navigate Dialogflow CX and Webex Control Hub portals to create a new agent and bind the agent to the Webex environment by creating a new Contact Center AI Config. + +

    Task 1. Create new Virtual Agent

    + +Step 1. Log into Dialogflow CX portal using your user account and password. Select project CL2024AMS. (If you experience any difficulties with logging in please clear the catch and cookies on the browser you use.) + +Step 2. Click Create Agent. Then select Build your own. + + + +Step 3. Provide the name for the new agent using this format: {Your Name}_Virtual_Agent . Select location global (Global serving, data-at-rest in US). + + + +

    Task 2. Assign the agent that you created for the Conversational profile.

    + +Note: A Dialogflow Conversation profile is a set of configuration settings that define the behavior of the virtual agent in a conversation with a user. + +Step 1. On the left top corner click Menu icon. + + + +Step 2. From the Menu options, select Agent Assist. + + + +Step 3. In the next window click on the Conversation profile under the DATA section. Now create a new Conversation profile for your section. + + + +Step 4. Create the name for your Conversation profile using this format: {Your Name}_Conversational_Profile. + + + +Step 5. Scroll down and enable the virtual agent for this Conversation profile. Click on the Agents field and select the agent that you created in the previous task and then click Create. + + + +Step 6. Once the Conversation profile is created, copy the profile ID past it to a notepad, or just know that this is the place where you can get the Conversation Profile ID as you need it the Task 4 of this section when configuring the AI config in Webex Control Hub. + + + +

    Task 3. Configure Google Contact Center AI connector

    + +(This Task is information only) +Log into Webex Control Hub using your user account, select Contact Center service and open Connectors. You can see the Google Contact Center AI card. This connector is used specifically for Dialogflow CX agents. Only users with permissions to Cisco Project can create this connector. For security reasons, the users for this section do not have such permission so this connector is preconfigured for you. For the demo purposes Dialogflow-CX connector can be used. + + + +

    Task 4. Create Contact Center AI config

    + +Step 1. In Webex Control Hub, go to the Contact Center service, select Feature, and click New. + + + +Step 2. On the next window, select Contact Center AI Config. + + + +Step 3. Give the name for the feature using this format: {Your Name}_WxCC__Virtual_Agent. Select Dialogflow CX as the Google Contact Center AI Connector and post the Conversation profile ID that you had previously in Task 2. + + + +Step 4. You can now see the Feature was created. + + + +

    Configure Dialogflow CX Virtual Agent

    + +

    Objectives

    + +This section describes how to configure the Virtual Agent to have a conversation with a caller and decide whether to send the call directly to the queue with human agents or collect estimate information and send the data to the Analyzer report. + +In the next screenshot, you can see a functional diagram of the flow for this section. + + + +

    Task 1. Navigate to Dialogflow CX Agent flow builder and customize the initial greeting.

    + +Step 1. Log in to Google Dialogflow CX portal using your user account and password. Select project CL2024AMS. + +Step 2. Select the Virtual Agent that you created earlier. + + + +Step 3. In the Dialogflow CX builder click on the Start page. + +Note: In Dialogflow CX, a page is a set of instructions that holds one or more related conversational turns. It represents a single step in a conversation flow, and it can contain various types of content, including text responses, prompts for user input, fulfillment actions, and more. Pages are connected together to create a conversation flow that guides the user through a conversation with the Dialogflow CX agent. + + + +Step 4. In the Start page click on Default Welcome Intent Route. On the right window, scroll down, delete all the default Agent responses, and click on the field to Enter agent dialog. + +Note: A route is a mapping between an intent and a specific page or flow within a conversation. Routes define how a conversation can flow based on the user input and the intent that is matched. + + + +Step 5. Provide your customized message to let the caller know that they reached an organization that provides sales services of Webex Contact Center. You can type something like: Hello! Thank you for calling. Here you know all about Webex Contact Center. In Dialogflow CX, the changes are not saved automatically, so you need to save the page every time you make a change. + +Note: Agent responses are the messages or actions that an agent sends back to the user or caller during a conversation. When a user or caller sends a message or makes a request to a Dialogflow CX agent, the agent analyses the input and determines the appropriate response to send back. + + + +Step 6. Test the agent response that you just created. Click Test Agent and type a greeting message such as Hello. + + + +

    Task 2. Create new page to collect the caller name

    + +Step 1. Close the Start page and Test Agent windows and click the plus icon (+) to create a new page. Name the page Caller_Name and confirm the creation. + + + +Step 2. Connect the Start page and Caller_Name page. For this, click the Default Welcome Intent route on the Start page. Scroll down on the right side and select that you would like the conversation to go to the next page. + + + +Step 3. From the drop-down list, select Caller_Name page. Do not forget to Save the change. + + + +Step 4. Configure the Caller_Name page to collect the name from the caller and store it in the parameter. In the Caller_Name page click Entry Fulfillment and type message in which you ask the caller name. Click Add and Save the change. + +Note: Entry Fulfillment is needed to provide a message to the caller once the call is moved to a new page to let the caller know where they are in the conversation and set the right expectations. + + + +Step 5. While on the Caller_Name page, click on Parameters, type Name as the parameter’s name, select sys.any from the list of preconfigured Entities, and click on Save. + +Note: A Parameter is a named entity or value that is extracted from user input during a conversation. Parameters can be used to store information that is relevant to the user request, such as their name, date of birth, or preferred language. Parameters can also be used to pass data to other parts of your application such as Contact Center. + + + +Step 6. Configure Routes in the Caller_Name page. Click Route, on the right window scroll down to Condition and set the condition $page.params.status ="FINAL". Click Save. By setting this condition, you can expect the call to move to the next page once the Name parameter which you created in the previous step is filled with a value. For example, if the caller says Nick then the call can move forward. + +Note: A Condition in the Dialogflow Routes configuration is a rule or set of rules that define when the route must be triggered. The Condition can be based on various factors such as user input, context, parameters, and session data. + + + +Step 7. Using the Test Agent option on the right top side, test if the flow is working as designed at this point. + + + +

    Task 3. Create new page Agent_or_Estimate and connect it with the Caller_Name page.

    + +Step 1. On the left bottom side, click to add a new page, name it Agent_or_Estimate, and confirm the creation. + + + +Step 2. Connect Caller_Name and Agent_or_Estimate pages. Open the Caller_Name page, and select the route that you created in the previous step, on the right side scroll down and select the page Agent_or_Estimate. Do not forget to Save the change. + +Remember in Task 2 of this section you configured the condition that once the parameter is filled it triggers an action. By selecting the next page you specify what action it is, in this example the call moves to the page Agent_or_Estimate. + + + +Step 3. Configure Entry Fulfillment for Agent_or_Estimate page. Open up Agent_or_Estimate page, and click Entry Fulfillment. In the Agent response type: Hi $session.params.Name, please let me know if you would like to speak with an agent or if you would to create an estimate? + +Do not forget to Save the change. + +Note: If you cannot copy and paste the suggested fulfillment just start typing in the Agent Response field, then you can paste the text, then delete unnecessary text. + + + +Step 4. Test if the conversation flow is configured properly at this point. Click Test Agent and in the Talk to Agent field type Hello and then type your name. + + + +

    Task 4. Configure Route in Agent_or_Estimate page to move the call to new page What_Kind_Of_Agent.

    + +Step 1. Open up the Agent_or_Estimate page, click on Create New Route, and then click on Create New Intent. + +Note: An intent is a mapping between what a user says or types and a specific action or response that the conversational agent can take. Intents help the agent understand the user request and determine the appropriate response or action to take. + + + +Step 2. Name the Intent Agent_intent. Provide 3-5 training phrases, something like agent, representative, escalate, real person. Do not forget to save the change of the page. + + + +Step 3. Create new page and name it What_Kind_Of_Agent. + + + +Step 4. Click on Agent_or_Estimate page. Add a new Route, select the Intent. + + + +Step 5. On the Routes settings scroll down and select action to move the call to the page What_Kind_Of_Agent. + + + +Step 6. For a better communication experience you need to add no-input-default Event handlers otherwise the system detects no input even before you have a chance to provide input. While on the Agent_or_Estimate page, click on Add state handler, select Event handlers, and click on Apply. + +Note: An Event handlers is a type of intent that is triggered when a specific event occurs. For example, if the Virtual Agent does not receive any input or it does not recognize the input, the event handler is used to trigger no-input intent which helps to continue the conversation. + + + +Step 7. Click on Add New Event handlers, select from the No-input default list and save the change. + + + +

    Task 5. Configure Route for Estimate branch and Connect Agent_or_Estimate to new page Estimate_Details.

    + +Step 1. Create Estimate_Intent. While on Agent_or_Estimate page click the plus icon (+) to add new Route and create new Intent. + + + +Step 2. Name the intent as Estimate_Intent and provide some training phrases. As for the training phrases you can add statements like estimate, price calculation, I need to know how much it cost. Save the intent. + + + +Step 3. Create new page with the name Estimate_Details. Connect Agent_or_Estimate and Estimate_Details pages when Estimate_Intent is triggered. + + + +Step 4. Click the Agent_or_Estimate page. Add new Route, and select the Intent Estimate_Intent. + + + +Step 5. Scroll a bit down and add the agent response that the caller hears once the Estimate_Intent is triggered. You can type something like, let me collect some information for the estimate. + + + +Step 6. Scroll all the way down and select the transaction to the page Estimate_Details once the intent is triggered. Save the page configuration. + + + +

    Task 6. Configure Estimate_Details page with Parameters and Route

    + +Step 1. Similar to how you created the Parameter for the caller name, create the Parameter for the number of agents which the caller needs the estimate for. Click on the Estimate_Details page, add the Parameter, name it Number_of_agents, and select from the list the standard Entity type sys.number. Do not forget to save the change. + + + +Step 2. Configure the Entry Fulfillment for the caller to understand what information the Virtual Agent is looking for. You can type something like, please let me know how many agents you are planning to have in your Contact Center. + +Note: If you cannot copy and paste the suggested fulfillment just start typing in the Agent Responses field, then you can paste the text, then delete unnecessary text. + + + +Step 3. Select the condition which triggers the action on the Estimate_Details page. While on the Estimate_details page, click on add new Route, on the right window scroll down a bit and configure the condition $page.params.status =“FINAL”. + + + +Step 4. Scroll more down and add the Virtual Agent response. Type: I am putting together the estimate request details for $session.params.Number_of_agents agents. + + + +Step 5. Add dialogue option and select Custom payload from the list. + + + +Post this next syntax to the Custom payload section and save the configurations. + +{ + + "Execute_Request": { + + "Data": { + + "Params": { + + "Estimate_Agents_Count": "$session.params.Number_of_agents" + + } + + } + + } + +} + +Note: In JSON data format, a variable is a key-value pair that represents a property of an object. The key is a string that identifies the property, and the value is the data associated with the property. + +The Custom payload contains the key Estimate_Agents_Count and the value is the Parameter $session.params.Number_of_agents. This Parameter is changed depending on the caller response. + + + +Step 6. Scroll more down on the Route section and set up Transition to End Flow. + + + +It terminates the session on the Dialogflow side and transfers the call to WxCC where it continues from the Virtual Agent Handled path. + + + +Step 7. Test your Virtual Agent flow at this point. + + + +

    Task 7. Configure Estimate_Details page with Routes.

    + +Step 1. Create two additional intents, TAC_Intent and Sales_Intent. Click on Manage, select Intents from the Resources list, and then click on Create. + + + +Name the intent and provide some training phrases. For example, for TAC_Intent you can add the phrases like: TAC Engineer, Technical Support. + + + +For Sales_Intent you can specify something like Price, Sales, and so on. + + + +Step 2. Add Route for the TAC queue. Go back to the queue and click on the What_Kind_Of_Agent page. Then click on Add New Route and select the intent you created in the previous step for the TAC queue. Save the route settings. + + + +Step 3. Scroll down and add the agent response that the caller hears once the intent is triggered. + + + +Step 4. Add the dialog option to move the call to the live agent by selecting Live agent handoff. + + + +By selecting this option, the call moves out of the Escalate output of the Virtual Agent V2 block in the flow builder. + + + +Step 5. In the Live agent handoff payload field, you can add the data in the JSON format which you can later parse in the WxCC flow. In this case, you need to add Type_Of_Agent (TAC). TAC which helps you to make the routing decision to the correct queue in the flow. + +{ + + "dialogflow.ccai.live-agent-escalation": { + + "Type_Of_Agent": "TAC" + + } + +} + + + + + +Step 6. End the flow on the Dialogflow side once the call is moved to the WxCC flow. + + + +Step 7. Do the same steps to configure the Route for the Sales queue. Click on Add New Route. Select Sales_Intent and save the Route settings. + + + +Step 8. Add the Agent response and Live agent handoff dialog option. + + + +Step 9. End the flow for this page once the intent is triggered and the call is moved to the WxCC flow. + + + +Step 10. Add the Entry Fulfillment to the What_Kind_Of_Agent page so the caller knows what kind of answer the Virtual Agent expects. Click on the Entry Fulfillment field and type, please let me if you would like to speak with a Technical Support Engineer or you would like to talk about sales. + + + +Step 11. Test your Virtual Agent. + +

    Configure Flow with Virtual Agent in Webex Contact Center Management Portal

    + +

    Objectives

    + +In this section, you can see how to build flow in Webex Contact Center Flow Builder with the Virtual Agent block which moves the call to queue with live agents or to estimate branch where data about the number of agents for the estimate can be extracted and used for Analyzer report. + +

    Task 1. Create new flow.

    + +Step 1. In the Webex Contact Center Admin portal open up the Routing Strategy Module and Create New Flow entry window. + + + +Step 2. Call the flow {Your Name}_Virtual_Agent_Flow. + + + +

    Task 2. Configured Handled path to extract estimate data for the Analyzer report.

    + +Step 1. Move the Virtual Agent V2 to the flow and connect it with the NewPhoneContact block. + + + +Step 2. Click on Virtual Agent V2 block and under the block settings select Contact Center AI Config which you created earlier or use the preconfigured Virtual Agent Dan_User1_Virtual_Agent. Also, click Advanced Settings and increase the Termination Delay time from 3 to 5 seconds. + +Note: Termination Delay is the time range that must be set to allow completion of the audio prompt from the Virtual Agent in Dialogflow before the contacts move to the Webex Contact Center. For example, if in Dialogflow VA config there is a long response before the call goes to Live agent handoff, it cuts the response not finished and the call moves to the queue. + + + +Step 3. (Informational only) Understand how the call-related data is moving from Dialogflow to Webex Contact Center. + +When the conversation is transferred from Dialogflow to WxCC, it creates some output variable with data in JSON format which has been generated in the Dialogflow portal while the caller was interacting with the Virtual Agent. One of the output variables is VirtualAgentV2.MetaData. You can see it by clicking anywhere on the grey area in the Flow Builder and scroll down on the right window. This output variable contains the data you specified in the Custom payload. + + + +The goal here is to extract the information about how many agents the caller requested for the estimate. In the previous section, you have created the parameter with the name Number_of_Agents. + + + +And you configure the Route with Custom payload where once the parameter is filled, the value of the parameter is assigned to the key Estimate_Agents_Count and then the call is moved to WxCC side. + + + +Step 4. Configure Virtual Agent Handled path to extract the estimate data and associate it with Global Variable. By parsing JSON data from the VirtualAgentV2_MetaData variable you can extract the value of the Number_of_Agents parameter value and assign it to the new variable on the WxCC environment. You also want the variable to be reportable, so you need to use a Global Variable. While in WxCC flow builder, cick anywhere on the grey area, and on the right window click on Add Global Variable. + + + +The Global Variable Estimate_Number_of_Agents needs to be created earlier in the WxCC Admin Portal. Then you just need to select it and click Add. This makes this Global Variable available for you to use in your flow. + + + +Step 5. Add the Parse node. In the Parse node select VirtualAgentV2.MetaData as the Input Variable, select from the list the Global Variable you added to the flow in the previous step as the Output Variable, and use this next string to parse the JSON data $.Params.Estimate_Agents_Count. + + + +Step. 6. Use the Play Message node to validate the result and notify the caller. Add the Play Message node, Enable Text-to-Speech feature, select the TTS connector and choose Output Voice from the list. + + + +Step 7. Add Disconnect Contact node. Then click in the Play Message again, and add this Text-to-Speech Message, in the TTS field type, thank you. The estimate request for {{Estimate_Number_of_Agents}} agents was created, and your team can reach out to you soon with the results. + +Delete the Audio File option and publish the flow. + + + +

    Task 3. Configured Escalated to move the call to the appropriate Queue with live agents.

    + +Step 1. Create Flow variable and name it Queue_Routing. + + + +Step 2. Add the Parse node and configure it to assign the value of the Type_Of_Agent variable from Dialogflow to the Queue_Routing flow variable. + + + +Step 3 Add the Case node and configure it with the variable Queue_Routing. In the link, Description configure values TAC and Sales as these are two values you move from the Dialogflow portal. + + + +Step 4. Add Play Message nodes to verify the call goes to the TAC queue. Configure the Play Message node with TTS and type the text similar to this, Thank ou for waiting. The TAC engineer can be with you shortly. + + + +Step 5. Do the same for the Sales queue. Let the caller know that the call can be connected to the Sales agent shortly. + + + +Step 6. Add Queue Contact block and configure it with the TAC_Queue. + + + +Step 7. Add additional Queue Contact and configure it with the Sales_Queue. + + + +Step 8. Point Default output on the Case node to the Play Message related to the Sales Queue. Validate and click Publish the Flow. + + + +

    Task 4. Add the flow to you Entry Point.

    + +Step 1. Go to Entry Points and select your Entry Point. Click on three dots to edit the Entry Point. + + + +Step 2. Select the flow and other required fields and save the Entry Point. + + + +Step 3. Configure Entry Point mapping for your Entry Point. + + + +

    Task 5. Test your configurations.

    + +After all these configurations are completed, call the DN related to your Entry Point and test the integration. + + + + + + + +--- + + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    + +# diff --git a/_pages/CH.md b/_pages/CH.md new file mode 100644 index 0000000000..0f26506250 --- /dev/null +++ b/_pages/CH.md @@ -0,0 +1,423 @@ +--- +title: Lab 1 - Admin Experience +author: Dmitry Bokatov +date: 2022-01-02 +layout: post +--- +``` +Last modified: Wed, 20 Sep 2023 +``` + + + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ------------------------------------------------------------------------------------- | ------------------ | ---------------- | ---------------- | +| [Introduction to the new Admin Experience](#introduction-to-the-new-admin-experience) | Watch & Understand | EASY | 10 min | +| [Control Hub User Management Tasks](#control-hub-user-management-tasks) | Practical Lab | EASY | 10 min | +| [Contact Center User Configuration](#contact-center-user-configuration) | Practical Lab | EASY | 10 min | +| [Bulk Operations](#bulk-operations) | Practical Lab | EASY | 5 min | +| [Access to the Agent Desktop](#access-to-the-agent-desktop) | Practical Lab | EASY | 10 min | +| [Bonus: Single Sign-on with OKTA IdP](#bonus-single-sign-on-with-okta-idp) | Practical Lab (optional) | MID | 15 min | + + +## Overview of the lab: + +In this Lab, we will go through Admin UI by completing the tasks that are required for the general pre-configuration of a tenant. These tasks are to be undertaken by a customer administrator. By following each of the steps, you would have prepared your tenant to begin configuring different services offered by the platform. At the end of the lab, you should be able to log in to an agent interface with the configured user extension. +You can do the tasks from the lab guide either on the **Lab Tenant** (you need to request access from the lab support team) or you can do it directly on your **Gold Tenant** / personal tenant. + +## Introduction + +### Lab Objective + +- This lab is designed to help you do the initial setup and configuration of the tenant. +- The lab contains multiple exercises on Control Hub (Admin Portal) to make you comfortable with the Webex Contact Center application. + +### Pre-requisites + +- You have Admin access to Control Hub +- You have the PSTN number (dialed number) registered on the Control Hub + +### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com){:target="\_blank"}**\ +> Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com){:target="\_blank"}**\ + +## Lab Section + +# Introduction to the new Admin Experience + +> The overall aim of admin consolidation is to provide a single pane of glass (SPOG) experience for administrators so that admins need not have frequent context switch by having to traverse different applications. The following video outlines the new features of a new admin experience. This introduces, the new left navigation panel for Webex Contact Center in Control Hub as well as other configuration settings which were migrated from the Management Portal. + + + +
    + +
    + + +# Control Hub User Management Tasks + +> The following video outlines the process to manage different types of users to the Customer tenant. Following the steps, you will add new users and set the Calling extension. While adding the user, we will see how to select user roles. + +
    + +
    + + + +### 1. Define your Attendee ID and Other parameters + +>Please **SKIP task #1** if you are doing the labs on the **Gold Tenant**. The task below is only for the **Lab Tenant** option where you have received an email with the Lab tenant credentials. In a such case, please copy and paste the Attendee ID number from the email into the corresponding field (Example: IDXXX). +{: .block-tip } + +
    + + +
    + +
    + + +
    + + + + +### 2. Add agent and supervisor users and set the calling extensions + +> We don't recommend using the @maildrop.cc or @mailinator.com accounts on your **Gold Tenant** due to security reasons. An attacker can easily gain access to your tenant and execute the outbound calls. +{: .block-warning } + +> - As a result of the task below you should add two new users (agent and supervisor) to the Control Hub and assign Webex CC Agent and Supervisor licenses. +> - Please **SKIP task #2** if you are working with the **Lab Tenant**. This tenant is integrated with SSO where the agents and supervisors have been pre-created according to the table below. +{: .block-tip } + + + + +| **User Role** | **User email** | **Endpoint** | +| ------------- | ----------------------------------------------------------------------------- | ------------- | +| Agent | wxcclabs+agent_AttendeeID@gmail.com | WebRTC | +| Supervisor | wxcclabs+supvr_AttendeeID@gmail.com | Webex App | + + +- Login to the [Control Hub](https://admin.webex.com){:target="\_blank"} with the admin account. + +- In the left navigation pane go to **_Users_** under **Management**. + +- Click on **_Manage Users_** button. + +- Select **_Manually add users_**. + +- Set the agent's **First name**, **Last name** and input the **Email addresses** of the agent. + +- Click on `+` sign and add the supervisor in the same way. + +- For consistency, verify that the **Email addresses** are same as in the table above and click **_Next_**. + +- In **Step 2: Assign license for users** select **_Webex Calling (Professional)_** & **_Contact Center (Premium Agent)_**. + +- On the next page, make sure that the **_Location_** is selected under **_Assign Numbers_**. The correct value should be already selected by default. + +- The **_Phone Number_** left as **None**. + +- On the same page, Enter the correct `Extension` under **_Assign Numbers_**. The correct Extensions should be provided to you with the admin credentials. + +- In step **Step 4: Review** verify the data and Click **_Add users_**. + +- On the next page, you should get confirmation **"2 users added"**. Confirm the same by pressing **_Close_**. + +- Now select the supervisor user and modify his role to **_Premium Agent - Supervisor Role_** by clicking the **_Edit Licenses_** button in the **_Licenses_** section. + +- Click **_Save_** and **_Close_** to confirm the changes. + +- Validate the users by going to the email account. Open the Control Hub validation email and follow the **Cisco Webex** instructions to activate the both accounts. + +- Refresh the **_Users_** page in the Control Hub, make sure that both users are in **Active** status. + +# Contact Center User Configuration + +> The following video outlines how to create a Site, Team, and Multimedia Profile that will be assigned to the Contact Center users. We will also learn how to navigate to the Webex Contact Center admin section and how to associate customer-created Site, Team, and Multi-Media Profile with new users. + +
    + +
    + +| **Entity** | **Name** | +| ------------------- | ------------------------------------------------------- | +| Multimedia Profiles | Your_Attendee_ID_MMP | +| Site | Your_Attendee_ID_Site | +| Team1 | Your_Attendee_ID_Team1 | + + + +> **NOTE:** If you are using the **Lab Tenant** the **Attendee ID** should be used as a name prefix for all your configurations. +> {: .block-tip } + +### 1. Create new Multimedia Profile + +- Login with admin credentials to Control Hub by accessing [https://admin.webex.com](https://admin.webex.com){:target="\_blank"}. + +- In the left pane navigate to **_Contact Center_** card. + +- Click **_Settings_** in the upper menu. + +- Scroll down in the left navigation panel to the **_DESKTOP EXPERIENCE_** section and click on **_Multimedia Profiles_**. + +- Click on `Create Multimedia Profile` button. + +- Input Name as **Your_Attendee_ID_MMP**. + +- In the Media Details section, leave the **Blended** mode and input `1` for **_Voice_**, `3` for **_Chat_**, `3` for **_Email_**, `3` for **_Social_**, and click **_Create_** button in the lower right corner. + +### 2. Create new Site + +- Navigate to **_USER MANAGEMENT_** in the left navigation panel and select **_Sites_**. + +- Click on `Create Site` button and provide the Name as **Your_Attendee_ID_Site**. + +- Select your MMP in the **_Multimedia profile_** drop down list and hit **_Create_**. + +### 3. Create new Team + +- Navigate to **_Teams_** under the **_USER MANAGEMENT_**. + +- Click on `Create Team`. + +- Input _Name_ as **Your_Attendee_ID_Team1**. + +- Select your site from the **_Parent Site_** drop-down. + +- Select the **_team type_** `Agent Based`. + +- Select your **_Multimedia profile_**. + +- Left as a default value **_Global Layout_** in the **_Desktop layout_** drop-down and click on **_Create_** button. + +### 4. Activate the Contact Center Settings for the users + +- Navigate to **_Contact Center Users_** under the **_USER MANAGEMENT_**. + +- Using Search, find your attendee ID and select the agent, to launch the **_Edit_** view for a particular User configuration. + +- Click on **_Contact Center Enabled_** toggle to move it to **_On_**. + +- In the **_Agent Settings_** section, select your site in the **_Site_** drop-down. + +- Click the **_Teams_** area and select your team + +- Select the default **_Agent-Profile_** in the **_Desktop Profile_** drop-down list. + +- Choose the **_Multimedia Profile_** and hit **_Save_**. + +- In the User's table make sure that the agent is now shown with the **_Contact Center Enabled_** flag as `Yes` and **_Status_** as `Active`. + +- Repeat the steps above for the supervisor. + +### 5. Use that form for providing the Admin UI feedback. + + + +# Bulk Operations + +> In this section you will learn how to use the Bulk Configuration in Control Hub by creating a second team. As an administrator, you can use Bulk Operations to create, modify, import, or export configuration objects in Webex Contact Center. This feature provides greater speed and efficiency to deploy and configure Webex Contact Center systems. + +Bulk Operations are available for the following configuration object types: + +| ------------------- | -------------------- | +| ------------------- | -------------------- | +| Entry Point | Auxiliary Code | +| Queue | Agent Profile | +| Outdial Entry Point | Address Book | +| Outdial Queue | Outdial ANI | +| Site | Skill Definition | +| Team | Skill Profile | +| Users | Entry Point Mappings | +| User Profiles | Audio Files | +| Work Types | Global Variable | + + + + +### Create the second Team + +- Go to the Control Hub by accessing [https://admin.webex.com](https://admin.webex.com){:target="\_blank"}. + +- In the left pane navigate to **_Contact Center_** card. + +- Select **_Bulk Operations_** in the Webex CC navigation pane from the left. + +- Click **_Create Bulk Operations_** button in the right upper corner. + +![Bulk Menue](/assets/images/Bulk-1.gif) + +- In Step 1 select the configuration object **_Team_** in the drop-down list. + +- In the Export section enter the **MyTeam** as the file name and click **Next** button. + +- Once the task is **Completed** click on **_Download export file_** button under the **Action** and open the csv file in the notepad. + +- The first line is the headers, it is mandatory to have it during the import process. Remove all lines from the CSV file except the first line with headers and the line with **Your_Attendee_ID_Team1**. + +```csv +NAME,SITE,TYPE,MULTIMEDIA PROFILE,SKILL PROFILE,DN,CAPACITY,DESKTOP LAYOUT +xxxx_team1,pod110_Site,AGENT,pod110_MMP,,,,Global Layout +``` + +- Rename the Team1 to **Your_Attendee_ID_Team2** and save the file. You should have only 2 rows in the file. + Example: + +```csv +NAME,SITE,TYPE,MULTIMEDIA PROFILE,SKILL PROFILE,DN,CAPACITY,DESKTOP LAYOUT +xxxx_team2,pod110_Site,AGENT,pod110_MMP,,,,Global Layout +``` + +- Go back to the **Bulk Operations** menu and click **_Create Bulk Operations_** button again. + +- In step 1, select the **_Team_** configuration object from the drop-down list and **import** the CSV file by dragging it into the Import section. + +- Click **Next** button and wait the results. The status should be shown as **Completed**. + +- Go to the Management Portal, click on **_Provisioning_** -> **_Team_** and verify that the **Your_Attendee_ID_Team2** is created. + +- In the Management Portal directly associate the **Your_Attendee_ID_Team2** with your agent and supervisor by adding your users to that team (__Advanced Settings -> Agents__). + + +# Access to the Agent Desktop + +> By following the steps below, you will log in to the Agent Desktop with your credentials and indicate the number (DN) where you want to receive the calls. + +> The Lab Tenant is located in the US datacenter. It does not allow outbound international calls. If you have the U.S. numbers you can use that for sign in as an agent or supervisor. Otherwise, please WebRTC for agent and download the Webex App for supervisor according to the steps below. +{: .block-warning } + +### 1. Download and Login in the Webex app for PC or Mac + +>Please **SKIP task #1** if you are doing the labs on the **Gold Tenant**. + +> For the **Lab Tenant** you would need Webex app for placing calls to Entry Point and sign in as supervisor. Alternatively, if you have the US number, you can use it as an supervisor's extension. This tenant does not allow numbers outside of the United States. In this lab, we will use the Webex app for your PC or Mac for the **supervisor** account. +{: .block-warning } + +- Download the Webex app from **[https://www.webex.com/downloads.html](https://www.webex.com/downloads.html){:target="\_blank"}**. + +![Webex App](/assets/images/Lab1-AD-1.png) + +- Install the application on your PC/Mac. + +- Open Webex app and сlick **Sign In**. Specify the supervisor credentials. + + +### 2. Agent Desktop Login + +> **Note**: To log in to the agent desktop, use either a different web browser or a new incognito web page. This will prevent the browser caching issues with admin and agent credentials. +> Depending on your tenant's location the agent ULR link can be different. The example below is for the tenant in the US datacenter. +{: .block-tip } + +- Navigate to **[https://desktop.wxcc-us1.cisco.com/](https://desktop.wxcc-us1.cisco.com/){:target="\_blank"}** in the chrome browser with the incognito mode. + +- Enter the agent’s **email ID** which you created in the previous task. + +- Enter the **Password** for the appropriate username. + +- In the **_Station Credentials_** pane, select **"Desktop"**. + +- Select the team **Your_Attendee_ID_Team1**. + +- Click **_Submit_** button. The browser may ask you to confirm use the microphone from the browser. + +- Make sure that you are successfully logged in to the Agent Desktop. + +![Agent Sign In](/assets/images/AG-2.gif) + + + + + +Now you can continue with Lab 2 or try the bonus SSO task below. + +# Bonus: Single Sign-on with OKTA IdP + +> **NOTE:** Please skip this task If you are using the **Lab Tenant**, this task can be configured only on your Gold Tenant. Inform other users on your tenant since the non SSO accounts will be deactivated. +> + +>In this section you will learn how to enable Single sign-on (SSO) in Control Hub. It enables users to sign in to Webex securely by authenticating to your organizations common identity provider (IdP). The Webex App uses the Webex service to communicate with the Webex Platform Identity Service. The identity service authenticates with your identity provider (IdP) +{: .block-warning } + +- From the customer view in [https://admin.webex.com](https://admin.webex.com/), go to Management > Organization Settings, and then scroll to Authentication, and then toggle on the Single sign-on setting to start the setup wizard. + +- Select SAML as the identity provider and click Next. + +![SSO1](/assets/images/SSO/1.png) + +- Choose the self signed by Cisco certificate and download the metadata and click Next. + +![SSO2](/assets/images/SSO/2.png) + +- Sign in to the Okta Tenant (example.okta.com, where example is your company or organization name) as an administrator, go to Applications, and then click Browse App Catalog. Search for "Cisco Webex" and add the application to your tenant. + +![SSO4](/assets/images/SSO/4.png) + +- Click Next and then click SAML 2.0. + +- In your browser, open the metadata file that you downloaded from Control Hub. Copy the URLs for the **entityID** (at the top of the file) and the **assertionConsumerService location** (at the bottom of the file) + +![SSO5](/assets/images/SSO/5.png) +![SSO6](/assets/images/SSO/6.png) + +-On the **Cisco Webex** tab in Okta, click on **Sign On** and then click on edit.Scroll to **Advanced Sign-on Settings**, and then paste the Entity ID and Assertion Consumer Service values that you copied from the Control Hub metadata file and then save changes. + +![SSO7](/assets/images/SSO/7.png) + +- Click **Sign On** and then download the Okta metadata file. You'll import this file back into your Control Hub instance + +![SSO8](/assets/images/SSO/8.png) + + +- Click **Assignments**, choose all the users and any relevant groups that you want to associate with apps and services managed in Control Hub, click **Assign** and then click **Done**. + +![SSO9](/assets/images/SSO/9.png) + +- Return back to Contro Hub.If Control Hub is no longer open in the browser tab, from the customer view in [https://admin.webex.com](https://admin.webex.com/), go to Management > Organization Settings, scroll to Authentication, and then choose Actions > Import Metadata + +- On the Import IdP Metadata page, either drag and drop the IdP metadata file onto the page or use the file browser option to locate and upload the metadata file. Click Next. + +![SSO10](/assets/images/SSO/10.png) + - At the next page just click Next + +- Select **Test SSO setup**, and when a new browser tab opens, authenticate with the IdP by signing in. + +![SSO12](/assets/images/SSO/12.png) + + +- Return to the Control Hub browser tab. If the test was successful, select Successful test. Turn on SSO and click Next. + +![SSO13](/assets/images/SSO/13.png) + +***Congratulations! You have successfully turned on SSO for your tenant*** + + +--- + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    diff --git a/_pages/CRM.md b/_pages/CRM.md new file mode 100644 index 0000000000..7bd4c7f563 --- /dev/null +++ b/_pages/CRM.md @@ -0,0 +1,903 @@ +--- +title: Lab 6 - CRM Integration +author: Neha Wuthoo & Pawan Kumar & Arunabh Bhattacharjee +date: 2022-06-06 +layout: post +--- +``` +Last modified: Wed, 3 May 2023 +``` + +## Introduction + +### Lab Objective + +This lab covers Webex Contact Center Agent Desktop integration with the most popular CRM solutions (Salesforce, Microsoft Dynamics 365, Service Now and Zendesk) which allows you to launch the Agent Desktop from within the CRM, providing an integrated Agent Experience for both inbound and outbound calls. + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ------------------------------------------------------------------------- | ------------- | ---------------- | ---------------- | +| [Salesforce integration](#salesforce-integration) | Practical Lab | MID | 35 min | +| [Microsoft Dynamics 365 integration](#microsoft-dynamics-365-integration) | Practical Lab | MID | 30 min | +| [Service Now integration](#service-now-integration) | Practical Lab | MID | TBD | | +| [Zendesk integration](#zendesk-integration) | Practical Lab | MID | 25 min | + +# Salesforce integration + +### Pre-requisites + +1. Administrator access to the organization on [Control Hub](https://admin.webex.com/) and [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/). +2. An agent account with access to [Agent Desktop](https://desktop.wxcc-us1.cisco.com/). +3. Salesforce instance. For the details, refer the next section [Create Salesforce Account](#optional-create-salesforce-account). +4. Access to the [Webex Contact Center Desktop Layout for Salesforce](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/Salesforce) JSON. +5. Lab 2 (IVR Contact Routing) completed. + +## Optional: Create Salesforce Account + +
    + +
    + +
    + +- Navigate to Salesforce Developer [Signup Page](https://developer.salesforce.com/signup). + +- Complete the form with your personal details and click on **Sign me up** to create your account. + +> **Note:** Username needs to be in the form of an e-mail address. This address does not need to be a real e-mail address. + +- Go to your e-mail inbox and wait for the confirmation e-mail regarding your account. Click on **Verify Account** in the confirmation email. + +- Set up your Salesforce account **password** and **security question**. This will successfully create your account and log you in the Salesforce platform. + +## Part 1: Connector Installation + +
    + +
    + +### Connector Installation From Salesforce AppExchange + +- Login to your [Salesforce](https://login.salesforce.com) instance and go to **Setup**. + +- In the search box, type `AppExchange Marketplace`. + +- In the AppExchange Marketplace type `Webex Contact Center for Salesforce`. + +- Click on the Webex Contact Center App and then click on **Get It Now**. + +- On the pop-up window, click on **Open Login Screen**. If prompted, login again with your credentials and **Allow** access to the `appx_api`. + +- After verifying your login, choose the **Intall in This Org** option. + +- Fill in the required fields with your details and accept the **Terms and Conditions** check box to be able to proceed with installation. + +- Choose **Install for All Users** option and then click on **Install**. + +- If asked, grant access to third party web site `_cpc.ccone.net_` by clicking on the checkbox and then click on **Continue**. + +- After the installation is completed, click **Done**. + +### Connector Installation Verification + +- In Salesforce, navigate to **Setup**. + +- In the search box, type `Installed Packages`. + +- In the Installed Packages list, check for **Webex Contact Center**. + +- If found, then installation was successful. + +## Part 2: Call Center Configuration + +
    + +
    + +### Salesforce Call Center Configuration + +- In Salesforce, navigate to **Setup**. + +- In the search box, type `Call Centers` and click on **Continue**. + +- Click the **Edit** link corresponding to the **Webex Contact Center Agent Desktop** to edit the Call Center Configurations. + +- Update the **Display Name** field, if you want to change the Display name of the call center. + +- Configure the CTI Adapter URL with the Agent Desktop URL. Use the relevant data center. + e.g. - https://desktop.wxcc-us1.cisco.com/ . + +- Click **Save** + +### Adding Call Center Users To Salesforce Call Center Application + +- Open the Call Center Definition file again (not in Edit mode). Just click on the Call Center File name. + +- At the bottom of the page, click on **Manage Call Center Users** to open the Manage Users page. + +- Click on **Add More Users** button to add users to the Call Center application. + +- On the **Search for New Users** page, either apply filters to find specific Call Center users or click on **Find** to list all the available users. + +- Select your user from the list and click on the **Add to Call Center** button. + +- You will be redirected to the **Manage Users** page, where your user should now be listed. + +## Part 3: Softphone & Task Layouts + +
    + +
    + +### Create Salesforce Softphone Layout Configuration + +- In Salesforce, navigate to **Setup**. + +- In the search box, type `Softphone Layout` and click on **Continue**. + +- Click on the **New** button to open the **Softphone Layout Configuration page** and create a softphone layout to use as `default`. + +- Enter a `Name` for the Softphone Layout Configuration. + +- Select the **Is Default Layout** checkbox to make this Softphone layout default for all the call center application. + +- On the **Display these salesforce.com objects**, remove `Lead` from the selections and add `Case`. + +- On the **Screen Pop Settings**, choose `Don't pop any screen` for **No matching records**, `Pop detail page` for **Single-matching records** and `Pop to search page` for **Multiple-matching records**. + +- Click **Save** to create the Softphone Layout configuration. + +- In the Call Center Configuration file, make the changes (if required) under **Screenpop Settings** (for No Matching Records) as per the business use-case. + +### Salesforce Softphone Layout Assignment + +- If not already there, in the search box type `Softphone Layout` and click on **Continue** to reach the Softphone Layout page. + +- Click on the **Softphone Layout Assignment** Button, it opens the Softphone Layout Assignment page. + +- Assign the Softphone Layout configuration you created to the **System Administrator** or your user profile. + +- Click **Save** to assign the Softphone Layout. + +### Salesforce Task Layout Configuration + +- In Salesforce, navigate to **Setup**. + +- In the search box, type `Object Manager` and click on it. + +- Filter the list page by typing `Task` in the **Quick Find** search box and click on the **Task** button link. + +- Select **Page Layouts** on the left of the Task details page. + +- Click on **Page Layout Assignment** on top-right and then on **Edit Assignment**. + +- Select the **System Administrator** profile or your user profile from the displayed list in the Profiles column. + +- Select the **Webex Contact Center Task Layout** from the **Page Layout To Use** drop-down list on top. + +- Click **Save** to assign the Custom Task Layout. + +## Part 4: Reports + +
    + +
    + +### WebexCC Salesforce Desktop Report View + +- In Salesforce, click **App Launcher** on top left and then choose **Webex Contact Center**. + +- From the Navigation Apps drop-down list, select **Reports**. + +> **Note:** If Reports is not listed, click **Edit** > **Add More Items** and add the **Reports**. + +- To see all the existing reports, click **All Reports**. + +> **Note:** There is a default call activity report that is configured alongwith Webex Contact Center app installation. + +## Part 5: WebExCC Salesforce Desktop Layout + +
    + +
    + +### WebexCC Salesforce Desktop Layout Configuration + +- Download the latest Custom Desktop Layout file from the [Github Repo](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/Salesforce) + +- Save it on your machine as JSON file. + +- Login to [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/portal/home.html). + +- Go to **Provisioning** > **Desktop Layout** > **New Layout**. + +- Enter Name and Description for the desktop layout. + +- Add the **Teams** to the Desktop layout. Only the agents associated with that team will get the Salesforce Desktop Layout. + +- Upload the custom desktop layout file saved earlier. + +- Click **Save**. This will create a Custom Desktop Layout in Webex Contact Center. + +## Part 6: Test Webex Contact Center Agent Desktop for Salesforce + +### Call Center Definition File - Advanced Configurations + +
    + +
    + +
    + +- This document covers customization of each field of call center definition file, its description and possible values : + [Integrate Webex Contact Center with Salesforce](https://help.webex.com/en-us/article/nhxw7kfb/Integrate-Webex-Contact-Center-with-Salesforce#Cisco_Reference.dita_053158ba-52cb-437e-9243-64d28a3c9845) + +### Login to Salesforce Agent Desktop and Make a Test Call + +
    + +
    + +- On Salesforce page, click on **App Launcher** icon on top left and then click on **Webex Contact Center**. + +- On the bottom left, click on **Phone** and then on **Sign In**. + +- Sign in to Webex Contact Center Agent Desktop using agent credentials. This agent user needs to be part of the same team with which we had associated the Desktop Layout previously. + +- Make sure the agent is in available state and make a test call to your EP. + +- Upon accepting the call, you should be able to see a screenpop as per the configurations in the Call Center Definiton file. + +- A Phone Call Activity Record will be created for every call and will be associated with the Salesforce Record. + +# Microsoft Dynamics 365 integration + +### Pre-requisites + +1. Administrator access to the organization on [Control Hub](https://admin.webex.com/) and [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/). +2. An agent account with access to [Agent Desktop](https://desktop.wxcc-us1.cisco.com/). +3. An MS Dynamics Sales instance. For the details, refer the next section [Start Microsoft Dynamics Trial](#optional-start-microsoft-dynamics-trial) +4. Access to the [Webex Contact Center Desktop Layout for Microsoft Dynamics](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/MS%20Dynamics) JSON. +5. Lab 2 (IVR Contact Routing) completed. + +## Optional: Start Microsoft Dynamics Trial + +### Step 1 : Create Dynamics 365 Sales account + +
    + +
    + +- Navigate to [Dynamics 365 Free Trial](https://dynamics.microsoft.com/en-us/dynamics-365-free-trial/) website + +- Scroll down and click on **Try for free** under "Dynamics 365 Sales". + +- Enter your email address at "Let's get started" page and press **Start your free trial** button. + +> **Note:** If there is a notification about using work account, click on **set up** link to create new account. Then follow the wizard. + +- To verify your email address, click **Next**. + +- In the next window, click **Create account**. + +- Create a password and click **Next**. + +- Create a password and click **Next**. + +- Enter the security code that you have received in your email to verify and click **Next**. + +- Complete the form with your personal details and click **Next** to continue. + +- Complete the next form with your organization details and click **Save**. + +- Next, enter any random number when asked for "Tax ID or PAN registeration number" and click **Save**. + +- On the next page, click on **Launch Trial** to open your Dynamics 365 trial account. + +> **Note:** Do not log out / refresh the browser at this point (without getting Microsoft-created user account details). + +### Step 2 : Get Microsoft-created user account details and Login to Power Platform Admin center + +
    + +
    + +- In your Dynamics 365 trial account, click on the gear icon on the top right corner to go to **Settings** and then select **Personalization Settings** from the list. + +- In the pop-up window, scroll down to the end and click on **user information** hyperlink. This will open user details in a new browser window. + +- Copy and save the **User Name** displayed on that page. This user is created by microsoft and has microsoft domain added in the user name. + +> **Note:** If you see your email ID in the user name, wait for sometime. It may take upto 20 minutes to update the Microsoft-created user details there. + +- Next step is to Sign in to [Power Platform Admin Center](https://admin.powerplatform.microsoft.com) with the user name we got from the last step and click **Next**. + +- Since we do not have the password of this user yet, click **Forgot my password** and follow the wizard to create a new password. + +- After creating the new password, click on **Sign in with your new password** + +- Enter the user name and password to login to **Power Platform Admin center** + +- Click on **Environments** from the left side navigation bar. You should be able to see a **Sales Trial** environment created with the Type - **Trial (subscription-based)** + +> **Note:** If you do not see Trial (subscription-based) enviornment created, follow the below steps to create one : +> +> - Under **Environments**, click on **New** button on the top. +> - In "New environment" dialog enter "Name", choose "Region", "Type" should be "Trial (subscription-based)" and press **Next**. +> - Choose "Language", "Currency". **Toggle Dynamics 365 apps to enable it.** Do not choose any apps to automatically deploy and press **Save** to create an environment. +> - Use **Refresh** button at the top of "Environments" page and wait untill the status of new envornment is changed to "Ready". + +## Part 1: Install applications for MS Dynamics 365 environment + +
    + +
    + +### Install Channel Integration Framework from AppSource + +- Sign into [Microsoft Power Platform Admin Center](https://admin.powerplatform.microsoft.com). + +- Go to "Environments" and click on the environment named **Sales Trial**. + +- Click on **Dynamics 365 apps** link under "Resources" section of your environment. + +- Click on **Open AppSource** at the top of the apps page. + +- Search for "channel" on the AppSource page and choose **Dynamics 365 Channel Integration Framework** from the list. + +- Press **Get it now** button on the app page to install it. + +- Sign into AppSource if needed using your username (with microsoft doamin in it). Then press **Get it now** on the app page one more time. + +- Choose the "Sales Trial" environment, tick both checkboxes and press **Install** button to start the installation. + +- Use **Refresh** button at the top of "Dynamics 365 apps" page and wait untill the status of "Dynamics 365 Channel Integration Framework" app is changed to "Installed". + +### Install Cisco Webex Contact Center for Microsoft Dynamics from AppSource + +- Click on **Open AppSource** at the top of the apps page one more time in order to navigate to AppSource. + +- Search for "webex" on the AppSource page and choose **Webex Contact Center for Microsoft Dynamics** from the list. + +- Press **Get it now** button on the app page to install it. + +- Select an environment, tick both checkboxes and press **Install** button to start the installation. + +- Use **Refresh** button at the top of "Dynamics 365 apps" page and wait untill the status of "Cisco Webex Contact Center for Microsoft Dynamics" app is changed to "Installed". + +## Part 2: Configure applications for MS Dynamics 365 environment + +
    + +
    + +### Configure Channel Integration Framework + +- Sign into [Microsoft Power Platform Admin Center](https://admin.powerplatform.microsoft.com). + +- Go to "Environments" and click on the environment named **Sales Trial** + +- Click on **Open Environment** at the top of the environment page. + +- Choose **Channel Integration Framework** on the page with published apps. + +- Press **New** button at the top of "Channel Providers" page to create a new channel provider. + +- Complete channel provider configuration by providing the following details: + +| Parameter Name | Parameter Value | +| ----------------------------- | ---------------------------------- | +| Name | Webex Contact Center | +| Label | Webex Contact Center | +| Channel URL | https://desktop.wxcc-us1.cisco.com | +| Enable Outbound Communication | Yes | +| Channel Order | 1 | +| API version | 1.0 | +| Trusted Domain | https://desktop.wxcc-us1.cisco.com | + +- Select "Customer Services Hub" as Unified Interface Apps for the Channel. + +- Select the relevant roles for the channel. + +- Press "Save & Close" button at the top of the page to save changes. + +### Create Custom Desktop Layout file + +
    + +
    + +- Sign into [Microsoft Power Platform Admin Center](https://admin.powerplatform.microsoft.com). + +- Go to "Environments" and click on the environment named **Sales Trial** + +- Note down the "Environment URL" under "Details" section. For example: **https://org2a50d69e.crm11.dynamics.com/**
    + We will need it while creating Custom Desktop Layout JSON file. + +- Navigate to [MS Dynamics Layout](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/MS%20Dynamics) page. + +- Click on "MSDynamics_Desktop_xxxxx.json" file. Copy the contents of the file, paste it in any text editor. + +- Find "hostname" key and replace the value of this key by Environment URL which you noted before. For example: + +``` +"hostName":"https://org2a50d69e.crm11.dynamics.com/" +``` + +- Save the file with .json extension. For example, **MSDynamics_Desktop.json** + +### Upload Custom Desktop Layout to Webex Contact Center Management Portal + +- Sing into [Webex Contact Center Managemnt Portal](https://portal.wxcc-us1.cisco.com/) of your lab pod. + +- Go to **Provisioning** -> **Desktop Layout** and press **New Layout** button. + +- Enter layout name (for example, "MS Dynamics 365"), press "Upload" and choose JSON file you have created above. Once file is uploaded, make sure it is validated successfully. + +- Click on "Teams" row and choose one or more teams. + +> **Note:** The agent you will use to test the integration with Dynamics 365 must be the part of the team chosen above. + +- Press **Save** to create the layout. Once layout is created make sure it is "Active". + +### Update Security Policy on Control Hub + +- Sign into [Webex Control Hub](https://admin.webex.com/) of your lab pod. + +- Go to **Contact Center** -> **Settings** -> **Security** and scroll down to "Content Secuity Policy Allowed List". + +- If the **\*.dynamics.com** value is not added, paste it into the text field and press **Add** button. Make sure the value has been added. + +## Part 3: Test Webex Contact Center Agent Desktop for MS Dynamics 365 + +
    + +
    + +### Sign into Webex Contact Center for Microsoft Dynamics 365 + +- Sign into [Microsoft Power Platform Admin Center](https://admin.powerplatform.microsoft.com). + +- Go to "Environments" and click on the environment named **Sales Trial** + +- Click on **Open Environment** at the top of the environment page to see the list of published apps on the Apps page. + +> **Note:** If you are forwarded to Channel Integration Framework page intead of Apps page, just click on **Channel Integration Framework** link at the top of the page near "Dynamics 365" title. Then you will see Apps page with the list of published apps. + +- Click on "Customer Service Hub" app and you will be redirected to Dashboards tab of Customer Service Hub. + +- Click on the icon on the right side bar to open the embedded **Webex Contact Center** app inside the Dynamics CRM. + +- Press **Sign In** button and provide agent credentials in a new browser tab. + +- Once authentication is completed, provide "Dial Number" / "Extension" and choose the proper team within "Webex Contact Center" app. + +> **Note:** This team must have the Custom Desktop Layout for Dynamics 365 applied in Webex Contact Center Management Portal in the previous part of this lab. + +- Make agent "Available" by selecting corresponding state. + +### Create new contact record in MS Dynamics + +> **Note:** You may create new contact record in Dynamics 365 to test the scenario when calling number matches phone number of the contact. + +- Go to "Contacts" tab of Customer Service Hub and press "New" button at the top to create new account. + +- Complete contact form with the details: + + - First Name + - Last name + - Mobile Phone (please enter calling number which you will use to make test call to Webex Contact Center later) + +- Press "Save & Close" button to save the contact. + +### Make inbound test calls + +
    + +
    + +- Initiate a call from the calling number which matches the one configured under new contact created on the previous step. + +- Answer the call by the agent. You should see the screen pop with the details of new contact created above. + +- Answer the call and wait few seconds. Then hang up and wrap-up the call. + +- You should see an activity record created with call details captured within MS Dynamics. “Call From” must be pre-populated with contact name. + +- Initiate one more call from calling number which does not match any contact in MS Dynamics and compare the behavior. + +- Answer the call by the agent. You should see the screen pop with "No results found" notification. + +- Answer the call and wait few seconds. Then hang up and wrap-up the call. + +- You should see an activity record created with call details captured within MS Dynamics. “Call From” must be empty. + +- Go to "Activities" and you should see both records created after the calls. + +# Service Now integration + +### Pre-requisites + +1. Administrator access to the organization on [Control Hub](https://admin.webex.com/) and [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/). +2. An agent account with access to [Agent Desktop](https://desktop.wxcc-us1.cisco.com/). +3. Service Now instance. For the details, refer the next section [Start Service Now Trial](#optional-start-service-now-trial). +4. Access to the [Webex Contact Center Desktop Layout for Service Now](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/ServiceNow) JSON. +5. Lab 2 (IVR Contact Routing) completed. + +> ##### NOTE : +> +> This lab is for Developer Instances only. For Licensed Instances, please refer : +>
    https://help.webex.com/en-us/article/54vvw/Integrate-Webex-Contact-Center-with-ServiceNow >> Integrate tab >> Install ServiceNow for licensed enterprise instances. +> {: .block-tip } + +## Optional: Start Service Now Trial + +
    + +
    + +
    + +- Navigate to [Service Now Developer Portal](https://developer.servicenow.com). + +- Click on **Sign up and Start Building**. + +- Fill the form with requested information. Accept the **Terms and Conditions** check box and click on **Sign Up**. + +- Verify the account by clicking on the verification link received on the email. + +- Now, login to the developer portal. + +- Click on **Request Instance** button and select the appropriate region to request for a Personal Development Instance (PDI). + +- You will be on waitlist for the instance. You will get an email once an instance is assigned to you. + +## Part 1: Install the OpenFrame Interface + +
    + +
    + +- Sign in to your ServiceNow developer portal. + +- From the **Filter navigator** at the upper left side of the window, navigate to **Plugins**. + +- Scroll down and search for **Openframe** plugin. + +- Click on **Install** button to install the Openframe plugin. + +- In the Activate Plugin dialog box, click on **Activate** button. + +- Once the plugin activation is completed, click on **Close & Reload Form** button. + +- To verify the plugin activation, from the **Filter navigator** at the upper left side of the window, search for OpenFrame. + If you are able to see OpenFrame >> Configurations listed there, the plugin installation is verified. + +## Part 2: Commit the Update Set & Edit System Properties + +
    + +
    + +### a. Commit the Update Set + +- Navigate to [Github page](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/ServiceNow) to download the latest System Update Set XML file. + +- Save the file **webexcc-servicenow-update-setv(X).xml** on your machine. + +- On your ServiceNow Developer Instance, from the **Filter navigator** at the upper left side of the window, navigate to System Update Sets >> **Update Sets to Commit**. + +- Click the **Import Update Set from XML** link. + +- Click **Choose File**, select the System Update Set XML file saved from the previous step, and click on **Upload**. + +- The update set appears in the Retrieved Update Sets list and is in the Loaded state. Click the **Update Set File Name (link)** to open the Update Set. + +- Click **Preview Update Set** to check the update set for any issues. + +- Click **Close** on the dialog box once preview is completed. + +- Click on **Commit Update Set**. + +- Click **Close** on the dialog box once Update Set Commit is completed. + +### b. Edit System Properties + +- In the **Filter navigator** at the upper left side of the window, type **sys_properties.list** and press enter. + +- On the System Properties page, search for **agentdesktop_url** and click on it to open. + +- In the value field, enter the URL for the **Webex Contact Center Agent Desktop** according to the region of operation. + + - North America: https://desktop.wxcc-us1.cisco.com + - UK: https://desktop.wxcc-eu1.cisco.com + - EU: https://desktop.wxcc-eu2.cisco.com + - APJC: https://desktop.wxcc-anz1.cisco.com + +- Click on **Update** to save the changes. + +### c. Optional : Change the Activity Table Name + +- In the **Filter navigator** at the upper left side of the window, type **sys_properties.list** and press enter. + +- On the System Properties page, search for **webexccactivitytable** and click on it to open. + +- Change the value field as required. Click on **Update** to save the changes. + +### d. Optional : Add User Groups + +- In the **Filter navigator** at the upper left side of the window, navigate to **Groups** under System Security. + +- Create a new user group or use an existing one. + +- Click on the User Group Name to open it. Click on **Edit** button. + +- Search for **sn_openframe_user** under Collection and move it to your user group. + +- Click on **Save**. + +## Part 3: OpenFrame Configurations and Service Now Desktop Layout setup + +
    + +
    + +### a. OpenFrame Configurations + +- From the **Filter navigator**, navigate to OpenFrame >> Configurations. +- Click **New**. +- Enter the following values in the form: + +| Parameter Name | Parameter Value | +| -------------- | ---------------------------- | +| Name | Webex Contact Center Desktop | +| Title | Webex Contact Center | +| Width | 550 (Recommended) | +| Height | 600 (Recommended) | + +- To the right of the URL field, click on the **Lock button** and add **agentdesktop.do** as the URL. + +- Click **Submit**. + +### b. Service Now Desktop Layout setup + +- Navigate to [Github page](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/ServiceNow) to download the latest Desktop Layout file. + +- Click on **ServiceNow_Desktop_xxxxx.jso** file. Copy the contents of the file, paste it in any text editor. + +- Update the properties in the Desktop Layout file, if required. Save the file with **.json extension**. + +- Sign into [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/). + +- Go to Provisioning -> Desktop Layout and press **New Layout** button. + +- Enter layout name (for example, "ServiceNow Desktop Layout"), press **Upload** and choose JSON file created in the previous step. Once the file is uploaded, make sure it is validated successfully. + +- Click on "Teams" row and choose one or more teams. + +> **Note:** The agent, you will use to test the integration with Service Now, must be the part of the team chosen above. + +- Press **Save** to create the layout. Once the layout is created make sure it is "Active". + +## Part 4: Test Webex Contact Center Service Now Agent Desktop + +### a. Make an inbound test call from a number NOT registered in ServiceNow CRM + +
    + +
    + +- From the **Filter navigator**, navigate to **Agent Workspace Home**. + +- Click on the phone icon on the bottom left corner and then on **Sign In**. + +- Sign in to Webex Contact Center Agent Desktop using agent credentials. This agent user needs to be part of the same team with which we had associated the Desktop Layout previously. + +- Make sure the agent is in available state and make a test call to your EP. + +- Upon accepting the call, you should be able to see the screenpop with a **new interaction** created. + +- "Opened For" field in the interaction will be blank as there is no matching customer record. + +- **Activity details** can be seen in the second vertical section and will be updated with the interaction. + +- If required, an incident can be created by clicking on the **Create Incident** button on the top right corner of the page. + +- Now hang up and wrap-up the call. + +### b. Make an inbound test call from a number registered in ServiceNow CRM + +
    + +
    + +
    + +> **Note:** To create a new user, login to the Developer Portal. +> +> Navigate to Users (under System Security) and click on New button. + +- From the **Filter navigator**, navigate to **Agent Workspace Home**. + +- Click on the phone icon on the bottom left corner and then on **Sign In**. + +- Sign in to Webex Contact Center Agent Desktop using agent credentials. This agent user needs to be part of the same team with which we had associated the Desktop Layout previously. + +- Make sure the agent is in available state and make a test call to your EP. + +- Upon accepting the call, you should be able to see the screenpop with a **new interaction** created. + +- The interaction will be mapped with the matching customer record and "Opened For" field will be pre-populated with the customer name. + +- **Activity details** can be seen in the second vertical section and will be updated with the interaction. + +- If required, an incident can be created by clicking on the **Create Incident** button on the top right corner of the page. + +- Now hang up and wrap-up the call. + +# Zendesk integration + +### Pre-requisites + +1. Administrator access to the organization on [Control Hub](https://admin.webex.com/) and [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/). +2. An agent account with access to [Agent Desktop](https://desktop.wxcc-us1.cisco.com/). +3. Zendesk instance. For the details, refer the next section [Start Zendesk Trial](#optional-start-zendesk-trial). +4. Access to the [Webex Contact Center Desktop Layout for Zendesk](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/Zendesk) JSON. +5. Lab 2 (IVR Contact Routing) completed. + +## Optional: Start Zendesk Trial + +
    + +
    + +
    + +> ##### NOTE : +> +> Zendesk free trial is valid for 14 days only. So, you need to complete the configuration and all tests within this time frame. +> {: .block-tip } + +- Navigate to [Zendesk](https://www.zendesk.com/) website. + +- Click on **Free Trial** on the main page of the website. + +- Enter your email address at "Start your free Zendesk trial" page. + +- Provide your First Name, Last Name, Phone number and Job title on the second step of the wizard and press **Next** button. + +> **Note:** The phone number is mandatory, but it is not used for any kind of verification, authentication or authorization. Thus you may provide any number. + +- On the last step of the wizard fill in the following fields: + + - Company Name + - Number of employees + - Purpose of the account + - Zendesk subdomain + + Then choose Language, enter new Password and click on **Complete trial signup**. + +- You should receive an email saying **Welcome to Zendesk: Verify your email**. Click on **Verify your account**. + +- You will be redirected to **Improve your trial experience** page, select any answer or Click on **No thanks** button to proceed. + +- You will be taken to your Zendesk instance. + +## Part 1: Install Webex Contact Center application on Zendesk instance + +
    + +
    + +### Install Webex Contact Center application for Zendesk from Marketplace + +- Sign into your Zendesk instance. URL should have format - **https://< your-zendesk-subdomain >.zendesk.com** + (This is the same page where you were at the end of last section) + +- Once signed into Zendesk, click on "Admin" icon (gear icon at the bottom of the vertical menu bar on the left). Then click on **Go to Admin Center** + +- You will be routed to the admin portal. Now, click on **Apps and integrations**. Then click on **Marketplace**. + Zendesk Marketplace will be opened in a new tab of the web browser. + +- Search for "Webex" on Marketplace and click on **Webex Contact Center** application. + +- Click on **Install** on the page of "Webex Contact Center" application. Then choose an account to install this app from drop-down list (Since you have already created Zendesk instance, you should be able to see your account name in the list) and click on "Install" one more time. You will be redirected to "Zendesk Admin Center" for the app installation. + +- The URL for "AgentDesktopHostUrl" is specific to your geographic location. By default, its value is **https://desktop.wxcc-us1.cisco.com**. Then scroll down and press "Install" button at the bottom of the page. + +- You can set the height and width of the connector widget here or can customize it later. + +- Wait few seconds until installation is completed and "Webex Contact Center" appears in the list of currently installed apps. + +## Part 2: Configure Webex Contact Center tenant and Zendesk instance + +
    + +
    + +### Create Custom Desktop Layout for Zendesk + +- Navigate to [Zendesk Layout](https://github.com/CiscoDevNet/webex-contact-center-crm-integrations/tree/main/Zendesk) GitHub page. + +- Click on "Zendesk_Desktop_xxxxx.json" file. Copy the contents of the file, paste it in any text editor and save with .json extension. For example, **Zendesk_Desktop.json** + +- Sign into [Webex Contact Center Management Portal](https://portal.wxcc-us1.cisco.com/) of your lab pod. + +- Go to Provisioning -> Desktop Layout and press **New Layout** button. + +- Enter layout name (for example, "Zendesk Desktop Layout"), press **Upload** and choose JSON file you have created above. Once file is uploaded, make sure it is validated successfully. + +- Click on "Teams" row and choose one or more teams. + +> **Note:** The agent, you will use to test the integration with Zendesk, must be the part of the team chosen above. + +- Press **Save** to create the layout. Once layout is created make sure it is "Active". + +### Create new Customer in Zendesk + +- In Zendesk instance, click on "Customers" icon in the vertical menu bar on the left. + +- Click on **Add customer** button. Provide the Customer Name and Email ID (optional) and press **Add** button. + +- Customer will be created and its info page will be opened. Click on **+add contact** link on the left side and enter the calling number which you will use to make test call to Webex Contact Center. + +- Go to "Customers" tab one more time to make sure new customer is successfully added. If you are unable to see the new customer there, just refresh the browser. + +## Part 3: Test Webex Contact Center Agent Desktop for Zendesk + +### Sign into Webex Contact Center for Zendesk + +- Sign into your Zendesk instance. + +- Click on Webex icon (grey square with Webex logo inside) at the top right corner of Zendesk window to launch embedded agent desktop in the CRM. + +- Press **Sign In** button within "Webex Contact Center" app and provide agent credentials in the new browser tab. + +- Once authentication is completed, provide "Dial Number" / "Extension" and choose proper team within "Webex Contact Center" app. + +> **Note:** This team must have the Custom Desktop Layout for Zendesk applied in Webex Contact Center Management Portal (covered in the previous part of this lab). + +- Make the agent "Available" by selecting corresponding state. + +### a. Make inbound test call from a number registered in Zendesk CRM + +
    + +
    + +- Initiate a call from the calling number which should be the same as the phone number of Zendesk customer created in the previous part of this lab. + +- Answer the call on the agent's end. You will be able to see the screen pop with the details of the customer created in the previous part of this lab and a new ticket will be created. + +- "Requester" field of the ticket will be pre-populated with the customer's name. + +- Now hang up and wrap-up the call. + +- The ticket that was created at the start of the call will be updated with call details after call wrap up. + +### b. Make inbound test call from a number NOT registered in Zendesk CRM + +
    + +
    + +- Initiate one more call from the calling number which does not match any customer in Zendesk and compare the behavior. + +- Answer the call on the agent's end. A new customer will be created and the customer details page will be opened as the screen pop. Also, a new ticket will be created. + +- "Requester" field of the ticket will be pre-populated with the new customer's name. + +- Now hang up and wrap-up the call. + +- The ticket that was created at the start of the call will be updated with call details after call wrap up. + +- Click on "Views" icon on the vertical menu bar on the left. You should be able to see both the tickets created after making the test calls. + +> **Note:** For Custom Desktop Layout configurations, kindly check out [help.webex docs](https://help.webex.com/en-us/article/jg2krv/Integrate-Webex-Contact-Center-with-Zendesk#customize) + +--- + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    diff --git a/_pages/Calabrio.md b/_pages/Calabrio.md new file mode 100644 index 0000000000..27ad4df512 --- /dev/null +++ b/_pages/Calabrio.md @@ -0,0 +1,23 @@ +--- +title: Lab 10 - QM/WFO - Calabrio +author: Carles Duz Palau & Susan Quick +date: 2022-10-10 +layout: post +--- +``` +Last-modified: Fri, 09 Jun 2023 +``` + +Work in progress. + + + + + + +--- + + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    diff --git a/_pages/Digital.md b/_pages/Digital.md new file mode 100644 index 0000000000..50108a1112 --- /dev/null +++ b/_pages/Digital.md @@ -0,0 +1,3659 @@ +--- +title: Lab 12 - Digital Channels +author: Davide Telari, Yurii Ulianov, Iranthi Ulluwishewa, David Ng, Naveen Kumar Narasimhan Almeti & Gajanan Pande. +date: 2022-12-12 +layout: post +--- +``` +Last modified: Tue, 20 Jun 2023 +``` + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------------------------------------------- | ----------------- | --------------- | ---------------- | +| [Architecture Overview and Provisioning](#lab121---architecture-overview-and-provisioning) | Read & Understand + Practical Lab | EASY | 15 min | +| [Connect GUI overview](#lab122---connect-gui-overview) | Read & Understand | EASY | 15 min | +| [Engage GUI overview](#lab123---engage-gui-overview) | Read & Understand | EASY | 15 min | +| [User Management in Connect](#lab124---user-management-in-connect) | Read & Understand + Practical Lab | EASY | 10 min | +| [Digital Channels Pre-configuration](#lab125---digital-channels-pre-configuration) | Practical Lab | EASY | 15 min | +| [Flow Builder](#lab126---flow-builder) | Read & Understand | EASY | 20 min | +| [Email Channel Configuration](#lab127---email-channel-configuration) | Practical Lab | EASY | 25 min | +| [Chat Channel Configuration](#lab128---chat-channel-configuration) | Practical Lab | EASY | 30 min | +| [Facebook Messenger Channel Configuration](#lab129---facebook-messenger-channel-configuration) | Practical Lab | EASY | 25 min | +| [SMS Channel Configuration](#lab1210---sms-channel-configuration) | Practical Lab | EASY | 20 min | +| [WhatsApp Channel Configuration](#lab1211---whatsapp-channel-configuration) | Practical Lab | EASY | 25 min | +| [Connect Templates](#lab1212---connect-templates) | Read & Understand | EASY | 20 min | +| [Engage Templates](#lab1213---engage-templates) | Read & Understand | EASY | 25 min | +| [Introduction to BOTs](#lab1214---introduction-to-bots) | Read & Understand | MED | 20 min | +| [Q&A BOTs](#lab1215---q&a-bots) | Practical Lab | MED | 25 min | +| [Task BOTs](#lab1216---task-bots) | Practical Lab | HARD | 30 min | +| [Event Scheduler](#lab1217---event-scheduler) | Read & Understand | MED | 15 min | +| [Inbound Webhooks](#lab1218---inbound-webhooks) | Practical Lab | HARD | 35 min | +| [Troubleshooting](#lab1219---troubleshooting) | Practical Lab | MED | 60 min | +| [Creating Custom Nodes](#lab1220---creating-custom-nodes) | Practical Lab | MED | 30 min | +| [Events and Triggers](#lab1221---event-and-triggers) | Practical Lab | MED | 30 min | +| [Global and Flow variable support in Digital channels](#lab1222---global-and-flow–variable–support–in-digital-channels) | Practical Lab | MED | 45 min | +| [Providing Digital Channels feedback](#providing-digital-channels-feedback) | Survey | EASY | 5 min | + + + +# Lab.12.1 - Architecture Overview and Provisioning + +## **Table of Contents** + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ------------------------------------------------------------------------------------- | -------- | --------------- | ---------------- | +| [Webex Connect architecture](#1-webex-connect-architecture) | Read & Understand | EASY | 5 min | +| [Webex Connect provisioning](#2-webex-connect-provisioning) | Practical Lab | EASY | 5 min | +| [Webex Connect provisioning verification](#3-webex-connect-provisioning-verification) | Practical Lab | EASY | 5 min | + + +## **Introduction** + +#### **Lab Objective** + +This lab is designed to introduce the audience to the digital channels (Webex Connect) platform, its architecture and its provisioning. In addition this lab will provide the instructions to verify if Webex Connect has been provisioned successfully. + +#### **Pre-requisite** + +1. Admin credentials to login to Control Hub and Webex Contact Center administration portal. + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## **1. Webex Connect architecture** + +Webex Connect consists of 2 main components, Connect and Engage, which are directly integrated with the Webex Contact Center platform (as per the drawing). +The access to Webex Connect is restricted to Administrators only. + +![Architecture](/assets/images/DC_Architecture.png) + +**Connect** serves as the entry point for all the messages received through any digital channel (email, chat, SMS, Messenger Facebook, WhatsApp) and as the intelligence for routing them. It hosts most of the configuration the Admin will create: flows, assets, bots, scheduled events and webhooks. +The access to Connect happens via a dedicated URL which is generated and provided to the administrator at the time of the initial provisioning. +Users in Connect are added and managed locally. + +**Engage** serves as the host for media and agents. Agents which are configured in Webex Contact Center gets automatically synchronized with Engage. In CPaaS (the standalone version of Webex Connect) Engage provides a dedicated agent console solution, while with Webex Contact Center it leaves that control to the native Webex Agent Desktop. Within Engage the Admin can customize some cosmetics of each channel and create templated responses agents can select and use inside their Agent Desktop. +The access to Engage happens via a dedicated icon inside the Webex Contact Center Management Portal. +Users in Engage are automatically synchronized with Webex Control Hub. + +## **2. Webex Connect provisioning** + +- Go to https://admin.webex.com +- Login with tenant administrator credentials +- Under ‘Services’ select ‘Contact Center’ > ‘Settings’ > ‘General’ +- Verify under ‘Service Details’ > ‘Digital Channel’ is set to ‘IMI Digital’ + +![Provisioning1](/assets/images/DC_Provisioning1.png) + +> In case the ‘Digital Channel’ section prompts a different value you will need to reach out Cisco for support to get this setting corrected before proceeding further. + +- Under ‘Services’ select ‘Contact Center’ > ‘Settings’ > ‘Digital’ +- Select the button ‘Provision Digital Channels’ + +![Provisioning1](/assets/images/DC_Provisioning2.png) + +- Then select from the list of administrators the account who will become the Owner of the new Webex Connect Tenant > Click on ‘Select + +![Provisioning1](/assets/images/DC_Provisioning3.png) + +- Wait approximately 5 minute for the automated provisioning process to complete. After this time, the selected administrator will receive an activation email. +- Open the email and click on ‘JOIN THE TEAM’ + +![Provisioning1](/assets/images/DC_Invite.png) + +- Follow the instructions to activate your account and set a local password. +- Once the activation is completed you will access the Connect portal > bookmark the website URL + +> For security reason, the activation is only valid for 24 hours since its delivery. Please activate your account immediately. In case you don’t receive the activation email, or not use it within 24 hours, will need to reach out Cisco for support. + +## **3. Webex Connect provisioning verification** + +- Go to https://admin.webex.com +- Login with tenant administrator credentials +- Under ‘Services’ select ‘Contact Center’ > ‘Settings’ > ‘Digital’ +- Verify Digital channels setup for Webex Contact Center is completed. + +![Provisioning1](/assets/images/DC_Provisioned1.png) + +- Return to ‘Services’ select ‘Contact Center’ > ‘Settings’ > ‘General’ > ‘Advanced Configuration’ > Select ‘Go to Webex Contact Center Management Portal’ to cross launch to administration portal +- In Administration portal, select ‘New Digital Channels’ to cross launch into the new component ‘Engage’ +- No additional login(or credentials) are required. The login to Engage portal should be seamless + +![Provisioning1](/assets/images/DC_Provisioned2.png) + +- In Engage portal, select Users > Search +- Verify that users with Administrator and Premium Agent previleges are replicated with role type ‘Administrative’ and ‘Customer Care’ roles +- Please note that the user account with which you have logged in will not show up in the engage user list. This is expected behaviour. + +![Provisioning1](/assets/images/DC_Provisioned3.png) + +--- + +**Congratulations, you have completed this section!** + + + +# Lab.12.2 - Connect GUI overview + +## **Table of Contents** + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------- | -------- | --------------- | ---------------- | +| [Overview of Connect menu items](#overview-of-connect-menu-items) | Read & Understand | EASY | 15 min | + + +## **Introduction** + +#### **Lab Objective** + +This lab is designed to introduce the Connect interface, which is used for the configuration and orchestration of all digital channels. In this lab you will not find configuration steps, the goal is to understand the purpose and use of each menu item. + +#### **Pre-requisite** + +1. Connect URL for browser access. +2. Admin credentials to login to Connect administration portal. + + +## **Overview of Connect menu items** + +Connect interface is divided in two main parts: the main menu on the left side and the configuration of the selected object in the center-right side. +Move your mouse pointer on each icon of the menu to see its name and the available options. Click on the ‘>>’ icon in the left bottom of the menu to expand the menu and see the description of each item in addition to the shortcut icons. + +This is the introduction video. It walks through the menu items and explains the purposes of each tab. + +
    + +
    + +#### **1. Services** + +Services are containers for all the flows the administrator will typically configure to orchestrate and route incoming messages from customers to agents. The administrators can create, name and arrange Services following their preferences. + +- After login into Connect, Services will be automatically selected. You can click on any of the existing services to explore their content. Use the search toolbar on the top to navigate and filter the available services when there are many. +- To create your own service click on **SERVICES** > **CREATE NEW SERVICE** button. Please set the **SERVICE NAME** with a name of your choice. +- You will be redirected to your service configuration. In the **DASHBOARD** tab, at the right bottom, you can see the traffic statistic per each channel, flow execution, and Messaging API statistic. +- Click on a second tab **FLOWS** to see the list of all flows created for that service. You should not have any pre-built services right now. +- Click on the **RULES** tab to see which triggers are configured for which flows. Again, there are no triggers right now. +- Click on **API** tab. Here you can get the **SERVICE ID** and **SERVICE SECRET** which are needed for external applications which are using API that are meant to trigger flows within this service. +- Click on the **SETTINGS** tab. Here you can rename or delete the service. You can add a description for better organization and even select the checkbox under ‘Service Locking’ so to prevent other users to apply any uncontrolled changes to it. + +#### **2. Reports** + +While the official platform for the Contact Center solution remains Analyzer, Connect offers the possibility to generate historical utilization reports for the existing flows. + +- Click on the next item in menu **REPORTS** > select the desired service in **ENTITY** (use the search bar on the top to navigate and filter the available services when there are many) > select one Channel (will collect data from all flows of the same kind) or one specific Flow > Select the desired Time Period > click on the “**GET REPORTS**” button. If there is no data, you will get a “No records found.” message. Later you can find here such data as numbers of Submitted, Rejected, Delivered, Read, and Failed messages. + +#### **3. Assets** + +Assets function as triggers and they are very similar to Entry Points in the Webex Contact Center Management Portal. + +- Go to the next item in menu **ASSETS** > **Numbers**. This will show you the list of SMS numbers added to the platform. SMS numbers are provided upon request by Cisco. Admin is not required to apply any configuration here. +- Now click on **ASSETS** > **Apps**. This section allows the administrator to add and manage the ‘trigger’ for each channel (except SMS). Apps require dedicated configuration to function properly. +- Click on next item **ASSETS** > **Integrations**. This section contains the list of all integrations configured for different events, which allow Connect to communicate with other components. By default, you will find two integrations: Webex CC Task (which allows Connect to communicate with the Webex Contact Center backend) and Webex CC Engage (which allows Connect to communicate with the Engage backend) + +#### **4. Tools** + +The Tools section contains several additional capabilities, but just few of them are commonly used. + +- Click on **TOOLS** > **Download SDKs**. Here you can download SDK if you want to build your own application. +- Go to **TOOLS** > **Templates**. Here you can create new templated messages that will be triggered inside the desired flows so to programmatically respond to customers and collect the desired information. +- Now go to **TOOLS >** **Export Logs**. This section allow the administrator to collect detailed logs for either Inbound or Outbound messages received/sent in a desired time frame. This option becomes very useful during troubleshooting. To consult the logs, select your Service name, select your Channel, time period, and click **DOWNLOAD** button. Wait few seconds for the report to be generated (the Status will change to ‘Ready for download’) + +#### **5. Debug** + +The Debug section is extremely useful when troubleshooting any ongoing issues. It offers the possibility to check some detailed information about incoming and outgoing messages, which can help the administrators to better understand what could be the root cause of occurring problems. + +- Click on **DEBUG**. +- Use **Query by Transaction ID** when looking for a specific conversation (this ID is retrievable inside the flow designer, this will be covered in another lab). +- Use **Query by Destination ID** when looking for outbound messages (typically from agent to customer) toward a specific destination (i.e. number, email, etc). +- Use **Historical Log** for a more generic search, select the query Channel type and date range. Click on the **SEARCH** button and check if you have any data. + +#### **6. Help** + +The Help section provides access to the available documentation. + +- Go to the next menu item by clicking on **HELP** > **Documentation** which redirects to the Webex Connect documentation portal. All menu items are documented in that documentation. +- Go to the second item in the **HELP** menu by clicking on **API Reference**. This will forward you to the API documentation portal. +- Now switch to the **Change Log** item in the same menu. Here you can find the updates of the product. + +#### **7. App Tray** + +Use the App Tray to access advanced platform capabilities. + +- Click on the **APP TRAY** > **Bot Builder**. This will redirect you to the Bot Builder tool where you will create the bots to automate the customers interactions. This section is covered in detail in a dedicated lab. +- Click on the **APP TRAY** > Event Scheduler. This will redirect you to the Scheduler tool where you will create the events and related schedule to programmatically trigger flows. This section is commonly used for outbound campaign on digital channels, and it’s covered in detail in a separated lab. + +#### **8. Settings** + +The Settings session allows the administrator to review and manage users and team settings. More details on user management will be provided in a dedicated lab. + +- Click on the next item **Settings** > **Profile Settings** and check the Profile settings. +- Go to **SETTINGS** > **Tenant Settings** and verify the configured Time Zone and Date Format. +- Open **SETTINGS** > **Usage** to see the general statistic of the entire tenant. +- Click on the next item **SETTINGS** > **Contact Support**. Here you can check the support contact details in case you need to escalate any query. +- Click on the next item **SETTINGS** > **Teammates**. From here you can add more users to Connect or change the permissions for existing users. +- Go to **SETTINGS** > **Groups/Teams** where you can create a new group or team. Please refer to _“here”_ link to see the explanation of Groups and Teams. +- As the final step click on the **Logout** in the **SETTINGS** menu and make sure that you are signed out from the Connect. + +--- + +**Congratulations, you have completed this section!** + + + +# Lab.12.3 - Engage GUI overview + +## **Table of Contents** + +| Topic | Lab Type | Difficulty Level | Estimated length | +| --------------------------------------------------------------- | -------- | --------------- | ---------------- | +| [Overview of Engage menu items](#overview-of-engage-menu-items) | Read & Understand | EASY | 15 min | + +## **Introduction** + +#### **Lab Objective** + +This lab is designed to introduce the Engage interface, which is used for the configuration and orchestration of all digital channels. In this lab you will not find configuration steps, the goal is to understand the purpose and use of each menu item. + +#### **Pre-requisite** + +1. Admin credentials to login to Control Hub and Webex Contact Center administration portal. + +## **Overview of Engage menu items** + +Engage interface is divided in two main parts: the main menu on the left side and the configuration of the selected object in the center-right side. +In addition, Engage has two different ‘portals’: the Admin portal (which is automatically loaded when logging-in) and the Customer Care portal. Both are accessible by clicking on the user icon on the top-right of the browser window. +Move your mouse pointer on each icon of the menu to see its name and the available options. +Within Engage not all the options in the menus are required to be known and used: this lab will cover the commonly used settings.       + +This is the introduction video. It walks through the menu items and explains the purposes of each tab. + +
    + +
    + +#### **1. Engage login** + +- In order to access Engage, login to Webex Control Hub > Navigate to ‘Services’ select ‘Contact Center’ > ‘Settings’ > ‘General’ > ‘Advanced Configuration’ > Select ‘Go to Webex Contact Center Management Portal’ to cross launch to administration portal +- Once logged in, click on the ‘hamburger’ icon on left, go to the last section and click on ‘New Digital Channels’ +- You will be automatically redirected to the Engage portal on a new browser tab. + +#### **2. Dashboard** + +The Dashboard provides a real-time view of all the ongoing chats. + +- After login into Engage, Dashboard will be automatically selected. From the drop down menu on the top-right check the ‘Select All’ entry to display all the data available for all the agents. +- Customize the views and filters in the dashboard as per your need to review the desired information. + +#### **3. Settings** + +Within the setting section the administrator can control if and which type of attachments can be exchanged in every channel. +IMPORTANT: since Webex Connect is a PCI compliant application only text-based files are allowed to be transferred. In case a document contains images in addition to plain text, such document will be rejected and not attached to the conversation. + +- In case you decide to do not allow any files to be exchanged, toggle the green switch ‘Enable Attachment’ > Click the **Submit** button to save the changes. +- If you would like to edit the support of attachments for a specific channel, click on the pencil icon under actions for your desired channel type > A pop-up window will appear > Edit the size and number of the attachments as needed > Add or Remove the extension type from the ‘Supported File Formats’ > Click the **OK** button to save the changes. + +#### **4. Users** + +The Users section lists all the licenses Contact Center Administrators and Agent users from Control Hub, except the user that is being used to login at that time. + +- Use the Role Type, Status or search bar to filter the list of users. The list will show if the agents are currently logged in and their role. +- In case any user is missing, return to Control Hub and verify the proper license is assigned to it. + +- If the proper license is assigned > Temporarily remove the license to the affected user > Navigate to ‘Services’ select ‘Contact Center’ > ‘Settings’ > ‘General’ > Click on Synchronize Users > Return to the User and re-assign the license > Return to to ‘Services’ select ‘Contact Center’ > ‘Settings’ > ‘General’ > Click on Synchronize Users. The user will now re-appear in the Engage Users list. + +#### **5. Assets** + +Assets contains required and optional configuration for Assets and agents. + +- Select **Channel Assets** > here you will see all the Assets that are configured in Connect which are automatically synced with Engage. This section will be used especially for the Web Chat widget configuration. +- Select **Templates** > here you can add and manage templated message the agents can select from their agent console to quickly reply to customers. + +#### **6. Customer Care portal** + +After logging into Engage Admin portal (from the Webex Contact Center Management Portal) click on the user icon on the top-right of the browser window and select Customer Care. + +#### **6.1. Dashboard** + +The Dashboard provides a real-time view of all the ongoing conversations and agents. + +- After login into Engage, Dashboard will be automatically selected. +- You can retrieve and download a conversation transcript by searching for a specific conversation ID (such ID can be retrieved from Connect) + +#### **6.2. Settings** + +Within the setting section the administrator can control some additional useful settings. + +- Select **Settings** > **MANAGE** > **Template** > You will see the same templates configured on the Admin view +- Select **Settings** > **MANAGE** > **Blocklist** > You can edit or add specific words which will be blocked from the conversation +- Select **Settings** > **CONFIGURE** > **Working Hours** > You can edit the ‘named’ operating hours of your service. This setting will have an actual impact only on the Chat widget layout (more details provided in the dedicated lab). + +--- + +**Congratulations, you have completed this section!** + + + +# Lab.12.4 - User Management in Connect + +## **Table of Contents** + +| Topic | Lab Type | Difficulty Level | Estimated length | +| -------------------------------------------------------------------------------- | -------- | --------------- | ---------------- | +| [User Roles and Permissions](#1-user-roles-and-permissions) | Read & Understand | EASY | 4 min | +| [Users organization](#2-users-organization) | Read & Understand | EASY | 1 min | +| [Login to Connect portal](#3-login-to-connect-portal) | Practical Lab | EASY | 1 min | +| [Add new users with administrator role](#4-add-new-users-with-administrator-role) | Practical Lab | EASY | 2 min | +| [New user activation](#5-new-user-activation) | Practical Lab | EASY | 2 min | + +## **Introduction** + +#### Lab Objective + +This lab is designed to introduce the Connect User Management structure. Throughout this lab you will learn how to add new administrator users in Connect and how to arrange user accesses. + +#### Pre-requisite + +1. Connect portal URL +2. Tenant Owner credentials to login to IMI Connect portal + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## **1. User Roles and Permissions** + +Connect allows its administrators to add local users and set the with different level of permissions. Here below the list of available roles: + +- Owner - first configured users (is the account that has been indicated at the time of the provisioning of Webex Connect tenant). The Owner has full permissions in the tenant. Only 1 Owner can exist in a tenant. +- Full Access – this is the most commonly used role for all other administrators that need access to Connect. +- Limited Access +- Read Only +- Restricted + +To review in details the permission assigned to each role please refer to the official documentation [https://help.imiconnect.io/docs/user-roles-and-hierarchy](https://help.imiconnect.io/docs/user-roles-and-hierarchy) + +The Owner is the only role who can provide the permission to other users to Decrypt Log (which is an essential permission to view logs when troubleshooting). +If an Owner leaves your organization, please reach out to your support contact the Partner Success team (PSM) to request the Owner change. +Connect shall be accessed only by system administrators and not by agents or supervisors. + +## **2. Users organization** + +Connect allows the Owner to create local users in containers called **Groups** and **Teams**. Users created within a Group or a Team will be able to access the configuration created within such container and below, but not to the configuration created at levels above. Users can be create in one of the following containers: + +- Tenant level – can contain users and Groups +- Group – can contain users and Teams +- Team – can contain users only + +> To create new groups or teams go to ‘Settings’ > 'Groups/Teams' + +## **3. Login to Connect portal** + +- Access Connect URL (this is specific to the tenant you are using) +- Login the provided credentials + +> Please contact the Partner Success team (PSM) if there are any challenges identifying the Connect Owner details + +![UserLogin](assets/images/DC_Login.png) + +## **4. Add new users with administrator role** + +- Once logged in to Connect, go to ‘Settings’ > ‘Teammates’ +- Add a new user (must be a working emailID) and select ‘Full access’ role and click ‘Invite user’ + +![AddUser](assets/images/DC_AddUser.png) + +## **5. New user activation** + +- Click ‘Join the team’ link in the welcome email to complete user registration. +- Provide your name and setup the passwords, click ‘Next’. +- Fill out additional details about yourself and click ‘Next’. +- The user will automatically login into the Connect portal. +- The user will have to inform the tenant Owner about the successful creation of the account > the Owner will go to ‘Settings’ > ‘Teammates’ > click ‘Edit’ for the specified user > mark the checkbox for Decrypt Logs > click ‘Save’ + +![UserActivation](assets/images/DC_UserActivation.png) + + +--- + +**Congratulations, you have completed this section!** + + +--- +# Lab.12.5 - Digital Channels Pre-configuration + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| -------------------------------------------------------------------------------- | -------- | --------------- | ---------------- | +| [Node Authorization for Webex CC Task and Engage nodes](#1-node-authorization-for-webex-cc-task-and-engage-nodes) | Practical Lab | EASY | 5 min | +| [Setup Agents in the Management Portal](#2-setup-agents-in-the-management-portal) | Practical Lab | EASY | 5 min | +| [Setup RONA timers](#3-setup-rona-timers) | Practical Lab | EASY | 5 min | + +## Introduction + +#### Lab Objective + +In this Lab, we will go through the tasks that are required to complete the general pre-configuration of a tenant with Digital Channels. These tasks are to be undertaken by an administrator. By following each of the steps, you would have prepared your tenant to begin configuring different services offered by the platform. The lab contains multiple exercises to make you familiar with Control Hub, Management portal UI and Webex Connect. At the end of the lab, you should be able to log in to an agent interface. + +#### Pre-requisites + +- You have received the access credentials with a full admin access +- You have received the access to the agent and supervisor account. + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## Configuration Order + +![ConfigOrder](/assets/images/DC_Lab_12.5_1.png) + +## 1. Node Authorization for Webex CC Task and Engage nodes + +Webex Connect is required to provide a valid access token for using various Webex Contact Center and Webex Engage APIs. The access token is generated using the authorization details configured within the ‘Node Runtime Authorization’ field that Webex Contact Center users are required to provide during flow configuration. +- To authorize a pre-built integration go to Assets -> Integrations. The integrations which are not yet authorized show the status as Authorization Pending. +- In front of Webex CC Engage Click Actions -> Manage. + ![Access](/assets/images/DC_Lab_12.5_2.gif) +- On the Manage Integrations page, scroll down to the Node Authorizations section. This section lists all the authorizations mapped to this integration. +- Click Action → Add Authorization associated with the WxCC Engage Authorisation, where Auth Type is oauth2 and Status is Authorization Pending. + ![Authorization](/assets/images/DC_Lab_12.5_3.png) +- Enter the Authorization Name and click Authorize. In that example we use WxCC Engage Authorisation. + ![Authorize](/assets/images/DC_Lab_12.5_4.png) +- Click on the back button for being redirected back to Integrations page and in front of Webex CC Task Click Actions → Manage. + ![Manage](/assets/images/DC_Lab_12.5_5.gif) +- On the Manage Integrations page, scroll down to the Node Authorizations section. This section lists all the authorizations mapped to this integration. Click Action → Add Authorization associated with the WxCC Authorisation, where Auth Type is oauth2 and Status is Authorization Pending. + ![Authorization](/assets/images/DC_Lab_12.5_6.png) +- Enter the Authorization Name (for example: WxCC Authorisation) and click Authorize. As the result the pop-up appears where you need to enter your Cisco admin email address and click Sign In. + ![Authenticate](/assets/images/DC_Lab_12.5_7.png) +- Click back button for being redirected back to Integrations page. Verify that the status of the authorizations is changed to Authorized. + +![Authorize](/assets/images/DC_Lab_12.5_8.gif) + +## 2. Setup Agents in the Management Portal + +This step shows how to access the admin portal and navigate the different configuration menus to create a Site, Team, and Multimedia Profile that will be assigned to the Contact Center user. + +**Users** +The users have the following pre-configuration +| User Role | User email | +| ---------- | -------------------------------- | +| Agent | cl1agentXXX@email.carehybrid.com | +| Supervisor | cl1supXXX@email.carehybrid.com | + +> Note: Your XXX was provided to you personally. XXX is the unique number equal to your POD. + +**User Settings** +| Entity | Name | +| ------------------- | ----- | +| Multimedia Profiles | MMP | +| Site | Site | +| Team1 | Team1 | +| Team2 | Team2 | + +1. Create new MultiMedia Profile +- Login to Management Portal (link provided in the Introduction section). +- Enter the Admin email address and click Sign in. +- Click on Provisioning and select Multimedia Profiles. +- Click on + New Multimedia Profile to open Multimedia Profile configuration page. +- Input Name as MMP. +- In the Media Details section, select the blended multimedia profile and input 1 for Voice, 3 for Chat, 3 for Email, , 3 for Social Channel and click on Save button. + ![MMP](/assets/images/DC_Lab_12.5_14.png) + +2. Create new Site +- Navigate to Provisioning and select Site. +- Click on + New Site button and provide the Name as Site. +- Select MMP in the Multimedia Profile drop down and hit Save. + ![Site](/assets/images/DC_Lab_12.5_15.png) + +3. Create new Teams +- Navigate to Provisioning and select Team. +- Click on + New Team. +- Select Site from the Site drop-down. +- Input Name as Team1. +- Use the default Type Agent Based. +- Select MMP in the Multimedia Profile drop-down. +- Left as a default value Global Layout in the Desktop Layout drop-down and hit Save. + ![Team](/assets/images/DC_Lab_12.5_16.png) +- Please follow the same steps as above to add an extra Team as Team2. + +4. User Configuration +- Click on Provisioning and select Users. +- Click on ... for the Agent user, to launch the Edit view for a particular User configuration. +- Make sure that the User Profile is set as Premium Agent User Profile. +- Click on Contact Center Enabled toggle to move it to On. +- In the Agent Settings section, select Site in the Site drop-down. +- Click the Teams area and select Team1 and Team2. +- Select Agent Profile in the Agent Profile drop-down list. +- Select MMP in the Multimedia Profile drop-down and hit Save. +- Make sure that the user are now shown with the Contact Center Enabled flag as Yes and Status as Active. + ![User](/assets/images/DC_Lab_12.5_17.png) +- Please follow the same steps for Supervisor user. + +## 3. Setup RONA timers +If an agent doesn’t answer a contact request, the contact request will return to the queue and the agent state will change to Redirection on No Answer (RONA). In this task, you will play with the feature that allows administrators to override the default RONA timeout values at the tenant level for every channel type to suit the business needs of the organization. The available channels are: +- Telephony +- Chat +- Email +- Social (Facebook and WhatsApp) + +- Log in to the Control Hub at https://admin.webex.com +- Navigate to Services -> Contact Center -> Settings -> Desktop -> RONA Timeouts. +![User](/assets/images/DC_Lab_12.5_18.png) +- Modify the existing timers by putting the values from the tables below: +| Channel | New Values | Limitations | +| --------- | ---------- | ---------------- | +| Telephony | 18 | 1 - 120 seconds | +| Chat | 60 | 1 - 6000 seconds | +| Email | 90 | 1 - 6000 seconds | +| Social | 60 | 1 - 6000 seconds | + +#### Verification: Access to the Agent Desktop + +> Note: To log in to the agent desktop, use either a separate web browser or a new incognito web page. This will prevent any browser caching issues with admin and agent credentials. +- Navigate to the Agent Desktop (link provided in the Introduction section) in a new browser or in incognito mode. +- Enter the agent’s email ID cl1agent**\**@email.carehybrid.com. +- Enter the Password for the appropriate Username. +- In the Station Login pane, select “Extension” and put any number, for instance 1000. +> Note: The Webex Calling service is not activated at this tenant we need to set a dummy extension only once during the login. +- Select the Team1 and click Submit. Make sure that you are successfully logged in to the Agent Desktop. Now you can continue with the Next Lab. + ![User](/assets/images/DC_Lab_12.5_19.gif) +--- + +**Congratulations, you have completed this section!** + + +--- +# Lab.12.6 - Flow Builder + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| -------------------------------------------------------------------------------- | -------- | --------------- | ---------------- | +| [Understanding Connect Flows](#1-understanding-connect-flows) | Read & Understand | EASY | 20 min | + +## Introduction + +#### Lab Objective + +This lab is designed to introduce the logic and methodology behind building flows that will handle incoming conversation via digital channels. Throughout this lab you will learn how to navigate the flow designer, understand how to read and configure nodes and how flows are being executed. In this lab you will not find configuration steps, the goal is to understand how to approach the build of a new flow. + +#### Pre-requisites + +1. Connect URL for browser access. +2. Admin credentials to login to Connect administration portal. + + +## 1. Understanding Connect Flows + +#### 1. Flows summary + +Here below a brief list of key aspects of any flow in Webex Connect: + - Flows can be freely build by the admin following customers’ requirement + - Flows can be located in any Service, the Admin is free to organize Flows and Services following the desired order and naming convention. + - Flows can be triggered by Assets, Events or Webhooks. + - Flows are built using and connecting functional nodes to execute the desired behaviour + - Every time a customer sends a new message, the associated Asset and then Flow are triggered from their starting node. + - Connect flows introduce the concept of Conversation: whenever a user has to send multiple messages via a single channel, which have to be considered as part of the same thread, the system shall create a Conversation ID, so to map and present all the messages together (from the user and from the agent). + - Flows do not automatically associate incoming messages from the same users/customers as part of the same thread, a dedicate node is required to check + - As reference, sample flows for each digital channel can be imported from the GitHub page (links in channels specific labs). + +#### 2. Create new flows + +You can create a new flow from scratch to explore the flow designer interface and its nodes. To create a new flow: + +- Access your Connect tenant +- Navigate to Service > select or create your service >  select the Flows tab > click on any of the two ‘Create Flow’ buttons +- Enter the a name inside the ‘Flow Name’ > under Type select ‘Work Flow’ > under Method select ‘New Flow’ > Select the ‘Start From Scratch’ icon > click on Create +- From the ‘Select Trigger Category’ select any of the channels (i.e. Email) +- You will be redirected to the flow canvas, already inside the first node in the flow > click on Cancel + +#### 3. Flow designer and node navigation + +The flow designer is divided in three main section: + +- Toolbar on top – containing the flow name and status, the settings, save and ‘make live’ buttons. +- Canvas in the middle – where the administrator can arrange the node to execute the desired workflow. +- Node menu on the left – containing all the nodes the admin can use (by dragging them inside the Canvas + +
    + +
    + +Nodes are categorized between Utilities, Channels and Integrations depending on their use but they all follow the same structure. To check a node simply drag and drop it into the canvas and double click on it. Inside each node you will find the: + +- Node Name – Can be edited by clicking on the pencil icon. +- Configuration tab – Every node needs to be properly configured to be executed. Each node has its own set of required Variables to be set. The details about how to configure each parameter can be found in the nodes’ specific documentation inside the Connect Help page. +- Transition Actions tab – use to configure additional activities before or after the node is executed (i.e. set desired values to additional variables). +- Node ID – Indicates the unique number identifier for this node. +- Input Variables section – Click on it to expand the section. You will see a list of all the Output and Custom Variables (grouped by node of origin) from the previously connected nodes. +- Output Variables section – Click on it to expand the section. You will see a list of variables (and their names) the node generates when successfully executed. +- Node Outcomes section – Click on it to expand the section. You will see a list of which and how many outcomes (exit connections) the node has. When closing the node configuration you will notice coloured dots on the right side of the node indicating the Outcomes. Drag those dots onto other nodes to connect them together, or into an empty point of the canvas if no further actions are needed. + +When using nodes’ Output Variables inside the configuration of other nodes, administrator will have to use the following syntax: $(nX.outputvariablename), where X is the node ID that has generated that variable. + +
    + +
    + +#### 4. Building a new flow + +As for any contact center flow, before proceeding building a new flow it’s always recommended to collect all the requirements as well as a draft of the intended workflow. +In addition to this, for the digital channels it’s crucial to distinguish the type of use for the flow: as mentioned in the chapter 1, Connect flows are executed from their starting node any time they are triggered +> excepts when using a Receive Node inside the flow itself, beyond the scope of this lab. + +For this reason the administrator should initially clarify if the flow shall be always triggered by distinct and unrelated sources or if multiple messages could come from the same source as part of a unique conversation. For most of the cases, when customers need to interact with your services, especially when expecting to connect with an agent, all their messages must be grouped into a uniquely identifiable thread. In Connect this is called **Conversation ID**. +For all the flows where you expect to have an ongoing conversation, your flow shall be built with an initial check, ideally after the starting node, where you will need to check if the incoming message is part, or not of an existing conversation, so to appropriately manage and route it accordingly. Here below a recommended flow structure: + +1. Accept incoming message via dedicated channel node. +2. Use the Resolve Conversation node to verify if the incoming message shall trigger the creation of a new Conversation ID ("created" outcome) or if such message shall be **appended** to an existing Conversation ID ("appended" outcome). The Resolve Conversation node also offer two additional outcomes, which allow the administrators to further customize their flows: "accepted" is triggered when the node receive the message (it might allow admins to add a confirmation response the system has successfully received the query), "reopened" is triggered when the same customer was already in a conversation with the system in the past, but that conversation was terminated by one of the 2 sides (or timed out). +3. Use the Queue Task node to queue the incoming message to the desired queue/team after the "created" and "reopened" outcomes only. +4. Connect the Close Task node for any failure outcomes for any nodes connected after the Append Conversation node. This will ensure the Conversation ID you created is properly terminated even if your flow experience some issues. + +When building a flow it is also recommend to appropriately handle the potential failure of each node by including messages back to the customer informing them about an ongoing issue. + + +#### 5. Activating a flow + +When a flow is being edited, its status appear as ‘Working Draft’ on the top-left of the browser window. Once the editing has been completed and you wish to start using the flow, you can click the Save button to save the latest changes. If there’s any missing or incorrect connection between nodes, a prompt will appear on the right side, listing all the occurring issue (misconfiguration inside each node won’t be detected here). +Once all the issues have been addressed, the Admin shall click on the ‘Make Live’ button to activate a flow in Working Draft status. A new pop-up will appear: select or modify the Application that will be triggering this flow, optionally add comments, and click ‘Make Live’. +Once a flow is set to go live, it will take approx. 2 minute before showing the correct ‘LIVE’ status on the top-left. In the meantime, it will show the ‘Publishing’ status, meaning that any messages received in the meantime will either be handled through the previous flow version or be rejected if no previous version is available. + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.7 - Email Channel Configuration +--- + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| -------------------------------------------------------------------------------- | -------- | --------------- | ---------------- | +| [Gmail account configuration](#1-gmail-account-configuration) | Practical Lab | EASY | 5 min | +| [Create Email Asset and Register to WebeXCC](#2-create-email-asset-and-register-to-webexcc) | Practical Lab | EASY | 5 min | +| [Email Entry Point and Queue creation](#3-email-entry-point-and-queue-creation) | Practical Lab | EASY | 5 min | +| [Create/Upload Email flow](#4-createupload-email-flow) | Practical Lab | EASY | 5 min | +| [Verification: Send an Email and accept the task](#5-verification-send-an-email-and-accept-the-task) | Practical Lab | EASY | 5 min | + + +## Introduction + +#### Lab Objective + +In this Lab, we will go through the tasks that are required to complete the basic email configuration. You will be able to initiate an email to the Contact Center and be able to accept/respond to the email by logging in as an agent. + +In this lab you will be configuring **Gmail** Account settings, Email Assets, Entry Point and corresponding workflows. All those steps are required for connecting the Email account with our application. + +#### Pre-requisite + +1. You received an admin credentials to configure in Management Portal and Webex Connect. +2. You received Email account credentials. +3. You have successfully completed the previous Lab12.5 **Pre-configuration**. + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## Configuration Order + +![DC_Lab.12.7_Email_ConfigurationOrder](/assets/images/DC_Lab.12.7_Email_ConfigurationOrder.png) + +## 1. Gmail account configuration + +Starting from May 30 the **Less Secure Apps** feature was disabled on all Google accounts. As long as this setting was enabled, it was possible to send emails via Gmail SMTP. In this lab, we will be using new OAuth 2.0 authentication for outbound email functionality. + +>**Note**: For this lab, we have created a Gmail account. Optionally, use your own account for polling and handling the emails. It can be a Gmail account or Office 365 account or any account which has email forwarding. The instructions below are applicable only for the Gmail accounts. + + +#### 1. Gmail forwarding activation (for incoming emails) + +| **User email** | +| ------------------------------------ | +| cl1webex**\**@gmail.com | + +> **Note:** Your \ was provided to you personally. \ is the unique number equal to your POD. + +- Login to the Gmail account with the credentials above [https://mail.google.com](https://mail.google.com). The password is the same as for Webex admin account. During first login select **Turn off smart features**. +- Enable POP3/IMAP setting by clicking on settings icon on top right corner and selecting **See all settings**. + +![DC_Lab.12.7_Gmail_account_configuration_1](/assets/images/DC_Lab.12.7_Gmail_account_configuration_1.png) + +- Now Click on **Forwarding and POP/IMAP**, enable the `POP Download` and `IMAP access` then click **Save Changes**. + +![DC_Lab.12.7_Gmail_account_configuration_2](/assets/images/DC_Lab.12.7_Gmail_account_configuration_2.png) + + +#### 2. Create a project at Google API Console +We need to activate API if we want to use Gmail account for outbound emails. + +- Login to [Google Developers Console](https://console.developers.google.com/) with the credentials above. The password is the same as for Webex Contact Center admin account. +- You will have to agree with the Terms of Service and pick their Country of residence. Then click **Select a project** and create a **NEW PROJECT**. + +![DC_Lab.12.7_Create_new_project_at_Google_API_Console_1](/assets/images/DC_Lab.12.7_Create_new_project_at_Google_API_Console_1.png) + +- Keep the default project's name and press **Create** at the bottom. Make sure that now you have selected this project. + +![DC_Lab.12.7_Create_new_project_at_Google_API_Console_2](/assets/images/DC_Lab.12.7_Create_new_project_at_Google_API_Console_2.png) + +#### 3. Enable Gmail API (for outgoing emails) + +- Enter `Gmail API` in the search bar and click on it once found. + +![DC_Lab.12.7_Enable_Gmail_API_1](/assets/images/DC_Lab.12.7_Enable_Gmail_API_1.png) + +- You need to enable the API for your project by clicking on **ENABLE** button. + +![DC_Lab.12.7_Enable_Gmail_API_2](/assets/images/DC_Lab.12.7_Enable_Gmail_API_2.png) + +#### 4. Configure OAuth Consent Screen and Scopes + +- Once the API is enabled, you’ll be taken to a nice dashboard that says, `"To use this API, you may need credentials"`. + +![DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_1](/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_1.png) + +- To create an OAuth client ID, you must first configure your consent screen. Under the APIs and Services section, click on **OAuth Consent Screen**, set the user type as `External` and click **CREATE** button. + +![DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_2](/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_2.png) + +- It will bring you to a page with many fields. Just enter the **App name** as `WebexCCEmails`, choose your **User support email** and enter the same email in the **Developer contact information**. In the end press **SAVE AND CONTINUE**. + +![DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_3](/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_3.png) + +- On the next screen, you need to provide Auth 2.0 Scopes for Google APIs. Click the **Add Or Remove Scopes** button and add https://www.googleapis.com/auth/gmail.send to the list of scopes since we only want to send emails from Gmail and not read any user data. Click **SAVE AND CONTINUE**. + +![DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_4](/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_4.png) + +- On the test user page, click **ADD USERS** and enter your Gmail address. Click **Save and Continue**. + +![DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_5](/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_5.png) + + +#### 5. Credentials and authentication with OAuth 2.0 + +Now create a new client ID that will be used to identify your application to Google’s OAuth servers. + +- In the APIs & Services section, click on **Credentials** and then pick **OAuth client ID** from the drop-down list of the **CREATE CREDENTIALS** button. + +![DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_1](/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_1.png) + +- Select `Web application` in the **Application type** +- You can leave the default name. The name of your OAuth 2.0 client is only used to identify the client in the Google Cloud console and will not be shown to application users. +- In the **Authorized redirect URIs** section click **ADD URI** button and set `https://cl1pod\.webexconnect.io/callback` where \ is your tenant number. Click **CREATE** button in the end. + +![DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_2](/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_2.png) + +- Download a JSON file with your credentials – you’ll need it later. + +![DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_3](/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_3.png) + + +## 2. Create Email Asset and Register to WebexCC + +#### 1. Create Email Asset + +- As an admin, login to Webex Connect UI using the provided URL https://cl1pod**\**.imiconnect.io/ (where **\** is your POD number). +- Select **Assets** -> **Apps** -> **CONFIGURE NEW APP** -> **Email**. + +![DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC](/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_1.gif) + +- Set the settings according to the table below: + +| **Entity** | **Name** | +| ------------------- | -------- | +| Asset Name | EmailAsset | +| Email ID | cl1webex**\**@gmail.com | +| Authentication Type | OAuth 2.0 | +| SMTP Server | smtp.gmail.com | +| Username | cl1webex**\**@gmail.com | +| Port | 465 | +| Security | SSL | +| Client ID | \ | +| client Secret | \ | +| Authorization URL | https://accounts.google.com/o/oauth2/auth | +| Scope | https://mail.google.com/ https://www.googleapis.com/auth/gmail.send | +| Access Token URL | https://oauth2.googleapis.com/token | +| Refresh Token URL | https://oauth2.googleapis.com/token | + +> where \ is your POD ID + +- Click **GENERATE TOKEN** and follow the step on the screenshot: + +![DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC](/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_2.gif) + +- Verify that the **ACCESS TOKEN** and **REFRESH TOKEN** are generated and click **SAVE**. + +![DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC](/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC.png) + +- Click on **REGISTER TO WEBEX CC** and Select the service **My First Service**. In the end click **REGISTER**. + +![DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC](/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_3.gif) + +#### 2. Add forwarding Address + +- Copy the forwarding address from the created asset in previous step and in Gmail account. + +![DC_Lab.12.7_Add_forwarding_Address_1](/assets/images/DC_Lab.12.7_Add_forwarding_Address_1.png) + +- Go back to the Gmail account and click on settings icon on top right corner -> Select **See all settings**. + +![DC_Lab.12.7_Add_forwarding_Address_2](/assets/images/DC_Lab.12.7_Add_forwarding_Address_2.png) + +- Click on **Forwarding and POP/IMAP** -> click on **Add a forwarding address** -> Paste the copied forwarding address from the created asset. Then click on **Next**. In a new pop up tab click **Proceed** and then click **OK** when it prompts. + +![DC_Lab.12.7_Add_forwarding_Address_3](/assets/images/DC_Lab.12.7_Add_forwarding_Address_3.gif) + +- In order to fetch the confirmation email, go back to Webex Connect and click on the **Debug Console** Menu on the left pane, select `Query Historical Logs` – `Channel = Email` – `Date Range = Today/Last Hour`. Click the **Search** button. + +![DebugConsole3](/assets/images/DebugConsole3.png) + +- You should only have 1 transaction in your logs at this point. Click the **Message ID** Link for `Event Handled` + +![OneTransaction](/assets/images/OneTransaction.png) + +- Click the **decrypt logs** button, then click the **Trace Details** link for that transaction. Click the **copy** button next to the Data entry in the lower right pane. + +![email_copy debug](/assets/images/email_copy_debug.gif) + +- Paste the copied data from the debug logs into the empty field below and press the Get URL button. This will pull out the forwarding verification URL that google sent you. + + + + + +- Paste the URL into a new browser tab and hit **Enter**. Click the **Confirm** button to OK the forwarding. + +![email_paste_debug](/assets/images/email_copy_debug.gif) + +- You will get a confirmation message + +![emailConfirmation](/assets/images/emailConfirmation.png) + +- Back in the settings of your Gmail account, forwarding should be reflected in the Forwarding and POP/IMAP tab. + +![CheckPopSetting](/assets/images/CheckPopSetting.png) + +## 3. Email Entry Point and Queue creation + +#### 1. Create Entry Point in Management Portal + +- Click on **_Provisioning_** and select **_Entry Points/Queues_** > **_Entry Point_**. +- Click on `New Entry Point`. +- Input **_Name_** as `Email_EP`. +- Select `Email` in the **_Channel Type_** section. +- Leave the **_Asset Name_** as appeared value `EmailASSET`. +- Set **_Service Level Threshold_** as `2` hours. +- The **_Time Zone_** can stay as default value. +- Click on **Save** after comparing your values with the screenshot below. + +![DC_Lab.12.7_Email_Entry_Point_and_Queue_creation](/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_1.png) + +#### 2. Create Two Queues in Management Portal + +- Click on **_Provisioning_** and select **_Entry Points/Queues_** > **_Queue_**. +- Click on `New Queue`. +- Input **_Name_** as `Email_Q`. +- Select `Email` in the **_Channel Type_** section. +- Leave the **_Queue Routing Type_** as default value `Longest Available Agent`. +- In the **_Email Distribution_** click on **Add Group** and select `Team1`. +- Set **_Service Level Threshold_** as `2` hours. +- Set **_Maximum Time in Queue_** as `3` hours. +- The **_Time Zone_** can stay as default value. +- Click on **Save** after comparing your values with the screenshot below. + +![DC_Lab.12.7_Email_Entry_Point_and_Queue_creation](/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_2.png) + +- Create a second queue by repeating the same steps as above. +- Input **_Name_** as `Email_Q2`. +- Select `Email` in the **_Channel Type_** section. +- In the the **_Email Distribution_** click on **Add Group** and select `Team2`. + +![DC_Lab.12.7_Email_Entry_Point_and_Queue_creation](/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_3.png) + +## 4. Create/Upload Email flow + +- Download the email flow from the [GitHub page](https://github.com/CiscoDevNet/webexcc-digital-channels). +- Navigate to **Webex Connect Flows** -> **v3.0** ->**Template** -> **Media Specific Workflows** -> **Email Inbound Flow.workflow.zip**, select the zip file and click download. +- Unzip the downloaded file. +- Go to Webex Connect, click on **Services** and select the service in which the Asset is created in step 2. It should be **My First Service** +- In the service click on **FLOWS** -> **CREATE FLOW** . +- Enter the **FLOW NAME** as **Email Inbound Flow**, select the **TYPE** as **Work Flow** and under **METHOD** select **Upload a flow**. +- Drag and drop the **Email Inbound Flow.workflow** flow that is downloaded in zip file, click **CREATE** and then click **SAVE**. + +![DC_Lab.12.7_Create-Upload_Email_flow](/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_1.png) + +- Click **Save** and in the created workflow find the **Queue Task**, click twice, select the **QUEUE NAME** as **Email_Q** and click on **SAVE**. + +![DC_Lab.12.7_Create-Upload_Email_flow](/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_2.png) + +- Click **Settings** on top right corner and switch to **Custom variables** tab. Here in the **bizemailid** row, update the default value with your email address of the Gmail account. Click **SAVE**. + +![DC_Lab.12.7_Create-Upload_Email_flow](/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_3.png) + +- Go to ***Resolve Conversation*** node and fill in ***Flow Id*** field with ***flowId*** value copied from the address bar of web browser. Then save changes. + +![DC_Lab.12.7_Create-Upload_Email_flow](/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_flowid.png) + +- Finally click on Make Live on top right corner -> Select the Application/Asset that we have created and click Make Live. + +![DC_Lab.12.7_Create-Upload_Email_flow](/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_4.png) + +## 5. Verification: Send an Email and accept the task + +- Go to personal email account and send an email to the support email address that was initially configured in the Email Asset. +- Go to the Agent Desktop and make the agent Available. + +![EmailVerification](/assets/images/DC_Lab.12.7_Verification_-_Send_an_Email_and_accept_the_task_1.png) + +- The Email will be offered to the agent. Click **Accept** to handle the email. Click "Reply" or Reply All" to the email and hit send button. + +![EmailVerification](/assets/images/DC_Lab.12.7_Verification_-_Send_an_Email_and_accept_the_task_2.png) + +- Add wrap up and close the task. + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.8 - Chat Channel Configuration + + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [\[Optional\] Create a service](#1-optional-create-a-service) | Practical Lab | EASY | 3 min | +| [Configure and Register Chat Asset](#2-configure-and-register-chat-asset) | Practical Lab | EASY | 3 min | +| [Create Entry Point for Chat](#3-create-entry-point-for-chat) | Practical Lab | EASY | 3 min | +| [Create Queue for Chat](#4-create-queue-for-chat) | Practical Lab | EASY | 3 min | +| [Create Chat Template](#5-create-chat-template) | Practical Lab | EASY | 3 min | +| [Website Widget Configuration](#6-website-widget-configuration) | Practical Lab | EASY | 3 min | +| [Create Chat Inbound Flow](#7-create-chat-inbound-flow) | Practical Lab | EASY | 3 min | +| [Create Chat Close Flow](#8-create-chat-close-flow) | Practical Lab | EASY | 3 min | +| [Publish Chat Widget](#9-publish-chat-widget) | Practical Lab | EASY | 3 min | +| [Verification: Initiate and Accept the Chat](#10-verification-initiate-and-accept-the-chat) | Practical Lab | EASY | 3 min | + + +## Introduction + +#### Lab Objective + +In this Lab, we will go through the tasks that are required to complete the basic web chat configuration. You will be able to initiate a chat to the Contact Center and be able to accept/respond to the chat by logging in as an agent. + +We will be configuring Service, Chat Assets, Entry Point, Queue, Chat Template, Website Settings, and corresponding workflows. + +#### Pre-requisite + +1. You received Webex CC Portal, Agent Desktop and Webex Connect URL . +2. You have admin credentials to complete configurations in Webex CC Management Portal and Engage Portal. +3. You have admin credentials to complete configurations in Connect Portal. +4. You have agent Credentials to handle the Chat. +5. You have successfully completed the previous Lab12.5 **Preconfiguration**. + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. \[Optional\] Create a service + +>**Note**: This step should be performed only if ***My First Service*** does not exist in Connect Portal. + +- Login to Connect Portal using provided URL ***https://cl1pod\.imiconnect.io/*** (where ***\*** is your POD number). +- Go to ***Services*** and press ***Create New Service*** button ar the right top corner. +- Input the name **`My First Service`** and press ***Create*** button. + +![DC_Lab.12.8_Create_Service](/assets/images/DC_Lab_12.8._Create_Service.png) + + +## 2. Configure and Register Chat Asset + +- Login to Connect Portal. +- Go to ***Assets*** -> ***Apps***, press ***Configure New App*** and select ***Mobile / Web*** option. + +![DC_Lab.12.8_Create_Asset_1](/assets/images/DC_Lab_12.8._Create_Asset_1.png) + +- Input ***Name*** as **`Chat_Asset`**. +- Toggle/enable ***Live Chat / In-AppMessaging*** to ***ON*** and choose ***Primary Transport Protocol*** as **`MQTT`** & ***Secondary Transport Protocol*** as **`Web Socket`** then tick ***Use Secured Port*** checkbox and press ***Save*** button. + +>**Note**: If there is an error that your request cannot be processed, please press ***Save*** button one more time. + +![DC_Lab.12.8_Create_Asset_2](/assets/images/DC_Lab_12.8._Create_Asset_2.png) + +- Once asset is saved, press ***Register To Webex Engage*** at the top, choose ***My First Service*** from the drop-down list and press ***Register*** button. + +![DC_Lab.12.8_Create_Asset_3](/assets/images/DC_Lab_12.8._Create_Asset_3.png) + +- Check and make sure the asset has been succesfully registered to the service and ***Register To Webex Engage*** button has been greyed out. + +![DC_Lab.12.8_Create_Asset_4](/assets/images/DC_Lab_12.8._Create_Asset_4.png) + +* Return to ***Assets*** -> ***Apps***, find ***ChatAsset***, copy ***App ID***, paste it into the text file and save. We will use it when configuring chat flow later. + +![DC_Lab.12.8_Create_Asset_5](/assets/images/DC_Lab_12.8._Create_Asset_5.png) + + +## 3. Create Entry Point for Chat + +- Login to Webex CC Management Portal URL with the credentials and access the menu ***Provisioning*** -> ***Entry Point/Queues*** -> ***Entry Point***. +- Press ***New Entry Point*** button. + +![DC_Lab.12.8_Create_Entry_Point_1](/assets/images/DC_Lab_12.8._Create_Entry_Point_1.png) + +- Input ***Name*** as **`Chat_EP`**. +- Select **`Chat`** from the ***Channel Type*** drop-down list. +- Select **`Chat_Asset`** as an ***Asset Name***. +- Set ***Service Level Threshold*** as **`7200`** seconds (2 hours). +- The ***Time Zone*** can stay as default value. +- Click on ***Save*** after comparing your values with the screenshot below. + +![DC_Lab.12.8_Create_Entry_Point_2](/assets/images/DC_Lab_12.8._Create_Entry_Point_2.png) + + +## 4. Create Queue for Chat + +- On Webex CC Management Portal access the menu ***Provisioning*** -> ***Entry Point/Queues*** -> ***Queue***. +- Click on ***New Queue***. + +![DC_Lab.12.8_Create_Queue_1](/assets/images/DC_Lab_12.8._Create_Queue_1.png) + +- Input ***Name*** as **`Chat_Q`**. +- Select **`Chat`** in the ***Channel Type*** section. +- Leave the ***Queue Routing Type*** as default value **`Longest Available Agent`**. +- In the ***Chat Distribution*** click on ***Add Group*** and select `Team1`. + +![DC_Lab.12.8_Create_Queue_2](/assets/images/DC_Lab_12.8._Create_Queue_2.png) + +- Set ***Service Level Threshold*** as **`7200`** seconds (2 hours). +- Set ***Maximum Time in Queue*** as **`10800`** seconds (3 hours). +- The ***Time Zone*** can stay as default value. +- Click on ***Save*** after comparing your values with the screenshot below. + +![DC_Lab.12.8_Create_Queue_3](/assets/images/DC_Lab_12.8._Create_Queue_3.png) + + +## 5. Create Chat Template + +- Login to Webex Connect UI. +- Go to ***Tools*** -> ***Templates*** and press ***Add new Template*** button. + +![DC_Lab.12.8_Create_Template_1](/assets/images/DC_Lab_12.8._Create_Template_1.png) + +- Provide **_Name_** as **`Chat_Template`** and choose **_Channel_** as **_Live Chat / In-App Messaging_** +- Select ***Message Type*** as ***Form****. +- Provide the ***Title*** as **`Welcome to Webex CC Chat`** and this will be the welcome message. +- Click on ***Add Field*** to start adding the fields into the template. + +![DC_Lab.12.8_Create_Template_2](/assets/images/DC_Lab_12.8._Create_Template_2.png) + +- Add ***Name*** field with the following parameters into the form: + +| **Parameter Name** | **Parameter Value** | +| --------------- | --------------- | +| Type | Text | +| Name | Name | +| Label | Name | +| Mandatory Field | On | + +![DC_Lab.12.8_Create_Template_3](/assets/images/DC_Lab_12.8._Create_Template_3.png) + +- Click on ***Add Field*** button and add ***Email*** field with the following parameters into the form: + +| **Parameter Name** | **Parameter Value** | +| --------------- | --------------- | +| Type | Email | +| Name | Email | +| Label | Email | +| Mandatory Field | On | + +![DC_Lab.12.8_Create_Template_4](/assets/images/DC_Lab_12.8._Create_Template_4.png) + +- Click on ***Save*** after comparing your values with the screenshot below. + +![DC_Lab.12.8_Create_Template_5](/assets/images/DC_Lab_12.8._Create_Template_5.png) + +## 6. Website Widget Configuration + +- Login to WxCC Management Portal access the menu and cross launch Engage Portal by choosing ***New Digital Channels***. + +![DC_Lab.12.8_Create_Website_1](/assets/images/DC_Lab_12.8._Create_Website_1.png) + +- Go to ***Assets*** -> search and edit ***Chat_Asset*** which you have created in Connect Portal. + +![DC_Lab.12.8_Create_Website_2](/assets/images/DC_Lab_12.8._Create_Website_2.png) + +- Scroll down and click on ***Save Changes*** button. +- Scroll to top of the page and choose ***Websites*** tab. +- Click on ***ADD Website***. + +![DC_Lab.12.8_Create_Website_3](/assets/images/DC_Lab_12.8._Create_Website_3.png) + +- Fill in the respective fields as per the table below: + +| **Parameter Name** | **Parameter Value** | +| ----------------------------- | -------------------------- | +| Chat Widget Language | English-US | +| Display Name | Webex CC Chat Demo | +| Byline Text | Web chat of the future | +| Button Text | Start Chat | +| First message | Hello! Welcome to the chat | +| PCI Compliance Banner Message | This chat is PCI compliant | +| Domain | www.w3schools.com | +| Set wait time | Disabled | +| Set Chat Announcement | Enabled | + +- Scroll down and click on ***Save changes*** button after comparing your values with the screenshot below. + +![DC_Lab.12.8_Create_Website_4](/assets/images/DC_Lab_12.8._Create_Website_4.png) + +![DC_Lab.12.8_Create_Website_5](/assets/images/DC_Lab_12.8._Create_Website_5.png) + +![DC_Lab.12.8_Create_Website_6](/assets/images/DC_Lab_12.8._Create_Website_6.png) + +- Scroll up, select ***Appearance*** and change the settings: + - \[Optional\] Widget Color + - \[Optional\] Widget Button Type + - \[Optional\[ Logo + - Enable Emojis + - Enable Attachments +- Press ***Save changes*** button at the bottom of the page. + +![DC_Lab.12.8_Create_Website_7](/assets/images/DC_Lab_12.8._Create_Website_7.png) + +- Scroll up, select ***Widget Visibility*** tab and make sure that ***Force Turn Off Widget*** switch is disabled. Then select ***Widget Visibility*** as ***Show without any restrictions*** and save changes. + +![DC_Lab.12.8_Create_Website_8](/assets/images/DC_Lab_12.8._Create_Website_8.png) + +- Now click on ***<*** arrow near ***Website Settings*** and go-back to edit your chat asset. + +![DC_Lab.12.8_Create_Website_9](/assets/images/DC_Lab_12.8._Create_Website_9.png) + +- Select ***Installation*** then click on ***Copy*** to copy the chat script to clipboard. + +![DC_Lab.12.8_Create_Website_10](/assets/images/DC_Lab_12.8._Create_Website_10.png) + +![DC_Lab.12.8_Create_Website_10](/assets/images/DC_Lab_12.8._Create_Website_11.png) + +- Paste copied script into a text editor and save it. We will paste it on web site later. + +## 7. Create Chat Inbound Flow + +>***Note***: Chat Inbound Flow is triggered whenever end user started new chat session or sent a message via existing one. + +- Navigate to GitHub page with Webex Connect Flows - [GitHub page](https://github.com/CiscoDevNet/webexcc-digital-channels). +- Goto to ***Webex Connect Flows*** -> ***v3.0*** -> ***Template*** -> ***Media Specific Workflows*** -> ***Live Chat Inbound Flow.workflow.zip*** and click ***Download***. +- Unzip the file. +- Go to Connect Portal, click on **Services** and select the service in which the Asset is created in step 2 above. It should be ***My First Service***. +- In the service click on **Flows** -> **Create Flow** . + +![DC_Lab.12.8_Create_Flow_1](/assets/images/DC_Lab_12.8._Create_Flow_1.png) + +- Enter the ***Flow Name*** as **`Chat Inbound Flow`**, select the ***Type*** as ***Work Flow*** and under ***Method*** select ***Upload a flow***. +- Drag and drop unzipped ***Live Chat Inbound Flow.workflow*** flow, click ***Create***. + +![DC_Lab.12.8_Create_Flow_2](/assets/images/DC_Lab_12.8._Create_Flow_2.png) + +- You will be redirected to the new flow opened in the flow builder. Click ***Save*** to save the changes. + +![DC_Lab.12.8_Create_Flow_3_1](/assets/images/DC_Lab_12.8._Create_Flow_3_1.png) + +- In the ***Pre-chat form*** node the ***Form Template*** needs to be selected as ***Chat_Template*** created in step 5 above. Press ***Save*** button to save changes in node configuration. + +![DC_Lab.12.8_Create_Flow_4_1](/assets/images/DC_Lab_12.8._Create_Flow_4_1.png) + +- In the ***Receive*** node also, select the same ***Chat_Template*** in ***Form Template*** drop-down list. + +![DC_Lab.12.8_Create_Flow_5_1](/assets/images/DC_Lab_12.8._Create_Flow_5_1.png) + +- Go to ***Transition Actions (Optional)*** tab of ***Receive*** node, check and make sure the values of ***customerName*** and ***customerEmail*** variables corresponds to the names of web chat template fields in ***Output Variables*** -> ***Receive*** -> ***InApp - Form Response*** section on the right pane. Correct the values if needed and save the node. + +>***Note***: The value of each variable has the following format: ***$(NodeID.OutputVariableName)***. In our case NodeID is 2438 (you can find it in the left bottom corner of ***Receive*** window), ***OutputVariableName*** is just exact name from ***Output Variables*** -> ***Receive*** -> ***InApp - Form Response*** section on the right pane. + +![DC_Lab.12.8_Create_Flow_6_1](/assets/images/DC_Lab_12.8._Create_Flow_6_1.png) + +- Go to ***Resolve Conversation*** node and fill in ***Flow Id*** field with ***flowId*** value copied from the address bar of web browser tab. In this example, Flow Id is 4464. Then save changes. + +![DC_Lab.12.8_Create_Flow_6_2](/assets/images/DC_Lab_12.8._Create_Flow_6_2.png) + +- In ***Queue Task*** node select ***Queue Name*** as ***Chat_Q*** created in Webex CC Management Portal in step 4 above and save changes. + +![DC_Lab.12.8_Create_Flow_7_1](/assets/images/DC_Lab_12.8._Create_Flow_7_1.png) + +- Click on ***Settings*** (gear icon) on top right corner of flow builder window and disable ***Descriptive logs*** on ***General*** tab. + +![DC_Lab.12.8_Create_Flow_8_1](/assets/images/DC_Lab_12.8._Create_Flow_8_1.png) + +- Then go to ***Custom variables*** tab. Here enter ***appId*** as the ***App ID*** of the asset created in step 2 above. In addition. enter ***liveChatDomain*** as **`www.w3schools.com`** and save changes. + +![DC_Lab.12.8_Create_Flow_8_2](/assets/images/DC_Lab_12.8._Create_Flow_8_2.png) + +- Click on ***Save*** button on top right corner to save the entire flow. +- Click on ***Make Live*** on top right corner (near ***Save*** button) then select the ***Application*** as ***Chat_Asset*** in pop-up window and click ***Make Live***. Wait around 2-3 minutes until flow goes live. + +>***Note***: If there is ***Forbidden*** message after you pressed ***Make Live*** button, please close Make Live window, open it one more time, select the asset again and press ***Make Live*** button one more time. + +![DC_Lab.12.8_Create_Flow_9_1](/assets/images/DC_Lab_12.8._Create_Flow_9_1.png) + + +## 8. Create Chat Close Flow + +>***Note***: Chat Close Flow is triggered every time whenever the end user closed the conversation thread from the widget. + +- Navigate to GitHub page with Webex Connect Flows - [GitHub page](https://github.com/CiscoDevNet/webexcc-digital-channels). +- Go to ***Webex Connect Flows*** -> ***v3.0*** -> ***Template*** -> ***Media Specific Workflows*** -> ***Live Chat Close Flow.workflow.zip*** and click ***Download.*** +- Unzip the file. +- Go to Connect Portal, click on **Services** and select the service in which the Asset is created in step 2 above. It should be ***My First Service***. +- In the service click on **Flows** -> **Create Flow**. +- Enter the ***Flow Name*** as **`Chat Close Flow`**, select the ***Type*** as ***Work Flow*** and under ***Method*** select ***Upload a flow***. +- Drag and drop unzipped ***Live Chat Close Flow.workflow*** flow, click ***Create***. + +![DC_Lab.12.8_Create_Closed_Flow_1](/assets/images/DC_Lab_12.8._Create_Closed_Flow_1.png) + +- You will be redirected to the new flow opened in the flow builder. Click ***Save*** to save the changes. + +![DC_Lab.12.8_Create_Closed_Flow_2](/assets/images/DC_Lab_12.8._Create_Closed_Flow_2.png) + +- Click on ***Save*** button on top right corner to save the entire flow. +- Click on ***Make Live*** on top right corner (near ***Save*** button) then select the ***Application*** as ***Chat_Asset*** in pop-up window and click on ***Make Live***. Wait around 2-3 minutes until flow goes live. + +>***Note***: If there is ***Forbidden*** message after you pressed ***Make Live*** button, please close Make Live window, open it one more time, select the asset again and press ***Make Live*** button one more time. + +![DC_Lab.12.8_Create_Closed_Flow_3](/assets/images/DC_Lab_12.8._Create_Closed_Flow_3.png) + + +## 9. Publish Chat Widget + +- Go to [HTML w3school Editor](https://www.w3schools.com/html/tryit.asp?filename=tryhtml_intro) +- Paste the script which you copied in step 6 just above the `````` tag in the left window and click on ***Run***. You should see chat widget icon in the right bottom corner of the window. + +![DC_Lab.12.8_Publish_Widget_1](/assets/images/DC_Lab_12.8._Publish_Widget_1.png) + + +## 10. Verification: Initiate and Accept the Chat + +- Login to the Agent Desktop and make the agent ***Not Ready***. +- Click on chat widget icon in the right bottom corner of [HTML TryIt Editor](https://www.w3schools.com/html/tryit.asp?filename=tryhtml_intro) window and press ***Start Chat*** button. + +![DC_Lab.12.8_Verify_1](/assets/images/DC_Lab_12.8._Verify_1.png) + +- Provide Name and Email to start chat. + +![DC_Lab.12.8_Verify_2](/assets/images/DC_Lab_12.8._Verify_2.png) + +- Go to the Agent Desktop and make the agent Available. Then accept incoming chat conversation by pressing ***Accept*** button on the chat card on the left pane. + +![DC_Lab.12.8_Verify_3](/assets/images/DC_Lab_12.8._Verify_3.png) + +- Make sure end user and agent are able to exchange messages with each other. Then you can close the chat. + +![DC_Lab.12.8_Verify_4](/assets/images/DC_Lab_12.8._Verify_4.png) + +![DC_Lab.12.8_Verify_5](/assets/images/DC_Lab_12.8._Verify_5.png) + +--- + +**Congratulations, you have completed this section!** + + +--- + + +# Lab.12.9 - Facebook Messenger Channel Configuration + + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ------------------------------------------------------------------------------------- | -------- | --------------- | ---------------- | +| [Facebook Page configuration](#1-facebook-page-configuration) | Practical Lab | EASY | 5 min | +| [Facebook Messenger Asset creation and Register to Webex CC](#2-facebook-messenger-asset-creation-and-register-to-webex-cc) | Practical Lab | EASY | 5 min | +| [Create Entry Point and Queue](#3-create-entry-point-and-queue) | Practical Lab | EASY | 5 min | +| [Create/Upload Facebook Messenger flow](#4-createupload-facebook-messenger-flow) | Practical Lab | EASY | 5 min | +| [Verification - start Facebook Chat and accept the request](#5-verification---start-facebook-chat-and-accept-the-request) | Practical Lab | EASY | 5 min | + + +## Introduction + +#### Lab Objective + +In this Lab, we will go through the tasks that are required to complete the basic Facebook Messenger (FBM) integration. You will be able to initiate a Facebook contact to the Contact Center from Facebook Messenger and be able to accept/respond to the contact by logging in as an agent. + +In this lab you will be configuring Service, Chat Assets, Entry Point, Queue, Chat Template, Website Settings, and corresponding workflows. + + +#### Pre-requisite + +1. You received an admin credentials to configure in Management Portal and Webex Connect. +2. You have successfully completed the previous Lab12.5 **Preconfiguration** +3. You have a Facebook Account + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. Facebook Page configuration + +- Customer/Partner should have a Facebook account to create a Facebook Business page + +- Login to Facebook and create a business page that can be used in Webex Contact Center for polling and handling the messenger chats Additional details of Facebook page setup is available here: [Facebook Business page setup](https://www.facebook.com/business/pages/set-up) + +- Click on `Create a Page` button + +![DC_Lab_12.9_Facebook_Page_configuration](/assets/images/DC_Lab_12.9_Facebook_Page_configuration1.jpg) + +- If you are logged in already to Facebook, you will be presented with the Business Page creation tool. Simply give the page a Name and a Category then Click `Create Page` button + +![DC_Lab_12.9_Facebook_Page_configuration](/assets/images/DC_Lab_12.9_Facebook_Page_configuration2.jpg) + +[Back to top](#table-of-contents) + +## 2. Facebook Messenger Asset creation and Register to Webex CC + +- Login to your respective Webex Connect UI using the provided URL https://cl1pod**X**.imiconnect.io/ (where **X** is your POD number). + +- Navigate to `Assets` > `Apps` > `Configure New App` > `Messenger` and Click on `Add Messenger Page` button + +![FM1](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC1.gif) + +- If you haven't done already, authenticate with your FB account where you have a page already created. Then select the respective page that you want to integrate + +![FM2](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC2.jpg) + +- Accept all default permissions + +![FM3](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC3.jpg) + +- That completes the linking of the Facebook connect with Webex Connect + +![FM4](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC4.jpg) + +- Finally select the Business Page you want to link to the Asset + +![FM5](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC5.jpg) + +- Provide the name and click `Save` + +![FM6](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC6.jpg) + +- Click `Register to Webex Engage`  in the ‘Configure New App-Messenger’ window -> In the resulting window select the service and click `Register`. + +![FM7](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC7.jpg) + +- Confirm that registration with Webex CC completed successfully + +![FM8](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC8.jpg) + +- Scroll down and take note of the M.Me link in the `Page Discovery Addons` section. We will use that link to trigger the Facebook Messenger interaction from the Customer end. Also take note of the numeric string parameter in the M.Me link. That's the `Facebook Page ID` which we will also need later when configuring the flow. + +![FM9](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC9.jpg) + +- Click on the back arrow to go back to the list of Assets Apps. Then take note of the application ID (app id) we just created. We will also need that app ID in the flow + +![FM10](/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC10.jpg) + +[Back to top](#table-of-contents) + +## 3. Create Entry Point and Queue + +#### 1. Create Entry Point in Management Portal + +- Click on **_Provisioning_** and select **_Entry Points/Queues_** > **_Entry Point_**. + +- Click on `New Entry Point`. + +- Input **_Name_** as `FBM_EP`. + +- Select `Social Channel` in the **_Channel Type_** section. + +- Select `Facebook Messenger` in the **_Social Channel Type_** section. + +- Leave the **_Asset Name_** as the configured value earlier. + +- The **_Time Zone_** can stay as default value. + +- Click on **Save** after comparing your values with the screenshot below. + +![DC_Lab_12.9_Create_Entry_Point_and_Queue](/assets/images/DC_Lab_12.9_Create_Entry_Point_and_Queue1.jpg) + +#### 2. Create Queue in Management Portal + +- Click on **_Provisioning_** and select **_Entry Points/Queues_** > **_Queue_**. + +- Click on `New Queue`. + +- Input **_Name_** as `FBM_Q`. + +- Select `Social Channel` in the **_Channel Type_** section. + +- Set Queue Routing Type to Longest Available Agent + +- Click `Add Group` in the **_Conversation distribution_** section. + +- Select the Agent based teams created in the previous lab and click `Save` . Once saved, click `Close` to exit this window. + +- Input **_Maximum Time in Queue_** as `300`. + +- The **_Time Zone_** can stay as default value. + +- Click on **Save** after comparing your values with the screenshot below. + +![DC_Lab_12.9_Create_Entry_Point_and_Queue](/assets/images/DC_Lab_12.9_Create_Entry_Point_and_Queue2.jpg) + +[Back to top](#table-of-contents) + +## 4. Create/Upload Facebook Messenger flow + +#### 1. Initial flow loading + +- Download the default Facebook Inbound flow from the [GitHub page](https://github.com/CiscoDevNet/webexcc-digital-channels). + +- Navigate to **Webex Connect Flows** -> **v3.0** ->**Template** -> **Media Specific Workflows** -> **Facebook Inbound Flow.workflow.zip**, select the zip file and click download. + +- Unzip the downloaded file. + +- Go to Webex Connect, click on **Services** and select the service in which the Asset is created in step 2. It should be **My First Service** + +- In the service click on **FLOWS** -> **CREATE FLOW** . + +![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow1.jpg) + +- Enter the **FLOW NAME** as **FBM Inbound Flow**, select the **TYPE** as **Work Flow** and under **METHOD** select **Upload a flow**. + +- Drag and drop the **Facebook Inbound Flow.workflow** flow file that you unzipped, click **CREATE** and then click **SAVE**. + +![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow2.jpg) + +#### 2. Start node and Custom Variables + +- A page will load with the imported workflow. We must make some changes to the default inbound flow based on our setup. + +- First Click `Save` in the `Configure APP Event` page that loaded, this defines what will trigger the flow and the default settings are already good. + +![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow3.jpg) + +- Click on the gear button on the top right to load the flow settings dialog + +![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow4.jpg) + +- Select the Custom Variables tab and set the following Default Values: + +*FBPageID*: to the numeric string in the M.Me link we saved earlier in Step 2. +*appid*: Application ID (appID) from the FBM Asset from Step 2 + +![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow5.jpg) + +- Click `Save` + +#### 3. Edit Queue Task node + +- In the created workflow find the **Queue Task**, click twice, select the **QUEUE NAME** as **FBM_Q** and click on **SAVE**. + +![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow6.jpg) + +- Go to ***Resolve Conversation*** node and fill in ***Flow Id*** field with ***flowId*** value copied from the address bar of web browser tab. Then save changes. + ![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flowID.png) + +- Finally click on Make Live on top right corner + +![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow7.jpg) + +- Select the Application/Asset that we have created and click `Make Live`. + +![DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow](/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow8.jpg) + +- Wait for 2 minutes and verify that the flow is published successfully. + +[Back to top](#table-of-contents) + +## 5. Verification - start Facebook Chat and accept the request + +- Open a new tab and login to the Agent Desktop if you haven't done already and make the agent Available (if you haven't done already in Lab2). + +![FC1](/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request1.png) + +- Open a new tab on the same browser session to make sure you are still authenticated to Facebook. Go to the M.Me URL you copied in Step 2 and the following FBM page should load with the Facebook Business page chat you created earlier + +![FC2](/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request2.jpg) + +- Start chatting and that should trigger a contact into Webex Contact Center that will get routed according to the flow we configured in Step 4. A notification should appear that should help you switch to the agent desktop tab to accept the contact + +![FC3](/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request3.jpg) + +![FC4](/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request4.jpg) + +- Type a response and hit send button. + +![FC5](/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request5.jpg) + +- Response will be received in the other tab where the FBM page is: + +![FC6](/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request6.jpg) + +- End the contact + +![FC7](/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request7.jpg) + +- Add wrap up and close the task. + +![FC8](/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request8.jpg) + + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.10 - SMS Channel Configuration + + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [SMS number procurement](#1-sms-number-procurement) | Practical Lab | EASY | 5 min | +| [Create SMS Asset and Register to WebexCC](#2-create-sms-asset-and-register-to-webexcc) | Practical Lab | EASY | 5 min | +| [Workflow Association](#3-workflow-association) | Practical Lab | EASY | 5 min | +| [Modifying the Flow](#4modifying-the-flow) | Practical Lab | EASY | 5 min | + + +#### Lab Objective + +This lab is designed to complete required SMS configurations in Webex Connect. You will be able to initiate a contact from a mobile number (SMS) and will be able to accept and respond to the SMS contact by logging in as an agent. + +#### Pre-requisite + +- WxCC Portal, Agent Desktop and Webex connect URL +- Admin credentials to complete configurations in WxCC portal and Webex connect. +- Agent Credentials to Handle the Chat +- **SMS number procurement process should be completed (Please work with your PSM)** +- SMS number should be assigned in your Webex Conenct tenant + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. SMS number procurement + +- SMS Numbers cannot be procured directly from the WxCC integrated Webex Connect tenant +- SMS Numbers are not assigned by default to any of the WxCC tenants. +- Please note that Partners have to go through a procurement process and work with your respective PSM to enable SMS and get numbers assigned to the gold tenant +- Once the procurement process is completed, SMS Numbers are assigned to the tenant by the backend operations team +- Please complete this step before proceeding further. + + +## 2. Create SMS Asset and Register to WebexCC + +- Login to Webex Connect tenant using your credentials. + +From the left side pane, click on Assets ---> Numbers + +![12.10.1](/assets/images/12.10.1.png) + +- Select the number from the list. Click on Manage and Register to Webex Engage.In the subsequent window select the service and click register. + +![12.10.2](/assets/images/12.10.2.png) + +- Login to the Contact Centre Management Portal . Click on Provisioning ---> Entry Points. Click on New entry Point. + +![12.10.3](/assets/images/12.10.3.png) + +- Enter a unique name, select the channel type as social, Social Channel Type as SMS and select the Asset that was created in Webex Connect as the Asset name. Click Save. + +![12.10.4](/assets/images/12.10.4.png) + +- Click on Provisioning---->Queue’s from the Left pane and click New Queue.Enter a unique name and select the Channel Type as Social Channel. Add the other required details and click Save. + +![12.10.5](/assets/images/12.10.5.png) + +## 3. Workflow Association + +- Download the SMS flow from the [GitHub page](https://github.com/CiscoDevNet/webexcc-digital-channels) +- Navigate to webexcc-digital-channels/Webex Connect Flows/v3.0/Template/Media Specific Workflows/SMS Inbound Flow.workflow.zip select the zip file and click download + +![12.10.6](/assets/images/12.10.6.png) + +- Unzip the downloaded file. +- Go to Webex Connect, click on Services and select the service in which the Asset is created in. +- In the service click on FLOWS -> CREATE FLOW +- Enter the FLOW NAME as SMS Inbound Flow, select the TYPE as Work Flow and under METHOD select Upload a flow. +- Drag and drop the SMS Inbound Flow.workflow flow that is downloaded in zip file, click CREATE + +![12.10.7](/assets/images/12.10.7.png) + +- In the resulting window select the Incoming number from the dropdown list and click Save + +![12.10.12](/assets/images/12.10.12.png) + +## 4. Modifying the Flow + +- Open the Resolve Conversation Node in the flow. Select the flow id from the URL and enter it in the Flow ID box and click Save. + + ![12.10.8.1](/assets/images/12.10.8.1.png) + +- Open the Queue Task Node in the flow. Select the Queue that you created in an earlier step and click Save. + +![12.10.8](/assets/images/12.10.8.png) + +- Open up an SMS node in the flow and enter the from Number variable selected from the right side pane as shown below.Click Save +- Repeat the above step for all the SMS nodes in the flow. + +![12.10.9](/assets/images/12.10.9.png) + +- Save the flow and Make Live + +![12.10.10](/assets/images/12.10.10.png) + +- Login to the agent desktop, initiate an SMS to the configured number. Once the interaction pops up on the agent desktop, accept the conversation + +![12.10.11](/assets/images/12.10.11.png) + +- Test the conversation between the agent and the customer. +- End the conversation and add a Wrapup Code. + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.11 - WhatsApp Channel Configuration + + +## Table of Contents + + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Verify WhatsApp Number Assignment](#1-verify-whatsapp-number-assignment) | Practical Lab | EASY | 5 min | +| [WhatsApp Asset registration to WebexCC](#2-whatsapp-asset-registration-to-webexcc) | Practical Lab | EASY | 5 min | +| [WhatsApp Entry Point and Queue creation](#3-whatsapp-entry-point-and-queue-creation) | Practical Lab | EASY | 5 min | +| [Create/Upload WhatsApp flow](#4-createupload-whatsapp-flow) | Practical Lab | EASY | 5 min | +| [Verification - send WhatsApp message and accept the request](#5-verification---send-whatsapp-message-and-accept-the-request) | Practical Lab | EASY | 5 min | + + +## Introduction + +#### Lab Objective + +In this Lab, we will go through the tasks that are required to complete the basic WhatsApp integration. You will be able to initiate a WhatsApp contact to the Contact Center and be able to accept/respond to the contact by logging in as an agent. + +In this lab you will be configuring **WhatsApp** number settings, Assets, Entry Point and corresponding workflows. All these steps are required for integrating WhatsApp with our application. + +#### Pre-requisite + +1. You received an admin credentials to configure in Management Portal and Webex Connect. +2. You received the WhatsApp number associated with your tenant. +3. You have successfully completed the previous Lab12.5 **Pre-configuration** +4. **WhatsApp Numbers cannot be procured directly from the Webex Contact Center integrated Webex Connect tenant (please work with your PSM). Note: For production use, please note that customers will have to work with Partners to go through a procurement process to enable WhatsApp and get numbers assigned to the tenant.** + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. Verify WhatsApp Number Assignment + +- Login to your respective Webex Connect UI using the provided URL https://cl1pod**X**.imiconnect.io/ (where **X** is your POD number). +- Navigate to Assets > App and verify that the tenant you are using has a SMS number assigned + +![DC_Lab_12.11_Verify_Whatsapp_Number_Assignment](/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment1.png) + +- Identify and make note of the APP ID (We will need this later in the flow configuration) + +![DC_Lab_12.11_Verify_Whatsapp_Number_Assignment](/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment2.png) + +- Select actions and click **Manage** + +![DC_Lab_12.11_Verify_Whatsapp_Number_Assignment](/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment3.png) + +- Identify and make a note of the **Number** and **WABA ID** (We will need this later in the flow configuration) + +![DC_Lab_12.11_Verify_Whatsapp_Number_Assignment](/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment4.png) + +## 2. WhatsApp Asset registration to WebexCC + +- In the WhatsApp number assigned, under actions select the 'Manage' option + +![DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC1](/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC1.png) + +- Click 'Register to WebexCC option' + +![DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC1](/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC2.png) + +- In the resulting window, select a service under which this asset would be managed + +![DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC1](/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC3.png) + +- Verify that the 'Register to Webex CC' option is now disabled and there is a message indicating the time when the asset was registered along with the service to which it is assigned. + +![DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC1](/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC4.png) + +## 3. WhatsApp Entry Point and Queue creation + +- Login to Webex Contact Centre administration portal +- Click on **_Provisioning_** and select **_Entry Points/Queues_** > **_Entry Point_**. +- Click on `New Entry Point`. + +![DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation](/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation1.jpg) + +- Input **_Name_** as `WhatsApp_EP`. +- Select `Social Channel` in the **_Channel Type_** section. +- Select `WhatsApp` in the **_Social Channel Type_** section. +- Leave the **_Asset Name_** as appeared value `WhatsApp Asset assigned in your Connect tenant`. +- The **_Time Zone_** can stay as default value. +- Click on **Save** after comparing your values with the screenshot below. + +![DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation](/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation2.png) + +- Click on **_Provisioning_** and select **_Entry Points/Queues_** > **_Queue_**. +- Click on `New Queue`. + +![DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation](/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation3.jpg) + +- Input **_Name_** as `WhatsApp_Queue`. +- Select `Social Channel` in the **_Channel Type_** section. +- Click `Add Group` in the **_Conversation distribution_** section. + +![DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation](/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation4.png) + +- Select the Agent based teams created in the previous lab and click `Save` . Once saved, click `Close` to exit this window. + +![DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation](/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation5.png) + +- Input **_Maximum Time in Queue_** as `300`. +- The **_Time Zone_** can stay as default value. +- Click on **Save** after comparing your values with the screenshot below. + +![DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation](/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation6.png) + +## 4. Create/Upload WhatsApp flow + +- Download the WhatsApp flow from the [GitHub page](https://github.com/CiscoDevNet/webexcc-digital-channels). +- Navigate to **Webex Connect Flows** -> **v3.0** ->**Template** -> **Media Specific Workflows** -> **Whatsapp Inbound Flow.workflow.zip**, select the zip file and click download. +- Unzip the downloaded file. +- Go to Webex Connect, click on **Services** and select the service in which the Asset is created in step 2. It should be **My First Service** +- In the service click on **FLOWS** -> **CREATE FLOW** +- Enter the **FLOW NAME** as **WhatsApp Inbound Flow**, select the **TYPE** as **Work Flow** and under **METHOD** select **Upload a flow**. +- Drag and drop the **Whatsapp Inbound Flow.workflow** flow that is downloaded in zip file, click **CREATE** + +![DC_Lab_12.11_Create-Upload_Whatsapp_flow](/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow2.png) + +- Once the flow is saved, the 'Configure WhatsApp Event' node will open. Select incoming message as trigger and click **Save** + +![DC_Lab_12.11_Create-Upload_Whatsapp_flow](/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow3.png) + +- Open Custom variables and update the value for **WANumber** and **appid** (These are the values that were identified in Step-1) and click on **SAVE**. + +![DC_Lab_12.11_Create-Upload_Whatsapp_flow](/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow4.png) + +- In the created workflow find the **Queue Task**, click twice, select the **QUEUE NAME** as **WhatsApp_Queue** and click on **SAVE**. + +![DC_Lab_12.11_Create-Upload_Whatsapp_flow](/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow5.png) + +- Go to ***Resolve Conversation*** node and fill in ***Flow Id*** field with ***flowId*** value copied from the address bar of web browser tab. Then save changes. + +![DC_Lab_12.11_Create-Upload_Whatsapp_flow](/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flowID.png) + +- Finally click on Make Live on top right corner and click Make Live. + +![DC_Lab_12.11_Create-Upload_Whatsapp_flow](/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow6.png) + +- Wait for 2 minutes and verify that the flow is published successfully & shows Live in state. + + + +## 5. Verification - send WhatsApp message and accept the request + +- Login to the Agent Desktop and make the agent Available. + +![WA1](/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request1.png) + +- In your personal mobile phone, add the WhatsApp number configured in the previous step as a new contact. (The screenshot is for reference. Please use the number assigned to your pod) + +![WA2](/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request2.png) + +- Open WhatsApp and look up the contact created in the previous step + +![WA3](/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request3.png) + +- Send a message to the contact identified in the previous step to initiate the conversation. + +![WA4](/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request4.png) + +- The WhatsApp contact will be offered to the agent. Click "Accept" to handle the contact. + +![WA5](/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request5.png) + +- Type a response and hit send button. + +![WA6](/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request6.png) + +- End the contact + +![WA7](/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request7.png) + +- Add wrap up and close the task. + +![WA8](/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request8.png) + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.12 - Connect Templates + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------- | ----------------- | --------------- | ---------------- | +| [Understanding Connect Templates](#1-understanding-connect-templates) | Read & Understand | EASY | 5 min | +| [Create Chat Templates in Connect](#2-create-chat-templates-in-connect) | Read & Understand | EASY | 5 min | +| [Create Email Templates in Connect](#3-create-email-templates-in-connect) | Read & Understand | EASY | 5 min | +| [Create SMS Templates in Connect](#4-create-sms-templates-in-connect) | Read & Understand | EASY | 5 min | + +## Introduction + +#### Lab Objective + +This section is designed to introduce Connect templates, which can be used for sending notifications from flows to the end user through various digital channels. In this section you will find configuration steps and examples of use. The goal is to understand the purpose of the most popular templates. + + +## 1. Understanding Connect Templates + +Connect templates can be configured on the platform and used within flows. Here are few key points to note about Connect templates which provide better understanding of the feature: +- Templates can be referenced in various flows. +- Templates can be used to send messages from flow to the end users through various digital channels. +- Template text can include simple text, URLs or forms. + +Each kind of template has different set of parameters depending on the type of digital channel which it is intended for. +- To create a template for any kind of digital channel, login to Connect Portal, then go to ***Tools*** -> ***Templates*** and press ***Add new Template*** button. + +![DC_Lab.12.12_Create_Connect_1](/assets/images/DC_Lab_12.12._Create_Connect_1.png) + +* You will be redirected to ***Manage Template*** window where you can select ***Channel*** and then provide other parameters of the template. + +![DC_Lab.12.12_Create_Connect_2](/assets/images/DC_Lab_12.12._Create_Connect_2.png) + + +## 2. Create Chat Templates in Connect + +Let's create Chat Form template which can be used to request initial information about the end user just after chat is initiated. This process is decribed in details in ***Create Chat Flow*** lab. + +- Select ***Channel*** as ***Live Chat / In-App Messaging*** in ***Manage Template*** window to create chat template. Then provide ***Name***, ***Message Type*** as ***Form***, ***Title***, and press ***Add Field*** button to add fields to the form. Once all necessary fields have been added, you can see the entire form in ***Preview*** section on the right. Save the template after the form is constructed. + +![DC_Lab.12.12_Create_Connect_2](/assets/images/DC_Lab_12.12._Create_Connect_3.png) + +- After chat template has been created, you can use it in ***Pre-chat form*** and ***Receive*** nodes of the chat flow to get necessary details from the end user which initiated the chat. After selecting the template save changes and make the flow live. + +![DC_Lab.12.12_Create_Connect_2](/assets/images/DC_Lab_12.12._Create_Connect_4.png) + +- The end user will get the form created in the template within chat widget. + +![DC_Lab.12.12_Create_Connect_2](/assets/images/DC_Lab_12.12._Create_Connect_4_1.png) + +- The details eneterd by the user in the form will be forwarded to the agent which accepted chat request. + +![DC_Lab.12.12_Create_Connect_2](/assets/images/DC_Lab_12.12._Create_Connect_4_2.png) + + +## 3. Create Email Templates in Connect + +Let's create Email template which notifies end user after incoming request over email has been accepted and ququed in Webex CC. + +- Select ***Channel*** as ***Email*** in ***Manage Template*** window to create email template. Then provide ***Name***, ***Reference ID***, ***Template Type***, ***Subject*** and save changes. + +![DC_Lab.12.12_Create_Connect_5](/assets/images/DC_Lab_12.12._Create_Connect_5.png) + +- You will be redirected to Email Composer. Please build the email using the canvas in the center and building blocks on the left-hand side. After email template is ready, press ***Save & Exit*** at the top right corner. + +![DC_Lab.12.12_Create_Connect_6_1](/assets/images/DC_Lab_12.12._Create_Connect_6_1.png) + +- Insert Email node into the corresponding flow just after Queue Task node. Provide necessary details including ***Email Type***, ***Template Type***, ***Template***, save changes and make the flow live. + +![DC_Lab.12.12_Create_Connect_6_2](/assets/images/DC_Lab_12.12._Create_Connect_6_2.png) + +- After the flow is triggered and email request is queued, the end user will be notified over email. + + +## 4. Create SMS Templates in Connect + +Let's create SMS template which notifies end user after incoming request over SMS has been accepted and ququed in Webex CC. + +- Select ***Channel*** as ***SMS*** in ***Manage Template*** window to create SMS template. Then provide ***Name***, ***Message Type***, ***Message***, ***Template Type*** and save changes. + +![DC_Lab.12.12_Create_Connect_7](/assets/images/DC_Lab_12.12._Create_Connect_7.png) + +- Insert SMS node into the corresponding flow just after Queue Task node. Provide necessary details including ***Template***, save changes and make the flow live. + +![DC_Lab.12.12_Create_Connect_8](/assets/images/DC_Lab_12.12._Create_Connect_8.png) + +- After the flow is triggered and SMS request is queued, the end user will be notified over SMS. + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.13 - Engage Templates + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------- | ----------------- | --------------- | ---------------- | +| [Understanding Engage Templates](#1-understanding-engage-templates) | Read & Understand | EASY | 5 min | +| [\[Optional\] Create Engage Template Group](#2-optional-create-engage-template-group) | Read & Understand | EASY | 5 min | +| [Create Engage Templates](#3-create-engage-templates) | Read & Understand | EASY | 5 min | +| [Bulk Upload of Engage Templates](#4-bulk-upload-of-engage-templates) | Read & Understand | EASY | 5 min | +| [Verify Engage Template in Agent Desktop](#5-verify-engage-template-in-agent-desktop) | Read & Understand | EASY | 5 min | + +## Introduction + +#### Lab Objective + +This section is designed to introduce Engage templates, which can be used for quick reply from the agent desktop to the end user through various digital channels. In this section you will find configuration steps and examples of use. The goal is to understand the purpose of each template. + + +## 1. Understanding Engage Templates + +Engage templates makes agent's job easier by providing the possiblity to use some standard quick replies to the end-user in the agent desktop during the conversation ove any digital channel. +Here are few key points to note about Engage templates which provide better understanding of the feature: +- Agent can use a template in the agent desktop only after accepting the conversation initiated via digital channel. +- Agent can edit the text of the template before sending the message unless it is prohibited by template settings. +- Engage administrator can create various template groups to organanize templates. +- Each template should be added into the group. +- Each teamplate can be created for for one or many digital channels. +- Many templates can be uploaded to Engage Portal in a bulk. +- One or more of the following categories can be assigned to each template brings more flexibility when using it: + - Start Template + - End Template + - Followup Template +- Engage administrator can use variables to customize the same template for each end user. For example: + - system.customer_name + - system.customer_id + - system.customer.mobile_no + - system.asset + - system.customer_email_address + + +## 2. \[Optional\] Create Engage Template Group + +>***Note:*** This step should be completed if you want to create template group. There is no need to create new group if you want to add a template into an existing one. + +- Login to WxCC Management Portal access the menu and cross launch Engage Portal by choosing ***New Digital Channels***. + +![DC_Lab.12.8_Create_Website_1](/assets/images/DC_Lab_12.8._Create_Website_1.png) + +* Go to ***Assets*** -> ***Templates*** and press **''+"** button near ***TEMPLATE GROUPS*** section. + +![DC_Lab.12.13_Create_Engage_1](/assets/images/DC_Lab_12.13._Create_Engage_1.png) + +- Provide ***Template Group name*** and press ***Add*** button to save it. + +![DC_Lab.12.13_Create_Engage_2](/assets/images/DC_Lab_12.13._Create_Engage_2.png) + +- You can delet existing template group by clicking on bin icon near the template name in ***TEMPLATE GROUPS*** section. + +![DC_Lab.12.13_Create_Engage_3](/assets/images/DC_Lab_12.13._Create_Engage_3.png) + + +## 3. Create Engage Templates + +- Go to ***Assets*** -> ***Templates***, click on template group name in ***TEMPLATE GROUPS*** section. Then press ***Add template*** button. + +![DC_Lab.12.13_Create_Engage_4](/assets/images/DC_Lab_12.13._Create_Engage_4.png) + +- Let's create start template for web chat channel. Please click on ***Livechat*** in template header and provide necessary template details: + +| **Parameter Name** | **Parameter Value** | +| ----------------- | --------------------------------------------------------- | +| Template DI | HelloTemplate | +| Template Text | Hello @@system.customer_name@@, How can I help you today? | +| Lock Template | Disabled | + +>***Note:*** Please pay your attention that we used ***system.customer_name*** variable in ***Template Text*** field. You can see the list of all supported variables and select the required one when typing @@ in the field. + +>***Note:*** You can lock the template by enabling ***Lock Template*** toggle. In this case agent will not be allowed to modify the text of the template before sending the message to the end user. + +![DC_Lab.12.13_Create_Engage_5](/assets/images/DC_Lab_12.13._Create_Engage_5_1.png) + +- You can edit or delete the template by clicking on corresponding icon in the ***Actions*** column in the table with template details. + +![DC_Lab.12.13_Create_Engage_6](/assets/images/DC_Lab_12.13._Create_Engage_6_1.png) + + +## 4. Bulk Upload of Engage Templates + +- Go to ***Assets*** -> ***Templates***, click on ***Upload template*** button. + +![DC_Lab.12.13_Bulk_Engage_1](/assets/images/DC_Lab_12.13._Bulk_Engage_1_1.png) + +- Click on ***Download sample file here*** link to download CSV sample file. + +![DC_Lab.12.13_Bulk_Engage_2](/assets/images/DC_Lab_12.13._Bulk_Engage_2.png) + +- Open sample file, provide necessary values according to ***Help Notes*** section. Then delete ***Help Notes*** section and save changes. + +![DC_Lab.12.13_Bulk_Engage_3](/assets/images/DC_Lab_12.13._Bulk_Engage_3.png) + +- Return to ***Upload Template*** window, press ***upload file*** button and select the file you created above. + +![DC_Lab.12.13_Bulk_Engage_4](/assets/images/DC_Lab_12.13._Bulk_Engage_4.png) + +- Check and make sure there were no conflicts found. Then click on ***Proceed*** button. + +![DC_Lab.12.13_Bulk_Engage_5](/assets/images/DC_Lab_12.13._Bulk_Engage_5.png) + +- Make sure your file is being processed and press ***OK*** button in pop-up window. + +![DC_Lab.12.13_Bulk_Engage_6](/assets/images/DC_Lab_12.13._Bulk_Engage_6.png) + +- Uploaded template will be added to the list. + +![DC_Lab.12.13_Bulk_Engage_7](/assets/images/DC_Lab_12.13._Bulk_Engage_7_1.png) + + +## 5. Verify Engage Template in Agent Desktop + +- Start web chat with the end user and make sure you are able to select the template in agent desktop and send the message. + +![DC_Lab.12.13_Validate_1](/assets/images/DC_Lab_12.13._Validate_1.png) + +![DC_Lab.12.13_Validate_2](/assets/images/DC_Lab_12.13._Validate_2.png) + +![DC_Lab.12.13_Validate_3](/assets/images/DC_Lab_12.13._Validate_3.png) + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.14 - Introduction to BOTs + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------- | ----------------- | --------------- | ---------------- | +| [Understanding Connect Bots](#1-understanding-connect-bots) | Read & Understand | MED | 5 min | +| [Access and navigation](#2-access-and-navigation) | Read & Understand | EASY | 5 min | +| [Understand and navigate Q&A Bots](#3-understand-and-navigate-qa-bots) | Read & Understand | MED | 5 min | +| [Understand and navigate Task Bots](#4-understand-and-navigate-task-bots) | Read & Understand | MED | 5 min | + +## Introduction + +#### Lab Objective + +This lab is designed to introduce the Bot Builder interface, which is used for the configuration and orchestration Bots within Connect. In this lab you will not find configuration steps, the goal is to understand the purpose and use of each menu item. + +#### Pre-requisites + +1. Connect URL for browser access. +2. Admin credentials to login to Connect administration portal. + +## 1. Understanding Connect Bots + +Bot Builder is a cloud-based bot platform that allows enterprises to create bots. It includes Bot creation, testing, hosting, analyzing, and editing capabilities. The key features of Bot Builder include: + +- Rules for handling flows +- Ability to retain context +- Omni-channel deployment +- Live agent handover +- Bot orchestration framework +- One-click bot testing +- Integration with business systems +- Enterprise-grade data security and privacy +- Analytics +- Custom reports + +There are three types of Bots that can be integrated within a Connect flow: + +- **Q&A Bots** – are knowledge-driven bots whose knowledge base consists of a series of possible questions (with their alternative syntax) and related answers. +- **Task Bots** – enable multi-turn conversations where a bot can obtain relevant data from users to perform the task at hand. +- **NLP Pipelines** – is a solution to build customized bots by defining the desired behaviors, without using the features already provided by Q&A and Task bots. + +## 2. Access and navigation + +Bot Builder is a dedicated portal which can be accessed via Connect: + +- Access your Connect tenant +- Navigate to App Tray > Bot Builder + +The interface, similarly to Connect, is divided in two main parts: the main menu on the left side and the configuration of the selected object in the center-right side. +Move your mouse pointer on each icon of the menu to see its name and the available options: + +- Dashboard – On the dashboard, the admin can review or create bots, which are then represented by cards that have basic information visible on them. There are 3 sections for each type of bot, by selecting each of them the admin can create new ones as the “+ New” button will update accordingly. +- Analytics – this section allows the administrator to collect and review statistics over bots utilization and performances. It’s a powerful tool to obtain an holistic view about volume and efficiency of configured bots. +- Help – the help icon will automatically open a new browser tab and redirect the admin to [https://help.imiconnect.io/](https://help.imiconnect.io/). On the home page scroll down until the ‘APP TRAY’ section and select ‘Bot Builder’ to read an in-depth explanation for all features and functionalities that bots can offer. + +## 3. Understand and navigate Q&A Bots + +First let’s start reviewing the interface as a new Q&A Bot gets created: + +- Access your Connect tenant +- Navigate to App Tray > Bot Builder +- From the Dashboard > Select ‘Q&A bots’ > Click on ‘+ New Q&A Bot’ +- Enter the Name and the Unique Name following your desired naming convention +- Select the text orientation as how the chat interface (within the Bot Builder) will position the text. +- \[OPTIONAL\] Toggle the option ‘Allow feedback’ to allow users to give a ‘thumb up’ or ‘thumb down’ to the answers the bot will prompt when consulted +- \[OPTIONAL\] Toggle the option ‘Allow agent handover’ to allow this bot to stop processing the incoming messages and handover the conversation to a different branch in your Connect flow. +- Click on ‘Done’ button to save and create the Q&A Bot. + +Once opening a Q&A Bot a dedicated option menu appears on the left side and additional options on top + +#### 3.1 Settings + +- Profile – in this section the admin can change the bot name, its description and the text alignment. +- Management – in this section the admin can change the Bot status and disable it (without deleting it) and change the ‘Allow Feedback’ option set when it was created. +- Handover – in this section the admin can change the ‘Allow agent handover’ option set when the bot was created, and change specific handover options. + +#### 3.2 Articles + +Articles are containers of questions (in their possible variations), for which the answer to be provided will be the same. The questions are called ‘Utterances’. Here the key information about Articles: + +- When creating a new Article the admin must provide a Default Utterance, which will be then displayed as ‘Title’ in the list. Then add possible alternative containing different key words and phrases the system will then use to recognize and match what will be provided by the user. +- Articles contain both the question (and its alternatives) and the related answer. +- Admin can create Categories and assign articles to them, so to have better control of existing configuration. +- When editing an Article, the admin can also edit the response (text, format and conditions). +- After any changes, the Q&A bot needs to be ‘Trained’ first, and then moved to ‘Live’. + +> Any new Q&A bot will be created with a default Articles list. + +**3.3 Testing** + +Bot Builder platform provides a built-in one-click bot testing framework that is extremely helpful in testing a large set of test cases easily and quickly. It helps to validate the use cases listed will trigger the expected behaviour. + +#### 3.4 Curation + +Curation console helps users in optimizing their bot's performance over time through human-in-the-loop learning. It facilitates users in reviewing cases where their bot performance was underwhelming. These can be curated to improve current articles/intents or to create new articles/intents + +#### 3.5 Session + +Displays the history of all sessions established with the customers. Each session is displayed as a record that contains all sent/received messages. Messages from a specific session or from multiples sessions can be downloaded as CSV file. Reviewing sessions in detail is extremely useful to audit, analyse, and improve the bot performances and customer satisfaction. + +#### 3.6 History + +Provide version control over all changes the administrator applies on that specific bot. Any admin can review which changes were applied on specific version and revert to previous ones where needed. + +## 4. Understand and navigate Task Bots + +First let’s start reviewing the interface as a new Q&A Bot gets created: + +- Access your Connect tenant. +- Navigate to App Tray > Bot Builder. +- From the Dashboard > Select ‘Task bots’ > Click on ‘+ New Task Bot’. +- Enter the Name and the Unique Name following your desired naming convention +- Select the text orientation as how the chat interface (within the Bot Builder) will position the text. +- \[OPTIONAL\] Toggle the option ‘Allow feedback’ to allow users to give a ‘thumb up’ or ‘thumb down’ to the answers the bot will prompt when consulted. +- Click on ‘Done’ button to save and create the Q&A Bot. + +Once opening a Task Bot a dedicated option menu appears on the left side and additional options on top + +#### 4.1 Settings + +- Profile – in this section the admin can change the bot name, its description and the text alignment. +- Management – in this section the admin can change the Bot status and disable it (without deleting it) and change the ‘Allow Feedback’ option set when it was created. +- Handover – in this section the admin can change the ‘Allow agent handover’ option set when the bot was created, and change specific handover options. + +#### 4.2 Training + +Similar to articles, the Training section allows the admin to define containers for customer queries, called Intents, and to identify specific words in those messages with objects called Entities. Here the key information about Articles: + +- Entities only contain the questions and they are mapped to the desired response. The response is defined separately. +- The admin will first need to define the desired Entities with the desired type (List, Time, Date, etc.). +- The Intent Name is just descriptive. The list of messages coming from the customer, and alternatives, will be listed under Utterances. +- When creating the Intent (adding the desired Utterances), the system will automatically recognize the specific words and map them to the respective Entity. +- In case any word is not automatically mapped, the admin can select the desired text in an Utterance and manually map it to an Entity +- Any Entity that is mapped in the defined Utterances will be listed inside the Slots section. This allows to trigger specific actions for each Entities before the bot provides the desired Response for that Intent. +- Entities can be used across multiple Intents, and their value can be stored and used in the Responses. +- After any changes in the Training section, the Training bot needs to be ‘Trained’ first, and then moved to ‘Live’. + +#### 4.3 Responses + +Answers for the Intents specified inside the Training section are defined within the respective Templates. Here the key information about Responses: + +- The layouts of each response within the Templates can be edited (text, format and conditions). +- Different responses, depending on the used channel, can be defined within the same template. +- Conditions can be configured so to trigger a different response following predefined criteria +- After any changes in the Response section, the Training bot needs to be ‘Updated’ first, and then moved to ‘Live’. +- The Agent Handover Response template it’s the default response that allows the Task Bot Node inside the Connect Flow Designer to escalate the chat through a different route. + +#### 4.4 Testing + +Bot Builder platform provides a built-in one-click bot testing framework that is extremely helpful in testing a large set of test cases easily and quickly. It helps to validate the use cases listed will trigger the expected behaviour. + +#### 4.5 Curation + +Curation console helps users in optimizing their bot's performance over time through human-in-the-loop learning. It facilitates users in reviewing cases where their bot performance was underwhelming. These can be curated to improve current articles/intents or to create new articles/intents + +#### 4.6 Session + +Displays the history of all sessions established with the customers. Each session is displayed as a record that contains all sent/received messages. Messages from a specific session or from multiples sessions can be downloaded as CSV file. Reviewing sessions in detail is extremely useful to audit, analyse, and improve the bot performances and customer satisfaction. + +#### 4.7 History + +Provide version control over all changes the administrator applies on that specific bot. Any admin can review which changes were applied on specific version and revert to previous ones where needed. + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.15 - QnA BOTs + + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Navigate to BOT Builder and Create bot](#1-navigate-to-bot-builder-and-create-bot) | Practical Lab | MED | 5 min | +| [Preview](#2preview) | Practical Lab | MED | 5 min | +| [Bot testing](#3bot-testing) | Practical Lab | MED | 5 min | +| [Curation](#4curation) | Practical Lab | MED | 10 min | + + +## Introduction + +#### Lab Objective + +This lab is designed to complete a new QnA bot creation, new article creation and previewing the same. We will also test the bot, add new test cases and learn about curation. + +#### Pre-requisite + +- WxCC Portal, Agent Desktop and IMI connect URL. +- Admin credentials to complete configurations in WxCC portal and IMI connect. +- Agent Credentials to Handle FBM digital contact. +- Sample Facebook Flow configured. + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. Navigate to BOT Builder and Create bot + +- Log on to Connect portal and navigate to BOT Builder. +- On the top right you have 2 options QnA BOT and Task BOT. +- Create new QnA Bot. +- Give name and enable Agent handover and Allow feedback options. For easy tracking of configurations, please use the Attendee ID as part of your Bot name. For example: + Bot Name: AttendeeID_QnA_Bot + + +## 2. Preview + +- Navigate to Article -> click on 3 dot -> import from catalogue +- Once the Article is added, click on preview on top right and test the BOT +- Click on Session to check to user input matching with Article + + +## 3. Bot testing + +- Open BOT Builder +- Log on to Connect portal and navigate to BOT Builder +- Click on the BOT created on Lab 1 +- Click on Testing and add test case +- Execute the test case +- Click on session to validate the test case + + +## 4. Curation + +- Make sure feedback to BOT is enabled under sessions +- Open preview option and run few input to test the article +- If BOT is not giving expected response, click on red down thumb to downvote the article +- Open curation menu +- BOT Admin has an option to change response, add new article or attach response with an existing Article + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.16 - Task BOTs + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------- | ----------------- | --------------- | ---------------- | +| [Create a new Task Bot](#1-create-a-new-task-bot) | Practical Lab | HARD | 10 min | +| [Add the Task Bot to your flow](#2-add-the-task-bot-to-your-flow) | Practical Lab | HARD | 15 min | +| [Testing](#3-testing) | Practical Lab | EASY | 5 min | + +## Introduction + +#### Lab Objective + +In this lab we will be creating a Task Bot using the Bot Builder in Webex Connect. We will collect information from the customer and pass the information to our chat agent so that they can assist the customer. Once the Task Bot configuration is completed we will incorporate the bot inside a Connect flow. + +#### Pre-requisites + +1. Connect URL for browser access. +2. Admin credentials to login to Connect administration portal. +3. A Connect flow (previously built and successfully tested). +4. Test agent credentials. + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. Create a new Task Bot + +- Access your Connect tenant +- Navigate to App Tray > Bot Builder +- From the Dashboard > Select ‘Q&A bots’ > Click on ‘+ New Q&A Bot’ +- Enter the Name and the Unique Name following your desired naming convention +- Leave the other settings as they are. +- Click on ‘Done’ button to save and create the Q&A Bot. +- Select Training > click on Entities > click on ‘+ Create entity’ +- Provide a Name and select the respective Entity Type in the list > Click on Save +- Repeat the step above for as many intent you wish to add +- Select Training > click on Intents > click on ‘+ Create Intent’ +- Insert a descriptive Intent Name +- Insert the utterances in the way you expect the customer to message your bot, including words you defined inside the Entities + - When adding utterances with Entities, those will be automatically highlighted and will appear in the Slot section + - You can decide to make Entities mandatory by selecting the respective checkbox. By doing so you will need to set the number of times the bot will keep asking for that value (Retries). The bot will ask for it using the corresponding Template Key (in the Responses). + - When using Entities it is recommended to add at least 3 alternative Utterances containing them. +- Select the Response which will be prompted as final message when all the required Entities will be collected. You can select ‘+ Create New’ at the bottom of the list to create a new dedicated response. + - When typing the response text, the syntax \${} will allow the admin to use system variables as part of the text to be presented as response to the customer. Use \${entity.YOURENTITYNAME} to use the value stored in an existing entity. It is recommended to use this only for Entities which are set as Required in the Intents to avoid empty messages being provided to customers. +- Click on Save (top-right) > Click on the ‘backward arrow’ (top-left) to return to the Training menu > Click on Train (top-right) > Leave a comment (mandatory) > Click on Continue > Click on Make Live (top-right) > Leave a comment (optional) > Click on Make Live. +- \[OPTIONAL\] Click on Preview (top-right) > In the chat widget that will appear you can start testing your bot by chatting with it. + +## 2. Add the Task Bot to your flow + +The recommendation in the Connect flow designer is to create a loop on the Task Bot node where any input from the customer will be received and answered by the bot. The loop can be interrupted either by checking the bot response through a Branch node (so to create different paths based on the responses) or when the bot itself will determine the Agent Handover condition. A Task Bot node can also be used without creating a loop, meaning that after the first execution the admin will need to define static subsequent actions. The Task Bot node should be added only after the Create/Re-open Conversation ID and Task nodes. For any nodes in the loop, the admin needs to ensure the Timeout and Failure Outcomes will be pointed to a Close Conversation and Close Task nodes. + +- Access your Connect tenant. +- Navigate to Service > Select and open your existing working service. +- Click on Edit (top-right). +- Navigate to Settings > Custom Variables > Create a new Custom Variable and name it BotInputMessage. +- Edit the Incoming Message (first node) > select Transition Actions > in Action 1 section select ‘+ Add’ > select BotInputMessage > assign the value $(n2.messenger.message) > Save +- Create some space between the Create Conversation node and the next by moving the subsequent nodes > Remove the Successful Outcome link (green) coming out the Create Conversation node. +- From the node menu (left) select the Task Bot node and drag it in the flo +- Connect the Create Conversation node from the Successful Outcome to the Task Bot node +- Edit the Task Bot node + - From the BOT drop-down menu select the Bot name we previously created + - In the message field enter $(BotInputMessage) + - From the channel drop-down menu select the channel this flow is using + - In the PS ID field enter $(n2.messenger.psId) + - Save the node configuratiom +- Connect the Timeout and Failure Outcomes from the Task not node to the Close Conversation node +- From the node menu (left) select the Channel node (depending on the channel in use in the flow, i.e. SMS) and drag it in the flow +- Connect the Task Bot node from the Successful Outcome to the Channel node > a pop-up window will appear > select OnSuccess and click OK +- Edit the Channel node + - Copy the configuration from another pre-existing Channel node in the flow + - In the Message field enter $(nX.taskbot.text_response) (replace the X with the node ID from the Task Bot node) + - Save the node configuration +- Connect the Failure Outcomes from the Channel node to the Close Conversation node +- From the node menu (left) select the Branch node and drag it in the flow +- Connect the Channel node from the Successful Outcome to the Branch node +- Edit the Branch node + - In the Branch 1 VARIABLE field enter $(nX.taskbot.text_response) (replace the X with the node ID from the Task Bot node). + - From the Condition drop-down menu select ‘Equals’. + - In the VALUE field enter the same text defines in the Goodbye Response Template from the Bot Builder (customize it if needed). + - Save the node configuration. +- Connect the Failure Outcomes from Branch node to the Close Conversation node > Connect the Successful Outcomes to the Close Conversation node > a pop-up window will appear > select Branch 1 and click OK. +- From the node menu (left) select the Receive node and drag it in the flow +- Edit the Receive node + - In the SELECT INCOMING MESSAGE/EVENT list select the option corresponding to your channel. + - Edit the MAX TIMEOUT with the preferred duration (in seconds) for the time the flow will allow the customer to add a response (i.e. 120) + - Enter the corresponding ID for your channel. + - From the EVENT NAME drop-down menu select ‘Incoming Message’. + - Click on Transaction Actions + - Click on ‘+ Add Action’. + - in TIME select On-leave. + - Action – Set Variable. + - Variable – BotInputMessage. + - Value – $(nX.receive.message) (replace the X with the node ID from this Receive node). + - Save the node configuration +- Connect the Failure Outcomes from the Receive node to the Close Conversation node > Connect the Successful Outcomes back to the Task Bot node +- From the node menu (left) select the Channel node and drag it in the flow +- Edit the Channel node + - Copy the configuration from another pre-existing Channel node in the flow + - From the MESSAGE TYPE drop-down menu select ‘Text’. + - In the Message field enter the following message “Sorry we didn’t hear back from you, please contact us again later”. + - Save the node configuration. +- Connect all Failure and Successful Outcomes from the Messenger node to the Close Conversation node. +- From the node menu (left) select the Channel node and drag it in the flow +- Edit the Channel node + - Copy the configuration from another pre-existing Channel node in the flow. + - From the MESSAGE TYPE drop-down menu select ‘Text’. + - In the Message field enter $(nX.taskbot.text_response) (replace the X with the node ID from the Task Bot node). + - Save the node configuration. +- Connect the Failure Outcomes from the Messenger node to the Close Conversation node > Connect the Successful Outcome from the Task Bot node to the Messenger node (the ‘onAgentHandover’ outcome event will be automatically selected) +- From the node menu (left) select the Append Conversation node and drag it in the flow. +- Edit the Append Conversation node + - METHOD NAME = Append. + - NODE RUNTIME AUTH = Select your predefined authorization. + - CHANNEL = Select the channel in use. + - CONVERSATION ID = $(conversationId) + - DIRECTION –Inbound + - TEXT = enter $(nX.taskbot.text_response) (replace the X with the node ID from the Task Bot node). + - TIMESTAMP = $(n2.messenger.ts) + - ATTACHMENTS = $(parseDataAttachment) + - Save the node configuration +- Connect the Timeout and Failure Outcomes from the Append Conversation node to the Close Conversation node > Connect the Successful Outcome to the Create Task node. +- Connect the Successful Outcome of the Channel node to the Append Conversation node. +- Save and publish the flow (Make Live). + +> In this lab, when the conversation is escalated to the agent, the agent will only receive the last response from the Bot to the customer, and for this reason earlier we recommended to add the Entities’ values in the Agent Handover Response (so the agent can understand which values where entered and will not have to ask for them again). If you prefer to provide the entire transcript of all messages exchanged between customer and Bot, you will need to add an Append Conversation node after each Channel and Receive node. + +## 3. Testing + +Time to test your new configuration: + +- Access the agent desktop using your test agent credentials. +- Using the preferred channel, send a message in. +- Continue your conversation with the bot and provide the Entities you defined. +- Get your conversation escalated to the agent. +- Have your agent conversating with the customer. + +--- + +**Congratulations, you have completed this section!** + + +--- + + +# Lab.12.17 - Event Scheduler + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------- | ----------------- | --------------- | ---------------- | +| [Introduction to Event Scheduler](#1-introduction-to-event-scheduler) | Read & Understand | HARD | 5 min | +| [Schedule SMS Event](#2-schedule-sms-event) | Practical Lab | HARD | 5 min | +| [Schedule Custom Event](#3-schedule-custom–event) | Practical Lab | EASY | 10 min | + + +## Introduction + +#### Lab Objective + +In this Lab, we will learn about what is Event Scheduler, how it works & the various configuration options it provides. Please note, Event Scheduler mainly provides two configuration options i.e. SMS Event & Custom Event. You may choose to try either one or both of them. + +Option 1:  SMS Event– Allows you to send SMS messages simply by processing the file. One of the columns in the uploaded file must contain the recipients' phone number(s). + +Option 2: Custom Event – Allows you to trigger rules or flows associated with the selected custom event. The variables required to trigger the custom event and for the successful execution of concerned flows/rules should be available in the file. + +#### Pre-requisite + +1. You've received Administrator credentials to configure in Management Portal and Webex Connect. +2. At least one SMS number is already provisioned in Webex Connect. +3. Access to MS Excel or any other CSV file editor +4. You have successfully completed the previous Labs Pre-configuration, Email Configuration + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. Introduction to Event Scheduler + +Event Scheduler allows Webex Connect users to send SMS messages or schedule execution of Webex Connect rules/live flows, by uploading a file (on the UI or via an SFTP location) with required information in the relevant format. From Webex Connect select the App Tray & then click on Event Scheduler (Event Scheduler will open in a new browser tab). + +The Event Scheduler page gives access to: +- Scheduler – to create new or manage existing scheduled tasks +- Logs – to review all trigger executions in the last 6 months +- SFTP – to manage external data sources to feed the scheduled tasks +- Settings – to manage Social Hours (business hours) and holidays + +![DC_Lab.12.17_Introduction_EventScheduler](/assets/images/DC_Lab.12.17_Introduction_EventScheduler.png) + +## 2. Schedule SMS Event + +Configuring scheduled outbound SMS campaign only require the setup inside the Event Scheduler. SMS uses source files containing data that will be used by the scheduler to determine the destination numbers as well as building custom messages (i.e. names, dates, addresses, etc.) + +- Inside Webex Connect portal, click on App Tray & then click on Event Scheduler. + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event1.png) + +- From the Scheduler menu click on Add Schedule + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event2.png) + +- Click on SMS + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event3.png) + +- Select options as described below & click Next + - Select Service : The Service you've setup. + - SMS Type : TEXT + - Sender ID :  Select the number from where the SMS will be sent out + - Extra Parameters : are only required in case of specific in-country regulation + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event4.png) + +- Open MS Excel or any other CSV file editor & Add the following column names: + + - MessageType – In this column add at least one entry as ‘SMS’ and at least one entry as ‘email’ + - Destination - In this column add the respective SMS numbers and Email addresses to perform the test with + - CustomerName – in this column add the Name (and/or Surname) for everyone added to the list + +- Save the file. +- Choose if to upload a file created in previous step or use an existing SFTP connection. For this lab, we'll choose Upload File. + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event5.png) + +- Once the file is imported, the scheduler will validate the file and its content. As Recipient Variable select the column containing the Destination numbers for your message. + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event6.png) + +- Build the custom message in the Message Body and use $(ColumnName) to add the values from the desired column as part of the text & Click Next. + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event7.png) + +- Add a name for this Event & Click Next. + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event8.png) + +- Choose a schedule for this event to be executed & Click Save. + +![DC_Lab.12.17_Schedule_SMS_Event1](/assets/images/DC_Lab.12.17_Schedule_SMS_Event9.png) + +## 3. Schedule Custom Event + +Configuration sequence for Custom Event is as below. + +#### Create new Integration --> Create a new Flow --> Create a new Schedule + +Custom Events use source files containing data that will be used by flows when sending out the desired messages (i.e. destination addresses, names, dates). This section will take a ‘Appointment Reminder’ use case Scenario as reference, to describe the process administrator will have to follow when sending reminders via SMS or Email to a list of customers + +#### 3.1 Create new Integration + +- Inside Webex Connect portal, click on Assets & then click on Integrations. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event1.png) + +- Click on Add Integrations & then click on Custom Event + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event2.png) + +- Name the event (i.e. “EVENT Appointment Reminder”) +- Add the following parameters: + - type (String) + - name (String) + - destination (String) + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event3.png) + +- Leave rest of the config unchanged & Click on the Save button. + +#### 3.2 Create a new Flow + +- Inside Webex Connect portal, navigate to Services > Select the desired service > Click on Flows > Click on Create Flow. +- Enter Flow name (e.g., “AppointmentReminder”). In the ‘Method’ select New Flow, Select Start from Scratch & Click Create. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event4.png) + +- On the Select Trigger Category page, click Custom Event + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event5.png) + +- Once the flow editor loads the Configure Custom Event node will automatically open. From Select Event dropdown, select ‘EVENT Appointment Reminder’ & the list of Parameters will automatically populate. Click Save. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event6.png) + +- From node menu (left) select Branch node and drag it in to flow canvas (right). +- Connect Configure Custom Event node to Branch node +- Edit Branch node (double click on the node) +- Click in the Branch 1 VARIABLE field (on left), select from the Input Variables list (on right ) ‘Start’ > customEvent.type + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.1.png) + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.2.png) + +- From the Condition drop-down menu select ‘Equals’ +- In the VALUE field enter “email” (without quotes) + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.3.png) + +- Rename Branch 1 into ‘EMAIL’ + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.4.png) + +- Click on Add Branch +- Click in the Branch 2 VARIABLE field (on left), select from the Input Variables list (on right ) ‘Start’ > customEvent.type + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.1.png) + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.2.png) + +- From the Condition drop-down menu select ‘Equals’ +- In the VALUE field enter “SMS” (without quotes) +- Rename Branch 2 into ‘SMS’ + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.3.png) + +- Click Save. +- From the node menu (left) select the Email node and drag it in the flow. Repeat this step so to have 2x Email nodes in the flow. Also do the same for getting one SMS node. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event9.png) + +- Edit the first Email node as described below & click Save. + - In Destination Type select Email Id + - In Destination enter $(n2.customEvent.destination) + - In From Name enter “Booking Reminder” + - In Email Type select Text + - In Subject enter “Gentle reminder about your booking” + - In Message enter “Hi $(n2.customEvent.name), we would like to remind you that your appointment is tomorrow!” + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event10.png) + +- Edit the first SMS node as described below & click Save. + + - In Destination Type select msisdn + - In Destination enter $(n2.customEvent.destination) + - In From Number drop-down menu select the SMS number from where you wish to send the SMS. + - In Message Type select Text. + - In Message enter “Hi $(n2.customEvent.name), we would like to remind you that your appointment is tomorrow!” + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event11.png) + +- Edit the second Email node as described below & click Save. + + - In Destination Type select Email Id. + - In Destination enter the email address from an administrator (who will be notified in case of issues). + - In From Name enter “Booking Error” + - In Email Type select Text + - In Subject enter “Error message from AppointmentReminder flow” + - In Message enter. + + “Something went wrong with the scheduled message that contained following data: + + Type = $(n2.customEvent.type) + Name = $(n2.customEvent.name) + Destination = $(n2.customEvent.destination) + The message has not been delivered.” + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event12.png) + +- Click on the Settings icon (near the Save button on the top-right) & enable the Descriptive logs toggle, put 60 in "Enabled for" field to enable Descriptive logs for an hour. Click on Save + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event13.png) + +- Click on Save (on the top-right of the flow canvas). +- Drag the Successful Outcome from the SMS and Email nodes to any empty point of the flow canvas. On the screen that opens, as Node Event, select OnSuccess & as Flow Result, select 101 –…[ Success ]. Click Save + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event14.png) + +- Drag the Error Outcome from the SMS and Email nodes to any empty point of the flow canvas. On the screen that opens, as Node Event, select OnError & as Flow Result, select 102 –…[ Error ]. Click Save + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event15.png) + +- Drag the Error Outcome from the SMS and Email nodes to any empty point of the flow canvas. On the screen that opens, as Node Event, select OnPolicyFail & as Flow Result, select 102 –…[ Error ]. Click Save + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event16.png) + +- Connect the Branch node from the Successful Outcome to the first Email node & Select EMAIL from the drop-down menu that will pop-up. +- Connect the Branch node from the Successful Outcome to the SMS node & Select SMS from the drop-down menu that will pop-up. +- Connect the Branch node from the Successful Outcome to the second Email node (the ‘None of the above’ option will be automatically selected). +- Connect the Branch node from the Error Outcome to the second Email node. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event17.png) + +- Click on MAKE LIVE (near the Save button on the top-right), Select the preconfigured Email Application (from where outbound emails will be sent) & Click on Make Live. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event18.1.png) + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event18.2.png) + +- Open MS Excel or any other CSV file editor & Add the following column names: + + - MessageType – In this column add at least one entry as ‘SMS’ and at least one entry as ‘email’. + - Destination - In this column add the respective SMS numbers and Email addresses to perform the test with. + - CustomerName – in this column add the Name (and/or Surname) for everyone added to the list + + +- Save the file. + +#### 3.3 Create a new Schedule + +- Inside Webex Connect portal navigate to App Tray & click on Event Scheduler + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event19.png) + +- On Scheduler page, click on Add Schedule button. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event20.png) + +- Click Custom Event + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event21.png) + +- Select the Service containing the AppointmentReminder flow & Select EVENT Appointment Reminder from the ‘Select Event / Inbound Webhook’ drop-down menu. Click Next. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event22.png) + +- Select ‘Upload File’, Drag and drop the previously created spreadsheet in the marked area for file drop. The page will automatically refresh and will request the admin to map the Custom Event Integration parameters with the Column Names in the loaded file. Map the FILE HEADERS as the name indicates. The page will automatically refresh and will notify about Total, Valid, Invalid and Duplicate Rows from the file (for additional validation). Click on Next button + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event23.png) + +- Add “Appointment Reminder Schedule” as name for this Event & Click on Next button + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event24.png) + +- Choose ‘Immediate’ as the execution schedule for this event (the event will be actually executed 2 minutes later). Click Save. + +![DC_Lab.12.17_Schedule_Custom_Event](/assets/images/DC_Lab.12.17_Schedule_Custom_Event25.png) + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.18 - Inbound Webhooks + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Creating an Inbound webhook flow](#1creating-an-inbound-webhook-flow) | Practical Lab | MED | 15 min | +| [Creating a voice flow in flow control](#2creating-a-voice-flow-in-flow-control)| Practical Lab | HARD | 15 min | +| [Test the Inbound Webhook](#3test-the-inbound-webhook) | Practical Lab | EASY | 5 min | + + +## Introduction + +#### Lab Objective + +Inbound Webhooks generate a unique endpoint that can be embedded into your applications to notify Webex Connect of events occurring on business systems.This lab is designed to showcase the capabilities of an inbound Webhook in Webex Connect. + +In this lab, we will explore how an Inbound Webhook can be used to generate an email to a customer that initiated the contact through a voice call. + +![12.18.1.png](/assets/images/12.18.1.png) + +#### Pre-requisite + +- Admin credentials to login to WxCC and Webex Connect portal +- Knowledge of WxCC Connect flows and basic troubleshooting + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. Create an Inbound Webhook + +- Click on Assets ---> Integrations from the left navigation pane + +![12.18.2.png](/assets/images/12.18.2.png) + +- Click on the Add Integration button and select Inbound Webhook + +![12.18.3.png](/assets/images/12.18.3.png) + +- Enter a unique name for the Inbound Webhook and enter the JSON data as follows. Click on Parse and Save. + +*Note: Save the Webhook URL for future reference* + +{ +    "outage":"outage notification", +    "maintenance":"maintenance notification" +} + +![12.18.4.png](/assets/images/12.18.4.png) + +- Navigate to the Service you created earlier on in the labs and click on Create blank Flow. + +![12.18.5.png](/assets/images/12.18.5.png) + +- Give the flow a unique name and click on create flow button. +- Select the Trigger Category as Webhook + +![12.18.6.png](/assets/images/12.18.6.png) + +- Select the Webhook you created in a previous step and click Save. + +![12.18.7.png](/assets/images/12.18.7.png) + +- Drag and drop the Email node from the left pane and connect the two nodes. + +![12.18.8.png](/assets/images/12.18.8.png) + +- Double click on the Email node to access the settings and details as shown below. Click Save. + +![12.18.9.png](/assets/images/12.18.9.png) + +- Save the flow and make the flow Live. + + +## 2. Creating a voice flow in flow control + +- Login to the Webex Contact Centre management portal and navigate to flow control. +- Create a simple flow that sends out Outage details as an email. The main menu prompt takes the caller to a http request node when they press 1. +- The http request node then triggers the Webhook along with the message that needs to be sent out in the request body . + +Request Body: +{ +"outage": "Current power outages are applicable for the suburbs 2118, 2456, 2761, 2229" +} + +![12.18.10.png](/assets/images/12.18.10.png) + +![12.18.11.png](/assets/images/12.18.11.png) + +- Save and publish the flow. + + +## 3. Testing the Inbound Webhook + +- Make a call to the Entry point associated with the voice call flow that you created in the previous step. +- After making the selection and the call should get disconnected. +- Check the email box of the Destination Email address that was entered in the Webex Connect flow to ensure the email has been received. + +![12.18.12.png](/assets/images/12.18.12.png) + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.19 - Troubleshooting + + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------- | ----------------- | --------------- | ---------------- | +| [Understanding of Webex Connect troubleshooting capabilities](#1-understanding-of-webex-connect-troubleshooting-capabilities) | Read & Understand | MED | 15 min | +| [Debugging a flow](#2-debugging-a-flow) | Read & Understand | MED | 15 min | +| [The most common issues in Webex Connect flows](#3-the-most-common-issues-in-webex-connect-flows) | Read & Understand | MED | 30 min | + + +## Introduction + +#### Lab Objective + +This section is designed to introduce troubleshooting capabilities available for digital channels in Webex Connect platform. In addition there examples of the most common issues and the ways of how to fix them. + +#### Pre-requisite + +1. You received Webex CC Management Portal, Agent Desktop and Webex Connect URL . +2. You have admin credentials for Webex CC Management Portal and Engage Portal. +3. You have admin credentials for Connect Portal. +4. You have at least one flow created and published in Webex Connect. + + +## 1. Understanding of Webex Connect troubleshooting capabilities + +>**Note:** Please check and make sure all configuration steps for digital channel have been completed successfully before start troubleshooting it. + +There are the following troubleshooting capabilities available for the administrator to troubleshoot issues in digital channels provided by Webex Connect: +- Export Logs tool +- The debugger built into the flow builder +Let's consider how we can use both of them. + +#### 1.1. Export Logs tool + +This tool allows Webex Connect admin to download inbound and outbound log events as XLSX file for any Service / Asset / Digital Channel for desired timeframe. The we can inspect this file to check, for example, whether the message was received or sent by corresponding component of Webex Connect platform. + +Please login to Connect Portal, then go to ***Tools*** -> ***Export Logs*** to access the tool. + +![DC_Lab.12.19_Export_Logs_1](/assets/images/DC_Lab_12.19._Export_Logs_1.png) + +Let's download all incoming messages received via ***Chat_Asset*** for the last 7 days. We need to provide the following details and press ***Download*** button: + +| Parameter Name | Parameter Value | +| -------------- | ---------------- | +| Number or App | Chat_asset | +| Channel Event | Incoming Message | +| Period | Last 7 days | + +![DC_Lab.12.19_Export_Logs_2](/assets/images/DC_Lab_12.19._Export_Logs_2.png) + +After the log file has been downloaded, we can open the file and see all inbound events, including timestamps, IDs and message text. We can use the file to check whether specific message rom the end user has been received by Webex Connect via selected Number or App (asset). + +![DC_Lab.12.19_Export_Logs_3](/assets/images/DC_Lab_12.19._Export_Logs_3.png) + +Now, let's download all outbound messages for ***My First Service*** for the last 7 days. We need to provide the following details and press ***Download*** button: + +| Parameter Name | Parameter Value | +| -------------- | ---------------------------- | +| Service | My First Sertvice | +| Channel | Live Chat / In-App Messaging | +| Period | Last 7 days | + +![DC_Lab.12.19_Export_Logs_4](/assets/images/DC_Lab_12.19._Export_Logs_4.png) + +After the log file has been downloaded, we can open the file and see all outbound events, incliding timestamps, IDs and message text. We can use this log to check whether exact message has been sent to the end user by Webex Connect via selected Service / Channel. + +![DC_Lab.12.19_Export_Logs_5](/assets/images/DC_Lab_12.19._Export_Logs_5.png) + +#### 1.2. Flow Debugger + +This tool allows Webex Connect admin to track flow execution from the beginning till the end. Flow debugger has the following capabilities: +- search for exact flow execution event based on the timestamp or Transaction ID +- briefly shows the result of exectuting each node of the flow in the form of a list +- adds unique ID to each node on flow canvas to simplify the mapping between the nodes and items in the list +- shows all the parameters used when calling each flow node +- shows the responce returned by each flow node after it had been called +- shows the values of the variables created by admin for troubleshooting purpose + +>**Note:** By default, debugging details are encrypted in Flow Debugger. Webex Connect admin account should have ***Decryption Access*** permission to be able to decrypt the details. +>- Admin account with ***Owner*** permission has ***Decryption Access*** by default. +>- Admin accoun without ***Owner*** permission has no ***Decryption Access*** by default - it can be granted by the owner. + +Login to Connect Portal and go to ***Settings*** -> ***Teammates*** and loot at ***Decryption Access*** column to check which accounts on Connect Portal have log decryption permission. For example: + +![DC_Lab.12.19_Flow_Debugger_1](/assets/images/DC_Lab_12.19._Flow_Debugger_1.png) + +To grant ***Decryption Access*** permission to some admin account, check and make sure you are logged in under admin account with ***Owner*** permission. Then click ***Edit*** button next to the desired admin account, tick ***Decrypt Logs*** check box in the pop-up window with account details and save changes. + +![DC_Lab.12.19_Flow_Debugger_2](/assets/images/DC_Lab_12.19._Flow_Debugger_2.png) + +Check and make sure ***Decryption Access*** permission is visible next to the desired admin account in the list of users. + +![DC_Lab.12.19_Flow_Debugger_3](/assets/images/DC_Lab_12.19._Flow_Debugger_3.png) + + +## 2. Debugging a flow + +Flow debugger is embedded into Webex Connect flow builedr. Let's have a look how to use it. + +- Login to Connect Portal and go to ***Services***. Then go to the service, switch to ***Flows*** tab and double-click on the flow which you are going to debug. +- Once the flow is loaded, click on ***Debug*** button on the right pane. Flow debugger window will +appear at the bottom. This window is scalable, so we can adjust its size to make troublehooting process more convenient. + +![DC_Lab.12.19_Debugging_Flow_1](/assets/images/DC_Lab_12.19._Debugging_Flow_1.png) + +- Provide proper time frame or ***Transaction ID*** (if you know it) and press ***Search*** button to find corresponding flow events. You will see all found flow events as a list in debugger window. Each line of the list represents single flow execution. + +![DC_Lab.12.19_Debugging_Flow_2](/assets/images/DC_Lab_12.19._Debugging_Flow_2.png) + +- Click on the corresponding hyperlink in ***Transaction ID*** column to see the details of exact flow execution. Those details will be displayed as a list at a separate tab in the same debugger window. The title of the tab will be the value of the Transaction ID. + +![DC_Lab.12.19_Debugging_Flow_3](/assets/images/DC_Lab_12.19._Debugging_Flow_3.png) + +- Select one item from the list to see its details on the right-hand side of debugging window. All details of the event are encrypted by default. Click on ***DECRYPT LOGS*** button in the title of debuggin screen to see decrypted log messages. + +![DC_Lab.12.19_Debugging_Flow_4](/assets/images/DC_Lab_12.19._Debugging_Flow_4.png) + +- Decrypted log messages will be displayed on the right-hand side of debuggin window. Those log messages include the parameters used when calling the node as well as the results returned by the node after the request was processed. You can copy the value of any debug message by pressing copy icon next to the message on the right-hand side of debugging window. + +![DC_Lab.12.19_Debugging_Flow_5](/assets/images/DC_Lab_12.19._Debugging_Flow_5.png) + +- All items in the list have ***Node ID*** and ***Node*** which matches the same values for each node on flow canvas. + +![DC_Lab.12.19_Debugging_Flow_6](/assets/images/DC_Lab_12.19._Debugging_Flow_6.png) + +- So, every time you click on any item in the list in debugging window the log messages of this node are displayed on the righ-hand side. In addition, corresponding node is highlighted with a blue border on flow canvas, which simplifies troubleshhoting. + +![DC_Lab.12.19_Debugging_Flow_7](/assets/images/DC_Lab_12.19._Debugging_Flow_7.png) + +- The ***OUTCOME*** column of the list shows the result of execuiting each flow node. In case if any node has been completed with an error or timeout, it will be displayed as an outcome in the line of the list which corresponds to the affected flow node. Error details will be available on rigth-hand side of debugging window. + +![DC_Lab.12.19_Debugging_Flow_8](/assets/images/DC_Lab_12.19._Debugging_Flow_8.png) + +In the next section we will look at the most common issues in Webex Connect flows and how to solve them. + + +## 3. The most common issues in Webex Connect flows + +Let's look at few examples of the most commn issues in Webex Connect flows. We will consider how to identify the cause of each issue and potential solutions. + +#### 3.1. Engage Asset not linked to Entry Point in Webex CC + +Here is an example of what will happen if live chat app (asset) is not assigned to the Entry Point on Webex CC management portal. Flow debugger disaplays ***onInvalidChoice*** error next to the affected ***Create Task*** node. The error on the right-hand side of debugging window contains ***desc : no valid edge found for the async event*** message. + +![DC_Lab.12.19_Error_No_EP_1](/assets/images/DC_Lab_12.19._Error_No_EP_1.png) + +Please follow the action plan below to fox the issue: +1. Please check which app/asset is assigned to the affected flow on Connect Portal. +2. Login to Webex CC Management Portal, go to ***Provisioning*** -> ***Etry Points/Queues*** -> ***Entry Point*** and select ***Edit*** next to the proper Entry Point. +3. Then select affected app/asset created on Connect Portal in the ***Asset Name*** drop-down list and save changes. If the affected asset is not in the drop-down list, please create new one on Connect portal, register it with proper service and check one more time. + + +#### 3.2. Engage authorization not working + +Here is an example where Webex CC authorization does not work properly. Flow debugger disaplays ***onInvalidData*** error next to the affected Engage node. + +![DC_Lab.12.19_Error_Engage_Auth_1](/assets/images/DC_Lab_12.19._Error_Engage_Auth_1.png) + +The error ***desc : Authorization not found*** means the autorization configured in ***NODE RUNTIME AUTHORIZATION*** field of ***Search Conversation*** node does not work. + +![DC_Lab.12.19_Error_Engage_Auth_2](/assets/images/DC_Lab_12.19._Error_Engage_Auth_2.png) + +Potential ways to fix the issue: + +1. If there is ***undefined*** value of autorization selected in ***NODE RUNTIME AUTHORIZATION*** field of the affected node, this means that Engage autorization used for this node has been deleted. Please select another autorization from the drop-down list or create new authorization, then save changes and make the flow live. + +3. If there is incorrect autorization selected in ***NODE RUNTIME AUTHORIZATION*** field of the affected node, please select proper value from the drop-down list, save changes and make the flow live. + +2. If correct autorization is selected in ***NODE RUNTIME AUTHORIZATION*** field of the affected node, but it fails, please update selected authorization. Go to ***Assets*** -> ***Integrations*** -> ***Webex CC Engage*** and select ***Manage*** from the drop-down list next to the integartion name. For example: + +![DC_Lab.12.19_Error_Engage_Auth_3](/assets/images/DC_Lab_12.19._Error_Engage_Auth_3.png) + +Then scroll down to ***Node Authorizations***, click on arrow button to expand the list and select ***Update*** from ***Actions*** list next to the affected authorization. + +![DC_Lab.12.19_Error_Engage_Auth_4](/assets/images/DC_Lab_12.19._Error_Engage_Auth_4.png) + +Then click on ***Authorize*** button in the pop-up window and provide credentials if needed to update Webex CC authorization. + +![DC_Lab.12.19_Error_Engage_Auth_5](/assets/images/DC_Lab_12.19._Error_Engage_Auth_5.png) + + +#### 3.3. Webex CC authorization not working + +Here is an example where Webex CC authorization does not work properly. Flow debugger disaplays ***onauthorizationfail*** error next to the affected Webex CC node. + +![DC_Lab.12.19_Error_WebexCC_Auth_1](/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_1.png) + +The error ***desc : unauthorized, integration :Create Task, method : Create Task*** means the autorization configured in ***NODE RUNTIME AUTHORIZATION*** field of ***Create Task*** node does not work. + +![DC_Lab.12.19_Error_WebexCC_Auth_2](/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_2.png) + +Potential ways to fix the issue: + +1. If there is incorrect autorization selected in ***NODE RUNTIME AUTHORIZATION*** field of the affected node, please select proper value from the drop-down list, save changes and make the flow live. + +2. If correct autorization is selected in ***NODE RUNTIME AUTHORIZATION*** field of the affected node, but it fails, please make sure proper account is still active on Control Hub. Then go to ***Assets*** -> ***Integrations*** -> ***Webex CC Task*** and select ***Manage*** from the drop-down list next to the integartion name. For example: + +![DC_Lab.12.19_Error_WebexCC_Auth_3](/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_3.png) + +Then scroll down to ***Node Authorizations***, click on arrow button to expand the list and select ***Update*** from ***Actions*** list next to the affected authorization. + +![DC_Lab.12.19_Error_WebexCC_Auth_4](/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_4.png) + +Then click on ***Authorize*** button in the pop-up window and provide credentials if needed to update Webex CC authorization. + +![DC_Lab.12.19_Error_WebexCC_Auth_5](/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_5.png) + + +#### 3.4. Variable does not exist or has an empty value + +Here is an example where the variable assigned to one of the parameters of flow node does not exist or has empty value. Flow debugger disaplays ***onError*** error next to the affected ***Create Task*** node. + +![DC_Lab.12.19_Error_No_Value_1](/assets/images/DC_Lab_12.19._Error_No_Value_1.png) + +The error ***desc : value is mandatory , name : task id*** means ***TASK ID*** parameter of ***Create Task*** node had no value when the node was executed. It could happen if the variable assigned to ***TASK ID*** did not exist or had an empty value. +To fix this issue, we need to open the configuration of ***Cretae Task*** node and check the value of ***TASK ID*** parameter. In our case there is a variable ***$(flid_na)***, which does not exist and that's why there was an empty value used when calling ***Create Task*** node. + +![DC_Lab.12.19_Error_No_Value_2](/assets/images/DC_Lab_12.19._Error_No_Value_2.png) + +Potential ways to fix the issue: +1. Correct variable name if it is wrong and check the value of this variable +2. Create a variable if it does not exist and assign proper value to it +3. \[Not a flexible approach\] Replace the variable name by exact value + + +#### 3.5. Variable or parameter has wrong value + +Here is an example where the variable or parameter of a flow node has wrong value. Flow debugger disaplays ***onAppendMessageFailure*** error next to the affected ***Append Conversation*** node. + +![DC_Lab.12.19_Error_Wrong_Value_1](/assets/images/DC_Lab_12.19._Error_Wrong_Value_1.png) + +The error ***""description":"Chat ID provided does not exist","event":"conversation-message:error","value":{"conversationId":"this-is-wrong-ID-just-for-example","aliasId":""}"*** means that ***CONVERSATION ID*** parameter of ***Append Conversation*** node has wrong value - ***"this-is-wrong-ID-just-for-example"***. Please double-click on the affected node and correct the value of ***CONVERSATION ID*** parameter to fix the issue. Then save changes and make the flow live. + +![DC_Lab.12.19_Error_Wrong_Value_2](/assets/images/DC_Lab_12.19._Error_Wrong_Value_2.png) + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.20 - Creating Custom Nodes + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Adding a Custom Node](#1-adding-a-custom-node) | Practical Lab | MED | 15 min | +| [Demo](#2-demo) | Read & Understand | EASY | 15 min | + +## Introduction + +#### Lab Objective + +This lab walks you through the creation of custom node and a demo of its usage. Custom nodes allow you to configure reusable integrations with your existing business system or with third-party applications using REST/SOAP APIs. In this sample example, we are going to show how you can integrate with WxCC and update Site name via calling into Entry Point. + +#### Pre-requisite + +- Admin credentials to login to Webex Connect portal + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> Webex Connect Portal: **[https://wxcctrainingpod29.us.webexconnect.io](https://wxcctrainingpod29.us.webexconnect.io)**  +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + + +## 1. Adding a Custom Node + +
    + +
    + +#### 1.1. Navigate to Integrations in Webex Connect + +- Login in to Webex Connect portal +- From left column, navigate to “Integrations” + +![Lab12.20_CustomNodeIntegrations](/assets/images/Lab12.20_CustomNodeIntegrations.png) + +#### 1.2. Add Custom Node + +- In Integrations, click ‘Add Integration’ +- Select ‘Custom Node’ + +![Lab12.20_CustomNodeAddIntegrations](/assets/images/Lab12.20_CustomNodeAddIntegrations.png) + +- Name your Custom Node, select ‘Custom Nodes’ under Node Category and click OK. For easy tracking of configurations, please use the Attendee ID as part of your node name. For example: + Node Name: AttendeeID_CustomNode + +![Lab12.20_CustomNodeCreateNew](/assets/images/Lab12.20_CustomNodeCreateNew.png) + +#### 1.3. Configure REST API under Settings tab + +These settings are specific to the requirement of your existing business system or with third-party applications you are trying to integrate. + +- Step 1: Configure Authorization +- Step 2: Configure Headers +- Step 3: Configure Body +- Step 4: Configure Response + +### 1.4. Configure Node UI tab (optional) + +- This setting are specific to the requirement of your existing business system or with third-party applications you are trying to integrate. + +## 2. Demo + +Here a quick Demo via calling EP into Webhook to invoke custom node to update WxCC Site name: + +
    + +
    + +**Note**: The ppt presented in the video has an error. The HTTP Request to Webhook is a POST request. Please refer to the diagram below. + +![Lab12.20_CustomNodeDemo](/assets/images/Lab12.20_CustomNodeDemo.png) + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.21 - Event and Triggers + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Creating an Inbound webhook flow](#1creating-an-inbound-webhook-flow) | Practical Lab | MED | 15 min | +| [Creating an Event in Webex Engage Portal](#2creating-an-event-in-webex-engage-portal)| Practical Lab | MED | 10 min | +| [Test the Event Trigger](#3test-the-event-trigger) | Practical Lab | EASY | 5 min | + + +## Introduction + +#### Lab Objective + +This lab walks through the configuration of Events and Triggers in the Webex Contact Centre Engage Portal. Once configured, these can be invoked by an agent handling digital interactions to achieve the required use case. + + +#### Pre-requisite + +- Admin credentials to login to WxCC and Webex Connect portal +- Working inbound chat and routed flow +- Knowledge of WxCC Connect flows and basic troubleshooting + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. Creating an Inbound Webhook flow + +- Login to Webex Connect portal. From Left column, navigate to Assets--> Integrations + +![12.21_1](/assets/images/12.21_1.png) + +- Click on Add Integration-->Inbound Webhook + +![12.21_2.png](/assets/images/12.21_2.png) + +- Give the Webhook a Unique name , and copy the Webhook URL and keep it aside for future reference. Click Save. + +![12.21_3.png](/assets/images/12.21_3.png) + +- Navigate to the relevant Service from the Left Pane and click on Create Blank Flow. + +![12.21_4.png](/assets/images/12.21_4.png) + +- Give the flow a name and click Create. Select the Webhook as the Trigger category. + +![12.21_5.png](/assets/images/12.21_5.png) + +- Select the Webhook name from the dropdown and paste the below Json data and click Parse. Save the changes + +{ +"email": "xxx@cisco.com", +"url": "https://www.cisco.com/" +} + +![12.21_6.png](/assets/images/12.21_6.png) + +- Drag the Email node from the left pane on to the canvas and connect the two nodes. + +![12.21_7.png](/assets/images/12.21_7.png) + +- Open the Email node and enter the Destination ID, From Name, Message and Subject. Click Save. + +![12.21_8.png](/assets/images/12.21_8.png) + +- Save the flow and make live. + + +## 2. Creating an Event in Webex Engage Portal + +- Login to Webex Contact Centre Management Portal and cross launch Webex Engage from the left side pane. + +![12.21_10.png](/assets/images/12.21_10.png) + +- Click on Groups- --> Default + +![12.21_11.png](/assets/images/12.21_11.png) + +- Click on the Default Team + +![12.21_12.png](/assets/images/12.21_12.png) + +- Click on Events and Rules and click Add new event. + +![12.21_13.png](/assets/images/12.21_13.png) + +- Enter a unique name, Method, Webhook URL, payload as Key Value pair . + +![12.21_14.png](/assets/images/12.21_14.png) + +- To enter the key Value pair, click on Add Param and enter parameters as shown below. + +![12.21_15.png](/assets/images/12.21_15.png) + +- Repeat the above step to create the url parameter + +![12.21_16.png](/assets/images/12.21_16.png) + +## 3. Test the Event Trigger + +- Login to the agent desktop and initiate a chat session. After accepting the chat session click on the lightning bolt icon to select the trigger and click Next. + +![12.21_17.png](/assets/images/12.21_17.png) + +![12.21_18.png](/assets/images/12.21_18.png) + +- Enter the email address you want to send the Email to and the url and press Trigger. + +![12.21_19.png](/assets/images/12.21_19.png) + +- Check the recipient’s mailbox to validate the Email has been received successfully. + +--- + +**Congratulations, you have completed this section!** + + +--- + +# Lab.12.22 - Global and Flow variable support in Digital channels + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Fetching and Reporting Global variable](#1-fetching-and-reporting-global-variable) | Practical Lab | MED | 15 min | +| [Configuring Flow variables](#2-configuring-flow-variables)| Practical Lab | MED | 15 min | +| [Transfer Global and Flow variable values between Webex Connect flows](#3-transfer-global-and-flow-variable-values-between-webex-connect-flows) | Practical Lab | MED | 15 min | + + +## Introduction + +#### Lab Objective + +This lab walks through the configuration of Global and Flow variables for digital channels. The behavior of these variables are the same as how they would work for telephony flows. Global variables are centrally configured and reported in WxCC and they are fetch via flows in Webex Connect. Flow variables are configured locally within Webex Connect flows and are not reportable. + +Both variables are transferable between flows. In the second part of this lab in 12.24.3, we will configure the transfer of chat form entries received in the inbound chat flow to routed flow when agent accepts the inbound chat. + +#### Pre-requisite + +- Admin credentials to login to WxCC and Webex Connect portal +- Working inbound chat and routed flow +- Knowledge of WxCC Global variables and Analyzer + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/)** +> US Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal)** +> US Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/)** +> UK Portal: **[https://portal.wxcc-eu1.cisco.com/portal](https://portal.wxcc-eu1.cisco.com/portal)** +> UK Agent Desktop: **[https://desktop.wxcc-eu1.cisco.com](https://desktop.wxcc-eu1.cisco.com/)** +> EMEA Portal: **[https://portal.wxcc-eu2.cisco.com/portal](https://portal.wxcc-eu2.cisco.com/portal)** +> EMEA Agent Desktop: **[https://desktop.wxcc-eu2.cisco.com](https://desktop.wxcc-eu2.cisco.com/)** +> ANZ Portal: **[https://portal.wxcc-anz1.cisco.com/portal](https://portal.wxcc-anz1.cisco.com/portal)** +> ANZ Agent Desktop: **[https://desktop.wxcc-anz1.cisco.com](https://desktop.wxcc-anz1.cisco.com/)** +> Webex Connect Documentation: **[https://help.imiconnect.io/](https://help.imiconnect.io/)** + + +## 1. Fetching and Reporting Global Variable + +
    + +
    + +#### 1.1. Login in to Webex CC administration portal + +- From left column, navigate to “Global Variables” + +![Lab12.24.1_GVFirst](/assets/images/Lab12.24.1_GVFirst.png) + +- Create a new OR select an existing Global Variable with the following configurations. For easy tracking of configurations, please use the Attendee ID as part of your global variable name. For example: + Name: AttendeeID_GV + + - Name: AttendeeID_GV + - Variable Type: String + - Default Value: _your prefered value_ + - Make Reportable: Yes + - Make Agent Viewable: Yes + - Desktop Label: _your prefered value_ + - Agent Editable: Yes + +#### 1.2. Next, login to Webex Connect portal and open your inbound chat flow + +- Click “Edit” on the top right of the flow +- Delete connection between “Queue Task” and “Update Conversation” +- Drag the “Set Variable” from the left panel and drop between “Queue Task” and “Update Conversation” nodes and connect them as shown in the video + +![Lab12.24.1_GVSecond](/assets/images/Lab12.24.1_GVSecond.png) + +- Configure “Set Variable” with the following: + + - Method Name: Select Global Variable + - Node Runtime Authorization: _Configured for your tenant_ + - Task ID: $(flid) + - Select the Global Variable configured earlier in WxCC Portal + - Set Variable: _Leave as default value configured_ + +- Save and make the flow live +- Start a new chat session and observe the Global variable value appearing in the interaction panel of Agent Desktop +- Capture the Session ID appearing at the address bar of the Agent Desktop upon accepting the chat session + +#### 1.3. Configure Analyzer to report the Global Variables configured in Webex Connect flow + +
    + +
    + +- Navigate to “Reporting and Analytics” at the left column of WxCC portal + +![Lab12.24.1_GVThird](/assets/images/Lab12.24.1_GVThird.png) + +- Create a new visualization with the following fields: + - Session ID + - _Global Variable defined in WxCC portal_ (In the video example, the Globle variable is _DavidGV1_) + - Create a report filter with the captured Session ID + +- Run the report and observe the Global variable value + +#### 1.4. Repeat a new chat sessions with the following scenario: + +- Chat session 2 use case: Prior to starting the chat session, open the specific flow again in Webex Connect. Edit the “Set Variable” value of the Global variable in the “Set Variable” node to something other than the default. Capture the Session ID for Analyzer report filter. +- Re-run the Anayzer report after adding the Session ID and observe the reported value of the Global variable. + +## 2. Configuring Flow Variables + +
    + +
    + +#### 2.1. Login in to Webex Connect portal and open your inbound chat flow + +- Click “Edit” on the top right of the flow +- Delete connection between “Set Variable” and “Update Conversation” +- Drag a second “Set Variable” from the left panel and drop between the earlier “Set Variable” and “Update Conversation” nodes and connect them as shown in the video +- Configure “Set Variable” with the following: + - Method Name: Select Flow Variable + - Node Runtime Authorization: _Configured for your tenant_ + - Task ID: $(flid) + - Set Variable: + - Name: AttendeeID_FV (For easy tracking, please prepend your Attendee ID) + - Type: String + - Value: + - Enable “Make agent viewable” + - Description: _your prefered value_ + - Desktop Label: _your prefered value_ + - Check “Agent Editable” +- Click Save +- Save and make the flow live. +- Start a new chat session and observe the Flow variable value appearing in the interaction panel of Agent Desktop. +- Note that Flow variables are not reportable in Analyzer. + +## 3. Transfer Global and Flow variable values between Webex Connect flows + +
    + +
    + +#### 3.1. Lab Objective + +To transfer chat form input and Global variable values from inbound chat flow to channel-agnostic routed flow for Agent Desktop screen pop + +#### 3.2. Login in to Webex Connect portal and open your routed flow + +- Click “Edit” on the top right of the flow +- Click on the gear icon at the top right of the screen and navigate to Custom Variables +- +![Lab12.24.3_TxFirst](/assets/images/Lab12.24.3_TxFirst.png) + +- Add the Global variable and Flow variable specific to your configuration (Note that the variables are case-sensitive) + +![Lab12.24.3_TxBetweenFirstSecond](/assets/images/Lab12.24.3_TxBetweenFirstSecond.png) + +- Next, double-click on the “Extract Task Variables” node and insert the following Javascript under Configuration tab just before the last line (Note: the italized words are specific to your variable name): + +`// function to extract fields into flow usable variables + +function extractVariable(varname) { + +    for (var i = 0; i < responseArray.length; i++) { + +        var object = responseArray[i]; + +        if (object.name == varname) { + +            return object.value; + +        } +    } +} + +//Extracting _NatureOfRequest_ and _DavidGV1_ variables set in the live chat inbound flow +var _natureOfRequest_ = extractVariable("_NatureOfRequest_"); +var _davidGV1_ = extractVariable("_DavidGV1_");` + +![Lab12.24.3_TxAftBetweenFirstSecond](/assets/images/Lab12.24.3_TxAftBetweenFirstSecond.png) + +- Within the same “Extract Task Variables” node, navigate to the second option “Transition Actions (Optional)” and add the Custom variables under “Time: On-leave” and “Action: Set variable” created above to the extracted Global and Flow variables: +- +![Lab12.24.3_TxSecond](/assets/images/Lab12.24.3_TxSecond.png) + +- Scroll down the same page and add both variables to the Debug Log for troubleshooting purposes if required. +- Save the settings and double-click on the Screen Pop node +- Add the following under “Query Parameters”: + +![Lab12.24.3_TxThird](/assets/images/Lab12.24.3_TxThird.png) + +- Save and make the flow live. +- Start a new chat session and observe the Screen Pop address bar upon Agent Desktop accepting the chat session. Both Global and Flow variables from the channel specific inbound chat flow are transfered to the routed flow. + + +![Lab12.24.3_TxLast](/assets/images/Lab12.24.3_TxLast.png) + + +# **Providing Digital Channels feedback** + +We are seeking your feedback on the Digital Channel capabilities. By participating in this survey, you will help us to improve the quality of our products: [https://forms.gle/qDRF2hYdkZHr5owa8 ](https://forms.gle/qDRF2hYdkZHr5owa8) + +--- + +**Congratulations, you have completed this section!** + + +--- diff --git a/_pages/IVR.md b/_pages/IVR.md new file mode 100644 index 0000000000..35733fcd58 --- /dev/null +++ b/_pages/IVR.md @@ -0,0 +1,735 @@ +--- +title: Lab 2 - IVR Contact Routing +author: Kevin Simpson & Krishna Tyagi & Chandramouli Vaithiyanathan +date: 2022-02-02 +category: Jekyll +layout: post +--- +``` +Last modified: Tue, 27 Jun 2023 +``` + + + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ----------------------------------------------------------------------------- | ------------- | --------------- | ---------------- | +| [Introduction to Flow Designer](#introduction-to-flow-designer) | Watch & Understand | EASY | 10 min| +| [Configuring tenant for Call Delivery](#configuring-tenant-for-call-delivery) | Practical Lab | EASY | 10 min | +| [Adding a comfort message while a call is in queue](#adding-a-comfort-message-while-a-call-is-in-queue) | Practical Lab | EASY | 8 min | +| [Creating alternating comfort messages while a call is in queue](#creating-alternating-comfort-messages-while-a-call-is-in-queue) | Practical Lab | EASY | 15 min | +| [Creating an opt-out option with ANI readout](#creating-an-opt-out-option-with-ani-readout) | Practical Lab | EASY | 15 min | +| [Adding the ability to receive a callback at a different number](#adding-the-ability-to-receive-a-callback-at-a-different-number) | Practical Lab | EASY | 15 min | +| [Adding the ability to collect an extension and present it to an agent during a callback](#adding-the-ability-to-collect-an-extension-and-present-it-to-an-agent-during-a-callback) | Practical Lab | EASY | 15 min | + + +--- + + +## Overview of the lab: + +In this lab, we will configure all of the required elements to deliver a call into a queue. We will then create a new flow and iterate on it adding functionality and exploring opportunities for improvement. + +## Introduction + +### Lab Objective + +- Configure Entry Point, Entry Point Mapping, Routing Strategy, and Queue +- Create a basic flow +- Add functionality to the flow by making small changes + + --- + +### Pre-requisites + +- Complete Lab 1 "Admin Experience" + - You have the administrator's access to the Tenant Management Portal. + - Agent and Supervisor users created and configured + - You have agent's access to the Agent Desktop + - You have the supervisor's access to the Tenant Management Portal. + - Agent is part of 2 Teams. + - Webex Calling extensions are assigned to a WxCC users (agent and supervisor). + + --- + +### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com){:target="\_blank"}**\ +> Portal: **[https://portal.wxcc-us1.cisco.com/](https://portal.wxcc-us1.cisco.com/){:target="\_blank"}**\ +> Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com){:target="\_blank"}**\ + + --- + + + +### Fill in the form with the details provided and agent email address you created in the previous lab, then click "Update Directions" +>Please skip the task if you are doing the labs on the Gold Tenant. The task below is only for the Lab Tenant option where you have received an email with the Lab tenant credentials. In a such case, please copy and paste the data from the email into the corresponding fields. +{: .block-tip } +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + + +
    + + + + +--- + +## Lab Section + +# Introduction to Flow Designer +> Flow designer is a simple drag-and-drop user interface (UI) to define the flows. The following video explains the Flow Designer layout, activity library, and terminology used in the Flow Designer. + +
    + +
    + + +# Configuring tenant for Call Delivery + +⚠️ If you are using your Gold Tenant you can use this link to download the [Audio Files](https://webexcc.github.io/assets/files/lab_wav.zip){:target="\_blank"}. Those files are already pre-uploaded on the Lab Tenant. + +### Create a queue + + 1.
    In the left pane of Control Hub > Select Contact Center > Queues (click for details) + +
    + +1. Click Create Queue + > Name your queue Q_AttendeeID + > + > Description: optional + > + > Queue Type: Inbound Queue + > + > Channel Type: Telephony + > + > Queue Routing Type: Longest Available Agent + > + > Call Distribution: + >> Click Create Group + >> + >> Select Your_Attendee_ID_Team1 + >> + >> Save Group + >> + >> Create second group + >> + >> Select Your_Attendee_ID_Team2 + >> + >> After: 60 Seconds in queue + >> + >> Priority: 2 + >> + >> Save Group + >> + >> Click Close + > + > --- + > + > Service Level Threshold: 60 + > + > Maximum Time in Queue: 600 + > + > Default Music in Queue: defaultmusic_on_hold.wav + > + > Save + + --- + +### Create your first flow +1. Download the [Flow Template](https://webexcc.github.io/../../../assets/files/flow_template.json){:target="\_blank"} + > The file will open in a separate window. + > + >>
    If using Firefox, Select the save option. (click for details) + >> + >> + >> + >>
    + >> + >>
    If using Chrome or Edge, right click and select save. (click for details) + >> + >> + >> + >>
    + >> + >>
    If using Chrome on a MAC, click the share icon in the URL bar and select save. (click for details) + >> + >> + >> + >>
    + >> + + + +2. In the left pane of Control Hub, click Flows +3. Click Manage Flows +4. Click Import Flows +5. Click Choose file or drag the flow template into the upload box +6. Click Import + +7. Click the name of the newly imported flow_template + > Rename the flow to AttendeeID_TechSummit by clicking on the pencil icon at the top of the screen, next to the flow name + > + > Click on the Play Message node + >> Audio File: welcome.wav + > + > --- + > Click on the Queue Contact node + >> Select Static Queue + >> + >> Queue: Q_AttendeeID + >> + > --- + > + > Click on the Play Music node + >> Select Static Audio File + >> + >> Music File: defaultmusic_on_hold.wav + >> + > --- + > + > Click the Validation switch to turn on validation + > + > Click Publish Flow + > + > Add a Publish Note of your choosing + > + > Click Publish Flow + > + > Click Return to Flow + > + > Turn off Validation + + --- + + + +### Create your Channel + +1. In the left pane of Control Hub, click Channels +2. Click Create Channel + > Name your Channel EP_AttendeeID + > + > Description: optional + > + > Channel Type: telephony + > + > Service Level Threshold: 60 + > + > Routing Flow: AttendeeID_TechSummit + > + > Music on Hold: defaultmusic_on_hold.wav + > + > In Support Number section: + > + >> Click Add + >> + >> In Webex Calling location, select "Office" + >> + >> In Available Numbers select Your Support Number + >> + >> Click the check mark + > + > Click Save + > + > --- + + +### Test your configuration +1. Call Your Support Number from your supervisor extension + > You should hear the greeting message and then the music in queue + > + > Go available in the agent desktop + >> The call should be delivered to your agent extension + > + > End the call, Wrap-up, and Go unavailable + > + > --- + +# Adding Functionality to Your Flow + +## Adding a comfort message while a call is in queue +1. Delete the connection which loops from the end of the Play Music node back to the beginning of the Play Music node. +2. Drag a new Play Message node under the Play Music node. +3. Click on the Play message node + > + > Activity Label: comfortMessage + > + > Audio File: comfort_1_English + > + > --- +4. Click on the Play Music node + > Set the music duration to 15 seconds + > + > --- +5. Connect the end of the Play Music node to the beginning of the play message node. +6. Connect the end of the Play Message node to the beginning of the Play Music node. +7. Validate and Publish the flow: + > Click the Validation switch to turn on validation + > + > Click Publish Flow + > + > Add a Publish Note of your choosing + > + > Click Publish Flow + > + > Click Return to Flow + > + > Turn off Validation + > + > [Compare](https://webexcc.github.io/../../../assets/images/IVR/comfortMessage.JPG){:target="\_blank"} + > + > --- +8. Place a test call to Your Support Number + > Did you hear the comfort message every 15 seconds? + > + > --- + +## Creating alternating comfort messages while a call is in queue +1. Create a new flow variable: + > Click on the cog in the lower left corner of the canvas (or on the background of the flow) + > + > Click Add Flow Variables + >> Name: Loop_Count + >> + >> Variable Type: Integer + >> + >> Default value: 0 + > + > Click Save + > + > --- + +2. Delete the connection from the Play Music node to the comfortMessage node. +3. Drag a Set Variable node onto the canvas and place it below the Play Music node +4. Click on the Set Variable node + > Activity Label: lCount + > + > Variable: Loop_Count + > + > Set Value: \{\{ Loop_Count + 1 \}\} + > + > --- +5. Connect the Play Music node to lCount +6. Drag a Condition node on the canvas +7. Connect the end of the Set Variable node to the Condition node +8. Click on the condition node + > Activity Label: evenOdd + > + > Expression: \{\{ Loop_Count is odd\}\} + > + > --- +9. Drag another Play Message node onto the canvas + > Activity Label: websiteMessage + > + > Audio File: website_English.wav + > + > --- +10. Connect the True node edge from evenOdd to comfortMessage +11. Connect the False node edge from evenOdd to websiteMessage +12. Connect the end of websiteMessage node to the Play Music node +13. Publish your flow [Compare](https://webexcc.github.io/../../../assets/images/IVR/altMessages.JPG){:target="\_blank"} +14. Place a test call to Your Support Number + > Did you hear the comfort message and website message alternate every 15 seconds? + > + > --- + +## Creating an opt-out option with ANI readout +1. Create new flow variables: + > Name: callbackANI + >> Type: String + >> + >> No default value + > + > --- + > + > Name: rDigit + >> Type: string + >> + >> No default value + > + > --- + > + > Name: sPosition + >> Type: Integer + >> + >> Default Value: 0 + >> + --- +2. Delete the connection from the websiteMessage node to Play Music +3. Drag a Menu node onto the canvas + > Activity Label: callback_opt + > + > Audio File: opt_out_English.wav + > + > Make Prompt Interruptible: True + > + > Digit Number: 1 Link Description: optOut + > + > Connect the No-Input Timeout node edge to Play Music + > + > Connect the Unmatched Entry node edge to Play Music + > + > --- +4. Connect the websiteMessage to the callback_opt node +5. Add a Set Variable node + > Activity Label: callbackANI_set + > + > Select Variable: callbackANI + > + > Set to Value: \{\{NewPhoneContact.ANI \| slice (NewPhoneContact.ANI.length -10,NewPhoneContact.ANI.length)\}\} + > + --- +6. Connect the callback_opt optOut node edge to callbackANI_set +7. Add a Play Message Node + > Activity Label: cfrom + > + > Audio File: calling_from_English.wav + > + > --- +8. Connect callbackANI_set to cfrom +9. Add a Set Variable node + > Activity Label: rDigit_set + > + > Select Variable: rDigit + > + > Set to Value: \{\{callbackANI \| slice (sPosition,sPosition+1)\}\} + > + --- +10. Connect cfrom to rDigit_set +11. Add a Play Message node + > Activity Label: playDigit + > + > Click Add Audio Prompt Variable + >> Audio Prompt Variable: \{\{rDigit\}\}_English.wav + >> + >> Delete the Audio File Drop Down + >> + >> --- +12. Connect rDigit_set to playDigit +13. Add a Set Variable node + > Activity Label: advance + > + > Select Variable: sPosition + > + > Set to Value: \{\{sPosition+1\}\} + > + --- +14. Connect playDigit to advance +15. Add a Condition node + > Activity Label: positionCheck + > + > Condition: \{\{sPosition <= (callbackANI.length -1) \}\} + > + > True: Connect to rDigit_set + > + > False: Add a new Disconnect Contact node and connect it here + > + --- +16. Connect advance to positionCheck +17. Publish your flow [Compare](https://webexcc.github.io/../../../assets/images/IVR/aniRead.JPG){:target="\_blank"} +18. Place a test call to Your Support Number + > When you are given the option for a callback, press 1. + >> Did you hear your 10 digit callback number being read back? + + --- + + + +## Adding the ability to receive a callback at a different number +1. Add a new Menu node + > Activity Label: confirmNumber + > + > Prompt: number_confirm_English.wav + > + > Make Prompt Interruptible: True + > + > Digit Number: 1 Link Description: confirm number + > + > Digit Number: 2 Link Description: change number + > + > Connect No-Input Timeout to the front of the confirmNumber node + > + > Connect Unmatched Entry to the front of the confirmNumber node + > + > --- +2. Delete the False node edge from positionCheck to Disconnect Contact +3. Connect the False node edge from positionCheck to confirmNumber +4. Connect the confirm number node edge to Disconnect Contact +5. Add a Collect Digits node + > Activity Label: newNumber + > + > Audio File: new_number_English.wav + > + > Make Prompt Interruptible: True + > + > Minimum Digits: 10 + > + > Maximum Digits: 10 + > + > Connect No-Input Timeout to the front of the newNumber node + > + > Connect Unmatched Entry to the front of the newNumber node + > + > --- +6. Connect the change number node edge to newNumber +7. Add a Set Variable Node + > Activity Label: newCB + > + > Variable: callbackANI + > + > Set Value: \{\{newNumber.DigitsEntered\}\} + > + > --- +8. Connect newNumber to newCB +9. Add a Set Variable Node + > Activity Label:resetPosition + > + > Variable: sPosition + > + > Set Value: 0 + > + > --- +10. Connect newCB to resetPosition +11. Add a Play message node + > Activity Label: rcontext + > + > Audio File: entered_English.wav + > + > --- +12. Connect resetPosition to rcontext +13. Connect rcontext to rDigit_set +14. Publish your flow [Compare](https://webexcc.github.io/../../../assets/images/IVR/changeNumber.JPG){:target="\_blank"} +15. Place a test call to Your Support Number + > When you are given the option for a callback, press 1. + > + > Press 2 to enter a different number. + >> Did you hear your 10 digit callback number being read back? + >> + >> Did you hear the number you entered read back? + + --- + + + +## Adding the ability to collect an extension and present it to an agent during a callback +1. Create new flow variable: + > Name: Extension + > + >> Type: String + >> + >> No default value + >> + >> Set as agent Viewable: True + >> + >> Desktop Label: Extension + > + --- +2. Add a Menu node + > Activity Label: needExt + > + > Audio File: ext_English.wav + > + > Make Prompt Interruptible: True + > + > Digit Number: 1 Link Description: collect ext + > + > --- +3. Delete to connection from the confirm number node edge of confirmNumber to Disconnect Contact +4. Connect the confirm number node edge of confirmNumber to needExt +5. Add a Collect Digits node + > Activity Label: getEXT + > + > Audio File: enter_ext_English + > + > Make Prompt Interruptible: True + > + > Connect the No-Input Timeout node edge to the front of the getEXT node + > + > Connect the Unmatched Entry node edge to the front of the getEXT node + > + > --- +6. Connect the collect ext node edge of needExt to getEXT +7. Add a Set Variable node + > Activity Label: setExt + > + > Variable: Extension + > + > Set Value: \{\{getEXT.DigitsEntered\}\} +8. Connect getEXT to setEXT +9. Add a Set variable node + > Activity Label: clrsPos + > + > Variable: sPosition + > + > Set Value: 0 + > + > --- +10. Connect setEXT to clrsPos +11. Add a Play Message node + > Activity Label: entEXT + > + > Audio File: entered_English.wav + > + > --- + +12. Connect clrsPos to entEXT +13. Use Shift + left click to select nodes: + - rDigit_set + - playDigit + - advance + - positionCheck +14. Click the copy button in the lower left corner of the canvas +15. Drag the copied versions of the nodes under the clrsPos node +16. Rename the copied nodes the original names = _EXT (example: rDigit_set_EXT) +17. Connect entEXT > rDigit_set_EXT > playDigit_EXT > advance_EXT > positionCheck_EXT +18. Edit rDigit_set_EXT + > Set value: \{\{Extension \| slice (sPosition,sPosition+1)\}\} + > + > --- +19. Edit positionCheck_EXT + > Expression: \{\{sPosition <= (Extension.length -1) \}\} + > + > Connect True node edge to rDigit_set_EXT + > + > --- +20. Add a Menu node + > Activity Label: confirmEXT + > + > Audio File: ext_confirm_English.wav + > + > Make Prompt Interruptible: True + > + > Digit Number: 1 Link Description: confirmed + > + > Digit Number: 2 Link Description: again + > + > Connect No-Input Timeout to the front of the confirmEXT node + > + > Connect Unmatched Entry to the front of the confirmEXT node + > + > Connect the Again node edge to getEXT + > + > --- +21. Connect the False node edge of positionCheck_EXT to confirmEXT +22. Add a Callback node + > Activity Label: callback + > + > Callback Dial Number: callbackANI + > + > Callback Queue: Q_AttendeeID + > + > --- +23. Connect the confirmed node edge of confirmedEXT to callback +24. Add a Play Message node + > Activity Label: callbackConfirm + > + > Audio File: callback_confirm_English.wav + > + > --- +25. Connect callback to callbackConfirm +26. Connect callbackConfirm to Disconnect Contact +27. Connect the No-Input Timeout and Unmatched Entry node edges from needExt to Disconnect Contact +28. Publish your flow [Compare](https://webexcc.github.io/../../../assets/images/IVR/collectExt.JPG){:target="\_blank"} +29. Place a test call to Your Support Number + > Press one to receive a callback + > + > Press one to keep the number which was read back + > + > Press one to receive a callback at an extension + > + > Enter Your Supervisor Extension and press #. + > + > In the agent desktop, go available. + > + > When your agent phone rings, answer the call. + > + > Listen to the prompts and enter the Extension shown on the agent desktop. + > + > Your Supervisor extension should ring, answer it. + > + > --- + + + + +### Coming soon: +#### Making the flow bi-lingual +#### Cisco TTS +#### Adding HTTP Request +#### Pubble Template + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    + diff --git a/_pages/JDS_XM.md b/_pages/JDS_XM.md new file mode 100644 index 0000000000..57b3cbc139 --- /dev/null +++ b/_pages/JDS_XM.md @@ -0,0 +1,464 @@ +--- +title: Lab 8 - Feedback and Journey +author: Ankan Dutta & Gagarin Sathiyanarayanan +date: 2022-08-08 +layout: post +--- + +``` +Last modified: Tue, 6 Aug 2024 +``` + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------------------------------------------- | ------------------ | ---------------- | ---------------- | +| [Introduction to Experience Management](#introduction-to-experience-management-post-interaction-and-post-call-surveys) | Watch & Understand | EASY | 7 min | +| [Configure Post Call IVR Survey](#configure-post-call-ivr-survey) | Practical Lab | EASY | 10 min | +| [Configure Post Interaction Digital Survey](#configure-post-interaction-digital-survey) | Practical Lab | EASY | 10 min | +| [Customer Journey Data Services (JDS) Introduction](#customer-journey-data-services-cjds) | Watch & Understand | EASY | N/A | +| [JDS Feature Overview](#jds-feature-overview) | Watch & Understand | EASY | 10 min | +| [Setup JDS](#setup-jds) | Watch & Understand | EASY | N/A | +| [Desktop Customer Journey Widget](#desktop-customer-journey-widget) | Watch & Understand | EASY | N/A | +| [JDS APIs](#jds-apis) | Practical Lab | MEDIUM | 40 min | +| [JDS Use Case Samples](#jds-use-case-samples) | Practical Lab | MEDIUM | 60 min | + +## Overview of the lab: + +In this lab, we will configure all the required elements to collect and view end-customer feedback using the new Experience Management. + +### Lab Objective + +- Create a basic survey +- Upload audio files to the survey +- Configure the survey in flow designer +- Simulate a customer interaction with survey feedback +- Download and verify survey feedback + + *** + +### Pre-requisites + +1. You have **completed Lab 1 - Admin Experience:** + - You are familiar with Control Hub and navigation within Control Hub +2. You have **completed Lab 2 - IVR Contact Routing:** + - You are familiar with creating and modifying flows +3. You have **completed Lab 3 - Agent Desktop:** + - You are familiar with logging in as an Agent and accepting inbound interactions +4. You have **Webex Calling installed** in your mobile phone and supervisor created in Lab 1 from which you can make calls to the contact center + + *** + +### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com){:target="\_blank"}**\ +> Portal: **[https://portal.wxcc-us1.cisco.com/](https://portal.wxcc-us1.cisco.com/){:target="\_blank"}**\ +> Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com){:target="\_blank"}**\ + +--- + +## Introduction + +# Introduction to Experience Management Post Interaction and Post Call Surveys + +> Experience Management is a next-gen tool that facilitates post interaction surveys and outcomes. It allows you to track and measure customer satisfaction using anchor metrics like Net Promoter Score (NPS), Customer Effort Score (CES), and Customer Satisfaction (CSAT). Webex Contact Center brings in an integration of Experience Management for its post call survey interactive voice response (PCS IVR) and digital channels. + +
    + +
    + +## Lab Section + +# Configure Post Call IVR Survey + +### Create a survey + +1. Click on Contact Center under Services from Control Hub + > +2. Under Contact Center, click on Surveys + > +3. Click the "Create new survey" button on the top-right corner of the Survey page + > Select Survey type as IVR + > + > > + > > + > > Provide a name for your survey appended with your Attendee ID + > > + > > + > > Choose the additional languages for the survey from the drop-down (optional) + > > + > > + > > Click on Next +4. Add audio files to the Welcome and Thank you notes ([Audio Files](https://webexcc.github.io/assets/files/Survey_wav.zip){:target="\_blank"}) + > Click on the pencil icon to the right + > + > > + > > + > > Select Choose a file when the note expands, pick the audio file (Welcome.wav) and upload + > > + > > + > > Repeat steps for Thank you note (Thankyou.wav) +5. Add a question to your survey + > Select the NPS question from the drop-down by clicking + Add a question + > + > > + > > + > > Choose the corresponding audio file, nps.wav for the NPS question and upload ([Audio Files](https://webexcc.github.io/assets/files/Survey_wav.zip){:target="\_blank"}) + > > + > > + > > Under Question to show on reporting type the column name as "NPS Score" + > > +6. Update Error handling settings (optional) + > Upload audio files for Invalid Input and Timeout by clicking on Choose a file under each section + > + > Set the maximum number of invalid inputs and timeouts allowed from the drop-down + > + > Choose an audio file for exceeding maximum tries +7. Save the survey from the bottom right corner + +--- + +### Add the feedback activity to your flow + +> **NOTE:** Refer to the Lab 2 - IVR Contact Routing if you are unfamiliar with working on flow designer +> {: .block-warning } + +1. Open your flow created from Lab 2 - IVR Contact Routing +2. Introduce a Menu into your main flow to prompt the caller to opt-in for the survey in between the NewPhoneContact event and the Queue Contact node + > Activity Label: surveyOptin + > + > Prompt: OptinMenu.wav ([Audio Files](https://webexcc.github.io/assets/files/Survey_wav.zip){:target="\_blank"}) + > + > Make Prompt Interruptible: True + > + > Digit Number - 1 + > + > > Link Description: Opt-In + > + > Digit Number - 2 + > + > > Link Description: Opt-Out +3. Assign true and false values for the Global_FeedbackSurveyOptin variable + > Drag and drop two Set Variable nodes into your main flow after the Menu + > + > Click on the first Set Variable node + > + > > Activity Label: OptIn + > > + > > Variable: Global_FeedbackSurveyOptin + > > + > > Set Value: TRUE + > + > Click on the second Set Variable node + > + > > Activity Label: OptOut + > > + > > Variable: Global_FeedbackSurveyOptin + > > + > > Set Value: False +4. Connect the nodes together + > Connect Custom Menu Links for digit 1 to the Set Variable node with Global_FeedbackSurveyOptin set as true + > + > Connect Digit 2 and error handling links to the Set Variable node with Global_FeedbackSurveyOptin set as false + > + > Connect the Set Variable blocks back to your flow before Queue Contact + > + > Example Flow + > + > > +5. Navigate to the Event Flows tab +6. Add the Feedback V2 node + > Connect the Feedback V2 node to the AgentDisconnected Activity + > + > Click on the Feedback V2 node + > + > > Activity Label: PCS_IVR + > > + > > Survey Method: Voice Based + > > + > > Select survey created earlier from drop-down + > > + > > Timeout: 10 +7. Complete the flow by adding a Disconnect Contact node after the Feedback V2 node + > Example Flow + > + > > +8. Validate and Publish the flow + +--- + +### Provide a survey response + +> **NOTE:** Refer to the section Basic Features in Lab 3 - Agent Desktop if you are unfamiliar with testing an incoming call +> {: .block-warning } + +1. Login to your Agent Desktop and make your state Available +2. Dial your designated DN and accept the incoming voice interaction +3. Provide the DTMF input 1 to opt-in to the survey +4. End the interaction from the Agent Desktop +5. Provide a rating on the scale 0-9 + +--- + +### Download and validate the survey response + +1. Navigate to the Surveys page on Control Hub +2. Click on the download button on the far right of your survey + > +3. Select the date range for the survey response period as Last 7 days and click Download + > +4. Verify your response in the excel sheet to the one you provided on the call + > + +--- + +# Configure Post Interaction Digital Survey + +> Coming soon. ETA is December 2024. +> {: .block-warning } + +--- + +# Customer Journey Data Services (CJDS) + +### Overview of the Lab + +In this lab, we will understand what is the Customer Journey Data Services (JDS) feature, how we can set it up and configure it in the Control Hub and how to enable the JDS Desktop widget for agents. Furthermore, we will see the Customer Journey Widget in action from an agent perspective and we will delve into all the API capabilities that the features offers. + +Finally, we will become familiar with the JDS Use Case library that Cisco has created to showcase how JDS can help you take your customers' journey to the next level. + +### Lab Objective + +At the end of this lab, you will be able to: + +- Enable JDS feature and the Customer Journey Widget in your tenant. +- Create and manipulate an end-user database with your customer information. +- Add the Customer Journey Widget to your Agent Desktop and take advantage of it during a customer interaction. +- Utilize the JDS APIs to enhance the customer journey experience with additional insights & actions. + +### Pre-requisites + +1. You have **completed** `Lab 1 - Admin Experience`: + - You are familiar with Control Hub and navigation within Control Hub, logging in as an administrator. +2. You have **completed** `Lab 2 - IVR Contact Routing`: + - You are familiar with creating and modifying flows +3. You have **completed** `Lab 3 - Agent Desktop`: + - You are familiar with logging in as an Agent and accepting inbound interactions. + - You are familiar with creating a custom Desktop Layout +4. You have **Webex Calling installed** in your device and can make calls to the contact center. + +### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com){:target="\_blank"}**\ +> Portal: **[https://portal.wxcc-us1.cisco.com/](https://portal.wxcc-us1.cisco.com/){:target="\_blank"}**\ +> Agent Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com){:target="\_blank"}**\ +> Developer Portal: **[https://developer.webex-cx.com/documentation/getting-started](https://developer.webex-cx.com/documentation/getting-started){:target="\_blank"}**\ + +## JDS Feature Overview + +CJDS is an API-first service that enables organizations to: + +- `Listen`: Integrate with any data source or third-party applications to listen to disparate data sources (e.g. customer called Support ...). +- `Identify`: Create a dynamic customer profile capturing propensity drivers, such as a customer's preferred mode of communication or preferred language (e.g. how many times has the customer contacted us in the last week?...). +- `Analyze`: Apply different aggregation techniques to all customer data collected (e.g. What is the CSAT score of the customer interaction? Is he using telephony,chat or other channel to contact? ...). +- `Act`: Use the data and insights within CJDS to dynamically change the flow within Webex Contact Center Flow Control and personalize the customer experience at a granular level. These insights are visible to customer-facing teams in real time through Agent Desktop. (e.g. bypass normal queue when customer calls for the third time in 24 hours and offer premium support...) + +A comprehensive summary of the feature is available in the [Developer Portal](https://developer.webex-cx.com/documentation/guides/journey---getting-started), where you can find all the vital information & step-by-step guide to enable JDS for the first time in your own tenant. CJDS is currently in `Limited Availability` for **US and EMEA based tenants** only. Rest of the regions (ANZ, Canada, Japan, Singapore) are expected to come within the year. + +## Setup JDS + +1. You need to fill out this [form](https://app.smartsheet.com/b/form/7776df72239e47d0bbb73a392e32927f) to get CJDS enabled, as it **not** by default enabled in all tenants in the Limited Availability regions. If applicable, please work together with your CSM to ensure a smooth process and enablement.Post the initial request, the Cisco team will assist you with CJDS instance setup within 72 hours + +2. When JDS is provisioned for the tenant, - `Customer Journey Data` tab appears in the Control Hub + +![jdschtab](/assets/images/JDS/jds_ch_tab.png) + + +## Desktop Customer Journey Widget +The customer Journey widget provides a single pane of glass view to the customer’s journey across all channels and applications, giving you the necessary contextual data for a more personalized customer experience and reducing average handling time. + +### Create a journey project and Activate Webex Contact Center connector +1. Sign in to Control Hub and go to Customer Journey Data > Journey projects +2. You can use the default Sandbox Project or Click Create a journey project +3. Enter a name and a description for the journey project +4. Select a journey project that you created in previous step +5. Toggle the Activate connector in the Webex Contact Center section to on + +![jdsactivateproject](/assets/images/JDS/jds_activate_project.png) + + + +### Add user identities to a journey project. +1. Select a journey project for which connector was activated +2. Select Identities .Click Add identities + +![jdsaddidentities](/assets/images/JDS/jds_add_identities.png) + + + +3. Download sample template + +![uploadcsvjds](/assets/images/JDS/upload_csv_jds.png) + + +4. In CSV file download, add the Customer identities [First Name,Last Name,Email Addresses,Phone Numbers,Customers Ids] +Each customer identity must have at least an email address, phone number, or customer ID or else the CSV file will return an error. +If you want to add multiple email addresses, phone numbers or customer IDs, you need to use the pipe “|” delimiter between them. For example, try to add your phone number both with and without a plus sign +For the Id column, make sure to leave each row empty. When you upload the CSV file, this field will auto-generate + +![jdscreatedcsv](/assets/images/JDS/jds_created_csv.png) + + +5. Upload a CSV file that you created for customer identities, and then click Next +6. If the CSV file is valid, a window appears to show you if the import was successful. Once you're done, select Close. You should see a list of all the uploaded customer identities + + +### Enable customer journey widget on an agent desktop + +1. Download the following Desktop Layout JSON file [JDSDesktopLayout](/assets/files//JDSDesktopLayout10.json) + +- If you are interested in adding the CJDS Widget to your existing desktop layout, get below code snippet + +CJDS Widget Code Block +```json + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "span", + "textContent": "Customer Journey" + } + ] + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "customer-journey-widget", + "script": "https://journey-widget.webex.com", + "attributes": { + "show-alias-icon": "true", + "condensed-view": "true" + }, + "properties": { + "interactionData": "$STORE.agentContact.taskSelected", + "bearerToken": "$STORE.auth.accessToken", + "organizationId": "$STORE.agent.orgId", + "dataCenter": "$STORE.app.datacenter" + }, + "wrapper": { + "title": "Customer Journey Widget", + "maximizeAreaName": "app-maximize-area" + } + } + ] + }, +``` +Here is a screenshot of the block in place (notice it is after IVR_TRASNCRIPT and before WXM_JOURNEY_TAB + +![JDSWidgetCode](/assets/images/JDS/JDS_Widget_Code.png) + + +2. Sign in to Control Hub and go to Contact Center > Desktop Layouts. + +3. Create a new Layout + +4. Assign an agent team + +5. Upload the Desktop Layout JSON file that you downloaded in step 1 + +4. Click Save + + +### View customer journey widget on an Agent desktop + +1. Login as an Agent into Agent Desktop. + +2. On Accepting an incoming request,CJDS Widget will appear in the right hand side + +The widget displays insights such as the number of times the customer has called or was contacted across all channels during a given duration. It also displays the channel history with wrap-up code, queue name, agent ID, and so on, and customizable event history such as third-party events and custom icons. + +The progressive profile allows for alignment of different phone numbers and emails under one profile, ensuring accurate and comprehensive interaction data + +![JDSWidgetDesktop](/assets/images/JDS/JDS_Widget_Desktop.png) + +## JDS APIs + +### API Documentation & Definitions + +AS JDS is an API-first solution, there is a wide range of APIs available. All the APIs can be found in the [Developer Portal](https://developer.webex-cx.com/documentation/journey), where -as with all APIs- there is information on how to create the API request, the path/query parameters, the expected response as well as a sample code example. For more information on Webex Contact Center APIs & Authentication, you can follow and the complete the [API Lab - Lab 11](https://webexcc.github.io/pages/API/). + +![JourneyDevPortal](/assets/images/JDS/JDS_Dev_Portal.png) + +To be able to understand all the capabilities these APIs offer, it is important to become familiar with a few terms used in them: + +- `Project / Workspace`: A uniquely identified entity that includes a specific set of JDS configurations and data sources. + - At any given moment, only one project can be active per tenant (i.e. listen to events). +- `Subscription`: The events that JDS listens on, e.g. all the agent activity state changes/logins/logouts are one default JDS subscription. +- `Identity / Person`: A unique customer, all the events that the same customer (e.g. call, chat, email, visit website) creates are marked under the same identity. +- `Alias`: Different ways we can identify the same customer/person (e.g. email, phone number, Customer ID). Customer **must have at least one alias**. +- `Profile Template`: A profile template defines the kind of aggregation technique we want to see for a customer (e.g. contacts within last 24 hours). +- `Progressive Profile`: The values that correspond to an identity’s profile template at that particular moment of time (e.g. contacts within last 24 hours = 10). +- `Actions`: Actions can mean two different things in the concept of JDS: + - The logical concept of differentiating the experience based on the result of Analyze (e.g. Call priority for repeated callers). + - An automated programmatic response to events (e.g. send an SMS to a repeated caller). + +### JDS API Collection + +As there a lot of different APIs available in JDS, to make the introduction to them easier, Cisco has created a [JDS API Collection](https://github.com/WebexSamples/webex-contact-center-api-samples/blob/main/customer-journey-samples/cjds-postman-example/JDS%20CiscoLive.postman_collection.json) as a starting point. In this segment, we will download this collection and import it to `Postman`, but any other API design platform can be used. + +1. Download the JDS Postman collection, by going to the [GitHub samples page](https://github.com/WebexSamples/webex-contact-center-api-samples/blob/main/customer-journey-samples/cjds-postman-example/JDS%20CiscoLive.postman_collection.json). + +2. Click on **Download raw file**. + ![JDSDownloadRaw](/assets/images/JDS/JDSDownloadRaw.png) + +3. Open the `Postman` app and click on the **Import** button. + +4. Select the **downloaded JSON file** in the appeared window. + ![JDSImport](/assets/images/JDS/JDSImport.png) + +5. Once the JDS collection is imported, select the root folder of the imported collection in the left menu, then navigate to the **Variables**, and define the values. + +6. Once the values are defined, click the **Save** button. + ![JDSSave](/assets/images/JDS/JDSSave.png) + +7. Go to **Authorization** and click on **Get New Access Token** button. The Postman will redirect you to the Auth page where you need to define your Admin account which was used for the App creation in the dev portal. As a result, you should get the message **Authentication complete**. Click **Proceed** and on the next page click on **Use Token** button. + ![JDSAuth](/assets/images/JDS/authJDS.gif) + +After successfully saving your JDS API collection in Postman, you can also check on the following video that shows how to use combinations of these APIs to manage your JDS profiles and templates. + +
    + +
    + +### JDS API Example + +> Work in progress. ETA is August 2024. +> {: .block-warning } + +## JDS Use Case Samples + +### Journey Based Queue Priority + +> Work in progress. ETA is August 2024. +> {: .block-warning } + +### More Use Cases + +More use case samples that utilize the Customer Journey Data Services (JDS) can be found in the Cisco Webex Contact Center samples [GitHub page](https://github.com/WebexSamples/webex-contact-center-api-samples/tree/main/customer-journey-samples). + +We highly suggest you **bookmark** this page as more use cases will be added in the future. + +--- + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    diff --git a/_pages/Provisioning.md b/_pages/Provisioning.md new file mode 100644 index 0000000000..759e9f2bd4 --- /dev/null +++ b/_pages/Provisioning.md @@ -0,0 +1,75 @@ +--- +title: Lab 0 - Provisioning +author: Yaroslav Bondar +date: 2022-01-01 +layout: post +--- +``` +Last modified: Fri, 10 May 2024 +``` + +## Webex Contact Center Provisioning +This is a supportive videos that do not require any actions since your tenant is already provisioned. Videos demonstrate the initial provisioning tasks for New Webex Contact Center as well as applying production subscriptions to existing organizations. + +## Table of Contents + + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ------------------------------------------------------------------------------------- | ------------------ | ---------------- | ---------------- | +| [How to create Webex Contact Center Trial](#how-to-create-webex-contact-center-trial) | Watch & Understand | EASY | 6 min | +| [Provisioning New Customer Organization](#provisioning-a-new-customer-organization) | Watch & Understand | EASY | 9 min | +| [Webex Contact Center Developer Sandbox](#webex-contact-center-developer-sandbox) | Read & Understand | EASY | 30 min | + + + +# How to create Webex Contact Center Trial +This video demonstrates the process of creation Webex Contact Center Trial. To create a Trial it is not necessary to go through the ordering process. Trial tenants are a great option for partners who are willing to start with the configuration before billing started. +> NOTE: By default the Webex Contact Center trial feature is not available in Partner Hubs. It can be activated only after approval. Please contact your PSM/CSM. +{: .block-tip } + +
    + +
    + + +# Provisioning a New Customer Organization +This video demonstrates how to create a new Customer organization by using Provisioning email generated in Web Order. +>Note: The demo explains how to provision a Gold Tenant order but the process is identical to production Webex Contact Center environment +{: .block-tip } + +
    + +
    + +--- + +# RTMS Overview + +> Real Time Media Services (RTMS) is a media processing layer for Webex Contact Center customers. This video will discuss what RTMS is, how it fits into the existing Webex Contact Center ecosystem, the customer onboarding process and a brief description of our roadmap and feature support. + +
    + +
    + +RTMS PDF: [RTMS GA Launch.pdf](https://webexcc.github.io/files/RTMS%20GA%20Launch.pdf) + + +>RTMS is a media processing layer for Webex Contact Center customers. This video will discuss what RTMS regional media is, how it fits into the existing Webex Contact Center ecosystem, the customer activation process and configuration of regional media. + +
    + +
    + +RTMS Regional Media PDF: [RTMS EA Regional Media.pdf](https://webexcc.github.io/files/RTMS%20EA%20Regional%20Media.pdf) + +# Webex Contact Center Developer Sandbox +A Contact Center Developer Sandbox provides you with administrator access to a licensed Webex organization. A licensed org lets you create and test capabilities of the Webex platform not available with Webex free plans. + +To get started with a Sandbox please follow the instructions in [Contact Center for Developers portal](https://developer.webex-cx.com/sandbox). + + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    + + diff --git a/_pages/Supervisor.md b/_pages/Supervisor.md new file mode 100644 index 0000000000..59c164aba6 --- /dev/null +++ b/_pages/Supervisor.md @@ -0,0 +1,271 @@ +--- +title: Lab 4 - Supervisor Desktop +author: Benjamin Bollaert & Yurii Ulianov & Iranthi Ulluwishewa +date: 2022-04-04 +layout: post +--- +``` +Last modified: Tue, 24 Oct 2023 +``` + +## Table of Contents + +| Topic | Lab Type | Difficulty Level | Estimated length | +| ---------------------------------------------------------------------------------- | ------------- | ---------------- | ---------------- | +| [Assign supervisor license to the user](#assign-supervisor-license-to-the-user) | Practical Lab | EASY | 5 min | +| [Configure supervisor in Management Portal](#configure-supervisor-in-management-portal) | Practical Lab | EASY | 10 min | +| [Supervisor Experience](#supervisor-experience) | Practical Lab | EASY | 15 min | | + + + +## **Introduction** + +#### **Lab Objective** + +This lab is designed to introduce the audience to the Extensible Supervisor Desktop (ESD), its configuration and capabilities. In addition this lab contains demo which shows user experience when working with ESD. + +#### **Pre-requisite** + +1. Admin credentials for sign-in to Control Hub. +2. At least one admin and one supervisor user with extensions have been created on Control Hub according to the instructions provided in ***Lab 1 - Admin Experience***. +4. Standard or Premium agent license is assigned to the agent's account on Control Hub. +5. The agent account is configured on the Webex CC management portal and you are able to sign in as an agent. + +#### Example of agent and supervisor users on Control Hub + +| **User Role** | **User email** | **Endpoint** | +| ------------- | ----------------------------------------------------------------------------- | ------------- | +| Agent | wxcclabs+agent_AttendeeID@gmail.com | WebRTC | +| Supervisor | wxcclabs+supvr_AttendeeID@gmail.com | Webex App | + +>**Note:** Please refer ***Lab 1 - Admin Experience*** if you need to add agent or supervisor users on Control Hub. + +#### Quick Links + +> Control Hub: **[https://admin.webex.com](https://admin.webex.com/){:target="\_blank"}** +> Webex CC Management Portal: **[https://portal.wxcc-us1.cisco.com/portal](https://portal.wxcc-us1.cisco.com/portal){:target="\_blank"}** +> Agent / Supervisor Desktop: **[https://desktop.wxcc-us1.cisco.com](https://desktop.wxcc-us1.cisco.com/){:target="\_blank"}** + +# Assign supervisor license to the user + +- Login to Control Hub under the organization admin account. +- Go to ***Users***, click on supervisor's account, scroll dow to ***Licenses*** section and press ***Edit Licenses*** button. + +![Lab_4_Supervisor_Config_1](/assets/images/DC_Lab_4_Supervisor_Config_1.png) + +- Press ***Edit Licenses*** button on ***Edit services*** page. + +![Lab_4_Supervisor_Config_2](/assets/images/DC_Lab_4_Supervisor_Config_2.png) + +- Go to ***Contact Center*** tab, tick ***Licenses Agent*** checkbox and assign ***Premium Agent - Supervisor Role*** license. Then save changes. + +![Lab_4_Supervisor_Config_3](/assets/images/DC_Lab_4_Supervisor_Config_3.png) + +- Check and make sure supervisor license has been assigned. Then click on ***Close*** button to return to the user settings. + +![Lab_4_Supervisor_Config_4](/assets/images/DC_Lab_4_Supervisor_Config_4.png) + +- Check and make sure supervisor license is displayed in ***Licenses*** section of user seetings on Control Hub. + +![Lab_4_Supervisor_Config_5](/assets/images/DC_Lab_4_Supervisor_Config_5.png) + +- Go to ***Contact Center*** -> ***Settings*** and press ***Synchronize Users*** button to sync all changes from Control Hub to Webex CC Management Portal. + +![Lab_4_Supervisor_Config_6](/assets/images/DC_Lab_4_Supervisor_Config_6.png) + + +# Configure supervisor in the Management Portal + +- Download the latest [Supervisor Desktop Layout JSON](https://www.cisco.com/c/dam/en/us/td/docs/voice_ip_comm/cust_contact/contact_center/webexcc/Supervisor-Call-Recordings-review-and-playback/Supervisor_Call_Recordings_review_and_playback_default-config.json){:target="\_blank"} file with Call Recordings feature. + +- Open the file in any JSON editor, check, and make sure it contains ***supervisor*** and ***supervisorAgent*** sections. + - ***supervisor*** section is used when the user signs in to supervisor desktop with ***Supervisor*** role. + - ***supervisorAdmin*** section is used when the user signs in to supervisor desktop with ***Supervisor and Agent*** role. + +![Lab_4_WebexCC_Config_1](/assets/images/DC_Lab_4_Supervisor_WebexCC_1.png) + +- Go to ***Provisioning*** -> ***Desktop Layout*** and click on ***New Layout***. + +![Lab_4_WebexCC_Config_2](/assets/images/DC_Lab_4_Supervisor_WebexCC_2.png) + +- Provide ***Name***, press ***Upload*** button and select JSON layout file downloaded above. After the file is uploaded check and make sure the validation is completed successfully and save desktop layout. + +![Lab_4_WebexCC_Config_3](/assets/images/DC_Lab_4_Supervisor_WebexCC_3.png) + +- Go to ***Provisioning*** -> ***Teams*** and click on ***New Team***. + +![Lab_4_WebexCC_Config_4](/assets/images/DC_Lab_4_Supervisor_WebexCC_4.png) + +- Choose the proper ***Site*** from the drop-down list according to the lab guide, provide ***Name***, select ***Desktop Layout*** for the supervisor created at the previous step, and save the team. + +![Lab_4_WebexCC_Config_5](/assets/images/DC_Lab_4_Supervisor_WebexCC_5.png) + +- Go to ***Provisioning*** -> ***User Profiles***, find default ***Supervisor Profile***, click on ***...*** button next to it, then on ***Copy***. + +![Lab_4_WebexCC_Config_6](/assets/images/DC_Lab_4_Supervisor_WebexCC_6.png) + +- Provide the proper user profile name and go to the ***Module Settings*** tab. + +![Lab_4_WebexCC_Config_7](/assets/images/DC_Lab_4_Supervisor_WebexCC_7.png) + +- Select ***Module Access*** as ***Specific***. Check and make sure ***Send Messages*** and ***Mid-Call Monitor*** capabilities are enabled. + +![Lab_4_WebexCC_Config_8](/assets/images/DC_Lab_4_Supervisor_WebexCC_8.png) + +- Scroll to the bottom of the page and save the supervisor profile. + +![Lab_4_WebexCC_Config_9](/assets/images/DC_Lab_4_Supervisor_WebexCC_9.png) + +- Go to **Provisioning*** -> ***Users***, find your supervisor user, click on ***...*** button next to it, then on ***Edit***. + +![Lab_4_WebexCC_Config_10](/assets/images/DC_Lab_4_Supervisor_WebexCC_10.png) + +- Set the following parameters and save changes: + +| **Parameter Name** | **Parameter Value** | +| -------------------------- | --------------------------------------------- | +| Contact Center Enabled | Yes | +| Primary Team | Select the supervisor team created above | +| Site | Select the proper site according the to lab guide | +| Teams | Add teams that the supervisor can use when signing in as an agent | +| Agent Profile | Select the default one - ***Agent-Profile*** | +| Multimedia Profile | Select the default one - ***Default_Multimedia_Profile*** | + +![Lab_4_WebexCC_Config_11](/assets/images/DC_Lab_4_Supervisor_WebexCC_11.png) + + +# Supervisor Experience + +In this section, you will act as a supervisor and perform activities. The Supervisor Desktop provides a holistic supervisor experience within a centralized interface. It enables supervisors to manage, monitor, assess, guide, and assist agents. It also enables administrators to customize the Supervisor Desktop with widgets to address specific Contact Center business needs + + +
    + +
    +
    + +#### **Pre-requisite** + +1. A supervisor user configured as described above +2. One agent logged in and in conversation with a customer so you can monitor the call. + +#### **Supervisor Log in** + +- Sign in to the **Supervisor Desktop**: https://desktop.wxcc-us1.cisco.com with your supervisor credentials. + +- In the next window, set your role as **supervisor** and your **own extension**. Please note that you can set your role either as **supervisor** or **agent and supervisor**. We will select this second option at the end of this lab. + + +![Lab_4_ESD](/assets/images/Lab4_ESD_11.png) + +- When you sign in to the **Supervisor Desktop**, the appearance depends on how the Webex Contact Center administrator has configured the desktop layout. The **Supervisor Desktop** display size must be greater than 500 x 500 pixels (width x height). You must set your web browser zoom to 100% for the best experience with the Supervisor Desktop. With this lab layout you get : + +1. **Home Page**: Displays a user-friendly interface that provides a consolidated view of key contact center metrics and filters. This is the default landing page in the Supervisor Desktop. The administrator can customize the Home Page in the layout JSON file. +2. **Task**: Displays all the tasks when you sign in to the Desktop in a dual role (supervisor and agent) or as a supervisor, interactions such as voice, chat, email, and social messaging conversations, along with monitoring. The icon displays a badge indicating the number of requests that you have not accepted across various channels. +3. **Team Performance**: Displays real-time information about an agent and a consolidated view of an agent’s performance as part of the team. You can also monitor and send 1:1 messages to an agent. + +> Note the **Supervisor Desktop** UI supports localization in 30 languages. The following are the supported languages: +> Bulgarian, Catalan, Chinese (China), Chinese (Taiwan), Croatian, Czech, Danish, Dutch, English (UK), English (US), Finnish, French, German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish, Portuguese (Brazil), Portuguese (Portugal), Romanian, Russian, Serbian, Slovak, Slovenian, Spanish, Swedish, Turkish, and Ukrainian. The Supervisor Desktop UI language is based on the language preference settings on your browser. For example, let us consider that you have selected the preferred language as French on the Google Chrome browser. When you launch the Supervisor Desktop in the Google Chrome browser, the Supervisor Desktop UI appears in Français (French). + +- **Home Page** : + +![Lab_4_ESD](/assets/images/Lab4_ESD_2.png) + +- click on the third menu option, and now you should see the **Team Performance Details** page where your agent's activities are displayed: status, call duration, team, etc. In the last column, you are presented with two options: **chat** or **monitor**. The monitoring option is obviously only enabled when an agent is in conversation with a customer otherwise the icon will be greyed. + +![Lab_4_ESD](/assets/images/Lab4_ESD_3.png) + +- The columns displayed are the following + +| **Column** | **Description** | +| ---------------------- | ------------------------------------------ | +| Agent Name | Displays name and avatar (Webex image) of the agent.| +| Agent State | The work status while using the Supervisor Desktop. The agent availability state includes Available, Idle codes, or RONA. | +| Agent State Duration | The time that the agent has been in the current state. The state timer format is hh:mm:ss (for example, 01:10:25).| +| Phone Number | Dial number or extension of the agent signed in.| +| Site | Name of the site with which the agent is associated.| +| Team | Name of the team with which the agent is associated.| +| Channels | The mode of communication through which an agent can communicate. For example, voice calls.| +| Contact Queue | Name of the queue from where the agent receives the incoming call.| +| Contact Status | The status of the agent in an active call. Example: Connected, Consulting, Conference, or Wrap up| +| Time in Contact Status | The time spent by an agent in an active call. For example, the time an agent is in a conference call.| +| Total Contact Duration | Total duration of the contact from when it was first connected (including any other state like consult or conference in the same contact). The time elapsed since the agent accepted the request. The connected timer format is hh:mm:ss (for example, 01:10:25).| +| Sign In Time | The time an agent has signed in to the Supervisor Desktop. The date and time format is dynamic and displays according to location.| +| Action | You can perform the following actions:• Review and Monitor - Based on the privilege provided by Administrator as part of user profile, you can review and monitor an ongoing agent call silently. • Send1:1 message to Agent – Based on the privilege provided by Administrator as part of a user profile, you can send a 1:1 message to an agent.| + +- you can customize this view to show/hide columns or group information at your convenience. + +![Lab_4_ESD](/assets/images/Lab4_ESD_32.png) + + +#### **Chat with your agents** + +Collaboration between agents and supervisors can help your Contact Center to be more effective and efficient for your customers and this is why we have enabled Webex messaging features in both Agent and Supervisor desktops. + +- Click on the **Send Message** button + +![Lab_4_ESD](/assets/images/Lab4_ESD_4_chat.png) + +- Fill the chat window with a message to send to your agent + +![Lab_4_ESD](/assets/images/Lab4_ESD_5_chat.png) + +- On the agent side, observe the message notification received + +![Lab_4_ESD](/assets/images/Lab4_ESD_6_chat.png) + +- If, as an agent, you want to answer to the supervisor, your will need to click on the **Webex logo** to open the Webex app embedded in the **Agent Desktop**. You can then reply to the supervisor directly. + +![Lab_4_ESD](/assets/images/Lab4_ESD_7_chat.png) + +- On the supervisor side, observe the message notification received + +![Lab_4_ESD](/assets/images/Lab4_ESD_8_chat.png) + + +#### **Monitor calls** + +- As a supervisor, the **Team Performance Details** page allows you to see all connected agents and decide to monitor calls by clicking on the **Review and Monitor** icon. + +![Lab_4_ESD](/assets/images/Lab4_ESD_9_monitor.png) + +- The following popup will be displayed. Click on **Start Monitoring**. Please note a supervisor can monitor other call types such as callbacks, outdial calls, outbound preview campaign calls. + +![Lab_4_ESD](/assets/images/Lab4_ESD_10_monitor.png) + +- In your **Supervisor Desktop**, an incoming popover window will be displayed and your softphone will ring as Webex Contact Center is now trying to reach you. You recognize the agent you want to monitor and other call variables are displayed. The Flow configuration defines variables to display on this popover (max 6). Accept the call on your supervisor softphone. + +![Lab_4_ESD](/assets/images/Lab4_ESD_11_monitor.png) + +- As a supervisor, the call you are now monitoring is displayed in your desktop with agent and customer details of which the call variables so you are aware of the context of the call. You can view previous communications with a customer across all channels (voice, email, chat, and social) in the **Contact History** pane. The pane displays details for the last 24 hours. + +![Lab_4_ESD](/assets/images/Lab4_ESD_12_monitor.png) + +- You can pause the monitoring and start is again if you will + +![Lab_4_ESD](/assets/images/Lab4_ESD_13_monitor.png) + +#### **Particular case when a supervisor is also an agent** + +- When you sign in to the Supervisor Desktop, you can - depending or your team assignment - choose either the supervisor role or supervisor AND agent role. + +![Lab_4_ESD](/assets/images/Lab4_ESD_14_monitor.png) + +- In this case, the supervisor experience is a bit different as your agent status appears in the header section of the Desktop. + +![Lab_4_ESD](/assets/images/Lab4_ESD_15_monitor.png) + +- If, as a supervisor, you choose to monitor a call, your status is set to **Engaged** and you cannot take other calls as an agent. + +![Lab_4_ESD](/assets/images/Lab4_ESD_16_monitor.png) + + + + + +--- + + +

    Congratulations, you have completed this lab! You can continue with the next one.

    + +

    diff --git a/_pages/about.md b/_pages/about.md deleted file mode 100644 index 1c621d403e..0000000000 --- a/_pages/about.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: About -author: Tao He -date: 2022-02-04 -category: Jekyll -layout: post ---- - -This is an about page. diff --git a/_pages/contact.md b/_pages/contact.md deleted file mode 100644 index a67b8efa73..0000000000 --- a/_pages/contact.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Contact -author: Tao He -date: 2022-02-05 -category: Jekyll -layout: post ---- - -This is an contact page. diff --git a/_pages/design/draft.md b/_pages/design/draft.md deleted file mode 100644 index 141e942a35..0000000000 --- a/_pages/design/draft.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Design Draft -author: Tao He -date: 2022-02-06 -category: Jekyll -layout: post ---- - -This is an draft page. diff --git a/_posts/2019-04-27-why.md b/_posts/2019-04-27-why.md deleted file mode 100644 index 81af6b7b61..0000000000 --- a/_posts/2019-04-27-why.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Why Jekyll with GitBook -author: Tao He -date: 2019-04-27 -category: Jekyll -layout: post ---- - -GitBook is an amazing frontend style to present and organize contents (such as book chapters -and blogs) on Web. The typical to deploy GitBook at [Github Pages][1] -is building HTML files locally and then push to Github repository, usually to the `gh-pages` -branch. However, it's quite annoying to repeat such workload and make it hard for people do -version control via git for when there are generated HTML files to be staged in and out. - -This theme takes style definition out of generated GitBook site and provided the template -for Jekyll to rendering markdown documents to HTML, thus the whole site can be deployed -to [Github Pages][1] without generating and uploading HTML bundle every time when there are -changes to the original repository. - -[1]: https://pages.github.com \ No newline at end of file diff --git a/_posts/2019-04-28-howto.md b/_posts/2019-04-28-howto.md deleted file mode 100644 index d1e9750fb1..0000000000 --- a/_posts/2019-04-28-howto.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: How to Get Started -author: Tao He -date: 2019-04-28 -category: Jekyll -layout: post ---- - -The jekyll-gitbook theme can be used just as other [Jekyll themes][3] and -support [remote theme][2] on [Github Pages][1], see [the official guide][4] -as well. - -You can introduce this jekyll theme into your own site by either - -- [Fork][5] this repository and add your markdown posts to the `_posts` folder, then - push to your own Github repository. -- Use as a remote theme in your [`_config.yml`][6](just like what we do for this - site itself), - -```yaml -# Configurations -title: Jekyll Gitbook -longtitle: Jekyll Gitbook - -remote_theme: sighingnow/jekyll-gitbook -``` - -> ##### TIP -> -> No need to push generated HTML bundle. -{: .block-tip } - -[1]: https://pages.github.com -[2]: https://github.com/sighingnow/jekyll-gitbook/fork -[3]: https://pages.github.com/themes -[4]: https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/adding-a-theme-to-your-github-pages-site-using-jekyll -[5]: https://github.com/sighingnow/jekyll-gitbook/fork -[6]: https://github.com/sighingnow/jekyll-gitbook/blob/master/_config.yml diff --git a/_posts/2019-04-29-license.md b/_posts/2019-04-29-license.md deleted file mode 100644 index 793e52a6ee..0000000000 --- a/_posts/2019-04-29-license.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: License -author: Tao He -date: 2019-04-29 -category: Jekyll -layout: post ---- - -This work is open sourced under the Apache License, Version 2.0, using the -same license as the original [GitBook](https://github.com/GitbookIO/gitbook) repository. - -Copyright 2019 Tao He. diff --git a/_posts/2021-08-10-toc.md b/_posts/2021-08-10-toc.md deleted file mode 100644 index 31e072ef10..0000000000 --- a/_posts/2021-08-10-toc.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -title: How to Generate TOC -author: Tao He -date: 2021-08-10 -category: Jekyll -layout: post ---- - -The jekyll-gitbook theme leverages [jekyll-toc][1] to generate the *Contents* for the page. -The TOC feature is not enabled by default. To use the TOC feature, modify the TOC -configuration in `_config.yml`: - -```yaml -toc: - enabled: true -``` - -Why this repo -------------- - -long contents ..... - -1. a -2. b -3. c -4. d - -Why this repo -------------- - -long contents ..... - -+ 1 -+ 2 -+ 3 -+ 4 - -Why this repo -------------- - -long contents ..... - -1. e -2. f -3. g -4. h - -Why this repo -------------- - -+ 5 -+ 6 -+ 7 -+ 8 - -Why this repo -------------- - -long contents ..... - -1. a -2. b -3. c -4. d - -Why this repo -------------- - -long contents ..... - -+ 1 -+ 2 -+ 3 -+ 4 - -Why this repo -------------- - -long contents ..... - -1. e -2. f -3. g -4. h - -Why this repo -------------- - -+ 5 -+ 6 -+ 7 -+ 8 - -Why this repo -------------- - -long contents ..... - -1. a -2. b -3. c -4. d - -Why this repo -------------- - -long contents ..... - -+ 1 -+ 2 -+ 3 -+ 4 - -Why this repo -------------- - -long contents ..... - -1. e -2. f -3. g -4. h - -Why this repo -------------- - -+ 5 -+ 6 -+ 7 -+ 8 - -Why this repo -------------- - -long contents ..... - -1. a -2. b -3. c -4. d - -Why this repo -------------- - -long contents ..... - -+ 1 -+ 2 -+ 3 -+ 4 - -Why this repo -------------- - -long contents ..... - -1. e -2. f -3. g -4. h - -Why this repo -------------- - -+ 5 -+ 6 -+ 7 -+ 8 - -[1]: https://github.com/allejo/jekyll-toc diff --git a/_posts/2022-05-24-page_cover.md b/_posts/2022-05-24-page_cover.md deleted file mode 100644 index 44a57e2fbe..0000000000 --- a/_posts/2022-05-24-page_cover.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Page with cover image -author: Tao He -date: 2022-05-24 -category: Jekyll -layout: post -cover: https://sighingnow.github.io/jekyll-gitbook/assets/dinosaur.gif ---- - -The jekyll-gitbook theme supports adding a cover image to a specific page by adding -a `cover` field to the page metadata: - -```diff - --- - title: Page with cover image - author: Tao He - date: 2022-05-24 - category: Jekyll - layout: post -+ cover: /assets/jekyll-gitbook/dinosaur.gif - --- -``` diff --git a/_posts/2022-06-26-wide_tables.md b/_posts/2022-06-26-wide_tables.md deleted file mode 100644 index 9693b161ea..0000000000 --- a/_posts/2022-06-26-wide_tables.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Wide tables -author: Tao He -date: 2022-06-26 -category: Jekyll -layout: post ---- - -A wide tables needs to be wrapped into a `div` with class `table-wrapper` -to make sure it displayed as expected on mobile devices. For example, - -```markdown -
    - -|title1|title2|title3|title4|title5|title6|title7|title8| -|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| -|1|2|3|4|5|6|7|8| -|1|2|3|4|5|6|7|8| -|1|2|3|4|5|6|7|8| -|1|2|3|4|5|6|7|8| - -
    -``` - -Will be rendered as - -
    - -|title1|title2|title3|title4|title5|title6|title7|title8| -|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| -|1|2|3|4|5|6|7|8| -|1|2|3|4|5|6|7|8| -|1|2|3|4|5|6|7|8| -|1|2|3|4|5|6|7|8| - -
    diff --git a/_posts/2022-06-30-tips_warnings_dangers.md b/_posts/2022-06-30-tips_warnings_dangers.md deleted file mode 100644 index 42944a9260..0000000000 --- a/_posts/2022-06-30-tips_warnings_dangers.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Tips, Warnings, and Dangers -author: Tao He -date: 2022-06-30 -category: Jekyll -layout: post ---- - -The jekyll-theme supports tips, warnings, and dangers blocks and the style is referred -from [the discord.js website][1]. - -You could have the following [markdown attributes (supported by kramdown)][2]: - -### Tips - -Using a `{: .block-tip}` attribute: - -```markdown -> ##### TIP -> -> This guide is last tested with @napi-rs/canvas^0.1.20, so make sure you have -> this or a similar version after installation. -{: .block-tip } -``` - -> ##### TIP -> -> This guide is last tested with @napi-rs/canvas^0.1.20, so make sure you have -> this or a similar version after installation. -{: .block-tip } - -### Warnings - -Using a `{: .block-warning}` attribute: - -```markdown -> ##### WARNING -> -> Be sure that you're familiar with things like async/await and object destructuring -> before continuing, as we'll be making use of features like these. -{: .block-warning } -``` - -> ##### WARNING -> -> Be sure that you're familiar with things like async/await and object destructuring -> before continuing, as we'll be making use of features like these. -{: .block-warning } - -### Dangers - -Using a `{: .block-danger}` attribute: - -```markdown -> ##### DANGER -> -> You cannot delete an ephemeral message. -{: .block-danger } -``` - -> ##### DANGER -> -> You cannot delete an ephemeral message. -{: .block-danger } - -[1]: https://discordjs.guide/popular-topics/canvas.html#setting-up-napi-rs-canvas -[2]: https://kramdown.gettalong.org/quickref.html#block-attributes diff --git a/assets/2023-12-23_22h29_20.png b/assets/2023-12-23_22h29_20.png new file mode 100644 index 0000000000..bfdf9cbc76 Binary files /dev/null and b/assets/2023-12-23_22h29_20.png differ diff --git a/assets/2023-12-23_22h30_08 (1).png b/assets/2023-12-23_22h30_08 (1).png new file mode 100644 index 0000000000..2b8f96e90a Binary files /dev/null and b/assets/2023-12-23_22h30_08 (1).png differ diff --git a/assets/2023-12-23_22h30_56.png b/assets/2023-12-23_22h30_56.png new file mode 100644 index 0000000000..734367b80f Binary files /dev/null and b/assets/2023-12-23_22h30_56.png differ diff --git a/assets/2023-12-23_22h31_32.png b/assets/2023-12-23_22h31_32.png new file mode 100644 index 0000000000..7b4563ee66 Binary files /dev/null and b/assets/2023-12-23_22h31_32.png differ diff --git a/assets/2023-12-23_22h32_10.png b/assets/2023-12-23_22h32_10.png new file mode 100644 index 0000000000..70ebb4dbb9 Binary files /dev/null and b/assets/2023-12-23_22h32_10.png differ diff --git a/assets/Acqueon_Desktop_Layout.json b/assets/Acqueon_Desktop_Layout.json new file mode 100644 index 0000000000..cc25438ee6 --- /dev/null +++ b/assets/Acqueon_Desktop_Layout.json @@ -0,0 +1,154 @@ +{ + "version": "0.0.2", + "appTitle": "Contact Center Desktop", + "logo": "", + "dragDropEnabled": false, + "notificationTimer": 8, + "maximumNotificationCount": 3, + "area": { + "header": { + "id": "dw-header", + "widgets": { + "acqueon-component": { + "comp": "agentx-preview-campaign", + "properties": { + "isCampaignManagementEnabled": "$STORE.agent.isCampaignManagementEnabled", + "agentDbId": "$STORE.agent.agentDbId", + "lcmUrl": "$STORE.agent.lcmUrl", + "isCallInProgress": "$STORE.agentContact.isActiveCall", + "outdialEntryPointId": "$STORE.agent.outDialEp", + "teamId": "$STORE.agent.teamId", + "campaignManagerAdditionalInfo": "$STORE.agent.campaignManagerAdditionalInfo" + } + } + }, + "layout": { + "areas": [["acqueon-component"]], + "size": { "cols": [1], "rows": [1] } + } + }, + "headless": { + "id": "dw-headless", + "widgets": { + "comp1": { "comp": "div" } + }, + "layout": { + "areas": [["comp1"]], + "size": { "cols": [1], "rows": [1] } + } + }, + "panel": { + "comp": "md-tabs", + "attributes": { "class": "widget-tabs" }, + "children": [ + { + "comp": "md-tab", + "attributes": { "slot": "tab", "class": "widget-pane-tab" }, + "children": [{ "comp": "#IVR_TRANSCRIPT_TAB" }], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [{ "comp": "#IVR_TRANSCRIPT" }], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab", + "attributes": { "slot": "tab", "class": "widget-pane-tab" }, + "children": [{ "comp": "#CUSTOMER_EXPERIENCE_JOURNEY_TAB" }], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [{ "comp": "#CUSTOMER_EXPERIENCE_JOURNEY" }], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab", + "attributes": { "slot": "tab", "class": "widget-pane-tab" }, + "children": [{ "comp": "#CONTACT_HISTORY_TAB" }] + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [{ "comp": "#CONTACT_HISTORY" }] + }, + { + "comp": "md-tab", + "attributes": { "slot": "tab", "class": "widget-pane-tab" }, + "children": [{ "comp": "#SCREEN_POP_TAB" }], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [{ "comp": "#SCREEN_POP" }], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab", + "attributes": { "slot": "tab", "class": "widget-pane-tab" }, + "children": [ + { "comp": "md-icon", "attributes": { "name": "icon-note_16" } }, + { "comp": "span", "textContent": "Call Guide" } + ], + "visibility": "CALL_GUIDE" + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [ + { + "comp": "agentx-call-guide", + "wrapper": { "title": "Call Guide", "maximizeAreaName": "app-maximize-area" }, + "properties": { + "lcmKey": "$STORE.agentContact.getCallGuideProps.LCMKey", + "agentDbId": "$STORE.agent.agentDbId", + "lcmUrl": "$STORE.agent.lcmUrl", + "campaignManagerAdditionalInfo": "$STORE.agent.campaignManagerAdditionalInfo" + } + } + ], + "visibility": "CALL_GUIDE" + } + ] + }, + "navigation": [ + { + "nav": { + "label": "WebEx Experience Manager Metrics", + "icon": "/app/images/wxm.bcd45cc3.svg", + "iconType": "other", + "navigateTo": "wxm-metrics", + "align": "top" + }, + "page": { + "id": "wxm-metrics", + "widgets": { + "comp1": { + "comp": "agentx-wc-cloudcherry-widget", + "attributes": { + "metrics": true + }, + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "$STORE.app.wxmUserParams.spaceId", + "metricsId": "$STORE.app.wxmUserParams.metricId", + "teamId": "$STORE.agent.teamName" + } + } + }, + "layout": { + "areas": [["comp1"]], + "size": { + "cols": [1], + "rows": [1] + } + } + } + } + ] + } +} \ No newline at end of file diff --git a/assets/files/AnalyzerLab_Flow.json b/assets/files/AnalyzerLab_Flow.json new file mode 100644 index 0000000000..67ec114eef --- /dev/null +++ b/assets/files/AnalyzerLab_Flow.json @@ -0,0 +1 @@ +{"orgId":"8e87fd7c-3d94-4b44-8506-1ea9a778aece","version":1,"id":"63f00e7630072469e75b6dd2","name":"AnalyzerLab_Flow","description":"","comment":"","variables":[{"name":"callbacknumber_int","description":"","type":"INTEGER","value":"100","isCAD":false,"desktopLabel":"","isAgentEditable":false,"source":"","isReportable":false,"overwrite":false,"isSecure":false,"id":""},{"name":"queueID_String","description":"","type":"STRING","value":"null","isCAD":false,"desktopLabel":"","isAgentEditable":false,"source":"","isReportable":false,"overwrite":false,"isSecure":false,"id":""},{"name":"retryCount","description":"","type":"INTEGER","value":"1","isCAD":false,"desktopLabel":"","isAgentEditable":false,"source":"","isReportable":false,"overwrite":false,"isSecure":false,"id":""},{"name":"retryValue","description":"","type":"INTEGER","value":"1","isCAD":false,"desktopLabel":"","isAgentEditable":false,"source":"","isReportable":false,"overwrite":false,"isSecure":false,"id":""},{"name":"AgentEmail","description":"","type":"STRING","value":"null","isCAD":false,"desktopLabel":"","isAgentEditable":false,"source":"","isReportable":false,"overwrite":false,"isSecure":false,"id":""},{"name":"Global_AttendeeID","description":"","type":"STRING","value":"","isCAD":true,"desktopLabel":"Attendee ID","isAgentEditable":false,"source":"GLOBAL","isReportable":true,"overwrite":false,"isSecure":false,"id":"7d78630e-816a-441a-8005-72f911750622"},{"name":"Global_IsCallback","description":"","type":"BOOLEAN","value":"true","isCAD":true,"desktopLabel":"IsCallback","isAgentEditable":false,"source":"GLOBAL","isReportable":true,"overwrite":false,"isSecure":false,"id":"ae0206dd-3d49-437b-acda-b3a59c734998"},{"name":"Global_FeedbackSurveyOptIn","description":"System-defined variable that indicates if the caller opts in to complete a feedback survey","type":"STRING","value":"uninitialized","isCAD":true,"desktopLabel":"Post Call Survey Opt-in","isAgentEditable":true,"source":"GLOBAL","isReportable":true,"overwrite":false,"isSecure":false,"id":"dcefc9bc-7816-11ec-ad77-12ae06263809"},{"name":"Global_Language","description":"System-defined variable to store the language","type":"STRING","value":"en-US","isCAD":true,"desktopLabel":"Customer Language","isAgentEditable":false,"source":"GLOBAL","isReportable":true,"overwrite":false,"isSecure":false,"id":"dcf425b2-7816-11ec-ad77-12ae06263809"},{"name":"Global_VoiceName","description":"System-defined variable to store the voice name","type":"STRING","value":"Automatic","isCAD":false,"desktopLabel":"","isAgentEditable":false,"source":"GLOBAL","isReportable":true,"overwrite":false,"isSecure":false,"id":"dcf8342c-7816-11ec-ad77-12ae06263809"},{"name":"Global_IVRpath","description":"","type":"STRING","value":"","isCAD":true,"desktopLabel":"Global IVR Path","isAgentEditable":false,"source":"GLOBAL","isReportable":true,"overwrite":false,"isSecure":false,"id":"e15bb80b-2f22-49e6-b6ed-b15f05fad714"}],"process":{"activities":{"d8d5d15e-2fa8-4cf2-a0b7-1016bc4b1ca3":{"id":"d8d5d15e-2fa8-4cf2-a0b7-1016bc4b1ca3","name":"NewPhoneContact","group":"start","properties":{"name":"NewPhoneContact","activityName":"NewPhoneContact","activityId":"start","event":"NewPhoneContact","_renderRequestTimestamp":1676676724030,"flowType":{"eventSourceId":"5eff0e2eb10162499bc9f932","eventClassificationId":"5f10475cf021306e89e1692c","eventSpecificationId":"5f2d02144332507e39cc8a7f","eventSourceName":"WebexContactCenter","eventClassificationName":"VoiceInteractions","eventSpecificationName":"ContactStartWorkflow"}}},"c1f1c31d-839c-4ffd-b9e0-19ff8a8164ff":{"id":"c1f1c31d-839c-4ffd-b9e0-19ff8a8164ff","name":"WelcomeMessage","group":"action","properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"play-message","description":"","toggle":false,"activityId":"5f114466ef5cfc454fbbf131","connector":null,"name":"WelcomeMessage","toggleLanguage":null,"_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"765_WelcomeToWxCC.wav"}],"promptsTts":null}},"4dea9e24-108a-49ae-96a8-f6de4c9b5dd4":{"id":"4dea9e24-108a-49ae-96a8-f6de4c9b5dd4","name":"CollectAttendeeID","group":"action","properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"maxDigits":"3","activityName":"ivr-collectdigits","description":"","terminatorSymbol":"#","toggle":false,"terminatorSymbol_type":null,"interruptible":false,"activityId":"5f1144eaef5cfc454fbbf132","terminatorSymbol:type":null,"connector":null,"minDigits":1,"name":"CollectAttendeeID","toggleLanguage":null,"interDigitTimeout":"5","_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"enterAttendee.wav"}],"entryTimeout":"10","promptsTts":null}},"8536facc-4042-4bf9-9c8e-6bac9741afb1":{"id":"8536facc-4042-4bf9-9c8e-6bac9741afb1","name":"SetAttendeeID","group":"set-variable","properties":{"activityId":"set-variable","srcVariable":"Global_AttendeeID","name":"SetAttendeeID","srcVariableType":"STRING","activityName":"set-variable","setTo":"set-to-variable","expr":"{{CollectAttendeeID.DigitsEntered}}","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"dbfe1125-20e8-4484-8060-1df5517ba0fb":{"id":"dbfe1125-20e8-4484-8060-1df5517ba0fb","name":"ErrorAttendeeMessage","group":"action","properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"play-message","description":"","toggle":false,"activityId":"5f114466ef5cfc454fbbf131","connector":null,"name":"ErrorAttendeeMessage","toggleLanguage":null,"_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"ErrorAttendee.wav"}],"promptsTts":null}},"fa88e57c-49d9-4578-974f-4e53fb085e5c":{"id":"fa88e57c-49d9-4578-974f-4e53fb085e5c","name":"QueueContact_s2i","group":"action","properties":{"fallbackQueue":null,"queueRadioGroup":"staticQueue","destination":"AXmQtfndzemenKet3Um8","activityName":"queue-contact","description":"","destination:type":"LONGEST_AVAILABLE_AGENT","toggle":false,"priority":null,"agentAvailabilityRadioGroup":null,"priorityRadioGroup":null,"skills":null,"activityId":"5f114550ef5cfc454fbbf133","destination_type":"LONGEST_AVAILABLE_AGENT","priorityVariable":null,"destinationVariable":null,"name":"QueueContact_s2i","toggleAgentAvailability":false,"agentAvailabilityVariable":null,"_renderRequestTimestamp":1676676724030}},"9184a936-86f1-49b4-80ab-f8e4e809c410":{"id":"9184a936-86f1-49b4-80ab-f8e4e809c410","name":"SetVariable_1vz","group":"set-variable","properties":{"activityId":"set-variable","srcVariable":"queueID_String","name":"SetVariable_1vz","srcVariableType":"STRING","activityName":"set-variable","setTo":"set-to-variable","expr":"{{queueID_String}}","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"f8406dae-479f-438d-a046-eb04c608e63f":{"id":"f8406dae-479f-438d-a046-eb04c608e63f","name":"HoldMusic","group":"action","properties":{"duration":null,"activityId":"5faa2ad13505f538acc86afc","prompt:type":null,"name":"HoldMusic","activityName":"play-music","description":"","prompt_type":null,"skip":0,"_renderRequestTimestamp":1676676724030,"prompt":"defaultmusic_on_hold.wav","promptDynamic":null,"audioRadioGroup":"staticAudio"}},"b984576b-7253-4134-9af3-a2f3f855459c":{"id":"b984576b-7253-4134-9af3-a2f3f855459c","name":"Menu_k6m","group":"enum-gateway","properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"ivr-menu","description":"","toggle":false,"interruptible":false,"activityId":"5f1145ceef5cfc454fbbf134","menuLinks":["1","2"],"connector":null,"name":"Menu_k6m","toggleLanguage":null,"_renderRequestTimestamp":1676676724030,"menuLinks_input":["1","2"],"prompts":[{"type":"audioFile","value":"1Callback2Preferred.wav"}],"entryTimeout":3,"menuLinks:input":["1","2"],"promptsTts":null}},"fb7dd02e-0f7c-4db4-8729-5c4dbab81aeb":{"id":"fb7dd02e-0f7c-4db4-8729-5c4dbab81aeb","name":"DisconnectContact_wg8","group":"terminating-action","properties":{"name":"DisconnectContact_wg8","activityName":"disconnect-contact","activityId":"5faa898c8bf5b65b82f0706b","_renderRequestTimestamp":1676676724030}},"1a0c3c99-afb1-4b76-963c-83a5242e53c4":{"id":"1a0c3c99-afb1-4b76-963c-83a5242e53c4","name":"SetIsCallback","group":"set-variable","properties":{"activityId":"set-variable","srcVariable":"Global_IsCallback","name":"SetIsCallback","srcVariableType":"BOOLEAN","activityName":"set-variable","setTo":"set-to-literal","expr":"True","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"6ea4f155-16af-41b0-b862-85b1442d79b5":{"id":"6ea4f155-16af-41b0-b862-85b1442d79b5","name":"SetAgentEmail","group":"set-variable","properties":{"activityId":"set-variable","srcVariable":"AgentEmail","name":"SetAgentEmail","srcVariableType":"STRING","activityName":"set-variable","setTo":"set-to-literal","expr":"lab_admin{{Global_AttendeeID}}@email.carehybrid.com","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"b1fce4bb-ce05-4ffa-8e86-c4b05d6d99d6":{"id":"b1fce4bb-ce05-4ffa-8e86-c4b05d6d99d6","name":"SetIVRPath","group":"set-variable","properties":{"activityId":"set-variable","srcVariable":"Global_IVRpath","name":"SetIVRPath","srcVariableType":"STRING","activityName":"set-variable","setTo":"set-to-literal","expr":"Preferred Agent","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"0a40d080-163f-4a5c-a0dc-d12eaac03212":{"id":"0a40d080-163f-4a5c-a0dc-d12eaac03212","name":"QueueToAgent_lqr","group":"action","properties":{"recoveryQueue:type":"LONGEST_AVAILABLE_AGENT","reportingQueue":"AXmQtfndzemenKet3Um8","activityName":"queue-to-agent","description":"","priority":null,"priorityRadioGroup":null,"reportingQueue:type":"LONGEST_AVAILABLE_AGENT","destinationLookupType":"agentEmail","activityId":"628d7efd4ba3176df6ce0088","reportingQueue_type":"LONGEST_AVAILABLE_AGENT","priorityToggle":false,"destinationLookupType:type":null,"priorityVariable":null,"destinationVariable":"{{AgentEmail}}","name":"QueueToAgent_lqr","destinationLookupType_type":null,"recoveryQueue_type":"LONGEST_AVAILABLE_AGENT","recoveryQueue":"AXmQtfndzemenKet3Um8","_renderRequestTimestamp":1676676724030,"parkContactToggle":true}},"a73560a1-4809-42d5-a0c3-cda47eb85d8c":{"id":"a73560a1-4809-42d5-a0c3-cda47eb85d8c","name":"SetCallbackNumber","group":"set-variable","properties":{"activityId":"set-variable","srcVariable":"callbacknumber_int","name":"SetCallbackNumber","srcVariableType":"INTEGER","activityName":"set-variable","setTo":"set-to-literal","expr":"{{NewPhoneContact.ANI|slice(1)}}","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"f0fe2951-de2c-4a3f-aa14-c9898505b495":{"id":"f0fe2951-de2c-4a3f-aa14-c9898505b495","name":"Callback","group":"action","properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"play-message","description":"","toggle":false,"activityId":"5f114466ef5cfc454fbbf131","connector":null,"name":"Callback","toggleLanguage":null,"_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"CallbackRequest.wav"}],"promptsTts":null}},"db978ed6-2a51-4bf2-b196-ad577431424b":{"id":"db978ed6-2a51-4bf2-b196-ad577431424b","name":"CallbackRequest","group":"action","properties":{"callbackAni:radioName":"staticAni","callbackAni_radioName":"staticAni","activityId":"5f367a285d76a50d1e8fb4d2","callbackQueue_radioName":"variableQueue","callbackAni":"+14402308010","name":"CallbackRequest","activityName":"callback","description":"","callbackDn":"{{NewPhoneContact.ani}}","callbackQueue:radioName":"variableQueue","_renderRequestTimestamp":1676676724030,"callbackQueue":"{{queueID_String}}"}}},"links":[{"id":"c5f8d487-2533-475f-a888-b647cde9132b","sourceActivityId":"d8d5d15e-2fa8-4cf2-a0b7-1016bc4b1ca3","targetActivityId":"c1f1c31d-839c-4ffd-b9e0-19ff8a8164ff","conditionExpr":"out","properties":{"value":"out"}},{"id":"ee17891c-c7c5-40dd-aadd-ca9a20ea1e90","sourceActivityId":"c1f1c31d-839c-4ffd-b9e0-19ff8a8164ff","targetActivityId":"4dea9e24-108a-49ae-96a8-f6de4c9b5dd4","conditionExpr":"default","properties":{"value":"default"}},{"id":"5bfb95dd-8bbb-4b68-a415-5b04af173c4b","sourceActivityId":"4dea9e24-108a-49ae-96a8-f6de4c9b5dd4","targetActivityId":"8536facc-4042-4bf9-9c8e-6bac9741afb1","conditionExpr":"default","properties":{"value":"default"}},{"id":"80d33d67-0f41-4be8-ad63-51f4ba61fa7f","sourceActivityId":"4dea9e24-108a-49ae-96a8-f6de4c9b5dd4","targetActivityId":"dbfe1125-20e8-4484-8060-1df5517ba0fb","conditionExpr":"timeout","properties":{"value":"timeout"}},{"id":"785d42ef-1758-47b3-af80-d10c86dbfb84","sourceActivityId":"4dea9e24-108a-49ae-96a8-f6de4c9b5dd4","targetActivityId":"dbfe1125-20e8-4484-8060-1df5517ba0fb","conditionExpr":"invalid","properties":{"value":"invalid"}},{"id":"7344b681-77ea-4da0-b37e-4ffe272a6654","sourceActivityId":"dbfe1125-20e8-4484-8060-1df5517ba0fb","targetActivityId":"4dea9e24-108a-49ae-96a8-f6de4c9b5dd4","conditionExpr":"default","properties":{"value":"default"}},{"id":"0bdd21ef-3273-495a-9434-95b01900b4f8","sourceActivityId":"8536facc-4042-4bf9-9c8e-6bac9741afb1","targetActivityId":"fa88e57c-49d9-4578-974f-4e53fb085e5c","conditionExpr":"out","properties":{"value":"out"}},{"id":"4035f6e7-c905-42ab-a90e-f572f09cbdf0","sourceActivityId":"fa88e57c-49d9-4578-974f-4e53fb085e5c","targetActivityId":"9184a936-86f1-49b4-80ab-f8e4e809c410","conditionExpr":"default","properties":{"value":"default"}},{"id":"7fd8e26b-49f6-41de-9e8a-aa1480b43811","sourceActivityId":"9184a936-86f1-49b4-80ab-f8e4e809c410","targetActivityId":"f8406dae-479f-438d-a046-eb04c608e63f","conditionExpr":"out","properties":{"value":"out"}},{"id":"81626678-0e83-41e8-a554-70018e4542d1","sourceActivityId":"f8406dae-479f-438d-a046-eb04c608e63f","targetActivityId":"b984576b-7253-4134-9af3-a2f3f855459c","conditionExpr":"default","properties":{"value":"default"}},{"id":"4ae447e6-66c0-40a3-b44a-1a564d09eb09","sourceActivityId":"b984576b-7253-4134-9af3-a2f3f855459c","targetActivityId":"f8406dae-479f-438d-a046-eb04c608e63f","conditionExpr":"timeout","properties":{"value":"timeout"}},{"id":"cb52442c-f9a4-4f51-8071-48c377bf6636","sourceActivityId":"b984576b-7253-4134-9af3-a2f3f855459c","targetActivityId":"f8406dae-479f-438d-a046-eb04c608e63f","conditionExpr":"invalid","properties":{"value":"invalid"}},{"id":"10bc9040-d12f-4547-8889-559448b02ccb","sourceActivityId":"b984576b-7253-4134-9af3-a2f3f855459c","targetActivityId":"fb7dd02e-0f7c-4db4-8729-5c4dbab81aeb","conditionExpr":"error","properties":{"value":"error"}},{"id":"f05559c7-3ed2-410b-b8c9-bc6961ea736f","sourceActivityId":"b984576b-7253-4134-9af3-a2f3f855459c","targetActivityId":"1a0c3c99-afb1-4b76-963c-83a5242e53c4","conditionExpr":"1","properties":{"value":"1"}},{"id":"44fd78fc-59ad-423f-af1e-6740b53b980a","sourceActivityId":"b984576b-7253-4134-9af3-a2f3f855459c","targetActivityId":"6ea4f155-16af-41b0-b862-85b1442d79b5","conditionExpr":"2","properties":{"value":"2"}},{"id":"b8ae55cb-211a-4d5d-839b-435257357406","sourceActivityId":"6ea4f155-16af-41b0-b862-85b1442d79b5","targetActivityId":"b1fce4bb-ce05-4ffa-8e86-c4b05d6d99d6","conditionExpr":"out","properties":{"value":"out"}},{"id":"834fefa7-cec8-4c8b-9e34-b48b54d1a5a1","sourceActivityId":"b1fce4bb-ce05-4ffa-8e86-c4b05d6d99d6","targetActivityId":"0a40d080-163f-4a5c-a0dc-d12eaac03212","conditionExpr":"out","properties":{"value":"out"}},{"id":"6d33b492-58ad-4a81-baeb-f2395040726b","sourceActivityId":"0a40d080-163f-4a5c-a0dc-d12eaac03212","targetActivityId":"fb7dd02e-0f7c-4db4-8729-5c4dbab81aeb","conditionExpr":"error","properties":{"value":"error"}},{"id":"d16f3fc4-279a-4521-a21e-0ee168cbec5a","sourceActivityId":"0a40d080-163f-4a5c-a0dc-d12eaac03212","targetActivityId":"f8406dae-479f-438d-a046-eb04c608e63f","conditionExpr":"default","properties":{"value":"default"}},{"id":"9d755bae-f685-4dc1-bdc5-b7d8085b4830","sourceActivityId":"1a0c3c99-afb1-4b76-963c-83a5242e53c4","targetActivityId":"a73560a1-4809-42d5-a0c3-cda47eb85d8c","conditionExpr":"out","properties":{"value":"out"}},{"id":"3d22b9a1-f82c-409f-90cc-4e15b33c8c44","sourceActivityId":"a73560a1-4809-42d5-a0c3-cda47eb85d8c","targetActivityId":"a73560a1-4809-42d5-a0c3-cda47eb85d8c","conditionExpr":"error","properties":{"value":"error"}},{"id":"ec5858c1-ff7e-4eb5-89dc-b457ad720f39","sourceActivityId":"a73560a1-4809-42d5-a0c3-cda47eb85d8c","targetActivityId":"f0fe2951-de2c-4a3f-aa14-c9898505b495","conditionExpr":"out","properties":{"value":"out"}},{"id":"6ce4d70f-8660-46f3-9b74-662b4ac1e18a","sourceActivityId":"f0fe2951-de2c-4a3f-aa14-c9898505b495","targetActivityId":"db978ed6-2a51-4bf2-b196-ad577431424b","conditionExpr":"default","properties":{"value":"default"}},{"id":"29f46a2d-cc08-429b-afef-25b089177177","sourceActivityId":"db978ed6-2a51-4bf2-b196-ad577431424b","targetActivityId":"fb7dd02e-0f7c-4db4-8729-5c4dbab81aeb","conditionExpr":"default","properties":{"value":"default"}}]},"diagram":{"widgets":{"d8d5d15e-2fa8-4cf2-a0b7-1016bc4b1ca3":{"id":"050dc36b-4e96-4170-885b-5bb00a689cd9","type":"start","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":100},"ports":[{"portId":"b0f442eb-1acf-4cf5-8fae-e51943bf865d","isSourcePort":false,"linkId":"93a3f855-72ab-4d8d-ac7e-cea4ca4b2fec","type":"arrow","links":["93a3f855-72ab-4d8d-ac7e-cea4ca4b2fec"],"properties":{"x":267,"name":"out","y":118,"label":"out","alignment":"right"}}],"properties":{"name":"NewPhoneContact","activityName":"NewPhoneContact","activityId":"start","event":"NewPhoneContact","_renderRequestTimestamp":1676676724030,"flowType":{"eventSourceId":"5eff0e2eb10162499bc9f932","eventClassificationId":"5f10475cf021306e89e1692c","eventSpecificationId":"5f2d02144332507e39cc8a7f","eventSourceName":"WebexContactCenter","eventClassificationName":"VoiceInteractions","eventSpecificationName":"ContactStartWorkflow"}}},"c1f1c31d-839c-4ffd-b9e0-19ff8a8164ff":{"id":"d08e1cba-1e1e-49c2-a389-c7dcb657f086","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":366,"y":113},"ports":[{"portId":"6d43ae35-0bba-48e5-93fd-6cf46aadda43","isSourcePort":true,"linkId":"93a3f855-72ab-4d8d-ac7e-cea4ca4b2fec","type":"arrow","links":["93a3f855-72ab-4d8d-ac7e-cea4ca4b2fec"],"properties":{"x":358,"name":"in","y":131,"label":"in","alignment":"left"}},{"portId":"3c8997a5-306e-4773-aee0-9a4a3e869b74","isSourcePort":false,"linkId":"7dd06a13-1597-42e0-a4e7-78fc9186db66","type":"arrow","links":["7dd06a13-1597-42e0-a4e7-78fc9186db66"],"properties":{"x":533,"name":"default","y":131,"label":"default","alignment":"right"}},{"portId":"c7f760f1-4c47-4722-a94f-072693930e89","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":533.5,"name":"error","y":224.2662353515625,"label":"error","alignment":"right"}}],"properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"play-message","description":"","toggle":false,"activityId":"5f114466ef5cfc454fbbf131","connector":null,"name":"WelcomeMessage","toggleLanguage":null,"_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"765_WelcomeToWxCC.wav"}],"promptsTts":null}},"c5f8d487-2533-475f-a888-b647cde9132b":{"id":"93a3f855-72ab-4d8d-ac7e-cea4ca4b2fec","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"5b7f08fa-1602-4771-b6b9-abed23d20360","type":"point","x":275,"y":126.5},{"id":"5358fefd-79d8-40c1-aa4c-f15d76ee161b","type":"point","x":295,"y":126.5},{"id":"08806696-87f5-41da-86a3-d2157d726e5b","type":"point","x":295,"y":93},{"id":"76290297-e7d1-4129-a546-caf010adc9a7","type":"point","x":346.5,"y":93},{"id":"f4bf0599-fc0c-46c8-ae4c-66d2b20bed3c","type":"point","x":346.5,"y":139.5},{"id":"1506a86e-37eb-41c2-958f-54928bc48cae","type":"point","x":366.5,"y":139.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"b0f442eb-1acf-4cf5-8fae-e51943bf865d","activeWidgetId":"050dc36b-4e96-4170-885b-5bb00a689cd9","point":{"x":275,"y":126}},"targetPort":{"id":"6d43ae35-0bba-48e5-93fd-6cf46aadda43","activeWidgetId":"d08e1cba-1e1e-49c2-a389-c7dcb657f086","point":{"x":366,"y":139}}},"4dea9e24-108a-49ae-96a8-f6de4c9b5dd4":{"id":"3ad45ab0-1975-4c77-aab9-b80e6991c431","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":597,"y":116},"ports":[{"portId":"b294c98a-ca36-43fd-bd3d-809111327297","isSourcePort":true,"linkId":"7dd06a13-1597-42e0-a4e7-78fc9186db66","type":"arrow","links":["7dd06a13-1597-42e0-a4e7-78fc9186db66","d936170c-35c5-4093-ae83-a6f50ec2a213"],"properties":{"x":589,"name":"in","y":134,"label":"in","alignment":"left"}},{"portId":"f9019aa3-b07d-4a3d-8828-43affd5980bc","isSourcePort":false,"linkId":"765bc2aa-e25c-4de4-bee8-c14e1c43cea9","type":"arrow","links":["765bc2aa-e25c-4de4-bee8-c14e1c43cea9"],"properties":{"x":764,"name":"default","y":134,"label":"default","alignment":"right"}},{"portId":"b621f931-b031-4598-ba61-6795d74ff662","isSourcePort":false,"linkId":"3096f1fa-5398-499a-807d-8bd25414f574","type":"arrow","links":["3096f1fa-5398-499a-807d-8bd25414f574"],"properties":{"x":764.5,"name":"timeout","y":227.2662353515625,"label":"timeout","alignment":"right"}},{"portId":"5d198536-10ca-48a8-a4a7-09dc96da9308","isSourcePort":false,"linkId":"72dd4a13-9a33-4b52-938b-6310e839448e","type":"arrow","links":["72dd4a13-9a33-4b52-938b-6310e839448e"],"properties":{"x":764.5,"name":"invalid","y":253.8365478515625,"label":"invalid","alignment":"right"}},{"portId":"1f366004-ab0a-4b17-b601-2367717c51a8","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":764.5,"name":"error","y":280.4068603515625,"label":"error","alignment":"right"}}],"properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"maxDigits":"3","activityName":"ivr-collectdigits","description":"","terminatorSymbol":"#","toggle":false,"interruptible":false,"activityId":"5f1144eaef5cfc454fbbf132","terminatorSymbol:type":null,"connector":null,"minDigits":1,"name":"CollectAttendeeID","toggleLanguage":null,"interDigitTimeout":"5","_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"enterAttendee.wav"}],"entryTimeout":"10","promptsTts":null}},"ee17891c-c7c5-40dd-aadd-ca9a20ea1e90":{"id":"7dd06a13-1597-42e0-a4e7-78fc9186db66","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"074c8af3-7f77-4e33-9a08-998e844f26a2","type":"point","x":541,"y":139.5},{"id":"1b7b1633-3692-4de3-93a3-438f3bf74cd7","type":"point","x":560,"y":139.5},{"id":"c2291589-4a20-43b8-b60e-5250ed917ae9","type":"point","x":560,"y":96},{"id":"f8e0c4a8-5695-4c36-83d6-d183ab3b72ff","type":"point","x":577.5,"y":96},{"id":"eea19fb4-9fbc-4dad-8687-e414103186c7","type":"point","x":577.5,"y":142.5},{"id":"1e12a06f-d3f3-468c-90bf-6f78b76777f4","type":"point","x":597.5,"y":142.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"3c8997a5-306e-4773-aee0-9a4a3e869b74","activeWidgetId":"d08e1cba-1e1e-49c2-a389-c7dcb657f086","point":{"x":541,"y":139}},"targetPort":{"id":"b294c98a-ca36-43fd-bd3d-809111327297","activeWidgetId":"3ad45ab0-1975-4c77-aab9-b80e6991c431","point":{"x":597,"y":142}}},"8536facc-4042-4bf9-9c8e-6bac9741afb1":{"id":"599571dd-06ed-41a4-b9f0-1adc436c474f","type":"set-variable","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":914,"y":-1},"ports":[{"portId":"ccc7b4c8-052b-4f77-b795-38aa738b42de","isSourcePort":true,"linkId":"765bc2aa-e25c-4de4-bee8-c14e1c43cea9","type":"arrow","links":["765bc2aa-e25c-4de4-bee8-c14e1c43cea9"],"properties":{"x":906,"name":"in","y":17,"label":"in","alignment":"left"}},{"portId":"b453d28e-6dbe-4a47-9dd9-e6707807bea8","isSourcePort":false,"linkId":"85c6322a-e830-4751-a110-60d136d06c49","type":"arrow","links":["85c6322a-e830-4751-a110-60d136d06c49"],"properties":{"x":1081,"name":"out","y":17,"label":"out","alignment":"right"}},{"portId":"f23c7db1-843b-47a6-8ed4-70fc736f0279","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":1081.5,"name":"error","y":110.2662353515625,"label":"error","alignment":"right"}}],"properties":{"activityId":"set-variable","srcVariable":"Global_AttendeeID","name":"SetAttendeeID","srcVariableType":"STRING","activityName":"set-variable","setTo":"set-to-variable","expr":"{{CollectAttendeeID.DigitsEntered}}","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"5bfb95dd-8bbb-4b68-a415-5b04af173c4b":{"id":"765bc2aa-e25c-4de4-bee8-c14e1c43cea9","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"ee58379c-efda-46d9-9c67-53920a66314f","type":"point","x":772,"y":142.5},{"id":"c74fcc1f-a2e7-4ef3-93e2-1dc05415ea59","type":"point","x":795,"y":142.5},{"id":"00d0a015-9403-4033-90cf-374441257a24","type":"point","x":795,"y":-21},{"id":"75926870-5859-4054-b501-743115fd7626","type":"point","x":894.5,"y":-21},{"id":"91ed66c9-2067-4ea2-80a7-c96e389247f9","type":"point","x":894.5,"y":25.5},{"id":"898e8237-d5d7-4a09-bb79-0acfaa3af450","type":"point","x":914.5,"y":25.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"f9019aa3-b07d-4a3d-8828-43affd5980bc","activeWidgetId":"3ad45ab0-1975-4c77-aab9-b80e6991c431","point":{"x":772,"y":142}},"targetPort":{"id":"ccc7b4c8-052b-4f77-b795-38aa738b42de","activeWidgetId":"599571dd-06ed-41a4-b9f0-1adc436c474f","point":{"x":914,"y":25}}},"dbfe1125-20e8-4484-8060-1df5517ba0fb":{"id":"7d9387a3-41a4-40f7-a70d-a6ebec554d0e","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":900,"y":229},"ports":[{"portId":"99f3aa29-573f-4790-a1a9-91ff377ab1d3","isSourcePort":true,"linkId":"3096f1fa-5398-499a-807d-8bd25414f574","type":"arrow","links":["3096f1fa-5398-499a-807d-8bd25414f574","72dd4a13-9a33-4b52-938b-6310e839448e"],"properties":{"x":892,"name":"in","y":247,"label":"in","alignment":"left"}},{"portId":"a336238a-0166-49a7-8248-c1294da77de4","isSourcePort":false,"linkId":"d936170c-35c5-4093-ae83-a6f50ec2a213","type":"arrow","links":["d936170c-35c5-4093-ae83-a6f50ec2a213"],"properties":{"x":1067,"name":"default","y":247,"label":"default","alignment":"right"}},{"portId":"d2cc9c8a-92e3-41c9-88db-40b4f0fdf25d","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":1067.5,"name":"error","y":340.2662353515625,"label":"error","alignment":"right"}}],"properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"play-message","description":"","toggle":false,"activityId":"5f114466ef5cfc454fbbf131","connector":null,"name":"ErrorAttendeeMessage","toggleLanguage":null,"_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"ErrorAttendee.wav"}],"promptsTts":null}},"80d33d67-0f41-4be8-ad63-51f4ba61fa7f":{"id":"3096f1fa-5398-499a-807d-8bd25414f574","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"e88e56da-60a2-42c5-9156-bc7eb7b1acc5","type":"point","x":773,"y":235.7662353515625},{"id":"6526ce1c-4f17-449d-b66c-b25142c69ec2","type":"point","x":795,"y":235.7662353515625},{"id":"6797bc42-249e-4939-a559-73da655e6787","type":"point","x":795,"y":209},{"id":"fefbaa15-6067-468c-b334-f29d4b2d4285","type":"point","x":880.5,"y":209},{"id":"59e4cb52-8424-4a27-8561-ea70799af14a","type":"point","x":880.5,"y":255.5},{"id":"80058c73-47d4-483e-9199-8025ed137432","type":"point","x":900.5,"y":255.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"b621f931-b031-4598-ba61-6795d74ff662","activeWidgetId":"3ad45ab0-1975-4c77-aab9-b80e6991c431","point":{"x":773,"y":235}},"targetPort":{"id":"99f3aa29-573f-4790-a1a9-91ff377ab1d3","activeWidgetId":"7d9387a3-41a4-40f7-a70d-a6ebec554d0e","point":{"x":900,"y":255}}},"785d42ef-1758-47b3-af80-d10c86dbfb84":{"id":"72dd4a13-9a33-4b52-938b-6310e839448e","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"3a23a5bc-79d5-4102-8b09-56cc341dccdc","type":"point","x":773,"y":262.3365478515625},{"id":"f8f797e2-8ae0-478d-9902-b5480f798fe2","type":"point","x":795,"y":262.3365478515625},{"id":"33b72aec-664c-41e1-8396-66a5b22627f4","type":"point","x":795,"y":209},{"id":"3aff9851-cc31-4297-b04a-29f1b5148e1e","type":"point","x":880.5,"y":209},{"id":"c70818df-3f96-4418-bf35-18756ed2c908","type":"point","x":880.5,"y":255.5},{"id":"ac6cb14c-1f61-4f53-af4a-8eef503fef73","type":"point","x":900.5,"y":255.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"5d198536-10ca-48a8-a4a7-09dc96da9308","activeWidgetId":"3ad45ab0-1975-4c77-aab9-b80e6991c431","point":{"x":773,"y":262}},"targetPort":{"id":"99f3aa29-573f-4790-a1a9-91ff377ab1d3","activeWidgetId":"7d9387a3-41a4-40f7-a70d-a6ebec554d0e","point":{"x":900,"y":255}}},"7344b681-77ea-4da0-b37e-4ffe272a6654":{"id":"d936170c-35c5-4093-ae83-a6f50ec2a213","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"a7cbe2cc-ef95-436d-a00d-c144de72c82b","type":"point","x":1075.5,"y":255.5},{"id":"0ec96698-4013-40cf-bb42-25f3db41f3d6","type":"point","x":1095,"y":255.5},{"id":"675c0880-0444-4a45-92d0-c4496e95acfc","type":"point","x":1095,"y":96},{"id":"f2435063-b225-4022-8eef-b4f16e99b5b9","type":"point","x":577.5,"y":96},{"id":"99e30b7a-5a70-48a9-8573-79da23047f43","type":"point","x":577.5,"y":142.5},{"id":"06774c5c-8405-46df-8ec1-cf117214aa03","type":"point","x":595,"y":142.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"a336238a-0166-49a7-8248-c1294da77de4","activeWidgetId":"7d9387a3-41a4-40f7-a70d-a6ebec554d0e","point":{"x":1075,"y":255}},"targetPort":{"id":"b294c98a-ca36-43fd-bd3d-809111327297","activeWidgetId":"3ad45ab0-1975-4c77-aab9-b80e6991c431","point":{"x":595,"y":142}}},"fa88e57c-49d9-4578-974f-4e53fb085e5c":{"id":"68d404bd-d665-46f8-ad44-975b471568b7","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":1173,"y":-1},"ports":[{"portId":"7f81e900-f0c3-4af4-87f7-130e2842017c","isSourcePort":true,"linkId":"85c6322a-e830-4751-a110-60d136d06c49","type":"arrow","links":["85c6322a-e830-4751-a110-60d136d06c49"],"properties":{"x":1165,"name":"in","y":16.666666666666668,"label":"in","alignment":"left"}},{"portId":"37af8986-e462-4c21-92f8-7720f2fd2ef2","isSourcePort":false,"linkId":"22057696-92c0-421c-bb90-e2e91c4eca34","type":"arrow","links":["22057696-92c0-421c-bb90-e2e91c4eca34"],"properties":{"x":1340,"name":"default","y":16.666666666666668,"label":"default","alignment":"right"}},{"portId":"0282a34a-8e73-4eaf-ba04-822d88536ced","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":1340.5,"name":"failure","y":109.93290201822917,"label":"failure","alignment":"right"}}],"properties":{"fallbackQueue":null,"queueRadioGroup":"staticQueue","destination":"AXmQtfndzemenKet3Um8","activityName":"queue-contact","description":"","destination:type":"LONGEST_AVAILABLE_AGENT","toggle":false,"priority":null,"agentAvailabilityRadioGroup":null,"priorityRadioGroup":null,"skills":null,"activityId":"5f114550ef5cfc454fbbf133","priorityVariable":null,"destinationVariable":null,"name":"QueueContact_s2i","toggleAgentAvailability":false,"agentAvailabilityVariable":null,"_renderRequestTimestamp":1676676724030}},"0bdd21ef-3273-495a-9434-95b01900b4f8":{"id":"85c6322a-e830-4751-a110-60d136d06c49","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"29e9460d-e8e8-408e-b350-2aebc9d94aca","type":"point","x":1089,"y":25.5},{"id":"53f85afc-6af8-44ee-8772-0d1ce1a96eb6","type":"point","x":1110,"y":25.5},{"id":"de76cdaf-ed09-47e9-a2c7-2b56040f6066","type":"point","x":1110,"y":-21.333333333333332},{"id":"dbd29499-1380-4687-8077-978208d40b45","type":"point","x":1153.5,"y":-21.333333333333332},{"id":"26ec870b-4e1f-4036-afd9-78af6600d2e2","type":"point","x":1153.5,"y":25.166666666666668},{"id":"7620adb6-6fb7-4e5c-a8f8-f1200c114e2e","type":"point","x":1170,"y":25.166666666666668}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"b453d28e-6dbe-4a47-9dd9-e6707807bea8","activeWidgetId":"599571dd-06ed-41a4-b9f0-1adc436c474f","point":{"x":1089,"y":25}},"targetPort":{"id":"7f81e900-f0c3-4af4-87f7-130e2842017c","activeWidgetId":"68d404bd-d665-46f8-ad44-975b471568b7","point":{"x":1170,"y":25}}},"9184a936-86f1-49b4-80ab-f8e4e809c410":{"id":"e707cc20-a42c-495f-b9d2-f6d004c25b8a","type":"set-variable","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":1423,"y":-2},"ports":[{"portId":"b62eca9a-d79f-4688-bb44-b7e049d0482e","isSourcePort":true,"linkId":"22057696-92c0-421c-bb90-e2e91c4eca34","type":"arrow","links":["22057696-92c0-421c-bb90-e2e91c4eca34"],"properties":{"x":1415,"name":"in","y":16,"label":"in","alignment":"left"}},{"portId":"2fdc12ce-5573-40a2-a813-a3c2fe966038","isSourcePort":false,"linkId":"a595077d-6e6c-4bc6-a1d6-93427f272f4f","type":"arrow","links":["a595077d-6e6c-4bc6-a1d6-93427f272f4f"],"properties":{"x":1590,"name":"out","y":16,"label":"out","alignment":"right"}},{"portId":"4fb7a385-9c7d-4c28-82c2-145bf4749517","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":1590.5,"name":"error","y":109.2662353515625,"label":"error","alignment":"right"}}],"properties":{"activityId":"set-variable","srcVariable":"queueID_String","name":"SetVariable_1vz","srcVariableType":"STRING","activityName":"set-variable","setTo":"set-to-variable","expr":"{{queueID_String}}","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"4035f6e7-c905-42ab-a90e-f572f09cbdf0":{"id":"22057696-92c0-421c-bb90-e2e91c4eca34","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"1d44df36-71d2-4d3a-b730-fba65e84207e","type":"point","x":1348,"y":25.166666666666668},{"id":"14cacc40-4f81-44cd-8f54-55dcdd3c5d28","type":"point","x":1370,"y":25.166666666666668},{"id":"3d4808be-c5bd-47ee-983b-cf42b1fff958","type":"point","x":1370,"y":-22},{"id":"8df717d0-7438-4d21-af76-57eff15253c7","type":"point","x":1403.5,"y":-22},{"id":"18ee2a5c-5baa-4757-99f9-1eba9130f297","type":"point","x":1403.5,"y":24.5},{"id":"46d7e8eb-ad4b-4b0d-b4d1-2693faf244f5","type":"point","x":1420,"y":24.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"37af8986-e462-4c21-92f8-7720f2fd2ef2","activeWidgetId":"68d404bd-d665-46f8-ad44-975b471568b7","point":{"x":1348,"y":25}},"targetPort":{"id":"b62eca9a-d79f-4688-bb44-b7e049d0482e","activeWidgetId":"e707cc20-a42c-495f-b9d2-f6d004c25b8a","point":{"x":1420,"y":24}}},"f8406dae-479f-438d-a046-eb04c608e63f":{"id":"351b1a91-ef0c-4948-a567-8a9cb1f6fcf8","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":1488,"y":200},"ports":[{"portId":"38fba055-0a82-4af5-b16c-0f825e782234","isSourcePort":true,"linkId":"a595077d-6e6c-4bc6-a1d6-93427f272f4f","type":"arrow","links":["a595077d-6e6c-4bc6-a1d6-93427f272f4f","e541f22b-603f-4edc-b0bf-85540689ccff","bc691daa-17f4-431b-948f-c4247213660a","fca9805e-ef82-4659-b2ec-ba09c7dc52f5"],"properties":{"x":1480,"name":"in","y":218,"label":"in","alignment":"left"}},{"portId":"a60281a7-b3c8-45b8-ab02-e770188b6ce8","isSourcePort":false,"linkId":"cb60486a-4ccd-4c1b-aaa0-5fde85577e89","type":"arrow","links":["cb60486a-4ccd-4c1b-aaa0-5fde85577e89"],"properties":{"x":1655,"name":"default","y":218,"label":"default","alignment":"right"}},{"portId":"f488e71f-7fdc-4901-9e88-927cc8b5ec83","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":1655.5,"name":"error","y":311.2662353515625,"label":"error","alignment":"right"}}],"properties":{"duration":null,"activityId":"5faa2ad13505f538acc86afc","prompt:type":null,"name":"HoldMusic","activityName":"play-music","description":"","skip":0,"_renderRequestTimestamp":1676676724030,"prompt":"defaultmusic_on_hold.wav","promptDynamic":null,"audioRadioGroup":"staticAudio"}},"7fd8e26b-49f6-41de-9e8a-aa1480b43811":{"id":"a595077d-6e6c-4bc6-a1d6-93427f272f4f","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"08de701c-c2f8-4551-a470-42c981279163","type":"point","x":1598,"y":24.5},{"id":"0d4473fe-d8b1-4ef3-bac7-878f0778f08b","type":"point","x":1620,"y":24.5},{"id":"4ae2b637-71dd-4ccc-95f1-5a24c34f14cf","type":"point","x":1620,"y":180},{"id":"b2465019-62a3-4317-8557-323a76f90877","type":"point","x":1468.5,"y":180},{"id":"ee220638-42b0-4cf3-ab3e-2c73db7aefa1","type":"point","x":1468.5,"y":226.5},{"id":"96d742f2-f933-46c9-b1b6-798d56abcd49","type":"point","x":1488.5,"y":226.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"2fdc12ce-5573-40a2-a813-a3c2fe966038","activeWidgetId":"e707cc20-a42c-495f-b9d2-f6d004c25b8a","point":{"x":1598,"y":24}},"targetPort":{"id":"38fba055-0a82-4af5-b16c-0f825e782234","activeWidgetId":"351b1a91-ef0c-4948-a567-8a9cb1f6fcf8","point":{"x":1488,"y":226}}},"b984576b-7253-4134-9af3-a2f3f855459c":{"id":"3b7cd616-26c1-4f4c-aa42-a83372bff632","type":"enum-gateway","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":1750,"y":126},"ports":[{"portId":"732f9d98-6032-44b9-8689-470187a37651","isSourcePort":false,"linkId":"4e119b75-f46f-436b-b0fe-e341c04ba370","type":"arrow","links":["4e119b75-f46f-436b-b0fe-e341c04ba370"],"properties":{"x":1917.5,"name":"1","y":244.140625,"label":"1","alignment":"right"}},{"portId":"4a730f26-784a-4831-8caf-8c16fa57c43c","isSourcePort":false,"linkId":"26219a53-e47f-4aff-8f2e-38bbf749719a","type":"arrow","links":["26219a53-e47f-4aff-8f2e-38bbf749719a"],"properties":{"x":1917.5,"name":"2","y":277.5625,"label":"2","alignment":"right"}},{"portId":"0c9fbbb1-1186-4cdf-bab4-3813c1ddf17f","isSourcePort":true,"linkId":"cb60486a-4ccd-4c1b-aaa0-5fde85577e89","type":"arrow","links":["cb60486a-4ccd-4c1b-aaa0-5fde85577e89"],"properties":{"x":1742,"name":"in","y":140,"label":"in","alignment":"left"}},{"portId":"33c1e348-14ae-4ac8-a5d5-99be13706958","isSourcePort":false,"linkId":"e541f22b-603f-4edc-b0bf-85540689ccff","type":"arrow","links":["e541f22b-603f-4edc-b0bf-85540689ccff"],"properties":{"x":1917.5,"name":"timeout","y":366.2506103515625,"label":"timeout","alignment":"right"}},{"portId":"19d7ae28-fe11-44c0-9149-fdd8cdfaf4b8","isSourcePort":false,"linkId":"bc691daa-17f4-431b-948f-c4247213660a","type":"arrow","links":["bc691daa-17f4-431b-948f-c4247213660a"],"properties":{"x":1917.5,"name":"invalid","y":392.8209228515625,"label":"invalid","alignment":"right"}},{"portId":"11c611ea-d330-4090-926a-10638465bda6","isSourcePort":false,"linkId":"16fd2fe8-1c61-42b9-babf-f0abc9017a07","type":"arrow","links":["16fd2fe8-1c61-42b9-babf-f0abc9017a07"],"properties":{"x":1917.5,"name":"error","y":419.3912353515625,"label":"error","alignment":"right"}}],"properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"ivr-menu","description":"","toggle":false,"interruptible":false,"activityId":"5f1145ceef5cfc454fbbf134","menuLinks":["1","2"],"connector":null,"name":"Menu_k6m","toggleLanguage":null,"_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"1Callback2Preferred.wav"}],"entryTimeout":3,"menuLinks:input":["1","2"],"promptsTts":null}},"81626678-0e83-41e8-a554-70018e4542d1":{"id":"cb60486a-4ccd-4c1b-aaa0-5fde85577e89","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"e4ad7a56-583a-4bf5-8e34-73aefec5d6a4","type":"point","x":1663,"y":226.5},{"id":"d28d6e5d-4466-4dae-a1df-c08b2ba18153","type":"point","x":1685,"y":226.5},{"id":"f6ccc973-4fa9-48c3-a48e-9456668c83f6","type":"point","x":1685,"y":106},{"id":"3039522e-6a59-4ed7-818a-d1cd11f306e9","type":"point","x":1730.5,"y":106},{"id":"09e51199-3f4c-49b8-903a-792d49232842","type":"point","x":1730.5,"y":148.5},{"id":"745d8f47-595e-4263-80ae-bb9ce6a0d7bb","type":"point","x":1750.5,"y":148.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"a60281a7-b3c8-45b8-ab02-e770188b6ce8","activeWidgetId":"351b1a91-ef0c-4948-a567-8a9cb1f6fcf8","point":{"x":1663,"y":226}},"targetPort":{"id":"0c9fbbb1-1186-4cdf-bab4-3813c1ddf17f","activeWidgetId":"3b7cd616-26c1-4f4c-aa42-a83372bff632","point":{"x":1750,"y":148}}},"4ae447e6-66c0-40a3-b44a-1a564d09eb09":{"id":"e541f22b-603f-4edc-b0bf-85540689ccff","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"ce1884f6-2cf3-4002-97cc-ffac796db7cd","type":"point","x":1926,"y":374.7506103515625},{"id":"6f10695f-63e5-4703-9949-d9c69dc8514c","type":"point","x":1945,"y":374.7506103515625},{"id":"3c11c471-46f3-46d9-a0ff-8d79d6bb80e3","type":"point","x":1945,"y":180},{"id":"c4723b4e-cf2e-4260-8494-7b3b5b2bda6d","type":"point","x":1468.5,"y":180},{"id":"f8822fb1-f10a-4d30-afa9-62da59c20858","type":"point","x":1468.5,"y":226.5},{"id":"593481e7-1a8d-4e96-a9ea-c42c56141883","type":"point","x":1485,"y":226.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"33c1e348-14ae-4ac8-a5d5-99be13706958","activeWidgetId":"3b7cd616-26c1-4f4c-aa42-a83372bff632","point":{"x":1926,"y":374}},"targetPort":{"id":"38fba055-0a82-4af5-b16c-0f825e782234","activeWidgetId":"351b1a91-ef0c-4948-a567-8a9cb1f6fcf8","point":{"x":1485,"y":226}}},"cb52442c-f9a4-4f51-8071-48c377bf6636":{"id":"bc691daa-17f4-431b-948f-c4247213660a","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"a81d6681-ae47-4782-a1c3-f5b61da74d8e","type":"point","x":1926,"y":401.3209228515625},{"id":"b48f9ac4-aa1a-49b5-aeac-4bb6e1fe39ee","type":"point","x":1945,"y":401.3209228515625},{"id":"3d92ec33-747f-42dc-b9d8-518e6d835346","type":"point","x":1945,"y":180},{"id":"04ced458-f9e6-4985-9802-d611a330148d","type":"point","x":1468.5,"y":180},{"id":"7a2d2498-d507-4a55-baf2-d46dc783e7a3","type":"point","x":1468.5,"y":226.5},{"id":"5a54611f-571b-4d50-88ff-997964bc2b85","type":"point","x":1485,"y":226.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"19d7ae28-fe11-44c0-9149-fdd8cdfaf4b8","activeWidgetId":"3b7cd616-26c1-4f4c-aa42-a83372bff632","point":{"x":1926,"y":401}},"targetPort":{"id":"38fba055-0a82-4af5-b16c-0f825e782234","activeWidgetId":"351b1a91-ef0c-4948-a567-8a9cb1f6fcf8","point":{"x":1485,"y":226}}},"fb7dd02e-0f7c-4db4-8729-5c4dbab81aeb":{"id":"0421ee97-e72d-46f3-b52e-f88112fd9c8d","type":"terminating-action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":2860,"y":200},"ports":[{"portId":"15c1f196-32f3-465c-a3aa-ef87f6ef2726","isSourcePort":true,"linkId":"16fd2fe8-1c61-42b9-babf-f0abc9017a07","type":"arrow","links":["16fd2fe8-1c61-42b9-babf-f0abc9017a07","06e7f723-5e40-4959-b84d-a9dc2baee52f","1c51cf12-7ac1-4940-b60d-b9ae17ed861a"],"properties":{"x":2852,"name":"in","y":218,"label":"in","alignment":"left"}}],"properties":{"name":"DisconnectContact_wg8","activityName":"disconnect-contact","activityId":"5faa898c8bf5b65b82f0706b","_renderRequestTimestamp":1676676724030}},"10bc9040-d12f-4547-8889-559448b02ccb":{"id":"16fd2fe8-1c61-42b9-babf-f0abc9017a07","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"d3304d94-a880-477f-975e-0cf365aff5ac","type":"point","x":1926,"y":427.8912353515625},{"id":"777a34a4-7268-4175-b9de-b2141f196d00","type":"point","x":1945,"y":427.8912353515625},{"id":"ac39ac43-ad2b-4557-847f-63a73c3c24ab","type":"point","x":1945,"y":180},{"id":"875510ac-a5c8-44bc-a820-573d5173f5a2","type":"point","x":2840.5,"y":180},{"id":"8e90a97b-01ac-41e8-8556-08869fa3d238","type":"point","x":2840.5,"y":226.5},{"id":"dcd793d3-a40f-4e95-8cc2-7aecdc13327a","type":"point","x":2860.5,"y":226.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"11c611ea-d330-4090-926a-10638465bda6","activeWidgetId":"3b7cd616-26c1-4f4c-aa42-a83372bff632","point":{"x":1926,"y":427}},"targetPort":{"id":"15c1f196-32f3-465c-a3aa-ef87f6ef2726","activeWidgetId":"0421ee97-e72d-46f3-b52e-f88112fd9c8d","point":{"x":2860,"y":226}}},"1a0c3c99-afb1-4b76-963c-83a5242e53c4":{"id":"521d57bc-932f-45f0-be33-ee75fdf6d250","type":"set-variable","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":1997,"y":4},"ports":[{"portId":"d44bbd2b-b429-4e5d-9ce4-930ee0f9f91a","isSourcePort":true,"linkId":"4e119b75-f46f-436b-b0fe-e341c04ba370","type":"arrow","links":["4e119b75-f46f-436b-b0fe-e341c04ba370"],"properties":{"x":1989,"name":"in","y":22,"label":"in","alignment":"left"}},{"portId":"60b734b9-6a1b-4f6d-9cc9-f0558491be78","isSourcePort":false,"linkId":"5ff59fa2-89bb-43eb-b91a-e305b197c2e3","type":"arrow","links":["5ff59fa2-89bb-43eb-b91a-e305b197c2e3"],"properties":{"x":2164,"name":"out","y":22,"label":"out","alignment":"right"}},{"portId":"631c73bd-5ce6-483b-bb37-da74e3db9a3d","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":2164.5,"name":"error","y":115.2662353515625,"label":"error","alignment":"right"}}],"properties":{"activityId":"set-variable","srcVariable":"Global_IsCallback","name":"SetIsCallback","srcVariableType":"BOOLEAN","activityName":"set-variable","setTo":"set-to-literal","expr":"True","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"f05559c7-3ed2-410b-b8c9-bc6961ea736f":{"id":"4e119b75-f46f-436b-b0fe-e341c04ba370","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"10a4c6b3-6c19-4975-80dd-96688cf36828","type":"point","x":1926,"y":252.640625},{"id":"76deee59-bd15-4d4a-bb83-479054ef27bc","type":"point","x":1945,"y":252.640625},{"id":"111edd5b-0ef3-4bd2-bf61-f74f2a20aa6e","type":"point","x":1945,"y":-16},{"id":"e6240768-cb87-409b-82d1-b85b9b48b766","type":"point","x":1977.5,"y":-16},{"id":"24b8050d-c1d4-4b25-83c9-3b9264f94162","type":"point","x":1977.5,"y":30.5},{"id":"a3676688-203c-4a88-96f8-79dd9a1bc620","type":"point","x":1997.5,"y":30.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"732f9d98-6032-44b9-8689-470187a37651","activeWidgetId":"3b7cd616-26c1-4f4c-aa42-a83372bff632","point":{"x":1926,"y":252}},"targetPort":{"id":"d44bbd2b-b429-4e5d-9ce4-930ee0f9f91a","activeWidgetId":"521d57bc-932f-45f0-be33-ee75fdf6d250","point":{"x":1997,"y":30}}},"6ea4f155-16af-41b0-b862-85b1442d79b5":{"id":"03e07a56-7e9d-4f9c-8c5e-8b9b32b4099e","type":"set-variable","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":2009,"y":298},"ports":[{"portId":"9e480fbd-6073-4a00-9399-928b32f29d31","isSourcePort":true,"linkId":"26219a53-e47f-4aff-8f2e-38bbf749719a","type":"arrow","links":["26219a53-e47f-4aff-8f2e-38bbf749719a"],"properties":{"x":2001,"name":"in","y":316,"label":"in","alignment":"left"}},{"portId":"f8baa596-4691-4fa2-bc4f-64e0ea892367","isSourcePort":false,"linkId":"90f95673-5bb1-4d11-b681-dcb510859b14","type":"arrow","links":["90f95673-5bb1-4d11-b681-dcb510859b14"],"properties":{"x":2176,"name":"out","y":316,"label":"out","alignment":"right"}},{"portId":"942ac6cb-3a04-4f37-9542-90873b4764cd","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":2176.5,"name":"error","y":409.2662353515625,"label":"error","alignment":"right"}}],"properties":{"activityId":"set-variable","srcVariable":"AgentEmail","name":"SetAgentEmail","srcVariableType":"STRING","activityName":"set-variable","setTo":"set-to-literal","expr":"lab_admin{{Global_AttendeeID}}@email.carehybrid.com","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"44fd78fc-59ad-423f-af1e-6740b53b980a":{"id":"26219a53-e47f-4aff-8f2e-38bbf749719a","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"d8ef6263-0f1f-47c1-9ebb-d59aca0eb8b5","type":"point","x":1926,"y":286.0625},{"id":"7b017f0c-1f38-4727-9dfd-d554c5f23b7a","type":"point","x":1945,"y":286.0625},{"id":"609e47b7-55f3-4e70-a70c-80f40a370a49","type":"point","x":1945,"y":278},{"id":"9d298fec-a0e3-4d6c-b2bb-7d72a6d7d054","type":"point","x":1989.5,"y":278},{"id":"24211d5e-b5a2-49ff-af69-e100206e0e29","type":"point","x":1989.5,"y":324.5},{"id":"05feccd4-a7c6-4c25-91ab-c46fe1c6ab62","type":"point","x":2009.5,"y":324.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"4a730f26-784a-4831-8caf-8c16fa57c43c","activeWidgetId":"3b7cd616-26c1-4f4c-aa42-a83372bff632","point":{"x":1926,"y":286}},"targetPort":{"id":"9e480fbd-6073-4a00-9399-928b32f29d31","activeWidgetId":"03e07a56-7e9d-4f9c-8c5e-8b9b32b4099e","point":{"x":2009,"y":324}}},"b1fce4bb-ce05-4ffa-8e86-c4b05d6d99d6":{"id":"036195f9-ffb8-4fea-89f3-ece43765d3ce","type":"set-variable","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":2268,"y":301},"ports":[{"portId":"088e6f63-281f-42bb-8c4e-fa38f2c55d85","isSourcePort":true,"linkId":"90f95673-5bb1-4d11-b681-dcb510859b14","type":"arrow","links":["90f95673-5bb1-4d11-b681-dcb510859b14"],"properties":{"x":2260,"name":"in","y":319,"label":"in","alignment":"left"}},{"portId":"bc35daa5-1e78-406d-8105-f4175b3438b2","isSourcePort":false,"linkId":"df466cef-0915-4202-b7b9-2b65e4ab8468","type":"arrow","links":["df466cef-0915-4202-b7b9-2b65e4ab8468"],"properties":{"x":2435,"name":"out","y":319,"label":"out","alignment":"right"}},{"portId":"68de9faf-f689-4582-9cce-801f0c0e28aa","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":2435.5,"name":"error","y":412.2662353515625,"label":"error","alignment":"right"}}],"properties":{"activityId":"set-variable","srcVariable":"Global_IVRpath","name":"SetIVRPath","srcVariableType":"STRING","activityName":"set-variable","setTo":"set-to-literal","expr":"Preferred Agent","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"b8ae55cb-211a-4d5d-839b-435257357406":{"id":"90f95673-5bb1-4d11-b681-dcb510859b14","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"e640d0f5-f76a-46af-95bf-94c3e1d9b714","type":"point","x":2184,"y":324.5},{"id":"59ed27d4-0232-4b00-8c48-06feebfc854b","type":"point","x":2205,"y":324.5},{"id":"71bb0a48-5070-4dbf-80b7-ea761e434f31","type":"point","x":2205,"y":281},{"id":"9dc07a48-f25d-4ba7-94fc-6dd1692c5ab4","type":"point","x":2248.5,"y":281},{"id":"019db613-34d7-4afd-83b3-5bbdabc84425","type":"point","x":2248.5,"y":327.5},{"id":"1f56be11-0018-4e83-b9de-cfb41fd4755b","type":"point","x":2268.5,"y":327.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"f8baa596-4691-4fa2-bc4f-64e0ea892367","activeWidgetId":"03e07a56-7e9d-4f9c-8c5e-8b9b32b4099e","point":{"x":2184,"y":324}},"targetPort":{"id":"088e6f63-281f-42bb-8c4e-fa38f2c55d85","activeWidgetId":"036195f9-ffb8-4fea-89f3-ece43765d3ce","point":{"x":2268,"y":327}}},"0a40d080-163f-4a5c-a0dc-d12eaac03212":{"id":"e8587b3a-e695-4dab-a332-5ebf6718c19d","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":2513,"y":306},"ports":[{"portId":"c0e0a0ca-086b-4c7c-8b17-faeb9d83457f","isSourcePort":true,"linkId":"df466cef-0915-4202-b7b9-2b65e4ab8468","type":"arrow","links":["df466cef-0915-4202-b7b9-2b65e4ab8468"],"properties":{"x":2505,"name":"in","y":324,"label":"in","alignment":"left"}},{"portId":"e9d9dddd-082e-4899-932c-9ddea2c82628","isSourcePort":false,"linkId":"fca9805e-ef82-4659-b2ec-ba09c7dc52f5","type":"arrow","links":["fca9805e-ef82-4659-b2ec-ba09c7dc52f5"],"properties":{"x":2680,"name":"default","y":324,"label":"default","alignment":"right"}},{"portId":"2ba1d70b-9d3e-450a-9445-e72671e4711f","isSourcePort":false,"linkId":"06e7f723-5e40-4959-b84d-a9dc2baee52f","type":"arrow","links":["06e7f723-5e40-4959-b84d-a9dc2baee52f"],"properties":{"x":2680.5,"name":"error","y":417.2662353515625,"label":"error","alignment":"right"}}],"properties":{"recoveryQueue:type":"LONGEST_AVAILABLE_AGENT","reportingQueue":"AXmQtfndzemenKet3Um8","activityName":"queue-to-agent","description":"","priority":null,"priorityRadioGroup":null,"reportingQueue:type":"LONGEST_AVAILABLE_AGENT","destinationLookupType":"agentEmail","activityId":"628d7efd4ba3176df6ce0088","priorityToggle":false,"destinationLookupType:type":null,"priorityVariable":null,"destinationVariable":"{{AgentEmail}}","name":"QueueToAgent_lqr","recoveryQueue":"AXmQtfndzemenKet3Um8","_renderRequestTimestamp":1676676724030,"parkContactToggle":true}},"834fefa7-cec8-4c8b-9e34-b48b54d1a5a1":{"id":"df466cef-0915-4202-b7b9-2b65e4ab8468","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"1a8eb890-aed9-41d3-82d5-fb8849c6896e","type":"point","x":2443,"y":327.5},{"id":"6cdb103b-07e1-421c-8c1a-9e254a9f2533","type":"point","x":2465,"y":327.5},{"id":"ba109685-452e-422f-9966-e6478dd2dec8","type":"point","x":2465,"y":286},{"id":"1a1cd001-80fb-46c2-9b64-c1abf970aad3","type":"point","x":2493.5,"y":286},{"id":"563e2f32-6284-474b-86f2-85d414c38f82","type":"point","x":2493.5,"y":332.5},{"id":"96105d0c-a7b1-44f9-ba07-de24602338e4","type":"point","x":2513.5,"y":332.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"bc35daa5-1e78-406d-8105-f4175b3438b2","activeWidgetId":"036195f9-ffb8-4fea-89f3-ece43765d3ce","point":{"x":2443,"y":327}},"targetPort":{"id":"c0e0a0ca-086b-4c7c-8b17-faeb9d83457f","activeWidgetId":"e8587b3a-e695-4dab-a332-5ebf6718c19d","point":{"x":2513,"y":332}}},"6d33b492-58ad-4a81-baeb-f2395040726b":{"id":"06e7f723-5e40-4959-b84d-a9dc2baee52f","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"4bf7dad6-2409-4070-be20-ab03dba8451c","type":"point","x":2689,"y":425.7662353515625},{"id":"38cba76b-e7b1-481e-bc8f-5b4d25ebe987","type":"point","x":2710,"y":425.7662353515625},{"id":"48c8b8d6-7a3a-4b9f-9f69-d997f0e9a1fa","type":"point","x":2710,"y":180},{"id":"64e8cdb5-939c-4827-86bc-80f49ad68b48","type":"point","x":2840.5,"y":180},{"id":"497c9d8a-873f-4039-8d50-1a1bc12e9976","type":"point","x":2840.5,"y":226.5},{"id":"70716de0-d38f-41c6-8ef1-66cd362fdb41","type":"point","x":2860.5,"y":226.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"2ba1d70b-9d3e-450a-9445-e72671e4711f","activeWidgetId":"e8587b3a-e695-4dab-a332-5ebf6718c19d","point":{"x":2689,"y":425}},"targetPort":{"id":"15c1f196-32f3-465c-a3aa-ef87f6ef2726","activeWidgetId":"0421ee97-e72d-46f3-b52e-f88112fd9c8d","point":{"x":2860,"y":226}}},"d16f3fc4-279a-4521-a21e-0ee168cbec5a":{"id":"fca9805e-ef82-4659-b2ec-ba09c7dc52f5","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"b040d1fe-6064-4e8c-8d82-ff7679dde3dc","type":"point","x":2688.5,"y":332.5},{"id":"fdf1a0f9-b8eb-4017-9932-fc955bc1ed32","type":"point","x":2710,"y":332.5},{"id":"58c518f3-a446-4cc6-ade3-00035afe1ea0","type":"point","x":2710,"y":180},{"id":"a1563f2b-a35f-4aff-887f-1d10ad7b3e10","type":"point","x":1468.5,"y":180},{"id":"9a781259-3795-4b94-8a47-7b94f4e07a38","type":"point","x":1468.5,"y":226.5},{"id":"ca2a8415-4c76-47c1-bb5a-d9394f338a6c","type":"point","x":1485,"y":226.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"e9d9dddd-082e-4899-932c-9ddea2c82628","activeWidgetId":"e8587b3a-e695-4dab-a332-5ebf6718c19d","point":{"x":2688,"y":332}},"targetPort":{"id":"38fba055-0a82-4af5-b16c-0f825e782234","activeWidgetId":"351b1a91-ef0c-4948-a567-8a9cb1f6fcf8","point":{"x":1485,"y":226}}},"a73560a1-4809-42d5-a0c3-cda47eb85d8c":{"id":"6585bb77-0540-4386-936a-5388a6e80fb2","type":"set-variable","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":2272,"y":0},"ports":[{"portId":"2681941e-8f17-437b-9365-1788c71f0750","isSourcePort":true,"linkId":"5ff59fa2-89bb-43eb-b91a-e305b197c2e3","type":"arrow","links":["5ff59fa2-89bb-43eb-b91a-e305b197c2e3","03b5b9d7-5609-4024-9e9a-82c6b52dbe67"],"properties":{"x":2264,"name":"in","y":18,"label":"in","alignment":"left"}},{"portId":"81fc0d83-b007-479b-a6b6-2c2908503c5e","isSourcePort":false,"linkId":"6eb4b712-dc83-433e-9598-5330e9ef0349","type":"arrow","links":["6eb4b712-dc83-433e-9598-5330e9ef0349"],"properties":{"x":2439,"name":"out","y":18,"label":"out","alignment":"right"}},{"portId":"c8a4c4c1-685d-434a-90c4-11e5f85d791b","isSourcePort":false,"linkId":"03b5b9d7-5609-4024-9e9a-82c6b52dbe67","type":"arrow","links":["03b5b9d7-5609-4024-9e9a-82c6b52dbe67"],"properties":{"x":2439.5,"name":"error","y":111.2662353515625,"label":"error","alignment":"right"}}],"properties":{"activityId":"set-variable","srcVariable":"callbacknumber_int","name":"SetCallbackNumber","srcVariableType":"INTEGER","activityName":"set-variable","setTo":"set-to-literal","expr":"{{NewPhoneContact.ANI|slice(1)}}","_renderRequestTimestamp":1676676724030,"literal_invalid_error":false}},"9d755bae-f685-4dc1-bdc5-b7d8085b4830":{"id":"5ff59fa2-89bb-43eb-b91a-e305b197c2e3","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"2e5c346c-5a80-436c-b4a9-7b49676136f9","type":"point","x":2172,"y":30.5},{"id":"6718290e-e82c-458c-b9b0-da9fe82cc4bf","type":"point","x":2195,"y":30.5},{"id":"1bee1a08-a7b3-4870-8a1c-192ec00b3b72","type":"point","x":2195,"y":-20},{"id":"0d9908ee-c717-4058-935f-11b8e4871c54","type":"point","x":2252.5,"y":-20},{"id":"629a9187-2fe1-47b0-b19d-078cfac8479b","type":"point","x":2252.5,"y":26.5},{"id":"aa4758f2-488e-4e20-a196-975ad44490e8","type":"point","x":2272.5,"y":26.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"60b734b9-6a1b-4f6d-9cc9-f0558491be78","activeWidgetId":"521d57bc-932f-45f0-be33-ee75fdf6d250","point":{"x":2172,"y":30}},"targetPort":{"id":"2681941e-8f17-437b-9365-1788c71f0750","activeWidgetId":"6585bb77-0540-4386-936a-5388a6e80fb2","point":{"x":2272,"y":26}}},"3d22b9a1-f82c-409f-90cc-4e15b33c8c44":{"id":"03b5b9d7-5609-4024-9e9a-82c6b52dbe67","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"a19bf665-155c-4320-91ea-0d4225392e22","type":"point","x":2448,"y":119.7662353515625},{"id":"20d4a2e9-8f86-4cfc-9cf1-427fd2a53e12","type":"point","x":2470,"y":119.7662353515625},{"id":"92aefbd3-cec5-45cd-880f-7d5656c71057","type":"point","x":2470,"y":-20},{"id":"f56f1530-68f2-439d-a76b-fc4ab5d6dcd4","type":"point","x":2252.5,"y":-20},{"id":"49c7c6e1-04f5-4faf-9b8f-78c9536df237","type":"point","x":2252.5,"y":26.5},{"id":"7975a0c3-84ae-43d5-9d79-6da012364032","type":"point","x":2270,"y":26.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"c8a4c4c1-685d-434a-90c4-11e5f85d791b","activeWidgetId":"6585bb77-0540-4386-936a-5388a6e80fb2","point":{"x":2448,"y":119}},"targetPort":{"id":"2681941e-8f17-437b-9365-1788c71f0750","activeWidgetId":"6585bb77-0540-4386-936a-5388a6e80fb2","point":{"x":2270,"y":26}}},"f0fe2951-de2c-4a3f-aa14-c9898505b495":{"id":"88fa8656-dc11-4c99-9e42-d5fc1727b3a3","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":2514,"y":-1},"ports":[{"portId":"29bc88ec-165d-440c-a439-c06d4532011a","isSourcePort":true,"linkId":"6eb4b712-dc83-433e-9598-5330e9ef0349","type":"arrow","links":["6eb4b712-dc83-433e-9598-5330e9ef0349"],"properties":{"x":2506,"name":"in","y":17,"label":"in","alignment":"left"}},{"portId":"30bdc398-8ee4-4fc8-9518-7f0d2e77297d","isSourcePort":false,"linkId":"99cb4c59-72da-4fd1-8225-bf3d4cc9149e","type":"arrow","links":["99cb4c59-72da-4fd1-8225-bf3d4cc9149e"],"properties":{"x":2681,"name":"default","y":17,"label":"default","alignment":"right"}},{"portId":"24aa9bc9-1c4c-4bc4-8894-c3ceda894f81","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":2681.5,"name":"error","y":110.2662353515625,"label":"error","alignment":"right"}}],"properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"play-message","description":"","toggle":false,"activityId":"5f114466ef5cfc454fbbf131","connector":null,"name":"Callback","toggleLanguage":null,"_renderRequestTimestamp":1676676724030,"prompts":[{"type":"audioFile","value":"CallbackRequest.wav"}],"promptsTts":null}},"ec5858c1-ff7e-4eb5-89dc-b457ad720f39":{"id":"6eb4b712-dc83-433e-9598-5330e9ef0349","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"cf5f56a9-d296-4ef1-82e1-f766367138d3","type":"point","x":2447,"y":26.5},{"id":"564885df-458d-48c0-ab6f-ddef2baf0deb","type":"point","x":2470,"y":26.5},{"id":"46807b1e-087d-4d9c-b57e-5e24131aa1d2","type":"point","x":2470,"y":-21},{"id":"d7050361-9665-4189-9c4c-2be8be8944f9","type":"point","x":2494.5,"y":-21},{"id":"5825a0b8-1ca6-440e-8c89-f363fd293cbe","type":"point","x":2494.5,"y":25.5},{"id":"f0b39f50-a8f2-4dd1-a773-7584d32392ba","type":"point","x":2514.5,"y":25.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"81fc0d83-b007-479b-a6b6-2c2908503c5e","activeWidgetId":"6585bb77-0540-4386-936a-5388a6e80fb2","point":{"x":2447,"y":26}},"targetPort":{"id":"29bc88ec-165d-440c-a439-c06d4532011a","activeWidgetId":"88fa8656-dc11-4c99-9e42-d5fc1727b3a3","point":{"x":2514,"y":25}}},"db978ed6-2a51-4bf2-b196-ad577431424b":{"id":"70f20257-ebb1-41cd-9e51-b9c132b8e6a3","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":2756,"y":-4},"ports":[{"portId":"cd7e469f-43aa-4a52-b261-3be37224a5f3","isSourcePort":true,"linkId":"99cb4c59-72da-4fd1-8225-bf3d4cc9149e","type":"arrow","links":["99cb4c59-72da-4fd1-8225-bf3d4cc9149e"],"properties":{"x":2748,"name":"in","y":14,"label":"in","alignment":"left"}},{"portId":"8c03feb5-433d-40cd-96ae-1fbeed36f7f7","isSourcePort":false,"linkId":"1c51cf12-7ac1-4940-b60d-b9ae17ed861a","type":"arrow","links":["1c51cf12-7ac1-4940-b60d-b9ae17ed861a"],"properties":{"x":2923,"name":"default","y":14,"label":"default","alignment":"right"}},{"portId":"1cb26811-116d-4d08-a197-f54f76b7b955","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":2906,"name":"failure","y":96,"label":"failure","alignment":"right"}}],"properties":{"callbackAni:radioName":"staticAni","activityId":"5f367a285d76a50d1e8fb4d2","callbackAni":"+14402308010","name":"CallbackRequest","activityName":"callback","description":"","callbackDn":"{{NewPhoneContact.ani}}","callbackQueue:radioName":"variableQueue","_renderRequestTimestamp":1676676724030,"callbackQueue":"{{queueID_String}}"}},"6ce4d70f-8660-46f3-9b74-662b4ac1e18a":{"id":"99cb4c59-72da-4fd1-8225-bf3d4cc9149e","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"0dc07402-19ca-4aa7-b3d2-dfdb0a10371e","type":"point","x":2689,"y":25.5},{"id":"0a431f1d-715a-4e32-95d1-3a29fd3dc864","type":"point","x":2710,"y":25.5},{"id":"4e576686-20f0-458a-b3eb-2cb674b5a36c","type":"point","x":2710,"y":-24},{"id":"c3ebefbe-3019-44fb-9c31-909998c806e1","type":"point","x":2736.5,"y":-24},{"id":"32e5796a-1d5b-4863-af99-db112dbd50bb","type":"point","x":2736.5,"y":22.5},{"id":"086b3606-0acd-4be4-a423-b8e51b981c1f","type":"point","x":2756.5,"y":22.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"30bdc398-8ee4-4fc8-9518-7f0d2e77297d","activeWidgetId":"88fa8656-dc11-4c99-9e42-d5fc1727b3a3","point":{"x":2689,"y":25}},"targetPort":{"id":"cd7e469f-43aa-4a52-b261-3be37224a5f3","activeWidgetId":"70f20257-ebb1-41cd-9e51-b9c132b8e6a3","point":{"x":2756,"y":22}}},"29f46a2d-cc08-429b-afef-25b089177177":{"id":"1c51cf12-7ac1-4940-b60d-b9ae17ed861a","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"1f7e560e-887d-4dc9-8bbe-38dd038dcbbd","type":"point","x":2931.5,"y":22.5},{"id":"cb9d6ab7-8fd7-4302-bc67-c3eeb094f97f","type":"point","x":2950,"y":22.5},{"id":"13983767-b8a9-49a4-ad3e-5930dd4a03f8","type":"point","x":2950,"y":180},{"id":"3358c53c-2df3-4e1b-9d9b-e004bfb2eb4c","type":"point","x":2840.5,"y":180},{"id":"1453fd3e-750f-4b30-9cbb-4142b3ad1f2c","type":"point","x":2840.5,"y":226.5},{"id":"2e7e6084-de9e-4300-91b4-24851d93044d","type":"point","x":2860,"y":226.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"8c03feb5-433d-40cd-96ae-1fbeed36f7f7","activeWidgetId":"70f20257-ebb1-41cd-9e51-b9c132b8e6a3","point":{"x":2931,"y":22}},"targetPort":{"id":"15c1f196-32f3-465c-a3aa-ef87f6ef2726","activeWidgetId":"0421ee97-e72d-46f3-b52e-f88112fd9c8d","point":{"x":2860,"y":226}}}},"properties":{"offsetX":-662,"offsetY":157,"zoom":75,"gridSize":0}},"flowId":"63efc53a30072469e75b5c99","eventFlows":{"eventsMap":{"GLOBAL_EVENTS":{"id":"GLOBAL_EVENTS","name":"name","description":"description","process":{"activities":{"e8cdd437-ec8b-4a6a-9518-8d833b3210f5":{"id":"e8cdd437-ec8b-4a6a-9518-8d833b3210f5","name":"FCAsk(ContactLastAgentRemoved)","group":"event","properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5ffeafa86a7eff72a481c4b5","eventSourceName":"WebexContactCenter","displayName":"AgentDisconnected","iconDiagram":"icon-headset-muted_16","eventSpecificationName":"FCAsk(ContactLastAgentRemoved)","name":"FCAsk(ContactLastAgentRemoved)","eventClassificationId":"5f10475cf021306e89e1692c","event":"AgentDisconnected","_renderRequestTimestamp":1676676724030,"eventClassificationName":"VoiceInteractions"}},"b6f144ed-43c4-4ee0-bc84-76b1fd1660f7":{"id":"b6f144ed-43c4-4ee0-bc84-76b1fd1660f7","name":"ContactEnded","group":"event","properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5f354a336fb8c44e97ccb30e","eventSourceName":"WebexContactCenter","displayName":"PhoneContactEnded","iconDiagram":"icon-handset-muted_16","eventSpecificationName":"ContactEnded","name":"ContactEnded","eventClassificationId":"5f10475cf021306e89e1692c","event":"PhoneContactEnded","_renderRequestTimestamp":1676676724030,"eventClassificationName":"VoiceInteractions"}},"1628fcb8-89c4-4556-a816-fed7448d0ef7":{"id":"1628fcb8-89c4-4556-a816-fed7448d0ef7","name":"GlobalErrorHandling","group":"event","properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"627c0663e98eca854178bba6","eventSourceName":"WebexContactCenter","displayName":"OnGlobalError","iconDiagram":"icon-error-legacy_16","eventSpecificationName":"GlobalErrorHandling","name":"GlobalErrorHandling","eventClassificationId":"5f10475cf021306e89e1692c","event":"OnGlobalError","_renderRequestTimestamp":1676676724030,"eventClassificationName":"VoiceInteractions"}},"f06a53c8-5dad-48f0-89af-0826bf290458":{"id":"f06a53c8-5dad-48f0-89af-0826bf290458","name":"AgentContactAssigned","group":"event","properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5f354a0c6fb8c44e97ccb30d","eventSourceName":"WebexContactCenter","displayName":"AgentAnswered","iconDiagram":"icon-headset_16","eventSpecificationName":"AgentContactAssigned","name":"AgentContactAssigned","eventClassificationId":"5f10475cf021306e89e1692c","event":"AgentAnswered","_renderRequestTimestamp":1676676724030,"eventClassificationName":"VoiceInteractions"}}},"links":[]},"onEvents":{"GlobalErrorHandling":"1628fcb8-89c4-4556-a816-fed7448d0ef7","AgentContactAssigned":"f06a53c8-5dad-48f0-89af-0826bf290458","ContactEnded":"b6f144ed-43c4-4ee0-bc84-76b1fd1660f7","FCAsk(ContactLastAgentRemoved)":"e8cdd437-ec8b-4a6a-9518-8d833b3210f5"},"diagram":{"widgets":{"1628fcb8-89c4-4556-a816-fed7448d0ef7":{"id":"5457e5b3-b4d9-4d18-91ee-d113db00e3e4","type":"event","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":115},"ports":[{"portId":"aa721f30-a7c7-434e-b9aa-8d9ee837dce1","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":100,"name":"out","y":115,"label":"out","alignment":"right"}}],"properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"627c0663e98eca854178bba6","eventSourceName":"WebexContactCenter","displayName":"OnGlobalError","iconDiagram":"icon-error-legacy_16","eventSpecificationName":"GlobalErrorHandling","name":"GlobalErrorHandling","eventClassificationId":"5f10475cf021306e89e1692c","event":"OnGlobalError","_renderRequestTimestamp":1676676724030,"eventClassificationName":"VoiceInteractions"}},"f06a53c8-5dad-48f0-89af-0826bf290458":{"id":"9403aaec-6155-4636-9dee-bdb4d6f1c67a","type":"event","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":230},"ports":[{"portId":"7e8c16bc-6e6f-42cc-8859-e46e33d689cc","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":100,"name":"out","y":230,"label":"out","alignment":"right"}}],"properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5f354a0c6fb8c44e97ccb30d","eventSourceName":"WebexContactCenter","displayName":"AgentAnswered","iconDiagram":"icon-headset_16","eventSpecificationName":"AgentContactAssigned","name":"AgentContactAssigned","eventClassificationId":"5f10475cf021306e89e1692c","event":"AgentAnswered","_renderRequestTimestamp":1676676724030,"eventClassificationName":"VoiceInteractions"}},"b6f144ed-43c4-4ee0-bc84-76b1fd1660f7":{"id":"8c202e39-af3e-4664-aebc-899456cc61da","type":"event","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":345},"ports":[{"portId":"0a0ae797-8d79-4abb-abee-52f907b2161d","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":100,"name":"out","y":345,"label":"out","alignment":"right"}}],"properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5f354a336fb8c44e97ccb30e","eventSourceName":"WebexContactCenter","displayName":"PhoneContactEnded","iconDiagram":"icon-handset-muted_16","eventSpecificationName":"ContactEnded","name":"ContactEnded","eventClassificationId":"5f10475cf021306e89e1692c","event":"PhoneContactEnded","_renderRequestTimestamp":1676676724030,"eventClassificationName":"VoiceInteractions"}},"e8cdd437-ec8b-4a6a-9518-8d833b3210f5":{"id":"aab29103-b5b8-4c65-974d-6d228932f1eb","type":"event","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":460},"ports":[{"portId":"674c7234-16d3-4414-a30b-26152c59526a","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":100,"name":"out","y":460,"label":"out","alignment":"right"}}],"properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5ffeafa86a7eff72a481c4b5","eventSourceName":"WebexContactCenter","displayName":"AgentDisconnected","iconDiagram":"icon-headset-muted_16","eventSpecificationName":"FCAsk(ContactLastAgentRemoved)","name":"FCAsk(ContactLastAgentRemoved)","eventClassificationId":"5f10475cf021306e89e1692c","event":"AgentDisconnected","_renderRequestTimestamp":1676676724030,"eventClassificationName":"VoiceInteractions"}}},"properties":{}}}},"properties":{"offsetX":0,"offsetY":0,"zoom":0,"gridSize":0}},"runtimeVariables":[],"validating":true,"persist":true,"validationResults":[],"createdBy":"adminlabus@email.carehybrid.com","createdDate":"2023-02-17T23:32:06.963","lastModifiedDate":"2023-02-17T23:32:06.963","lastModifiedBy":"adminlabus@email.carehybrid.com","variableOrders":{"pop-over":[{"name":"ani","variableSeq":"0"},{"name":"dn","variableSeq":"1"},{"name":"virtualTeamName","variableSeq":"2"}],"interaction-panel":[]}} \ No newline at end of file diff --git a/assets/files/ESD_default_layout.json b/assets/files/ESD_default_layout.json new file mode 100644 index 0000000000..4348cbf34c --- /dev/null +++ b/assets/files/ESD_default_layout.json @@ -0,0 +1,1185 @@ +{ + "agent": { + "version": "0.1.0", + "appTitle": "Webex Contact Center", + "logo": "", + "stopNavigateOnAcceptTask": false, + "dragDropEnabled": true, + "notificationTimer": 8, + "maximumNotificationCount": 3, + "browserNotificationTimer": 8, + "wxmConfigured": false, + "desktopChatApp": { + "webexConfigured": true + }, + "area": { + "advancedHeader": [ + { + "comp": "agentx-webex" + }, + { + "comp": "agentx-outdial" + }, + { + "comp": "agentx-notification" + }, + { + "comp": "agentx-state-selector" + } + ], + "panel": { + "comp": "md-tabs", + "attributes": { + "class": "widget-tabs" + }, + "children": [ + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT_TAB" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "WXM_JOURNEY_TAB" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "agentx-wc-cloudcherry-widget", + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "ani": "$STORE.agentContact.taskSelected.ani", + "isDarkMode": "$STORE.app.darkMode" + }, + "wrapper": { + "title": "Customer Experience Journey", + "maximizeAreaName": "app-maximize-area" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY_TAB" + } + } + ] + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY" + } + } + ] + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP_TAB" + } + } + ], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP" + } + } + ], + "visibility": "SCREEN_POP" + } + ] + }, + "navigation": [ + { + "nav": { + "label": "Customer Experience Analytics", + "icon": "/app/images/wxm.bcd45cc3.svg", + "iconType": "other", + "navigateTo": "wxm-metrics", + "align": "top" + }, + "page": { + "id": "wxm-metrics", + "widgets": { + "comp1": { + "comp": "agentx-wc-cloudcherry-widget", + "attributes": { + "metrics": true + }, + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "isDarkMode": "$STORE.app.darkMode", + "agentId": "$STORE.agent.agentId" + } + } + }, + "layout": { + "areas": [["comp1"]], + "size": { + "cols": [1], + "rows": [1] + } + } + }, + "visibility": "WXM_METRICS" + } + ] + } + }, + "supervisor": { + "version": "0.1.0", + "appTitle": "Webex Contact Center", + "logo": "", + "stopNavigateOnAcceptTask": false, +<<<<<<< HEAD + "dragDropEnabled": false, +======= + "dragDropEnabled": true, +>>>>>>> origin/master + "notificationTimer": 8, + "maximumNotificationCount": 3, + "browserNotificationTimer": 8, + "wxmConfigured": false, + "desktopChatApp": { + "webexConfigured": true + }, + "area": { + "advancedHeader": [ + { + "comp": "agentx-webex" + }, + { + "comp": "agentx-notification" + } + ], + "panel": { + "comp": "md-tabs", + "attributes": { + "class": "widget-tabs" + }, + "children": [ + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT_TAB" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "WXM_JOURNEY_TAB" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "agentx-wc-cloudcherry-widget", + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "ani": "$STORE.agentContact.taskSelected.ani", + "isDarkMode": "$STORE.app.darkMode" + }, + "wrapper": { + "title": "Customer Experience Journey", + "maximizeAreaName": "app-maximize-area" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY_TAB" + } + } + ] + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY" + } + } + ] + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP_TAB" + } + } + ], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP" + } + } + ], + "visibility": "SCREEN_POP" + } + ] + }, + "homepage": { + "nav": { + "label": "$I18N.common.homePageLabel", + "icon": "home", + "iconType": "momentum", + "navigateTo": "home", + "align": "top" + }, + "page": { + "id": "landing", + "pageHeader": { + "comp": "div", + "children": [ + { + "comp": "page-title", + "attributes": { + "pageTitle": "$STORE.page.getDefaultPageTitle" + } + } + ] + }, + "useFlexLayout": true, + "pageSubHeader": { + "comp": "div", + "attributes": { + "style": "display: flex; float:right;margin:16px 0px 16px 16px" + }, + "children": [ + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.queueName", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-queue-filter", + "properties": { + "selectedQueueList": "$STORE.agent.selectedQueueList", + "managedQueues": "$STORE.agent.managedQueues", + "isLoading": "$STORE.agent.isManagedQueueLoading", + "isError": "$STORE.agent.isManagedQueuesError" + } + } + ], + "attributes": { + "style": "display:block;width:260px;" + } + }, + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.channelType", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-channel-filter", + "properties": { + "selectedChannelList": "$STORE.agent.selectedChannelList" + } + } + ], + "attributes": { + "style": "display:block;margin-left:16px;width:260px; " + } + }, + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.managedTeams", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-team-filter", + "properties": { + "selectedTeamList": "$STORE.agent.selectedTeamList", + "managedTeams": "$STORE.agent.managedTeams", + "isLoading": "$STORE.agent.isManagedTeamLoading", + "isError": "$STORE.agent.isManagedTeamsError" + } + } + ], + "attributes": { + "style": "display:block;margin-left:16px;width:260px;" + } + }, + { + "comp": "div", + "children": [ + { + "comp": "agentx-more-actions-wrapper", + "properties": { + "actionList": [ + { + "comp": "agentx-wc-goto-analyzer" + } + ] + } + } + ], + "attributes": { + "style": "display:block;margin-top: 20px;" + } + } + ] + }, + "widgets": { + "comp1": { + "comp": "analyzer-widget", + "width": 25, + "height": 25, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "c04c307c-71fd-41f4-828f-a196f94ce08a" + } + }, + "comp2": { + "comp": "analyzer-widget", + "width": 25, + "height": 25, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "bc3f908d-11fa-4f86-be9b-7edfe76eaa59" + } + }, + "comp3": { + "comp": "analyzer-widget", + "width": 25, + "height": 25, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "3e4555a5-be23-46e6-8450-8ebf3f1c35e1" + } + }, + "comp4": { + "comp": "analyzer-widget", + "width": 25, + "height": 25, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "2902a699-bf70-4568-afa1-6857db3e0dc4" + } + }, + "comp5": { + "comp": "analyzer-widget", + "width": 33, + "height": 30, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "21716c3a-09a9-476a-bab1-5fbcff226ac6" + } + }, + "comp6": { + "comp": "analyzer-widget", + "width": 33, + "height": 30, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "0136c56b-c40f-47a0-af1c-1a180db1fd64" + } + }, + "comp7": { + "comp": "analyzer-widget", + "width": 34, + "height": 30, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "e5e19275-0465-4e8c-923d-c9c06002330f" + } + }, + "comp8": { + "comp": "analyzer-widget", + "width": 50, + "height": 40, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "9d80a068-099c-48e3-b8a8-207eb38c47c5" + } + }, + "comp9": { + "comp": "analyzer-widget", + "width": 50, + "height": 40, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "a0bbecca-0129-4649-9261-ef0fe69281aa" + } + } + } + } + }, + "navigation": [ + { + "nav": { + "label": "Customer Experience Analytics", + "icon": "/app/images/wxm.bcd45cc3.svg", + "iconType": "other", + "navigateTo": "wxm-metrics", + "align": "top" + }, + "page": { + "id": "wxm-metrics", + "widgets": { + "comp1": { + "comp": "agentx-wc-cloudcherry-widget", + "attributes": { + "metrics": true + }, + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "isDarkMode": "$STORE.app.darkMode", + "agentId": "$STORE.agent.agentId" + } + } + }, + "layout": { + "areas": [["comp1"]], + "size": { + "cols": [1], + "rows": [1] + } + } + }, + "visibility": "WXM_METRICS" + }, + { + "nav": { + "label": "Team Performance Details", + "icon": "team", + "iconType": "momentum", + "navigateTo": "tpw", + "align": "top" + }, + "page": { + "id": "tpw-sup", + "useFlexLayout": true, + "widgets": { + "comp1": { + "comp": "agentx-wc-team-performance-widget", + "width": 100, + "height": 100, + "wrapper": { + "title": "$I18N.tpw.wrapperTitle", + "id": "tpw-1", + "maximizeAreaName": "app-maximize-area" + }, + "properties": { + "tpwConfigs": "$STORE.agent.tpwConfigs" + } + } + } + } + } + ] + } + }, + "supervisorAgent": { + "version": "0.1.0", + "appTitle": "Webex Contact Center", + "logo": "", + "stopNavigateOnAcceptTask": false, +<<<<<<< HEAD + "dragDropEnabled": false, +======= + "dragDropEnabled": true, +>>>>>>> origin/master + "notificationTimer": 8, + "maximumNotificationCount": 3, + "browserNotificationTimer": 8, + "wxmConfigured": false, + "desktopChatApp": { + "webexConfigured": true + }, + "area": { + "advancedHeader": [ + { + "comp": "agentx-webex" + }, + { + "comp": "agentx-outdial" + }, + { + "comp": "agentx-notification" + }, + { + "comp": "agentx-state-selector" + } + ], + "panel": { + "comp": "md-tabs", + "attributes": { + "class": "widget-tabs" + }, + "children": [ + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT_TAB" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "WXM_JOURNEY_TAB" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "agentx-wc-cloudcherry-widget", + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "ani": "$STORE.agentContact.taskSelected.ani", + "isDarkMode": "$STORE.app.darkMode" + }, + "wrapper": { + "title": "Customer Experience Journey", + "maximizeAreaName": "app-maximize-area" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY_TAB" + } + } + ] + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY" + } + } + ] + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP_TAB" + } + } + ], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP" + } + } + ], + "visibility": "SCREEN_POP" + } + ] + }, + "homepage": { + "nav": { + "label": "$I18N.common.homePageLabel", + "icon": "home", + "iconType": "momentum", + "navigateTo": "home", + "align": "top" + }, + "page": { + "id": "landing", + "useFlexLayout": true, + "pageHeader": { + "comp": "div", + "children": [ + { + "comp": "page-title", + "attributes": { + "pageTitle": "$STORE.page.getDefaultPageTitle" + } + } + ], + "attributes": { + "style": "margin: 0px 0px 0px 16px" + } + }, + "pageSubHeader": { + "comp": "div", + "attributes": { + "style": "display: flex; float:right" + }, + "children": [ + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.queueName", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-queue-filter", + "properties": { + "selectedQueueList": "$STORE.agent.selectedQueueList", + "managedQueues": "$STORE.agent.managedQueues", + "isLoading": "$STORE.agent.isManagedQueueLoading", + "isError": "$STORE.agent.isManagedQueuesError" + } + } + ], + "attributes": { + "style": "display:block;width:260px;" + } + }, + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.channelType", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-channel-filter", + "properties": { + "selectedChannelList": "$STORE.agent.selectedChannelList" + } + } + ], + "attributes": { + "style": "display:block;margin-left:16px;width:260px; " + } + }, + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.managedTeams", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-team-filter", + "properties": { + "selectedTeamList": "$STORE.agent.selectedTeamList", + "managedTeams": "$STORE.agent.managedTeams", + "isLoading": "$STORE.agent.isManagedTeamLoading", + "isError": "$STORE.agent.isManagedTeamsError" + } + } + ], + "attributes": { + "style": "display:block;margin-left:16px;width:260px;" + } + }, + { + "comp": "div", + "children": [ + { + "comp": "agentx-more-actions-wrapper", + "properties": { + "actionList": [ + { + "comp": "agentx-wc-goto-analyzer" + } + ] + } + } + ], + "attributes": { + "style": "display:block;margin-top: 20px;" + } + } + ] + }, + "widgets": { + "comp1": { + "comp": "analyzer-widget", + "width": 25, + "height": 25, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "c04c307c-71fd-41f4-828f-a196f94ce08a" + } + }, + "comp2": { + "comp": "analyzer-widget", + "width": 25, + "height": 25, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "bc3f908d-11fa-4f86-be9b-7edfe76eaa59" + } + }, + "comp3": { + "comp": "analyzer-widget", + "width": 25, + "height": 25, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "3e4555a5-be23-46e6-8450-8ebf3f1c35e1" + } + }, + "comp4": { + "comp": "analyzer-widget", + "width": 25, + "height": 25, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "2902a699-bf70-4568-afa1-6857db3e0dc4" + } + }, + "comp5": { + "comp": "analyzer-widget", + "width": 33, + "height": 30, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "21716c3a-09a9-476a-bab1-5fbcff226ac6" + } + }, + "comp6": { + "comp": "analyzer-widget", + "width": 33, + "height": 30, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "0136c56b-c40f-47a0-af1c-1a180db1fd64" + } + }, + "comp7": { + "comp": "analyzer-widget", + "width": 34, + "height": 30, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "e5e19275-0465-4e8c-923d-c9c06002330f" + } + }, + "comp8": { + "comp": "analyzer-widget", + "width": 50, + "height": 40, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "9d80a068-099c-48e3-b8a8-207eb38c47c5" + } + }, + "comp9": { + "comp": "analyzer-widget", + "width": 50, + "height": 40, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "a0bbecca-0129-4649-9261-ef0fe69281aa" + } + } + } + } + }, + "navigation": [ + { + "nav": { + "label": "Customer Experience Analytics", + "icon": "/app/images/wxm.bcd45cc3.svg", + "iconType": "other", + "navigateTo": "wxm-metrics", + "align": "top" + }, + "page": { + "id": "wxm-metrics", + "widgets": { + "comp1": { + "comp": "agentx-wc-cloudcherry-widget", + "attributes": { + "metrics": true + }, + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "isDarkMode": "$STORE.app.darkMode", + "agentId": "$STORE.agent.agentId" + } + } + }, + "layout": { + "areas": [["comp1"]], + "size": { + "cols": [1], + "rows": [1] + } + } + }, + "visibility": "WXM_METRICS" + }, + { + "nav": { + "label": "Team Performance Details", + "icon": "team", + "iconType": "momentum", + "navigateTo": "tpw", + "align": "top" + }, + "page": { + "id": "tpw-sup-agent", + "useFlexLayout": true, + "widgets": { + "comp1": { + "comp": "agentx-wc-team-performance-widget", + "width": 100, + "height": 100, + "wrapper": { + "title": "$I18N.tpw.wrapperTitle", + "id": "tpw-1", + "maximizeAreaName": "app-maximize-area" + }, + "properties": { + "tpwConfigs": "$STORE.agent.tpwConfigs" + } + } + } + } + } + ] + } + } +<<<<<<< HEAD +} +======= +} +>>>>>>> origin/master diff --git a/assets/files/ESD_default_layout.json.zip b/assets/files/ESD_default_layout.json.zip new file mode 100644 index 0000000000..ae6d2b6743 Binary files /dev/null and b/assets/files/ESD_default_layout.json.zip differ diff --git a/assets/files/JDSDesktopLayout10.json b/assets/files/JDSDesktopLayout10.json new file mode 100644 index 0000000000..0aa48184eb --- /dev/null +++ b/assets/files/JDSDesktopLayout10.json @@ -0,0 +1,1298 @@ +{ + "agent": { + "version": "0.1.0", + "appTitle": "Webex Contact Center", + "logo": "", + "stopNavigateOnAcceptTask": false, + "dragDropEnabled": false, + "notificationTimer": 8, + "maximumNotificationCount": 3, + "browserNotificationTimer": 8, + "wxmConfigured": false, + "desktopChatApp": { + "webexConfigured": false + }, + "area": { + "advancedHeader": [ + { + "comp": "agentx-webex" + }, + { + "comp": "agentx-outdial" + }, + { + "comp": "agentx-notification" + }, + { + "comp": "agentx-state-selector" + } + ], + "panel": { + "comp": "md-tabs", + "attributes": { + "class": "widget-tabs" + }, + "children": [ + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT_TAB" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "span", + "textContent": "Customer Journey" + } + ] + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "customer-journey-widget", + "script": "https://journey-widget.webex.com", + "attributes": { + "show-alias-icon": "true", + "condensed-view": "true" + }, + "properties": { + "interactionData": "$STORE.agentContact.taskSelected", + "bearerToken": "$STORE.auth.accessToken", + "organizationId": "$STORE.agent.orgId", + "dataCenter": "$STORE.app.datacenter" + }, + "wrapper": { + "title": "Customer Journey Widget", + "maximizeAreaName": "app-maximize-area" + } + } + ] + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "WXM_JOURNEY_TAB" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "agentx-wc-cloudcherry-widget", + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "ani": "$STORE.agentContact.taskSelected.ani", + "isDarkMode": "$STORE.app.darkMode" + }, + "wrapper": { + "title": "Customer Experience Journey", + "maximizeAreaName": "app-maximize-area" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY_TAB" + } + } + ] + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY" + } + } + ] + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP_TAB" + } + } + ], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP" + } + } + ], + "visibility": "SCREEN_POP" + } + ] + }, + "navigation": [ + { + "nav": { + "label": "Customer Experience Analytics", + "icon": "/app/images/wxm.bcd45cc3.svg", + "iconType": "other", + "navigateTo": "wxm-metrics", + "align": "top" + }, + "page": { + "id": "wxm-metrics", + "widgets": { + "comp1": { + "comp": "agentx-wc-cloudcherry-widget", + "attributes": { + "metrics": true + }, + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "isDarkMode": "$STORE.app.darkMode", + "agentId": "$STORE.agent.agentId" + } + } + }, + "layout": { + "areas": [ + [ + "comp1" + ] + ], + "size": { + "cols": [ + 1 + ], + "rows": [ + 1 + ] + } + } + }, + "visibility": "WXM_METRICS" + } + ] + } + }, + "supervisor": { + "version": "0.1.0", + "appTitle": "Webex Contact Center", + "logo": "", + "stopNavigateOnAcceptTask": false, + "dragDropEnabled": false, + "notificationTimer": 8, + "maximumNotificationCount": 3, + "browserNotificationTimer": 8, + "wxmConfigured": false, + "desktopChatApp": { + "webexConfigured": false + }, + "area": { + "advancedHeader": [ + { + "comp": "agentx-webex" + }, + { + "comp": "agentx-notification" + } + ], + "panel": { + "comp": "md-tabs", + "attributes": { + "class": "widget-tabs" + }, + "children": [ + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT_TAB" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "WXM_JOURNEY_TAB" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "agentx-wc-cloudcherry-widget", + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "ani": "$STORE.agentContact.taskSelected.ani", + "isDarkMode": "$STORE.app.darkMode" + }, + "wrapper": { + "title": "Customer Experience Journey", + "maximizeAreaName": "app-maximize-area" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY_TAB" + } + } + ] + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY" + } + } + ] + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP_TAB" + } + } + ], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP" + } + } + ], + "visibility": "SCREEN_POP" + } + ] + }, + "homepage": { + "nav": { + "label": "$I18N.common.homePageLabel", + "icon": "home", + "iconType": "momentum", + "navigateTo": "home", + "align": "top" + }, + "page": { + "id": "landing", + "pageHeader": { + "comp": "div", + "children": [ + { + "comp": "page-title", + "attributes": { + "pageTitle": "$STORE.page.getDefaultPageTitle" + } + } + ], + "attributes": { + "style": "margin: 25px 16px 25px 16px" + } + }, + "useFlexLayout": true, + "pageSubHeader": { + "comp": "div", + "attributes": { + "style": "display: flex; float:right;" + }, + "children": [ + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.queueName", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-queue-filter", + "properties": { + "selectedQueueList": "$STORE.agent.selectedQueueList", + "managedQueues": "$STORE.agent.managedQueues", + "isLoading": "$STORE.agent.isManagedQueueLoading", + "isError": "$STORE.agent.isManagedQueuesError" + } + } + ], + "attributes": { + "style": "display:block;width:260px;" + } + }, + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.channelType", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-channel-filter", + "properties": { + "selectedChannelList": "$STORE.agent.selectedChannelList" + } + } + ], + "attributes": { + "style": "display:block;margin-left:16px;width:260px; " + } + }, + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.managedTeams", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-team-filter", + "properties": { + "selectedTeamList": "$STORE.agent.selectedTeamList", + "managedTeams": "$STORE.agent.managedTeams", + "isLoading": "$STORE.agent.isManagedTeamLoading", + "isError": "$STORE.agent.isManagedTeamsError" + } + } + ], + "attributes": { + "style": "display:block;margin-left:16px;width:260px;" + } + }, + { + "comp": "div", + "children": [ + { + "comp": "agentx-more-actions-wrapper", + "properties": { + "actionList": [ + { + "comp": "agentx-wc-goto-analyzer" + } + ] + } + } + ], + "attributes": { + "style": "display:block;margin-top: 20px;" + } + } + ] + }, + "widgets": { + "comp1": { + "comp": "analyzer-widget", + "width": 3, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "c04c307c-71fd-41f4-828f-a196f94ce08a" + } + }, + "comp2": { + "comp": "analyzer-widget", + "width": 3, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "bc3f908d-11fa-4f86-be9b-7edfe76eaa59" + } + }, + "comp3": { + "comp": "analyzer-widget", + "width": 3, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "3e4555a5-be23-46e6-8450-8ebf3f1c35e1" + } + }, + "comp4": { + "comp": "analyzer-widget", + "width": 3, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "2902a699-bf70-4568-afa1-6857db3e0dc4" + } + }, + "comp5": { + "comp": "analyzer-widget", + "width": 4, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "21716c3a-09a9-476a-bab1-5fbcff226ac6" + } + }, + "comp6": { + "comp": "analyzer-widget", + "width": 4, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "0136c56b-c40f-47a0-af1c-1a180db1fd64" + } + }, + "comp7": { + "comp": "analyzer-widget", + "width": 4, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "e5e19275-0465-4e8c-923d-c9c06002330f" + } + }, + "comp8": { + "comp": "analyzer-widget", + "width": 6, + "height": 7, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "9d80a068-099c-48e3-b8a8-207eb38c47c5" + } + }, + "comp9": { + "comp": "analyzer-widget", + "width": 6, + "height": 7, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "a0bbecca-0129-4649-9261-ef0fe69281aa" + } + } + } + } + }, + "navigation": [ + { + "nav": { + "label": "Customer Experience Analytics", + "icon": "/app/images/wxm.bcd45cc3.svg", + "iconType": "other", + "navigateTo": "wxm-metrics", + "align": "top" + }, + "page": { + "id": "wxm-metrics", + "widgets": { + "comp1": { + "comp": "agentx-wc-cloudcherry-widget", + "attributes": { + "metrics": true + }, + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "isDarkMode": "$STORE.app.darkMode", + "agentId": "$STORE.agent.agentId" + } + } + }, + "layout": { + "areas": [ + [ + "comp1" + ] + ], + "size": { + "cols": [ + 1 + ], + "rows": [ + 1 + ] + } + } + }, + "visibility": "WXM_METRICS" + }, + { + "nav": { + "label": "$I18N.tpw.widgetTitle", + "icon": "team", + "iconType": "momentum", + "navigateTo": "tpw", + "align": "top" + }, + "page": { + "id": "tpw-sup", + "useFlexLayout": true, + "widgets": { + "comp1": { + "comp": "agentx-wc-team-performance-widget", + "width": 12, + "height": 19, + "wrapper": { + "title": "$I18N.tpw.widgetTitle", + "id": "tpw-1", + "maximizeAreaName": "app-maximize-area" + }, + "properties": { + "tpwConfigs": "$STORE.agent.tpwConfigs" + } + } + } + } + }, + { + "nav": { + "label": "$I18N.qmw.recordings", + "icon": "waveform", + "iconType": "momentum", + "navigateTo": "recordings", + "align": "top" + }, + "page": { + "id": "qmw-sup", + "useFlexLayout": true, + "widgets": { + "comp1": { + "comp": "agentx-wc-quality-monitoring-widget", + "width": 12, + "height": 19, + "wrapper": { + "title": "$I18N.qmw.recordings", + "id": "qmw-1", + "maximizeAreaName": "app-maximize-area" + }, + "properties": { + "isDarkMode": "$STORE.app.darkMode", + "isLoggedIntoStation": "$STORE.app.isStationLoginSuccess" + } + } + } + } + } + ] + } + }, + "supervisorAgent": { + "version": "0.1.0", + "appTitle": "Webex Contact Center", + "logo": "", + "stopNavigateOnAcceptTask": false, + "dragDropEnabled": false, + "notificationTimer": 8, + "maximumNotificationCount": 3, + "browserNotificationTimer": 8, + "wxmConfigured": false, + "desktopChatApp": { + "webexConfigured": false + }, + "area": { + "advancedHeader": [ + { + "comp": "agentx-webex" + }, + { + "comp": "agentx-outdial" + }, + { + "comp": "agentx-notification" + }, + { + "comp": "agentx-state-selector" + } + ], + "panel": { + "comp": "md-tabs", + "attributes": { + "class": "widget-tabs" + }, + "children": [ + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT_TAB" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "IVR_TRANSCRIPT" + } + } + ], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "WXM_JOURNEY_TAB" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "agentx-wc-cloudcherry-widget", + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "ani": "$STORE.agentContact.taskSelected.ani", + "isDarkMode": "$STORE.app.darkMode" + }, + "wrapper": { + "title": "Customer Experience Journey", + "maximizeAreaName": "app-maximize-area" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY_TAB" + } + } + ] + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "CONTACT_HISTORY" + } + } + ] + }, + { + "comp": "md-tab", + "attributes": { + "slot": "tab", + "class": "widget-pane-tab" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP_TAB" + } + } + ], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab-panel", + "attributes": { + "slot": "panel", + "class": "widget-pane" + }, + "children": [ + { + "comp": "slot", + "attributes": { + "name": "SCREEN_POP" + } + } + ], + "visibility": "SCREEN_POP" + } + ] + }, + "homepage": { + "nav": { + "label": "$I18N.common.homePageLabel", + "icon": "home", + "iconType": "momentum", + "navigateTo": "home", + "align": "top" + }, + "page": { + "id": "landing", + "useFlexLayout": true, + "pageHeader": { + "comp": "div", + "children": [ + { + "comp": "page-title", + "attributes": { + "pageTitle": "$STORE.page.getDefaultPageTitle" + } + } + ], + "attributes": { + "style": "margin: 25px 16px 25px 16px" + } + }, + "pageSubHeader": { + "comp": "div", + "attributes": { + "style": "display: flex; float:right" + }, + "children": [ + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.queueName", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-queue-filter", + "properties": { + "selectedQueueList": "$STORE.agent.selectedQueueList", + "managedQueues": "$STORE.agent.managedQueues", + "isLoading": "$STORE.agent.isManagedQueueLoading", + "isError": "$STORE.agent.isManagedQueuesError" + } + } + ], + "attributes": { + "style": "display:block;width:260px;" + } + }, + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.channelType", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-channel-filter", + "properties": { + "selectedChannelList": "$STORE.agent.selectedChannelList" + } + } + ], + "attributes": { + "style": "display:block;margin-left:16px;width:260px; " + } + }, + { + "comp": "div", + "children": [ + { + "comp": "md-label", + "textContent": "$I18N.pageSubHeader.managedTeams", + "attributes": { + "style": "margin-bottom:8px;" + } + }, + { + "comp": "agentx-wc-team-filter", + "properties": { + "selectedTeamList": "$STORE.agent.selectedTeamList", + "managedTeams": "$STORE.agent.managedTeams", + "isLoading": "$STORE.agent.isManagedTeamLoading", + "isError": "$STORE.agent.isManagedTeamsError" + } + } + ], + "attributes": { + "style": "display:block;margin-left:16px;width:260px;" + } + }, + { + "comp": "div", + "children": [ + { + "comp": "agentx-more-actions-wrapper", + "properties": { + "actionList": [ + { + "comp": "agentx-wc-goto-analyzer" + } + ] + } + } + ], + "attributes": { + "style": "display:block;margin-top: 20px;" + } + } + ] + }, + "widgets": { + "comp1": { + "comp": "analyzer-widget", + "width": 3, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "c04c307c-71fd-41f4-828f-a196f94ce08a" + } + }, + "comp2": { + "comp": "analyzer-widget", + "width": 3, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "bc3f908d-11fa-4f86-be9b-7edfe76eaa59" + } + }, + "comp3": { + "comp": "analyzer-widget", + "width": 3, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "3e4555a5-be23-46e6-8450-8ebf3f1c35e1" + } + }, + "comp4": { + "comp": "analyzer-widget", + "width": 3, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "2902a699-bf70-4568-afa1-6857db3e0dc4" + } + }, + "comp5": { + "comp": "analyzer-widget", + "width": 4, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "21716c3a-09a9-476a-bab1-5fbcff226ac6" + } + }, + "comp6": { + "comp": "analyzer-widget", + "width": 4, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "0136c56b-c40f-47a0-af1c-1a180db1fd64" + } + }, + "comp7": { + "comp": "analyzer-widget", + "width": 4, + "height": 5, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "e5e19275-0465-4e8c-923d-c9c06002330f" + } + }, + "comp8": { + "comp": "analyzer-widget", + "width": 6, + "height": 7, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "9d80a068-099c-48e3-b8a8-207eb38c47c5" + } + }, + "comp9": { + "comp": "analyzer-widget", + "width": 6, + "height": 7, + "attributes": { + "is-dark-mode": "$STORE.app.darkMode", + "filter": "$STORE.agent.analyzerInteractionFilter", + "access-token": "$STORE.auth.accessToken", + "user-id": "$STORE.agent.agentId", + "org-id": "$STORE.agent.orgId", + "dashboard-id": "a4e99697-06d8-4575-b25d-82ef348e2410", + "widget-id": "a0bbecca-0129-4649-9261-ef0fe69281aa" + } + } + } + } + }, + "navigation": [ + { + "nav": { + "label": "Customer Experience Analytics", + "icon": "/app/images/wxm.bcd45cc3.svg", + "iconType": "other", + "navigateTo": "wxm-metrics", + "align": "top" + }, + "page": { + "id": "wxm-metrics", + "widgets": { + "comp1": { + "comp": "agentx-wc-cloudcherry-widget", + "attributes": { + "metrics": true + }, + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "isDarkMode": "$STORE.app.darkMode", + "agentId": "$STORE.agent.agentId" + } + } + }, + "layout": { + "areas": [ + [ + "comp1" + ] + ], + "size": { + "cols": [ + 1 + ], + "rows": [ + 1 + ] + } + } + }, + "visibility": "WXM_METRICS" + }, + { + "nav": { + "label": "$I18N.tpw.widgetTitle", + "icon": "team", + "iconType": "momentum", + "navigateTo": "tpw", + "align": "top" + }, + "page": { + "id": "tpw-sup-agent", + "useFlexLayout": true, + "widgets": { + "comp1": { + "comp": "agentx-wc-team-performance-widget", + "width": 12, + "height": 19, + "wrapper": { + "title": "$I18N.tpw.widgetTitle", + "id": "tpw-1", + "maximizeAreaName": "app-maximize-area" + }, + "properties": { + "tpwConfigs": "$STORE.agent.tpwConfigs" + } + } + } + } + }, + { + "nav": { + "label": "$I18N.qmw.recordings", + "icon": "waveform", + "iconType": "momentum", + "navigateTo": "recordings", + "align": "top" + }, + "page": { + "id": "qmw-sup", + "useFlexLayout": true, + "widgets": { + "comp1": { + "comp": "agentx-wc-quality-monitoring-widget", + "width": 12, + "height": 19, + "wrapper": { + "title": "$I18N.qmw.recordings", + "id": "qmw-1", + "maximizeAreaName": "app-maximize-area" + }, + "properties": { + "isDarkMode": "$STORE.app.darkMode", + "isLoggedIntoStation": "$STORE.app.isStationLoginSuccess" + } + } + } + } + } + ] + } + } +} diff --git a/assets/files/Survey_wav.zip b/assets/files/Survey_wav.zip new file mode 100644 index 0000000000..8d8dd47325 Binary files /dev/null and b/assets/files/Survey_wav.zip differ diff --git a/assets/files/flow_template.json b/assets/files/flow_template.json new file mode 100644 index 0000000000..b71171a715 --- /dev/null +++ b/assets/files/flow_template.json @@ -0,0 +1 @@ +{"orgId":"0228104d-cc26-442d-a829-5eb403bf919b","version":0,"id":"63f7abc130072469e75be481","name":"flow_template","description":"","comment":null,"variables":[],"process":{"activities":{"49adc68c-1f86-426b-ae33-1a3dd227551a":{"id":"49adc68c-1f86-426b-ae33-1a3dd227551a","name":"NewPhoneContact","group":"start","properties":{"name":"NewPhoneContact","activityName":"NewPhoneContact","activityId":"start","event":"NewPhoneContact","_renderRequestTimestamp":1677175736655,"flowType":{"eventSourceId":"5eff0e2eb10162499bc9f932","eventClassificationId":"5f10475cf021306e89e1692c","eventSpecificationId":"5f2d02144332507e39cc8a7f","eventSourceName":"WebexContactCenter","eventClassificationName":"VoiceInteractions","eventSpecificationName":"ContactStartWorkflow"}}},"933f3b55-dd95-4228-a250-d36640aa2ce7":{"id":"933f3b55-dd95-4228-a250-d36640aa2ce7","name":"PlayMessage_ca8","group":"action","properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"play-message","description":"","toggle":false,"activityId":"5f114466ef5cfc454fbbf131","connector":null,"name":"PlayMessage_ca8","toggleLanguage":null,"_renderRequestTimestamp":1677175736655,"prompts":[],"promptsTts":null}},"abedcc1a-6c73-46e2-863d-735ee2c8efb0":{"id":"abedcc1a-6c73-46e2-863d-735ee2c8efb0","name":"QueueContact_ypp","group":"action","properties":{"fallbackQueue":null,"queueRadioGroup":"staticQueue","destination":null,"activityName":"queue-contact","description":"","toggle":false,"priority":null,"agentAvailabilityRadioGroup":null,"priorityRadioGroup":null,"skills":null,"activityId":"5f114550ef5cfc454fbbf133","priorityVariable":null,"destinationVariable":null,"name":"QueueContact_ypp","toggleAgentAvailability":false,"agentAvailabilityVariable":null,"_renderRequestTimestamp":1677175736655}},"770dda5b-2e2c-4ebf-bf08-b3aa651e320a":{"id":"770dda5b-2e2c-4ebf-bf08-b3aa651e320a","name":"PlayMusic_q5r","group":"action","properties":{"duration":null,"activityId":"5faa2ad13505f538acc86afc","prompt:type":null,"name":"PlayMusic_q5r","activityName":"play-music","description":"","prompt_type":null,"skip":0,"_renderRequestTimestamp":1677175736655,"prompt":"defaultmusic_on_hold.wav","promptDynamic":null,"audioRadioGroup":"staticAudio"}}},"links":[{"id":"95fe1b9d-c447-4051-89e4-dfa2f49c34da","sourceActivityId":"49adc68c-1f86-426b-ae33-1a3dd227551a","targetActivityId":"933f3b55-dd95-4228-a250-d36640aa2ce7","conditionExpr":"out","properties":{"value":"out"}},{"id":"e6d6c069-8c0e-471b-8087-8e10b9116255","sourceActivityId":"933f3b55-dd95-4228-a250-d36640aa2ce7","targetActivityId":"abedcc1a-6c73-46e2-863d-735ee2c8efb0","conditionExpr":"default","properties":{"value":"default"}},{"id":"06ae50c0-dc88-4990-b3b3-257303f286b1","sourceActivityId":"abedcc1a-6c73-46e2-863d-735ee2c8efb0","targetActivityId":"770dda5b-2e2c-4ebf-bf08-b3aa651e320a","conditionExpr":"default","properties":{"value":"default"}},{"id":"00281e31-ca39-45ab-a169-69d4becbcd20","sourceActivityId":"770dda5b-2e2c-4ebf-bf08-b3aa651e320a","targetActivityId":"770dda5b-2e2c-4ebf-bf08-b3aa651e320a","conditionExpr":"default","properties":{"value":"default"}}]},"diagram":{"widgets":{"49adc68c-1f86-426b-ae33-1a3dd227551a":{"id":"6cc27bcb-b374-49e1-a1dc-515888d61c8e","type":"start","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":100},"ports":[{"portId":"18b53c83-24af-41f6-9d36-34926e857c71","isSourcePort":false,"linkId":"0f590a79-ebff-4a4a-a2bf-02610c0f6243","type":"arrow","links":["0f590a79-ebff-4a4a-a2bf-02610c0f6243"],"properties":{"x":267,"name":"out","y":118,"label":"out","alignment":"right"}}],"properties":{"name":"NewPhoneContact","activityName":"NewPhoneContact","activityId":"start","event":"NewPhoneContact","_renderRequestTimestamp":1677175736655,"flowType":{"eventSourceId":"5eff0e2eb10162499bc9f932","eventClassificationId":"5f10475cf021306e89e1692c","eventSpecificationId":"5f2d02144332507e39cc8a7f","eventSourceName":"WebexContactCenter","eventClassificationName":"VoiceInteractions","eventSpecificationName":"ContactStartWorkflow"}}},"933f3b55-dd95-4228-a250-d36640aa2ce7":{"id":"f3284395-3a39-4b21-9863-b0f689c90286","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":402,"y":101},"ports":[{"portId":"1e2e24fc-4d6c-480a-b3c1-d0b059e9d539","isSourcePort":true,"linkId":"0f590a79-ebff-4a4a-a2bf-02610c0f6243","type":"arrow","links":["0f590a79-ebff-4a4a-a2bf-02610c0f6243"],"properties":{"x":394,"name":"in","y":119,"label":"in","alignment":"left"}},{"portId":"af61a546-272d-41cc-bbfc-5d9ba607d7e5","isSourcePort":false,"linkId":"fd7f78af-056b-4818-a8f7-568eaa37a069","type":"arrow","links":["fd7f78af-056b-4818-a8f7-568eaa37a069"],"properties":{"x":569,"name":"default","y":119,"label":"default","alignment":"right"}},{"portId":"8eb8cc6e-0e46-4143-9db7-d664b815037d","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":569.5,"name":"error","y":212.2833251953125,"label":"error","alignment":"right"}}],"properties":{"volumeGainDb":null,"speakingRate":null,"voiceLanguage":null,"activityName":"play-message","description":"","toggle":false,"activityId":"5f114466ef5cfc454fbbf131","connector":null,"name":"PlayMessage_ca8","toggleLanguage":null,"_renderRequestTimestamp":1677175736655,"prompts":[],"promptsTts":null}},"95fe1b9d-c447-4051-89e4-dfa2f49c34da":{"id":"0f590a79-ebff-4a4a-a2bf-02610c0f6243","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"c5dafc67-48b1-42fe-a205-84e55bd19ffa","type":"point","x":275,"y":126.5},{"id":"f4a17bd9-b5cd-4f19-8241-99d496439fa8","type":"point","x":295,"y":126.5},{"id":"01473bc6-24f3-492a-b6f1-2a880b2ad698","type":"point","x":295,"y":127.5},{"id":"0568a410-35fe-4421-a80a-d9b2bce09491","type":"point","x":400,"y":127.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"18b53c83-24af-41f6-9d36-34926e857c71","activeWidgetId":"6cc27bcb-b374-49e1-a1dc-515888d61c8e","point":{"x":275,"y":126}},"targetPort":{"id":"1e2e24fc-4d6c-480a-b3c1-d0b059e9d539","activeWidgetId":"f3284395-3a39-4b21-9863-b0f689c90286","point":{"x":400,"y":127}}},"abedcc1a-6c73-46e2-863d-735ee2c8efb0":{"id":"714b3d1b-a44d-4e9d-80de-01f8cd14f61b","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":664,"y":101},"ports":[{"portId":"d3a6f78c-8930-4fb3-a17a-edabdaf38bb1","isSourcePort":true,"linkId":"fd7f78af-056b-4818-a8f7-568eaa37a069","type":"arrow","links":["fd7f78af-056b-4818-a8f7-568eaa37a069"],"properties":{"x":656,"name":"in","y":119,"label":"in","alignment":"left"}},{"portId":"92a3e2a5-de65-49c4-832e-196b9bb76840","isSourcePort":false,"linkId":"0630ef20-c6cb-4199-b445-94a80b08b575","type":"arrow","links":["0630ef20-c6cb-4199-b445-94a80b08b575"],"properties":{"x":831,"name":"default","y":119,"label":"default","alignment":"right"}},{"portId":"8872a948-55e3-4f1f-8883-fecea34bd1c9","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":831.5,"name":"failure","y":212.2833251953125,"label":"failure","alignment":"right"}}],"properties":{"fallbackQueue":null,"queueRadioGroup":"staticQueue","destination":null,"activityName":"queue-contact","description":"","toggle":false,"priority":null,"agentAvailabilityRadioGroup":null,"priorityRadioGroup":null,"skills":null,"activityId":"5f114550ef5cfc454fbbf133","priorityVariable":null,"destinationVariable":null,"name":"QueueContact_ypp","toggleAgentAvailability":false,"agentAvailabilityVariable":null,"_renderRequestTimestamp":1677175736655}},"e6d6c069-8c0e-471b-8087-8e10b9116255":{"id":"fd7f78af-056b-4818-a8f7-568eaa37a069","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"efb2ab58-9460-46fb-993e-370cdc0840d0","type":"point","x":577,"y":127.5},{"id":"270edd51-2108-4c98-8304-3f904e2619df","type":"point","x":600,"y":127.5},{"id":"4722363f-6742-41ff-9020-bb757f8bdb05","type":"point","x":600,"y":81},{"id":"d44265a0-3615-40fc-a4a4-f86ec8eb9775","type":"point","x":644.5,"y":81},{"id":"d4faba28-c4bd-4151-977b-c929150c37cc","type":"point","x":644.5,"y":127.5},{"id":"de7e8177-8b8e-4624-9eff-ba1c17f5d6bf","type":"point","x":660,"y":127.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"af61a546-272d-41cc-bbfc-5d9ba607d7e5","activeWidgetId":"f3284395-3a39-4b21-9863-b0f689c90286","point":{"x":577,"y":127}},"targetPort":{"id":"d3a6f78c-8930-4fb3-a17a-edabdaf38bb1","activeWidgetId":"714b3d1b-a44d-4e9d-80de-01f8cd14f61b","point":{"x":660,"y":127}}},"770dda5b-2e2c-4ebf-bf08-b3aa651e320a":{"id":"4f59ea41-6cfd-4bcf-932b-36cc1b65a888","type":"action","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":960,"y":102},"ports":[{"portId":"fb40f487-03a0-4bdf-8fa3-caf5a44042bb","isSourcePort":true,"linkId":"0630ef20-c6cb-4199-b445-94a80b08b575","type":"arrow","links":["0630ef20-c6cb-4199-b445-94a80b08b575","fa6ea8f0-47eb-41fc-b857-4186677a446d"],"properties":{"x":952,"name":"in","y":120,"label":"in","alignment":"left"}},{"portId":"d530e2f6-e223-4a31-b5e8-6ad1aa698dfb","isSourcePort":false,"linkId":"fa6ea8f0-47eb-41fc-b857-4186677a446d","type":"arrow","links":["fa6ea8f0-47eb-41fc-b857-4186677a446d"],"properties":{"x":1127,"name":"default","y":120,"label":"default","alignment":"right"}},{"portId":"8a0dfd61-1112-4e8c-8f79-3d03bafae022","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":1127.5,"name":"error","y":213.26666259765625,"label":"error","alignment":"right"}}],"properties":{"duration":null,"activityId":"5faa2ad13505f538acc86afc","prompt:type":null,"name":"PlayMusic_q5r","activityName":"play-music","description":"","skip":0,"_renderRequestTimestamp":1677175736655,"prompt":"defaultmusic_on_hold.wav","promptDynamic":null,"audioRadioGroup":"staticAudio"}},"06ae50c0-dc88-4990-b3b3-257303f286b1":{"id":"0630ef20-c6cb-4199-b445-94a80b08b575","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"09204b63-863e-4c48-a520-687022c4899a","type":"point","x":839,"y":127.5},{"id":"9116caf6-1ecf-4181-8114-d68121b2d388","type":"point","x":860,"y":127.5},{"id":"7f3dc664-3151-4d58-afab-ef70a0978c5b","type":"point","x":860,"y":82},{"id":"00fe3b7e-20f7-424e-b4d7-5009d1d7b292","type":"point","x":940.5,"y":82},{"id":"980b7265-498b-462a-a4c1-9927a2c56c13","type":"point","x":940.5,"y":128.5},{"id":"f148b66f-6ae0-4941-843b-da8683b0d2ba","type":"point","x":960.5,"y":128.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"92a3e2a5-de65-49c4-832e-196b9bb76840","activeWidgetId":"714b3d1b-a44d-4e9d-80de-01f8cd14f61b","point":{"x":839,"y":127}},"targetPort":{"id":"fb40f487-03a0-4bdf-8fa3-caf5a44042bb","activeWidgetId":"4f59ea41-6cfd-4bcf-932b-36cc1b65a888","point":{"x":960,"y":128}}},"00281e31-ca39-45ab-a169-69d4becbcd20":{"id":"fa6ea8f0-47eb-41fc-b857-4186677a446d","type":"arrow","widgetType":"link","label":"","properties":{"curvyness":50,"selected":false,"color":"gray","points":[{"id":"7a9a3605-ac24-4766-95c6-f68d8bc048fc","type":"point","x":1135,"y":128.5},{"id":"1dcd93cc-b57b-4a00-9eee-693d26d78666","type":"point","x":1155,"y":128.5},{"id":"93fc89aa-215e-4407-9ec1-74d8eadba0cc","type":"point","x":1155,"y":82},{"id":"81ee5406-2641-4192-821c-1754544f8ff1","type":"point","x":940.5,"y":82},{"id":"137c54be-fe70-4229-b3da-10acaf3eabec","type":"point","x":940.5,"y":128.5},{"id":"4e56b7ec-a77c-41b7-b510-3b8c571d0910","type":"point","x":960,"y":128.5}],"width":1,"selectedColor":"rgb(0,192,255)"},"points":[],"sourcePort":{"id":"d530e2f6-e223-4a31-b5e8-6ad1aa698dfb","activeWidgetId":"4f59ea41-6cfd-4bcf-932b-36cc1b65a888","point":{"x":1135,"y":128}},"targetPort":{"id":"fb40f487-03a0-4bdf-8fa3-caf5a44042bb","activeWidgetId":"4f59ea41-6cfd-4bcf-932b-36cc1b65a888","point":{"x":960,"y":128}}}},"properties":{"offsetX":0,"offsetY":0,"zoom":50,"gridSize":0}},"flowId":"63f7ab457fd2791318c23a39","eventFlows":{"eventsMap":{"GLOBAL_EVENTS":{"id":"GLOBAL_EVENTS","name":"name","description":"description","process":{"activities":{"2445d96a-a195-448b-aa51-26580d5be5ec":{"id":"2445d96a-a195-448b-aa51-26580d5be5ec","name":"ContactEnded","group":"event","properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5f354a336fb8c44e97ccb30e","eventSourceName":"WebexContactCenter","displayName":"PhoneContactEnded","iconDiagram":"icon-handset-muted_16","eventSpecificationName":"ContactEnded","name":"ContactEnded","eventClassificationId":"5f10475cf021306e89e1692c","event":"PhoneContactEnded","_renderRequestTimestamp":1677175736655,"eventClassificationName":"VoiceInteractions"}},"de844d6a-1da1-48c7-9464-840508b95d21":{"id":"de844d6a-1da1-48c7-9464-840508b95d21","name":"FCAsk(ContactLastAgentRemoved)","group":"event","properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5ffeafa86a7eff72a481c4b5","eventSourceName":"WebexContactCenter","displayName":"AgentDisconnected","iconDiagram":"icon-headset-muted_16","eventSpecificationName":"FCAsk(ContactLastAgentRemoved)","name":"FCAsk(ContactLastAgentRemoved)","eventClassificationId":"5f10475cf021306e89e1692c","event":"AgentDisconnected","_renderRequestTimestamp":1677175736655,"eventClassificationName":"VoiceInteractions"}},"e1d851be-8765-4e5d-a764-5802c03d5690":{"id":"e1d851be-8765-4e5d-a764-5802c03d5690","name":"GlobalErrorHandling","group":"event","properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"627c0663e98eca854178bba6","eventSourceName":"WebexContactCenter","displayName":"OnGlobalError","iconDiagram":"icon-error-legacy_16","eventSpecificationName":"GlobalErrorHandling","name":"GlobalErrorHandling","eventClassificationId":"5f10475cf021306e89e1692c","event":"OnGlobalError","_renderRequestTimestamp":1677175736655,"eventClassificationName":"VoiceInteractions"}},"9f9a42fe-0411-4103-88f2-9e4fd89ed817":{"id":"9f9a42fe-0411-4103-88f2-9e4fd89ed817","name":"AgentContactAssigned","group":"event","properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5f354a0c6fb8c44e97ccb30d","eventSourceName":"WebexContactCenter","displayName":"AgentAnswered","iconDiagram":"icon-headset_16","eventSpecificationName":"AgentContactAssigned","name":"AgentContactAssigned","eventClassificationId":"5f10475cf021306e89e1692c","event":"AgentAnswered","_renderRequestTimestamp":1677175736655,"eventClassificationName":"VoiceInteractions"}}},"links":[]},"onEvents":{"GlobalErrorHandling":"e1d851be-8765-4e5d-a764-5802c03d5690","AgentContactAssigned":"9f9a42fe-0411-4103-88f2-9e4fd89ed817","ContactEnded":"2445d96a-a195-448b-aa51-26580d5be5ec","FCAsk(ContactLastAgentRemoved)":"de844d6a-1da1-48c7-9464-840508b95d21"},"diagram":{"widgets":{"e1d851be-8765-4e5d-a764-5802c03d5690":{"id":"b77f3d39-ba30-4048-9547-bc1189433e73","type":"event","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":115},"ports":[{"portId":"f272a432-d97c-4939-a198-567b052f54e0","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":100,"name":"out","y":115,"label":"out","alignment":"right"}}],"properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"627c0663e98eca854178bba6","eventSourceName":"WebexContactCenter","displayName":"OnGlobalError","iconDiagram":"icon-error-legacy_16","eventSpecificationName":"GlobalErrorHandling","name":"GlobalErrorHandling","eventClassificationId":"5f10475cf021306e89e1692c","event":"OnGlobalError","_renderRequestTimestamp":1677175736655,"eventClassificationName":"VoiceInteractions"}},"9f9a42fe-0411-4103-88f2-9e4fd89ed817":{"id":"7c3515db-0315-4643-a8ed-7c7bc1fca29d","type":"event","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":230},"ports":[{"portId":"82ad63d3-57c4-4ae8-aa28-d7ff867d3fae","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":100,"name":"out","y":230,"label":"out","alignment":"right"}}],"properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5f354a0c6fb8c44e97ccb30d","eventSourceName":"WebexContactCenter","displayName":"AgentAnswered","iconDiagram":"icon-headset_16","eventSpecificationName":"AgentContactAssigned","name":"AgentContactAssigned","eventClassificationId":"5f10475cf021306e89e1692c","event":"AgentAnswered","_renderRequestTimestamp":1677175736655,"eventClassificationName":"VoiceInteractions"}},"2445d96a-a195-448b-aa51-26580d5be5ec":{"id":"b5cdebdf-5187-45c5-a71b-00a8c14f1ce6","type":"event","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":345},"ports":[{"portId":"f73e7aa2-a5d5-46e2-810f-14b38acdfa4f","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":100,"name":"out","y":345,"label":"out","alignment":"right"}}],"properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5f354a336fb8c44e97ccb30e","eventSourceName":"WebexContactCenter","displayName":"PhoneContactEnded","iconDiagram":"icon-handset-muted_16","eventSpecificationName":"ContactEnded","name":"ContactEnded","eventClassificationId":"5f10475cf021306e89e1692c","event":"PhoneContactEnded","_renderRequestTimestamp":1677175736655,"eventClassificationName":"VoiceInteractions"}},"de844d6a-1da1-48c7-9464-840508b95d21":{"id":"cb76d83f-d0a2-4eba-9f50-6c0a4e88bcdf","type":"event","widgetType":"activity","label":"New Activity Widget in Diagram","point":{"x":100,"y":460},"ports":[{"portId":"5455e215-8fef-4892-8b31-ff6070071e6d","isSourcePort":false,"linkId":null,"type":"arrow","links":[],"properties":{"x":100,"name":"out","y":460,"label":"out","alignment":"right"}}],"properties":{"eventSourceId":"5eff0e2eb10162499bc9f932","activityId":"event","eventSpecificationId":"5ffeafa86a7eff72a481c4b5","eventSourceName":"WebexContactCenter","displayName":"AgentDisconnected","iconDiagram":"icon-headset-muted_16","eventSpecificationName":"FCAsk(ContactLastAgentRemoved)","name":"FCAsk(ContactLastAgentRemoved)","eventClassificationId":"5f10475cf021306e89e1692c","event":"AgentDisconnected","_renderRequestTimestamp":1677175736655,"eventClassificationName":"VoiceInteractions"}}},"properties":{}}}},"properties":{"offsetX":0,"offsetY":0,"zoom":0,"gridSize":0}},"runtimeVariables":[],"validating":false,"persist":true,"validationResults":[],"createdBy":"kevsimps_csam_americas@email.carehybrid.com","createdDate":"2023-02-23T18:08:56.577","lastModifiedDate":"2023-02-23T18:09:05.907","lastModifiedBy":"kevsimps_csam_americas@email.carehybrid.com","variableOrders":{"pop-over":[{"name":"ani","variableSeq":"0"},{"name":"dn","variableSeq":"1"},{"name":"virtualTeamName","variableSeq":"2"}],"interaction-panel":[]}} \ No newline at end of file diff --git a/assets/files/flow_template.json.zip b/assets/files/flow_template.json.zip new file mode 100644 index 0000000000..41845d7780 Binary files /dev/null and b/assets/files/flow_template.json.zip differ diff --git a/assets/files/lab_wav.zip b/assets/files/lab_wav.zip new file mode 100644 index 0000000000..43536c4640 Binary files /dev/null and b/assets/files/lab_wav.zip differ diff --git a/assets/gitbook/custom.css b/assets/gitbook/custom.css index 987906304f..d478acd000 100644 --- a/assets/gitbook/custom.css +++ b/assets/gitbook/custom.css @@ -1,269 +1,269 @@ ---- ---- - -.book-body { - overflow-y: scroll; -} - -.book-body .book-header { - position: fixed; - width: 100%; -} - -.book.with-summary .book-body .book-header { - position: fixed; - width: calc(100% - 300px); -} - -.book-body .body-inner { - /* position: absolute; */ - margin-top: 50px; - min-height: calc(100% - 50px); -} - -.book-body .body-inner .page-wrapper { - min-height: calc(100% - 46px); -} - -.book-body .body-inner .page-wrapper .page-inner { - padding-bottom: 20px; -} - -@media (max-width: 1240px) { - .book-body .body-inner .navigation { - max-width: calc(50% - 3px); - width: calc(50% - 3px); - } -} - -.book .book-body .book-header { - background: #ffffff; -} - -.book.color-theme-1 .book-body .book-header { - background: #f3eacb; -} - -.book.color-theme-2 .book-body .book-header { - background: #1c1f2b; -} - -.page-inner { - max-width: {{ site.page_width | default: '800px' }}; -} - -.back-to-top { - right: calc((100% - 300px - min(100% - 300px, {{ site.page_width | default: '800px' }})) / 2 + 25px); -} - -/* scrollbar */ -::-webkit-scrollbar { - width: 5px; - height: 5px; -} - -::-webkit-scrollbar-track-piece { - /* background-color: rgba(125, 125, 125, 0.2); */ - -webkit-border-radius: 6px; -} - -::-webkit-scrollbar-thumb:vertical { - height: 5px; - background-color: rgba(7, 17, 27, .2); - -webkit-border-radius: 6px; -} - -::-webkit-scrollbar-thumb:horizontal { - width: 5px; - background-color: rgba(125, 125, 125, 0.2); - -webkit-border-radius: 6px; -} - -/* Style for search page on mobile screens */ - -#book-search-input-link { - padding: 6px; - background: 0 0; - background: inherit; - transition: top .5s ease; - border-bottom: 1px solid rgba(0,0,0,.07); - border-top: 1px solid rgba(0,0,0,.07); - margin-bottom: 10px; - margin-top: -1px; -} - -#book-search-input-link a { - width: 100%; - background: 0 0; - border: 1px solid transparent; - box-shadow: none; - outline: 0; - line-height: 38px; - padding: 7px 7px; - color: #757575; -} - -#book-search-input { - display: block; -} -#book-search-input-link { - display: none; -} - -@media (max-width: 1240px) { - #book-search-input { - display: none; - } - #book-search-input-link { - display: block; - } -} - -#book-search-input-inside { - padding: 6px; - background: 0 0; - transition: top .5s ease; - background: #fff; - border-bottom: 1px solid rgba(0,0,0,.07); - border-top: 1px solid rgba(0,0,0,.07); - margin-bottom: 10px; - margin-top: -1px; -} - -#book-search-input-inside input { - width: 100%; - background: 0 0; - border: 1px solid transparent; - box-shadow: none; - outline: 0; - line-height: 22px; - padding: 7px 7px; - color: inherit; -} - - -/* Custom font settings */ - -.book.font-family-0 { - font-family: Georgia, serif; -} -.book.font-family-1 { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -} - -/* Render wide tables */ - -.table-wrapper { - overflow-x: scroll; -} - -/* Tips, warnings, and dangers */ - -.markdown-section blockquote.block-tip { - border-color: var(--c-tip); - background-color: var(--c-tip-bg); - color: var(--c-tip-text); - font-family: var(--font-family); -} - -.markdown-section blockquote.block-tip h1 { - color: var(--c-tip-title); -} - -.markdown-section blockquote.block-tip h2 { - color: var(--c-tip-title); -} - -.markdown-section blockquote.block-tip h3 { - color: var(--c-tip-title); -} - -.markdown-section blockquote.block-tip h4 { - color: var(--c-tip-title); -} - -.markdown-section blockquote.block-tip h5 { - color: var(--c-tip-title); -} - -.markdown-section blockquote.block-tip h6 { - color: var(--c-tip-title); -} - -.markdown-section blockquote.block-warning { - border-color: var(--c-warning); - background-color: var(--c-warning-bg); - color: var(--c-warning-text); - font-family: var(--font-family); -} - -.markdown-section blockquote.block-warning h1 { - color: var(--c-warning-title); -} - -.markdown-section blockquote.block-warning h2 { - color: var(--c-warning-title); -} - -.markdown-section blockquote.block-warning h3 { - color: var(--c-warning-title); -} - -.markdown-section blockquote.block-warning h4 { - color: var(--c-warning-title); -} - -.markdown-section blockquote.block-warning h5 { - color: var(--c-warning-title); -} - -.markdown-section blockquote.block-warning h6 { - color: var(--c-warning-title); -} - -.markdown-section blockquote.block-danger { - border-color: var(--c-danger); - background-color: var(--c-danger-bg); - color: var(--c-danger-text); - font-family: var(--font-family); -} - -.markdown-section blockquote.block-danger h1 { - color: var(--c-danger-title); -} - -.markdown-section blockquote.block-danger h2 { - color: var(--c-danger-title); -} - -.markdown-section blockquote.block-danger h3 { - color: var(--c-danger-title); -} - -.markdown-section blockquote.block-danger h4 { - color: var(--c-danger-title); -} - -.markdown-section blockquote.block-danger h5 { - color: var(--c-danger-title); -} - -.markdown-section blockquote.block-danger h6 { - color: var(--c-danger-title); -} - -:root { - --c-tip: #42b983; - --c-tip-bg: #e2f5ec; - --c-tip-text: #215d42; - --c-tip-title: #359469; - --c-warning: #e7c000; - --c-warning-bg: rgba(255, 229, 100, .25); - --c-warning-text: #6b5900; - --c-warning-title: #b29400; - --c-danger: #c00; - --c-danger-bg: #ffe0e0; - --c-danger-text: #600; - --c-danger-title: #c00; - --font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; -} +--- +--- + +.book-body { + overflow-y: scroll; +} + +.book-body .book-header { + position: fixed; + width: 100%; +} + +.book.with-summary .book-body .book-header { + position: fixed; + width: calc(100% - 300px); +} + +.book-body .body-inner { + /* position: absolute; */ + margin-top: 50px; + min-height: calc(100% - 50px); +} + +.book-body .body-inner .page-wrapper { + min-height: calc(100% - 46px); +} + +.book-body .body-inner .page-wrapper .page-inner { + padding-bottom: 20px; +} + +@media (max-width: 1240px) { + .book-body .body-inner .navigation { + max-width: calc(50% - 3px); + width: calc(50% - 3px); + } +} + +.book .book-body .book-header { + background: #ffffff; +} + +.book.color-theme-1 .book-body .book-header { + background: #f3eacb; +} + +.book.color-theme-2 .book-body .book-header { + background: #1c1f2b; +} + +.page-inner { + max-width: {{ site.page_width | default: '800px' }}; +} + +.back-to-top { + right: calc((100% - 300px - min(100% - 300px, {{ site.page_width | default: '800px' }})) / 2 + 25px); +} + +/* scrollbar */ +::-webkit-scrollbar { + width: 5px; + height: 5px; +} + +::-webkit-scrollbar-track-piece { + /* background-color: rgba(125, 125, 125, 0.2); */ + -webkit-border-radius: 6px; +} + +::-webkit-scrollbar-thumb:vertical { + height: 5px; + background-color: rgba(7, 17, 27, .2); + -webkit-border-radius: 6px; +} + +::-webkit-scrollbar-thumb:horizontal { + width: 5px; + background-color: rgba(125, 125, 125, 0.2); + -webkit-border-radius: 6px; +} + +/* Style for search page on mobile screens */ + +#book-search-input-link { + padding: 6px; + background: 0 0; + background: inherit; + transition: top .5s ease; + border-bottom: 1px solid rgba(0,0,0,.07); + border-top: 1px solid rgba(0,0,0,.07); + margin-bottom: 10px; + margin-top: -1px; +} + +#book-search-input-link a { + width: 100%; + background: 0 0; + border: 1px solid transparent; + box-shadow: none; + outline: 0; + line-height: 38px; + padding: 7px 7px; + color: #757575; +} + +#book-search-input { + display: block; +} +#book-search-input-link { + display: none; +} + +@media (max-width: 1240px) { + #book-search-input { + display: none; + } + #book-search-input-link { + display: block; + } +} + +#book-search-input-inside { + padding: 6px; + background: 0 0; + transition: top .5s ease; + background: #fff; + border-bottom: 1px solid rgba(0,0,0,.07); + border-top: 1px solid rgba(0,0,0,.07); + margin-bottom: 10px; + margin-top: -1px; +} + +#book-search-input-inside input { + width: 100%; + background: 0 0; + border: 1px solid transparent; + box-shadow: none; + outline: 0; + line-height: 22px; + padding: 7px 7px; + color: inherit; +} + + +/* Custom font settings */ + +.book.font-family-0 { + font-family: Georgia, serif; +} +.book.font-family-1 { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +/* Render wide tables */ + +.table-wrapper { + overflow-x: scroll; +} + +/* Tips, warnings, and dangers */ + +.markdown-section blockquote.block-tip { + border-color: var(--c-tip); + background-color: var(--c-tip-bg); + color: var(--c-tip-text); + font-family: var(--font-family); +} + +.markdown-section blockquote.block-tip h1 { + color: var(--c-tip-title); +} + +.markdown-section blockquote.block-tip h2 { + color: var(--c-tip-title); +} + +.markdown-section blockquote.block-tip h3 { + color: var(--c-tip-title); +} + +.markdown-section blockquote.block-tip h4 { + color: var(--c-tip-title); +} + +.markdown-section blockquote.block-tip h5 { + color: var(--c-tip-title); +} + +.markdown-section blockquote.block-tip h6 { + color: var(--c-tip-title); +} + +.markdown-section blockquote.block-warning { + border-color: var(--c-warning); + background-color: var(--c-warning-bg); + color: var(--c-warning-text); + font-family: var(--font-family); +} + +.markdown-section blockquote.block-warning h1 { + color: var(--c-warning-title); +} + +.markdown-section blockquote.block-warning h2 { + color: var(--c-warning-title); +} + +.markdown-section blockquote.block-warning h3 { + color: var(--c-warning-title); +} + +.markdown-section blockquote.block-warning h4 { + color: var(--c-warning-title); +} + +.markdown-section blockquote.block-warning h5 { + color: var(--c-warning-title); +} + +.markdown-section blockquote.block-warning h6 { + color: var(--c-warning-title); +} + +.markdown-section blockquote.block-danger { + border-color: var(--c-danger); + background-color: var(--c-danger-bg); + color: var(--c-danger-text); + font-family: var(--font-family); +} + +.markdown-section blockquote.block-danger h1 { + color: var(--c-danger-title); +} + +.markdown-section blockquote.block-danger h2 { + color: var(--c-danger-title); +} + +.markdown-section blockquote.block-danger h3 { + color: var(--c-danger-title); +} + +.markdown-section blockquote.block-danger h4 { + color: var(--c-danger-title); +} + +.markdown-section blockquote.block-danger h5 { + color: var(--c-danger-title); +} + +.markdown-section blockquote.block-danger h6 { + color: var(--c-danger-title); +} + +:root { + --c-tip: #42b983; + --c-tip-bg: #c1d5cbd1; + --c-tip-text: #06100b; + --c-tip-title: #359469; + --c-warning: #e7c000; + --c-warning-bg: rgba(255, 229, 100, .65); + --c-warning-text: #010100; + --c-warning-title: #b29400; + --c-danger: #c00; + --c-danger-bg: #dfacac9c; + --c-danger-text: #060303; + --c-danger-title: #c00; + --font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; +} diff --git a/assets/gitbook/form.js b/assets/gitbook/form.js new file mode 100644 index 0000000000..c7b9ad9e2c --- /dev/null +++ b/assets/gitbook/form.js @@ -0,0 +1,31 @@ +// Get the form and its inputs + const form = document.getElementById('AttendeeForm'); + const nameInput = document.getElementById('name'); + const emailInput = document.getElementById('email'); + +// Check if there is data in local storage + const storedData = localStorage.getItem('myFormData'); + if (storedData) { + const parsedData = JSON.parse(storedData); + nameInput.value = parsedData.name; + emailInput.value = parsedData.email; + } + +// Add an event listener for the form submission + form.addEventListener('submit', function(event) { + event.preventDefault(); // Prevent the default form submission + +// Get the form data and store it in local storage + const formData = { + name: nameInput.value, + email: emailInput.value + }; + localStorage.setItem('myFormData', JSON.stringify(formData)); + +// Display a message indicating that the data was saved + const message = document.getElementById('message'); + message.textContent = 'Values updated!'; + +// Reset the form + form.reset(); + }); diff --git a/assets/gitbook/gitbook-plugin-back-to-top-button/plugin.css b/assets/gitbook/gitbook-plugin-back-to-top-button/plugin.css index 7b00e367f2..779149d781 100644 --- a/assets/gitbook/gitbook-plugin-back-to-top-button/plugin.css +++ b/assets/gitbook/gitbook-plugin-back-to-top-button/plugin.css @@ -1,55 +1,55 @@ -.back-to-top { - position: fixed; - bottom: 25px; - right: calc((100% - 300px - min(100% - 300px, 800px)) / 2 + 25px); - background: rgba(0, 0, 0, 0.5); - width: 50px; - height: 50px; - display: block; - text-decoration: none; - -webkit-border-radius: 35px; - -moz-border-radius: 35px; - border-radius: 35px; - display: none; -} -.back-to-top i { - color: #fff; - margin: 0; - position: relative; - left: 15px; - top: 14px; - font-size: 22px; -} -.back-to-top:hover { - background: rgba(0, 0, 0, 0.9); - cursor: pointer; -} -.book.color-theme-1 .back-to-top { - background: rgba(112, 66, 20, 0.5); -} -.book.color-theme-1 .back-to-top i { - color: #f3eacb; -} -.book.color-theme-1 .back-to-top:hover { - background: rgba(112, 66, 20, 0.9); -} -.book.color-theme-2 .back-to-top { - background: rgba(189, 202, 219, 0.5); -} -.book.color-theme-2 .back-to-top i { - color: #1C1F2B; -} -.book.color-theme-2 .back-to-top:hover { - background: rgba(189, 202, 219, 0.9); -} - -@media only screen - and (min-device-width: 320px) - and (max-device-width: 480px) - and (-webkit-min-device-pixel-ratio: 2) - and (orientation: portrait) { - .back-to-top { - bottom: 10px; - right: 10px; - } -} +.back-to-top { + position: fixed; + bottom: 25px; + right: calc((100% - 300px - min(100% - 300px, 800px)) / 2 + 25px); + background: rgba(0, 0, 0, 0.5); + width: 50px; + height: 50px; + display: block; + text-decoration: none; + -webkit-border-radius: 35px; + -moz-border-radius: 35px; + border-radius: 35px; + display: none; +} +.back-to-top i { + color: #fff; + margin: 0; + position: relative; + left: 15px; + top: 14px; + font-size: 22px; +} +.back-to-top:hover { + background: rgba(0, 0, 0, 0.9); + cursor: pointer; +} +.book.color-theme-1 .back-to-top { + background: rgba(112, 66, 20, 0.5); +} +.book.color-theme-1 .back-to-top i { + color: #f3eacb; +} +.book.color-theme-1 .back-to-top:hover { + background: rgba(112, 66, 20, 0.9); +} +.book.color-theme-2 .back-to-top { + background: rgba(189, 202, 219, 0.5); +} +.book.color-theme-2 .back-to-top i { + color: #1C1F2B; +} +.book.color-theme-2 .back-to-top:hover { + background: rgba(189, 202, 219, 0.9); +} + +@media only screen + and (min-device-width: 320px) + and (max-device-width: 480px) + and (-webkit-min-device-pixel-ratio: 2) + and (orientation: portrait) { + .back-to-top { + bottom: 10px; + right: 10px; + } +} diff --git a/assets/gitbook/gitbook-plugin-back-to-top-button/plugin.js b/assets/gitbook/gitbook-plugin-back-to-top-button/plugin.js index e3b80dadec..d4ecc1deec 100644 --- a/assets/gitbook/gitbook-plugin-back-to-top-button/plugin.js +++ b/assets/gitbook/gitbook-plugin-back-to-top-button/plugin.js @@ -1,32 +1,32 @@ -require([ - 'gitbook', - 'jquery' -], function(gitbook, $) { - gitbook.events.on('page.change', function() { - var back_to_top_button = ['
    '].join(""); - $(".page-wrapper").append(back_to_top_button) - - $(".back-to-top").hide(); - - $(".back-to-top").hover(function() { - $(this).css('cursor', 'pointer').attr('title', 'Back to top'); - }, function() { - $(this).css('cursor', 'auto'); - }); - - $('.book-body,.body-inner,.page-wrapper').on('scroll', function () { - if ($(this).scrollTop() > 100) { - $('.back-to-top').fadeIn(); - } else { - $('.back-to-top').fadeOut(); - } - }); - - $('.back-to-top').on('click', function () { - $('.book-body,.body-inner').animate({ - scrollTop: 0 - }, 800); - return false; - }); - }); -}); +require([ + 'gitbook', + 'jquery' +], function(gitbook, $) { + gitbook.events.on('page.change', function() { + var back_to_top_button = ['
    '].join(""); + $(".page-wrapper").append(back_to_top_button) + + $(".back-to-top").hide(); + + $(".back-to-top").hover(function() { + $(this).css('cursor', 'pointer').attr('title', 'Back to top'); + }, function() { + $(this).css('cursor', 'auto'); + }); + + $('.book-body,.body-inner,.page-wrapper').on('scroll', function () { + if ($(this).scrollTop() > 100) { + $('.back-to-top').fadeIn(); + } else { + $('.back-to-top').fadeOut(); + } + }); + + $('.back-to-top').on('click', function () { + $('.book-body,.body-inner').animate({ + scrollTop: 0 + }, 800); + return false; + }); + }); +}); diff --git a/assets/gitbook/gitbook-plugin-chapter-fold/chapter-fold.css b/assets/gitbook/gitbook-plugin-chapter-fold/chapter-fold.css index d3945cf4ff..9b3aea3b3b 100644 --- a/assets/gitbook/gitbook-plugin-chapter-fold/chapter-fold.css +++ b/assets/gitbook/gitbook-plugin-chapter-fold/chapter-fold.css @@ -1,28 +1,28 @@ -.book .book-summary .chapter > .articles { - overflow: hidden; - max-height: 0px; -} - -.book .book-summary .chapter.expanded > .articles { - max-height: 9999px; -} - -.book .book-summary .exc-trigger { - position: absolute; - left: 12px; - top: 12px; -} - -.book .book-summary ul.summary li a, -.book .book-summary ul.summary li span { - padding-left: 30px; -} - -.book .book-summary .exc-trigger:before { - content: "\f105"; -} - -.book .book-summary .expanded > a .exc-trigger:before, -.book .book-summary .expanded > span .exc-trigger:before { - content: "\f107"; -} +.book .book-summary .chapter > .articles { + overflow: hidden; + max-height: 0px; +} + +.book .book-summary .chapter.expanded > .articles { + max-height: 9999px; +} + +.book .book-summary .exc-trigger { + position: absolute; + left: 12px; + top: 12px; +} + +.book .book-summary ul.summary li a, +.book .book-summary ul.summary li span { + padding-left: 30px; +} + +.book .book-summary .exc-trigger:before { + content: "\f105"; +} + +.book .book-summary .expanded > a .exc-trigger:before, +.book .book-summary .expanded > span .exc-trigger:before { + content: "\f107"; +} diff --git a/assets/gitbook/gitbook-plugin-chapter-fold/chapter-fold.js b/assets/gitbook/gitbook-plugin-chapter-fold/chapter-fold.js index a80a92152e..0a75189972 100644 --- a/assets/gitbook/gitbook-plugin-chapter-fold/chapter-fold.js +++ b/assets/gitbook/gitbook-plugin-chapter-fold/chapter-fold.js @@ -1,67 +1,67 @@ -require(['gitbook', 'jQuery'], function(gitbook, $) { - var TOGGLE_CLASSNAME = 'expanded', - CHAPTER = '.chapter', - ARTICLES = '.articles', - TRIGGER_TEMPLATE = '', - LS_NAMESPACE = 'expChapters'; - var init = function () { - // adding the trigger element to each ARTICLES parent and binding the event - var chapterLink = $(ARTICLES).parent(CHAPTER).children('a'); - chapterLink.append($(TRIGGER_TEMPLATE)); - chapterLink.on('click', function (e) { - e.preventDefault(); - //e.stopPropagation(); - toggle($(e.target).closest(CHAPTER)); - }); - - expand(lsItem()); - //expand current selected chapter with it's parents - collapse($(CHAPTER)); - var activeChapter = $(CHAPTER + '.active'); - expand(activeChapter); - expand(activeChapter.parents(CHAPTER)); - } - //on page.change will happend the function. - - var toggle = function ($chapter) { - if ($chapter.hasClass('expanded')) { - collapse($chapter); - } else { - expand($chapter); - //$chapter.addClass('active').siblings().removeClass('active'); - } - } - var collapse = function ($chapter) { - if ($chapter.length && $chapter.hasClass(TOGGLE_CLASSNAME)) { - $chapter.removeClass(TOGGLE_CLASSNAME); - lsItem($chapter); - } - } - var expand = function ($chapter) { - if ($chapter.length && !$chapter.hasClass(TOGGLE_CLASSNAME)) { - $chapter.addClass(TOGGLE_CLASSNAME); - lsItem($chapter); - } - } - var lsItem = function () { - var map = JSON.parse(localStorage.getItem(LS_NAMESPACE)) || {} - if (arguments.length) { - var $chapters = arguments[0]; - $chapters.each(function (index, element) { - var level = $(this).data('level'); - var value = $(this).hasClass(TOGGLE_CLASSNAME); - map[level] = value; - }) - localStorage.setItem(LS_NAMESPACE, JSON.stringify(map)); - } else { - return $(CHAPTER).map(function(index, element){ - if (map[$(this).data('level')]) { - return this; - } - }) - } - } - gitbook.events.bind('page.change', function() { - init() - }); -}); +require(['gitbook', 'jQuery'], function(gitbook, $) { + var TOGGLE_CLASSNAME = 'expanded', + CHAPTER = '.chapter', + ARTICLES = '.articles', + TRIGGER_TEMPLATE = '', + LS_NAMESPACE = 'expChapters'; + var init = function () { + // adding the trigger element to each ARTICLES parent and binding the event + var chapterLink = $(ARTICLES).parent(CHAPTER).children('a'); + chapterLink.append($(TRIGGER_TEMPLATE)); + chapterLink.on('click', function (e) { + e.preventDefault(); + //e.stopPropagation(); + toggle($(e.target).closest(CHAPTER)); + }); + + expand(lsItem()); + //expand current selected chapter with it's parents + collapse($(CHAPTER)); + var activeChapter = $(CHAPTER + '.active'); + expand(activeChapter); + expand(activeChapter.parents(CHAPTER)); + } + //on page.change will happend the function. + + var toggle = function ($chapter) { + if ($chapter.hasClass('expanded')) { + collapse($chapter); + } else { + expand($chapter); + //$chapter.addClass('active').siblings().removeClass('active'); + } + } + var collapse = function ($chapter) { + if ($chapter.length && $chapter.hasClass(TOGGLE_CLASSNAME)) { + $chapter.removeClass(TOGGLE_CLASSNAME); + lsItem($chapter); + } + } + var expand = function ($chapter) { + if ($chapter.length && !$chapter.hasClass(TOGGLE_CLASSNAME)) { + $chapter.addClass(TOGGLE_CLASSNAME); + lsItem($chapter); + } + } + var lsItem = function () { + var map = JSON.parse(localStorage.getItem(LS_NAMESPACE)) || {} + if (arguments.length) { + var $chapters = arguments[0]; + $chapters.each(function (index, element) { + var level = $(this).data('level'); + var value = $(this).hasClass(TOGGLE_CLASSNAME); + map[level] = value; + }) + localStorage.setItem(LS_NAMESPACE, JSON.stringify(map)); + } else { + return $(CHAPTER).map(function(index, element){ + if (map[$(this).data('level')]) { + return this; + } + }) + } + } + gitbook.events.bind('page.change', function() { + init() + }); +}); diff --git a/assets/gitbook/gitbook-plugin-sharing/buttons.js b/assets/gitbook/gitbook-plugin-sharing/buttons.js index c8f819b1ff..c8bf4947b2 100644 --- a/assets/gitbook/gitbook-plugin-sharing/buttons.js +++ b/assets/gitbook/gitbook-plugin-sharing/buttons.js @@ -5,7 +5,7 @@ require(['gitbook', 'jquery'], function(gitbook, $) { 'icon': 'fa fa-facebook', 'onClick': function(e) { e.preventDefault(); - window.open('http://www.facebook.com/sharer/sharer.php?s=100&p[url]='+encodeURIComponent(location.href)); + window.open('https://www.facebook.com/webex'); } }, 'twitter': { @@ -13,7 +13,7 @@ require(['gitbook', 'jquery'], function(gitbook, $) { 'icon': 'fa fa-twitter', 'onClick': function(e) { e.preventDefault(); - window.open('http://twitter.com/home?status='+encodeURIComponent(document.title+' '+location.href)); + window.open('https://twitter.com/Webex'); } }, 'github': { diff --git a/assets/gitbook/images/Home.jpeg b/assets/gitbook/images/Home.jpeg new file mode 100644 index 0000000000..a545eb30c8 Binary files /dev/null and b/assets/gitbook/images/Home.jpeg differ diff --git a/assets/gitbook/images/favicon.ico b/assets/gitbook/images/favicon.ico index 9ee99fa211..00565e5f0c 100644 Binary files a/assets/gitbook/images/favicon.ico and b/assets/gitbook/images/favicon.ico differ diff --git a/assets/gitbook/images/webex-small.png b/assets/gitbook/images/webex-small.png new file mode 100644 index 0000000000..d5f4729429 Binary files /dev/null and b/assets/gitbook/images/webex-small.png differ diff --git a/assets/gitbook/images/webex.png b/assets/gitbook/images/webex.png new file mode 100644 index 0000000000..5f5a59804d Binary files /dev/null and b/assets/gitbook/images/webex.png differ diff --git a/assets/gitbook/rouge/base16.css b/assets/gitbook/rouge/base16.css index 51a33fe590..23412390b7 100644 --- a/assets/gitbook/rouge/base16.css +++ b/assets/gitbook/rouge/base16.css @@ -1,80 +1,80 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight, .highlight .w { - color: #303030; -} -.highlight .err { - color: #151515; - background-color: #ac4142; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { - color: #505050; -} -.highlight .cp { - color: #f4bf75; -} -.highlight .nt { - color: #f4bf75; -} -.highlight .o, .highlight .ow { - color: #d0d0d0; -} -.highlight .p, .highlight .pi { - color: #d0d0d0; -} -.highlight .gi { - color: #90a959; -} -.highlight .gd { - color: #ac4142; -} -.highlight .gh { - color: #6a9fb5; - background-color: #151515; - font-weight: bold; -} -.highlight .k, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kv { - color: #aa759f; -} -.highlight .kc { - color: #d28445; -} -.highlight .kt { - color: #d28445; -} -.highlight .kd { - color: #d28445; -} -.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .s1 { - color: #90a959; -} -.highlight .sa { - color: #aa759f; -} -.highlight .sr { - color: #75b5aa; -} -.highlight .si { - color: #8f5536; -} -.highlight .se { - color: #8f5536; -} -.highlight .nn { - color: #f4bf75; -} -.highlight .nc { - color: #f4bf75; -} -.highlight .no { - color: #f4bf75; -} -.highlight .na { - color: #6a9fb5; -} -.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { - color: #90a959; -} -.highlight .ss { - color: #90a959; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight, .highlight .w { + color: #303030; +} +.highlight .err { + color: #151515; + background-color: #ac4142; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { + color: #505050; +} +.highlight .cp { + color: #f4bf75; +} +.highlight .nt { + color: #f4bf75; +} +.highlight .o, .highlight .ow { + color: #d0d0d0; +} +.highlight .p, .highlight .pi { + color: #d0d0d0; +} +.highlight .gi { + color: #90a959; +} +.highlight .gd { + color: #ac4142; +} +.highlight .gh { + color: #6a9fb5; + background-color: #151515; + font-weight: bold; +} +.highlight .k, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kv { + color: #aa759f; +} +.highlight .kc { + color: #d28445; +} +.highlight .kt { + color: #d28445; +} +.highlight .kd { + color: #d28445; +} +.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .s1 { + color: #90a959; +} +.highlight .sa { + color: #aa759f; +} +.highlight .sr { + color: #75b5aa; +} +.highlight .si { + color: #8f5536; +} +.highlight .se { + color: #8f5536; +} +.highlight .nn { + color: #f4bf75; +} +.highlight .nc { + color: #f4bf75; +} +.highlight .no { + color: #f4bf75; +} +.highlight .na { + color: #6a9fb5; +} +.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { + color: #90a959; +} +.highlight .ss { + color: #90a959; +} diff --git a/assets/gitbook/rouge/bw.css b/assets/gitbook/rouge/bw.css index 86d205a7ac..c823dac223 100644 --- a/assets/gitbook/rouge/bw.css +++ b/assets/gitbook/rouge/bw.css @@ -1,66 +1,66 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight, .highlight .w { - color: #000000; - background-color: #ffffff; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { - font-style: italic; -} -.highlight .cp { -} -.highlight .k, .highlight .kc, .highlight .kd, .highlight .kn, .highlight .kr, .highlight .kv { - font-weight: bold; -} -.highlight .kp { -} -.highlight .kt { -} -.highlight .o, .highlight .ow { - font-weight: bold; -} -.highlight .nc { - font-weight: bold; -} -.highlight .nn { - font-weight: bold; -} -.highlight .ne { - font-weight: bold; -} -.highlight .ni { - font-weight: bold; -} -.highlight .nt { - font-weight: bold; -} -.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .sr, .highlight .s1, .highlight .ss { - font-style: italic; -} -.highlight .sa { - font-weight: bold; -} -.highlight .si { - font-weight: bold; -} -.highlight .se { - font-weight: bold; -} -.highlight .gh { - font-weight: bold; -} -.highlight .gu { - font-weight: bold; -} -.highlight .ge { - font-style: italic; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gp { - font-weight: bold; -} -.highlight .err { - color: #FF0000; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight, .highlight .w { + color: #000000; + background-color: #ffffff; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { + font-style: italic; +} +.highlight .cp { +} +.highlight .k, .highlight .kc, .highlight .kd, .highlight .kn, .highlight .kr, .highlight .kv { + font-weight: bold; +} +.highlight .kp { +} +.highlight .kt { +} +.highlight .o, .highlight .ow { + font-weight: bold; +} +.highlight .nc { + font-weight: bold; +} +.highlight .nn { + font-weight: bold; +} +.highlight .ne { + font-weight: bold; +} +.highlight .ni { + font-weight: bold; +} +.highlight .nt { + font-weight: bold; +} +.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .sr, .highlight .s1, .highlight .ss { + font-style: italic; +} +.highlight .sa { + font-weight: bold; +} +.highlight .si { + font-weight: bold; +} +.highlight .se { + font-weight: bold; +} +.highlight .gh { + font-weight: bold; +} +.highlight .gu { + font-weight: bold; +} +.highlight .ge { + font-style: italic; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gp { + font-weight: bold; +} +.highlight .err { + color: #FF0000; +} diff --git a/assets/gitbook/rouge/colorful.css b/assets/gitbook/rouge/colorful.css index 859ec85c80..291666f379 100644 --- a/assets/gitbook/rouge/colorful.css +++ b/assets/gitbook/rouge/colorful.css @@ -1,174 +1,174 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight, .highlight .w { - color: #bbbbbb; - background-color: #000; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1 { - color: #888; -} -.highlight .cp { - color: #579; -} -.highlight .cs { - color: #cc0000; - font-weight: bold; -} -.highlight .k, .highlight .kc, .highlight .kd, .highlight .kn, .highlight .kr, .highlight .kv { - color: #080; - font-weight: bold; -} -.highlight .kp { - color: #038; -} -.highlight .kt { - color: #339; -} -.highlight .o { - color: #333; -} -.highlight .ow { - color: #000; - font-weight: bold; -} -.highlight .nb, .highlight .bp { - color: #007020; -} -.highlight .nf, .highlight .fm { - color: #06B; - font-weight: bold; -} -.highlight .nc { - color: #B06; - font-weight: bold; -} -.highlight .nn { - color: #0e84b5; - font-weight: bold; -} -.highlight .ne { - color: #F00; - font-weight: bold; -} -.highlight .nv, .highlight .vm { - color: #963; -} -.highlight .vi { - color: #33B; -} -.highlight .vc { - color: #369; -} -.highlight .vg { - color: #d70; - font-weight: bold; -} -.highlight .no { - color: #036; - font-weight: bold; -} -.highlight .nl { - color: #970; - font-weight: bold; -} -.highlight .ni { - color: #800; - font-weight: bold; -} -.highlight .na { - color: #00C; -} -.highlight .nt { - color: #070; -} -.highlight .nd { - color: #555; - font-weight: bold; -} -.highlight .s, .highlight .sb, .highlight .dl, .highlight .s2, .highlight .sh, .highlight .s1 { - background-color: #fff0f0; -} -.highlight .sa { - color: #080; - font-weight: bold; -} -.highlight .sc { - color: #04D; -} -.highlight .sd { - color: #D42; -} -.highlight .si { - background-color: #eee; -} -.highlight .se { - color: #666; - font-weight: bold; -} -.highlight .sr { - color: #000; - background-color: #fff0ff; -} -.highlight .ss { - color: #A60; -} -.highlight .sx { - color: #D20; -} -.highlight .m, .highlight .mb, .highlight .mx { - color: #60E; - font-weight: bold; -} -.highlight .mi, .highlight .il { - color: #00D; - font-weight: bold; -} -.highlight .mf { - color: #60E; - font-weight: bold; -} -.highlight .mh { - color: #058; - font-weight: bold; -} -.highlight .mo { - color: #40E; - font-weight: bold; -} -.highlight .gh { - color: #000080; - font-weight: bold; -} -.highlight .gu { - color: #800080; - font-weight: bold; -} -.highlight .gd { - color: #A00000; -} -.highlight .gi { - color: #00A000; -} -.highlight .gr { - color: #FF0000; -} -.highlight .ge { - font-style: italic; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gp { - color: #c65d09; - font-weight: bold; -} -.highlight .go { - color: #888; -} -.highlight .gt { - color: #04D; -} -.highlight .err { - color: #F00; - background-color: #FAA; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight, .highlight .w { + color: #bbbbbb; + background-color: #000; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1 { + color: #888; +} +.highlight .cp { + color: #579; +} +.highlight .cs { + color: #cc0000; + font-weight: bold; +} +.highlight .k, .highlight .kc, .highlight .kd, .highlight .kn, .highlight .kr, .highlight .kv { + color: #080; + font-weight: bold; +} +.highlight .kp { + color: #038; +} +.highlight .kt { + color: #339; +} +.highlight .o { + color: #333; +} +.highlight .ow { + color: #000; + font-weight: bold; +} +.highlight .nb, .highlight .bp { + color: #007020; +} +.highlight .nf, .highlight .fm { + color: #06B; + font-weight: bold; +} +.highlight .nc { + color: #B06; + font-weight: bold; +} +.highlight .nn { + color: #0e84b5; + font-weight: bold; +} +.highlight .ne { + color: #F00; + font-weight: bold; +} +.highlight .nv, .highlight .vm { + color: #963; +} +.highlight .vi { + color: #33B; +} +.highlight .vc { + color: #369; +} +.highlight .vg { + color: #d70; + font-weight: bold; +} +.highlight .no { + color: #036; + font-weight: bold; +} +.highlight .nl { + color: #970; + font-weight: bold; +} +.highlight .ni { + color: #800; + font-weight: bold; +} +.highlight .na { + color: #00C; +} +.highlight .nt { + color: #070; +} +.highlight .nd { + color: #555; + font-weight: bold; +} +.highlight .s, .highlight .sb, .highlight .dl, .highlight .s2, .highlight .sh, .highlight .s1 { + background-color: #fff0f0; +} +.highlight .sa { + color: #080; + font-weight: bold; +} +.highlight .sc { + color: #04D; +} +.highlight .sd { + color: #D42; +} +.highlight .si { + background-color: #eee; +} +.highlight .se { + color: #666; + font-weight: bold; +} +.highlight .sr { + color: #000; + background-color: #fff0ff; +} +.highlight .ss { + color: #A60; +} +.highlight .sx { + color: #D20; +} +.highlight .m, .highlight .mb, .highlight .mx { + color: #60E; + font-weight: bold; +} +.highlight .mi, .highlight .il { + color: #00D; + font-weight: bold; +} +.highlight .mf { + color: #60E; + font-weight: bold; +} +.highlight .mh { + color: #058; + font-weight: bold; +} +.highlight .mo { + color: #40E; + font-weight: bold; +} +.highlight .gh { + color: #000080; + font-weight: bold; +} +.highlight .gu { + color: #800080; + font-weight: bold; +} +.highlight .gd { + color: #A00000; +} +.highlight .gi { + color: #00A000; +} +.highlight .gr { + color: #FF0000; +} +.highlight .ge { + font-style: italic; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gp { + color: #c65d09; + font-weight: bold; +} +.highlight .go { + color: #888; +} +.highlight .gt { + color: #04D; +} +.highlight .err { + color: #F00; + background-color: #FAA; +} diff --git a/assets/gitbook/rouge/github.css b/assets/gitbook/rouge/github.css index 4de1be53d7..2af5601adb 100644 --- a/assets/gitbook/rouge/github.css +++ b/assets/gitbook/rouge/github.css @@ -1,213 +1,213 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight .cm { - color: #999988; - font-style: italic; -} -.highlight .cp { - color: #999999; - font-weight: bold; -} -.highlight .c1 { - color: #999988; - font-style: italic; -} -.highlight .cs { - color: #999999; - font-weight: bold; - font-style: italic; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf { - color: #999988; - font-style: italic; -} -.highlight .err { - color: #a61717; - background-color: #e3d2d2; -} -.highlight .gd { - color: #000000; - background-color: #ffdddd; -} -.highlight .ge { - color: #000000; - font-style: italic; -} -.highlight .gr { - color: #aa0000; -} -.highlight .gh { - color: #999999; -} -.highlight .gi { - color: #000000; - background-color: #ddffdd; -} -.highlight .go { - color: #888888; -} -.highlight .gp { - color: #555555; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gu { - color: #aaaaaa; -} -.highlight .gt { - color: #aa0000; -} -.highlight .kc { - color: #000000; - font-weight: bold; -} -.highlight .kd { - color: #000000; - font-weight: bold; -} -.highlight .kn { - color: #000000; - font-weight: bold; -} -.highlight .kp { - color: #000000; - font-weight: bold; -} -.highlight .kr { - color: #000000; - font-weight: bold; -} -.highlight .kt { - color: #445588; - font-weight: bold; -} -.highlight .k, .highlight .kv { - color: #000000; - font-weight: bold; -} -.highlight .mf { - color: #009999; -} -.highlight .mh { - color: #009999; -} -.highlight .il { - color: #009999; -} -.highlight .mi { - color: #009999; -} -.highlight .mo { - color: #009999; -} -.highlight .m, .highlight .mb, .highlight .mx { - color: #009999; -} -.highlight .sa { - color: #000000; - font-weight: bold; -} -.highlight .sb { - color: #d14; -} -.highlight .sc { - color: #d14; -} -.highlight .sd { - color: #d14; -} -.highlight .s2 { - color: #d14; -} -.highlight .se { - color: #d14; -} -.highlight .sh { - color: #d14; -} -.highlight .si { - color: #d14; -} -.highlight .sx { - color: #d14; -} -.highlight .sr { - color: #009926; -} -.highlight .s1 { - color: #d14; -} -.highlight .ss { - color: #990073; -} -.highlight .s, .highlight .dl { - color: #d14; -} -.highlight .na { - color: #008080; -} -.highlight .bp { - color: #999999; -} -.highlight .nb { - color: #0086B3; -} -.highlight .nc { - color: #445588; - font-weight: bold; -} -.highlight .no { - color: #008080; -} -.highlight .nd { - color: #3c5d5d; - font-weight: bold; -} -.highlight .ni { - color: #800080; -} -.highlight .ne { - color: #990000; - font-weight: bold; -} -.highlight .nf, .highlight .fm { - color: #990000; - font-weight: bold; -} -.highlight .nl { - color: #990000; - font-weight: bold; -} -.highlight .nn { - color: #555555; -} -.highlight .nt { - color: #000080; -} -.highlight .vc { - color: #008080; -} -.highlight .vg { - color: #008080; -} -.highlight .vi { - color: #008080; -} -.highlight .nv, .highlight .vm { - color: #008080; -} -.highlight .ow { - color: #000000; - font-weight: bold; -} -.highlight .o { - color: #000000; - font-weight: bold; -} -.highlight .w { - color: #bbbbbb; -} -.highlight { - background-color: #f8f8f8; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight .cm { + color: #999988; + font-style: italic; +} +.highlight .cp { + color: #999999; + font-weight: bold; +} +.highlight .c1 { + color: #999988; + font-style: italic; +} +.highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf { + color: #999988; + font-style: italic; +} +.highlight .err { + color: #a61717; + background-color: #e3d2d2; +} +.highlight .gd { + color: #000000; + background-color: #ffdddd; +} +.highlight .ge { + color: #000000; + font-style: italic; +} +.highlight .gr { + color: #aa0000; +} +.highlight .gh { + color: #999999; +} +.highlight .gi { + color: #000000; + background-color: #ddffdd; +} +.highlight .go { + color: #888888; +} +.highlight .gp { + color: #555555; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gu { + color: #aaaaaa; +} +.highlight .gt { + color: #aa0000; +} +.highlight .kc { + color: #000000; + font-weight: bold; +} +.highlight .kd { + color: #000000; + font-weight: bold; +} +.highlight .kn { + color: #000000; + font-weight: bold; +} +.highlight .kp { + color: #000000; + font-weight: bold; +} +.highlight .kr { + color: #000000; + font-weight: bold; +} +.highlight .kt { + color: #445588; + font-weight: bold; +} +.highlight .k, .highlight .kv { + color: #000000; + font-weight: bold; +} +.highlight .mf { + color: #009999; +} +.highlight .mh { + color: #009999; +} +.highlight .il { + color: #009999; +} +.highlight .mi { + color: #009999; +} +.highlight .mo { + color: #009999; +} +.highlight .m, .highlight .mb, .highlight .mx { + color: #009999; +} +.highlight .sa { + color: #000000; + font-weight: bold; +} +.highlight .sb { + color: #d14; +} +.highlight .sc { + color: #d14; +} +.highlight .sd { + color: #d14; +} +.highlight .s2 { + color: #d14; +} +.highlight .se { + color: #d14; +} +.highlight .sh { + color: #d14; +} +.highlight .si { + color: #d14; +} +.highlight .sx { + color: #d14; +} +.highlight .sr { + color: #009926; +} +.highlight .s1 { + color: #d14; +} +.highlight .ss { + color: #990073; +} +.highlight .s, .highlight .dl { + color: #d14; +} +.highlight .na { + color: #008080; +} +.highlight .bp { + color: #999999; +} +.highlight .nb { + color: #0086B3; +} +.highlight .nc { + color: #445588; + font-weight: bold; +} +.highlight .no { + color: #008080; +} +.highlight .nd { + color: #3c5d5d; + font-weight: bold; +} +.highlight .ni { + color: #800080; +} +.highlight .ne { + color: #990000; + font-weight: bold; +} +.highlight .nf, .highlight .fm { + color: #990000; + font-weight: bold; +} +.highlight .nl { + color: #990000; + font-weight: bold; +} +.highlight .nn { + color: #555555; +} +.highlight .nt { + color: #000080; +} +.highlight .vc { + color: #008080; +} +.highlight .vg { + color: #008080; +} +.highlight .vi { + color: #008080; +} +.highlight .nv, .highlight .vm { + color: #008080; +} +.highlight .ow { + color: #000000; + font-weight: bold; +} +.highlight .o { + color: #000000; + font-weight: bold; +} +.highlight .w { + color: #bbbbbb; +} +.highlight { + background-color: #f8f8f8; +} diff --git a/assets/gitbook/rouge/gruvbox.css b/assets/gitbook/rouge/gruvbox.css index a0a4aca461..a2214580ff 100644 --- a/assets/gitbook/rouge/gruvbox.css +++ b/assets/gitbook/rouge/gruvbox.css @@ -1,87 +1,87 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight, .highlight .w { - color: #fbf1c7; - background-color: #282828; -} -.highlight .err { - color: #fb4934; - background-color: #282828; - font-weight: bold; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { - color: #928374; - font-style: italic; -} -.highlight .cp { - color: #8ec07c; -} -.highlight .nt { - color: #fb4934; -} -.highlight .o, .highlight .ow { - color: #fbf1c7; -} -.highlight .p, .highlight .pi { - color: #fbf1c7; -} -.highlight .gi { - color: #b8bb26; - background-color: #282828; -} -.highlight .gd { - color: #fb4934; - background-color: #282828; -} -.highlight .gh { - color: #b8bb26; - font-weight: bold; -} -.highlight .k, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kv { - color: #fb4934; -} -.highlight .kc { - color: #d3869b; -} -.highlight .kt { - color: #fabd2f; -} -.highlight .kd { - color: #fe8019; -} -.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .s1 { - color: #b8bb26; - font-style: italic; -} -.highlight .si { - color: #b8bb26; - font-style: italic; -} -.highlight .sr { - color: #b8bb26; - font-style: italic; -} -.highlight .sa { - color: #fb4934; -} -.highlight .se { - color: #fe8019; -} -.highlight .nn { - color: #8ec07c; -} -.highlight .nc { - color: #8ec07c; -} -.highlight .no { - color: #d3869b; -} -.highlight .na { - color: #b8bb26; -} -.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { - color: #d3869b; -} -.highlight .ss { - color: #83a598; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight, .highlight .w { + color: #fbf1c7; + background-color: #282828; +} +.highlight .err { + color: #fb4934; + background-color: #282828; + font-weight: bold; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { + color: #928374; + font-style: italic; +} +.highlight .cp { + color: #8ec07c; +} +.highlight .nt { + color: #fb4934; +} +.highlight .o, .highlight .ow { + color: #fbf1c7; +} +.highlight .p, .highlight .pi { + color: #fbf1c7; +} +.highlight .gi { + color: #b8bb26; + background-color: #282828; +} +.highlight .gd { + color: #fb4934; + background-color: #282828; +} +.highlight .gh { + color: #b8bb26; + font-weight: bold; +} +.highlight .k, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kv { + color: #fb4934; +} +.highlight .kc { + color: #d3869b; +} +.highlight .kt { + color: #fabd2f; +} +.highlight .kd { + color: #fe8019; +} +.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .s1 { + color: #b8bb26; + font-style: italic; +} +.highlight .si { + color: #b8bb26; + font-style: italic; +} +.highlight .sr { + color: #b8bb26; + font-style: italic; +} +.highlight .sa { + color: #fb4934; +} +.highlight .se { + color: #fe8019; +} +.highlight .nn { + color: #8ec07c; +} +.highlight .nc { + color: #8ec07c; +} +.highlight .no { + color: #d3869b; +} +.highlight .na { + color: #b8bb26; +} +.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { + color: #d3869b; +} +.highlight .ss { + color: #83a598; +} diff --git a/assets/gitbook/rouge/igor_pro.css b/assets/gitbook/rouge/igor_pro.css index 8d1180d8b3..e0681312fa 100644 --- a/assets/gitbook/rouge/igor_pro.css +++ b/assets/gitbook/rouge/igor_pro.css @@ -1 +1 @@ -unknown theme: igor_pro +unknown theme: igor_pro diff --git a/assets/gitbook/rouge/magritte.css b/assets/gitbook/rouge/magritte.css index 7e868284fd..000b03c951 100644 --- a/assets/gitbook/rouge/magritte.css +++ b/assets/gitbook/rouge/magritte.css @@ -1,171 +1,171 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight { - color: #000707; - background-color: #f3ffff; -} -.highlight .gl { - color: #f3ffff; - background-color: #000707; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { - color: #006c6c; - font-style: italic; -} -.highlight .cp { - color: #920241; - font-weight: bold; -} -.highlight .err { - color: #f3ffff; - background-color: #f22700; -} -.highlight .gr { - color: #f22700; - font-weight: bold; - font-style: italic; -} -.highlight .k, .highlight .kd, .highlight .kv { - color: #19003a; - font-weight: bold; -} -.highlight .o, .highlight .ow { - color: #4c48fe; - font-weight: bold; -} -.highlight .p, .highlight .pi { - color: #4c48fe; -} -.highlight .gd { - color: #f22700; -} -.highlight .gi { - color: #007500; -} -.highlight .ge { - font-style: italic; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gt { - color: #000000; - background-color: #d8d9ff; -} -.highlight .kc { - color: #007500; - font-weight: bold; -} -.highlight .kn { - color: #007500; - font-weight: bold; -} -.highlight .kp { - color: #007500; - font-weight: bold; -} -.highlight .kr { - color: #007500; - font-weight: bold; -} -.highlight .gh { - color: #007500; - font-weight: bold; -} -.highlight .gu { - color: #007500; - font-weight: bold; -} -.highlight .kt { - color: #920241; - font-weight: bold; -} -.highlight .no { - color: #920241; - font-weight: bold; -} -.highlight .nc { - color: #920241; - font-weight: bold; -} -.highlight .nd { - color: #920241; - font-weight: bold; -} -.highlight .nn { - color: #920241; - font-weight: bold; -} -.highlight .bp { - color: #920241; - font-weight: bold; -} -.highlight .ne { - color: #920241; - font-weight: bold; -} -.highlight .nl { - color: #840084; - font-weight: bold; -} -.highlight .nt { - color: #840084; - font-weight: bold; -} -.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { - color: #007500; - font-weight: bold; -} -.highlight .ld { - color: #007500; - font-weight: bold; -} -.highlight .ss { - color: #007500; -} -.highlight .s, .highlight .sb, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .sr, .highlight .s1 { - color: #7c0000; - font-weight: bold; -} -.highlight .sa { - color: #19003a; - font-weight: bold; -} -.highlight .se { - color: #840084; - font-weight: bold; -} -.highlight .sc { - color: #840084; - font-weight: bold; -} -.highlight .si { - color: #840084; - font-weight: bold; -} -.highlight .nb { - font-weight: bold; -} -.highlight .ni { - color: #999999; - font-weight: bold; -} -.highlight .w { - color: #BBBBBB; -} -.highlight .go { - color: #19003a; -} -.highlight .nf, .highlight .fm { - color: #ff0089; -} -.highlight .py { - color: #ff0089; -} -.highlight .na { - color: #ff0089; -} -.highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm { - color: #ff0089; - font-weight: bold; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight { + color: #000707; + background-color: #f3ffff; +} +.highlight .gl { + color: #f3ffff; + background-color: #000707; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { + color: #006c6c; + font-style: italic; +} +.highlight .cp { + color: #920241; + font-weight: bold; +} +.highlight .err { + color: #f3ffff; + background-color: #f22700; +} +.highlight .gr { + color: #f22700; + font-weight: bold; + font-style: italic; +} +.highlight .k, .highlight .kd, .highlight .kv { + color: #19003a; + font-weight: bold; +} +.highlight .o, .highlight .ow { + color: #4c48fe; + font-weight: bold; +} +.highlight .p, .highlight .pi { + color: #4c48fe; +} +.highlight .gd { + color: #f22700; +} +.highlight .gi { + color: #007500; +} +.highlight .ge { + font-style: italic; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gt { + color: #000000; + background-color: #d8d9ff; +} +.highlight .kc { + color: #007500; + font-weight: bold; +} +.highlight .kn { + color: #007500; + font-weight: bold; +} +.highlight .kp { + color: #007500; + font-weight: bold; +} +.highlight .kr { + color: #007500; + font-weight: bold; +} +.highlight .gh { + color: #007500; + font-weight: bold; +} +.highlight .gu { + color: #007500; + font-weight: bold; +} +.highlight .kt { + color: #920241; + font-weight: bold; +} +.highlight .no { + color: #920241; + font-weight: bold; +} +.highlight .nc { + color: #920241; + font-weight: bold; +} +.highlight .nd { + color: #920241; + font-weight: bold; +} +.highlight .nn { + color: #920241; + font-weight: bold; +} +.highlight .bp { + color: #920241; + font-weight: bold; +} +.highlight .ne { + color: #920241; + font-weight: bold; +} +.highlight .nl { + color: #840084; + font-weight: bold; +} +.highlight .nt { + color: #840084; + font-weight: bold; +} +.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { + color: #007500; + font-weight: bold; +} +.highlight .ld { + color: #007500; + font-weight: bold; +} +.highlight .ss { + color: #007500; +} +.highlight .s, .highlight .sb, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .sr, .highlight .s1 { + color: #7c0000; + font-weight: bold; +} +.highlight .sa { + color: #19003a; + font-weight: bold; +} +.highlight .se { + color: #840084; + font-weight: bold; +} +.highlight .sc { + color: #840084; + font-weight: bold; +} +.highlight .si { + color: #840084; + font-weight: bold; +} +.highlight .nb { + font-weight: bold; +} +.highlight .ni { + color: #999999; + font-weight: bold; +} +.highlight .w { + color: #BBBBBB; +} +.highlight .go { + color: #19003a; +} +.highlight .nf, .highlight .fm { + color: #ff0089; +} +.highlight .py { + color: #ff0089; +} +.highlight .na { + color: #ff0089; +} +.highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm { + color: #ff0089; + font-weight: bold; +} diff --git a/assets/gitbook/rouge/molokai.css b/assets/gitbook/rouge/molokai.css index 78cdfa8996..8c81d8556d 100644 --- a/assets/gitbook/rouge/molokai.css +++ b/assets/gitbook/rouge/molokai.css @@ -1,208 +1,208 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf { - color: #5e5d83; - font-style: italic; -} -.highlight .cm { - color: #5e5d83; - font-style: italic; -} -.highlight .c1 { - color: #5e5d83; - font-style: italic; -} -.highlight .cp { - color: #465457; - font-weight: bold; -} -.highlight .cs { - color: #465457; - font-weight: bold; - font-style: italic; -} -.highlight .err { - color: #f8f8f2; - background-color: #403d3d; -} -.highlight .gi { - color: #a6e22e; -} -.highlight .gd { - color: #f92672; -} -.highlight .ge { - color: #1b1d1e; - font-style: italic; -} -.highlight .gr { - color: #f92672; -} -.highlight .gt { - color: #f92672; -} -.highlight .gh { - color: #403d3d; -} -.highlight .go { - color: #403d3d; -} -.highlight .gp { - color: #66d9ef; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gu { - color: #465457; -} -.highlight .k, .highlight .kv { - color: #66d9ef; - font-weight: bold; -} -.highlight .kc { - color: #66d9ef; - font-weight: bold; -} -.highlight .kd { - color: #66d9ef; - font-weight: bold; -} -.highlight .kp { - color: #66d9ef; - font-weight: bold; -} -.highlight .kr { - color: #66d9ef; - font-weight: bold; -} -.highlight .kt { - color: #66d9ef; - font-weight: bold; -} -.highlight .kn { - color: #f92672; - font-weight: bold; -} -.highlight .ow { - color: #f92672; - font-weight: bold; -} -.highlight .o { - color: #f92672; - font-weight: bold; -} -.highlight .mf { - color: #af87ff; -} -.highlight .mh { - color: #af87ff; -} -.highlight .il { - color: #af87ff; -} -.highlight .mi { - color: #af87ff; -} -.highlight .mo { - color: #af87ff; -} -.highlight .m, .highlight .mb, .highlight .mx { - color: #af87ff; -} -.highlight .se { - color: #af87ff; -} -.highlight .sb { - color: #d7d787; -} -.highlight .sc { - color: #d7d787; -} -.highlight .sd { - color: #d7d787; -} -.highlight .s2 { - color: #d7d787; -} -.highlight .sh { - color: #d7d787; -} -.highlight .si { - color: #d7d787; -} -.highlight .sx { - color: #d7d787; -} -.highlight .sr { - color: #d7d787; -} -.highlight .s1 { - color: #d7d787; -} -.highlight .ss { - color: #d7d787; -} -.highlight .s, .highlight .sa, .highlight .dl { - color: #d7d787; -} -.highlight .na { - color: #a6e22e; -} -.highlight .nc { - color: #a6e22e; - font-weight: bold; -} -.highlight .nd { - color: #a6e22e; - font-weight: bold; -} -.highlight .ne { - color: #a6e22e; - font-weight: bold; -} -.highlight .nf, .highlight .fm { - color: #a6e22e; - font-weight: bold; -} -.highlight .no { - color: #66d9ef; -} -.highlight .bp { - color: #f8f8f2; -} -.highlight .nb { - color: #f8f8f2; -} -.highlight .ni { - color: #f8f8f2; -} -.highlight .nn { - color: #f8f8f2; -} -.highlight .vc { - color: #f8f8f2; -} -.highlight .vg { - color: #f8f8f2; -} -.highlight .vi { - color: #f8f8f2; -} -.highlight .nv, .highlight .vm { - color: #f8f8f2; -} -.highlight .w { - color: #f8f8f2; -} -.highlight .nl { - color: #f8f8f2; - font-weight: bold; -} -.highlight .nt { - color: #f92672; -} -.highlight { - color: #f8f8f2; - background-color: #1b1d1e; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf { + color: #5e5d83; + font-style: italic; +} +.highlight .cm { + color: #5e5d83; + font-style: italic; +} +.highlight .c1 { + color: #5e5d83; + font-style: italic; +} +.highlight .cp { + color: #465457; + font-weight: bold; +} +.highlight .cs { + color: #465457; + font-weight: bold; + font-style: italic; +} +.highlight .err { + color: #f8f8f2; + background-color: #403d3d; +} +.highlight .gi { + color: #a6e22e; +} +.highlight .gd { + color: #f92672; +} +.highlight .ge { + color: #1b1d1e; + font-style: italic; +} +.highlight .gr { + color: #f92672; +} +.highlight .gt { + color: #f92672; +} +.highlight .gh { + color: #403d3d; +} +.highlight .go { + color: #403d3d; +} +.highlight .gp { + color: #66d9ef; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gu { + color: #465457; +} +.highlight .k, .highlight .kv { + color: #66d9ef; + font-weight: bold; +} +.highlight .kc { + color: #66d9ef; + font-weight: bold; +} +.highlight .kd { + color: #66d9ef; + font-weight: bold; +} +.highlight .kp { + color: #66d9ef; + font-weight: bold; +} +.highlight .kr { + color: #66d9ef; + font-weight: bold; +} +.highlight .kt { + color: #66d9ef; + font-weight: bold; +} +.highlight .kn { + color: #f92672; + font-weight: bold; +} +.highlight .ow { + color: #f92672; + font-weight: bold; +} +.highlight .o { + color: #f92672; + font-weight: bold; +} +.highlight .mf { + color: #af87ff; +} +.highlight .mh { + color: #af87ff; +} +.highlight .il { + color: #af87ff; +} +.highlight .mi { + color: #af87ff; +} +.highlight .mo { + color: #af87ff; +} +.highlight .m, .highlight .mb, .highlight .mx { + color: #af87ff; +} +.highlight .se { + color: #af87ff; +} +.highlight .sb { + color: #d7d787; +} +.highlight .sc { + color: #d7d787; +} +.highlight .sd { + color: #d7d787; +} +.highlight .s2 { + color: #d7d787; +} +.highlight .sh { + color: #d7d787; +} +.highlight .si { + color: #d7d787; +} +.highlight .sx { + color: #d7d787; +} +.highlight .sr { + color: #d7d787; +} +.highlight .s1 { + color: #d7d787; +} +.highlight .ss { + color: #d7d787; +} +.highlight .s, .highlight .sa, .highlight .dl { + color: #d7d787; +} +.highlight .na { + color: #a6e22e; +} +.highlight .nc { + color: #a6e22e; + font-weight: bold; +} +.highlight .nd { + color: #a6e22e; + font-weight: bold; +} +.highlight .ne { + color: #a6e22e; + font-weight: bold; +} +.highlight .nf, .highlight .fm { + color: #a6e22e; + font-weight: bold; +} +.highlight .no { + color: #66d9ef; +} +.highlight .bp { + color: #f8f8f2; +} +.highlight .nb { + color: #f8f8f2; +} +.highlight .ni { + color: #f8f8f2; +} +.highlight .nn { + color: #f8f8f2; +} +.highlight .vc { + color: #f8f8f2; +} +.highlight .vg { + color: #f8f8f2; +} +.highlight .vi { + color: #f8f8f2; +} +.highlight .nv, .highlight .vm { + color: #f8f8f2; +} +.highlight .w { + color: #f8f8f2; +} +.highlight .nl { + color: #f8f8f2; + font-weight: bold; +} +.highlight .nt { + color: #f92672; +} +.highlight { + color: #f8f8f2; + background-color: #1b1d1e; +} diff --git a/assets/gitbook/rouge/monokai.css b/assets/gitbook/rouge/monokai.css index 21b957065d..1c22a6dbdb 100644 --- a/assets/gitbook/rouge/monokai.css +++ b/assets/gitbook/rouge/monokai.css @@ -1,214 +1,214 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf { - color: #75715e; - font-style: italic; -} -.highlight .cm { - color: #75715e; - font-style: italic; -} -.highlight .c1 { - color: #75715e; - font-style: italic; -} -.highlight .cp { - color: #75715e; - font-weight: bold; -} -.highlight .cs { - color: #75715e; - font-weight: bold; - font-style: italic; -} -.highlight .err { - color: #960050; - background-color: #1e0010; -} -.highlight .gi { - color: #ffffff; - background-color: #324932; -} -.highlight .gd { - color: #ffffff; - background-color: #493131; -} -.highlight .ge { - color: #000000; - font-style: italic; -} -.highlight .gr { - color: #aa0000; -} -.highlight .gt { - color: #aa0000; -} -.highlight .gh { - color: #999999; -} -.highlight .go { - color: #888888; -} -.highlight .gp { - color: #555555; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gu { - color: #aaaaaa; -} -.highlight .k, .highlight .kv { - color: #66d9ef; - font-weight: bold; -} -.highlight .kc { - color: #66d9ef; - font-weight: bold; -} -.highlight .kd { - color: #66d9ef; - font-weight: bold; -} -.highlight .kp { - color: #66d9ef; - font-weight: bold; -} -.highlight .kr { - color: #66d9ef; - font-weight: bold; -} -.highlight .kt { - color: #66d9ef; - font-weight: bold; -} -.highlight .kn { - color: #f92672; - font-weight: bold; -} -.highlight .ow { - color: #f92672; - font-weight: bold; -} -.highlight .o { - color: #f92672; - font-weight: bold; -} -.highlight .mf { - color: #ae81ff; -} -.highlight .mh { - color: #ae81ff; -} -.highlight .il { - color: #ae81ff; -} -.highlight .mi { - color: #ae81ff; -} -.highlight .mo { - color: #ae81ff; -} -.highlight .m, .highlight .mb, .highlight .mx { - color: #ae81ff; -} -.highlight .se { - color: #ae81ff; -} -.highlight .sa { - color: #66d9ef; - font-weight: bold; -} -.highlight .sb { - color: #e6db74; -} -.highlight .sc { - color: #e6db74; -} -.highlight .sd { - color: #e6db74; -} -.highlight .s2 { - color: #e6db74; -} -.highlight .sh { - color: #e6db74; -} -.highlight .si { - color: #e6db74; -} -.highlight .sx { - color: #e6db74; -} -.highlight .sr { - color: #e6db74; -} -.highlight .s1 { - color: #e6db74; -} -.highlight .ss { - color: #e6db74; -} -.highlight .s, .highlight .dl { - color: #e6db74; -} -.highlight .na { - color: #a6e22e; -} -.highlight .nc { - color: #a6e22e; - font-weight: bold; -} -.highlight .nd { - color: #a6e22e; - font-weight: bold; -} -.highlight .ne { - color: #a6e22e; - font-weight: bold; -} -.highlight .nf, .highlight .fm { - color: #a6e22e; - font-weight: bold; -} -.highlight .no { - color: #66d9ef; -} -.highlight .bp { - color: #f8f8f2; -} -.highlight .nb { - color: #f8f8f2; -} -.highlight .ni { - color: #f8f8f2; -} -.highlight .nn { - color: #f8f8f2; -} -.highlight .vc { - color: #f8f8f2; -} -.highlight .vg { - color: #f8f8f2; -} -.highlight .vi { - color: #f8f8f2; -} -.highlight .nv, .highlight .vm { - color: #f8f8f2; -} -.highlight .w { - color: #f8f8f2; -} -.highlight .nl { - color: #f8f8f2; - font-weight: bold; -} -.highlight .nt { - color: #f92672; -} -.highlight { - color: #f8f8f2; - background-color: #49483e; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf { + color: #75715e; + font-style: italic; +} +.highlight .cm { + color: #75715e; + font-style: italic; +} +.highlight .c1 { + color: #75715e; + font-style: italic; +} +.highlight .cp { + color: #75715e; + font-weight: bold; +} +.highlight .cs { + color: #75715e; + font-weight: bold; + font-style: italic; +} +.highlight .err { + color: #960050; + background-color: #1e0010; +} +.highlight .gi { + color: #ffffff; + background-color: #324932; +} +.highlight .gd { + color: #ffffff; + background-color: #493131; +} +.highlight .ge { + color: #000000; + font-style: italic; +} +.highlight .gr { + color: #aa0000; +} +.highlight .gt { + color: #aa0000; +} +.highlight .gh { + color: #999999; +} +.highlight .go { + color: #888888; +} +.highlight .gp { + color: #555555; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gu { + color: #aaaaaa; +} +.highlight .k, .highlight .kv { + color: #66d9ef; + font-weight: bold; +} +.highlight .kc { + color: #66d9ef; + font-weight: bold; +} +.highlight .kd { + color: #66d9ef; + font-weight: bold; +} +.highlight .kp { + color: #66d9ef; + font-weight: bold; +} +.highlight .kr { + color: #66d9ef; + font-weight: bold; +} +.highlight .kt { + color: #66d9ef; + font-weight: bold; +} +.highlight .kn { + color: #f92672; + font-weight: bold; +} +.highlight .ow { + color: #f92672; + font-weight: bold; +} +.highlight .o { + color: #f92672; + font-weight: bold; +} +.highlight .mf { + color: #ae81ff; +} +.highlight .mh { + color: #ae81ff; +} +.highlight .il { + color: #ae81ff; +} +.highlight .mi { + color: #ae81ff; +} +.highlight .mo { + color: #ae81ff; +} +.highlight .m, .highlight .mb, .highlight .mx { + color: #ae81ff; +} +.highlight .se { + color: #ae81ff; +} +.highlight .sa { + color: #66d9ef; + font-weight: bold; +} +.highlight .sb { + color: #e6db74; +} +.highlight .sc { + color: #e6db74; +} +.highlight .sd { + color: #e6db74; +} +.highlight .s2 { + color: #e6db74; +} +.highlight .sh { + color: #e6db74; +} +.highlight .si { + color: #e6db74; +} +.highlight .sx { + color: #e6db74; +} +.highlight .sr { + color: #e6db74; +} +.highlight .s1 { + color: #e6db74; +} +.highlight .ss { + color: #e6db74; +} +.highlight .s, .highlight .dl { + color: #e6db74; +} +.highlight .na { + color: #a6e22e; +} +.highlight .nc { + color: #a6e22e; + font-weight: bold; +} +.highlight .nd { + color: #a6e22e; + font-weight: bold; +} +.highlight .ne { + color: #a6e22e; + font-weight: bold; +} +.highlight .nf, .highlight .fm { + color: #a6e22e; + font-weight: bold; +} +.highlight .no { + color: #66d9ef; +} +.highlight .bp { + color: #f8f8f2; +} +.highlight .nb { + color: #f8f8f2; +} +.highlight .ni { + color: #f8f8f2; +} +.highlight .nn { + color: #f8f8f2; +} +.highlight .vc { + color: #f8f8f2; +} +.highlight .vg { + color: #f8f8f2; +} +.highlight .vi { + color: #f8f8f2; +} +.highlight .nv, .highlight .vm { + color: #f8f8f2; +} +.highlight .w { + color: #f8f8f2; +} +.highlight .nl { + color: #f8f8f2; + font-weight: bold; +} +.highlight .nt { + color: #f92672; +} +.highlight { + color: #f8f8f2; + background-color: #49483e; +} diff --git a/assets/gitbook/rouge/monokai_sublime.css b/assets/gitbook/rouge/monokai_sublime.css index b615316625..75b3637feb 100644 --- a/assets/gitbook/rouge/monokai_sublime.css +++ b/assets/gitbook/rouge/monokai_sublime.css @@ -1 +1 @@ -unknown theme: monokai_sublime +unknown theme: monokai_sublime diff --git a/assets/gitbook/rouge/pastie.css b/assets/gitbook/rouge/pastie.css index b95057457c..05f6b0ba31 100644 --- a/assets/gitbook/rouge/pastie.css +++ b/assets/gitbook/rouge/pastie.css @@ -1,150 +1,150 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1 { - color: #888888; -} -.highlight .cp { - color: #cc0000; - font-weight: bold; -} -.highlight .cs { - color: #cc0000; - background-color: #fff0f0; - font-weight: bold; -} -.highlight .err { - color: #a61717; - background-color: #e3d2d2; -} -.highlight .gr { - color: #aa0000; -} -.highlight .gh { - color: #333333; -} -.highlight .gu { - color: #666666; -} -.highlight .gd { - color: #000000; - background-color: #ffdddd; -} -.highlight .gi { - color: #000000; - background-color: #ddffdd; -} -.highlight .ge { - font-style: italic; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gl { - color: #888888; -} -.highlight .go { - color: #888888; -} -.highlight .gp { - color: #555555; -} -.highlight .gt { - color: #aa0000; -} -.highlight .k, .highlight .kc, .highlight .kd, .highlight .kn, .highlight .kr, .highlight .kv { - color: #008800; - font-weight: bold; -} -.highlight .kp { - color: #008800; -} -.highlight .kt { - color: #888888; - font-weight: bold; -} -.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { - color: #0000dd; - font-weight: bold; -} -.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .s1 { - color: #dd2200; - background-color: #fff0f0; -} -.highlight .sa { - color: #008800; - font-weight: bold; -} -.highlight .se { - color: #0044dd; - background-color: #fff0f0; -} -.highlight .si { - color: #3333bb; - background-color: #fff0f0; -} -.highlight .sx { - color: #22bb22; - background-color: #f0fff0; -} -.highlight .sr { - color: #008800; -} -.highlight .ss { - color: #aa6600; - background-color: #fff0f0; -} -.highlight .na { - color: #336699; -} -.highlight .nb, .highlight .bp { - color: #003388; -} -.highlight .nc { - color: #bb0066; - font-weight: bold; -} -.highlight .no { - color: #003366; - font-weight: bold; -} -.highlight .nd { - color: #555555; -} -.highlight .ne { - color: #bb0066; - font-weight: bold; -} -.highlight .nf, .highlight .fm { - color: #0066bb; - font-weight: bold; -} -.highlight .nl { - color: #336699; -} -.highlight .nn { - color: #bb0066; - font-weight: bold; -} -.highlight .py { - color: #336699; - font-weight: bold; -} -.highlight .nt { - color: #bb0066; - font-weight: bold; -} -.highlight .nv, .highlight .vc, .highlight .vm { - color: #336699; -} -.highlight .vg { - color: #dd7700; -} -.highlight .vi { - color: #3333bb; -} -.highlight .ow { - color: #008800; -} -.highlight .w { - color: #bbbbbb; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1 { + color: #888888; +} +.highlight .cp { + color: #cc0000; + font-weight: bold; +} +.highlight .cs { + color: #cc0000; + background-color: #fff0f0; + font-weight: bold; +} +.highlight .err { + color: #a61717; + background-color: #e3d2d2; +} +.highlight .gr { + color: #aa0000; +} +.highlight .gh { + color: #333333; +} +.highlight .gu { + color: #666666; +} +.highlight .gd { + color: #000000; + background-color: #ffdddd; +} +.highlight .gi { + color: #000000; + background-color: #ddffdd; +} +.highlight .ge { + font-style: italic; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gl { + color: #888888; +} +.highlight .go { + color: #888888; +} +.highlight .gp { + color: #555555; +} +.highlight .gt { + color: #aa0000; +} +.highlight .k, .highlight .kc, .highlight .kd, .highlight .kn, .highlight .kr, .highlight .kv { + color: #008800; + font-weight: bold; +} +.highlight .kp { + color: #008800; +} +.highlight .kt { + color: #888888; + font-weight: bold; +} +.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { + color: #0000dd; + font-weight: bold; +} +.highlight .s, .highlight .sb, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .s1 { + color: #dd2200; + background-color: #fff0f0; +} +.highlight .sa { + color: #008800; + font-weight: bold; +} +.highlight .se { + color: #0044dd; + background-color: #fff0f0; +} +.highlight .si { + color: #3333bb; + background-color: #fff0f0; +} +.highlight .sx { + color: #22bb22; + background-color: #f0fff0; +} +.highlight .sr { + color: #008800; +} +.highlight .ss { + color: #aa6600; + background-color: #fff0f0; +} +.highlight .na { + color: #336699; +} +.highlight .nb, .highlight .bp { + color: #003388; +} +.highlight .nc { + color: #bb0066; + font-weight: bold; +} +.highlight .no { + color: #003366; + font-weight: bold; +} +.highlight .nd { + color: #555555; +} +.highlight .ne { + color: #bb0066; + font-weight: bold; +} +.highlight .nf, .highlight .fm { + color: #0066bb; + font-weight: bold; +} +.highlight .nl { + color: #336699; +} +.highlight .nn { + color: #bb0066; + font-weight: bold; +} +.highlight .py { + color: #336699; + font-weight: bold; +} +.highlight .nt { + color: #bb0066; + font-weight: bold; +} +.highlight .nv, .highlight .vc, .highlight .vm { + color: #336699; +} +.highlight .vg { + color: #dd7700; +} +.highlight .vi { + color: #3333bb; +} +.highlight .ow { + color: #008800; +} +.highlight .w { + color: #bbbbbb; +} diff --git a/assets/gitbook/rouge/thankful_eyes.css b/assets/gitbook/rouge/thankful_eyes.css index 24d4ac7766..94b9121d6f 100644 --- a/assets/gitbook/rouge/thankful_eyes.css +++ b/assets/gitbook/rouge/thankful_eyes.css @@ -1,176 +1,176 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight { - color: #faf6e4; - background-color: #122b3b; -} -.highlight .gl { - color: #dee5e7; - background-color: #4e5d62; -} -.highlight .gp { - color: #a8e1fe; - font-weight: bold; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { - color: #6c8b9f; - font-style: italic; -} -.highlight .cp { - color: #b2fd6d; - font-weight: bold; -} -.highlight .err { - color: #fefeec; - background-color: #cc0000; -} -.highlight .gr { - color: #cc0000; - font-weight: bold; - font-style: italic; -} -.highlight .k, .highlight .kd, .highlight .kv { - color: #f6dd62; - font-weight: bold; -} -.highlight .o, .highlight .ow { - color: #4df4ff; - font-weight: bold; -} -.highlight .p, .highlight .pi { - color: #4df4ff; -} -.highlight .gd { - color: #cc0000; -} -.highlight .gi { - color: #b2fd6d; -} -.highlight .ge { - font-style: italic; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gt { - color: #dee5e7; - background-color: #4e5d62; -} -.highlight .kc { - color: #f696db; - font-weight: bold; -} -.highlight .kn { - color: #ffb000; - font-weight: bold; -} -.highlight .kp { - color: #ffb000; - font-weight: bold; -} -.highlight .kr { - color: #ffb000; - font-weight: bold; -} -.highlight .gh { - color: #ffb000; - font-weight: bold; -} -.highlight .gu { - color: #ffb000; - font-weight: bold; -} -.highlight .kt { - color: #b2fd6d; - font-weight: bold; -} -.highlight .no { - color: #b2fd6d; - font-weight: bold; -} -.highlight .nc { - color: #b2fd6d; - font-weight: bold; -} -.highlight .nd { - color: #b2fd6d; - font-weight: bold; -} -.highlight .nn { - color: #b2fd6d; - font-weight: bold; -} -.highlight .bp { - color: #b2fd6d; - font-weight: bold; -} -.highlight .ne { - color: #b2fd6d; - font-weight: bold; -} -.highlight .nl { - color: #ffb000; - font-weight: bold; -} -.highlight .nt { - color: #ffb000; - font-weight: bold; -} -.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { - color: #f696db; - font-weight: bold; -} -.highlight .ld { - color: #f696db; - font-weight: bold; -} -.highlight .ss { - color: #f696db; - font-weight: bold; -} -.highlight .s, .highlight .sb, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .sr, .highlight .s1 { - color: #fff0a6; - font-weight: bold; -} -.highlight .sa { - color: #f6dd62; - font-weight: bold; -} -.highlight .se { - color: #4df4ff; - font-weight: bold; -} -.highlight .sc { - color: #4df4ff; - font-weight: bold; -} -.highlight .si { - color: #4df4ff; - font-weight: bold; -} -.highlight .nb { - font-weight: bold; -} -.highlight .ni { - color: #999999; - font-weight: bold; -} -.highlight .w { - color: #BBBBBB; -} -.highlight .go { - color: #BBBBBB; -} -.highlight .nf, .highlight .fm { - color: #a8e1fe; -} -.highlight .py { - color: #a8e1fe; -} -.highlight .na { - color: #a8e1fe; -} -.highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm { - color: #a8e1fe; - font-weight: bold; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight { + color: #faf6e4; + background-color: #122b3b; +} +.highlight .gl { + color: #dee5e7; + background-color: #4e5d62; +} +.highlight .gp { + color: #a8e1fe; + font-weight: bold; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { + color: #6c8b9f; + font-style: italic; +} +.highlight .cp { + color: #b2fd6d; + font-weight: bold; +} +.highlight .err { + color: #fefeec; + background-color: #cc0000; +} +.highlight .gr { + color: #cc0000; + font-weight: bold; + font-style: italic; +} +.highlight .k, .highlight .kd, .highlight .kv { + color: #f6dd62; + font-weight: bold; +} +.highlight .o, .highlight .ow { + color: #4df4ff; + font-weight: bold; +} +.highlight .p, .highlight .pi { + color: #4df4ff; +} +.highlight .gd { + color: #cc0000; +} +.highlight .gi { + color: #b2fd6d; +} +.highlight .ge { + font-style: italic; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gt { + color: #dee5e7; + background-color: #4e5d62; +} +.highlight .kc { + color: #f696db; + font-weight: bold; +} +.highlight .kn { + color: #ffb000; + font-weight: bold; +} +.highlight .kp { + color: #ffb000; + font-weight: bold; +} +.highlight .kr { + color: #ffb000; + font-weight: bold; +} +.highlight .gh { + color: #ffb000; + font-weight: bold; +} +.highlight .gu { + color: #ffb000; + font-weight: bold; +} +.highlight .kt { + color: #b2fd6d; + font-weight: bold; +} +.highlight .no { + color: #b2fd6d; + font-weight: bold; +} +.highlight .nc { + color: #b2fd6d; + font-weight: bold; +} +.highlight .nd { + color: #b2fd6d; + font-weight: bold; +} +.highlight .nn { + color: #b2fd6d; + font-weight: bold; +} +.highlight .bp { + color: #b2fd6d; + font-weight: bold; +} +.highlight .ne { + color: #b2fd6d; + font-weight: bold; +} +.highlight .nl { + color: #ffb000; + font-weight: bold; +} +.highlight .nt { + color: #ffb000; + font-weight: bold; +} +.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { + color: #f696db; + font-weight: bold; +} +.highlight .ld { + color: #f696db; + font-weight: bold; +} +.highlight .ss { + color: #f696db; + font-weight: bold; +} +.highlight .s, .highlight .sb, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .sr, .highlight .s1 { + color: #fff0a6; + font-weight: bold; +} +.highlight .sa { + color: #f6dd62; + font-weight: bold; +} +.highlight .se { + color: #4df4ff; + font-weight: bold; +} +.highlight .sc { + color: #4df4ff; + font-weight: bold; +} +.highlight .si { + color: #4df4ff; + font-weight: bold; +} +.highlight .nb { + font-weight: bold; +} +.highlight .ni { + color: #999999; + font-weight: bold; +} +.highlight .w { + color: #BBBBBB; +} +.highlight .go { + color: #BBBBBB; +} +.highlight .nf, .highlight .fm { + color: #a8e1fe; +} +.highlight .py { + color: #a8e1fe; +} +.highlight .na { + color: #a8e1fe; +} +.highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm { + color: #a8e1fe; + font-weight: bold; +} diff --git a/assets/gitbook/rouge/tulip.css b/assets/gitbook/rouge/tulip.css index 5fc2a3efb3..d30f5d2dd6 100644 --- a/assets/gitbook/rouge/tulip.css +++ b/assets/gitbook/rouge/tulip.css @@ -1,167 +1,167 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight { - color: #FFFFFF; - background-color: #231529; -} -.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { - color: #6D6E70; - font-style: italic; -} -.highlight .cp { - color: #41ff5b; - font-weight: bold; -} -.highlight .err { - color: #FFFFFF; - background-color: #CC0000; -} -.highlight .gr { - color: #FFFFFF; - background-color: #CC0000; -} -.highlight .k, .highlight .kd, .highlight .kv { - color: #FFF02A; - font-weight: bold; -} -.highlight .o, .highlight .ow { - color: #41ff5b; -} -.highlight .p, .highlight .pi { - color: #41ff5b; -} -.highlight .gd { - color: #CC0000; -} -.highlight .gi { - color: #3FB34F; -} -.highlight .ge { - font-style: italic; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gt { - color: #FFFFFF; - background-color: #766DAF; -} -.highlight .gl { - color: #FFFFFF; - background-color: #766DAF; -} -.highlight .kc { - color: #9f93e6; - font-weight: bold; -} -.highlight .kn { - color: #FFFFFF; - font-weight: bold; -} -.highlight .kp { - color: #FFFFFF; - font-weight: bold; -} -.highlight .kr { - color: #FFFFFF; - font-weight: bold; -} -.highlight .gh { - color: #FFFFFF; - font-weight: bold; -} -.highlight .gu { - color: #FFFFFF; - font-weight: bold; -} -.highlight .kt { - color: #FAAF4C; - font-weight: bold; -} -.highlight .no { - color: #FAAF4C; - font-weight: bold; -} -.highlight .nc { - color: #FAAF4C; - font-weight: bold; -} -.highlight .nd { - color: #FAAF4C; - font-weight: bold; -} -.highlight .nn { - color: #FAAF4C; - font-weight: bold; -} -.highlight .bp { - color: #FAAF4C; - font-weight: bold; -} -.highlight .ne { - color: #FAAF4C; - font-weight: bold; -} -.highlight .nl { - color: #9f93e6; - font-weight: bold; -} -.highlight .nt { - color: #9f93e6; - font-weight: bold; -} -.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { - color: #9f93e6; - font-weight: bold; -} -.highlight .ld { - color: #9f93e6; - font-weight: bold; -} -.highlight .ss { - color: #9f93e6; - font-weight: bold; -} -.highlight .s, .highlight .sb, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .sr, .highlight .s1 { - color: #fff0a6; - font-weight: bold; -} -.highlight .sa { - color: #FFF02A; - font-weight: bold; -} -.highlight .se { - color: #FAAF4C; - font-weight: bold; -} -.highlight .sc { - color: #FAAF4C; - font-weight: bold; -} -.highlight .si { - color: #FAAF4C; - font-weight: bold; -} -.highlight .nb { - font-weight: bold; -} -.highlight .ni { - color: #999999; - font-weight: bold; -} -.highlight .w { - color: #BBBBBB; -} -.highlight .nf, .highlight .fm { - color: #41ff5b; -} -.highlight .py { - color: #41ff5b; -} -.highlight .na { - color: #41ff5b; -} -.highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm { - color: #41ff5b; - font-weight: bold; -} +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight { + color: #FFFFFF; + background-color: #231529; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cpf, .highlight .c1, .highlight .cs { + color: #6D6E70; + font-style: italic; +} +.highlight .cp { + color: #41ff5b; + font-weight: bold; +} +.highlight .err { + color: #FFFFFF; + background-color: #CC0000; +} +.highlight .gr { + color: #FFFFFF; + background-color: #CC0000; +} +.highlight .k, .highlight .kd, .highlight .kv { + color: #FFF02A; + font-weight: bold; +} +.highlight .o, .highlight .ow { + color: #41ff5b; +} +.highlight .p, .highlight .pi { + color: #41ff5b; +} +.highlight .gd { + color: #CC0000; +} +.highlight .gi { + color: #3FB34F; +} +.highlight .ge { + font-style: italic; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gt { + color: #FFFFFF; + background-color: #766DAF; +} +.highlight .gl { + color: #FFFFFF; + background-color: #766DAF; +} +.highlight .kc { + color: #9f93e6; + font-weight: bold; +} +.highlight .kn { + color: #FFFFFF; + font-weight: bold; +} +.highlight .kp { + color: #FFFFFF; + font-weight: bold; +} +.highlight .kr { + color: #FFFFFF; + font-weight: bold; +} +.highlight .gh { + color: #FFFFFF; + font-weight: bold; +} +.highlight .gu { + color: #FFFFFF; + font-weight: bold; +} +.highlight .kt { + color: #FAAF4C; + font-weight: bold; +} +.highlight .no { + color: #FAAF4C; + font-weight: bold; +} +.highlight .nc { + color: #FAAF4C; + font-weight: bold; +} +.highlight .nd { + color: #FAAF4C; + font-weight: bold; +} +.highlight .nn { + color: #FAAF4C; + font-weight: bold; +} +.highlight .bp { + color: #FAAF4C; + font-weight: bold; +} +.highlight .ne { + color: #FAAF4C; + font-weight: bold; +} +.highlight .nl { + color: #9f93e6; + font-weight: bold; +} +.highlight .nt { + color: #9f93e6; + font-weight: bold; +} +.highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx { + color: #9f93e6; + font-weight: bold; +} +.highlight .ld { + color: #9f93e6; + font-weight: bold; +} +.highlight .ss { + color: #9f93e6; + font-weight: bold; +} +.highlight .s, .highlight .sb, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .sr, .highlight .s1 { + color: #fff0a6; + font-weight: bold; +} +.highlight .sa { + color: #FFF02A; + font-weight: bold; +} +.highlight .se { + color: #FAAF4C; + font-weight: bold; +} +.highlight .sc { + color: #FAAF4C; + font-weight: bold; +} +.highlight .si { + color: #FAAF4C; + font-weight: bold; +} +.highlight .nb { + font-weight: bold; +} +.highlight .ni { + color: #999999; + font-weight: bold; +} +.highlight .w { + color: #BBBBBB; +} +.highlight .nf, .highlight .fm { + color: #41ff5b; +} +.highlight .py { + color: #41ff5b; +} +.highlight .na { + color: #41ff5b; +} +.highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm { + color: #41ff5b; + font-weight: bold; +} diff --git a/assets/gitbook/style.css b/assets/gitbook/style.css index e517c6a0c5..9aa2ebff11 100644 --- a/assets/gitbook/style.css +++ b/assets/gitbook/style.css @@ -1,9 +1,4326 @@ -/*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}.link-inherit{color:inherit}.link-inherit:focus,.link-inherit:hover{color:inherit}.hidden{display:none}.alert{padding:15px;margin-bottom:20px;color:#444;background:#eee;border-bottom:5px solid #ddd}.alert-success{background:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-info{background:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-danger{background:#f2dede;border-color:#ebccd1;color:#a94442}.alert-warning{background:#fcf8e3;border-color:#faebcc;color:#8a6d3b}/*! +/*! normalize.css v2.1.0 | MIT License | git.io/normalize */ +article, +aside, +/* details, */ +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section +/* summary */ +{ + display: block +} + +audio, +canvas, +video { + display: inline-block +} + +audio:not([controls]) { + display: none; + height: 0 +} + +[hidden] { + display: none +} + +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100% +} + +body { + margin: 0 +} + +a:focus { + outline: thin dotted +} + +a:active, +a:hover { + outline: 0 +} + +h1 { + font-size: 2em; + margin: .67em 0 +} + +abbr[title] { + border-bottom: 1px dotted +} + +b, +strong { + font-weight: 700 +} + +dfn { + font-style: italic +} + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0 +} + +mark { + background: #ff0; + color: #000 +} + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em +} + +pre { + white-space: pre-wrap +} + +q { + quotes: "\201C" "\201D" "\2018" "\2019" +} + +small { + font-size: 80% +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sup { + top: -.5em +} + +sub { + bottom: -.25em +} + +img { + border: 0 +} + +svg:not(:root) { + overflow: hidden +} + +figure { + margin: 0 +} + +fieldset { + border: 1px solid silver; + margin: 0 2px; + padding: .35em .625em .75em +} + +legend { + border: 0; + padding: 0 +} + +button, +input, +select, +textarea { + font-family: inherit; + font-size: 100%; + margin: 0 +} + +button, +input { + line-height: normal +} + +button, +select { + text-transform: none +} + +button, +html input[type=button], +input[type=reset], +input[type=submit] { + -webkit-appearance: button; + cursor: pointer +} + +button[disabled], +html input[disabled] { + cursor: default +} + +input[type=checkbox], +input[type=radio] { + box-sizing: border-box; + padding: 0 +} + +input[type=search] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box +} + +input[type=search]::-webkit-search-cancel-button, +input[type=search]::-webkit-search-decoration { + -webkit-appearance: none +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0 +} + +textarea { + overflow: auto; + vertical-align: top +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +.link-inherit { + color: inherit +} + +.link-inherit:focus, +.link-inherit:hover { + color: inherit +} + +.hidden { + display: none +} + +.alert { + padding: 15px; + margin-bottom: 20px; + color: #444; + background: #eee; + border-bottom: 5px solid #ddd +} + +.alert-success { + background: #dff0d8; + border-color: #d6e9c6; + color: #3c763d +} + +.alert-info { + background: #d9edf7; + border-color: #bce8f1; + color: #31708f +} + +.alert-danger { + background: #f2dede; + border-color: #ebccd1; + color: #a94442 +} + +.alert-warning { + background: #fcf8e3; + border-color: #faebcc; + color: #8a6d3b +} + +/*! * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome/fontawesome-webfont.eot?v=4.6.3);src:url(fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.6.3) format('embedded-opentype'),url(fonts/fontawesome/fontawesome-webfont.woff2?v=4.6.3) format('woff2'),url(fonts/fontawesome/fontawesome-webfont.woff?v=4.6.3) format('woff'),url(fonts/fontawesome/fontawesome-webfont.ttf?v=4.6.3) format('truetype'),url(fonts/fontawesome/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:"\f2a3"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}/*! + */ +@font-face { + font-family: FontAwesome; + src: url(fonts/fontawesome/fontawesome-webfont.eot?v=4.6.3); + src: url(fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.6.3) format('embedded-opentype'), url(fonts/fontawesome/fontawesome-webfont.woff2?v=4.6.3) format('woff2'), url(fonts/fontawesome/fontawesome-webfont.woff?v=4.6.3) format('woff'), url(fonts/fontawesome/fontawesome-webfont.ttf?v=4.6.3) format('truetype'), url(fonts/fontawesome/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular) format('svg'); + font-weight: 400; + font-style: normal +} + +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale +} + +.fa-lg { + font-size: 1.33333333em; + line-height: .75em; + vertical-align: -15% +} + +.fa-2x { + font-size: 2em +} + +.fa-3x { + font-size: 3em +} + +.fa-4x { + font-size: 4em +} + +.fa-5x { + font-size: 5em +} + +.fa-fw { + width: 1.28571429em; + text-align: center +} + +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none +} + +.fa-ul>li { + position: relative +} + +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: .14285714em; + text-align: center +} + +.fa-li.fa-lg { + left: -1.85714286em +} + +.fa-border { + padding: .2em .25em .15em; + border: solid .08em #eee; + border-radius: .1em +} + +.fa-pull-left { + float: left +} + +.fa-pull-right { + float: right +} + +.fa.fa-pull-left { + margin-right: .3em +} + +.fa.fa-pull-right { + margin-left: .3em +} + +.pull-right { + float: right +} + +.pull-left { + float: left +} + +.fa.pull-left { + margin-right: .3em +} + +.fa.pull-right { + margin-left: .3em +} + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear +} + +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8) +} + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0) + } + + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg) + } +} + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0) + } + + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg) + } +} + +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg) +} + +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg) +} + +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg) +} + +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1) +} + +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1) +} + +:root .fa-flip-horizontal, +:root .fa-flip-vertical, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-rotate-90 { + filter: none +} + +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle +} + +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center +} + +.fa-stack-1x { + line-height: inherit +} + +.fa-stack-2x { + font-size: 2em +} + +.fa-inverse { + color: #fff +} + +.fa-glass:before { + content: "\f000" +} + +.fa-music:before { + content: "\f001" +} + +.fa-search:before { + content: "\f002" +} + +.fa-envelope-o:before { + content: "\f003" +} + +.fa-heart:before { + content: "\f004" +} + +.fa-star:before { + content: "\f005" +} + +.fa-star-o:before { + content: "\f006" +} + +.fa-user:before { + content: "\f007" +} + +.fa-film:before { + content: "\f008" +} + +.fa-th-large:before { + content: "\f009" +} + +.fa-th:before { + content: "\f00a" +} + +.fa-th-list:before { + content: "\f00b" +} + +.fa-check:before { + content: "\f00c" +} + +.fa-close:before, +.fa-remove:before, +.fa-times:before { + content: "\f00d" +} + +.fa-search-plus:before { + content: "\f00e" +} + +.fa-search-minus:before { + content: "\f010" +} + +.fa-power-off:before { + content: "\f011" +} + +.fa-signal:before { + content: "\f012" +} + +.fa-cog:before, +.fa-gear:before { + content: "\f013" +} + +.fa-trash-o:before { + content: "\f014" +} + +.fa-home:before { + content: "\f015" +} + +.fa-file-o:before { + content: "\f016" +} + +.fa-clock-o:before { + content: "\f017" +} + +.fa-road:before { + content: "\f018" +} + +.fa-download:before { + content: "\f019" +} + +.fa-arrow-circle-o-down:before { + content: "\f01a" +} + +.fa-arrow-circle-o-up:before { + content: "\f01b" +} + +.fa-inbox:before { + content: "\f01c" +} + +.fa-play-circle-o:before { + content: "\f01d" +} + +.fa-repeat:before, +.fa-rotate-right:before { + content: "\f01e" +} + +.fa-refresh:before { + content: "\f021" +} + +.fa-list-alt:before { + content: "\f022" +} + +.fa-lock:before { + content: "\f023" +} + +.fa-flag:before { + content: "\f024" +} + +.fa-headphones:before { + content: "\f025" +} + +.fa-volume-off:before { + content: "\f026" +} + +.fa-volume-down:before { + content: "\f027" +} + +.fa-volume-up:before { + content: "\f028" +} + +.fa-qrcode:before { + content: "\f029" +} + +.fa-barcode:before { + content: "\f02a" +} + +.fa-tag:before { + content: "\f02b" +} + +.fa-tags:before { + content: "\f02c" +} + +.fa-book:before { + content: "\f02d" +} + +.fa-bookmark:before { + content: "\f02e" +} + +.fa-print:before { + content: "\f02f" +} + +.fa-camera:before { + content: "\f030" +} + +.fa-font:before { + content: "\f031" +} + +.fa-bold:before { + content: "\f032" +} + +.fa-italic:before { + content: "\f033" +} + +.fa-text-height:before { + content: "\f034" +} + +.fa-text-width:before { + content: "\f035" +} + +.fa-align-left:before { + content: "\f036" +} + +.fa-align-center:before { + content: "\f037" +} + +.fa-align-right:before { + content: "\f038" +} + +.fa-align-justify:before { + content: "\f039" +} + +.fa-list:before { + content: "\f03a" +} + +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b" +} + +.fa-indent:before { + content: "\f03c" +} + +.fa-video-camera:before { + content: "\f03d" +} + +.fa-image:before, +.fa-photo:before, +.fa-picture-o:before { + content: "\f03e" +} + +.fa-pencil:before { + content: "\f040" +} + +.fa-map-marker:before { + content: "\f041" +} + +.fa-adjust:before { + content: "\f042" +} + +.fa-tint:before { + content: "\f043" +} + +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044" +} + +.fa-share-square-o:before { + content: "\f045" +} + +.fa-check-square-o:before { + content: "\f046" +} + +.fa-arrows:before { + content: "\f047" +} + +.fa-step-backward:before { + content: "\f048" +} + +.fa-fast-backward:before { + content: "\f049" +} + +.fa-backward:before { + content: "\f04a" +} + +.fa-play:before { + content: "\f04b" +} + +.fa-pause:before { + content: "\f04c" +} + +.fa-stop:before { + content: "\f04d" +} + +.fa-forward:before { + content: "\f04e" +} + +.fa-fast-forward:before { + content: "\f050" +} + +.fa-step-forward:before { + content: "\f051" +} + +.fa-eject:before { + content: "\f052" +} + +.fa-chevron-left:before { + content: "\f053" +} + +.fa-chevron-right:before { + content: "\f054" +} + +.fa-plus-circle:before { + content: "\f055" +} + +.fa-minus-circle:before { + content: "\f056" +} + +.fa-times-circle:before { + content: "\f057" +} + +.fa-check-circle:before { + content: "\f058" +} + +.fa-question-circle:before { + content: "\f059" +} + +.fa-info-circle:before { + content: "\f05a" +} + +.fa-crosshairs:before { + content: "\f05b" +} + +.fa-times-circle-o:before { + content: "\f05c" +} + +.fa-check-circle-o:before { + content: "\f05d" +} + +.fa-ban:before { + content: "\f05e" +} + +.fa-arrow-left:before { + content: "\f060" +} + +.fa-arrow-right:before { + content: "\f061" +} + +.fa-arrow-up:before { + content: "\f062" +} + +.fa-arrow-down:before { + content: "\f063" +} + +.fa-mail-forward:before, +.fa-share:before { + content: "\f064" +} + +.fa-expand:before { + content: "\f065" +} + +.fa-compress:before { + content: "\f066" +} + +.fa-plus:before { + content: "\f067" +} + +.fa-minus:before { + content: "\f068" +} + +.fa-asterisk:before { + content: "\f069" +} + +.fa-exclamation-circle:before { + content: "\f06a" +} + +.fa-gift:before { + content: "\f06b" +} + +.fa-leaf:before { + content: "\f06c" +} + +.fa-fire:before { + content: "\f06d" +} + +.fa-eye:before { + content: "\f06e" +} + +.fa-eye-slash:before { + content: "\f070" +} + +.fa-exclamation-triangle:before, +.fa-warning:before { + content: "\f071" +} + +.fa-plane:before { + content: "\f072" +} + +.fa-calendar:before { + content: "\f073" +} + +.fa-random:before { + content: "\f074" +} + +.fa-comment:before { + content: "\f075" +} + +.fa-magnet:before { + content: "\f076" +} + +.fa-chevron-up:before { + content: "\f077" +} + +.fa-chevron-down:before { + content: "\f078" +} + +.fa-retweet:before { + content: "\f079" +} + +.fa-shopping-cart:before { + content: "\f07a" +} + +.fa-folder:before { + content: "\f07b" +} + +.fa-folder-open:before { + content: "\f07c" +} + +.fa-arrows-v:before { + content: "\f07d" +} + +.fa-arrows-h:before { + content: "\f07e" +} + +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080" +} + +.fa-twitter-square:before { + content: "\f081" +} + +.fa-facebook-square:before { + content: "\f082" +} + +.fa-camera-retro:before { + content: "\f083" +} + +.fa-key:before { + content: "\f084" +} + +.fa-cogs:before, +.fa-gears:before { + content: "\f085" +} + +.fa-comments:before { + content: "\f086" +} + +.fa-thumbs-o-up:before { + content: "\f087" +} + +.fa-thumbs-o-down:before { + content: "\f088" +} + +.fa-star-half:before { + content: "\f089" +} + +.fa-heart-o:before { + content: "\f08a" +} + +.fa-sign-out:before { + content: "\f08b" +} + +.fa-linkedin-square:before { + content: "\f08c" +} + +.fa-thumb-tack:before { + content: "\f08d" +} + +.fa-external-link:before { + content: "\f08e" +} + +.fa-sign-in:before { + content: "\f090" +} + +.fa-trophy:before { + content: "\f091" +} + +.fa-github-square:before { + content: "\f092" +} + +.fa-upload:before { + content: "\f093" +} + +.fa-lemon-o:before { + content: "\f094" +} + +.fa-phone:before { + content: "\f095" +} + +.fa-square-o:before { + content: "\f096" +} + +.fa-bookmark-o:before { + content: "\f097" +} + +.fa-phone-square:before { + content: "\f098" +} + +.fa-twitter:before { + content: "\f099" +} + +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a" +} + +.fa-github:before { + content: "\f09b" +} + +.fa-unlock:before { + content: "\f09c" +} + +.fa-credit-card:before { + content: "\f09d" +} + +.fa-feed:before, +.fa-rss:before { + content: "\f09e" +} + +.fa-hdd-o:before { + content: "\f0a0" +} + +.fa-bullhorn:before { + content: "\f0a1" +} + +.fa-bell:before { + content: "\f0f3" +} + +.fa-certificate:before { + content: "\f0a3" +} + +.fa-hand-o-right:before { + content: "\f0a4" +} + +.fa-hand-o-left:before { + content: "\f0a5" +} + +.fa-hand-o-up:before { + content: "\f0a6" +} + +.fa-hand-o-down:before { + content: "\f0a7" +} + +.fa-arrow-circle-left:before { + content: "\f0a8" +} + +.fa-arrow-circle-right:before { + content: "\f0a9" +} + +.fa-arrow-circle-up:before { + content: "\f0aa" +} + +.fa-arrow-circle-down:before { + content: "\f0ab" +} + +.fa-globe:before { + content: "\f0ac" +} + +.fa-wrench:before { + content: "\f0ad" +} + +.fa-tasks:before { + content: "\f0ae" +} + +.fa-filter:before { + content: "\f0b0" +} + +.fa-briefcase:before { + content: "\f0b1" +} + +.fa-arrows-alt:before { + content: "\f0b2" +} + +.fa-group:before, +.fa-users:before { + content: "\f0c0" +} + +.fa-chain:before, +.fa-link:before { + content: "\f0c1" +} + +.fa-cloud:before { + content: "\f0c2" +} + +.fa-flask:before { + content: "\f0c3" +} + +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4" +} + +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5" +} + +.fa-paperclip:before { + content: "\f0c6" +} + +.fa-floppy-o:before, +.fa-save:before { + content: "\f0c7" +} + +.fa-square:before { + content: "\f0c8" +} + +.fa-bars:before, +.fa-navicon:before, +.fa-reorder:before { + content: "\f0c9" +} + +.fa-list-ul:before { + content: "\f0ca" +} + +.fa-list-ol:before { + content: "\f0cb" +} + +.fa-strikethrough:before { + content: "\f0cc" +} + +.fa-underline:before { + content: "\f0cd" +} + +.fa-table:before { + content: "\f0ce" +} + +.fa-magic:before { + content: "\f0d0" +} + +.fa-truck:before { + content: "\f0d1" +} + +.fa-pinterest:before { + content: "\f0d2" +} + +.fa-pinterest-square:before { + content: "\f0d3" +} + +.fa-google-plus-square:before { + content: "\f0d4" +} + +.fa-google-plus:before { + content: "\f0d5" +} + +.fa-money:before { + content: "\f0d6" +} + +.fa-caret-down:before { + content: "\f0d7" +} + +.fa-caret-up:before { + content: "\f0d8" +} + +.fa-caret-left:before { + content: "\f0d9" +} + +.fa-caret-right:before { + content: "\f0da" +} + +.fa-columns:before { + content: "\f0db" +} + +.fa-sort:before, +.fa-unsorted:before { + content: "\f0dc" +} + +.fa-sort-desc:before, +.fa-sort-down:before { + content: "\f0dd" +} + +.fa-sort-asc:before, +.fa-sort-up:before { + content: "\f0de" +} + +.fa-envelope:before { + content: "\f0e0" +} + +.fa-linkedin:before { + content: "\f0e1" +} + +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2" +} + +.fa-gavel:before, +.fa-legal:before { + content: "\f0e3" +} + +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4" +} + +.fa-comment-o:before { + content: "\f0e5" +} + +.fa-comments-o:before { + content: "\f0e6" +} + +.fa-bolt:before, +.fa-flash:before { + content: "\f0e7" +} + +.fa-sitemap:before { + content: "\f0e8" +} + +.fa-umbrella:before { + content: "\f0e9" +} + +.fa-clipboard:before, +.fa-paste:before { + content: "\f0ea" +} + +.fa-lightbulb-o:before { + content: "\f0eb" +} + +.fa-exchange:before { + content: "\f0ec" +} + +.fa-cloud-download:before { + content: "\f0ed" +} + +.fa-cloud-upload:before { + content: "\f0ee" +} + +.fa-user-md:before { + content: "\f0f0" +} + +.fa-stethoscope:before { + content: "\f0f1" +} + +.fa-suitcase:before { + content: "\f0f2" +} + +.fa-bell-o:before { + content: "\f0a2" +} + +.fa-coffee:before { + content: "\f0f4" +} + +.fa-cutlery:before { + content: "\f0f5" +} + +.fa-file-text-o:before { + content: "\f0f6" +} + +.fa-building-o:before { + content: "\f0f7" +} + +.fa-hospital-o:before { + content: "\f0f8" +} + +.fa-ambulance:before { + content: "\f0f9" +} + +.fa-medkit:before { + content: "\f0fa" +} + +.fa-fighter-jet:before { + content: "\f0fb" +} + +.fa-beer:before { + content: "\f0fc" +} + +.fa-h-square:before { + content: "\f0fd" +} + +.fa-plus-square:before { + content: "\f0fe" +} + +.fa-angle-double-left:before { + content: "\f100" +} + +.fa-angle-double-right:before { + content: "\f101" +} + +.fa-angle-double-up:before { + content: "\f102" +} + +.fa-angle-double-down:before { + content: "\f103" +} + +.fa-angle-left:before { + content: "\f104" +} + +.fa-angle-right:before { + content: "\f105" +} + +.fa-angle-up:before { + content: "\f106" +} + +.fa-angle-down:before { + content: "\f107" +} + +.fa-desktop:before { + content: "\f108" +} + +.fa-laptop:before { + content: "\f109" +} + +.fa-tablet:before { + content: "\f10a" +} + +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b" +} + +.fa-circle-o:before { + content: "\f10c" +} + +.fa-quote-left:before { + content: "\f10d" +} + +.fa-quote-right:before { + content: "\f10e" +} + +.fa-spinner:before { + content: "\f110" +} + +.fa-circle:before { + content: "\f111" +} + +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112" +} + +.fa-github-alt:before { + content: "\f113" +} + +.fa-folder-o:before { + content: "\f114" +} + +.fa-folder-open-o:before { + content: "\f115" +} + +.fa-smile-o:before { + content: "\f118" +} + +.fa-frown-o:before { + content: "\f119" +} + +.fa-meh-o:before { + content: "\f11a" +} + +.fa-gamepad:before { + content: "\f11b" +} + +.fa-keyboard-o:before { + content: "\f11c" +} + +.fa-flag-o:before { + content: "\f11d" +} + +.fa-flag-checkered:before { + content: "\f11e" +} + +.fa-terminal:before { + content: "\f120" +} + +.fa-code:before { + content: "\f121" +} + +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122" +} + +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123" +} + +.fa-location-arrow:before { + content: "\f124" +} + +.fa-crop:before { + content: "\f125" +} + +.fa-code-fork:before { + content: "\f126" +} + +.fa-chain-broken:before, +.fa-unlink:before { + content: "\f127" +} + +.fa-question:before { + content: "\f128" +} + +.fa-info:before { + content: "\f129" +} + +.fa-exclamation:before { + content: "\f12a" +} + +.fa-superscript:before { + content: "\f12b" +} + +.fa-subscript:before { + content: "\f12c" +} + +.fa-eraser:before { + content: "\f12d" +} + +.fa-puzzle-piece:before { + content: "\f12e" +} + +.fa-microphone:before { + content: "\f130" +} + +.fa-microphone-slash:before { + content: "\f131" +} + +.fa-shield:before { + content: "\f132" +} + +.fa-calendar-o:before { + content: "\f133" +} + +.fa-fire-extinguisher:before { + content: "\f134" +} + +.fa-rocket:before { + content: "\f135" +} + +.fa-maxcdn:before { + content: "\f136" +} + +.fa-chevron-circle-left:before { + content: "\f137" +} + +.fa-chevron-circle-right:before { + content: "\f138" +} + +.fa-chevron-circle-up:before { + content: "\f139" +} + +.fa-chevron-circle-down:before { + content: "\f13a" +} + +.fa-html5:before { + content: "\f13b" +} + +.fa-css3:before { + content: "\f13c" +} + +.fa-anchor:before { + content: "\f13d" +} + +.fa-unlock-alt:before { + content: "\f13e" +} + +.fa-bullseye:before { + content: "\f140" +} + +.fa-ellipsis-h:before { + content: "\f141" +} + +.fa-ellipsis-v:before { + content: "\f142" +} + +.fa-rss-square:before { + content: "\f143" +} + +.fa-play-circle:before { + content: "\f144" +} + +.fa-ticket:before { + content: "\f145" +} + +.fa-minus-square:before { + content: "\f146" +} + +.fa-minus-square-o:before { + content: "\f147" +} + +.fa-level-up:before { + content: "\f148" +} + +.fa-level-down:before { + content: "\f149" +} + +.fa-check-square:before { + content: "\f14a" +} + +.fa-pencil-square:before { + content: "\f14b" +} + +.fa-external-link-square:before { + content: "\f14c" +} + +.fa-share-square:before { + content: "\f14d" +} + +.fa-compass:before { + content: "\f14e" +} + +.fa-caret-square-o-down:before, +.fa-toggle-down:before { + content: "\f150" +} + +.fa-caret-square-o-up:before, +.fa-toggle-up:before { + content: "\f151" +} + +.fa-caret-square-o-right:before, +.fa-toggle-right:before { + content: "\f152" +} + +.fa-eur:before, +.fa-euro:before { + content: "\f153" +} + +.fa-gbp:before { + content: "\f154" +} + +.fa-dollar:before, +.fa-usd:before { + content: "\f155" +} + +.fa-inr:before, +.fa-rupee:before { + content: "\f156" +} + +.fa-cny:before, +.fa-jpy:before, +.fa-rmb:before, +.fa-yen:before { + content: "\f157" +} + +.fa-rouble:before, +.fa-rub:before, +.fa-ruble:before { + content: "\f158" +} + +.fa-krw:before, +.fa-won:before { + content: "\f159" +} + +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a" +} + +.fa-file:before { + content: "\f15b" +} + +.fa-file-text:before { + content: "\f15c" +} + +.fa-sort-alpha-asc:before { + content: "\f15d" +} + +.fa-sort-alpha-desc:before { + content: "\f15e" +} + +.fa-sort-amount-asc:before { + content: "\f160" +} + +.fa-sort-amount-desc:before { + content: "\f161" +} + +.fa-sort-numeric-asc:before { + content: "\f162" +} + +.fa-sort-numeric-desc:before { + content: "\f163" +} + +.fa-thumbs-up:before { + content: "\f164" +} + +.fa-thumbs-down:before { + content: "\f165" +} + +.fa-youtube-square:before { + content: "\f166" +} + +.fa-youtube:before { + content: "\f167" +} + +.fa-xing:before { + content: "\f168" +} + +.fa-xing-square:before { + content: "\f169" +} + +.fa-youtube-play:before { + content: "\f16a" +} + +.fa-dropbox:before { + content: "\f16b" +} + +.fa-stack-overflow:before { + content: "\f16c" +} + +.fa-instagram:before { + content: "\f16d" +} + +.fa-flickr:before { + content: "\f16e" +} + +.fa-adn:before { + content: "\f170" +} + +.fa-bitbucket:before { + content: "\f171" +} + +.fa-bitbucket-square:before { + content: "\f172" +} + +.fa-tumblr:before { + content: "\f173" +} + +.fa-tumblr-square:before { + content: "\f174" +} + +.fa-long-arrow-down:before { + content: "\f175" +} + +.fa-long-arrow-up:before { + content: "\f176" +} + +.fa-long-arrow-left:before { + content: "\f177" +} + +.fa-long-arrow-right:before { + content: "\f178" +} + +.fa-apple:before { + content: "\f179" +} + +.fa-windows:before { + content: "\f17a" +} + +.fa-android:before { + content: "\f17b" +} + +.fa-linux:before { + content: "\f17c" +} + +.fa-dribbble:before { + content: "\f17d" +} + +.fa-skype:before { + content: "\f17e" +} + +.fa-foursquare:before { + content: "\f180" +} + +.fa-trello:before { + content: "\f181" +} + +.fa-female:before { + content: "\f182" +} + +.fa-male:before { + content: "\f183" +} + +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184" +} + +.fa-sun-o:before { + content: "\f185" +} + +.fa-moon-o:before { + content: "\f186" +} + +.fa-archive:before { + content: "\f187" +} + +.fa-bug:before { + content: "\f188" +} + +.fa-vk:before { + content: "\f189" +} + +.fa-weibo:before { + content: "\f18a" +} + +.fa-renren:before { + content: "\f18b" +} + +.fa-pagelines:before { + content: "\f18c" +} + +.fa-stack-exchange:before { + content: "\f18d" +} + +.fa-arrow-circle-o-right:before { + content: "\f18e" +} + +.fa-arrow-circle-o-left:before { + content: "\f190" +} + +.fa-caret-square-o-left:before, +.fa-toggle-left:before { + content: "\f191" +} + +.fa-dot-circle-o:before { + content: "\f192" +} + +.fa-wheelchair:before { + content: "\f193" +} + +.fa-vimeo-square:before { + content: "\f194" +} + +.fa-try:before, +.fa-turkish-lira:before { + content: "\f195" +} + +.fa-plus-square-o:before { + content: "\f196" +} + +.fa-space-shuttle:before { + content: "\f197" +} + +.fa-slack:before { + content: "\f198" +} + +.fa-envelope-square:before { + content: "\f199" +} + +.fa-wordpress:before { + content: "\f19a" +} + +.fa-openid:before { + content: "\f19b" +} + +.fa-bank:before, +.fa-institution:before, +.fa-university:before { + content: "\f19c" +} + +.fa-graduation-cap:before, +.fa-mortar-board:before { + content: "\f19d" +} + +.fa-yahoo:before { + content: "\f19e" +} + +.fa-google:before { + content: "\f1a0" +} + +.fa-reddit:before { + content: "\f1a1" +} + +.fa-reddit-square:before { + content: "\f1a2" +} + +.fa-stumbleupon-circle:before { + content: "\f1a3" +} + +.fa-stumbleupon:before { + content: "\f1a4" +} + +.fa-delicious:before { + content: "\f1a5" +} + +.fa-digg:before { + content: "\f1a6" +} + +.fa-pied-piper-pp:before { + content: "\f1a7" +} + +.fa-pied-piper-alt:before { + content: "\f1a8" +} + +.fa-drupal:before { + content: "\f1a9" +} + +.fa-joomla:before { + content: "\f1aa" +} + +.fa-language:before { + content: "\f1ab" +} + +.fa-fax:before { + content: "\f1ac" +} + +.fa-building:before { + content: "\f1ad" +} + +.fa-child:before { + content: "\f1ae" +} + +.fa-paw:before { + content: "\f1b0" +} + +.fa-spoon:before { + content: "\f1b1" +} + +.fa-cube:before { + content: "\f1b2" +} + +.fa-cubes:before { + content: "\f1b3" +} + +.fa-behance:before { + content: "\f1b4" +} + +.fa-behance-square:before { + content: "\f1b5" +} + +.fa-steam:before { + content: "\f1b6" +} + +.fa-steam-square:before { + content: "\f1b7" +} + +.fa-recycle:before { + content: "\f1b8" +} + +.fa-automobile:before, +.fa-car:before { + content: "\f1b9" +} + +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba" +} + +.fa-tree:before { + content: "\f1bb" +} + +.fa-spotify:before { + content: "\f1bc" +} + +.fa-deviantart:before { + content: "\f1bd" +} + +.fa-soundcloud:before { + content: "\f1be" +} + +.fa-database:before { + content: "\f1c0" +} + +.fa-file-pdf-o:before { + content: "\f1c1" +} + +.fa-file-word-o:before { + content: "\f1c2" +} + +.fa-file-excel-o:before { + content: "\f1c3" +} + +.fa-file-powerpoint-o:before { + content: "\f1c4" +} + +.fa-file-image-o:before, +.fa-file-photo-o:before, +.fa-file-picture-o:before { + content: "\f1c5" +} + +.fa-file-archive-o:before, +.fa-file-zip-o:before { + content: "\f1c6" +} + +.fa-file-audio-o:before, +.fa-file-sound-o:before { + content: "\f1c7" +} + +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8" +} + +.fa-file-code-o:before { + content: "\f1c9" +} + +.fa-vine:before { + content: "\f1ca" +} + +.fa-codepen:before { + content: "\f1cb" +} + +.fa-jsfiddle:before { + content: "\f1cc" +} + +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-ring:before, +.fa-life-saver:before, +.fa-support:before { + content: "\f1cd" +} + +.fa-circle-o-notch:before { + content: "\f1ce" +} + +.fa-ra:before, +.fa-rebel:before, +.fa-resistance:before { + content: "\f1d0" +} + +.fa-empire:before, +.fa-ge:before { + content: "\f1d1" +} + +.fa-git-square:before { + content: "\f1d2" +} + +.fa-git:before { + content: "\f1d3" +} + +.fa-hacker-news:before, +.fa-y-combinator-square:before, +.fa-yc-square:before { + content: "\f1d4" +} + +.fa-tencent-weibo:before { + content: "\f1d5" +} + +.fa-qq:before { + content: "\f1d6" +} + +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7" +} + +.fa-paper-plane:before, +.fa-send:before { + content: "\f1d8" +} + +.fa-paper-plane-o:before, +.fa-send-o:before { + content: "\f1d9" +} + +.fa-history:before { + content: "\f1da" +} + +.fa-circle-thin:before { + content: "\f1db" +} + +.fa-header:before { + content: "\f1dc" +} + +.fa-paragraph:before { + content: "\f1dd" +} + +.fa-sliders:before { + content: "\f1de" +} + +.fa-share-alt:before { + content: "\f1e0" +} + +.fa-share-alt-square:before { + content: "\f1e1" +} + +.fa-bomb:before { + content: "\f1e2" +} + +.fa-futbol-o:before, +.fa-soccer-ball-o:before { + content: "\f1e3" +} + +.fa-tty:before { + content: "\f1e4" +} + +.fa-binoculars:before { + content: "\f1e5" +} + +.fa-plug:before { + content: "\f1e6" +} + +.fa-slideshare:before { + content: "\f1e7" +} + +.fa-twitch:before { + content: "\f1e8" +} + +.fa-yelp:before { + content: "\f1e9" +} + +.fa-newspaper-o:before { + content: "\f1ea" +} + +.fa-wifi:before { + content: "\f1eb" +} + +.fa-calculator:before { + content: "\f1ec" +} + +.fa-paypal:before { + content: "\f1ed" +} + +.fa-google-wallet:before { + content: "\f1ee" +} + +.fa-cc-visa:before { + content: "\f1f0" +} + +.fa-cc-mastercard:before { + content: "\f1f1" +} + +.fa-cc-discover:before { + content: "\f1f2" +} + +.fa-cc-amex:before { + content: "\f1f3" +} + +.fa-cc-paypal:before { + content: "\f1f4" +} + +.fa-cc-stripe:before { + content: "\f1f5" +} + +.fa-bell-slash:before { + content: "\f1f6" +} + +.fa-bell-slash-o:before { + content: "\f1f7" +} + +.fa-trash:before { + content: "\f1f8" +} + +.fa-copyright:before { + content: "\f1f9" +} + +.fa-at:before { + content: "\f1fa" +} + +.fa-eyedropper:before { + content: "\f1fb" +} + +.fa-paint-brush:before { + content: "\f1fc" +} + +.fa-birthday-cake:before { + content: "\f1fd" +} + +.fa-area-chart:before { + content: "\f1fe" +} + +.fa-pie-chart:before { + content: "\f200" +} + +.fa-line-chart:before { + content: "\f201" +} + +.fa-lastfm:before { + content: "\f202" +} + +.fa-lastfm-square:before { + content: "\f203" +} + +.fa-toggle-off:before { + content: "\f204" +} + +.fa-toggle-on:before { + content: "\f205" +} + +.fa-bicycle:before { + content: "\f206" +} + +.fa-bus:before { + content: "\f207" +} + +.fa-ioxhost:before { + content: "\f208" +} + +.fa-angellist:before { + content: "\f209" +} + +.fa-cc:before { + content: "\f20a" +} + +.fa-ils:before, +.fa-shekel:before, +.fa-sheqel:before { + content: "\f20b" +} + +.fa-meanpath:before { + content: "\f20c" +} + +.fa-buysellads:before { + content: "\f20d" +} + +.fa-connectdevelop:before { + content: "\f20e" +} + +.fa-dashcube:before { + content: "\f210" +} + +.fa-forumbee:before { + content: "\f211" +} + +.fa-leanpub:before { + content: "\f212" +} + +.fa-sellsy:before { + content: "\f213" +} + +.fa-shirtsinbulk:before { + content: "\f214" +} + +.fa-simplybuilt:before { + content: "\f215" +} + +.fa-skyatlas:before { + content: "\f216" +} + +.fa-cart-plus:before { + content: "\f217" +} + +.fa-cart-arrow-down:before { + content: "\f218" +} + +.fa-diamond:before { + content: "\f219" +} + +.fa-ship:before { + content: "\f21a" +} + +.fa-user-secret:before { + content: "\f21b" +} + +.fa-motorcycle:before { + content: "\f21c" +} + +.fa-street-view:before { + content: "\f21d" +} + +.fa-heartbeat:before { + content: "\f21e" +} + +.fa-venus:before { + content: "\f221" +} + +.fa-mars:before { + content: "\f222" +} + +.fa-mercury:before { + content: "\f223" +} + +.fa-intersex:before, +.fa-transgender:before { + content: "\f224" +} + +.fa-transgender-alt:before { + content: "\f225" +} + +.fa-venus-double:before { + content: "\f226" +} + +.fa-mars-double:before { + content: "\f227" +} + +.fa-venus-mars:before { + content: "\f228" +} + +.fa-mars-stroke:before { + content: "\f229" +} + +.fa-mars-stroke-v:before { + content: "\f22a" +} + +.fa-mars-stroke-h:before { + content: "\f22b" +} + +.fa-neuter:before { + content: "\f22c" +} + +.fa-genderless:before { + content: "\f22d" +} + +.fa-facebook-official:before { + content: "\f230" +} + +.fa-pinterest-p:before { + content: "\f231" +} + +.fa-whatsapp:before { + content: "\f232" +} + +.fa-server:before { + content: "\f233" +} + +.fa-user-plus:before { + content: "\f234" +} + +.fa-user-times:before { + content: "\f235" +} + +.fa-bed:before, +.fa-hotel:before { + content: "\f236" +} + +.fa-viacoin:before { + content: "\f237" +} + +.fa-train:before { + content: "\f238" +} + +.fa-subway:before { + content: "\f239" +} + +.fa-medium:before { + content: "\f23a" +} + +.fa-y-combinator:before, +.fa-yc:before { + content: "\f23b" +} + +.fa-optin-monster:before { + content: "\f23c" +} + +.fa-opencart:before { + content: "\f23d" +} + +.fa-expeditedssl:before { + content: "\f23e" +} + +.fa-battery-4:before, +.fa-battery-full:before { + content: "\f240" +} + +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241" +} + +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242" +} + +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243" +} + +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244" +} + +.fa-mouse-pointer:before { + content: "\f245" +} + +.fa-i-cursor:before { + content: "\f246" +} + +.fa-object-group:before { + content: "\f247" +} + +.fa-object-ungroup:before { + content: "\f248" +} + +.fa-sticky-note:before { + content: "\f249" +} + +.fa-sticky-note-o:before { + content: "\f24a" +} + +.fa-cc-jcb:before { + content: "\f24b" +} + +.fa-cc-diners-club:before { + content: "\f24c" +} + +.fa-clone:before { + content: "\f24d" +} + +.fa-balance-scale:before { + content: "\f24e" +} + +.fa-hourglass-o:before { + content: "\f250" +} + +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251" +} + +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252" +} + +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253" +} + +.fa-hourglass:before { + content: "\f254" +} + +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255" +} + +.fa-hand-paper-o:before, +.fa-hand-stop-o:before { + content: "\f256" +} + +.fa-hand-scissors-o:before { + content: "\f257" +} + +.fa-hand-lizard-o:before { + content: "\f258" +} + +.fa-hand-spock-o:before { + content: "\f259" +} + +.fa-hand-pointer-o:before { + content: "\f25a" +} + +.fa-hand-peace-o:before { + content: "\f25b" +} + +.fa-trademark:before { + content: "\f25c" +} + +.fa-registered:before { + content: "\f25d" +} + +.fa-creative-commons:before { + content: "\f25e" +} + +.fa-gg:before { + content: "\f260" +} + +.fa-gg-circle:before { + content: "\f261" +} + +.fa-tripadvisor:before { + content: "\f262" +} + +.fa-odnoklassniki:before { + content: "\f263" +} + +.fa-odnoklassniki-square:before { + content: "\f264" +} + +.fa-get-pocket:before { + content: "\f265" +} + +.fa-wikipedia-w:before { + content: "\f266" +} + +.fa-safari:before { + content: "\f267" +} + +.fa-chrome:before { + content: "\f268" +} + +.fa-firefox:before { + content: "\f269" +} + +.fa-opera:before { + content: "\f26a" +} + +.fa-internet-explorer:before { + content: "\f26b" +} + +.fa-television:before, +.fa-tv:before { + content: "\f26c" +} + +.fa-contao:before { + content: "\f26d" +} + +.fa-500px:before { + content: "\f26e" +} + +.fa-amazon:before { + content: "\f270" +} + +.fa-calendar-plus-o:before { + content: "\f271" +} + +.fa-calendar-minus-o:before { + content: "\f272" +} + +.fa-calendar-times-o:before { + content: "\f273" +} + +.fa-calendar-check-o:before { + content: "\f274" +} + +.fa-industry:before { + content: "\f275" +} + +.fa-map-pin:before { + content: "\f276" +} + +.fa-map-signs:before { + content: "\f277" +} + +.fa-map-o:before { + content: "\f278" +} + +.fa-map:before { + content: "\f279" +} + +.fa-commenting:before { + content: "\f27a" +} + +.fa-commenting-o:before { + content: "\f27b" +} + +.fa-houzz:before { + content: "\f27c" +} + +.fa-vimeo:before { + content: "\f27d" +} + +.fa-black-tie:before { + content: "\f27e" +} + +.fa-fonticons:before { + content: "\f280" +} + +.fa-reddit-alien:before { + content: "\f281" +} + +.fa-edge:before { + content: "\f282" +} + +.fa-credit-card-alt:before { + content: "\f283" +} + +.fa-codiepie:before { + content: "\f284" +} + +.fa-modx:before { + content: "\f285" +} + +.fa-fort-awesome:before { + content: "\f286" +} + +.fa-usb:before { + content: "\f287" +} + +.fa-product-hunt:before { + content: "\f288" +} + +.fa-mixcloud:before { + content: "\f289" +} + +.fa-scribd:before { + content: "\f28a" +} + +.fa-pause-circle:before { + content: "\f28b" +} + +.fa-pause-circle-o:before { + content: "\f28c" +} + +.fa-stop-circle:before { + content: "\f28d" +} + +.fa-stop-circle-o:before { + content: "\f28e" +} + +.fa-shopping-bag:before { + content: "\f290" +} + +.fa-shopping-basket:before { + content: "\f291" +} + +.fa-hashtag:before { + content: "\f292" +} + +.fa-bluetooth:before { + content: "\f293" +} + +.fa-bluetooth-b:before { + content: "\f294" +} + +.fa-percent:before { + content: "\f295" +} + +.fa-gitlab:before { + content: "\f296" +} + +.fa-wpbeginner:before { + content: "\f297" +} + +.fa-wpforms:before { + content: "\f298" +} + +.fa-envira:before { + content: "\f299" +} + +.fa-universal-access:before { + content: "\f29a" +} + +.fa-wheelchair-alt:before { + content: "\f29b" +} + +.fa-question-circle-o:before { + content: "\f29c" +} + +.fa-blind:before { + content: "\f29d" +} + +.fa-audio-description:before { + content: "\f29e" +} + +.fa-volume-control-phone:before { + content: "\f2a0" +} + +.fa-braille:before { + content: "\f2a1" +} + +.fa-assistive-listening-systems:before { + content: "\f2a2" +} + +.fa-american-sign-language-interpreting:before, +.fa-asl-interpreting:before { + content: "\f2a3" +} + +.fa-deaf:before, +.fa-deafness:before, +.fa-hard-of-hearing:before { + content: "\f2a4" +} + +.fa-glide:before { + content: "\f2a5" +} + +.fa-glide-g:before { + content: "\f2a6" +} + +.fa-sign-language:before, +.fa-signing:before { + content: "\f2a7" +} + +.fa-low-vision:before { + content: "\f2a8" +} + +.fa-viadeo:before { + content: "\f2a9" +} + +.fa-viadeo-square:before { + content: "\f2aa" +} + +.fa-snapchat:before { + content: "\f2ab" +} + +.fa-snapchat-ghost:before { + content: "\f2ac" +} + +.fa-snapchat-square:before { + content: "\f2ad" +} + +.fa-pied-piper:before { + content: "\f2ae" +} + +.fa-first-order:before { + content: "\f2b0" +} + +.fa-yoast:before { + content: "\f2b1" +} + +.fa-themeisle:before { + content: "\f2b2" +} + +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3" +} + +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4" +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0 +} + +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto +} + +/*! * Preboot v2 * * Open sourced under MIT license by @mdo. * Some variables and mixins from Bootstrap (Apache 2 license). - */.book-langs-index{width:100%;height:100%;padding:40px 0;margin:0;overflow:auto}@media (max-width:600px){.book-langs-index{padding:0}}.book-langs-index .inner{max-width:600px;width:100%;margin:0 auto;padding:30px;background:#fff;border-radius:3px}.book-langs-index .inner h3{margin:0}.book-langs-index .inner .languages{list-style:none;padding:20px 30px;margin-top:20px;border-top:1px solid #eee}.book-langs-index .inner .languages:after,.book-langs-index .inner .languages:before{content:" ";display:table;line-height:0}.book-langs-index .inner .languages:after{clear:both}.book-langs-index .inner .languages li{width:50%;float:left;padding:10px 5px;font-size:16px}@media (max-width:600px){.book-langs-index .inner .languages li{width:100%;max-width:100%}}.book-header{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;overflow:visible;height:50px;padding:0 8px;z-index:2;font-size:.85em;color:#7e888b;background:0 0}.book-header .btn{display:block;height:50px;padding:0 15px;border-bottom:none;color:#ccc;text-transform:uppercase;line-height:50px;-webkit-box-shadow:none!important;box-shadow:none!important;position:relative;font-size:14px}.book-header .btn:hover{position:relative;text-decoration:none;color:#444;background:0 0}.book-header .btn:focus{outline:0}.book-header h1{margin:0;font-size:20px;font-weight:200;text-align:center;line-height:50px;opacity:0;-webkit-transition:opacity ease .4s;-moz-transition:opacity ease .4s;-o-transition:opacity ease .4s;transition:opacity ease .4s;padding-left:200px;padding-right:200px;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;-o-transition:opacity .2s ease;transition:opacity .2s ease;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.book-header h1 a,.book-header h1 a:hover{color:inherit;text-decoration:none}@media (max-width:1000px){.book-header h1{display:none}}.book-header h1 i{display:none}.book-header:hover h1{opacity:1}.book.is-loading .book-header h1 i{display:inline-block}.book.is-loading .book-header h1 a{display:none}.dropdown{position:relative}.dropdown-menu{position:absolute;top:100%;left:0;z-index:100;display:none;float:left;min-width:160px;padding:0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fafafa;border:1px solid rgba(0,0,0,.07);border-radius:1px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.open{display:block}.dropdown-menu.dropdown-left{left:auto;right:4%}.dropdown-menu.dropdown-left .dropdown-caret{right:14px;left:auto}.dropdown-menu .dropdown-caret{position:absolute;top:-8px;left:14px;width:18px;height:10px;float:left;overflow:hidden}.dropdown-menu .dropdown-caret .caret-outer{position:absolute;border-left:9px solid transparent;border-right:9px solid transparent;border-bottom:9px solid rgba(0,0,0,.1);height:auto;left:0;top:0;width:auto;display:inline-block;margin-left:-1px}.dropdown-menu .dropdown-caret .caret-inner{position:absolute;display:inline-block;margin-top:-1px;top:0;top:1px;border-left:9px solid transparent;border-right:9px solid transparent;border-bottom:9px solid #fafafa}.dropdown-menu .buttons{border-bottom:1px solid rgba(0,0,0,.07)}.dropdown-menu .buttons:after,.dropdown-menu .buttons:before{content:" ";display:table;line-height:0}.dropdown-menu .buttons:after{clear:both}.dropdown-menu .buttons:last-child{border-bottom:none}.dropdown-menu .buttons .button{border:0;background-color:transparent;color:#a6a6a6;width:100%;text-align:center;float:left;line-height:1.42857143;padding:8px 4px}.dropdown-menu .buttons .button:hover{color:#444}.dropdown-menu .buttons .button:focus,.dropdown-menu .buttons .button:hover{outline:0}.dropdown-menu .buttons .button.size-2{width:50%}.dropdown-menu .buttons .button.size-3{width:33%}.book-summary{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;position:absolute;top:0;left:-300px;bottom:0;z-index:1;overflow-y:auto;width:300px;color:#364149;background:#fafafa;border-right:1px solid rgba(0,0,0,.07);-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}.book-summary ul.summary{list-style:none;margin:0;padding:0;-webkit-transition:top .5s ease;-moz-transition:top .5s ease;-o-transition:top .5s ease;transition:top .5s ease}.book-summary ul.summary li{list-style:none}.book-summary ul.summary li.header{padding:10px 15px;padding-top:20px;text-transform:uppercase;color:#939da3}.book-summary ul.summary li.divider{height:1px;margin:7px 0;overflow:hidden;background:rgba(0,0,0,.07)}.book-summary ul.summary li i.fa-check{display:none;position:absolute;right:9px;top:16px;font-size:9px;color:#3c3}.book-summary ul.summary li.done>a{color:#364149;font-weight:400}.book-summary ul.summary li.done>a i{display:inline}.book-summary ul.summary li a,.book-summary ul.summary li span{display:block;padding:10px 15px;border-bottom:none;color:#364149;background:0 0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;position:relative}.book-summary ul.summary li a:hover{text-decoration:underline}.book-summary ul.summary li a:focus{outline:0}.book-summary ul.summary li.active>a{color:#008cff;background:0 0;text-decoration:none}.book-summary ul.summary li ul{padding-left:20px}@media (max-width:600px){.book-summary{width:calc(100% - 60px);bottom:0;left:-100%}}.book.with-summary .book-summary{left:0}.book.without-animation .book-summary{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book{position:relative;width:100%;height:100%}@media (min-width:600px){.book.with-summary .book-body{left:300px}}@media (max-width:600px){.book.with-summary{overflow:hidden}.book.with-summary .book-body{-webkit-transform:translate(calc(100% - 60px),0);-moz-transform:translate(calc(100% - 60px),0);-ms-transform:translate(calc(100% - 60px),0);-o-transform:translate(calc(100% - 60px),0);transform:translate(calc(100% - 60px),0)}}.book.without-animation .book-body{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.book-body{position:absolute;top:0;right:0;left:0;bottom:0;overflow-y:auto;color:#000;background:#fff;-webkit-transition:left 250ms ease;-moz-transition:left 250ms ease;-o-transition:left 250ms ease;transition:left 250ms ease}.book-body .body-inner{position:absolute;top:0;right:0;left:0;bottom:0;overflow-y:auto}@media (max-width:1240px){.book-body{-webkit-transition:-webkit-transform 250ms ease;-moz-transition:-moz-transform 250ms ease;-o-transition:-o-transform 250ms ease;transition:transform 250ms ease;padding-bottom:20px}.book-body .body-inner{position:static;min-height:calc(100% - 50px)}}.page-wrapper{position:relative;outline:0}.page-inner{position:relative;max-width:800px;margin:0 auto;padding:20px 15px 40px 15px}.page-inner .btn-group .btn{border-radius:0;background:#eee;border:0}.buttons:after,.buttons:before{content:" ";display:table;line-height:0}.buttons:after{clear:both}.button{border:0;background-color:transparent;background:#eee;color:#666;width:100%;text-align:center;float:left;line-height:1.42857143;padding:8px 4px}.button:hover{color:#444}.button:focus,.button:hover{outline:0}.button.size-2{width:50%}.button.size-3{width:33%}.markdown-section{display:block;word-wrap:break-word;overflow:hidden;color:#333;line-height:1.7;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%}.markdown-section *{box-sizing:border-box;-webkit-box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}.markdown-section>:last-child{margin-bottom:0!important}.markdown-section blockquote,.markdown-section code,.markdown-section figure,.markdown-section img,.markdown-section pre,.markdown-section table,.markdown-section tr{page-break-inside:avoid}.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5,.markdown-section p{orphans:3;widows:3}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5{page-break-after:avoid}.markdown-section b,.markdown-section strong{font-weight:700}.markdown-section em{font-style:italic}.markdown-section blockquote,.markdown-section dl,.markdown-section ol,.markdown-section p,.markdown-section table,.markdown-section ul{margin-top:0;margin-bottom:.85em}.markdown-section a{color:#4183c4;text-decoration:none;background:0 0}.markdown-section a:active,.markdown-section a:focus,.markdown-section a:hover{outline:0;text-decoration:underline}.markdown-section img{border:0;max-width:100%}.markdown-section hr{height:4px;padding:0;margin:1.7em 0;overflow:hidden;background-color:#e7e7e7;border:none}.markdown-section hr:after,.markdown-section hr:before{display:table;content:" "}.markdown-section hr:after{clear:both}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section h5,.markdown-section h6{margin-top:1.275em;margin-bottom:.85em;font-weight:700}.markdown-section h1{font-size:2em}.markdown-section h2{font-size:1.75em}.markdown-section h3{font-size:1.5em}.markdown-section h4{font-size:1.25em}.markdown-section h5{font-size:1em}.markdown-section h6{font-size:1em;color:#777}.markdown-section code,.markdown-section pre{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;direction:ltr;margin:0;padding:0;border:none;color:inherit}.markdown-section pre{overflow:auto;word-wrap:normal;margin:0;padding:.85em 1em;margin-bottom:1.275em;background:#f7f7f7}.markdown-section pre>code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;font-size:.85em;white-space:pre;background:0 0}.markdown-section pre>code:after,.markdown-section pre>code:before{content:normal}.markdown-section code{padding:.2em;margin:0;font-size:.85em;background-color:#f7f7f7}.markdown-section code:after,.markdown-section code:before{letter-spacing:-.2em;content:"\00a0"}.markdown-section table{display:table;width:100%;border-collapse:collapse;border-spacing:0;overflow:auto}.markdown-section table td,.markdown-section table th{padding:6px 13px;border:1px solid #ddd}.markdown-section table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-section table tr:nth-child(2n){background-color:#f8f8f8}.markdown-section table th{font-weight:700}.markdown-section ol,.markdown-section ul{padding:0;margin:0;margin-bottom:.85em;padding-left:2em}.markdown-section ol ol,.markdown-section ol ul,.markdown-section ul ol,.markdown-section ul ul{margin-top:0;margin-bottom:0}.markdown-section ol ol{list-style-type:lower-roman}.markdown-section blockquote{margin:0;margin-bottom:.85em;padding:0 15px;color:#858585;border-left:4px solid #e5e5e5}.markdown-section blockquote:first-child{margin-top:0}.markdown-section blockquote:last-child{margin-bottom:0}.markdown-section dl{padding:0}.markdown-section dl dt{padding:0;margin-top:.85em;font-style:italic;font-weight:700}.markdown-section dl dd{padding:0 .85em;margin-bottom:.85em}.markdown-section dd{margin-left:0}.markdown-section .glossary-term{cursor:help;text-decoration:underline}.navigation{position:absolute;top:50px;bottom:0;margin:0;max-width:150px;min-width:90px;display:flex;justify-content:center;align-content:center;flex-direction:column;font-size:40px;color:#ccc;text-align:center;-webkit-transition:all 350ms ease;-moz-transition:all 350ms ease;-o-transition:all 350ms ease;transition:all 350ms ease}.navigation:hover{text-decoration:none;color:#444}.navigation.navigation-next{right:0}.navigation.navigation-prev{left:0}@media (max-width:1240px){.navigation{position:static;top:auto;max-width:50%;width:50%;display:inline-block;float:left}.navigation.navigation-unique{max-width:100%;/*width:100%*/}}#book-search-input{padding:6px;background:0 0;transition:top .5s ease;background:#fff;border-bottom:1px solid rgba(0,0,0,.07);border-top:1px solid rgba(0,0,0,.07);margin-bottom:10px;margin-top:-1px}#book-search-input input,#book-search-input input:focus,#book-search-input input:hover{width:100%;background:0 0;border:1px solid transparent;box-shadow:none;outline:0;line-height:22px;padding:7px 7px;color:inherit}#book-search-results{opacity:1}#book-search-results .search-results .search-results-title{text-transform:uppercase;text-align:center;font-weight:200;margin-bottom:35px;opacity:.6}#book-search-results .search-results .has-results .search-results-item{display:block;word-wrap:break-word;overflow:hidden;color:#333;line-height:1.7;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%}#book-search-results .search-results .has-results .search-results-item *{box-sizing:border-box;-webkit-box-sizing:border-box;font-size:inherit}#book-search-results .search-results .has-results .search-results-item>:first-child{margin-top:0!important}#book-search-results .search-results .has-results .search-results-item>:last-child{margin-bottom:0!important}#book-search-results .search-results .has-results .search-results-item blockquote,#book-search-results .search-results .has-results .search-results-item code,#book-search-results .search-results .has-results .search-results-item figure,#book-search-results .search-results .has-results .search-results-item img,#book-search-results .search-results .has-results .search-results-item pre,#book-search-results .search-results .has-results .search-results-item table,#book-search-results .search-results .has-results .search-results-item tr{page-break-inside:avoid}#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5,#book-search-results .search-results .has-results .search-results-item p{orphans:3;widows:3}#book-search-results .search-results .has-results .search-results-item h1,#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5{page-break-after:avoid}#book-search-results .search-results .has-results .search-results-item b,#book-search-results .search-results .has-results .search-results-item strong{font-weight:700}#book-search-results .search-results .has-results .search-results-item em{font-style:italic}#book-search-results .search-results .has-results .search-results-item blockquote,#book-search-results .search-results .has-results .search-results-item dl,#book-search-results .search-results .has-results .search-results-item ol,#book-search-results .search-results .has-results .search-results-item p,#book-search-results .search-results .has-results .search-results-item table,#book-search-results .search-results .has-results .search-results-item ul{margin-top:0;margin-bottom:.85em}#book-search-results .search-results .has-results .search-results-item a{color:#4183c4;text-decoration:none;background:0 0}#book-search-results .search-results .has-results .search-results-item a:active,#book-search-results .search-results .has-results .search-results-item a:focus,#book-search-results .search-results .has-results .search-results-item a:hover{outline:0;text-decoration:underline}#book-search-results .search-results .has-results .search-results-item img{border:0;max-width:100%}#book-search-results .search-results .has-results .search-results-item hr{height:4px;padding:0;margin:1.7em 0;overflow:hidden;background-color:#e7e7e7;border:none}#book-search-results .search-results .has-results .search-results-item hr:after,#book-search-results .search-results .has-results .search-results-item hr:before{display:table;content:" "}#book-search-results .search-results .has-results .search-results-item hr:after{clear:both}#book-search-results .search-results .has-results .search-results-item h1,#book-search-results .search-results .has-results .search-results-item h2,#book-search-results .search-results .has-results .search-results-item h3,#book-search-results .search-results .has-results .search-results-item h4,#book-search-results .search-results .has-results .search-results-item h5,#book-search-results .search-results .has-results .search-results-item h6{margin-top:1.275em;margin-bottom:.85em;font-weight:700}#book-search-results .search-results .has-results .search-results-item h1{font-size:2em}#book-search-results .search-results .has-results .search-results-item h2{font-size:1.75em}#book-search-results .search-results .has-results .search-results-item h3{font-size:1.5em}#book-search-results .search-results .has-results .search-results-item h4{font-size:1.25em}#book-search-results .search-results .has-results .search-results-item h5{font-size:1em}#book-search-results .search-results .has-results .search-results-item h6{font-size:1em;color:#777}#book-search-results .search-results .has-results .search-results-item code,#book-search-results .search-results .has-results .search-results-item pre{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;direction:ltr;margin:0;padding:0;border:none;color:inherit}#book-search-results .search-results .has-results .search-results-item pre{overflow:auto;word-wrap:normal;margin:0;padding:.85em 1em;margin-bottom:1.275em;background:#f7f7f7}#book-search-results .search-results .has-results .search-results-item pre>code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;font-size:.85em;white-space:pre;background:0 0}#book-search-results .search-results .has-results .search-results-item pre>code:after,#book-search-results .search-results .has-results .search-results-item pre>code:before{content:normal}#book-search-results .search-results .has-results .search-results-item code{padding:.2em;margin:0;font-size:.85em;background-color:#f7f7f7}#book-search-results .search-results .has-results .search-results-item code:after,#book-search-results .search-results .has-results .search-results-item code:before{letter-spacing:-.2em;content:"\00a0"}#book-search-results .search-results .has-results .search-results-item table{display:table;width:100%;border-collapse:collapse;border-spacing:0;overflow:auto}#book-search-results .search-results .has-results .search-results-item table td,#book-search-results .search-results .has-results .search-results-item table th{padding:6px 13px;border:1px solid #ddd}#book-search-results .search-results .has-results .search-results-item table tr{background-color:#fff;border-top:1px solid #ccc}#book-search-results .search-results .has-results .search-results-item table tr:nth-child(2n){background-color:#f8f8f8}#book-search-results .search-results .has-results .search-results-item table th{font-weight:700}#book-search-results .search-results .has-results .search-results-item ol,#book-search-results .search-results .has-results .search-results-item ul{padding:0;margin:0;margin-bottom:.85em;padding-left:2em}#book-search-results .search-results .has-results .search-results-item ol ol,#book-search-results .search-results .has-results .search-results-item ol ul,#book-search-results .search-results .has-results .search-results-item ul ol,#book-search-results .search-results .has-results .search-results-item ul ul{margin-top:0;margin-bottom:0}#book-search-results .search-results .has-results .search-results-item ol ol{list-style-type:lower-roman}#book-search-results .search-results .has-results .search-results-item blockquote{margin:0;margin-bottom:.85em;padding:0 15px;color:#858585;border-left:4px solid #e5e5e5}#book-search-results .search-results .has-results .search-results-item blockquote:first-child{margin-top:0}#book-search-results .search-results .has-results .search-results-item blockquote:last-child{margin-bottom:0}#book-search-results .search-results .has-results .search-results-item dl{padding:0}#book-search-results .search-results .has-results .search-results-item dl dt{padding:0;margin-top:.85em;font-style:italic;font-weight:700}#book-search-results .search-results .has-results .search-results-item dl dd{padding:0 .85em;margin-bottom:.85em}#book-search-results .search-results .has-results .search-results-item dd{margin-left:0}#book-search-results .search-results .has-results .search-results-item h3{margin-top:0;margin-bottom:0}#book-search-results .search-results .no-results{padding:40px 0}body.search-loading #book-search-results{opacity:.3}body.with-search .navigation{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-font-smoothing:antialiased}a{text-decoration:none}body,html{height:100%}html{font-size:62.5%}body{text-rendering:optimizeLegibility;font-smoothing:antialiased;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;letter-spacing:.2px;text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} \ No newline at end of file + */ +.book-langs-index { + width: 100%; + height: 100%; + padding: 40px 0; + margin: 0; + overflow: auto +} + +@media (max-width:600px) { + .book-langs-index { + padding: 0 + } +} + +.book-langs-index .inner { + max-width: 600px; + width: 100%; + margin: 0 auto; + padding: 30px; + background: #fff; + border-radius: 3px +} + +.book-langs-index .inner h3 { + margin: 0 +} + +.book-langs-index .inner .languages { + list-style: none; + padding: 20px 30px; + margin-top: 20px; + border-top: 1px solid #eee +} + +.book-langs-index .inner .languages:after, +.book-langs-index .inner .languages:before { + content: " "; + display: table; + line-height: 0 +} + +.book-langs-index .inner .languages:after { + clear: both +} + +.book-langs-index .inner .languages li { + width: 50%; + float: left; + padding: 10px 5px; + font-size: 16px +} + +@media (max-width:600px) { + .book-langs-index .inner .languages li { + width: 100%; + max-width: 100% + } +} + +.book-header { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + overflow: visible; + height: 50px; + padding: 0 8px; + z-index: 2; + font-size: .85em; + color: #7e888b; + background: 0 0 +} + +.book-header .btn { + display: block; + height: 50px; + padding: 0 15px; + border-bottom: none; + color: #ccc; + text-transform: uppercase; + line-height: 50px; + -webkit-box-shadow: none !important; + box-shadow: none !important; + position: relative; + font-size: 14px +} + +.book-header .btn:hover { + position: relative; + text-decoration: none; + color: #444; + background: 0 0 +} + +.book-header .btn:focus { + outline: 0 +} + +.book-header h1 { + margin: 0; + font-size: 20px; + font-weight: 200; + text-align: center; + line-height: 50px; + opacity: 0; + -webkit-transition: opacity ease .4s; + -moz-transition: opacity ease .4s; + -o-transition: opacity ease .4s; + transition: opacity ease .4s; + padding-left: 200px; + padding-right: 200px; + -webkit-transition: opacity .2s ease; + -moz-transition: opacity .2s ease; + -o-transition: opacity .2s ease; + transition: opacity .2s ease; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.book-header h1 a, +.book-header h1 a:hover { + color: inherit; + text-decoration: none +} + +@media (max-width:1000px) { + .book-header h1 { + display: none + } +} + +.book-header h1 i { + display: none +} + +.book-header:hover h1 { + opacity: 1 +} + +.book.is-loading .book-header h1 i { + display: inline-block +} + +.book.is-loading .book-header h1 a { + display: none +} + +.dropdown { + position: relative +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 100; + display: none; + float: left; + min-width: 160px; + padding: 0; + margin: 2px 0 0; + list-style: none; + font-size: 14px; + background-color: #fafafa; + border: 1px solid rgba(0, 0, 0, .07); + border-radius: 1px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + background-clip: padding-box +} + +.dropdown-menu.open { + display: block +} + +.dropdown-menu.dropdown-left { + left: auto; + right: 4% +} + +.dropdown-menu.dropdown-left .dropdown-caret { + right: 14px; + left: auto +} + +.dropdown-menu .dropdown-caret { + position: absolute; + top: -8px; + left: 14px; + width: 18px; + height: 10px; + float: left; + overflow: hidden +} + +.dropdown-menu .dropdown-caret .caret-outer { + position: absolute; + border-left: 9px solid transparent; + border-right: 9px solid transparent; + border-bottom: 9px solid rgba(0, 0, 0, .1); + height: auto; + left: 0; + top: 0; + width: auto; + display: inline-block; + margin-left: -1px +} + +.dropdown-menu .dropdown-caret .caret-inner { + position: absolute; + display: inline-block; + margin-top: -1px; + top: 0; + top: 1px; + border-left: 9px solid transparent; + border-right: 9px solid transparent; + border-bottom: 9px solid #fafafa +} + +.dropdown-menu .buttons { + border-bottom: 1px solid rgba(0, 0, 0, .07) +} + +.dropdown-menu .buttons:after, +.dropdown-menu .buttons:before { + content: " "; + display: table; + line-height: 0 +} + +.dropdown-menu .buttons:after { + clear: both +} + +.dropdown-menu .buttons:last-child { + border-bottom: none +} + +.dropdown-menu .buttons .button { + border: 0; + background-color: transparent; + color: #a6a6a6; + width: 100%; + text-align: center; + float: left; + line-height: 1.42857143; + padding: 8px 4px +} + +.dropdown-menu .buttons .button:hover { + color: #444 +} + +.dropdown-menu .buttons .button:focus, +.dropdown-menu .buttons .button:hover { + outline: 0 +} + +.dropdown-menu .buttons .button.size-2 { + width: 50% +} + +.dropdown-menu .buttons .button.size-3 { + width: 33% +} + +.book-summary { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + position: absolute; + top: 0; + left: -300px; + bottom: 0; + z-index: 1; + overflow-y: auto; + width: 300px; + color: #364149; + background: #fafafa; + border-right: 1px solid rgba(0, 0, 0, .07); + -webkit-transition: left 250ms ease; + -moz-transition: left 250ms ease; + -o-transition: left 250ms ease; + transition: left 250ms ease +} + +.book-summary ul.summary { + list-style: none; + margin: 0; + padding: 0; + -webkit-transition: top .5s ease; + -moz-transition: top .5s ease; + -o-transition: top .5s ease; + transition: top .5s ease +} + +.book-summary ul.summary li { + list-style: none +} + +.book-summary ul.summary li.header { + padding: 10px 15px; + padding-top: 20px; + text-transform: uppercase; + color: #939da3 +} + +.book-summary ul.summary li.divider { + height: 1px; + margin: 7px 0; + overflow: hidden; + background: rgba(0, 0, 0, .07) +} + +.book-summary ul.summary li i.fa-check { + display: none; + position: absolute; + right: 9px; + top: 16px; + font-size: 9px; + color: #3c3 +} + +.book-summary ul.summary li.done>a { + color: #364149; + font-weight: 400 +} + +.book-summary ul.summary li.done>a i { + display: inline +} + +.book-summary ul.summary li a, +.book-summary ul.summary li span { + display: block; + padding: 10px 15px; + border-bottom: none; + color: #364149; + background: 0 0; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + position: relative +} + +.book-summary ul.summary li a:hover { + text-decoration: underline +} + +.book-summary ul.summary li a:focus { + outline: 0 +} + +.book-summary ul.summary li.active>a { + color: #008cff; + background: 0 0; + text-decoration: none +} + +.book-summary ul.summary li ul { + padding-left: 20px +} + +@media (max-width:600px) { + .book-summary { + width: calc(100% - 60px); + bottom: 0; + left: -100% + } +} + +.book.with-summary .book-summary { + left: 0 +} + +.book.without-animation .book-summary { + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + transition: none !important +} + +.book { + position: relative; + width: 100%; + height: 100% +} + +@media (min-width:600px) { + .book.with-summary .book-body { + left: 300px + } +} + +@media (max-width:600px) { + .book.with-summary { + overflow: hidden + } + + .book.with-summary .book-body { + -webkit-transform: translate(calc(100% - 60px), 0); + -moz-transform: translate(calc(100% - 60px), 0); + -ms-transform: translate(calc(100% - 60px), 0); + -o-transform: translate(calc(100% - 60px), 0); + transform: translate(calc(100% - 60px), 0) + } +} + +.book.without-animation .book-body { + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + transition: none !important +} + +.book-body { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + overflow-y: auto; + color: #000; + background: #fff; + -webkit-transition: left 250ms ease; + -moz-transition: left 250ms ease; + -o-transition: left 250ms ease; + transition: left 250ms ease +} + +.book-body .body-inner { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + overflow-y: auto +} + +@media (max-width:1240px) { + .book-body { + -webkit-transition: -webkit-transform 250ms ease; + -moz-transition: -moz-transform 250ms ease; + -o-transition: -o-transform 250ms ease; + transition: transform 250ms ease; + padding-bottom: 20px + } + + .book-body .body-inner { + position: static; + min-height: calc(100% - 50px) + } +} + +.page-wrapper { + position: relative; + outline: 0 +} + +.page-inner { + position: relative; + max-width: 800px; + margin: 0 auto; + padding: 20px 15px 40px 15px +} + +.page-inner .btn-group .btn { + border-radius: 0; + background: #eee; + border: 0 +} + +.buttons:after, +.buttons:before { + content: " "; + display: table; + line-height: 0 +} + +.buttons:after { + clear: both +} + +.button { + border: 0; + background-color: transparent; + background: #eee; + color: #666; + width: 100%; + text-align: center; + float: left; + line-height: 1.42857143; + padding: 8px 4px +} + +.button:hover { + color: #444 +} + +.button:focus, +.button:hover { + outline: 0 +} + +.button.size-2 { + width: 50% +} + +.button.size-3 { + width: 33% +} + +.markdown-section { + display: block; + word-wrap: break-word; + overflow: hidden; + color: #333; + line-height: 1.7; + text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100% +} + +.markdown-section * { + box-sizing: border-box; + -webkit-box-sizing: border-box; + font-size: inherit +} + +.markdown-section>:first-child { + margin-top: 0 !important +} + +.markdown-section>:last-child { + margin-bottom: 0 !important +} + +.markdown-section blockquote, +.markdown-section code, +.markdown-section figure, +.markdown-section img, +.markdown-section pre, +.markdown-section table, +.markdown-section tr { + page-break-inside: avoid +} + +.markdown-section h2, +.markdown-section h3, +.markdown-section h4, +.markdown-section h5, +.markdown-section p { + orphans: 3; + widows: 3 +} + +.markdown-section h1, +.markdown-section h2, +.markdown-section h3, +.markdown-section h4, +.markdown-section h5 { + page-break-after: avoid +} + +.markdown-section b, +.markdown-section strong { + font-weight: 700 +} + +.markdown-section em { + font-style: italic +} + +.markdown-section blockquote, +.markdown-section dl, +.markdown-section ol, +.markdown-section p, +.markdown-section table, +.markdown-section ul { + margin-top: 0; + margin-bottom: .85em +} + +.markdown-section a { + color: #4183c4; + text-decoration: none; + background: 0 0 +} + +.markdown-section a:active, +.markdown-section a:focus, +.markdown-section a:hover { + outline: 0; + text-decoration: underline +} + +.markdown-section img { + border: 0; + max-width: 100% +} + +.markdown-section hr { + height: 4px; + padding: 0; + margin: 1.7em 0; + overflow: hidden; + background-color: #e7e7e7; + border: none +} + +.markdown-section hr:after, +.markdown-section hr:before { + display: table; + content: " " +} + +.markdown-section hr:after { + clear: both +} + +.markdown-section h1, +.markdown-section h2, +.markdown-section h3, +.markdown-section h4, +.markdown-section h5, +.markdown-section h6 { + margin-top: 1.275em; + margin-bottom: .85em; + font-weight: 700 +} + +.markdown-section h1 { + font-size: 2em +} + +.markdown-section h2 { + font-size: 1.75em +} + +.markdown-section h3 { + font-size: 1.5em +} + +.markdown-section h4 { + font-size: 1.25em +} + +.markdown-section h5 { + font-size: 1em +} + +.markdown-section h6 { + font-size: 1em; + color: #777 +} + +.markdown-section code, +.markdown-section pre { + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + direction: ltr; + margin: 0; + padding: 0; + border: none; + color: inherit +} + +.markdown-section pre { + overflow: auto; + word-wrap: normal; + margin: 0; + padding: .85em 1em; + margin-bottom: 1.275em; + background: #f7f7f7 +} + +.markdown-section pre>code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + font-size: .85em; + white-space: pre; + background: 0 0 +} + +.markdown-section pre>code:after, +.markdown-section pre>code:before { + content: normal +} + +.markdown-section code { + padding: .2em; + margin: 0; + font-size: .85em; + background-color: #f7f7f7 +} + +.markdown-section code:after, +.markdown-section code:before { + letter-spacing: -.2em; + content: "\00a0" +} + +.markdown-section table { + display: table; + width: 100%; + border-collapse: collapse; + border-spacing: 0; + overflow: auto +} + +.markdown-section table td, +.markdown-section table th { + padding: 6px 13px; + border: 1px solid #ddd +} + +.markdown-section table tr { + background-color: #fff; + border-top: 1px solid #ccc +} + +.markdown-section table tr:nth-child(2n) { + background-color: #f8f8f8 +} + +.markdown-section table th { + font-weight: 700 +} + +.markdown-section ol, +.markdown-section ul { + padding: 0; + margin: 0; + margin-bottom: .85em; + padding-left: 2em +} + +.markdown-section ol ol, +.markdown-section ol ul, +.markdown-section ul ol, +.markdown-section ul ul { + margin-top: 0; + margin-bottom: 0 +} + +.markdown-section ol ol { + list-style-type: lower-roman +} + +.markdown-section blockquote { + margin: 0; + margin-bottom: .85em; + padding: 0 15px; + color: #858585; + border-left: 4px solid #e5e5e5 +} + +.markdown-section blockquote:first-child { + margin-top: 0 +} + +.markdown-section blockquote:last-child { + margin-bottom: 0 +} + +.markdown-section dl { + padding: 0 +} + +.markdown-section dl dt { + padding: 0; + margin-top: .85em; + font-style: italic; + font-weight: 700 +} + +.markdown-section dl dd { + padding: 0 .85em; + margin-bottom: .85em +} + +.markdown-section dd { + margin-left: 0 +} + +.markdown-section .glossary-term { + cursor: help; + text-decoration: underline +} + +.navigation { + position: absolute; + top: 50px; + bottom: 0; + margin: 0; + max-width: 150px; + min-width: 90px; + display: flex; + justify-content: center; + align-content: center; + flex-direction: column; + font-size: 40px; + color: #ccc; + text-align: center; + -webkit-transition: all 350ms ease; + -moz-transition: all 350ms ease; + -o-transition: all 350ms ease; + transition: all 350ms ease +} + +.navigation:hover { + text-decoration: none; + color: #444 +} + +.navigation.navigation-next { + right: 0 +} + +.navigation.navigation-prev { + left: 0 +} + +@media (max-width:1240px) { + .navigation { + position: static; + top: auto; + max-width: 50%; + width: 50%; + display: inline-block; + float: left + } + + .navigation.navigation-unique { + max-width: 100%; + /*width:100%*/ + } +} + +#book-search-input { + padding: 6px; + background: 0 0; + transition: top .5s ease; + background: #fff; + border-bottom: 1px solid rgba(0, 0, 0, .07); + border-top: 1px solid rgba(0, 0, 0, .07); + margin-bottom: 10px; + margin-top: -1px +} + +#book-search-input input, +#book-search-input input:focus, +#book-search-input input:hover { + width: 100%; + background: 0 0; + border: 1px solid transparent; + box-shadow: none; + outline: 0; + line-height: 22px; + padding: 7px 7px; + color: inherit +} + +#book-search-results { + opacity: 1 +} + +#book-search-results .search-results .search-results-title { + text-transform: uppercase; + text-align: center; + font-weight: 200; + margin-bottom: 35px; + opacity: .6 +} + +#book-search-results .search-results .has-results .search-results-item { + display: block; + word-wrap: break-word; + overflow: hidden; + color: #333; + line-height: 1.7; + text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100% +} + +#book-search-results .search-results .has-results .search-results-item * { + box-sizing: border-box; + -webkit-box-sizing: border-box; + font-size: inherit +} + +#book-search-results .search-results .has-results .search-results-item>:first-child { + margin-top: 0 !important +} + +#book-search-results .search-results .has-results .search-results-item>:last-child { + margin-bottom: 0 !important +} + +#book-search-results .search-results .has-results .search-results-item blockquote, +#book-search-results .search-results .has-results .search-results-item code, +#book-search-results .search-results .has-results .search-results-item figure, +#book-search-results .search-results .has-results .search-results-item img, +#book-search-results .search-results .has-results .search-results-item pre, +#book-search-results .search-results .has-results .search-results-item table, +#book-search-results .search-results .has-results .search-results-item tr { + page-break-inside: avoid +} + +#book-search-results .search-results .has-results .search-results-item h2, +#book-search-results .search-results .has-results .search-results-item h3, +#book-search-results .search-results .has-results .search-results-item h4, +#book-search-results .search-results .has-results .search-results-item h5, +#book-search-results .search-results .has-results .search-results-item p { + orphans: 3; + widows: 3 +} + +#book-search-results .search-results .has-results .search-results-item h1, +#book-search-results .search-results .has-results .search-results-item h2, +#book-search-results .search-results .has-results .search-results-item h3, +#book-search-results .search-results .has-results .search-results-item h4, +#book-search-results .search-results .has-results .search-results-item h5 { + page-break-after: avoid +} + +#book-search-results .search-results .has-results .search-results-item b, +#book-search-results .search-results .has-results .search-results-item strong { + font-weight: 700 +} + +#book-search-results .search-results .has-results .search-results-item em { + font-style: italic +} + +#book-search-results .search-results .has-results .search-results-item blockquote, +#book-search-results .search-results .has-results .search-results-item dl, +#book-search-results .search-results .has-results .search-results-item ol, +#book-search-results .search-results .has-results .search-results-item p, +#book-search-results .search-results .has-results .search-results-item table, +#book-search-results .search-results .has-results .search-results-item ul { + margin-top: 0; + margin-bottom: .85em +} + +#book-search-results .search-results .has-results .search-results-item a { + color: #4183c4; + text-decoration: none; + background: 0 0 +} + +#book-search-results .search-results .has-results .search-results-item a:active, +#book-search-results .search-results .has-results .search-results-item a:focus, +#book-search-results .search-results .has-results .search-results-item a:hover { + outline: 0; + text-decoration: underline +} + +#book-search-results .search-results .has-results .search-results-item img { + border: 0; + max-width: 100% +} + +#book-search-results .search-results .has-results .search-results-item hr { + height: 4px; + padding: 0; + margin: 1.7em 0; + overflow: hidden; + background-color: #e7e7e7; + border: none +} + +#book-search-results .search-results .has-results .search-results-item hr:after, +#book-search-results .search-results .has-results .search-results-item hr:before { + display: table; + content: " " +} + +#book-search-results .search-results .has-results .search-results-item hr:after { + clear: both +} + +#book-search-results .search-results .has-results .search-results-item h1, +#book-search-results .search-results .has-results .search-results-item h2, +#book-search-results .search-results .has-results .search-results-item h3, +#book-search-results .search-results .has-results .search-results-item h4, +#book-search-results .search-results .has-results .search-results-item h5, +#book-search-results .search-results .has-results .search-results-item h6 { + margin-top: 1.275em; + margin-bottom: .85em; + font-weight: 700 +} + +#book-search-results .search-results .has-results .search-results-item h1 { + font-size: 2em +} + +#book-search-results .search-results .has-results .search-results-item h2 { + font-size: 1.75em +} + +#book-search-results .search-results .has-results .search-results-item h3 { + font-size: 1.5em +} + +#book-search-results .search-results .has-results .search-results-item h4 { + font-size: 1.25em +} + +#book-search-results .search-results .has-results .search-results-item h5 { + font-size: 1em +} + +#book-search-results .search-results .has-results .search-results-item h6 { + font-size: 1em; + color: #777 +} + +#book-search-results .search-results .has-results .search-results-item code, +#book-search-results .search-results .has-results .search-results-item pre { + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + direction: ltr; + margin: 0; + padding: 0; + border: none; + color: inherit +} + +#book-search-results .search-results .has-results .search-results-item pre { + overflow: auto; + word-wrap: normal; + margin: 0; + padding: .85em 1em; + margin-bottom: 1.275em; + background: #f7f7f7 +} + +#book-search-results .search-results .has-results .search-results-item pre>code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + font-size: .85em; + white-space: pre; + background: 0 0 +} + +#book-search-results .search-results .has-results .search-results-item pre>code:after, +#book-search-results .search-results .has-results .search-results-item pre>code:before { + content: normal +} + +#book-search-results .search-results .has-results .search-results-item code { + padding: .2em; + margin: 0; + font-size: .85em; + background-color: #f7f7f7 +} + +#book-search-results .search-results .has-results .search-results-item code:after, +#book-search-results .search-results .has-results .search-results-item code:before { + letter-spacing: -.2em; + content: "\00a0" +} + +#book-search-results .search-results .has-results .search-results-item table { + display: table; + width: 100%; + border-collapse: collapse; + border-spacing: 0; + overflow: auto +} + +#book-search-results .search-results .has-results .search-results-item table td, +#book-search-results .search-results .has-results .search-results-item table th { + padding: 6px 13px; + border: 1px solid #ddd +} + +#book-search-results .search-results .has-results .search-results-item table tr { + background-color: #fff; + border-top: 1px solid #ccc +} + +#book-search-results .search-results .has-results .search-results-item table tr:nth-child(2n) { + background-color: #f8f8f8 +} + +#book-search-results .search-results .has-results .search-results-item table th { + font-weight: 700 +} + +#book-search-results .search-results .has-results .search-results-item ol, +#book-search-results .search-results .has-results .search-results-item ul { + padding: 0; + margin: 0; + margin-bottom: .85em; + padding-left: 2em +} + +#book-search-results .search-results .has-results .search-results-item ol ol, +#book-search-results .search-results .has-results .search-results-item ol ul, +#book-search-results .search-results .has-results .search-results-item ul ol, +#book-search-results .search-results .has-results .search-results-item ul ul { + margin-top: 0; + margin-bottom: 0 +} + +#book-search-results .search-results .has-results .search-results-item ol ol { + list-style-type: lower-roman +} + +#book-search-results .search-results .has-results .search-results-item blockquote { + margin: 0; + margin-bottom: .85em; + padding: 0 15px; + color: #858585; + border-left: 4px solid #e5e5e5 +} + +#book-search-results .search-results .has-results .search-results-item blockquote:first-child { + margin-top: 0 +} + +#book-search-results .search-results .has-results .search-results-item blockquote:last-child { + margin-bottom: 0 +} + +#book-search-results .search-results .has-results .search-results-item dl { + padding: 0 +} + +#book-search-results .search-results .has-results .search-results-item dl dt { + padding: 0; + margin-top: .85em; + font-style: italic; + font-weight: 700 +} + +#book-search-results .search-results .has-results .search-results-item dl dd { + padding: 0 .85em; + margin-bottom: .85em +} + +#book-search-results .search-results .has-results .search-results-item dd { + margin-left: 0 +} + +#book-search-results .search-results .has-results .search-results-item h3 { + margin-top: 0; + margin-bottom: 0 +} + +#book-search-results .search-results .no-results { + padding: 40px 0 +} + +body.search-loading #book-search-results { + opacity: .3 +} + +body.with-search .navigation { + display: none +} + +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-overflow-scrolling: touch; + -webkit-tap-highlight-color: transparent; + -webkit-text-size-adjust: none; + -webkit-touch-callout: none; + -webkit-font-smoothing: antialiased +} + +a { + text-decoration: none +} + +body, +html { + height: 100% +} + +html { + font-size: 62.5% +} + +body { + text-rendering: optimizeLegibility; + font-smoothing: antialiased; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + letter-spacing: .2px; + text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100% +} \ No newline at end of file diff --git a/assets/icons/1.png b/assets/icons/1.png new file mode 100644 index 0000000000..f9dee00eb3 Binary files /dev/null and b/assets/icons/1.png differ diff --git a/assets/icons/2.png b/assets/icons/2.png new file mode 100644 index 0000000000..7d3d2401e2 Binary files /dev/null and b/assets/icons/2.png differ diff --git a/assets/icons/3.png b/assets/icons/3.png new file mode 100644 index 0000000000..bdbdd4a021 Binary files /dev/null and b/assets/icons/3.png differ diff --git a/assets/icons/4.png b/assets/icons/4.png new file mode 100644 index 0000000000..78638a091a Binary files /dev/null and b/assets/icons/4.png differ diff --git a/assets/icons/5.png b/assets/icons/5.png new file mode 100644 index 0000000000..f83afaaca2 Binary files /dev/null and b/assets/icons/5.png differ diff --git a/assets/icons/6.png b/assets/icons/6.png new file mode 100644 index 0000000000..c272beaab4 Binary files /dev/null and b/assets/icons/6.png differ diff --git a/assets/images/12.10.1.png b/assets/images/12.10.1.png new file mode 100644 index 0000000000..e3a4abd5ec Binary files /dev/null and b/assets/images/12.10.1.png differ diff --git a/assets/images/12.10.10.png b/assets/images/12.10.10.png new file mode 100644 index 0000000000..7f6b05c6b6 Binary files /dev/null and b/assets/images/12.10.10.png differ diff --git a/assets/images/12.10.11.1.png.md b/assets/images/12.10.11.1.png.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/images/12.10.11.png b/assets/images/12.10.11.png new file mode 100644 index 0000000000..d69668cbc4 Binary files /dev/null and b/assets/images/12.10.11.png differ diff --git a/assets/images/12.10.12.png b/assets/images/12.10.12.png new file mode 100644 index 0000000000..59c124465a Binary files /dev/null and b/assets/images/12.10.12.png differ diff --git a/assets/images/12.10.2.png b/assets/images/12.10.2.png new file mode 100644 index 0000000000..f6859d96ff Binary files /dev/null and b/assets/images/12.10.2.png differ diff --git a/assets/images/12.10.3.png b/assets/images/12.10.3.png new file mode 100644 index 0000000000..643c81ae41 Binary files /dev/null and b/assets/images/12.10.3.png differ diff --git a/assets/images/12.10.4.png b/assets/images/12.10.4.png new file mode 100644 index 0000000000..13e6ac7906 Binary files /dev/null and b/assets/images/12.10.4.png differ diff --git a/assets/images/12.10.5.png b/assets/images/12.10.5.png new file mode 100644 index 0000000000..3a09bf1011 Binary files /dev/null and b/assets/images/12.10.5.png differ diff --git a/assets/images/12.10.6.png b/assets/images/12.10.6.png new file mode 100644 index 0000000000..fe23bef726 Binary files /dev/null and b/assets/images/12.10.6.png differ diff --git a/assets/images/12.10.7.png b/assets/images/12.10.7.png new file mode 100644 index 0000000000..64e9dd2c8b Binary files /dev/null and b/assets/images/12.10.7.png differ diff --git a/assets/images/12.10.8.1.png b/assets/images/12.10.8.1.png new file mode 100644 index 0000000000..9b3ecbd207 Binary files /dev/null and b/assets/images/12.10.8.1.png differ diff --git a/assets/images/12.10.8.png b/assets/images/12.10.8.png new file mode 100644 index 0000000000..e0e24be1ac Binary files /dev/null and b/assets/images/12.10.8.png differ diff --git a/assets/images/12.10.9.png b/assets/images/12.10.9.png new file mode 100644 index 0000000000..ae653d21d6 Binary files /dev/null and b/assets/images/12.10.9.png differ diff --git a/assets/images/12.10_1.png.md b/assets/images/12.10_1.png.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/images/12.18.1.png b/assets/images/12.18.1.png new file mode 100644 index 0000000000..069601cc34 Binary files /dev/null and b/assets/images/12.18.1.png differ diff --git a/assets/images/12.18.10.png b/assets/images/12.18.10.png new file mode 100644 index 0000000000..a5ad6ea805 Binary files /dev/null and b/assets/images/12.18.10.png differ diff --git a/assets/images/12.18.11.png b/assets/images/12.18.11.png new file mode 100644 index 0000000000..9f9cb97309 Binary files /dev/null and b/assets/images/12.18.11.png differ diff --git a/assets/images/12.18.12.png b/assets/images/12.18.12.png new file mode 100644 index 0000000000..e9cc344ff5 Binary files /dev/null and b/assets/images/12.18.12.png differ diff --git a/assets/images/12.18.2.png b/assets/images/12.18.2.png new file mode 100644 index 0000000000..138aa3a4a0 Binary files /dev/null and b/assets/images/12.18.2.png differ diff --git a/assets/images/12.18.3.png b/assets/images/12.18.3.png new file mode 100644 index 0000000000..3181b36775 Binary files /dev/null and b/assets/images/12.18.3.png differ diff --git a/assets/images/12.18.4.png b/assets/images/12.18.4.png new file mode 100644 index 0000000000..6a84cc944d Binary files /dev/null and b/assets/images/12.18.4.png differ diff --git a/assets/images/12.18.5.png b/assets/images/12.18.5.png new file mode 100644 index 0000000000..e1c5c45a29 Binary files /dev/null and b/assets/images/12.18.5.png differ diff --git a/assets/images/12.18.6.png b/assets/images/12.18.6.png new file mode 100644 index 0000000000..bcbf719a5e Binary files /dev/null and b/assets/images/12.18.6.png differ diff --git a/assets/images/12.18.7.png b/assets/images/12.18.7.png new file mode 100644 index 0000000000..a938bb64df Binary files /dev/null and b/assets/images/12.18.7.png differ diff --git a/assets/images/12.18.8.png b/assets/images/12.18.8.png new file mode 100644 index 0000000000..d5d0f0bfe5 Binary files /dev/null and b/assets/images/12.18.8.png differ diff --git a/assets/images/12.18.9.png b/assets/images/12.18.9.png new file mode 100644 index 0000000000..8239067ec9 Binary files /dev/null and b/assets/images/12.18.9.png differ diff --git a/assets/images/12.21_1.png b/assets/images/12.21_1.png new file mode 100644 index 0000000000..1ed1b387d2 Binary files /dev/null and b/assets/images/12.21_1.png differ diff --git a/assets/images/12.21_10.png b/assets/images/12.21_10.png new file mode 100644 index 0000000000..6867e25b16 Binary files /dev/null and b/assets/images/12.21_10.png differ diff --git a/assets/images/12.21_11.png b/assets/images/12.21_11.png new file mode 100644 index 0000000000..1080b5f266 Binary files /dev/null and b/assets/images/12.21_11.png differ diff --git a/assets/images/12.21_12.png b/assets/images/12.21_12.png new file mode 100644 index 0000000000..df82557188 Binary files /dev/null and b/assets/images/12.21_12.png differ diff --git a/assets/images/12.21_13.png b/assets/images/12.21_13.png new file mode 100644 index 0000000000..03507240e9 Binary files /dev/null and b/assets/images/12.21_13.png differ diff --git a/assets/images/12.21_14.png b/assets/images/12.21_14.png new file mode 100644 index 0000000000..2407888bd2 Binary files /dev/null and b/assets/images/12.21_14.png differ diff --git a/assets/images/12.21_15.png b/assets/images/12.21_15.png new file mode 100644 index 0000000000..eb984bd746 Binary files /dev/null and b/assets/images/12.21_15.png differ diff --git a/assets/images/12.21_16.png b/assets/images/12.21_16.png new file mode 100644 index 0000000000..52e2dadcb0 Binary files /dev/null and b/assets/images/12.21_16.png differ diff --git a/assets/images/12.21_17.png b/assets/images/12.21_17.png new file mode 100644 index 0000000000..9e0237343f Binary files /dev/null and b/assets/images/12.21_17.png differ diff --git a/assets/images/12.21_18.png b/assets/images/12.21_18.png new file mode 100644 index 0000000000..d7908b6147 Binary files /dev/null and b/assets/images/12.21_18.png differ diff --git a/assets/images/12.21_19.png b/assets/images/12.21_19.png new file mode 100644 index 0000000000..73cf59175a Binary files /dev/null and b/assets/images/12.21_19.png differ diff --git a/assets/images/12.21_2.png b/assets/images/12.21_2.png new file mode 100644 index 0000000000..0c94322e9c Binary files /dev/null and b/assets/images/12.21_2.png differ diff --git a/assets/images/12.21_3.png b/assets/images/12.21_3.png new file mode 100644 index 0000000000..a95346b6ef Binary files /dev/null and b/assets/images/12.21_3.png differ diff --git a/assets/images/12.21_4.png b/assets/images/12.21_4.png new file mode 100644 index 0000000000..0dc06bb118 Binary files /dev/null and b/assets/images/12.21_4.png differ diff --git a/assets/images/12.21_5.png b/assets/images/12.21_5.png new file mode 100644 index 0000000000..e5cc26b887 Binary files /dev/null and b/assets/images/12.21_5.png differ diff --git a/assets/images/12.21_6.png b/assets/images/12.21_6.png new file mode 100644 index 0000000000..505c883998 Binary files /dev/null and b/assets/images/12.21_6.png differ diff --git a/assets/images/12.21_7.png b/assets/images/12.21_7.png new file mode 100644 index 0000000000..19c4ef21e4 Binary files /dev/null and b/assets/images/12.21_7.png differ diff --git a/assets/images/12.21_8.png b/assets/images/12.21_8.png new file mode 100644 index 0000000000..8fbb88e33a Binary files /dev/null and b/assets/images/12.21_8.png differ diff --git a/assets/images/12.21_9.png b/assets/images/12.21_9.png new file mode 100644 index 0000000000..57de9d9a90 Binary files /dev/null and b/assets/images/12.21_9.png differ diff --git a/assets/images/1_OB_1.gif b/assets/images/1_OB_1.gif new file mode 100644 index 0000000000..431ed490f1 Binary files /dev/null and b/assets/images/1_OB_1.gif differ diff --git a/assets/images/1_OB_10.gif b/assets/images/1_OB_10.gif new file mode 100644 index 0000000000..43268befa8 Binary files /dev/null and b/assets/images/1_OB_10.gif differ diff --git a/assets/images/1_OB_11.gif b/assets/images/1_OB_11.gif new file mode 100644 index 0000000000..0bb45a2194 Binary files /dev/null and b/assets/images/1_OB_11.gif differ diff --git a/assets/images/1_OB_12.gif b/assets/images/1_OB_12.gif new file mode 100644 index 0000000000..6b3a78c757 Binary files /dev/null and b/assets/images/1_OB_12.gif differ diff --git a/assets/images/1_OB_13.gif b/assets/images/1_OB_13.gif new file mode 100644 index 0000000000..6ed6111719 Binary files /dev/null and b/assets/images/1_OB_13.gif differ diff --git a/assets/images/1_OB_14.gif b/assets/images/1_OB_14.gif new file mode 100644 index 0000000000..08f6f85ca1 Binary files /dev/null and b/assets/images/1_OB_14.gif differ diff --git a/assets/images/1_OB_15.png b/assets/images/1_OB_15.png new file mode 100644 index 0000000000..397cb70cbe Binary files /dev/null and b/assets/images/1_OB_15.png differ diff --git a/assets/images/1_OB_2.gif b/assets/images/1_OB_2.gif new file mode 100644 index 0000000000..f50d7b5bc2 Binary files /dev/null and b/assets/images/1_OB_2.gif differ diff --git a/assets/images/1_OB_3.gif b/assets/images/1_OB_3.gif new file mode 100644 index 0000000000..d3aa9c9ff8 Binary files /dev/null and b/assets/images/1_OB_3.gif differ diff --git a/assets/images/1_OB_4.gif b/assets/images/1_OB_4.gif new file mode 100644 index 0000000000..eff91318d5 Binary files /dev/null and b/assets/images/1_OB_4.gif differ diff --git a/assets/images/1_OB_5.gif b/assets/images/1_OB_5.gif new file mode 100644 index 0000000000..935ae600a5 Binary files /dev/null and b/assets/images/1_OB_5.gif differ diff --git a/assets/images/1_OB_6.gif b/assets/images/1_OB_6.gif new file mode 100644 index 0000000000..c4ee01fd32 Binary files /dev/null and b/assets/images/1_OB_6.gif differ diff --git a/assets/images/1_OB_7.gif b/assets/images/1_OB_7.gif new file mode 100644 index 0000000000..9e571b5440 Binary files /dev/null and b/assets/images/1_OB_7.gif differ diff --git a/assets/images/1_OB_8.gif b/assets/images/1_OB_8.gif new file mode 100644 index 0000000000..acab528873 Binary files /dev/null and b/assets/images/1_OB_8.gif differ diff --git a/assets/images/1_OB_9.gif b/assets/images/1_OB_9.gif new file mode 100644 index 0000000000..6e1044e696 Binary files /dev/null and b/assets/images/1_OB_9.gif differ diff --git a/assets/images/AG-2.gif b/assets/images/AG-2.gif new file mode 100644 index 0000000000..bb88af3e12 Binary files /dev/null and b/assets/images/AG-2.gif differ diff --git a/assets/images/Acqueon/AE_9.1.1.gif b/assets/images/Acqueon/AE_9.1.1.gif new file mode 100644 index 0000000000..e45a4ad4fd Binary files /dev/null and b/assets/images/Acqueon/AE_9.1.1.gif differ diff --git a/assets/images/Acqueon/AE_9.1.2.gif b/assets/images/Acqueon/AE_9.1.2.gif new file mode 100644 index 0000000000..c0ca707d50 Binary files /dev/null and b/assets/images/Acqueon/AE_9.1.2.gif differ diff --git a/assets/images/Acqueon/AE_9.2.1.png b/assets/images/Acqueon/AE_9.2.1.png new file mode 100644 index 0000000000..f3bbe9afc3 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.1.png differ diff --git a/assets/images/Acqueon/AE_9.2.10.gif b/assets/images/Acqueon/AE_9.2.10.gif new file mode 100644 index 0000000000..026814b738 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.10.gif differ diff --git a/assets/images/Acqueon/AE_9.2.11.png b/assets/images/Acqueon/AE_9.2.11.png new file mode 100644 index 0000000000..d554893e87 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.11.png differ diff --git a/assets/images/Acqueon/AE_9.2.12.png b/assets/images/Acqueon/AE_9.2.12.png new file mode 100644 index 0000000000..81f3a3b578 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.12.png differ diff --git a/assets/images/Acqueon/AE_9.2.13.png b/assets/images/Acqueon/AE_9.2.13.png new file mode 100644 index 0000000000..8c979d1f5e Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.13.png differ diff --git a/assets/images/Acqueon/AE_9.2.14.png b/assets/images/Acqueon/AE_9.2.14.png new file mode 100644 index 0000000000..d8ff0a26c4 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.14.png differ diff --git a/assets/images/Acqueon/AE_9.2.15.png b/assets/images/Acqueon/AE_9.2.15.png new file mode 100644 index 0000000000..f03be948a1 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.15.png differ diff --git a/assets/images/Acqueon/AE_9.2.16.png b/assets/images/Acqueon/AE_9.2.16.png new file mode 100644 index 0000000000..8bc3c8dfae Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.16.png differ diff --git a/assets/images/Acqueon/AE_9.2.17.png b/assets/images/Acqueon/AE_9.2.17.png new file mode 100644 index 0000000000..2954de8758 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.17.png differ diff --git a/assets/images/Acqueon/AE_9.2.18.png b/assets/images/Acqueon/AE_9.2.18.png new file mode 100644 index 0000000000..da82599a8a Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.18.png differ diff --git a/assets/images/Acqueon/AE_9.2.19.png b/assets/images/Acqueon/AE_9.2.19.png new file mode 100644 index 0000000000..1966f8b1be Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.19.png differ diff --git a/assets/images/Acqueon/AE_9.2.2.png b/assets/images/Acqueon/AE_9.2.2.png new file mode 100644 index 0000000000..4b85a5610e Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.2.png differ diff --git a/assets/images/Acqueon/AE_9.2.20.png b/assets/images/Acqueon/AE_9.2.20.png new file mode 100644 index 0000000000..8245ab9ded Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.20.png differ diff --git a/assets/images/Acqueon/AE_9.2.21.png b/assets/images/Acqueon/AE_9.2.21.png new file mode 100644 index 0000000000..77ce331131 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.21.png differ diff --git a/assets/images/Acqueon/AE_9.2.22.png b/assets/images/Acqueon/AE_9.2.22.png new file mode 100644 index 0000000000..45e3c86e8f Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.22.png differ diff --git a/assets/images/Acqueon/AE_9.2.23.png b/assets/images/Acqueon/AE_9.2.23.png new file mode 100644 index 0000000000..ddd9d98ac8 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.23.png differ diff --git a/assets/images/Acqueon/AE_9.2.24.png b/assets/images/Acqueon/AE_9.2.24.png new file mode 100644 index 0000000000..82053fce5b Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.24.png differ diff --git a/assets/images/Acqueon/AE_9.2.25.png b/assets/images/Acqueon/AE_9.2.25.png new file mode 100644 index 0000000000..a9c84c010f Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.25.png differ diff --git a/assets/images/Acqueon/AE_9.2.26.gif b/assets/images/Acqueon/AE_9.2.26.gif new file mode 100644 index 0000000000..acab528873 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.26.gif differ diff --git a/assets/images/Acqueon/AE_9.2.27.png b/assets/images/Acqueon/AE_9.2.27.png new file mode 100644 index 0000000000..e948971a43 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.27.png differ diff --git a/assets/images/Acqueon/AE_9.2.28.png b/assets/images/Acqueon/AE_9.2.28.png new file mode 100644 index 0000000000..26a3907ba6 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.28.png differ diff --git a/assets/images/Acqueon/AE_9.2.29.png b/assets/images/Acqueon/AE_9.2.29.png new file mode 100644 index 0000000000..a724a057d5 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.29.png differ diff --git a/assets/images/Acqueon/AE_9.2.3.png b/assets/images/Acqueon/AE_9.2.3.png new file mode 100644 index 0000000000..a4ff728f4c Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.3.png differ diff --git a/assets/images/Acqueon/AE_9.2.30.png b/assets/images/Acqueon/AE_9.2.30.png new file mode 100644 index 0000000000..019b10f844 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.30.png differ diff --git a/assets/images/Acqueon/AE_9.2.31.png b/assets/images/Acqueon/AE_9.2.31.png new file mode 100644 index 0000000000..52eb229045 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.31.png differ diff --git a/assets/images/Acqueon/AE_9.2.32.png b/assets/images/Acqueon/AE_9.2.32.png new file mode 100644 index 0000000000..b15e395635 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.32.png differ diff --git a/assets/images/Acqueon/AE_9.2.33.png b/assets/images/Acqueon/AE_9.2.33.png new file mode 100644 index 0000000000..91c0b26d43 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.33.png differ diff --git a/assets/images/Acqueon/AE_9.2.34.png b/assets/images/Acqueon/AE_9.2.34.png new file mode 100644 index 0000000000..3bec476e73 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.34.png differ diff --git a/assets/images/Acqueon/AE_9.2.4.png b/assets/images/Acqueon/AE_9.2.4.png new file mode 100644 index 0000000000..6a64c9ee85 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.4.png differ diff --git a/assets/images/Acqueon/AE_9.2.5.gif b/assets/images/Acqueon/AE_9.2.5.gif new file mode 100644 index 0000000000..221b06c49e Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.5.gif differ diff --git a/assets/images/Acqueon/AE_9.2.6.png b/assets/images/Acqueon/AE_9.2.6.png new file mode 100644 index 0000000000..fc794100aa Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.6.png differ diff --git a/assets/images/Acqueon/AE_9.2.7.gif b/assets/images/Acqueon/AE_9.2.7.gif new file mode 100644 index 0000000000..2e5d5a6c6b Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.7.gif differ diff --git a/assets/images/Acqueon/AE_9.2.8.png b/assets/images/Acqueon/AE_9.2.8.png new file mode 100644 index 0000000000..d716aa7350 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.8.png differ diff --git a/assets/images/Acqueon/AE_9.2.9.png b/assets/images/Acqueon/AE_9.2.9.png new file mode 100644 index 0000000000..2733e3b085 Binary files /dev/null and b/assets/images/Acqueon/AE_9.2.9.png differ diff --git a/assets/images/Acqueon/AE_9.3.1.gif b/assets/images/Acqueon/AE_9.3.1.gif new file mode 100644 index 0000000000..b907ead5fd Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.1.gif differ diff --git a/assets/images/Acqueon/AE_9.3.10.gif b/assets/images/Acqueon/AE_9.3.10.gif new file mode 100644 index 0000000000..4db0fbd0c7 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.10.gif differ diff --git a/assets/images/Acqueon/AE_9.3.11.png b/assets/images/Acqueon/AE_9.3.11.png new file mode 100644 index 0000000000..f75749769c Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.11.png differ diff --git a/assets/images/Acqueon/AE_9.3.12.png b/assets/images/Acqueon/AE_9.3.12.png new file mode 100644 index 0000000000..addf6ae348 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.12.png differ diff --git a/assets/images/Acqueon/AE_9.3.13.png b/assets/images/Acqueon/AE_9.3.13.png new file mode 100644 index 0000000000..e79c9bb267 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.13.png differ diff --git a/assets/images/Acqueon/AE_9.3.14.png b/assets/images/Acqueon/AE_9.3.14.png new file mode 100644 index 0000000000..d3a977a72d Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.14.png differ diff --git a/assets/images/Acqueon/AE_9.3.15.png b/assets/images/Acqueon/AE_9.3.15.png new file mode 100644 index 0000000000..8af0d83135 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.15.png differ diff --git a/assets/images/Acqueon/AE_9.3.16.png b/assets/images/Acqueon/AE_9.3.16.png new file mode 100644 index 0000000000..0afbafbf8e Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.16.png differ diff --git a/assets/images/Acqueon/AE_9.3.17.png b/assets/images/Acqueon/AE_9.3.17.png new file mode 100644 index 0000000000..b22443264f Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.17.png differ diff --git a/assets/images/Acqueon/AE_9.3.18.png b/assets/images/Acqueon/AE_9.3.18.png new file mode 100644 index 0000000000..76bd91a5df Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.18.png differ diff --git a/assets/images/Acqueon/AE_9.3.19.png b/assets/images/Acqueon/AE_9.3.19.png new file mode 100644 index 0000000000..8860e13479 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.19.png differ diff --git a/assets/images/Acqueon/AE_9.3.2.png b/assets/images/Acqueon/AE_9.3.2.png new file mode 100644 index 0000000000..3fe7fed8ea Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.2.png differ diff --git a/assets/images/Acqueon/AE_9.3.20.png b/assets/images/Acqueon/AE_9.3.20.png new file mode 100644 index 0000000000..f02228d0a5 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.20.png differ diff --git a/assets/images/Acqueon/AE_9.3.21.png b/assets/images/Acqueon/AE_9.3.21.png new file mode 100644 index 0000000000..625d0af176 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.21.png differ diff --git a/assets/images/Acqueon/AE_9.3.22.png b/assets/images/Acqueon/AE_9.3.22.png new file mode 100644 index 0000000000..454a707f23 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.22.png differ diff --git a/assets/images/Acqueon/AE_9.3.23.png b/assets/images/Acqueon/AE_9.3.23.png new file mode 100644 index 0000000000..85775e9137 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.23.png differ diff --git a/assets/images/Acqueon/AE_9.3.24.gif b/assets/images/Acqueon/AE_9.3.24.gif new file mode 100644 index 0000000000..96134b1c5d Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.24.gif differ diff --git a/assets/images/Acqueon/AE_9.3.25.png b/assets/images/Acqueon/AE_9.3.25.png new file mode 100644 index 0000000000..5828003c3f Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.25.png differ diff --git a/assets/images/Acqueon/AE_9.3.3.png b/assets/images/Acqueon/AE_9.3.3.png new file mode 100644 index 0000000000..395430d456 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.3.png differ diff --git a/assets/images/Acqueon/AE_9.3.4.gif b/assets/images/Acqueon/AE_9.3.4.gif new file mode 100644 index 0000000000..c827545d07 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.4.gif differ diff --git a/assets/images/Acqueon/AE_9.3.5.gif b/assets/images/Acqueon/AE_9.3.5.gif new file mode 100644 index 0000000000..d2aaf61fe5 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.5.gif differ diff --git a/assets/images/Acqueon/AE_9.3.6.gif b/assets/images/Acqueon/AE_9.3.6.gif new file mode 100644 index 0000000000..eeae85d15a Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.6.gif differ diff --git a/assets/images/Acqueon/AE_9.3.7.gif b/assets/images/Acqueon/AE_9.3.7.gif new file mode 100644 index 0000000000..4742a7c1f7 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.7.gif differ diff --git a/assets/images/Acqueon/AE_9.3.8.png b/assets/images/Acqueon/AE_9.3.8.png new file mode 100644 index 0000000000..8d156378e1 Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.8.png differ diff --git a/assets/images/Acqueon/AE_9.3.9.png b/assets/images/Acqueon/AE_9.3.9.png new file mode 100644 index 0000000000..e920fb7efd Binary files /dev/null and b/assets/images/Acqueon/AE_9.3.9.png differ diff --git a/assets/images/AgentDesktopOverview.png b/assets/images/AgentDesktopOverview.png new file mode 100644 index 0000000000..7159eb9f20 Binary files /dev/null and b/assets/images/AgentDesktopOverview.png differ diff --git a/assets/images/Analyzer/APS.png b/assets/images/Analyzer/APS.png new file mode 100644 index 0000000000..ff146d28fa Binary files /dev/null and b/assets/images/Analyzer/APS.png differ diff --git a/assets/images/Analyzer/AgentHome.png b/assets/images/Analyzer/AgentHome.png new file mode 100644 index 0000000000..cc07f5bc8f Binary files /dev/null and b/assets/images/Analyzer/AgentHome.png differ diff --git a/assets/images/Analyzer/Analyzer_Import.zip b/assets/images/Analyzer/Analyzer_Import.zip new file mode 100644 index 0000000000..a90f8d37eb Binary files /dev/null and b/assets/images/Analyzer/Analyzer_Import.zip differ diff --git a/assets/images/Analyzer/Copy.png b/assets/images/Analyzer/Copy.png new file mode 100644 index 0000000000..3c87bac1f5 Binary files /dev/null and b/assets/images/Analyzer/Copy.png differ diff --git a/assets/images/Analyzer/CustomDesktopLayout_v1.json b/assets/images/Analyzer/CustomDesktopLayout_v1.json new file mode 100644 index 0000000000..659388eb3f --- /dev/null +++ b/assets/images/Analyzer/CustomDesktopLayout_v1.json @@ -0,0 +1,150 @@ +{ + "version": "0.0.6", + "appTitle": "Contact Center Desktop", + "logo": "", + "dragDropEnabled": false, + "notificationTimer": 8, + "maximumNotificationCount": 3, + "browserNotificationTimer": 8, + "wxmConfigured": false, + "webexAppConfigured": true, + "area": { + "headless": { + "id": "dw-headless", + "widgets": { "comp1": { "comp": "div" } }, + "layout": { "areas": [["comp1"]], "size": { "cols": [1], "rows": [1] } } + }, + "panel": { + "comp": "md-tabs", + "attributes": { "class": "widget-tabs" }, + "children": [ + { + "comp": "md-tab", + "attributes": { "slot": "tab", "class": "widget-pane-tab" }, + "children": [{ "comp": "slot", "attributes": { "name": "IVR_TRANSCRIPT_TAB" } }], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [{ "comp": "slot", "attributes": { "name": "IVR_TRANSCRIPT" } }], + "visibility": "IVR_TRANSCRIPT" + }, + { + "comp": "md-tab", + "attributes": { "slot": "tab" }, + "children": [{ "comp": "slot", "attributes": { "name": "WXM_JOURNEY_TAB" } }], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [ + { + "comp": "agentx-wc-cloudcherry-widget", + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "teamId": "$STORE.agent.teamName", + "ani": "$STORE.agentContact.taskSelected.ani", + "isDarkMode": "$STORE.app.darkMode" + }, + "wrapper": { + "title": "Customer Experience Journey", + "maximizeAreaName": "app-maximize-area" + } + } + ], + "visibility": "WXM_JOURNEY" + }, + { + "comp": "md-tab", + "attributes": { "slot": "tab", "class": "widget-pane-tab" }, + "children": [{ "comp": "slot", "attributes": { "name": "CONTACT_HISTORY_TAB" } }] + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [{ "comp": "slot", "attributes": { "name": "CONTACT_HISTORY" } }] + }, + { + "comp": "md-tab", + "attributes": { "slot": "tab", "class": "widget-pane-tab" }, + "children": [{ "comp": "slot", "attributes": { "name": "SCREEN_POP_TAB" } }], + "visibility": "SCREEN_POP" + }, + { + "comp": "md-tab-panel", + "attributes": { "slot": "panel", "class": "widget-pane" }, + "children": [{ "comp": "slot", "attributes": { "name": "SCREEN_POP" } }], + "visibility": "SCREEN_POP" + } + ] + }, + "navigation": [ + { + "nav": { + "label": "Analyzer iFrame Widget", + "icon": "https://qaemailmedia.s3.amazonaws.com/d3116af2-20cd-4306-b471-0a44cc164308/AnalyzerReport_3323586588428918.png", + "iconType": "other", + "navigateTo": "iframe-widget", + "align": "top" + }, + "page": { + "id": "iframe-widget", + "widgets": { + "left": { + "comp": "agentx-wc-iframe", + "attributes": { + "src": "https://analyzer-v2.wxcc-us1.cisco.com/analyzer/view/dashboard?tId=494&rId=100069" + } + } + }, + "layout": { + "areas": [["left"]], + "size": { + "cols": [1], + "rows": [1] + } + } + } + }, + { + "nav": { + "label": "Customer Experience Analytics", + "icon": "/app/images/wxm.bcd45cc3.svg", + "iconType": "other", + "navigateTo": "wxm-metrics", + "align": "top" + }, + "page": { + "id": "wxm-metrics", + "widgets": { + "comp1": { + "comp": "agentx-wc-cloudcherry-widget", + "attributes": { + "metrics": true + }, + "properties": { + "userModel": "$STORE.app.userModel", + "spaceId": "", + "metricsId": "", + "teamId": "$STORE.agent.teamName", + "isDarkMode": "$STORE.app.darkMode" + } + } + }, + "layout": { + "areas": [["comp1"]], + "size": { + "cols": [1], + "rows": [1] + } + } + }, + "visibility": "WXM_METRICS" + } + ] + } +} diff --git a/assets/images/Analyzer/DataRepos.png b/assets/images/Analyzer/DataRepos.png new file mode 100644 index 0000000000..c3ea8972d8 Binary files /dev/null and b/assets/images/Analyzer/DataRepos.png differ diff --git a/assets/images/Analyzer/DesktopWidget.png b/assets/images/Analyzer/DesktopWidget.png new file mode 100644 index 0000000000..0cd18fea2b Binary files /dev/null and b/assets/images/Analyzer/DesktopWidget.png differ diff --git a/assets/images/Analyzer/Ellipsis.png b/assets/images/Analyzer/Ellipsis.png new file mode 100644 index 0000000000..01851b800b Binary files /dev/null and b/assets/images/Analyzer/Ellipsis.png differ diff --git a/assets/images/Analyzer/Expand.png b/assets/images/Analyzer/Expand.png new file mode 100644 index 0000000000..6dd8f1d0d4 Binary files /dev/null and b/assets/images/Analyzer/Expand.png differ diff --git a/assets/images/Analyzer/MarkAsRead.png b/assets/images/Analyzer/MarkAsRead.png new file mode 100644 index 0000000000..3978e52935 Binary files /dev/null and b/assets/images/Analyzer/MarkAsRead.png differ diff --git a/assets/images/Analyzer/Queue1.png b/assets/images/Analyzer/Queue1.png new file mode 100644 index 0000000000..b1458c19d4 Binary files /dev/null and b/assets/images/Analyzer/Queue1.png differ diff --git a/assets/images/Analyzer/Queue2.png b/assets/images/Analyzer/Queue2.png new file mode 100644 index 0000000000..df90cd59b6 Binary files /dev/null and b/assets/images/Analyzer/Queue2.png differ diff --git a/assets/images/Analyzer/StockStructure.png b/assets/images/Analyzer/StockStructure.png new file mode 100644 index 0000000000..2e4b883d7b Binary files /dev/null and b/assets/images/Analyzer/StockStructure.png differ diff --git a/assets/images/Analyzer/ThresholdAlert.png b/assets/images/Analyzer/ThresholdAlert.png new file mode 100644 index 0000000000..3781ca241e Binary files /dev/null and b/assets/images/Analyzer/ThresholdAlert.png differ diff --git a/assets/images/Analyzer/dots.png b/assets/images/Analyzer/dots.png new file mode 100644 index 0000000000..e063ca50ef Binary files /dev/null and b/assets/images/Analyzer/dots.png differ diff --git a/assets/images/Analyzer/eye.png b/assets/images/Analyzer/eye.png new file mode 100644 index 0000000000..70d38e97ef Binary files /dev/null and b/assets/images/Analyzer/eye.png differ diff --git a/assets/images/Analyzer/grid.png b/assets/images/Analyzer/grid.png new file mode 100644 index 0000000000..ac913c1c2c Binary files /dev/null and b/assets/images/Analyzer/grid.png differ diff --git a/assets/images/Analyzer/substract.png b/assets/images/Analyzer/substract.png new file mode 100644 index 0000000000..719900b79b Binary files /dev/null and b/assets/images/Analyzer/substract.png differ diff --git a/assets/images/Analyzer/swap.png b/assets/images/Analyzer/swap.png new file mode 100644 index 0000000000..85b9576940 Binary files /dev/null and b/assets/images/Analyzer/swap.png differ diff --git a/assets/images/Analyzer/zoom.png b/assets/images/Analyzer/zoom.png new file mode 100644 index 0000000000..dd55bde973 Binary files /dev/null and b/assets/images/Analyzer/zoom.png differ diff --git a/assets/images/Bulk-1.gif b/assets/images/Bulk-1.gif new file mode 100644 index 0000000000..2d4f88f8f2 Binary files /dev/null and b/assets/images/Bulk-1.gif differ diff --git a/assets/images/CX/2023-12-23_22h21_31.png b/assets/images/CX/2023-12-23_22h21_31.png new file mode 100644 index 0000000000..2afff69446 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h21_31.png differ diff --git a/assets/images/CX/2023-12-23_22h22_46.png b/assets/images/CX/2023-12-23_22h22_46.png new file mode 100644 index 0000000000..fe4cb26b91 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h22_46.png differ diff --git a/assets/images/CX/2023-12-23_22h25_09.png b/assets/images/CX/2023-12-23_22h25_09.png new file mode 100644 index 0000000000..e560a4e71b Binary files /dev/null and b/assets/images/CX/2023-12-23_22h25_09.png differ diff --git a/assets/images/CX/2023-12-23_22h27_26.png b/assets/images/CX/2023-12-23_22h27_26.png new file mode 100644 index 0000000000..54e5d0ecec Binary files /dev/null and b/assets/images/CX/2023-12-23_22h27_26.png differ diff --git a/assets/images/CX/2023-12-23_22h28_19.png b/assets/images/CX/2023-12-23_22h28_19.png new file mode 100644 index 0000000000..27c6f71c3b Binary files /dev/null and b/assets/images/CX/2023-12-23_22h28_19.png differ diff --git a/assets/images/CX/2023-12-23_22h29_20.png b/assets/images/CX/2023-12-23_22h29_20.png new file mode 100644 index 0000000000..bfdf9cbc76 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h29_20.png differ diff --git a/assets/images/CX/2023-12-23_22h30_08 (1).png b/assets/images/CX/2023-12-23_22h30_08 (1).png new file mode 100644 index 0000000000..2b8f96e90a Binary files /dev/null and b/assets/images/CX/2023-12-23_22h30_08 (1).png differ diff --git a/assets/images/CX/2023-12-23_22h30_56.png b/assets/images/CX/2023-12-23_22h30_56.png new file mode 100644 index 0000000000..734367b80f Binary files /dev/null and b/assets/images/CX/2023-12-23_22h30_56.png differ diff --git a/assets/images/CX/2023-12-23_22h31_32.png b/assets/images/CX/2023-12-23_22h31_32.png new file mode 100644 index 0000000000..7b4563ee66 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h31_32.png differ diff --git a/assets/images/CX/2023-12-23_22h32_10.png b/assets/images/CX/2023-12-23_22h32_10.png new file mode 100644 index 0000000000..70ebb4dbb9 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h32_10.png differ diff --git a/assets/images/CX/2023-12-23_22h32_59.png b/assets/images/CX/2023-12-23_22h32_59.png new file mode 100644 index 0000000000..6afa1774b4 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h32_59.png differ diff --git a/assets/images/CX/2023-12-23_22h33_57.png b/assets/images/CX/2023-12-23_22h33_57.png new file mode 100644 index 0000000000..d86e79126e Binary files /dev/null and b/assets/images/CX/2023-12-23_22h33_57.png differ diff --git a/assets/images/CX/2023-12-23_22h34_37.png b/assets/images/CX/2023-12-23_22h34_37.png new file mode 100644 index 0000000000..0258420498 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h34_37.png differ diff --git a/assets/images/CX/2023-12-23_22h35_31.png b/assets/images/CX/2023-12-23_22h35_31.png new file mode 100644 index 0000000000..976251e5e0 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h35_31.png differ diff --git a/assets/images/CX/2023-12-23_22h36_12.png b/assets/images/CX/2023-12-23_22h36_12.png new file mode 100644 index 0000000000..cb2ddd6b56 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h36_12.png differ diff --git a/assets/images/CX/2023-12-23_22h38_41.png b/assets/images/CX/2023-12-23_22h38_41.png new file mode 100644 index 0000000000..f57ccae471 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h38_41.png differ diff --git a/assets/images/CX/2023-12-23_22h39_19.png b/assets/images/CX/2023-12-23_22h39_19.png new file mode 100644 index 0000000000..63c9f0eafa Binary files /dev/null and b/assets/images/CX/2023-12-23_22h39_19.png differ diff --git a/assets/images/CX/2023-12-23_22h40_10.png b/assets/images/CX/2023-12-23_22h40_10.png new file mode 100644 index 0000000000..c5a1f95a9e Binary files /dev/null and b/assets/images/CX/2023-12-23_22h40_10.png differ diff --git a/assets/images/CX/2023-12-23_22h40_56.png b/assets/images/CX/2023-12-23_22h40_56.png new file mode 100644 index 0000000000..30d573fa50 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h40_56.png differ diff --git a/assets/images/CX/2023-12-23_22h44_11.png b/assets/images/CX/2023-12-23_22h44_11.png new file mode 100644 index 0000000000..0567c6c706 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h44_11.png differ diff --git a/assets/images/CX/2023-12-23_22h46_25.png b/assets/images/CX/2023-12-23_22h46_25.png new file mode 100644 index 0000000000..be5618faef Binary files /dev/null and b/assets/images/CX/2023-12-23_22h46_25.png differ diff --git a/assets/images/CX/2023-12-23_22h47_09.png b/assets/images/CX/2023-12-23_22h47_09.png new file mode 100644 index 0000000000..c43228e613 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h47_09.png differ diff --git a/assets/images/CX/2023-12-23_22h47_44.png b/assets/images/CX/2023-12-23_22h47_44.png new file mode 100644 index 0000000000..7ddb2147d1 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h47_44.png differ diff --git a/assets/images/CX/2023-12-23_22h48_24.png b/assets/images/CX/2023-12-23_22h48_24.png new file mode 100644 index 0000000000..3e0ed3549c Binary files /dev/null and b/assets/images/CX/2023-12-23_22h48_24.png differ diff --git a/assets/images/CX/2023-12-23_22h49_33.png b/assets/images/CX/2023-12-23_22h49_33.png new file mode 100644 index 0000000000..e90f839d80 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h49_33.png differ diff --git a/assets/images/CX/2023-12-23_22h50_16.png b/assets/images/CX/2023-12-23_22h50_16.png new file mode 100644 index 0000000000..c7d0e270e6 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h50_16.png differ diff --git a/assets/images/CX/2023-12-23_22h51_16.png b/assets/images/CX/2023-12-23_22h51_16.png new file mode 100644 index 0000000000..8e88ea6597 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h51_16.png differ diff --git a/assets/images/CX/2023-12-23_22h52_03.png b/assets/images/CX/2023-12-23_22h52_03.png new file mode 100644 index 0000000000..5002d42c65 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h52_03.png differ diff --git a/assets/images/CX/2023-12-23_22h52_45.png b/assets/images/CX/2023-12-23_22h52_45.png new file mode 100644 index 0000000000..7afa83ea9e Binary files /dev/null and b/assets/images/CX/2023-12-23_22h52_45.png differ diff --git a/assets/images/CX/2023-12-23_22h54_20.png b/assets/images/CX/2023-12-23_22h54_20.png new file mode 100644 index 0000000000..d6195bdd07 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h54_20.png differ diff --git a/assets/images/CX/2023-12-23_22h55_05.png b/assets/images/CX/2023-12-23_22h55_05.png new file mode 100644 index 0000000000..8a76f9c0cd Binary files /dev/null and b/assets/images/CX/2023-12-23_22h55_05.png differ diff --git a/assets/images/CX/2023-12-23_22h55_56.png b/assets/images/CX/2023-12-23_22h55_56.png new file mode 100644 index 0000000000..4ba71b7a33 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h55_56.png differ diff --git a/assets/images/CX/2023-12-23_22h56_39.png b/assets/images/CX/2023-12-23_22h56_39.png new file mode 100644 index 0000000000..f39588240b Binary files /dev/null and b/assets/images/CX/2023-12-23_22h56_39.png differ diff --git a/assets/images/CX/2023-12-23_22h57_12.png b/assets/images/CX/2023-12-23_22h57_12.png new file mode 100644 index 0000000000..4458527993 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h57_12.png differ diff --git a/assets/images/CX/2023-12-23_22h57_50.png b/assets/images/CX/2023-12-23_22h57_50.png new file mode 100644 index 0000000000..ab3fb4c8f0 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h57_50.png differ diff --git a/assets/images/CX/2023-12-23_22h58_23.png b/assets/images/CX/2023-12-23_22h58_23.png new file mode 100644 index 0000000000..9b3f8fb7e3 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h58_23.png differ diff --git a/assets/images/CX/2023-12-23_22h58_57.png b/assets/images/CX/2023-12-23_22h58_57.png new file mode 100644 index 0000000000..1076d5f2f7 Binary files /dev/null and b/assets/images/CX/2023-12-23_22h58_57.png differ diff --git a/assets/images/CX/2023-12-23_22h59_34.png b/assets/images/CX/2023-12-23_22h59_34.png new file mode 100644 index 0000000000..d5f96c552f Binary files /dev/null and b/assets/images/CX/2023-12-23_22h59_34.png differ diff --git a/assets/images/CX/2023-12-23_23h00_31.png b/assets/images/CX/2023-12-23_23h00_31.png new file mode 100644 index 0000000000..7b765841ae Binary files /dev/null and b/assets/images/CX/2023-12-23_23h00_31.png differ diff --git a/assets/images/CX/2023-12-23_23h01_08.png b/assets/images/CX/2023-12-23_23h01_08.png new file mode 100644 index 0000000000..7df62dbb1d Binary files /dev/null and b/assets/images/CX/2023-12-23_23h01_08.png differ diff --git a/assets/images/CX/2023-12-23_23h01_43.png b/assets/images/CX/2023-12-23_23h01_43.png new file mode 100644 index 0000000000..ab6f9e6f98 Binary files /dev/null and b/assets/images/CX/2023-12-23_23h01_43.png differ diff --git a/assets/images/CX/2023-12-23_23h02_22.png b/assets/images/CX/2023-12-23_23h02_22.png new file mode 100644 index 0000000000..818745e7b4 Binary files /dev/null and b/assets/images/CX/2023-12-23_23h02_22.png differ diff --git a/assets/images/CX/2023-12-23_23h03_07.png b/assets/images/CX/2023-12-23_23h03_07.png new file mode 100644 index 0000000000..297e594a2d Binary files /dev/null and b/assets/images/CX/2023-12-23_23h03_07.png differ diff --git a/assets/images/CX/2023-12-23_23h03_39.png b/assets/images/CX/2023-12-23_23h03_39.png new file mode 100644 index 0000000000..e8a36bda1b Binary files /dev/null and b/assets/images/CX/2023-12-23_23h03_39.png differ diff --git a/assets/images/CX/2023-12-23_23h04_25.png b/assets/images/CX/2023-12-23_23h04_25.png new file mode 100644 index 0000000000..39310aedb2 Binary files /dev/null and b/assets/images/CX/2023-12-23_23h04_25.png differ diff --git a/assets/images/CX/2023-12-23_23h04_55.png b/assets/images/CX/2023-12-23_23h04_55.png new file mode 100644 index 0000000000..75f07362fb Binary files /dev/null and b/assets/images/CX/2023-12-23_23h04_55.png differ diff --git a/assets/images/CX/2023-12-23_23h05_26.png b/assets/images/CX/2023-12-23_23h05_26.png new file mode 100644 index 0000000000..3634175f7b Binary files /dev/null and b/assets/images/CX/2023-12-23_23h05_26.png differ diff --git a/assets/images/CX/2023-12-23_23h06_08.png b/assets/images/CX/2023-12-23_23h06_08.png new file mode 100644 index 0000000000..328755a337 Binary files /dev/null and b/assets/images/CX/2023-12-23_23h06_08.png differ diff --git a/assets/images/CX/2023-12-25_11h32_46.png b/assets/images/CX/2023-12-25_11h32_46.png new file mode 100644 index 0000000000..887b57c23a Binary files /dev/null and b/assets/images/CX/2023-12-25_11h32_46.png differ diff --git a/assets/images/CX/2023-12-25_11h34_03.png b/assets/images/CX/2023-12-25_11h34_03.png new file mode 100644 index 0000000000..9f45fa2865 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h34_03.png differ diff --git a/assets/images/CX/2023-12-25_11h34_59.png b/assets/images/CX/2023-12-25_11h34_59.png new file mode 100644 index 0000000000..6fc53479fc Binary files /dev/null and b/assets/images/CX/2023-12-25_11h34_59.png differ diff --git a/assets/images/CX/2023-12-25_11h35_26.png b/assets/images/CX/2023-12-25_11h35_26.png new file mode 100644 index 0000000000..4178679613 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h35_26.png differ diff --git a/assets/images/CX/2023-12-25_11h35_51.png b/assets/images/CX/2023-12-25_11h35_51.png new file mode 100644 index 0000000000..9fc069e7b0 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h35_51.png differ diff --git a/assets/images/CX/2023-12-25_11h36_35.png b/assets/images/CX/2023-12-25_11h36_35.png new file mode 100644 index 0000000000..c3ba011fb9 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h36_35.png differ diff --git a/assets/images/CX/2023-12-25_11h37_10.png b/assets/images/CX/2023-12-25_11h37_10.png new file mode 100644 index 0000000000..b5f9a5fce7 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h37_10.png differ diff --git a/assets/images/CX/2023-12-25_11h38_06.png b/assets/images/CX/2023-12-25_11h38_06.png new file mode 100644 index 0000000000..ac519f90b1 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h38_06.png differ diff --git a/assets/images/CX/2023-12-25_11h39_35.png b/assets/images/CX/2023-12-25_11h39_35.png new file mode 100644 index 0000000000..6dfec3b4ce Binary files /dev/null and b/assets/images/CX/2023-12-25_11h39_35.png differ diff --git a/assets/images/CX/2023-12-25_11h40_34.png b/assets/images/CX/2023-12-25_11h40_34.png new file mode 100644 index 0000000000..aa1b87f3df Binary files /dev/null and b/assets/images/CX/2023-12-25_11h40_34.png differ diff --git a/assets/images/CX/2023-12-25_11h41_16.png b/assets/images/CX/2023-12-25_11h41_16.png new file mode 100644 index 0000000000..8e312c6290 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h41_16.png differ diff --git a/assets/images/CX/2023-12-25_11h41_42.png b/assets/images/CX/2023-12-25_11h41_42.png new file mode 100644 index 0000000000..e5ea694ccd Binary files /dev/null and b/assets/images/CX/2023-12-25_11h41_42.png differ diff --git a/assets/images/CX/2023-12-25_11h42_11.png b/assets/images/CX/2023-12-25_11h42_11.png new file mode 100644 index 0000000000..d595406f62 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h42_11.png differ diff --git a/assets/images/CX/2023-12-25_11h42_47.png b/assets/images/CX/2023-12-25_11h42_47.png new file mode 100644 index 0000000000..bd97df397d Binary files /dev/null and b/assets/images/CX/2023-12-25_11h42_47.png differ diff --git a/assets/images/CX/2023-12-25_11h43_17.png b/assets/images/CX/2023-12-25_11h43_17.png new file mode 100644 index 0000000000..86c84bca3f Binary files /dev/null and b/assets/images/CX/2023-12-25_11h43_17.png differ diff --git a/assets/images/CX/2023-12-25_11h43_53.png b/assets/images/CX/2023-12-25_11h43_53.png new file mode 100644 index 0000000000..fc21add9cd Binary files /dev/null and b/assets/images/CX/2023-12-25_11h43_53.png differ diff --git a/assets/images/CX/2023-12-25_11h44_32.png b/assets/images/CX/2023-12-25_11h44_32.png new file mode 100644 index 0000000000..b7f42757fc Binary files /dev/null and b/assets/images/CX/2023-12-25_11h44_32.png differ diff --git a/assets/images/CX/2023-12-25_11h45_02.png b/assets/images/CX/2023-12-25_11h45_02.png new file mode 100644 index 0000000000..586eff5a58 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h45_02.png differ diff --git a/assets/images/CX/2023-12-25_11h45_58.png b/assets/images/CX/2023-12-25_11h45_58.png new file mode 100644 index 0000000000..6eee75eaa9 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h45_58.png differ diff --git a/assets/images/CX/2023-12-25_11h46_25.png b/assets/images/CX/2023-12-25_11h46_25.png new file mode 100644 index 0000000000..2491dfac3c Binary files /dev/null and b/assets/images/CX/2023-12-25_11h46_25.png differ diff --git a/assets/images/CX/2023-12-25_11h46_58.png b/assets/images/CX/2023-12-25_11h46_58.png new file mode 100644 index 0000000000..d5651ea125 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h46_58.png differ diff --git a/assets/images/CX/2023-12-25_11h47_31.png b/assets/images/CX/2023-12-25_11h47_31.png new file mode 100644 index 0000000000..2d2f322ec5 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h47_31.png differ diff --git a/assets/images/CX/2023-12-25_11h48_04.png b/assets/images/CX/2023-12-25_11h48_04.png new file mode 100644 index 0000000000..51ab58ef73 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h48_04.png differ diff --git a/assets/images/CX/2023-12-25_11h48_43.png b/assets/images/CX/2023-12-25_11h48_43.png new file mode 100644 index 0000000000..d557724020 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h48_43.png differ diff --git a/assets/images/CX/2023-12-25_11h49_14.png b/assets/images/CX/2023-12-25_11h49_14.png new file mode 100644 index 0000000000..00236bb2e9 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h49_14.png differ diff --git a/assets/images/CX/2023-12-25_11h49_48.png b/assets/images/CX/2023-12-25_11h49_48.png new file mode 100644 index 0000000000..9f386f7050 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h49_48.png differ diff --git a/assets/images/CX/2023-12-25_11h50_19.png b/assets/images/CX/2023-12-25_11h50_19.png new file mode 100644 index 0000000000..d2613ea8f6 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h50_19.png differ diff --git a/assets/images/CX/2023-12-25_11h50_52.png b/assets/images/CX/2023-12-25_11h50_52.png new file mode 100644 index 0000000000..c47f5b60ed Binary files /dev/null and b/assets/images/CX/2023-12-25_11h50_52.png differ diff --git a/assets/images/CX/2023-12-25_11h51_27.png b/assets/images/CX/2023-12-25_11h51_27.png new file mode 100644 index 0000000000..98769e05e2 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h51_27.png differ diff --git a/assets/images/CX/2023-12-25_11h51_58.png b/assets/images/CX/2023-12-25_11h51_58.png new file mode 100644 index 0000000000..9a644ca38a Binary files /dev/null and b/assets/images/CX/2023-12-25_11h51_58.png differ diff --git a/assets/images/CX/2023-12-25_11h52_40.png b/assets/images/CX/2023-12-25_11h52_40.png new file mode 100644 index 0000000000..19615fea30 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h52_40.png differ diff --git a/assets/images/CX/2023-12-25_11h53_14.png b/assets/images/CX/2023-12-25_11h53_14.png new file mode 100644 index 0000000000..8f1de6654e Binary files /dev/null and b/assets/images/CX/2023-12-25_11h53_14.png differ diff --git a/assets/images/CX/2023-12-25_11h53_44.png b/assets/images/CX/2023-12-25_11h53_44.png new file mode 100644 index 0000000000..23481af6f0 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h53_44.png differ diff --git a/assets/images/CX/2023-12-25_11h54_25.png b/assets/images/CX/2023-12-25_11h54_25.png new file mode 100644 index 0000000000..87ded15499 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h54_25.png differ diff --git a/assets/images/CX/2023-12-25_11h55_03.png b/assets/images/CX/2023-12-25_11h55_03.png new file mode 100644 index 0000000000..165b5b0f50 Binary files /dev/null and b/assets/images/CX/2023-12-25_11h55_03.png differ diff --git a/assets/images/CX/2023-12-25_11h55_36.png b/assets/images/CX/2023-12-25_11h55_36.png new file mode 100644 index 0000000000..7cb604f7da Binary files /dev/null and b/assets/images/CX/2023-12-25_11h55_36.png differ diff --git a/assets/images/CX/2023-12-25_12h01_53.png b/assets/images/CX/2023-12-25_12h01_53.png new file mode 100644 index 0000000000..b8c23dd015 Binary files /dev/null and b/assets/images/CX/2023-12-25_12h01_53.png differ diff --git a/assets/images/CX/2023-12-25_12h02_38.png b/assets/images/CX/2023-12-25_12h02_38.png new file mode 100644 index 0000000000..e4c07b98d0 Binary files /dev/null and b/assets/images/CX/2023-12-25_12h02_38.png differ diff --git a/assets/images/CX/2023-12-25_12h03_13.png b/assets/images/CX/2023-12-25_12h03_13.png new file mode 100644 index 0000000000..60b7485a9e Binary files /dev/null and b/assets/images/CX/2023-12-25_12h03_13.png differ diff --git a/assets/images/CX/2023-12-25_12h03_52.png b/assets/images/CX/2023-12-25_12h03_52.png new file mode 100644 index 0000000000..318df73e70 Binary files /dev/null and b/assets/images/CX/2023-12-25_12h03_52.png differ diff --git a/assets/images/CX/2023-12-25_12h04_54.png b/assets/images/CX/2023-12-25_12h04_54.png new file mode 100644 index 0000000000..d8164ebac5 Binary files /dev/null and b/assets/images/CX/2023-12-25_12h04_54.png differ diff --git a/assets/images/CX/2023-12-27_10h47_01.png b/assets/images/CX/2023-12-27_10h47_01.png new file mode 100644 index 0000000000..f6f86c2c11 Binary files /dev/null and b/assets/images/CX/2023-12-27_10h47_01.png differ diff --git a/assets/images/CX/test b/assets/images/CX/test new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/assets/images/CX/test @@ -0,0 +1 @@ + diff --git a/assets/images/CheckPopSetting.png b/assets/images/CheckPopSetting.png new file mode 100644 index 0000000000..e9cf02a0ed Binary files /dev/null and b/assets/images/CheckPopSetting.png differ diff --git a/assets/images/DC_AddUser.png b/assets/images/DC_AddUser.png new file mode 100644 index 0000000000..6b699c79ab Binary files /dev/null and b/assets/images/DC_AddUser.png differ diff --git a/assets/images/DC_Architecture.png b/assets/images/DC_Architecture.png new file mode 100644 index 0000000000..bf4fdf0ac9 Binary files /dev/null and b/assets/images/DC_Architecture.png differ diff --git a/assets/images/DC_Architecture.png.md b/assets/images/DC_Architecture.png.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/images/DC_Invite.png b/assets/images/DC_Invite.png new file mode 100644 index 0000000000..e72b61d8c1 Binary files /dev/null and b/assets/images/DC_Invite.png differ diff --git a/assets/images/DC_Lab.12.17_Introduction_EventScheduler.png b/assets/images/DC_Lab.12.17_Introduction_EventScheduler.png new file mode 100644 index 0000000000..5bfe407ff0 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Introduction_EventScheduler.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event1.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event1.png new file mode 100644 index 0000000000..9fb029bfd1 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event1.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event10.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event10.png new file mode 100644 index 0000000000..1f1665bd14 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event10.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event11.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event11.png new file mode 100644 index 0000000000..6d2f83872e Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event11.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event12.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event12.png new file mode 100644 index 0000000000..76da7edc29 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event12.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event13.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event13.png new file mode 100644 index 0000000000..d4b0bdfe4c Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event13.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event14.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event14.png new file mode 100644 index 0000000000..ce539aea4a Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event14.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event15.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event15.png new file mode 100644 index 0000000000..6d7569438a Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event15.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event16.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event16.png new file mode 100644 index 0000000000..1916317500 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event16.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event17.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event17.png new file mode 100644 index 0000000000..73b764f227 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event17.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event18.1.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event18.1.png new file mode 100644 index 0000000000..1dc1441b9b Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event18.1.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event18.2.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event18.2.png new file mode 100644 index 0000000000..711f8a5ad2 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event18.2.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event19.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event19.png new file mode 100644 index 0000000000..a8420b2177 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event19.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event2.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event2.png new file mode 100644 index 0000000000..c5fabf3aa3 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event2.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event20.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event20.png new file mode 100644 index 0000000000..5425261327 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event20.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event21.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event21.png new file mode 100644 index 0000000000..cc153c4456 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event21.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event22.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event22.png new file mode 100644 index 0000000000..bccaea9d49 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event22.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event23.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event23.png new file mode 100644 index 0000000000..43ecc8cec5 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event23.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event24.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event24.png new file mode 100644 index 0000000000..f7c169748a Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event24.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event25.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event25.png new file mode 100644 index 0000000000..d7455de18d Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event25.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event3.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event3.png new file mode 100644 index 0000000000..1583fef713 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event3.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event4.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event4.png new file mode 100644 index 0000000000..d5710c6046 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event4.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event5.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event5.png new file mode 100644 index 0000000000..bdb5a087e6 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event5.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event6.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event6.png new file mode 100644 index 0000000000..cadb04dc3e Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event6.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.1.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.1.png new file mode 100644 index 0000000000..2ea069bcc4 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.1.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.2.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.2.png new file mode 100644 index 0000000000..b0e94375fb Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.2.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.3.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.3.png new file mode 100644 index 0000000000..25a305b98c Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.3.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.4.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.4.png new file mode 100644 index 0000000000..be475c1491 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event7.4.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.1.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.1.png new file mode 100644 index 0000000000..6a865bd6dc Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.1.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.2.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.2.png new file mode 100644 index 0000000000..c00c8cadb1 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.2.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.3.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.3.png new file mode 100644 index 0000000000..1ac057157d Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event8.3.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_Custom_Event9.png b/assets/images/DC_Lab.12.17_Schedule_Custom_Event9.png new file mode 100644 index 0000000000..3ed3808cef Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_Custom_Event9.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event1.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event1.png new file mode 100644 index 0000000000..eba05b13a5 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event1.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event2.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event2.png new file mode 100644 index 0000000000..0473d5e874 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event2.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event3.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event3.png new file mode 100644 index 0000000000..33607706c8 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event3.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event4.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event4.png new file mode 100644 index 0000000000..495f5294e1 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event4.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event5.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event5.png new file mode 100644 index 0000000000..e35f316bf8 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event5.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event6.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event6.png new file mode 100644 index 0000000000..707bd99ec9 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event6.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event7.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event7.png new file mode 100644 index 0000000000..bcdc8d3d6b Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event7.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event8.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event8.png new file mode 100644 index 0000000000..8704c2c3af Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event8.png differ diff --git a/assets/images/DC_Lab.12.17_Schedule_SMS_Event9.png b/assets/images/DC_Lab.12.17_Schedule_SMS_Event9.png new file mode 100644 index 0000000000..b2105f2c82 Binary files /dev/null and b/assets/images/DC_Lab.12.17_Schedule_SMS_Event9.png differ diff --git a/assets/images/DC_Lab.12.7_Add_forwarding_Address_1.png b/assets/images/DC_Lab.12.7_Add_forwarding_Address_1.png new file mode 100644 index 0000000000..231843852b Binary files /dev/null and b/assets/images/DC_Lab.12.7_Add_forwarding_Address_1.png differ diff --git a/assets/images/DC_Lab.12.7_Add_forwarding_Address_2.png b/assets/images/DC_Lab.12.7_Add_forwarding_Address_2.png new file mode 100644 index 0000000000..b2919a9392 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Add_forwarding_Address_2.png differ diff --git a/assets/images/DC_Lab.12.7_Add_forwarding_Address_3.gif b/assets/images/DC_Lab.12.7_Add_forwarding_Address_3.gif new file mode 100644 index 0000000000..4a29b7439f Binary files /dev/null and b/assets/images/DC_Lab.12.7_Add_forwarding_Address_3.gif differ diff --git a/assets/images/DC_Lab.12.7_Add_forwarding_Address_4.gif b/assets/images/DC_Lab.12.7_Add_forwarding_Address_4.gif new file mode 100644 index 0000000000..d85ef47703 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Add_forwarding_Address_4.gif differ diff --git a/assets/images/DC_Lab.12.7_Add_forwarding_Address_5.png b/assets/images/DC_Lab.12.7_Add_forwarding_Address_5.png new file mode 100644 index 0000000000..a1ceea25e4 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Add_forwarding_Address_5.png differ diff --git a/assets/images/DC_Lab.12.7_Add_forwarding_Address_6.png b/assets/images/DC_Lab.12.7_Add_forwarding_Address_6.png new file mode 100644 index 0000000000..ac3dce5781 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Add_forwarding_Address_6.png differ diff --git a/assets/images/DC_Lab.12.7_Add_forwarding_Address_7.png b/assets/images/DC_Lab.12.7_Add_forwarding_Address_7.png new file mode 100644 index 0000000000..373205a6b5 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Add_forwarding_Address_7.png differ diff --git a/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_1.png b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_1.png new file mode 100644 index 0000000000..a9a85f7a93 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_1.png differ diff --git a/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_2.png b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_2.png new file mode 100644 index 0000000000..9976afdb69 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_2.png differ diff --git a/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_3.png b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_3.png new file mode 100644 index 0000000000..2fb661bafe Binary files /dev/null and b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_3.png differ diff --git a/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_4.png b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_4.png new file mode 100644 index 0000000000..784daa6f10 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_4.png differ diff --git a/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_5.png b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_5.png new file mode 100644 index 0000000000..673a62bfa2 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Configure_OAuth_Consent_Screen_and_Scopes_5.png differ diff --git a/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_1.png b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_1.png new file mode 100644 index 0000000000..af69637ae1 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_1.png differ diff --git a/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_2.png b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_2.png new file mode 100644 index 0000000000..640902a439 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_2.png differ diff --git a/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_3.png b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_3.png new file mode 100644 index 0000000000..d8c3cb3df0 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_3.png differ diff --git a/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_4.png b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_4.png new file mode 100644 index 0000000000..96e1ebf45d Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_4.png differ diff --git a/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_flowid.png b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_flowid.png new file mode 100644 index 0000000000..a24ee9d8aa Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create-Upload_Email_flow_flowid.png differ diff --git a/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC.png b/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC.png new file mode 100644 index 0000000000..1acf6d1b86 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC.png differ diff --git a/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_1.gif b/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_1.gif new file mode 100644 index 0000000000..af610db55b Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_1.gif differ diff --git a/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_2.gif b/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_2.gif new file mode 100644 index 0000000000..3d45455fe3 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_2.gif differ diff --git a/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_3.gif b/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_3.gif new file mode 100644 index 0000000000..3c91708b19 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create_Email_Asset_and_Register_to_WebexCC_3.gif differ diff --git a/assets/images/DC_Lab.12.7_Create_new_project_at_Google_API_Console_1.png b/assets/images/DC_Lab.12.7_Create_new_project_at_Google_API_Console_1.png new file mode 100644 index 0000000000..a72c36cd7d Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create_new_project_at_Google_API_Console_1.png differ diff --git a/assets/images/DC_Lab.12.7_Create_new_project_at_Google_API_Console_2.png b/assets/images/DC_Lab.12.7_Create_new_project_at_Google_API_Console_2.png new file mode 100644 index 0000000000..ef8c55bc94 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Create_new_project_at_Google_API_Console_2.png differ diff --git a/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_1.png b/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_1.png new file mode 100644 index 0000000000..dbb162b232 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_1.png differ diff --git a/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_2.png b/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_2.png new file mode 100644 index 0000000000..533967e8ea Binary files /dev/null and b/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_2.png differ diff --git a/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_3.png b/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_3.png new file mode 100644 index 0000000000..06d62ba4d4 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Credentials_and_authentication_with_OAuth_2.0_3.png differ diff --git a/assets/images/DC_Lab.12.7_Email_ConfigurationOrder.png b/assets/images/DC_Lab.12.7_Email_ConfigurationOrder.png new file mode 100644 index 0000000000..16381151b8 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Email_ConfigurationOrder.png differ diff --git a/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_1.png b/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_1.png new file mode 100644 index 0000000000..31261ae90b Binary files /dev/null and b/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_1.png differ diff --git a/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_2.png b/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_2.png new file mode 100644 index 0000000000..d2c1f59d29 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_2.png differ diff --git a/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_3.png b/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_3.png new file mode 100644 index 0000000000..b36394b84e Binary files /dev/null and b/assets/images/DC_Lab.12.7_Email_Entry_Point_and_Queue_creation_3.png differ diff --git a/assets/images/DC_Lab.12.7_Enable_Gmail_API_1.png b/assets/images/DC_Lab.12.7_Enable_Gmail_API_1.png new file mode 100644 index 0000000000..f083a285be Binary files /dev/null and b/assets/images/DC_Lab.12.7_Enable_Gmail_API_1.png differ diff --git a/assets/images/DC_Lab.12.7_Enable_Gmail_API_2.png b/assets/images/DC_Lab.12.7_Enable_Gmail_API_2.png new file mode 100644 index 0000000000..975aff97b1 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Enable_Gmail_API_2.png differ diff --git a/assets/images/DC_Lab.12.7_Gmail_account_configuration_1.png b/assets/images/DC_Lab.12.7_Gmail_account_configuration_1.png new file mode 100644 index 0000000000..b2919a9392 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Gmail_account_configuration_1.png differ diff --git a/assets/images/DC_Lab.12.7_Gmail_account_configuration_2.png b/assets/images/DC_Lab.12.7_Gmail_account_configuration_2.png new file mode 100644 index 0000000000..a2cb714a35 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Gmail_account_configuration_2.png differ diff --git a/assets/images/DC_Lab.12.7_Verification_-_Send_an_Email_and_accept_the_task_1.png b/assets/images/DC_Lab.12.7_Verification_-_Send_an_Email_and_accept_the_task_1.png new file mode 100644 index 0000000000..4ee4bbb511 Binary files /dev/null and b/assets/images/DC_Lab.12.7_Verification_-_Send_an_Email_and_accept_the_task_1.png differ diff --git a/assets/images/DC_Lab.12.7_Verification_-_Send_an_Email_and_accept_the_task_2.png b/assets/images/DC_Lab.12.7_Verification_-_Send_an_Email_and_accept_the_task_2.png new file mode 100644 index 0000000000..2df52fa6eb Binary files /dev/null and b/assets/images/DC_Lab.12.7_Verification_-_Send_an_Email_and_accept_the_task_2.png differ diff --git a/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow1.png b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow1.png new file mode 100644 index 0000000000..09dcf52273 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow1.png differ diff --git a/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow2.png b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow2.png new file mode 100644 index 0000000000..fd19e985fd Binary files /dev/null and b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow2.png differ diff --git a/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow3.png b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow3.png new file mode 100644 index 0000000000..1e1b1eb3a5 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow3.png differ diff --git a/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow4.png b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow4.png new file mode 100644 index 0000000000..b87a86b7db Binary files /dev/null and b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow4.png differ diff --git a/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow5.png b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow5.png new file mode 100644 index 0000000000..d4782b9843 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow5.png differ diff --git a/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow6.png b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow6.png new file mode 100644 index 0000000000..e08bf14a64 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow6.png differ diff --git a/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow7.png b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow7.png new file mode 100644 index 0000000000..367bc0100a Binary files /dev/null and b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flow7.png differ diff --git a/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flowID.png b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flowID.png new file mode 100644 index 0000000000..7a5208d7e1 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Create-Upload_Whatsapp_flowID.png differ diff --git a/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request1.png b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request1.png new file mode 100644 index 0000000000..4ee4bbb511 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request1.png differ diff --git a/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request2.png b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request2.png new file mode 100644 index 0000000000..8019021fdb Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request2.png differ diff --git a/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request3.png b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request3.png new file mode 100644 index 0000000000..fed230b682 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request3.png differ diff --git a/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request4.png b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request4.png new file mode 100644 index 0000000000..d33c20d574 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request4.png differ diff --git a/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request5.png b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request5.png new file mode 100644 index 0000000000..4ec04e2089 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request5.png differ diff --git a/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request6.png b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request6.png new file mode 100644 index 0000000000..d93836ba86 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request6.png differ diff --git a/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request7.png b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request7.png new file mode 100644 index 0000000000..a07ae88ec5 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request7.png differ diff --git a/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request8.png b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request8.png new file mode 100644 index 0000000000..1484f710db Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verification_-_send_Whatsapp_message_and_accept_the_request8.png differ diff --git a/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment1.png b/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment1.png new file mode 100644 index 0000000000..247ba7ff87 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment1.png differ diff --git a/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment2.png b/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment2.png new file mode 100644 index 0000000000..2b84d522c5 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment2.png differ diff --git a/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment3.png b/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment3.png new file mode 100644 index 0000000000..d81fc581a0 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment3.png differ diff --git a/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment4.png b/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment4.png new file mode 100644 index 0000000000..57e1d6f08e Binary files /dev/null and b/assets/images/DC_Lab_12.11_Verify_Whatsapp_Number_Assignment4.png differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC1.png b/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC1.png new file mode 100644 index 0000000000..4876337883 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC1.png differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC2.png b/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC2.png new file mode 100644 index 0000000000..dc6d0b439b Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC2.png differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC3.png b/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC3.png new file mode 100644 index 0000000000..241cb670d1 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC3.png differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC4.png b/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC4.png new file mode 100644 index 0000000000..e38ba739e0 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Asset_registration_to_WebexCC4.png differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation1.jpg b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation1.jpg new file mode 100644 index 0000000000..87b026daf9 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation1.jpg differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation2.png b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation2.png new file mode 100644 index 0000000000..8ff95ef0dc Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation2.png differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation3.jpg b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation3.jpg new file mode 100644 index 0000000000..475142c6d1 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation3.jpg differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation4.png b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation4.png new file mode 100644 index 0000000000..7a55a9dbb4 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation4.png differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation5.png b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation5.png new file mode 100644 index 0000000000..1108cecd34 Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation5.png differ diff --git a/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation6.png b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation6.png new file mode 100644 index 0000000000..48307702ec Binary files /dev/null and b/assets/images/DC_Lab_12.11_Whatsapp_Entry_Point_and_Queue_creation6.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_1.png b/assets/images/DC_Lab_12.12._Create_Connect_1.png new file mode 100644 index 0000000000..9c5ed7373d Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_1.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_2.png b/assets/images/DC_Lab_12.12._Create_Connect_2.png new file mode 100644 index 0000000000..285e204133 Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_2.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_3.png b/assets/images/DC_Lab_12.12._Create_Connect_3.png new file mode 100644 index 0000000000..d13d4e1c5b Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_3.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_4.png b/assets/images/DC_Lab_12.12._Create_Connect_4.png new file mode 100644 index 0000000000..72e31cd66f Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_4.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_4_1.png b/assets/images/DC_Lab_12.12._Create_Connect_4_1.png new file mode 100644 index 0000000000..46d33ce31a Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_4_1.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_4_2.png b/assets/images/DC_Lab_12.12._Create_Connect_4_2.png new file mode 100644 index 0000000000..987cd98856 Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_4_2.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_5.png b/assets/images/DC_Lab_12.12._Create_Connect_5.png new file mode 100644 index 0000000000..a203102e84 Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_5.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_6.png.md b/assets/images/DC_Lab_12.12._Create_Connect_6.png.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/images/DC_Lab_12.12._Create_Connect_6_1.png b/assets/images/DC_Lab_12.12._Create_Connect_6_1.png new file mode 100644 index 0000000000..e5377f83f9 Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_6_1.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_6_2.png b/assets/images/DC_Lab_12.12._Create_Connect_6_2.png new file mode 100644 index 0000000000..1c4ec1f083 Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_6_2.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_7.png b/assets/images/DC_Lab_12.12._Create_Connect_7.png new file mode 100644 index 0000000000..e196b98db1 Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_7.png differ diff --git a/assets/images/DC_Lab_12.12._Create_Connect_8.png b/assets/images/DC_Lab_12.12._Create_Connect_8.png new file mode 100644 index 0000000000..35956b3027 Binary files /dev/null and b/assets/images/DC_Lab_12.12._Create_Connect_8.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_1.png b/assets/images/DC_Lab_12.13._Bulk_Engage_1.png new file mode 100644 index 0000000000..cfda6c1c3c Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_1.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_1_1.png b/assets/images/DC_Lab_12.13._Bulk_Engage_1_1.png new file mode 100644 index 0000000000..7b45827fd9 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_1_1.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_2.png b/assets/images/DC_Lab_12.13._Bulk_Engage_2.png new file mode 100644 index 0000000000..6a6f3f159e Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_2.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_3.png b/assets/images/DC_Lab_12.13._Bulk_Engage_3.png new file mode 100644 index 0000000000..23f87801ae Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_3.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_4.png b/assets/images/DC_Lab_12.13._Bulk_Engage_4.png new file mode 100644 index 0000000000..3375583840 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_4.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_5.png b/assets/images/DC_Lab_12.13._Bulk_Engage_5.png new file mode 100644 index 0000000000..bdccad6c41 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_5.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_6.png b/assets/images/DC_Lab_12.13._Bulk_Engage_6.png new file mode 100644 index 0000000000..1bf03ea159 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_6.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_7.png b/assets/images/DC_Lab_12.13._Bulk_Engage_7.png new file mode 100644 index 0000000000..49ae5ae81a Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_7.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_7_1.png b/assets/images/DC_Lab_12.13._Bulk_Engage_7_1.png new file mode 100644 index 0000000000..acbeaf3f9c Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_7_1.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_8.png b/assets/images/DC_Lab_12.13._Bulk_Engage_8.png new file mode 100644 index 0000000000..3a7d565e41 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_8.png differ diff --git a/assets/images/DC_Lab_12.13._Bulk_Engage_9.png b/assets/images/DC_Lab_12.13._Bulk_Engage_9.png new file mode 100644 index 0000000000..0e2b430783 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Bulk_Engage_9.png differ diff --git a/assets/images/DC_Lab_12.13._Create_Engage_1.png b/assets/images/DC_Lab_12.13._Create_Engage_1.png new file mode 100644 index 0000000000..b5340b4574 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Create_Engage_1.png differ diff --git a/assets/images/DC_Lab_12.13._Create_Engage_2.png b/assets/images/DC_Lab_12.13._Create_Engage_2.png new file mode 100644 index 0000000000..f466ce0247 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Create_Engage_2.png differ diff --git a/assets/images/DC_Lab_12.13._Create_Engage_3.png b/assets/images/DC_Lab_12.13._Create_Engage_3.png new file mode 100644 index 0000000000..0c44ea092c Binary files /dev/null and b/assets/images/DC_Lab_12.13._Create_Engage_3.png differ diff --git a/assets/images/DC_Lab_12.13._Create_Engage_4.png b/assets/images/DC_Lab_12.13._Create_Engage_4.png new file mode 100644 index 0000000000..e69e30d337 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Create_Engage_4.png differ diff --git a/assets/images/DC_Lab_12.13._Create_Engage_5.png b/assets/images/DC_Lab_12.13._Create_Engage_5.png new file mode 100644 index 0000000000..cbd5c0eb60 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Create_Engage_5.png differ diff --git a/assets/images/DC_Lab_12.13._Create_Engage_5_1.png b/assets/images/DC_Lab_12.13._Create_Engage_5_1.png new file mode 100644 index 0000000000..692bddbdb2 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Create_Engage_5_1.png differ diff --git a/assets/images/DC_Lab_12.13._Create_Engage_6.png b/assets/images/DC_Lab_12.13._Create_Engage_6.png new file mode 100644 index 0000000000..05b40a43aa Binary files /dev/null and b/assets/images/DC_Lab_12.13._Create_Engage_6.png differ diff --git a/assets/images/DC_Lab_12.13._Create_Engage_6_1.png b/assets/images/DC_Lab_12.13._Create_Engage_6_1.png new file mode 100644 index 0000000000..3647d4be0a Binary files /dev/null and b/assets/images/DC_Lab_12.13._Create_Engage_6_1.png differ diff --git a/assets/images/DC_Lab_12.13._Validate_1.png b/assets/images/DC_Lab_12.13._Validate_1.png new file mode 100644 index 0000000000..5badfb9ea8 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Validate_1.png differ diff --git a/assets/images/DC_Lab_12.13._Validate_2.png b/assets/images/DC_Lab_12.13._Validate_2.png new file mode 100644 index 0000000000..240401838d Binary files /dev/null and b/assets/images/DC_Lab_12.13._Validate_2.png differ diff --git a/assets/images/DC_Lab_12.13._Validate_3.png b/assets/images/DC_Lab_12.13._Validate_3.png new file mode 100644 index 0000000000..9dcbff3323 Binary files /dev/null and b/assets/images/DC_Lab_12.13._Validate_3.png differ diff --git a/assets/images/DC_Lab_12.19._Debugging_Flow_1.png b/assets/images/DC_Lab_12.19._Debugging_Flow_1.png new file mode 100644 index 0000000000..94ddf3e6f0 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Debugging_Flow_1.png differ diff --git a/assets/images/DC_Lab_12.19._Debugging_Flow_2.png b/assets/images/DC_Lab_12.19._Debugging_Flow_2.png new file mode 100644 index 0000000000..79ecf1a226 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Debugging_Flow_2.png differ diff --git a/assets/images/DC_Lab_12.19._Debugging_Flow_3.png b/assets/images/DC_Lab_12.19._Debugging_Flow_3.png new file mode 100644 index 0000000000..88c3454cdd Binary files /dev/null and b/assets/images/DC_Lab_12.19._Debugging_Flow_3.png differ diff --git a/assets/images/DC_Lab_12.19._Debugging_Flow_4.png b/assets/images/DC_Lab_12.19._Debugging_Flow_4.png new file mode 100644 index 0000000000..ac08c91c7d Binary files /dev/null and b/assets/images/DC_Lab_12.19._Debugging_Flow_4.png differ diff --git a/assets/images/DC_Lab_12.19._Debugging_Flow_5.png b/assets/images/DC_Lab_12.19._Debugging_Flow_5.png new file mode 100644 index 0000000000..58d945cfbf Binary files /dev/null and b/assets/images/DC_Lab_12.19._Debugging_Flow_5.png differ diff --git a/assets/images/DC_Lab_12.19._Debugging_Flow_6.png b/assets/images/DC_Lab_12.19._Debugging_Flow_6.png new file mode 100644 index 0000000000..57513b3fe8 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Debugging_Flow_6.png differ diff --git a/assets/images/DC_Lab_12.19._Debugging_Flow_7.png b/assets/images/DC_Lab_12.19._Debugging_Flow_7.png new file mode 100644 index 0000000000..12b5327d5c Binary files /dev/null and b/assets/images/DC_Lab_12.19._Debugging_Flow_7.png differ diff --git a/assets/images/DC_Lab_12.19._Debugging_Flow_8.png b/assets/images/DC_Lab_12.19._Debugging_Flow_8.png new file mode 100644 index 0000000000..1c139ffc42 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Debugging_Flow_8.png differ diff --git a/assets/images/DC_Lab_12.19._Error_Engage_Auth_1.png b/assets/images/DC_Lab_12.19._Error_Engage_Auth_1.png new file mode 100644 index 0000000000..cdde49b0eb Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_Engage_Auth_1.png differ diff --git a/assets/images/DC_Lab_12.19._Error_Engage_Auth_2.png b/assets/images/DC_Lab_12.19._Error_Engage_Auth_2.png new file mode 100644 index 0000000000..a138a68431 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_Engage_Auth_2.png differ diff --git a/assets/images/DC_Lab_12.19._Error_Engage_Auth_3.png b/assets/images/DC_Lab_12.19._Error_Engage_Auth_3.png new file mode 100644 index 0000000000..d5fa59797e Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_Engage_Auth_3.png differ diff --git a/assets/images/DC_Lab_12.19._Error_Engage_Auth_4.png b/assets/images/DC_Lab_12.19._Error_Engage_Auth_4.png new file mode 100644 index 0000000000..6325e12ef2 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_Engage_Auth_4.png differ diff --git a/assets/images/DC_Lab_12.19._Error_Engage_Auth_5.png b/assets/images/DC_Lab_12.19._Error_Engage_Auth_5.png new file mode 100644 index 0000000000..69b78d1034 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_Engage_Auth_5.png differ diff --git a/assets/images/DC_Lab_12.19._Error_No_EP_1.png b/assets/images/DC_Lab_12.19._Error_No_EP_1.png new file mode 100644 index 0000000000..76978837ee Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_No_EP_1.png differ diff --git a/assets/images/DC_Lab_12.19._Error_No_Value_1.png b/assets/images/DC_Lab_12.19._Error_No_Value_1.png new file mode 100644 index 0000000000..30c4b0025f Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_No_Value_1.png differ diff --git a/assets/images/DC_Lab_12.19._Error_No_Value_2.png b/assets/images/DC_Lab_12.19._Error_No_Value_2.png new file mode 100644 index 0000000000..4a88a9b944 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_No_Value_2.png differ diff --git a/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_1.png b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_1.png new file mode 100644 index 0000000000..9617f8e2ba Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_1.png differ diff --git a/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_2.png b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_2.png new file mode 100644 index 0000000000..847f8d9561 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_2.png differ diff --git a/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_3.png b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_3.png new file mode 100644 index 0000000000..e44f17e4af Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_3.png differ diff --git a/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_4.png b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_4.png new file mode 100644 index 0000000000..df88720a2b Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_4.png differ diff --git a/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_5.png b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_5.png new file mode 100644 index 0000000000..afe9df1354 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_WebexCC_Auth_5.png differ diff --git a/assets/images/DC_Lab_12.19._Error_Wrong_Value_1.png b/assets/images/DC_Lab_12.19._Error_Wrong_Value_1.png new file mode 100644 index 0000000000..a18e9063cc Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_Wrong_Value_1.png differ diff --git a/assets/images/DC_Lab_12.19._Error_Wrong_Value_2.png b/assets/images/DC_Lab_12.19._Error_Wrong_Value_2.png new file mode 100644 index 0000000000..f903dc62a0 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Error_Wrong_Value_2.png differ diff --git a/assets/images/DC_Lab_12.19._Export_Logs_1.png b/assets/images/DC_Lab_12.19._Export_Logs_1.png new file mode 100644 index 0000000000..ae920a7e52 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Export_Logs_1.png differ diff --git a/assets/images/DC_Lab_12.19._Export_Logs_2.png b/assets/images/DC_Lab_12.19._Export_Logs_2.png new file mode 100644 index 0000000000..7faf307955 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Export_Logs_2.png differ diff --git a/assets/images/DC_Lab_12.19._Export_Logs_3.png b/assets/images/DC_Lab_12.19._Export_Logs_3.png new file mode 100644 index 0000000000..5b38aac614 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Export_Logs_3.png differ diff --git a/assets/images/DC_Lab_12.19._Export_Logs_4.png b/assets/images/DC_Lab_12.19._Export_Logs_4.png new file mode 100644 index 0000000000..cca5123766 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Export_Logs_4.png differ diff --git a/assets/images/DC_Lab_12.19._Export_Logs_5.png b/assets/images/DC_Lab_12.19._Export_Logs_5.png new file mode 100644 index 0000000000..19e29f0752 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Export_Logs_5.png differ diff --git a/assets/images/DC_Lab_12.19._Flow_Debugger_1.png b/assets/images/DC_Lab_12.19._Flow_Debugger_1.png new file mode 100644 index 0000000000..bc462a6c6b Binary files /dev/null and b/assets/images/DC_Lab_12.19._Flow_Debugger_1.png differ diff --git a/assets/images/DC_Lab_12.19._Flow_Debugger_2.png b/assets/images/DC_Lab_12.19._Flow_Debugger_2.png new file mode 100644 index 0000000000..ce599882f2 Binary files /dev/null and b/assets/images/DC_Lab_12.19._Flow_Debugger_2.png differ diff --git a/assets/images/DC_Lab_12.19._Flow_Debugger_3.png b/assets/images/DC_Lab_12.19._Flow_Debugger_3.png new file mode 100644 index 0000000000..3731005d4a Binary files /dev/null and b/assets/images/DC_Lab_12.19._Flow_Debugger_3.png differ diff --git a/assets/images/DC_Lab_12.5_1.png b/assets/images/DC_Lab_12.5_1.png new file mode 100644 index 0000000000..dce5d84a3d Binary files /dev/null and b/assets/images/DC_Lab_12.5_1.png differ diff --git a/assets/images/DC_Lab_12.5_10.png b/assets/images/DC_Lab_12.5_10.png new file mode 100644 index 0000000000..7ed48704e8 Binary files /dev/null and b/assets/images/DC_Lab_12.5_10.png differ diff --git a/assets/images/DC_Lab_12.5_11.png b/assets/images/DC_Lab_12.5_11.png new file mode 100644 index 0000000000..abeedb247e Binary files /dev/null and b/assets/images/DC_Lab_12.5_11.png differ diff --git a/assets/images/DC_Lab_12.5_12.png b/assets/images/DC_Lab_12.5_12.png new file mode 100644 index 0000000000..31f9191bf6 Binary files /dev/null and b/assets/images/DC_Lab_12.5_12.png differ diff --git a/assets/images/DC_Lab_12.5_13.gif b/assets/images/DC_Lab_12.5_13.gif new file mode 100644 index 0000000000..13e95825aa Binary files /dev/null and b/assets/images/DC_Lab_12.5_13.gif differ diff --git a/assets/images/DC_Lab_12.5_14.png b/assets/images/DC_Lab_12.5_14.png new file mode 100644 index 0000000000..f41030cda0 Binary files /dev/null and b/assets/images/DC_Lab_12.5_14.png differ diff --git a/assets/images/DC_Lab_12.5_15.png b/assets/images/DC_Lab_12.5_15.png new file mode 100644 index 0000000000..f311248697 Binary files /dev/null and b/assets/images/DC_Lab_12.5_15.png differ diff --git a/assets/images/DC_Lab_12.5_16.png b/assets/images/DC_Lab_12.5_16.png new file mode 100644 index 0000000000..4089dd34d3 Binary files /dev/null and b/assets/images/DC_Lab_12.5_16.png differ diff --git a/assets/images/DC_Lab_12.5_17.png b/assets/images/DC_Lab_12.5_17.png new file mode 100644 index 0000000000..2c800749c1 Binary files /dev/null and b/assets/images/DC_Lab_12.5_17.png differ diff --git a/assets/images/DC_Lab_12.5_18.png b/assets/images/DC_Lab_12.5_18.png new file mode 100644 index 0000000000..e037acc35b Binary files /dev/null and b/assets/images/DC_Lab_12.5_18.png differ diff --git a/assets/images/DC_Lab_12.5_19.gif b/assets/images/DC_Lab_12.5_19.gif new file mode 100644 index 0000000000..e78dcc846a Binary files /dev/null and b/assets/images/DC_Lab_12.5_19.gif differ diff --git a/assets/images/DC_Lab_12.5_2.gif b/assets/images/DC_Lab_12.5_2.gif new file mode 100644 index 0000000000..0e1ae6f491 Binary files /dev/null and b/assets/images/DC_Lab_12.5_2.gif differ diff --git a/assets/images/DC_Lab_12.5_3.png b/assets/images/DC_Lab_12.5_3.png new file mode 100644 index 0000000000..ec5d2f5b3b Binary files /dev/null and b/assets/images/DC_Lab_12.5_3.png differ diff --git a/assets/images/DC_Lab_12.5_4.png b/assets/images/DC_Lab_12.5_4.png new file mode 100644 index 0000000000..517f364010 Binary files /dev/null and b/assets/images/DC_Lab_12.5_4.png differ diff --git a/assets/images/DC_Lab_12.5_5.gif b/assets/images/DC_Lab_12.5_5.gif new file mode 100644 index 0000000000..f2e8324141 Binary files /dev/null and b/assets/images/DC_Lab_12.5_5.gif differ diff --git a/assets/images/DC_Lab_12.5_6.png b/assets/images/DC_Lab_12.5_6.png new file mode 100644 index 0000000000..70d05a579c Binary files /dev/null and b/assets/images/DC_Lab_12.5_6.png differ diff --git a/assets/images/DC_Lab_12.5_7.png b/assets/images/DC_Lab_12.5_7.png new file mode 100644 index 0000000000..487b52e281 Binary files /dev/null and b/assets/images/DC_Lab_12.5_7.png differ diff --git a/assets/images/DC_Lab_12.5_8.gif b/assets/images/DC_Lab_12.5_8.gif new file mode 100644 index 0000000000..f6c214cd59 Binary files /dev/null and b/assets/images/DC_Lab_12.5_8.gif differ diff --git a/assets/images/DC_Lab_12.5_9.gif b/assets/images/DC_Lab_12.5_9.gif new file mode 100644 index 0000000000..8cbbdbb0d1 Binary files /dev/null and b/assets/images/DC_Lab_12.5_9.gif differ diff --git a/assets/images/DC_Lab_12.8._Create_Asset_1.png b/assets/images/DC_Lab_12.8._Create_Asset_1.png new file mode 100644 index 0000000000..cdbfa9b23d Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Asset_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Asset_2.png b/assets/images/DC_Lab_12.8._Create_Asset_2.png new file mode 100644 index 0000000000..647c670c1b Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Asset_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Asset_3.png b/assets/images/DC_Lab_12.8._Create_Asset_3.png new file mode 100644 index 0000000000..fa6facdae4 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Asset_3.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Asset_4.png b/assets/images/DC_Lab_12.8._Create_Asset_4.png new file mode 100644 index 0000000000..f9cdec7653 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Asset_4.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Asset_5.png b/assets/images/DC_Lab_12.8._Create_Asset_5.png new file mode 100644 index 0000000000..5697c5e0d5 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Asset_5.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Closed_Flow_1.png b/assets/images/DC_Lab_12.8._Create_Closed_Flow_1.png new file mode 100644 index 0000000000..16829d78da Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Closed_Flow_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Closed_Flow_2.png b/assets/images/DC_Lab_12.8._Create_Closed_Flow_2.png new file mode 100644 index 0000000000..1bc78913cf Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Closed_Flow_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Closed_Flow_3.png b/assets/images/DC_Lab_12.8._Create_Closed_Flow_3.png new file mode 100644 index 0000000000..0ba9acd17a Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Closed_Flow_3.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Entry_Point_1.png b/assets/images/DC_Lab_12.8._Create_Entry_Point_1.png new file mode 100644 index 0000000000..854c09378f Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Entry_Point_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Entry_Point_2.png b/assets/images/DC_Lab_12.8._Create_Entry_Point_2.png new file mode 100644 index 0000000000..91c4f51b1c Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Entry_Point_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_1.png b/assets/images/DC_Lab_12.8._Create_Flow_1.png new file mode 100644 index 0000000000..d6ec6ed78f Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_2.png b/assets/images/DC_Lab_12.8._Create_Flow_2.png new file mode 100644 index 0000000000..c5b77b7a31 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_3.png b/assets/images/DC_Lab_12.8._Create_Flow_3.png new file mode 100644 index 0000000000..332224e827 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_3.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_3_1.png b/assets/images/DC_Lab_12.8._Create_Flow_3_1.png new file mode 100644 index 0000000000..dfc8454ace Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_3_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_4.png b/assets/images/DC_Lab_12.8._Create_Flow_4.png new file mode 100644 index 0000000000..c88109d06c Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_4.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_4_1.png b/assets/images/DC_Lab_12.8._Create_Flow_4_1.png new file mode 100644 index 0000000000..4ab4e289d2 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_4_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_5.png b/assets/images/DC_Lab_12.8._Create_Flow_5.png new file mode 100644 index 0000000000..5cbb3c6238 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_5.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_5_1.png b/assets/images/DC_Lab_12.8._Create_Flow_5_1.png new file mode 100644 index 0000000000..3191a289de Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_5_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_6.png b/assets/images/DC_Lab_12.8._Create_Flow_6.png new file mode 100644 index 0000000000..e909239228 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_6.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_6_1.png b/assets/images/DC_Lab_12.8._Create_Flow_6_1.png new file mode 100644 index 0000000000..479e58ad7d Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_6_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_6_2.png b/assets/images/DC_Lab_12.8._Create_Flow_6_2.png new file mode 100644 index 0000000000..a5444c7a51 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_6_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_7.png b/assets/images/DC_Lab_12.8._Create_Flow_7.png new file mode 100644 index 0000000000..979954de51 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_7.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_7_1.png b/assets/images/DC_Lab_12.8._Create_Flow_7_1.png new file mode 100644 index 0000000000..60eb9e0fce Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_7_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_8.png b/assets/images/DC_Lab_12.8._Create_Flow_8.png new file mode 100644 index 0000000000..382d54c46e Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_8.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_8_1.png b/assets/images/DC_Lab_12.8._Create_Flow_8_1.png new file mode 100644 index 0000000000..1398f69d75 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_8_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_8_2.png b/assets/images/DC_Lab_12.8._Create_Flow_8_2.png new file mode 100644 index 0000000000..265d7ac080 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_8_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_9.png b/assets/images/DC_Lab_12.8._Create_Flow_9.png new file mode 100644 index 0000000000..c2be5cc43d Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_9.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Flow_9_1.png b/assets/images/DC_Lab_12.8._Create_Flow_9_1.png new file mode 100644 index 0000000000..e51a6b1924 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Flow_9_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Queue_1.png b/assets/images/DC_Lab_12.8._Create_Queue_1.png new file mode 100644 index 0000000000..b91ee5bb84 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Queue_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Queue_2.png b/assets/images/DC_Lab_12.8._Create_Queue_2.png new file mode 100644 index 0000000000..9c5bd0e417 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Queue_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Queue_3.png b/assets/images/DC_Lab_12.8._Create_Queue_3.png new file mode 100644 index 0000000000..2885bfc5c6 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Queue_3.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Service.png b/assets/images/DC_Lab_12.8._Create_Service.png new file mode 100644 index 0000000000..69fc44e993 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Service.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Template_1.png b/assets/images/DC_Lab_12.8._Create_Template_1.png new file mode 100644 index 0000000000..c5b1be3921 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Template_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Template_2.png b/assets/images/DC_Lab_12.8._Create_Template_2.png new file mode 100644 index 0000000000..0758b2649f Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Template_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Template_3.png b/assets/images/DC_Lab_12.8._Create_Template_3.png new file mode 100644 index 0000000000..4787d3e0f5 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Template_3.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Template_4.png b/assets/images/DC_Lab_12.8._Create_Template_4.png new file mode 100644 index 0000000000..f0d8f5ac45 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Template_4.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Template_5.png b/assets/images/DC_Lab_12.8._Create_Template_5.png new file mode 100644 index 0000000000..6f3677a43a Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Template_5.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_1.png b/assets/images/DC_Lab_12.8._Create_Website_1.png new file mode 100644 index 0000000000..f1d25228e7 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_1.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_10.png b/assets/images/DC_Lab_12.8._Create_Website_10.png new file mode 100644 index 0000000000..ada21fc66b Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_10.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_11.png b/assets/images/DC_Lab_12.8._Create_Website_11.png new file mode 100644 index 0000000000..30983989a3 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_11.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_2.png b/assets/images/DC_Lab_12.8._Create_Website_2.png new file mode 100644 index 0000000000..c7344ce225 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_2.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_3.png b/assets/images/DC_Lab_12.8._Create_Website_3.png new file mode 100644 index 0000000000..7e0f5f7097 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_3.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_4.png b/assets/images/DC_Lab_12.8._Create_Website_4.png new file mode 100644 index 0000000000..0ebd5d7a00 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_4.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_5.png b/assets/images/DC_Lab_12.8._Create_Website_5.png new file mode 100644 index 0000000000..82b0c4625a Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_5.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_6.png b/assets/images/DC_Lab_12.8._Create_Website_6.png new file mode 100644 index 0000000000..4bd82f5b40 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_6.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_7.png b/assets/images/DC_Lab_12.8._Create_Website_7.png new file mode 100644 index 0000000000..664871ace2 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_7.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_8.png b/assets/images/DC_Lab_12.8._Create_Website_8.png new file mode 100644 index 0000000000..a06d05d834 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_8.png differ diff --git a/assets/images/DC_Lab_12.8._Create_Website_9.png b/assets/images/DC_Lab_12.8._Create_Website_9.png new file mode 100644 index 0000000000..2175a11d6b Binary files /dev/null and b/assets/images/DC_Lab_12.8._Create_Website_9.png differ diff --git a/assets/images/DC_Lab_12.8._Publish_Widget_1.png b/assets/images/DC_Lab_12.8._Publish_Widget_1.png new file mode 100644 index 0000000000..18110537f8 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Publish_Widget_1.png differ diff --git a/assets/images/DC_Lab_12.8._Verify_1.png b/assets/images/DC_Lab_12.8._Verify_1.png new file mode 100644 index 0000000000..6c0b3afce2 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Verify_1.png differ diff --git a/assets/images/DC_Lab_12.8._Verify_1.png.md b/assets/images/DC_Lab_12.8._Verify_1.png.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/images/DC_Lab_12.8._Verify_2.png b/assets/images/DC_Lab_12.8._Verify_2.png new file mode 100644 index 0000000000..c7f7fe5033 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Verify_2.png differ diff --git a/assets/images/DC_Lab_12.8._Verify_3.png b/assets/images/DC_Lab_12.8._Verify_3.png new file mode 100644 index 0000000000..7110e7b8c8 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Verify_3.png differ diff --git a/assets/images/DC_Lab_12.8._Verify_4.png b/assets/images/DC_Lab_12.8._Verify_4.png new file mode 100644 index 0000000000..e301550564 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Verify_4.png differ diff --git a/assets/images/DC_Lab_12.8._Verify_5.png b/assets/images/DC_Lab_12.8._Verify_5.png new file mode 100644 index 0000000000..c728e261e0 Binary files /dev/null and b/assets/images/DC_Lab_12.8._Verify_5.png differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow1.jpg b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow1.jpg new file mode 100644 index 0000000000..63a6f33347 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow1.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow2.jpg b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow2.jpg new file mode 100644 index 0000000000..0ce4762b1a Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow2.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow3.jpg b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow3.jpg new file mode 100644 index 0000000000..585e0710bb Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow3.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow4.jpg b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow4.jpg new file mode 100644 index 0000000000..59032937b3 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow4.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow5.jpg b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow5.jpg new file mode 100644 index 0000000000..2e8055910f Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow5.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow6.jpg b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow6.jpg new file mode 100644 index 0000000000..b5cd974760 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow6.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow7.jpg b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow7.jpg new file mode 100644 index 0000000000..f604c1de18 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow7.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow8.jpg b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow8.jpg new file mode 100644 index 0000000000..741a7c8b4f Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flow8.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flowID.png b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flowID.png new file mode 100644 index 0000000000..2310926c61 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create-Upload_Facebook_Messenger_flowID.png differ diff --git a/assets/images/DC_Lab_12.9_Create_Entry_Point_and_Queue1.jpg b/assets/images/DC_Lab_12.9_Create_Entry_Point_and_Queue1.jpg new file mode 100644 index 0000000000..24b3e8c7ae Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create_Entry_Point_and_Queue1.jpg differ diff --git a/assets/images/DC_Lab_12.9_Create_Entry_Point_and_Queue2.jpg b/assets/images/DC_Lab_12.9_Create_Entry_Point_and_Queue2.jpg new file mode 100644 index 0000000000..0e74a19685 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Create_Entry_Point_and_Queue2.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC1.gif b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC1.gif new file mode 100644 index 0000000000..9a50a3bd75 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC1.gif differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC10.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC10.jpg new file mode 100644 index 0000000000..2dcf3bcb80 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC10.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC2.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC2.jpg new file mode 100644 index 0000000000..006689ee07 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC2.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC3.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC3.jpg new file mode 100644 index 0000000000..b319b6aef5 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC3.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC4.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC4.jpg new file mode 100644 index 0000000000..aee7783e43 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC4.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC5.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC5.jpg new file mode 100644 index 0000000000..79bca2ff1b Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC5.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC6.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC6.jpg new file mode 100644 index 0000000000..e8dc055322 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC6.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC7.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC7.jpg new file mode 100644 index 0000000000..b16e01eb86 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC7.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC8.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC8.jpg new file mode 100644 index 0000000000..b456aba04b Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC8.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC9.jpg b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC9.jpg new file mode 100644 index 0000000000..2f4e194fb2 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Messenger_Asset_creation_&_register_to_Webex_CC9.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Page_configuration1.jpg b/assets/images/DC_Lab_12.9_Facebook_Page_configuration1.jpg new file mode 100644 index 0000000000..b02b538644 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Page_configuration1.jpg differ diff --git a/assets/images/DC_Lab_12.9_Facebook_Page_configuration2.jpg b/assets/images/DC_Lab_12.9_Facebook_Page_configuration2.jpg new file mode 100644 index 0000000000..6a5f8ae56d Binary files /dev/null and b/assets/images/DC_Lab_12.9_Facebook_Page_configuration2.jpg differ diff --git a/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request1.png b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request1.png new file mode 100644 index 0000000000..4ee4bbb511 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request1.png differ diff --git a/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request2.jpg b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request2.jpg new file mode 100644 index 0000000000..fa127f9e9d Binary files /dev/null and b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request2.jpg differ diff --git a/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request3.jpg b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request3.jpg new file mode 100644 index 0000000000..d8d06002c8 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request3.jpg differ diff --git a/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request4.jpg b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request4.jpg new file mode 100644 index 0000000000..d5078519f5 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request4.jpg differ diff --git a/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request5.jpg b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request5.jpg new file mode 100644 index 0000000000..cdbc9ae455 Binary files /dev/null and b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request5.jpg differ diff --git a/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request6.jpg b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request6.jpg new file mode 100644 index 0000000000..3b019b473f Binary files /dev/null and b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request6.jpg differ diff --git a/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request7.jpg b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request7.jpg new file mode 100644 index 0000000000..8486ab2f2d Binary files /dev/null and b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request7.jpg differ diff --git a/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request8.jpg b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request8.jpg new file mode 100644 index 0000000000..da74b98e1c Binary files /dev/null and b/assets/images/DC_Lab_12.9_Verification_-_start_Facebook_Chat_and_accept_the_request8.jpg differ diff --git a/assets/images/DC_Lab_4_Supervisor_Config_1.png b/assets/images/DC_Lab_4_Supervisor_Config_1.png new file mode 100644 index 0000000000..3036507035 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_Config_1.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_Config_2.png b/assets/images/DC_Lab_4_Supervisor_Config_2.png new file mode 100644 index 0000000000..4c2f7b72f8 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_Config_2.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_Config_3.png b/assets/images/DC_Lab_4_Supervisor_Config_3.png new file mode 100644 index 0000000000..4d57a6dd5b Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_Config_3.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_Config_4.png b/assets/images/DC_Lab_4_Supervisor_Config_4.png new file mode 100644 index 0000000000..b28251feb4 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_Config_4.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_Config_5.png b/assets/images/DC_Lab_4_Supervisor_Config_5.png new file mode 100644 index 0000000000..e3ad62a6f5 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_Config_5.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_Config_6.png b/assets/images/DC_Lab_4_Supervisor_Config_6.png new file mode 100644 index 0000000000..62f5881e79 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_Config_6.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_1.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_1.png new file mode 100644 index 0000000000..667e10591b Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_1.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_10.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_10.png new file mode 100644 index 0000000000..ef872a2582 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_10.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_11.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_11.png new file mode 100644 index 0000000000..bde2a30fce Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_11.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_2.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_2.png new file mode 100644 index 0000000000..afd260d33f Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_2.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_3.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_3.png new file mode 100644 index 0000000000..728b4a4f92 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_3.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_4.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_4.png new file mode 100644 index 0000000000..41fb012ae6 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_4.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_5.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_5.png new file mode 100644 index 0000000000..b4328887da Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_5.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_6.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_6.png new file mode 100644 index 0000000000..82d8636504 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_6.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_7.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_7.png new file mode 100644 index 0000000000..52fdb9a508 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_7.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_8.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_8.png new file mode 100644 index 0000000000..39a83c9bdc Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_8.png differ diff --git a/assets/images/DC_Lab_4_Supervisor_WebexCC_9.png b/assets/images/DC_Lab_4_Supervisor_WebexCC_9.png new file mode 100644 index 0000000000..862f16b2f7 Binary files /dev/null and b/assets/images/DC_Lab_4_Supervisor_WebexCC_9.png differ diff --git a/assets/images/DC_Login.png b/assets/images/DC_Login.png new file mode 100644 index 0000000000..4386e85484 Binary files /dev/null and b/assets/images/DC_Login.png differ diff --git a/assets/images/DC_Provisioned1.png b/assets/images/DC_Provisioned1.png new file mode 100644 index 0000000000..d8e12dffe1 Binary files /dev/null and b/assets/images/DC_Provisioned1.png differ diff --git a/assets/images/DC_Provisioned2.png b/assets/images/DC_Provisioned2.png new file mode 100644 index 0000000000..68a2de0b70 Binary files /dev/null and b/assets/images/DC_Provisioned2.png differ diff --git a/assets/images/DC_Provisioned3.png b/assets/images/DC_Provisioned3.png new file mode 100644 index 0000000000..e1e6b7c300 Binary files /dev/null and b/assets/images/DC_Provisioned3.png differ diff --git a/assets/images/DC_Provisioning1.png b/assets/images/DC_Provisioning1.png new file mode 100644 index 0000000000..e6661d4545 Binary files /dev/null and b/assets/images/DC_Provisioning1.png differ diff --git a/assets/images/DC_Provisioning2.png b/assets/images/DC_Provisioning2.png new file mode 100644 index 0000000000..e3306ca93b Binary files /dev/null and b/assets/images/DC_Provisioning2.png differ diff --git a/assets/images/DC_Provisioning3.png b/assets/images/DC_Provisioning3.png new file mode 100644 index 0000000000..3b67c03808 Binary files /dev/null and b/assets/images/DC_Provisioning3.png differ diff --git a/assets/images/DC_UserActivation.png b/assets/images/DC_UserActivation.png new file mode 100644 index 0000000000..7e1e29f812 Binary files /dev/null and b/assets/images/DC_UserActivation.png differ diff --git a/assets/images/DebugConsole3.png b/assets/images/DebugConsole3.png new file mode 100644 index 0000000000..e39991d14a Binary files /dev/null and b/assets/images/DebugConsole3.png differ diff --git a/assets/images/EM/NPSReporting.gif b/assets/images/EM/NPSReporting.gif new file mode 100644 index 0000000000..07c89fa578 Binary files /dev/null and b/assets/images/EM/NPSReporting.gif differ diff --git a/assets/images/EM/addNPS.gif b/assets/images/EM/addNPS.gif new file mode 100644 index 0000000000..876950a4e0 Binary files /dev/null and b/assets/images/EM/addNPS.gif differ diff --git a/assets/images/EM/contactCenter.gif b/assets/images/EM/contactCenter.gif new file mode 100644 index 0000000000..5a44ea286e Binary files /dev/null and b/assets/images/EM/contactCenter.gif differ diff --git a/assets/images/EM/downloadDate.gif b/assets/images/EM/downloadDate.gif new file mode 100644 index 0000000000..fc47b1bebb Binary files /dev/null and b/assets/images/EM/downloadDate.gif differ diff --git a/assets/images/EM/downloadResponse.gif b/assets/images/EM/downloadResponse.gif new file mode 100644 index 0000000000..6fbc7822c3 Binary files /dev/null and b/assets/images/EM/downloadResponse.gif differ diff --git a/assets/images/EM/feedbackV2.png b/assets/images/EM/feedbackV2.png new file mode 100644 index 0000000000..75c916a185 Binary files /dev/null and b/assets/images/EM/feedbackV2.png differ diff --git a/assets/images/EM/languageSupport.png b/assets/images/EM/languageSupport.png new file mode 100644 index 0000000000..4ed428363d Binary files /dev/null and b/assets/images/EM/languageSupport.png differ diff --git a/assets/images/EM/survey.gif b/assets/images/EM/survey.gif new file mode 100644 index 0000000000..cbf1e5ea77 Binary files /dev/null and b/assets/images/EM/survey.gif differ diff --git a/assets/images/EM/surveyName.gif b/assets/images/EM/surveyName.gif new file mode 100644 index 0000000000..180691b313 Binary files /dev/null and b/assets/images/EM/surveyName.gif differ diff --git a/assets/images/EM/surveyOptin.png b/assets/images/EM/surveyOptin.png new file mode 100644 index 0000000000..b8a2f5152a Binary files /dev/null and b/assets/images/EM/surveyOptin.png differ diff --git a/assets/images/EM/surveyReport.png b/assets/images/EM/surveyReport.png new file mode 100644 index 0000000000..d2ac0ac7de Binary files /dev/null and b/assets/images/EM/surveyReport.png differ diff --git a/assets/images/EM/surveyType.gif b/assets/images/EM/surveyType.gif new file mode 100644 index 0000000000..4993600555 Binary files /dev/null and b/assets/images/EM/surveyType.gif differ diff --git a/assets/images/EM/uploadNPS.gif b/assets/images/EM/uploadNPS.gif new file mode 100644 index 0000000000..649daba3c7 Binary files /dev/null and b/assets/images/EM/uploadNPS.gif differ diff --git a/assets/images/EM/uploadWelcome.gif b/assets/images/EM/uploadWelcome.gif new file mode 100644 index 0000000000..5db0d3b444 Binary files /dev/null and b/assets/images/EM/uploadWelcome.gif differ diff --git a/assets/images/EM/welcomeThankyou.gif b/assets/images/EM/welcomeThankyou.gif new file mode 100644 index 0000000000..e1053c4344 Binary files /dev/null and b/assets/images/EM/welcomeThankyou.gif differ diff --git a/assets/images/IVR/altMessages.JPG b/assets/images/IVR/altMessages.JPG new file mode 100644 index 0000000000..0ac2b85bc8 Binary files /dev/null and b/assets/images/IVR/altMessages.JPG differ diff --git a/assets/images/IVR/aniRead.JPG b/assets/images/IVR/aniRead.JPG new file mode 100644 index 0000000000..35f81b01d7 Binary files /dev/null and b/assets/images/IVR/aniRead.JPG differ diff --git a/assets/images/IVR/changeNumber.JPG b/assets/images/IVR/changeNumber.JPG new file mode 100644 index 0000000000..e92705d1d1 Binary files /dev/null and b/assets/images/IVR/changeNumber.JPG differ diff --git a/assets/images/IVR/collectExt.JPG b/assets/images/IVR/collectExt.JPG new file mode 100644 index 0000000000..3d9bb0efa5 Binary files /dev/null and b/assets/images/IVR/collectExt.JPG differ diff --git a/assets/images/IVR/comfortMessage.JPG b/assets/images/IVR/comfortMessage.JPG new file mode 100644 index 0000000000..23df000a90 Binary files /dev/null and b/assets/images/IVR/comfortMessage.JPG differ diff --git a/assets/images/IVR/flowCog.JPG b/assets/images/IVR/flowCog.JPG new file mode 100644 index 0000000000..3918b5ee0b Binary files /dev/null and b/assets/images/IVR/flowCog.JPG differ diff --git a/assets/images/IVR/openEP.gif b/assets/images/IVR/openEP.gif new file mode 100644 index 0000000000..23dbbe1133 Binary files /dev/null and b/assets/images/IVR/openEP.gif differ diff --git a/assets/images/IVR/openEPmap.gif b/assets/images/IVR/openEPmap.gif new file mode 100644 index 0000000000..7a8f5abb16 Binary files /dev/null and b/assets/images/IVR/openEPmap.gif differ diff --git a/assets/images/IVR/openFlow.JPG b/assets/images/IVR/openFlow.JPG new file mode 100644 index 0000000000..eb38eccb90 Binary files /dev/null and b/assets/images/IVR/openFlow.JPG differ diff --git a/assets/images/IVR/openQueue.gif b/assets/images/IVR/openQueue.gif new file mode 100644 index 0000000000..4791f2f500 Binary files /dev/null and b/assets/images/IVR/openQueue.gif differ diff --git a/assets/images/IVR/openQueue.jpg b/assets/images/IVR/openQueue.jpg new file mode 100644 index 0000000000..4791f2f500 Binary files /dev/null and b/assets/images/IVR/openQueue.jpg differ diff --git a/assets/images/IVR/openQueueNew.gif b/assets/images/IVR/openQueueNew.gif new file mode 100644 index 0000000000..552b52d4c7 Binary files /dev/null and b/assets/images/IVR/openQueueNew.gif differ diff --git a/assets/images/IVR/routingStrategy.JPG b/assets/images/IVR/routingStrategy.JPG new file mode 100644 index 0000000000..901567fcee Binary files /dev/null and b/assets/images/IVR/routingStrategy.JPG differ diff --git a/assets/images/IVR/rsToFlow.gif b/assets/images/IVR/rsToFlow.gif new file mode 100644 index 0000000000..7ea679ba75 Binary files /dev/null and b/assets/images/IVR/rsToFlow.gif differ diff --git a/assets/images/IVR/saveJson.gif b/assets/images/IVR/saveJson.gif new file mode 100644 index 0000000000..4ab698a47e Binary files /dev/null and b/assets/images/IVR/saveJson.gif differ diff --git a/assets/images/IVR/saveJsonChrome.gif b/assets/images/IVR/saveJsonChrome.gif new file mode 100644 index 0000000000..9562f0ae04 Binary files /dev/null and b/assets/images/IVR/saveJsonChrome.gif differ diff --git a/assets/images/IVR/saveJsonChromeMac.gif b/assets/images/IVR/saveJsonChromeMac.gif new file mode 100644 index 0000000000..ffd6c2d66d Binary files /dev/null and b/assets/images/IVR/saveJsonChromeMac.gif differ diff --git a/assets/images/JDS/JDSDownloadRaw.png b/assets/images/JDS/JDSDownloadRaw.png new file mode 100644 index 0000000000..f8ff59a4ec Binary files /dev/null and b/assets/images/JDS/JDSDownloadRaw.png differ diff --git a/assets/images/JDS/JDSImport.png b/assets/images/JDS/JDSImport.png new file mode 100644 index 0000000000..f09d3bfa0a Binary files /dev/null and b/assets/images/JDS/JDSImport.png differ diff --git a/assets/images/JDS/JDSSave.png b/assets/images/JDS/JDSSave.png new file mode 100644 index 0000000000..de16a980a4 Binary files /dev/null and b/assets/images/JDS/JDSSave.png differ diff --git a/assets/images/JDS/JDS_Desktop_Layout_JSON.png b/assets/images/JDS/JDS_Desktop_Layout_JSON.png new file mode 100644 index 0000000000..27f7b4761f Binary files /dev/null and b/assets/images/JDS/JDS_Desktop_Layout_JSON.png differ diff --git a/assets/images/JDS/JDS_Dev_Portal.png b/assets/images/JDS/JDS_Dev_Portal.png new file mode 100644 index 0000000000..45c74aed06 Binary files /dev/null and b/assets/images/JDS/JDS_Dev_Portal.png differ diff --git a/assets/images/JDS/JDS_Widget_Code.png b/assets/images/JDS/JDS_Widget_Code.png new file mode 100644 index 0000000000..1cc46a76c4 Binary files /dev/null and b/assets/images/JDS/JDS_Widget_Code.png differ diff --git a/assets/images/JDS/JDS_Widget_Desktop.png b/assets/images/JDS/JDS_Widget_Desktop.png new file mode 100644 index 0000000000..d0ffcca06d Binary files /dev/null and b/assets/images/JDS/JDS_Widget_Desktop.png differ diff --git a/assets/images/JDS/authJDS.gif b/assets/images/JDS/authJDS.gif new file mode 100644 index 0000000000..45a410565f Binary files /dev/null and b/assets/images/JDS/authJDS.gif differ diff --git a/assets/images/JDS/jds_activate_project.png b/assets/images/JDS/jds_activate_project.png new file mode 100644 index 0000000000..becd16060c Binary files /dev/null and b/assets/images/JDS/jds_activate_project.png differ diff --git a/assets/images/JDS/jds_add_identities.png b/assets/images/JDS/jds_add_identities.png new file mode 100644 index 0000000000..297b84b139 Binary files /dev/null and b/assets/images/JDS/jds_add_identities.png differ diff --git a/assets/images/JDS/jds_ch_tab.png b/assets/images/JDS/jds_ch_tab.png new file mode 100644 index 0000000000..df39ad242a Binary files /dev/null and b/assets/images/JDS/jds_ch_tab.png differ diff --git a/assets/images/JDS/jds_created_csv.png b/assets/images/JDS/jds_created_csv.png new file mode 100644 index 0000000000..18e40ab6b0 Binary files /dev/null and b/assets/images/JDS/jds_created_csv.png differ diff --git a/assets/images/JDS/upload_csv_jds.png b/assets/images/JDS/upload_csv_jds.png new file mode 100644 index 0000000000..a94569604e Binary files /dev/null and b/assets/images/JDS/upload_csv_jds.png differ diff --git a/assets/images/LAB2_email/OneTransaction.png.md b/assets/images/LAB2_email/OneTransaction.png.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/images/Lab1-AD-1.png b/assets/images/Lab1-AD-1.png new file mode 100644 index 0000000000..000cdff989 Binary files /dev/null and b/assets/images/Lab1-AD-1.png differ diff --git a/assets/images/Lab12.20_CustomNodeAddIntegrations.png b/assets/images/Lab12.20_CustomNodeAddIntegrations.png new file mode 100644 index 0000000000..4b258c7b2c Binary files /dev/null and b/assets/images/Lab12.20_CustomNodeAddIntegrations.png differ diff --git a/assets/images/Lab12.20_CustomNodeCreateNew.png b/assets/images/Lab12.20_CustomNodeCreateNew.png new file mode 100644 index 0000000000..ee6683bd4c Binary files /dev/null and b/assets/images/Lab12.20_CustomNodeCreateNew.png differ diff --git a/assets/images/Lab12.20_CustomNodeDemo.png b/assets/images/Lab12.20_CustomNodeDemo.png new file mode 100644 index 0000000000..c5896ec49b Binary files /dev/null and b/assets/images/Lab12.20_CustomNodeDemo.png differ diff --git a/assets/images/Lab12.20_CustomNodeIntegrations.png b/assets/images/Lab12.20_CustomNodeIntegrations.png new file mode 100644 index 0000000000..aef6484448 Binary files /dev/null and b/assets/images/Lab12.20_CustomNodeIntegrations.png differ diff --git a/assets/images/Lab12.24.1_GVFirst.png b/assets/images/Lab12.24.1_GVFirst.png new file mode 100644 index 0000000000..c6e17645da Binary files /dev/null and b/assets/images/Lab12.24.1_GVFirst.png differ diff --git a/assets/images/Lab12.24.1_GVSecond.png b/assets/images/Lab12.24.1_GVSecond.png new file mode 100644 index 0000000000..15263cfe5b Binary files /dev/null and b/assets/images/Lab12.24.1_GVSecond.png differ diff --git a/assets/images/Lab12.24.1_GVThird.png b/assets/images/Lab12.24.1_GVThird.png new file mode 100644 index 0000000000..55c0036404 Binary files /dev/null and b/assets/images/Lab12.24.1_GVThird.png differ diff --git a/assets/images/Lab12.24.3_TxAftBetweenFirstSecond.png b/assets/images/Lab12.24.3_TxAftBetweenFirstSecond.png new file mode 100644 index 0000000000..4349120f83 Binary files /dev/null and b/assets/images/Lab12.24.3_TxAftBetweenFirstSecond.png differ diff --git a/assets/images/Lab12.24.3_TxBetweenFirstSecond.png b/assets/images/Lab12.24.3_TxBetweenFirstSecond.png new file mode 100644 index 0000000000..ee083e250d Binary files /dev/null and b/assets/images/Lab12.24.3_TxBetweenFirstSecond.png differ diff --git a/assets/images/Lab12.24.3_TxFirst.png b/assets/images/Lab12.24.3_TxFirst.png new file mode 100644 index 0000000000..3a10b4873a Binary files /dev/null and b/assets/images/Lab12.24.3_TxFirst.png differ diff --git a/assets/images/Lab12.24.3_TxLast.png b/assets/images/Lab12.24.3_TxLast.png new file mode 100644 index 0000000000..6810155bee Binary files /dev/null and b/assets/images/Lab12.24.3_TxLast.png differ diff --git a/assets/images/Lab12.24.3_TxSecond.png b/assets/images/Lab12.24.3_TxSecond.png new file mode 100644 index 0000000000..29cfb8eec3 Binary files /dev/null and b/assets/images/Lab12.24.3_TxSecond.png differ diff --git a/assets/images/Lab12.24.3_TxThird.png b/assets/images/Lab12.24.3_TxThird.png new file mode 100644 index 0000000000..c6cfac98e3 Binary files /dev/null and b/assets/images/Lab12.24.3_TxThird.png differ diff --git a/assets/images/Lab4_ESD_1.png b/assets/images/Lab4_ESD_1.png new file mode 100644 index 0000000000..13b0a4293e Binary files /dev/null and b/assets/images/Lab4_ESD_1.png differ diff --git a/assets/images/Lab4_ESD_10_monitor.png b/assets/images/Lab4_ESD_10_monitor.png new file mode 100644 index 0000000000..88adeca987 Binary files /dev/null and b/assets/images/Lab4_ESD_10_monitor.png differ diff --git a/assets/images/Lab4_ESD_11.png b/assets/images/Lab4_ESD_11.png new file mode 100644 index 0000000000..cc8b6156ba Binary files /dev/null and b/assets/images/Lab4_ESD_11.png differ diff --git a/assets/images/Lab4_ESD_11_monitor.png b/assets/images/Lab4_ESD_11_monitor.png new file mode 100644 index 0000000000..5d94693e31 Binary files /dev/null and b/assets/images/Lab4_ESD_11_monitor.png differ diff --git a/assets/images/Lab4_ESD_12_monitor.png b/assets/images/Lab4_ESD_12_monitor.png new file mode 100644 index 0000000000..3ec70001a9 Binary files /dev/null and b/assets/images/Lab4_ESD_12_monitor.png differ diff --git a/assets/images/Lab4_ESD_13_monitor.png b/assets/images/Lab4_ESD_13_monitor.png new file mode 100644 index 0000000000..31ac59636c Binary files /dev/null and b/assets/images/Lab4_ESD_13_monitor.png differ diff --git a/assets/images/Lab4_ESD_14_monitor.png b/assets/images/Lab4_ESD_14_monitor.png new file mode 100644 index 0000000000..9adc6f261a Binary files /dev/null and b/assets/images/Lab4_ESD_14_monitor.png differ diff --git a/assets/images/Lab4_ESD_15_monitor.png b/assets/images/Lab4_ESD_15_monitor.png new file mode 100644 index 0000000000..8aa271da5b Binary files /dev/null and b/assets/images/Lab4_ESD_15_monitor.png differ diff --git a/assets/images/Lab4_ESD_16_monitor.png b/assets/images/Lab4_ESD_16_monitor.png new file mode 100644 index 0000000000..14fb0371e5 Binary files /dev/null and b/assets/images/Lab4_ESD_16_monitor.png differ diff --git a/assets/images/Lab4_ESD_2.png b/assets/images/Lab4_ESD_2.png new file mode 100644 index 0000000000..d921ea8661 Binary files /dev/null and b/assets/images/Lab4_ESD_2.png differ diff --git a/assets/images/Lab4_ESD_3.png b/assets/images/Lab4_ESD_3.png new file mode 100644 index 0000000000..63f7d6b1a7 Binary files /dev/null and b/assets/images/Lab4_ESD_3.png differ diff --git a/assets/images/Lab4_ESD_32.png b/assets/images/Lab4_ESD_32.png new file mode 100644 index 0000000000..1a873fd783 Binary files /dev/null and b/assets/images/Lab4_ESD_32.png differ diff --git a/assets/images/Lab4_ESD_4_chat.png b/assets/images/Lab4_ESD_4_chat.png new file mode 100644 index 0000000000..cab83a16ff Binary files /dev/null and b/assets/images/Lab4_ESD_4_chat.png differ diff --git a/assets/images/Lab4_ESD_5_chat.png b/assets/images/Lab4_ESD_5_chat.png new file mode 100644 index 0000000000..add5f5d3dc Binary files /dev/null and b/assets/images/Lab4_ESD_5_chat.png differ diff --git a/assets/images/Lab4_ESD_6_chat.png b/assets/images/Lab4_ESD_6_chat.png new file mode 100644 index 0000000000..9354f86682 Binary files /dev/null and b/assets/images/Lab4_ESD_6_chat.png differ diff --git a/assets/images/Lab4_ESD_7_chat.png b/assets/images/Lab4_ESD_7_chat.png new file mode 100644 index 0000000000..9cf5373d0b Binary files /dev/null and b/assets/images/Lab4_ESD_7_chat.png differ diff --git a/assets/images/Lab4_ESD_8_chat.png b/assets/images/Lab4_ESD_8_chat.png new file mode 100644 index 0000000000..0d64bc03b1 Binary files /dev/null and b/assets/images/Lab4_ESD_8_chat.png differ diff --git a/assets/images/Lab4_ESD_9_monitor.png b/assets/images/Lab4_ESD_9_monitor.png new file mode 100644 index 0000000000..1615b5804f Binary files /dev/null and b/assets/images/Lab4_ESD_9_monitor.png differ diff --git a/assets/images/Lab4_ESD_9_monitor2.png b/assets/images/Lab4_ESD_9_monitor2.png new file mode 100644 index 0000000000..47767a18ff Binary files /dev/null and b/assets/images/Lab4_ESD_9_monitor2.png differ diff --git a/assets/images/OnboardingProcess/AutonomousOnboarding.png b/assets/images/OnboardingProcess/AutonomousOnboarding.png new file mode 100644 index 0000000000..728fe1b253 Binary files /dev/null and b/assets/images/OnboardingProcess/AutonomousOnboarding.png differ diff --git a/assets/images/OnboardingProcess/AutonomousOnboarding_goLive.png b/assets/images/OnboardingProcess/AutonomousOnboarding_goLive.png new file mode 100644 index 0000000000..973f018f95 Binary files /dev/null and b/assets/images/OnboardingProcess/AutonomousOnboarding_goLive.png differ diff --git a/assets/images/OnboardingProcess/AutonomousOnboarding_start.png b/assets/images/OnboardingProcess/AutonomousOnboarding_start.png new file mode 100644 index 0000000000..25f8e1fb5f Binary files /dev/null and b/assets/images/OnboardingProcess/AutonomousOnboarding_start.png differ diff --git a/assets/images/OnboardingProcess/AutonomousOnboarding_step0.png b/assets/images/OnboardingProcess/AutonomousOnboarding_step0.png new file mode 100644 index 0000000000..fd979732a5 Binary files /dev/null and b/assets/images/OnboardingProcess/AutonomousOnboarding_step0.png differ diff --git a/assets/images/OnboardingProcess/AutonomousOnboarding_step1.png b/assets/images/OnboardingProcess/AutonomousOnboarding_step1.png new file mode 100644 index 0000000000..1d81e339f9 Binary files /dev/null and b/assets/images/OnboardingProcess/AutonomousOnboarding_step1.png differ diff --git a/assets/images/OnboardingProcess/AutonomousOnboarding_step2.png b/assets/images/OnboardingProcess/AutonomousOnboarding_step2.png new file mode 100644 index 0000000000..13e248ed77 Binary files /dev/null and b/assets/images/OnboardingProcess/AutonomousOnboarding_step2.png differ diff --git a/assets/images/OnboardingProcess/AutonomousOnboarding_step3.png b/assets/images/OnboardingProcess/AutonomousOnboarding_step3.png new file mode 100644 index 0000000000..437c4c7b18 Binary files /dev/null and b/assets/images/OnboardingProcess/AutonomousOnboarding_step3.png differ diff --git a/assets/images/OnboardingProcess/AutonomousOnboarding_step4.png b/assets/images/OnboardingProcess/AutonomousOnboarding_step4.png new file mode 100644 index 0000000000..b3368a6c3e Binary files /dev/null and b/assets/images/OnboardingProcess/AutonomousOnboarding_step4.png differ diff --git a/assets/images/OnboardingProcess/webex-new-logo1.png b/assets/images/OnboardingProcess/webex-new-logo1.png new file mode 100644 index 0000000000..d5f4729429 Binary files /dev/null and b/assets/images/OnboardingProcess/webex-new-logo1.png differ diff --git a/assets/images/OneTransaction.png b/assets/images/OneTransaction.png new file mode 100644 index 0000000000..0c246f1e51 Binary files /dev/null and b/assets/images/OneTransaction.png differ diff --git a/assets/images/SSO/1.png b/assets/images/SSO/1.png new file mode 100644 index 0000000000..36d0ddfddc Binary files /dev/null and b/assets/images/SSO/1.png differ diff --git a/assets/images/SSO/10.png b/assets/images/SSO/10.png new file mode 100644 index 0000000000..4234e0650a Binary files /dev/null and b/assets/images/SSO/10.png differ diff --git a/assets/images/SSO/12.png b/assets/images/SSO/12.png new file mode 100644 index 0000000000..39ff7ca456 Binary files /dev/null and b/assets/images/SSO/12.png differ diff --git a/assets/images/SSO/13.png b/assets/images/SSO/13.png new file mode 100644 index 0000000000..4033f051a4 Binary files /dev/null and b/assets/images/SSO/13.png differ diff --git a/assets/images/SSO/2.png b/assets/images/SSO/2.png new file mode 100644 index 0000000000..b9992a1a42 Binary files /dev/null and b/assets/images/SSO/2.png differ diff --git a/assets/images/SSO/3.png b/assets/images/SSO/3.png new file mode 100644 index 0000000000..7654af5f49 Binary files /dev/null and b/assets/images/SSO/3.png differ diff --git a/assets/images/SSO/4.png b/assets/images/SSO/4.png new file mode 100644 index 0000000000..5cd43a9a5c Binary files /dev/null and b/assets/images/SSO/4.png differ diff --git a/assets/images/SSO/5.png b/assets/images/SSO/5.png new file mode 100644 index 0000000000..b388ced5f3 Binary files /dev/null and b/assets/images/SSO/5.png differ diff --git a/assets/images/SSO/6.png b/assets/images/SSO/6.png new file mode 100644 index 0000000000..1b3528c153 Binary files /dev/null and b/assets/images/SSO/6.png differ diff --git a/assets/images/SSO/7.png b/assets/images/SSO/7.png new file mode 100644 index 0000000000..d4dc875a31 Binary files /dev/null and b/assets/images/SSO/7.png differ diff --git a/assets/images/SSO/8.png b/assets/images/SSO/8.png new file mode 100644 index 0000000000..58f4914024 Binary files /dev/null and b/assets/images/SSO/8.png differ diff --git a/assets/images/SSO/9.png b/assets/images/SSO/9.png new file mode 100644 index 0000000000..77bfd4f944 Binary files /dev/null and b/assets/images/SSO/9.png differ diff --git a/assets/images/Single.md b/assets/images/Single.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/images/emailConfirmation.png b/assets/images/emailConfirmation.png new file mode 100644 index 0000000000..e3750c3499 Binary files /dev/null and b/assets/images/emailConfirmation.png differ diff --git a/assets/images/email_copy_debug.gif b/assets/images/email_copy_debug.gif new file mode 100644 index 0000000000..f52ab1b210 Binary files /dev/null and b/assets/images/email_copy_debug.gif differ diff --git a/assets/images/email_paste_debug.gif b/assets/images/email_paste_debug.gif new file mode 100644 index 0000000000..0bf448ba72 Binary files /dev/null and b/assets/images/email_paste_debug.gif differ diff --git a/assets/images/maildrop.gif b/assets/images/maildrop.gif new file mode 100644 index 0000000000..3118c31492 Binary files /dev/null and b/assets/images/maildrop.gif differ diff --git a/assets/images/mailinator-1.gif b/assets/images/mailinator-1.gif new file mode 100644 index 0000000000..8947c94215 Binary files /dev/null and b/assets/images/mailinator-1.gif differ diff --git a/assets/images/mailinator-1.gif.md b/assets/images/mailinator-1.gif.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/assets/images/wxcallingandroid.png b/assets/images/wxcallingandroid.png new file mode 100644 index 0000000000..e6b986f770 Binary files /dev/null and b/assets/images/wxcallingandroid.png differ diff --git a/assets/search.html b/assets/search.html index dbe4eff9b9..331abdcdc9 100644 --- a/assets/search.html +++ b/assets/search.html @@ -1,9 +1,9 @@ ---- -layout: search-base ---- - - - - +--- +layout: search-base +--- + + + + diff --git a/files/ESD_default_layout.json.md b/files/ESD_default_layout.json.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/files/RTMS EA Regional Media.pdf b/files/RTMS EA Regional Media.pdf new file mode 100644 index 0000000000..4b294f46b7 Binary files /dev/null and b/files/RTMS EA Regional Media.pdf differ diff --git a/files/RTMS GA Launch.pdf b/files/RTMS GA Launch.pdf new file mode 100644 index 0000000000..377da97014 Binary files /dev/null and b/files/RTMS GA Launch.pdf differ diff --git a/support.md b/support.md new file mode 100644 index 0000000000..735efbcd49 --- /dev/null +++ b/support.md @@ -0,0 +1,12 @@ +--- +title: Support & Feedback +layout: home +--- + +**Lab Support Email:** [wxcclabs@cisco.com](mailto:wxcclabs@cisco.com) + + +Please use that form for providing the lab feedback. + + +