(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["PhoneJs"] = factory(); else root["PhoneJs"] = factory(); })(typeof self !== 'undefined' ? self : this, function() { return (function(modules) { // webpackBootstrap // The module cache var installedModules = {}; // The require function function __webpack_require__(moduleId) { // Check if module is in cache if(installedModules[moduleId]) { return installedModules[moduleId].exports; } // Create a new module (and put it into the cache) var module = installedModules[moduleId] = { i: moduleId, l: false, exports: {} }; // Execute the module function modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded module.l = true; // Return the exports of the module return module.exports; } // expose the modules object (__webpack_modules__) __webpack_require__.m = modules; // expose the module cache __webpack_require__.c = installedModules; // define getter function for harmony exports __webpack_require__.d = function(exports, name, getter) { if(!__webpack_require__.o(exports, name)) { Object.defineProperty(exports, name, { configurable: false, enumerable: true, get: getter }); } }; // getDefaultExport function for compatibility with non-harmony modules __webpack_require__.n = function(module) { var getter = module && module.__esModule ? function getDefault() { return module['default']; } : function getModuleExports() { return module; }; __webpack_require__.d(getter, 'a', getter); return getter; }; // Object.prototype.hasOwnProperty.call __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; // __webpack_public_path__ __webpack_require__.p = ""; // Load entry module and return exports return __webpack_require__(__webpack_require__.s = 23); }) /************************************************************************/ ([ /* 0 */ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/* eslint-env browser */ /** * This is the web browser implementation of `debug()`. */ exports.log = log; exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = localstorage(); /** * Colors. */ exports.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']; /** * Currently only WebKit-based Web Inspectors, Firefox >= v31, * and the Firebug extension (any Firefox version) are known * to support "%c" CSS customizations. * * TODO: add a `localStorage` variable to explicitly enable/disable colors */ // eslint-disable-next-line complexity function useColors() { // NB: In an Electron preload script, document will be defined but not fully // initialized. Since we know we're in Chrome, we'll just detect this case // explicitly if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { return true; } // Internet Explorer and Edge do not support colors. if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { return false; } // Is webkit? http://stackoverflow.com/a/16459606/376773 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 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+)/); } /** * Colorize log arguments if enabled. * * @api public */ function formatArgs(args) { args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); if (!this.useColors) { return; } const c = 'color: ' + this.color; args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other // arguments passed either before or after the %c, so we need to // figure out the correct index to insert the CSS into let index = 0; let lastC = 0; args[0].replace(/%[a-zA-Z%]/g, match => { if (match === '%%') { return; } index++; if (match === '%c') { // We only are interested in the *last* %c // (the user may have provided their own) lastC = index; } }); args.splice(lastC, 0, c); } /** * Invokes `console.log()` when available. * No-op when `console.log` is not a "function". * * @api public */ function log(...args) { // This hackery is required for IE8/9, where // the `console.log` function doesn't have 'apply' return typeof console === 'object' && console.log && console.log(...args); } /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { try { if (namespaces) { exports.storage.setItem('debug', namespaces); } else { exports.storage.removeItem('debug'); } } catch (error) {// Swallow // XXX (@Qix-) should we be logging these? } } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { let r; try { r = exports.storage.getItem('debug'); } catch (error) {} // Swallow // XXX (@Qix-) should we be logging these? // If debug isn't set in LS, and we're in Electron, try to load $DEBUG if (!r && typeof process !== 'undefined' && 'env' in process) { r = process.env.DEBUG; } return r; } /** * Localstorage attempts to return the localstorage. * * This is necessary because safari throws * when a user disables cookies/localstorage * and you attempt to access it. * * @return {LocalStorage} * @api private */ function localstorage() { try { // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context // The Browser also has localStorage in the global context. return localStorage; } catch (error) {// Swallow // XXX (@Qix-) should we be logging these? } } module.exports = __webpack_require__(29)(exports); const { formatters } = module.exports; /** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */ formatters.j = function (v) { try { return JSON.stringify(v); } catch (error) { return '[UnexpectedJSONParseError]: ' + error.message; } }; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15))) }), /* 1 */ (function(module, exports, __webpack_require__) { "use strict"; var pkg = __webpack_require__(12); module.exports = { USER_AGENT: "".concat(pkg.title, " ").concat(pkg.version), // SIP scheme. SIP: 'sip', SIPS: 'sips', // End and Failure causes. causes: { // Generic error causes. CONNECTION_ERROR: 'Connection Error', REQUEST_TIMEOUT: 'Request Timeout', SIP_FAILURE_CODE: 'SIP Failure Code', INTERNAL_ERROR: 'Internal Error', // SIP error causes. BUSY: 'Busy', REJECTED: 'Rejected', REDIRECTED: 'Redirected', UNAVAILABLE: 'Unavailable', NOT_FOUND: 'Not Found', ADDRESS_INCOMPLETE: 'Address Incomplete', INCOMPATIBLE_SDP: 'Incompatible SDP', MISSING_SDP: 'Missing SDP', AUTHENTICATION_ERROR: 'Authentication Error', // Session error causes. BYE: 'Terminated', WEBRTC_ERROR: 'WebRTC Error', CANCELED: 'Canceled', NO_ANSWER: 'No Answer', EXPIRES: 'Expires', NO_ACK: 'No ACK', DIALOG_ERROR: 'Dialog Error', USER_DENIED_MEDIA_ACCESS: 'User Denied Media Access', BAD_MEDIA_DESCRIPTION: 'Bad Media Description', RTP_TIMEOUT: 'RTP Timeout' }, SIP_ERROR_CAUSES: { REDIRECTED: [300, 301, 302, 305, 380], BUSY: [486, 600], REJECTED: [403, 603], NOT_FOUND: [404, 604], UNAVAILABLE: [480, 410, 408, 430], ADDRESS_INCOMPLETE: [484, 424], INCOMPATIBLE_SDP: [488, 606], AUTHENTICATION_ERROR: [401, 407] }, // SIP Methods. ACK: 'ACK', BYE: 'BYE', CANCEL: 'CANCEL', INFO: 'INFO', INVITE: 'INVITE', MESSAGE: 'MESSAGE', NOTIFY: 'NOTIFY', OPTIONS: 'OPTIONS', REGISTER: 'REGISTER', REFER: 'REFER', UPDATE: 'UPDATE', SUBSCRIBE: 'SUBSCRIBE', /* SIP Response Reasons * DOC: https://www.iana.org/assignments/sip-parameters * Copied from https://github.com/versatica/OverSIP/blob/master/lib/oversip/sip/constants.rb#L7 */ REASON_PHRASE: { 100: 'Trying', 180: 'Ringing', 181: 'Call Is Being Forwarded', 182: 'Queued', 183: 'Session Progress', 199: 'Early Dialog Terminated', // draft-ietf-sipcore-199 200: 'OK', 202: 'Accepted', // RFC 3265 204: 'No Notification', // RFC 5839 300: 'Multiple Choices', 301: 'Moved Permanently', 302: 'Moved Temporarily', 305: 'Use Proxy', 380: 'Alternative Service', 400: 'Bad Request', 401: 'Unauthorized', 402: 'Payment Required', 403: 'Forbidden', 404: 'Not Found', 405: 'Method Not Allowed', 406: 'Not Acceptable', 407: 'Proxy Authentication Required', 408: 'Request Timeout', 410: 'Gone', 412: 'Conditional Request Failed', // RFC 3903 413: 'Request Entity Too Large', 414: 'Request-URI Too Long', 415: 'Unsupported Media Type', 416: 'Unsupported URI Scheme', 417: 'Unknown Resource-Priority', // RFC 4412 420: 'Bad Extension', 421: 'Extension Required', 422: 'Session Interval Too Small', // RFC 4028 423: 'Interval Too Brief', 424: 'Bad Location Information', // RFC 6442 428: 'Use Identity Header', // RFC 4474 429: 'Provide Referrer Identity', // RFC 3892 430: 'Flow Failed', // RFC 5626 433: 'Anonymity Disallowed', // RFC 5079 436: 'Bad Identity-Info', // RFC 4474 437: 'Unsupported Certificate', // RFC 4744 438: 'Invalid Identity Header', // RFC 4744 439: 'First Hop Lacks Outbound Support', // RFC 5626 440: 'Max-Breadth Exceeded', // RFC 5393 469: 'Bad Info Package', // draft-ietf-sipcore-info-events 470: 'Consent Needed', // RFC 5360 478: 'Unresolvable Destination', // Custom code copied from Kamailio. 480: 'Temporarily Unavailable', 481: 'Call/Transaction Does Not Exist', 482: 'Loop Detected', 483: 'Too Many Hops', 484: 'Address Incomplete', 485: 'Ambiguous', 486: 'Busy Here', 487: 'Request Terminated', 488: 'Not Acceptable Here', 489: 'Bad Event', // RFC 3265 491: 'Request Pending', 493: 'Undecipherable', 494: 'Security Agreement Required', // RFC 3329 500: 'JsSIP Internal Error', 501: 'Not Implemented', 502: 'Bad Gateway', 503: 'Service Unavailable', 504: 'Server Time-out', 505: 'Version Not Supported', 513: 'Message Too Large', 580: 'Precondition Failure', // RFC 3312 600: 'Busy Everywhere', 603: 'Decline', 604: 'Does Not Exist Anywhere', 606: 'Not Acceptable' }, ALLOWED_METHODS: 'INVITE,ACK,CANCEL,BYE,UPDATE,MESSAGE,OPTIONS,REFER,INFO', ACCEPTED_BODY_TYPES: 'application/sdp, application/dtmf-relay', MAX_FORWARDS: 69, SESSION_EXPIRES: 90, MIN_SESSION_EXPIRES: 60 }; }), (function(module, exports, __webpack_require__) { "use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } var JsSIP_C = __webpack_require__(1); var URI = __webpack_require__(8); var Grammar = __webpack_require__(3); exports.str_utf8_length = function (string) { return unescape(encodeURIComponent(string)).length; }; // Used by 'hasMethods'. var isFunction = exports.isFunction = function (fn) { if (fn !== undefined) { return Object.prototype.toString.call(fn) === '[object Function]' ? true : false; } else { return false; } }; exports.isString = function (str) { if (str !== undefined) { return Object.prototype.toString.call(str) === '[object String]' ? true : false; } else { return false; } }; exports.isDecimal = function (num) { return !isNaN(num) && parseFloat(num) === parseInt(num, 10); }; exports.isEmpty = function (value) { return value === null || value === '' || value === undefined || Array.isArray(value) && value.length === 0 || typeof value === 'number' && isNaN(value); }; exports.hasMethods = function (obj) { for (var _len = arguments.length, methodNames = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { methodNames[_key - 1] = arguments[_key]; } for (var _i = 0; _i < methodNames.length; _i++) { var methodName = methodNames[_i]; if (isFunction(obj[methodName])) { return false; } } return true; }; // Used by 'newTag'. var createRandomToken = exports.createRandomToken = function (size) { var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 32; var i, r, token = ''; for (i = 0; i < size; i++) { r = Math.random() * base | 0; token += r.toString(base); } return token; }; exports.newTag = function () { return createRandomToken(10); }; // https://stackoverflow.com/users/109538/broofa. exports.newUUID = function () { var UUID = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c === 'x' ? r : r & 0x3 | 0x8; return v.toString(16); }); return UUID; }; exports.hostType = function (host) { if (!host) { return; } else { host = Grammar.parse(host, 'host'); if (host !== -1) { return host.host_type; } } }; /** * Hex-escape a SIP URI user. * Don't hex-escape ':' (%3A), '+' (%2B), '?' (%3F"), '/' (%2F). * * Used by 'normalizeTarget'. */ var escapeUser = exports.escapeUser = function (user) { return encodeURIComponent(decodeURIComponent(user)).replace(/%3A/ig, ':').replace(/%2B/ig, '+').replace(/%3F/ig, '?').replace(/%2F/ig, '/'); }; /** * Normalize SIP URI. * NOTE: It does not allow a SIP URI without username. * Accepts 'sip', 'sips' and 'tel' URIs and convert them into 'sip'. * Detects the domain part (if given) and properly hex-escapes the user portion. * If the user portion has only 'tel' number symbols the user portion is clean of 'tel' visual separators. */ exports.normalizeTarget = function (target, domain) { // If no target is given then raise an error. if (!target) { return; // If a URI instance is given then return it. } else if (target instanceof URI) { return target; // If a string is given split it by '@': // - Last fragment is the desired domain. // - Otherwise append the given domain argument. } else if (typeof target === 'string') { var target_array = target.split('@'); var target_user; var target_domain; switch (target_array.length) { case 1: if (!domain) { return; } target_user = target; target_domain = domain; break; case 2: target_user = target_array[0]; target_domain = target_array[1]; break; default: target_user = target_array.slice(0, target_array.length - 1).join('@'); target_domain = target_array[target_array.length - 1]; } // Remove the URI scheme (if present). target_user = target_user.replace(/^(sips?|tel):/i, ''); // Remove 'tel' visual separators if the user portion just contains 'tel' number symbols. if (/^[-.()]*\+?[0-9\-.()]+$/.test(target_user)) { target_user = target_user.replace(/[-.()]/g, ''); } // Build the complete SIP URI. target = "".concat(JsSIP_C.SIP, ":").concat(escapeUser(target_user), "@").concat(target_domain); // Finally parse the resulting URI. var uri; if (uri = URI.parse(target)) { return uri; } else { return; } } else { return; } }; exports.headerize = function (string) { var exceptions = { 'Call-Id': 'Call-ID', 'Cseq': 'CSeq', 'Www-Authenticate': 'WWW-Authenticate' }; var name = string.toLowerCase().replace(/_/g, '-').split('-'); var hname = ''; var parts = name.length; var part; for (part = 0; part < parts; part++) { if (part !== 0) { hname += '-'; } hname += name[part].charAt(0).toUpperCase() + name[part].substring(1); } if (exceptions[hname]) { hname = exceptions[hname]; } return hname; }; exports.sipErrorCause = function (status_code) { for (var cause in JsSIP_C.SIP_ERROR_CAUSES) { if (JsSIP_C.SIP_ERROR_CAUSES[cause].indexOf(status_code) !== -1) { return JsSIP_C.causes[cause]; } } return JsSIP_C.causes.SIP_FAILURE_CODE; }; /** * Generate a random Test-Net IP (https://tools.ietf.org/html/rfc5735) */ exports.getRandomTestNetIP = function () { function getOctet(from, to) { return Math.floor(Math.random() * (to - from + 1) + from); } return "192.0.2.".concat(getOctet(1, 254)); }; // MD5 (Message-Digest Algorithm) https://www.webtoolkit.info. exports.calculateMD5 = function (string) { function rotateLeft(lValue, iShiftBits) { return lValue << iShiftBits | lValue >>> 32 - iShiftBits; } function addUnsigned(lX, lY) { var lX8 = lX & 0x80000000; var lY8 = lY & 0x80000000; var lX4 = lX & 0x40000000; var lY4 = lY & 0x40000000; var lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); if (lX4 & lY4) { return lResult ^ 0x80000000 ^ lX8 ^ lY8; } if (lX4 | lY4) { if (lResult & 0x40000000) { return lResult ^ 0xC0000000 ^ lX8 ^ lY8; } else { return lResult ^ 0x40000000 ^ lX8 ^ lY8; } } else { return lResult ^ lX8 ^ lY8; } } function doF(x, y, z) { return x & y | ~x & z; } function doG(x, y, z) { return x & z | y & ~z; } function doH(x, y, z) { return x ^ y ^ z; } function doI(x, y, z) { return y ^ (x | ~z); } function doFF(a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(doF(b, c, d), x), ac)); return addUnsigned(rotateLeft(a, s), b); } function doGG(a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(doG(b, c, d), x), ac)); return addUnsigned(rotateLeft(a, s), b); } function doHH(a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(doH(b, c, d), x), ac)); return addUnsigned(rotateLeft(a, s), b); } function doII(a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(doI(b, c, d), x), ac)); return addUnsigned(rotateLeft(a, s), b); } function convertToWordArray(str) { var lWordCount; var lMessageLength = str.length; var lNumberOfWords_temp1 = lMessageLength + 8; var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - lNumberOfWords_temp1 % 64) / 64; var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16; var lWordArray = new Array(lNumberOfWords - 1); var lBytePosition = 0; var lByteCount = 0; while (lByteCount < lMessageLength) { lWordCount = (lByteCount - lByteCount % 4) / 4; lBytePosition = lByteCount % 4 * 8; lWordArray[lWordCount] = lWordArray[lWordCount] | str.charCodeAt(lByteCount) << lBytePosition; lByteCount++; } lWordCount = (lByteCount - lByteCount % 4) / 4; lBytePosition = lByteCount % 4 * 8; lWordArray[lWordCount] = lWordArray[lWordCount] | 0x80 << lBytePosition; lWordArray[lNumberOfWords - 2] = lMessageLength << 3; lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29; return lWordArray; } function wordToHex(lValue) { var wordToHexValue = '', wordToHexValue_temp = '', lByte, lCount; for (lCount = 0; lCount <= 3; lCount++) { lByte = lValue >>> lCount * 8 & 255; wordToHexValue_temp = "0".concat(lByte.toString(16)); wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2); } return wordToHexValue; } function utf8Encode(str) { str = str.replace(/\r\n/g, '\n'); var utftext = ''; for (var n = 0; n < str.length; n++) { var _c = str.charCodeAt(n); if (_c < 128) { utftext += String.fromCharCode(_c); } else if (_c > 127 && _c < 2048) { utftext += String.fromCharCode(_c >> 6 | 192); utftext += String.fromCharCode(_c & 63 | 128); } else { utftext += String.fromCharCode(_c >> 12 | 224); utftext += String.fromCharCode(_c >> 6 & 63 | 128); utftext += String.fromCharCode(_c & 63 | 128); } } return utftext; } var x = []; var k, AA, BB, CC, DD, a, b, c, d; var S11 = 7, S12 = 12, S13 = 17, S14 = 22; var S21 = 5, S22 = 9, S23 = 14, S24 = 20; var S31 = 4, S32 = 11, S33 = 16, S34 = 23; var S41 = 6, S42 = 10, S43 = 15, S44 = 21; string = utf8Encode(string); x = convertToWordArray(string); a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476; for (k = 0; k < x.length; k += 16) { AA = a; BB = b; CC = c; DD = d; a = doFF(a, b, c, d, x[k + 0], S11, 0xD76AA478); d = doFF(d, a, b, c, x[k + 1], S12, 0xE8C7B756); c = doFF(c, d, a, b, x[k + 2], S13, 0x242070DB); b = doFF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE); a = doFF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF); d = doFF(d, a, b, c, x[k + 5], S12, 0x4787C62A); c = doFF(c, d, a, b, x[k + 6], S13, 0xA8304613); b = doFF(b, c, d, a, x[k + 7], S14, 0xFD469501); a = doFF(a, b, c, d, x[k + 8], S11, 0x698098D8); d = doFF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF); c = doFF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1); b = doFF(b, c, d, a, x[k + 11], S14, 0x895CD7BE); a = doFF(a, b, c, d, x[k + 12], S11, 0x6B901122); d = doFF(d, a, b, c, x[k + 13], S12, 0xFD987193); c = doFF(c, d, a, b, x[k + 14], S13, 0xA679438E); b = doFF(b, c, d, a, x[k + 15], S14, 0x49B40821); a = doGG(a, b, c, d, x[k + 1], S21, 0xF61E2562); d = doGG(d, a, b, c, x[k + 6], S22, 0xC040B340); c = doGG(c, d, a, b, x[k + 11], S23, 0x265E5A51); b = doGG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA); a = doGG(a, b, c, d, x[k + 5], S21, 0xD62F105D); d = doGG(d, a, b, c, x[k + 10], S22, 0x2441453); c = doGG(c, d, a, b, x[k + 15], S23, 0xD8A1E681); b = doGG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8); a = doGG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6); d = doGG(d, a, b, c, x[k + 14], S22, 0xC33707D6); c = doGG(c, d, a, b, x[k + 3], S23, 0xF4D50D87); b = doGG(b, c, d, a, x[k + 8], S24, 0x455A14ED); a = doGG(a, b, c, d, x[k + 13], S21, 0xA9E3E905); d = doGG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8); c = doGG(c, d, a, b, x[k + 7], S23, 0x676F02D9); b = doGG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A); a = doHH(a, b, c, d, x[k + 5], S31, 0xFFFA3942); d = doHH(d, a, b, c, x[k + 8], S32, 0x8771F681); c = doHH(c, d, a, b, x[k + 11], S33, 0x6D9D6122); b = doHH(b, c, d, a, x[k + 14], S34, 0xFDE5380C); a = doHH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44); d = doHH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9); c = doHH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60); b = doHH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70); a = doHH(a, b, c, d, x[k + 13], S31, 0x289B7EC6); d = doHH(d, a, b, c, x[k + 0], S32, 0xEAA127FA); c = doHH(c, d, a, b, x[k + 3], S33, 0xD4EF3085); b = doHH(b, c, d, a, x[k + 6], S34, 0x4881D05); a = doHH(a, b, c, d, x[k + 9], S31, 0xD9D4D039); d = doHH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5); c = doHH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8); b = doHH(b, c, d, a, x[k + 2], S34, 0xC4AC5665); a = doII(a, b, c, d, x[k + 0], S41, 0xF4292244); d = doII(d, a, b, c, x[k + 7], S42, 0x432AFF97); c = doII(c, d, a, b, x[k + 14], S43, 0xAB9423A7); b = doII(b, c, d, a, x[k + 5], S44, 0xFC93A039); a = doII(a, b, c, d, x[k + 12], S41, 0x655B59C3); d = doII(d, a, b, c, x[k + 3], S42, 0x8F0CCC92); c = doII(c, d, a, b, x[k + 10], S43, 0xFFEFF47D); b = doII(b, c, d, a, x[k + 1], S44, 0x85845DD1); a = doII(a, b, c, d, x[k + 8], S41, 0x6FA87E4F); d = doII(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0); c = doII(c, d, a, b, x[k + 6], S43, 0xA3014314); b = doII(b, c, d, a, x[k + 13], S44, 0x4E0811A1); a = doII(a, b, c, d, x[k + 4], S41, 0xF7537E82); d = doII(d, a, b, c, x[k + 11], S42, 0xBD3AF235); c = doII(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB); b = doII(b, c, d, a, x[k + 9], S44, 0xEB86D391); a = addUnsigned(a, AA); b = addUnsigned(b, BB); c = addUnsigned(c, CC); d = addUnsigned(d, DD); } var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d); return temp.toLowerCase(); }; exports.closeMediaStream = function (stream) { if (!stream) { return; } // Latest spec states that MediaStream has no stop() method and instead must // call stop() on every MediaStreamTrack. try { var tracks; if (stream.getTracks) { tracks = stream.getTracks(); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = tracks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var track = _step.value; track.stop(); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } else { tracks = stream.getAudioTracks(); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = tracks[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _track = _step2.value; _track.stop(); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } tracks = stream.getVideoTracks(); var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = tracks[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _track2 = _step3.value; _track2.stop(); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return != null) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } } catch (error) { // Deprecated by the spec, but still in use. // NOTE: In Temasys IE plugin stream.stop is a callable 'object'. if (typeof stream.stop === 'function' || _typeof(stream.stop) === 'object') { stream.stop(); } } }; exports.cloneArray = function (array) { return array && array.slice() || []; }; }), /* 3 */ (function(module, exports, __webpack_require__) { "use strict"; module.exports = function () { /* * Generated by PEG.js 0.7.0. * * http://pegjs.majda.cz/ */ function quote(s) { /* * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a * string literal except for the closing quote character, backslash, * carriage return, line separator, paragraph separator, and line feed. * Any character may appear in the form of an escape sequence. * * For portability, we also escape escape all control and non-ASCII * characters. Note that "\0" and "\v" escape sequences are not used * because JSHint does not like the first and IE the second. */ return '"' + s.replace(/\\/g, '\\\\') // backslash .replace(/"/g, '\\"') // closing quote character .replace(/\x08/g, '\\b') // backspace .replace(/\t/g, '\\t') // horizontal tab .replace(/\n/g, '\\n') // line feed .replace(/\f/g, '\\f') // form feed .replace(/\r/g, '\\r') // carriage return .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) + '"'; } var result = { /* * Parses the input with a generated parser. If the parsing is successfull, * returns a value explicitly or implicitly specified by the grammar from * which the parser was generated (see |PEG.buildParser|). If the parsing is * unsuccessful, throws |PEG.parser.SyntaxError| describing the error. */ parse: function parse(input, startRule) { var parseFunctions = { "CRLF": parse_CRLF, "DIGIT": parse_DIGIT, "ALPHA": parse_ALPHA, "HEXDIG": parse_HEXDIG, "WSP": parse_WSP, "OCTET": parse_OCTET, "DQUOTE": parse_DQUOTE, "SP": parse_SP, "HTAB": parse_HTAB, "alphanum": parse_alphanum, "reserved": parse_reserved, "unreserved": parse_unreserved, "mark": parse_mark, "escaped": parse_escaped, "LWS": parse_LWS, "SWS": parse_SWS, "HCOLON": parse_HCOLON, "TEXT_UTF8_TRIM": parse_TEXT_UTF8_TRIM, "TEXT_UTF8char": parse_TEXT_UTF8char, "UTF8_NONASCII": parse_UTF8_NONASCII, "UTF8_CONT": parse_UTF8_CONT, "LHEX": parse_LHEX, "token": parse_token, "token_nodot": parse_token_nodot, "separators": parse_separators, "word": parse_word, "STAR": parse_STAR, "SLASH": parse_SLASH, "EQUAL": parse_EQUAL, "LPAREN": parse_LPAREN, "RPAREN": parse_RPAREN, "RAQUOT": parse_RAQUOT, "LAQUOT": parse_LAQUOT, "COMMA": parse_COMMA, "SEMI": parse_SEMI, "COLON": parse_COLON, "LDQUOT": parse_LDQUOT, "RDQUOT": parse_RDQUOT, "comment": parse_comment, "ctext": parse_ctext, "quoted_string": parse_quoted_string, "quoted_string_clean": parse_quoted_string_clean, "qdtext": parse_qdtext, "quoted_pair": parse_quoted_pair, "SIP_URI_noparams": parse_SIP_URI_noparams, "SIP_URI": parse_SIP_URI, "uri_scheme": parse_uri_scheme, "uri_scheme_sips": parse_uri_scheme_sips, "uri_scheme_sip": parse_uri_scheme_sip, "userinfo": parse_userinfo, "user": parse_user, "user_unreserved": parse_user_unreserved, "password": parse_password, "hostport": parse_hostport, "host": parse_host, "hostname": parse_hostname, "domainlabel": parse_domainlabel, "toplabel": parse_toplabel, "IPv6reference": parse_IPv6reference, "IPv6address": parse_IPv6address, "h16": parse_h16, "ls32": parse_ls32, "IPv4address": parse_IPv4address, "dec_octet": parse_dec_octet, "port": parse_port, "uri_parameters": parse_uri_parameters, "uri_parameter": parse_uri_parameter, "transport_param": parse_transport_param, "user_param": parse_user_param, "method_param": parse_method_param, "ttl_param": parse_ttl_param, "maddr_param": parse_maddr_param, "lr_param": parse_lr_param, "other_param": parse_other_param, "pname": parse_pname, "pvalue": parse_pvalue, "paramchar": parse_paramchar, "param_unreserved": parse_param_unreserved, "headers": parse_headers, "header": parse_header, "hname": parse_hname, "hvalue": parse_hvalue, "hnv_unreserved": parse_hnv_unreserved, "Request_Response": parse_Request_Response, "Request_Line": parse_Request_Line, "Request_URI": parse_Request_URI, "absoluteURI": parse_absoluteURI, "hier_part": parse_hier_part, "net_path": parse_net_path, "abs_path": parse_abs_path, "opaque_part": parse_opaque_part, "uric": parse_uric, "uric_no_slash": parse_uric_no_slash, "path_segments": parse_path_segments, "segment": parse_segment, "param": parse_param, "pchar": parse_pchar, "scheme": parse_scheme, "authority": parse_authority, "srvr": parse_srvr, "reg_name": parse_reg_name, "query": parse_query, "SIP_Version": parse_SIP_Version, "INVITEm": parse_INVITEm, "ACKm": parse_ACKm, "OPTIONSm": parse_OPTIONSm, "BYEm": parse_BYEm, "CANCELm": parse_CANCELm, "REGISTERm": parse_REGISTERm, "SUBSCRIBEm": parse_SUBSCRIBEm, "NOTIFYm": parse_NOTIFYm, "REFERm": parse_REFERm, "Method": parse_Method, "Status_Line": parse_Status_Line, "Status_Code": parse_Status_Code, "extension_code": parse_extension_code, "Reason_Phrase": parse_Reason_Phrase, "Allow_Events": parse_Allow_Events, "Call_ID": parse_Call_ID, "Contact": parse_Contact, "contact_param": parse_contact_param, "name_addr": parse_name_addr, "display_name": parse_display_name, "contact_params": parse_contact_params, "c_p_q": parse_c_p_q, "c_p_expires": parse_c_p_expires, "delta_seconds": parse_delta_seconds, "qvalue": parse_qvalue, "generic_param": parse_generic_param, "gen_value": parse_gen_value, "Content_Disposition": parse_Content_Disposition, "disp_type": parse_disp_type, "disp_param": parse_disp_param, "handling_param": parse_handling_param, "Content_Encoding": parse_Content_Encoding, "Content_Length": parse_Content_Length, "Content_Type": parse_Content_Type, "media_type": parse_media_type, "m_type": parse_m_type, "discrete_type": parse_discrete_type, "composite_type": parse_composite_type, "extension_token": parse_extension_token, "x_token": parse_x_token, "m_subtype": parse_m_subtype, "m_parameter": parse_m_parameter, "m_value": parse_m_value, "CSeq": parse_CSeq, "CSeq_value": parse_CSeq_value, "Expires": parse_Expires, "Event": parse_Event, "event_type": parse_event_type, "From": parse_From, "from_param": parse_from_param, "tag_param": parse_tag_param, "Max_Forwards": parse_Max_Forwards, "Min_Expires": parse_Min_Expires, "Name_Addr_Header": parse_Name_Addr_Header, "Proxy_Authenticate": parse_Proxy_Authenticate, "challenge": parse_challenge, "other_challenge": parse_other_challenge, "auth_param": parse_auth_param, "digest_cln": parse_digest_cln, "realm": parse_realm, "realm_value": parse_realm_value, "domain": parse_domain, "URI": parse_URI, "nonce": parse_nonce, "nonce_value": parse_nonce_value, "opaque": parse_opaque, "stale": parse_stale, "algorithm": parse_algorithm, "qop_options": parse_qop_options, "qop_value": parse_qop_value, "Proxy_Require": parse_Proxy_Require, "Record_Route": parse_Record_Route, "rec_route": parse_rec_route, "Reason": parse_Reason, "reason_param": parse_reason_param, "reason_cause": parse_reason_cause, "Require": parse_Require, "Route": parse_Route, "route_param": parse_route_param, "Subscription_State": parse_Subscription_State, "substate_value": parse_substate_value, "subexp_params": parse_subexp_params, "event_reason_value": parse_event_reason_value, "Subject": parse_Subject, "Supported": parse_Supported, "To": parse_To, "to_param": parse_to_param, "Via": parse_Via, "via_param": parse_via_param, "via_params": parse_via_params, "via_ttl": parse_via_ttl, "via_maddr": parse_via_maddr, "via_received": parse_via_received, "via_branch": parse_via_branch, "response_port": parse_response_port, "sent_protocol": parse_sent_protocol, "protocol_name": parse_protocol_name, "transport": parse_transport, "sent_by": parse_sent_by, "via_host": parse_via_host, "via_port": parse_via_port, "ttl": parse_ttl, "WWW_Authenticate": parse_WWW_Authenticate, "Session_Expires": parse_Session_Expires, "s_e_expires": parse_s_e_expires, "s_e_params": parse_s_e_params, "s_e_refresher": parse_s_e_refresher, "extension_header": parse_extension_header, "header_value": parse_header_value, "message_body": parse_message_body, "uuid_URI": parse_uuid_URI, "uuid": parse_uuid, "hex4": parse_hex4, "hex8": parse_hex8, "hex12": parse_hex12, "Refer_To": parse_Refer_To, "Replaces": parse_Replaces, "call_id": parse_call_id, "replaces_param": parse_replaces_param, "to_tag": parse_to_tag, "from_tag": parse_from_tag, "early_flag": parse_early_flag }; if (startRule !== undefined) { if (parseFunctions[startRule] === undefined) { throw new Error("Invalid rule name: " + quote(startRule) + "."); } } else { startRule = "CRLF"; } var pos = 0; var reportFailures = 0; var rightmostFailuresPos = 0; var rightmostFailuresExpected = []; function padLeft(input, padding, length) { var result = input; var padLength = length - input.length; for (var i = 0; i < padLength; i++) { result = padding + result; } return result; } function escape(ch) { var charCode = ch.charCodeAt(0); var escapeChar; var length; if (charCode <= 0xFF) { escapeChar = 'x'; length = 2; } else { escapeChar = 'u'; length = 4; } return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length); } function matchFailed(failure) { if (pos < rightmostFailuresPos) { return; } if (pos > rightmostFailuresPos) { rightmostFailuresPos = pos; rightmostFailuresExpected = []; } rightmostFailuresExpected.push(failure); } function parse_CRLF() { var result0; if (input.substr(pos, 2) === "\r\n") { result0 = "\r\n"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"\\r\\n\""); } } return result0; } function parse_DIGIT() { var result0; if (/^[0-9]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[0-9]"); } } return result0; } function parse_ALPHA() { var result0; if (/^[a-zA-Z]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[a-zA-Z]"); } } return result0; } function parse_HEXDIG() { var result0; if (/^[0-9a-fA-F]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[0-9a-fA-F]"); } } return result0; } function parse_WSP() { var result0; result0 = parse_SP(); if (result0 === null) { result0 = parse_HTAB(); } return result0; } function parse_OCTET() { var result0; if (/^[\0-\xFF]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[\\0-\\xFF]"); } } return result0; } function parse_DQUOTE() { var result0; if (/^["]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[\"]"); } } return result0; } function parse_SP() { var result0; if (input.charCodeAt(pos) === 32) { result0 = " "; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\" \""); } } return result0; } function parse_HTAB() { var result0; if (input.charCodeAt(pos) === 9) { result0 = "\t"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"\\t\""); } } return result0; } function parse_alphanum() { var result0; if (/^[a-zA-Z0-9]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[a-zA-Z0-9]"); } } return result0; } function parse_reserved() { var result0; if (input.charCodeAt(pos) === 59) { result0 = ";"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 47) { result0 = "/"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 63) { result0 = "?"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 58) { result0 = ":"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 64) { result0 = "@"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 38) { result0 = "&"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 61) { result0 = "="; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 43) { result0 = "+"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 36) { result0 = "$"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 44) { result0 = ","; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\",\""); } } } } } } } } } } } return result0; } function parse_unreserved() { var result0; result0 = parse_alphanum(); if (result0 === null) { result0 = parse_mark(); } return result0; } function parse_mark() { var result0; if (input.charCodeAt(pos) === 45) { result0 = "-"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 95) { result0 = "_"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 46) { result0 = "."; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 33) { result0 = "!"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 126) { result0 = "~"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"~\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 42) { result0 = "*"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 39) { result0 = "'"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 40) { result0 = "("; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"(\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 41) { result0 = ")"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\")\""); } } } } } } } } } } return result0; } function parse_escaped() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 37) { result0 = "%"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"%\""); } } if (result0 !== null) { result1 = parse_HEXDIG(); if (result1 !== null) { result2 = parse_HEXDIG(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, escaped) { return escaped.join(''); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_LWS() { var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; pos2 = pos; result0 = []; result1 = parse_WSP(); while (result1 !== null) { result0.push(result1); result1 = parse_WSP(); } if (result0 !== null) { result1 = parse_CRLF(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos2; } } else { result0 = null; pos = pos2; } result0 = result0 !== null ? result0 : ""; if (result0 !== null) { result2 = parse_WSP(); if (result2 !== null) { result1 = []; while (result2 !== null) { result1.push(result2); result2 = parse_WSP(); } } else { result1 = null; } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return " "; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_SWS() { var result0; result0 = parse_LWS(); result0 = result0 !== null ? result0 : ""; return result0; } function parse_HCOLON() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = []; result1 = parse_SP(); if (result1 === null) { result1 = parse_HTAB(); } while (result1 !== null) { result0.push(result1); result1 = parse_SP(); if (result1 === null) { result1 = parse_HTAB(); } } if (result0 !== null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return ':'; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_TEXT_UTF8_TRIM() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result1 = parse_TEXT_UTF8char(); if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_TEXT_UTF8char(); } } else { result0 = null; } if (result0 !== null) { result1 = []; pos2 = pos; result2 = []; result3 = parse_LWS(); while (result3 !== null) { result2.push(result3); result3 = parse_LWS(); } if (result2 !== null) { result3 = parse_TEXT_UTF8char(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = []; result3 = parse_LWS(); while (result3 !== null) { result2.push(result3); result3 = parse_LWS(); } if (result2 !== null) { result3 = parse_TEXT_UTF8char(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_TEXT_UTF8char() { var result0; if (/^[!-~]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[!-~]"); } } if (result0 === null) { result0 = parse_UTF8_NONASCII(); } return result0; } function parse_UTF8_NONASCII() { var result0; if (/^[\x80-\uFFFF]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[\\x80-\\uFFFF]"); } } return result0; } function parse_UTF8_CONT() { var result0; if (/^[\x80-\xBF]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[\\x80-\\xBF]"); } } return result0; } function parse_LHEX() { var result0; result0 = parse_DIGIT(); if (result0 === null) { if (/^[a-f]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[a-f]"); } } } return result0; } function parse_token() { var result0, result1; var pos0; pos0 = pos; result1 = parse_alphanum(); if (result1 === null) { if (input.charCodeAt(pos) === 45) { result1 = "-"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 33) { result1 = "!"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 37) { result1 = "%"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"%\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 42) { result1 = "*"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 95) { result1 = "_"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 96) { result1 = "`"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"`\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 39) { result1 = "'"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 126) { result1 = "~"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"~\""); } } } } } } } } } } } } if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_alphanum(); if (result1 === null) { if (input.charCodeAt(pos) === 45) { result1 = "-"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 33) { result1 = "!"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 37) { result1 = "%"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"%\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 42) { result1 = "*"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 95) { result1 = "_"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 96) { result1 = "`"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"`\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 39) { result1 = "'"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 126) { result1 = "~"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"~\""); } } } } } } } } } } } } } } else { result0 = null; } if (result0 !== null) { result0 = function (offset) { return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_token_nodot() { var result0, result1; var pos0; pos0 = pos; result1 = parse_alphanum(); if (result1 === null) { if (input.charCodeAt(pos) === 45) { result1 = "-"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 33) { result1 = "!"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 37) { result1 = "%"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"%\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 42) { result1 = "*"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 95) { result1 = "_"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 96) { result1 = "`"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"`\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 39) { result1 = "'"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 126) { result1 = "~"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"~\""); } } } } } } } } } } } if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_alphanum(); if (result1 === null) { if (input.charCodeAt(pos) === 45) { result1 = "-"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 33) { result1 = "!"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 37) { result1 = "%"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"%\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 42) { result1 = "*"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 95) { result1 = "_"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 96) { result1 = "`"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"`\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 39) { result1 = "'"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 126) { result1 = "~"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"~\""); } } } } } } } } } } } } } else { result0 = null; } if (result0 !== null) { result0 = function (offset) { return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_separators() { var result0; if (input.charCodeAt(pos) === 40) { result0 = "("; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"(\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 41) { result0 = ")"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 60) { result0 = "<"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"<\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 62) { result0 = ">"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\">\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 64) { result0 = "@"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 44) { result0 = ","; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 59) { result0 = ";"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 58) { result0 = ":"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 92) { result0 = "\\"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"\\\\\""); } } if (result0 === null) { result0 = parse_DQUOTE(); if (result0 === null) { if (input.charCodeAt(pos) === 47) { result0 = "/"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 91) { result0 = "["; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"[\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 93) { result0 = "]"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"]\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 63) { result0 = "?"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 61) { result0 = "="; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 123) { result0 = "{"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"{\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 125) { result0 = "}"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"}\""); } } if (result0 === null) { result0 = parse_SP(); if (result0 === null) { result0 = parse_HTAB(); } } } } } } } } } } } } } } } } } } return result0; } function parse_word() { var result0, result1; var pos0; pos0 = pos; result1 = parse_alphanum(); if (result1 === null) { if (input.charCodeAt(pos) === 45) { result1 = "-"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 33) { result1 = "!"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 37) { result1 = "%"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"%\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 42) { result1 = "*"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 95) { result1 = "_"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 96) { result1 = "`"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"`\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 39) { result1 = "'"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 126) { result1 = "~"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"~\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 40) { result1 = "("; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"(\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 41) { result1 = ")"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 60) { result1 = "<"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"<\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 62) { result1 = ">"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\">\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 92) { result1 = "\\"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"\\\\\""); } } if (result1 === null) { result1 = parse_DQUOTE(); if (result1 === null) { if (input.charCodeAt(pos) === 47) { result1 = "/"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 91) { result1 = "["; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"[\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 93) { result1 = "]"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"]\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 63) { result1 = "?"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 123) { result1 = "{"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"{\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 125) { result1 = "}"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"}\""); } } } } } } } } } } } } } } } } } } } } } } } } } if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_alphanum(); if (result1 === null) { if (input.charCodeAt(pos) === 45) { result1 = "-"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 33) { result1 = "!"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 37) { result1 = "%"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"%\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 42) { result1 = "*"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 95) { result1 = "_"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 96) { result1 = "`"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"`\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 39) { result1 = "'"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"'\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 126) { result1 = "~"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"~\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 40) { result1 = "("; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"(\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 41) { result1 = ")"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 60) { result1 = "<"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"<\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 62) { result1 = ">"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\">\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 92) { result1 = "\\"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"\\\\\""); } } if (result1 === null) { result1 = parse_DQUOTE(); if (result1 === null) { if (input.charCodeAt(pos) === 47) { result1 = "/"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 91) { result1 = "["; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"[\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 93) { result1 = "]"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"]\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 63) { result1 = "?"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 123) { result1 = "{"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"{\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 125) { result1 = "}"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"}\""); } } } } } } } } } } } } } } } } } } } } } } } } } } } else { result0 = null; } if (result0 !== null) { result0 = function (offset) { return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_STAR() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 42) { result1 = "*"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"*\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return "*"; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_SLASH() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 47) { result1 = "/"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return "/"; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_EQUAL() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return "="; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_LPAREN() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 40) { result1 = "("; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"(\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return "("; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_RPAREN() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 41) { result1 = ")"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\")\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return ")"; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_RAQUOT() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 62) { result0 = ">"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\">\""); } } if (result0 !== null) { result1 = parse_SWS(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return ">"; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_LAQUOT() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 60) { result1 = "<"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"<\""); } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return "<"; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_COMMA() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 44) { result1 = ","; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return ","; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_SEMI() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 59) { result1 = ";"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return ";"; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_COLON() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_SWS(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return ":"; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_LDQUOT() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { result1 = parse_DQUOTE(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return "\""; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_RDQUOT() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_DQUOTE(); if (result0 !== null) { result1 = parse_SWS(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return "\""; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_comment() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_LPAREN(); if (result0 !== null) { result1 = []; result2 = parse_ctext(); if (result2 === null) { result2 = parse_quoted_pair(); if (result2 === null) { result2 = parse_comment(); } } while (result2 !== null) { result1.push(result2); result2 = parse_ctext(); if (result2 === null) { result2 = parse_quoted_pair(); if (result2 === null) { result2 = parse_comment(); } } } if (result1 !== null) { result2 = parse_RPAREN(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_ctext() { var result0; if (/^[!-']/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[!-']"); } } if (result0 === null) { if (/^[*-[]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[*-[]"); } } if (result0 === null) { if (/^[\]-~]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[\\]-~]"); } } if (result0 === null) { result0 = parse_UTF8_NONASCII(); if (result0 === null) { result0 = parse_LWS(); } } } } return result0; } function parse_quoted_string() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { result1 = parse_DQUOTE(); if (result1 !== null) { result2 = []; result3 = parse_qdtext(); if (result3 === null) { result3 = parse_quoted_pair(); } while (result3 !== null) { result2.push(result3); result3 = parse_qdtext(); if (result3 === null) { result3 = parse_quoted_pair(); } } if (result2 !== null) { result3 = parse_DQUOTE(); if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_quoted_string_clean() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_SWS(); if (result0 !== null) { result1 = parse_DQUOTE(); if (result1 !== null) { result2 = []; result3 = parse_qdtext(); if (result3 === null) { result3 = parse_quoted_pair(); } while (result3 !== null) { result2.push(result3); result3 = parse_qdtext(); if (result3 === null) { result3 = parse_quoted_pair(); } } if (result2 !== null) { result3 = parse_DQUOTE(); if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return input.substring(pos - 1, offset + 1); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_qdtext() { var result0; result0 = parse_LWS(); if (result0 === null) { if (input.charCodeAt(pos) === 33) { result0 = "!"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"!\""); } } if (result0 === null) { if (/^[#-[]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[#-[]"); } } if (result0 === null) { if (/^[\]-~]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[\\]-~]"); } } if (result0 === null) { result0 = parse_UTF8_NONASCII(); } } } } return result0; } function parse_quoted_pair() { var result0, result1; var pos0; pos0 = pos; if (input.charCodeAt(pos) === 92) { result0 = "\\"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"\\\\\""); } } if (result0 !== null) { if (/^[\0-\t]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[\\0-\\t]"); } } if (result1 === null) { if (/^[\x0B-\f]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[\\x0B-\\f]"); } } if (result1 === null) { if (/^[\x0E-]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[\\x0E-]"); } } } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_SIP_URI_noparams() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_uri_scheme(); if (result0 !== null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_userinfo(); result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result3 = parse_hostport(); if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { try { data.uri = new URI(data.scheme, data.user, data.host, data.port); delete data.scheme; delete data.user; delete data.host; delete data.host_type; delete data.port; } catch (e) { data = -1; } }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_SIP_URI() { var result0, result1, result2, result3, result4, result5; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_uri_scheme(); if (result0 !== null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_userinfo(); result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result3 = parse_hostport(); if (result3 !== null) { result4 = parse_uri_parameters(); if (result4 !== null) { result5 = parse_headers(); result5 = result5 !== null ? result5 : ""; if (result5 !== null) { result0 = [result0, result1, result2, result3, result4, result5]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { var header; try { data.uri = new URI(data.scheme, data.user, data.host, data.port, data.uri_params, data.uri_headers); delete data.scheme; delete data.user; delete data.host; delete data.host_type; delete data.port; delete data.uri_params; if (startRule === 'SIP_URI') { data = data.uri; } } catch (e) { data = -1; } }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_uri_scheme() { var result0; result0 = parse_uri_scheme_sips(); if (result0 === null) { result0 = parse_uri_scheme_sip(); } return result0; } function parse_uri_scheme_sips() { var result0; var pos0; pos0 = pos; if (input.substr(pos, 4).toLowerCase() === "sips") { result0 = input.substr(pos, 4); pos += 4; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"sips\""); } } if (result0 !== null) { result0 = function (offset, scheme) { data.scheme = scheme.toLowerCase(); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_uri_scheme_sip() { var result0; var pos0; pos0 = pos; if (input.substr(pos, 3).toLowerCase() === "sip") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"sip\""); } } if (result0 !== null) { result0 = function (offset, scheme) { data.scheme = scheme.toLowerCase(); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_userinfo() { var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_user(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_password(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { if (input.charCodeAt(pos) === 64) { result2 = "@"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { data.user = decodeURIComponent(input.substring(pos - 1, offset)); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_user() { var result0, result1; result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); if (result1 === null) { result1 = parse_user_unreserved(); } } if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); if (result1 === null) { result1 = parse_user_unreserved(); } } } } else { result0 = null; } return result0; } function parse_user_unreserved() { var result0; if (input.charCodeAt(pos) === 38) { result0 = "&"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 61) { result0 = "="; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 43) { result0 = "+"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 36) { result0 = "$"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 44) { result0 = ","; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 59) { result0 = ";"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 63) { result0 = "?"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 47) { result0 = "/"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } } } } } } } } return result0; } function parse_password() { var result0, result1; var pos0; pos0 = pos; result0 = []; result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); if (result1 === null) { if (input.charCodeAt(pos) === 38) { result1 = "&"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 36) { result1 = "$"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 44) { result1 = ","; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\",\""); } } } } } } } } while (result1 !== null) { result0.push(result1); result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); if (result1 === null) { if (input.charCodeAt(pos) === 38) { result1 = "&"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 36) { result1 = "$"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 44) { result1 = ","; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\",\""); } } } } } } } } } if (result0 !== null) { result0 = function (offset) { data.password = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_hostport() { var result0, result1, result2; var pos0, pos1; pos0 = pos; result0 = parse_host(); if (result0 !== null) { pos1 = pos; if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_port(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos1; } } else { result1 = null; pos = pos1; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_host() { var result0; var pos0; pos0 = pos; result0 = parse_hostname(); if (result0 === null) { result0 = parse_IPv4address(); if (result0 === null) { result0 = parse_IPv6reference(); } } if (result0 !== null) { result0 = function (offset) { data.host = input.substring(pos, offset).toLowerCase(); return data.host; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_hostname() { var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = []; pos2 = pos; result1 = parse_domainlabel(); if (result1 !== null) { if (input.charCodeAt(pos) === 46) { result2 = "."; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } while (result1 !== null) { result0.push(result1); pos2 = pos; result1 = parse_domainlabel(); if (result1 !== null) { if (input.charCodeAt(pos) === 46) { result2 = "."; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } } if (result0 !== null) { result1 = parse_toplabel(); if (result1 !== null) { if (input.charCodeAt(pos) === 46) { result2 = "."; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\".\""); } } result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { data.host_type = 'domain'; return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_domainlabel() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_alphanum(); if (result0 !== null) { result1 = []; result2 = parse_alphanum(); if (result2 === null) { if (input.charCodeAt(pos) === 45) { result2 = "-"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result2 === null) { if (input.charCodeAt(pos) === 95) { result2 = "_"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } } } while (result2 !== null) { result1.push(result2); result2 = parse_alphanum(); if (result2 === null) { if (input.charCodeAt(pos) === 45) { result2 = "-"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result2 === null) { if (input.charCodeAt(pos) === 95) { result2 = "_"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } } } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_toplabel() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_ALPHA(); if (result0 !== null) { result1 = []; result2 = parse_alphanum(); if (result2 === null) { if (input.charCodeAt(pos) === 45) { result2 = "-"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result2 === null) { if (input.charCodeAt(pos) === 95) { result2 = "_"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } } } while (result2 !== null) { result1.push(result2); result2 = parse_alphanum(); if (result2 === null) { if (input.charCodeAt(pos) === 45) { result2 = "-"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result2 === null) { if (input.charCodeAt(pos) === 95) { result2 = "_"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"_\""); } } } } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_IPv6reference() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 91) { result0 = "["; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"[\""); } } if (result0 !== null) { result1 = parse_IPv6address(); if (result1 !== null) { if (input.charCodeAt(pos) === 93) { result2 = "]"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"]\""); } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { data.host_type = 'IPv6'; return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_IPv6address() { var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_h16(); if (result0 !== null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { if (input.charCodeAt(pos) === 58) { result3 = ":"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result3 !== null) { result4 = parse_h16(); if (result4 !== null) { if (input.charCodeAt(pos) === 58) { result5 = ":"; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result5 !== null) { result6 = parse_h16(); if (result6 !== null) { if (input.charCodeAt(pos) === 58) { result7 = ":"; pos++; } else { result7 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result7 !== null) { result8 = parse_h16(); if (result8 !== null) { if (input.charCodeAt(pos) === 58) { result9 = ":"; pos++; } else { result9 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result9 !== null) { result10 = parse_h16(); if (result10 !== null) { if (input.charCodeAt(pos) === 58) { result11 = ":"; pos++; } else { result11 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result11 !== null) { result12 = parse_ls32(); if (result12 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; if (input.substr(pos, 2) === "::") { result0 = "::"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result0 !== null) { result1 = parse_h16(); if (result1 !== null) { if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { if (input.charCodeAt(pos) === 58) { result4 = ":"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result4 !== null) { result5 = parse_h16(); if (result5 !== null) { if (input.charCodeAt(pos) === 58) { result6 = ":"; pos++; } else { result6 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result6 !== null) { result7 = parse_h16(); if (result7 !== null) { if (input.charCodeAt(pos) === 58) { result8 = ":"; pos++; } else { result8 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result8 !== null) { result9 = parse_h16(); if (result9 !== null) { if (input.charCodeAt(pos) === 58) { result10 = ":"; pos++; } else { result10 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result10 !== null) { result11 = parse_ls32(); if (result11 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; if (input.substr(pos, 2) === "::") { result0 = "::"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result0 !== null) { result1 = parse_h16(); if (result1 !== null) { if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { if (input.charCodeAt(pos) === 58) { result4 = ":"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result4 !== null) { result5 = parse_h16(); if (result5 !== null) { if (input.charCodeAt(pos) === 58) { result6 = ":"; pos++; } else { result6 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result6 !== null) { result7 = parse_h16(); if (result7 !== null) { if (input.charCodeAt(pos) === 58) { result8 = ":"; pos++; } else { result8 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result8 !== null) { result9 = parse_ls32(); if (result9 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; if (input.substr(pos, 2) === "::") { result0 = "::"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result0 !== null) { result1 = parse_h16(); if (result1 !== null) { if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { if (input.charCodeAt(pos) === 58) { result4 = ":"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result4 !== null) { result5 = parse_h16(); if (result5 !== null) { if (input.charCodeAt(pos) === 58) { result6 = ":"; pos++; } else { result6 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result6 !== null) { result7 = parse_ls32(); if (result7 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; if (input.substr(pos, 2) === "::") { result0 = "::"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result0 !== null) { result1 = parse_h16(); if (result1 !== null) { if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { if (input.charCodeAt(pos) === 58) { result4 = ":"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result4 !== null) { result5 = parse_ls32(); if (result5 !== null) { result0 = [result0, result1, result2, result3, result4, result5]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; if (input.substr(pos, 2) === "::") { result0 = "::"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result0 !== null) { result1 = parse_h16(); if (result1 !== null) { if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_ls32(); if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; if (input.substr(pos, 2) === "::") { result0 = "::"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result0 !== null) { result1 = parse_ls32(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; if (input.substr(pos, 2) === "::") { result0 = "::"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result0 !== null) { result1 = parse_h16(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; result0 = parse_h16(); if (result0 !== null) { if (input.substr(pos, 2) === "::") { result1 = "::"; pos += 2; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { if (input.charCodeAt(pos) === 58) { result3 = ":"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result3 !== null) { result4 = parse_h16(); if (result4 !== null) { if (input.charCodeAt(pos) === 58) { result5 = ":"; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result5 !== null) { result6 = parse_h16(); if (result6 !== null) { if (input.charCodeAt(pos) === 58) { result7 = ":"; pos++; } else { result7 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result7 !== null) { result8 = parse_h16(); if (result8 !== null) { if (input.charCodeAt(pos) === 58) { result9 = ":"; pos++; } else { result9 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result9 !== null) { result10 = parse_ls32(); if (result10 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; result0 = parse_h16(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { if (input.substr(pos, 2) === "::") { result2 = "::"; pos += 2; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { if (input.charCodeAt(pos) === 58) { result4 = ":"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result4 !== null) { result5 = parse_h16(); if (result5 !== null) { if (input.charCodeAt(pos) === 58) { result6 = ":"; pos++; } else { result6 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result6 !== null) { result7 = parse_h16(); if (result7 !== null) { if (input.charCodeAt(pos) === 58) { result8 = ":"; pos++; } else { result8 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result8 !== null) { result9 = parse_ls32(); if (result9 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; result0 = parse_h16(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } result2 = result2 !== null ? result2 : ""; if (result2 !== null) { if (input.substr(pos, 2) === "::") { result3 = "::"; pos += 2; } else { result3 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result3 !== null) { result4 = parse_h16(); if (result4 !== null) { if (input.charCodeAt(pos) === 58) { result5 = ":"; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result5 !== null) { result6 = parse_h16(); if (result6 !== null) { if (input.charCodeAt(pos) === 58) { result7 = ":"; pos++; } else { result7 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result7 !== null) { result8 = parse_ls32(); if (result8 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; result0 = parse_h16(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } result2 = result2 !== null ? result2 : ""; if (result2 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result3 = ":"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result3 !== null) { result4 = parse_h16(); if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos2; } } else { result3 = null; pos = pos2; } result3 = result3 !== null ? result3 : ""; if (result3 !== null) { if (input.substr(pos, 2) === "::") { result4 = "::"; pos += 2; } else { result4 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result4 !== null) { result5 = parse_h16(); if (result5 !== null) { if (input.charCodeAt(pos) === 58) { result6 = ":"; pos++; } else { result6 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result6 !== null) { result7 = parse_ls32(); if (result7 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; result0 = parse_h16(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } result2 = result2 !== null ? result2 : ""; if (result2 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result3 = ":"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result3 !== null) { result4 = parse_h16(); if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos2; } } else { result3 = null; pos = pos2; } result3 = result3 !== null ? result3 : ""; if (result3 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result4 = ":"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result4 !== null) { result5 = parse_h16(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos2; } } else { result4 = null; pos = pos2; } result4 = result4 !== null ? result4 : ""; if (result4 !== null) { if (input.substr(pos, 2) === "::") { result5 = "::"; pos += 2; } else { result5 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result5 !== null) { result6 = parse_ls32(); if (result6 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; result0 = parse_h16(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } result2 = result2 !== null ? result2 : ""; if (result2 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result3 = ":"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result3 !== null) { result4 = parse_h16(); if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos2; } } else { result3 = null; pos = pos2; } result3 = result3 !== null ? result3 : ""; if (result3 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result4 = ":"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result4 !== null) { result5 = parse_h16(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos2; } } else { result4 = null; pos = pos2; } result4 = result4 !== null ? result4 : ""; if (result4 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result5 = ":"; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result5 !== null) { result6 = parse_h16(); if (result6 !== null) { result5 = [result5, result6]; } else { result5 = null; pos = pos2; } } else { result5 = null; pos = pos2; } result5 = result5 !== null ? result5 : ""; if (result5 !== null) { if (input.substr(pos, 2) === "::") { result6 = "::"; pos += 2; } else { result6 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result6 !== null) { result7 = parse_h16(); if (result7 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { pos1 = pos; result0 = parse_h16(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result2 = ":"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result2 !== null) { result3 = parse_h16(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } result2 = result2 !== null ? result2 : ""; if (result2 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result3 = ":"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result3 !== null) { result4 = parse_h16(); if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos2; } } else { result3 = null; pos = pos2; } result3 = result3 !== null ? result3 : ""; if (result3 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result4 = ":"; pos++; } else { result4 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result4 !== null) { result5 = parse_h16(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos2; } } else { result4 = null; pos = pos2; } result4 = result4 !== null ? result4 : ""; if (result4 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result5 = ":"; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result5 !== null) { result6 = parse_h16(); if (result6 !== null) { result5 = [result5, result6]; } else { result5 = null; pos = pos2; } } else { result5 = null; pos = pos2; } result5 = result5 !== null ? result5 : ""; if (result5 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 58) { result6 = ":"; pos++; } else { result6 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result6 !== null) { result7 = parse_h16(); if (result7 !== null) { result6 = [result6, result7]; } else { result6 = null; pos = pos2; } } else { result6 = null; pos = pos2; } result6 = result6 !== null ? result6 : ""; if (result6 !== null) { if (input.substr(pos, 2) === "::") { result7 = "::"; pos += 2; } else { result7 = null; if (reportFailures === 0) { matchFailed("\"::\""); } } if (result7 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } } } } } } } } } } } } } } if (result0 !== null) { result0 = function (offset) { data.host_type = 'IPv6'; return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_h16() { var result0, result1, result2, result3; var pos0; pos0 = pos; result0 = parse_HEXDIG(); if (result0 !== null) { result1 = parse_HEXDIG(); result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result2 = parse_HEXDIG(); result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result3 = parse_HEXDIG(); result3 = result3 !== null ? result3 : ""; if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_ls32() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_h16(); if (result0 !== null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_h16(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } if (result0 === null) { result0 = parse_IPv4address(); } return result0; } function parse_IPv4address() { var result0, result1, result2, result3, result4, result5, result6; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_dec_octet(); if (result0 !== null) { if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result1 !== null) { result2 = parse_dec_octet(); if (result2 !== null) { if (input.charCodeAt(pos) === 46) { result3 = "."; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result3 !== null) { result4 = parse_dec_octet(); if (result4 !== null) { if (input.charCodeAt(pos) === 46) { result5 = "."; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result5 !== null) { result6 = parse_dec_octet(); if (result6 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { data.host_type = 'IPv4'; return input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_dec_octet() { var result0, result1, result2; var pos0; pos0 = pos; if (input.substr(pos, 2) === "25") { result0 = "25"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"25\""); } } if (result0 !== null) { if (/^[0-5]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[0-5]"); } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } if (result0 === null) { pos0 = pos; if (input.charCodeAt(pos) === 50) { result0 = "2"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"2\""); } } if (result0 !== null) { if (/^[0-4]/.test(input.charAt(pos))) { result1 = input.charAt(pos); pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("[0-4]"); } } if (result1 !== null) { result2 = parse_DIGIT(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } if (result0 === null) { pos0 = pos; if (input.charCodeAt(pos) === 49) { result0 = "1"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"1\""); } } if (result0 !== null) { result1 = parse_DIGIT(); if (result1 !== null) { result2 = parse_DIGIT(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } if (result0 === null) { pos0 = pos; if (/^[1-9]/.test(input.charAt(pos))) { result0 = input.charAt(pos); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("[1-9]"); } } if (result0 !== null) { result1 = parse_DIGIT(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } if (result0 === null) { result0 = parse_DIGIT(); } } } } return result0; } function parse_port() { var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_DIGIT(); result0 = result0 !== null ? result0 : ""; if (result0 !== null) { result1 = parse_DIGIT(); result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result2 = parse_DIGIT(); result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result3 = parse_DIGIT(); result3 = result3 !== null ? result3 : ""; if (result3 !== null) { result4 = parse_DIGIT(); result4 = result4 !== null ? result4 : ""; if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, port) { port = parseInt(port.join('')); data.port = port; return port; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_uri_parameters() { var result0, result1, result2; var pos0; result0 = []; pos0 = pos; if (input.charCodeAt(pos) === 59) { result1 = ";"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result1 !== null) { result2 = parse_uri_parameter(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos0; } } else { result1 = null; pos = pos0; } while (result1 !== null) { result0.push(result1); pos0 = pos; if (input.charCodeAt(pos) === 59) { result1 = ";"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result1 !== null) { result2 = parse_uri_parameter(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos0; } } else { result1 = null; pos = pos0; } } return result0; } function parse_uri_parameter() { var result0; result0 = parse_transport_param(); if (result0 === null) { result0 = parse_user_param(); if (result0 === null) { result0 = parse_method_param(); if (result0 === null) { result0 = parse_ttl_param(); if (result0 === null) { result0 = parse_maddr_param(); if (result0 === null) { result0 = parse_lr_param(); if (result0 === null) { result0 = parse_other_param(); } } } } } } return result0; } function parse_transport_param() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 10).toLowerCase() === "transport=") { result0 = input.substr(pos, 10); pos += 10; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"transport=\""); } } if (result0 !== null) { if (input.substr(pos, 3).toLowerCase() === "udp") { result1 = input.substr(pos, 3); pos += 3; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"udp\""); } } if (result1 === null) { if (input.substr(pos, 3).toLowerCase() === "tcp") { result1 = input.substr(pos, 3); pos += 3; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"tcp\""); } } if (result1 === null) { if (input.substr(pos, 4).toLowerCase() === "sctp") { result1 = input.substr(pos, 4); pos += 4; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"sctp\""); } } if (result1 === null) { if (input.substr(pos, 3).toLowerCase() === "tls") { result1 = input.substr(pos, 3); pos += 3; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"tls\""); } } if (result1 === null) { result1 = parse_token(); } } } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, transport) { if (!data.uri_params) data.uri_params = {}; data.uri_params['transport'] = transport.toLowerCase(); }(pos0, result0[1]); } if (result0 === null) { pos = pos0; } return result0; } function parse_user_param() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 5).toLowerCase() === "user=") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"user=\""); } } if (result0 !== null) { if (input.substr(pos, 5).toLowerCase() === "phone") { result1 = input.substr(pos, 5); pos += 5; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"phone\""); } } if (result1 === null) { if (input.substr(pos, 2).toLowerCase() === "ip") { result1 = input.substr(pos, 2); pos += 2; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"ip\""); } } if (result1 === null) { result1 = parse_token(); } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, user) { if (!data.uri_params) data.uri_params = {}; data.uri_params['user'] = user.toLowerCase(); }(pos0, result0[1]); } if (result0 === null) { pos = pos0; } return result0; } function parse_method_param() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 7).toLowerCase() === "method=") { result0 = input.substr(pos, 7); pos += 7; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"method=\""); } } if (result0 !== null) { result1 = parse_Method(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, method) { if (!data.uri_params) data.uri_params = {}; data.uri_params['method'] = method; }(pos0, result0[1]); } if (result0 === null) { pos = pos0; } return result0; } function parse_ttl_param() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 4).toLowerCase() === "ttl=") { result0 = input.substr(pos, 4); pos += 4; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"ttl=\""); } } if (result0 !== null) { result1 = parse_ttl(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, ttl) { if (!data.params) data.params = {}; data.params['ttl'] = ttl; }(pos0, result0[1]); } if (result0 === null) { pos = pos0; } return result0; } function parse_maddr_param() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 6).toLowerCase() === "maddr=") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"maddr=\""); } } if (result0 !== null) { result1 = parse_host(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, maddr) { if (!data.uri_params) data.uri_params = {}; data.uri_params['maddr'] = maddr; }(pos0, result0[1]); } if (result0 === null) { pos = pos0; } return result0; } function parse_lr_param() { var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; if (input.substr(pos, 2).toLowerCase() === "lr") { result0 = input.substr(pos, 2); pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"lr\""); } } if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 !== null) { result2 = parse_token(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { if (!data.uri_params) data.uri_params = {}; data.uri_params['lr'] = undefined; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_other_param() { var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_pname(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 !== null) { result2 = parse_pvalue(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, param, value) { if (!data.uri_params) data.uri_params = {}; if (typeof value === 'undefined') { value = undefined; } else { value = value[1]; } data.uri_params[param.toLowerCase()] = value; }(pos0, result0[0], result0[1]); } if (result0 === null) { pos = pos0; } return result0; } function parse_pname() { var result0, result1; var pos0; pos0 = pos; result1 = parse_paramchar(); if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_paramchar(); } } else { result0 = null; } if (result0 !== null) { result0 = function (offset, pname) { return pname.join(''); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_pvalue() { var result0, result1; var pos0; pos0 = pos; result1 = parse_paramchar(); if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_paramchar(); } } else { result0 = null; } if (result0 !== null) { result0 = function (offset, pvalue) { return pvalue.join(''); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_paramchar() { var result0; result0 = parse_param_unreserved(); if (result0 === null) { result0 = parse_unreserved(); if (result0 === null) { result0 = parse_escaped(); } } return result0; } function parse_param_unreserved() { var result0; if (input.charCodeAt(pos) === 91) { result0 = "["; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"[\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 93) { result0 = "]"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"]\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 47) { result0 = "/"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 58) { result0 = ":"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 38) { result0 = "&"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 43) { result0 = "+"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 36) { result0 = "$"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } } } } } } } return result0; } function parse_headers() { var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; if (input.charCodeAt(pos) === 63) { result0 = "?"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result0 !== null) { result1 = parse_header(); if (result1 !== null) { result2 = []; pos1 = pos; if (input.charCodeAt(pos) === 38) { result3 = "&"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result3 !== null) { result4 = parse_header(); if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos1; } } else { result3 = null; pos = pos1; } while (result3 !== null) { result2.push(result3); pos1 = pos; if (input.charCodeAt(pos) === 38) { result3 = "&"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result3 !== null) { result4 = parse_header(); if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos1; } } else { result3 = null; pos = pos1; } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_header() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_hname(); if (result0 !== null) { if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 !== null) { result2 = parse_hvalue(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, hname, hvalue) { hname = hname.join('').toLowerCase(); hvalue = hvalue.join(''); if (!data.uri_headers) data.uri_headers = {}; if (!data.uri_headers[hname]) { data.uri_headers[hname] = [hvalue]; } else { data.uri_headers[hname].push(hvalue); } }(pos0, result0[0], result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_hname() { var result0, result1; result1 = parse_hnv_unreserved(); if (result1 === null) { result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); } } if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_hnv_unreserved(); if (result1 === null) { result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); } } } } else { result0 = null; } return result0; } function parse_hvalue() { var result0, result1; result0 = []; result1 = parse_hnv_unreserved(); if (result1 === null) { result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); } } while (result1 !== null) { result0.push(result1); result1 = parse_hnv_unreserved(); if (result1 === null) { result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); } } } return result0; } function parse_hnv_unreserved() { var result0; if (input.charCodeAt(pos) === 91) { result0 = "["; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"[\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 93) { result0 = "]"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"]\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 47) { result0 = "/"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 63) { result0 = "?"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 58) { result0 = ":"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 43) { result0 = "+"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 36) { result0 = "$"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } } } } } } } return result0; } function parse_Request_Response() { var result0; result0 = parse_Status_Line(); if (result0 === null) { result0 = parse_Request_Line(); } return result0; } function parse_Request_Line() { var result0, result1, result2, result3, result4; var pos0; pos0 = pos; result0 = parse_Method(); if (result0 !== null) { result1 = parse_SP(); if (result1 !== null) { result2 = parse_Request_URI(); if (result2 !== null) { result3 = parse_SP(); if (result3 !== null) { result4 = parse_SIP_Version(); if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Request_URI() { var result0; result0 = parse_SIP_URI(); if (result0 === null) { result0 = parse_absoluteURI(); } return result0; } function parse_absoluteURI() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_scheme(); if (result0 !== null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 !== null) { result2 = parse_hier_part(); if (result2 === null) { result2 = parse_opaque_part(); } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_hier_part() { var result0, result1, result2; var pos0, pos1; pos0 = pos; result0 = parse_net_path(); if (result0 === null) { result0 = parse_abs_path(); } if (result0 !== null) { pos1 = pos; if (input.charCodeAt(pos) === 63) { result1 = "?"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result1 !== null) { result2 = parse_query(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos1; } } else { result1 = null; pos = pos1; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_net_path() { var result0, result1, result2; var pos0; pos0 = pos; if (input.substr(pos, 2) === "//") { result0 = "//"; pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"//\""); } } if (result0 !== null) { result1 = parse_authority(); if (result1 !== null) { result2 = parse_abs_path(); result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_abs_path() { var result0, result1; var pos0; pos0 = pos; if (input.charCodeAt(pos) === 47) { result0 = "/"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result0 !== null) { result1 = parse_path_segments(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_opaque_part() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_uric_no_slash(); if (result0 !== null) { result1 = []; result2 = parse_uric(); while (result2 !== null) { result1.push(result2); result2 = parse_uric(); } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_uric() { var result0; result0 = parse_reserved(); if (result0 === null) { result0 = parse_unreserved(); if (result0 === null) { result0 = parse_escaped(); } } return result0; } function parse_uric_no_slash() { var result0; result0 = parse_unreserved(); if (result0 === null) { result0 = parse_escaped(); if (result0 === null) { if (input.charCodeAt(pos) === 59) { result0 = ";"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 63) { result0 = "?"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"?\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 58) { result0 = ":"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 64) { result0 = "@"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 38) { result0 = "&"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 61) { result0 = "="; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 43) { result0 = "+"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 36) { result0 = "$"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 44) { result0 = ","; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\",\""); } } } } } } } } } } } } return result0; } function parse_path_segments() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_segment(); if (result0 !== null) { result1 = []; pos1 = pos; if (input.charCodeAt(pos) === 47) { result2 = "/"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result2 !== null) { result3 = parse_segment(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; if (input.charCodeAt(pos) === 47) { result2 = "/"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result2 !== null) { result3 = parse_segment(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_segment() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = []; result1 = parse_pchar(); while (result1 !== null) { result0.push(result1); result1 = parse_pchar(); } if (result0 !== null) { result1 = []; pos1 = pos; if (input.charCodeAt(pos) === 59) { result2 = ";"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result2 !== null) { result3 = parse_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; if (input.charCodeAt(pos) === 59) { result2 = ";"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result2 !== null) { result3 = parse_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_param() { var result0, result1; result0 = []; result1 = parse_pchar(); while (result1 !== null) { result0.push(result1); result1 = parse_pchar(); } return result0; } function parse_pchar() { var result0; result0 = parse_unreserved(); if (result0 === null) { result0 = parse_escaped(); if (result0 === null) { if (input.charCodeAt(pos) === 58) { result0 = ":"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 64) { result0 = "@"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 38) { result0 = "&"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 61) { result0 = "="; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 43) { result0 = "+"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 36) { result0 = "$"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } if (result0 === null) { if (input.charCodeAt(pos) === 44) { result0 = ","; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\",\""); } } } } } } } } } } return result0; } function parse_scheme() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_ALPHA(); if (result0 !== null) { result1 = []; result2 = parse_ALPHA(); if (result2 === null) { result2 = parse_DIGIT(); if (result2 === null) { if (input.charCodeAt(pos) === 43) { result2 = "+"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result2 === null) { if (input.charCodeAt(pos) === 45) { result2 = "-"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result2 === null) { if (input.charCodeAt(pos) === 46) { result2 = "."; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\".\""); } } } } } } while (result2 !== null) { result1.push(result2); result2 = parse_ALPHA(); if (result2 === null) { result2 = parse_DIGIT(); if (result2 === null) { if (input.charCodeAt(pos) === 43) { result2 = "+"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } if (result2 === null) { if (input.charCodeAt(pos) === 45) { result2 = "-"; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result2 === null) { if (input.charCodeAt(pos) === 46) { result2 = "."; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\".\""); } } } } } } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { data.scheme = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_authority() { var result0; result0 = parse_srvr(); if (result0 === null) { result0 = parse_reg_name(); } return result0; } function parse_srvr() { var result0, result1; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_userinfo(); if (result0 !== null) { if (input.charCodeAt(pos) === 64) { result1 = "@"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } result0 = result0 !== null ? result0 : ""; if (result0 !== null) { result1 = parse_hostport(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } result0 = result0 !== null ? result0 : ""; return result0; } function parse_reg_name() { var result0, result1; result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); if (result1 === null) { if (input.charCodeAt(pos) === 36) { result1 = "$"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 44) { result1 = ","; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 59) { result1 = ";"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 64) { result1 = "@"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 38) { result1 = "&"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } } } } } } } } } } if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); if (result1 === null) { if (input.charCodeAt(pos) === 36) { result1 = "$"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"$\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 44) { result1 = ","; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 59) { result1 = ";"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\";\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 58) { result1 = ":"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\":\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 64) { result1 = "@"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 38) { result1 = "&"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"&\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 61) { result1 = "="; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"=\""); } } if (result1 === null) { if (input.charCodeAt(pos) === 43) { result1 = "+"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"+\""); } } } } } } } } } } } } } else { result0 = null; } return result0; } function parse_query() { var result0, result1; result0 = []; result1 = parse_uric(); while (result1 !== null) { result0.push(result1); result1 = parse_uric(); } return result0; } function parse_SIP_Version() { var result0, result1, result2, result3, result4, result5; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 3).toLowerCase() === "sip") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"SIP\""); } } if (result0 !== null) { if (input.charCodeAt(pos) === 47) { result1 = "/"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"/\""); } } if (result1 !== null) { result3 = parse_DIGIT(); if (result3 !== null) { result2 = []; while (result3 !== null) { result2.push(result3); result3 = parse_DIGIT(); } } else { result2 = null; } if (result2 !== null) { if (input.charCodeAt(pos) === 46) { result3 = "."; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result3 !== null) { result5 = parse_DIGIT(); if (result5 !== null) { result4 = []; while (result5 !== null) { result4.push(result5); result5 = parse_DIGIT(); } } else { result4 = null; } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { data.sip_version = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_INVITEm() { var result0; if (input.substr(pos, 6) === "INVITE") { result0 = "INVITE"; pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"INVITE\""); } } return result0; } function parse_ACKm() { var result0; if (input.substr(pos, 3) === "ACK") { result0 = "ACK"; pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"ACK\""); } } return result0; } function parse_OPTIONSm() { var result0; if (input.substr(pos, 7) === "OPTIONS") { result0 = "OPTIONS"; pos += 7; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"OPTIONS\""); } } return result0; } function parse_BYEm() { var result0; if (input.substr(pos, 3) === "BYE") { result0 = "BYE"; pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"BYE\""); } } return result0; } function parse_CANCELm() { var result0; if (input.substr(pos, 6) === "CANCEL") { result0 = "CANCEL"; pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"CANCEL\""); } } return result0; } function parse_REGISTERm() { var result0; if (input.substr(pos, 8) === "REGISTER") { result0 = "REGISTER"; pos += 8; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"REGISTER\""); } } return result0; } function parse_SUBSCRIBEm() { var result0; if (input.substr(pos, 9) === "SUBSCRIBE") { result0 = "SUBSCRIBE"; pos += 9; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"SUBSCRIBE\""); } } return result0; } function parse_NOTIFYm() { var result0; if (input.substr(pos, 6) === "NOTIFY") { result0 = "NOTIFY"; pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"NOTIFY\""); } } return result0; } function parse_REFERm() { var result0; if (input.substr(pos, 5) === "REFER") { result0 = "REFER"; pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"REFER\""); } } return result0; } function parse_Method() { var result0; var pos0; pos0 = pos; result0 = parse_INVITEm(); if (result0 === null) { result0 = parse_ACKm(); if (result0 === null) { result0 = parse_OPTIONSm(); if (result0 === null) { result0 = parse_BYEm(); if (result0 === null) { result0 = parse_CANCELm(); if (result0 === null) { result0 = parse_REGISTERm(); if (result0 === null) { result0 = parse_SUBSCRIBEm(); if (result0 === null) { result0 = parse_NOTIFYm(); if (result0 === null) { result0 = parse_REFERm(); if (result0 === null) { result0 = parse_token(); } } } } } } } } } if (result0 !== null) { result0 = function (offset) { data.method = input.substring(pos, offset); return data.method; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Status_Line() { var result0, result1, result2, result3, result4; var pos0; pos0 = pos; result0 = parse_SIP_Version(); if (result0 !== null) { result1 = parse_SP(); if (result1 !== null) { result2 = parse_Status_Code(); if (result2 !== null) { result3 = parse_SP(); if (result3 !== null) { result4 = parse_Reason_Phrase(); if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Status_Code() { var result0; var pos0; pos0 = pos; result0 = parse_extension_code(); if (result0 !== null) { result0 = function (offset, status_code) { data.status_code = parseInt(status_code.join('')); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_extension_code() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_DIGIT(); if (result0 !== null) { result1 = parse_DIGIT(); if (result1 !== null) { result2 = parse_DIGIT(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Reason_Phrase() { var result0, result1; var pos0; pos0 = pos; result0 = []; result1 = parse_reserved(); if (result1 === null) { result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); if (result1 === null) { result1 = parse_UTF8_NONASCII(); if (result1 === null) { result1 = parse_UTF8_CONT(); if (result1 === null) { result1 = parse_SP(); if (result1 === null) { result1 = parse_HTAB(); } } } } } } while (result1 !== null) { result0.push(result1); result1 = parse_reserved(); if (result1 === null) { result1 = parse_unreserved(); if (result1 === null) { result1 = parse_escaped(); if (result1 === null) { result1 = parse_UTF8_NONASCII(); if (result1 === null) { result1 = parse_UTF8_CONT(); if (result1 === null) { result1 = parse_SP(); if (result1 === null) { result1 = parse_HTAB(); } } } } } } } if (result0 !== null) { result0 = function (offset) { data.reason_phrase = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Allow_Events() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_event_type(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_event_type(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_event_type(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Call_ID() { var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_word(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 64) { result1 = "@"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result1 !== null) { result2 = parse_word(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { data = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Contact() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; result0 = parse_STAR(); if (result0 === null) { pos1 = pos; result0 = parse_contact_param(); if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_contact_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_contact_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } if (result0 !== null) { result0 = function (offset) { var idx, length; length = data.multi_header.length; for (idx = 0; idx < length; idx++) { if (data.multi_header[idx].parsed === null) { data = null; break; } } if (data !== null) { data = data.multi_header; } else { data = -1; } }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_contact_param() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_SIP_URI_noparams(); if (result0 === null) { result0 = parse_name_addr(); } if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_contact_params(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_contact_params(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { var header; if (!data.multi_header) data.multi_header = []; try { header = new NameAddrHeader(data.uri, data.display_name, data.params); delete data.uri; delete data.display_name; delete data.params; } catch (e) { header = null; } data.multi_header.push({ 'possition': pos, 'offset': offset, 'parsed': header }); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_name_addr() { var result0, result1, result2, result3; var pos0; pos0 = pos; result0 = parse_display_name(); result0 = result0 !== null ? result0 : ""; if (result0 !== null) { result1 = parse_LAQUOT(); if (result1 !== null) { result2 = parse_SIP_URI(); if (result2 !== null) { result3 = parse_RAQUOT(); if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_display_name() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_token(); if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_LWS(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_LWS(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 === null) { result0 = parse_quoted_string(); } if (result0 !== null) { result0 = function (offset, display_name) { display_name = input.substring(pos, offset).trim(); if (display_name[0] === '\"') { display_name = display_name.substring(1, display_name.length - 1); } data.display_name = display_name; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_contact_params() { var result0; result0 = parse_c_p_q(); if (result0 === null) { result0 = parse_c_p_expires(); if (result0 === null) { result0 = parse_generic_param(); } } return result0; } function parse_c_p_q() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 1).toLowerCase() === "q") { result0 = input.substr(pos, 1); pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"q\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_qvalue(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, q) { if (!data.params) data.params = {}; data.params['q'] = q; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_c_p_expires() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 7).toLowerCase() === "expires") { result0 = input.substr(pos, 7); pos += 7; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"expires\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_delta_seconds(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, expires) { if (!data.params) data.params = {}; data.params['expires'] = expires; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_delta_seconds() { var result0, result1; var pos0; pos0 = pos; result1 = parse_DIGIT(); if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_DIGIT(); } } else { result0 = null; } if (result0 !== null) { result0 = function (offset, delta_seconds) { return parseInt(delta_seconds.join('')); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_qvalue() { var result0, result1, result2, result3, result4; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; if (input.charCodeAt(pos) === 48) { result0 = "0"; pos++; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"0\""); } } if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 46) { result1 = "."; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result1 !== null) { result2 = parse_DIGIT(); result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result3 = parse_DIGIT(); result3 = result3 !== null ? result3 : ""; if (result3 !== null) { result4 = parse_DIGIT(); result4 = result4 !== null ? result4 : ""; if (result4 !== null) { result1 = [result1, result2, result3, result4]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { return parseFloat(input.substring(pos, offset)); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_generic_param() { var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_token(); if (result0 !== null) { pos2 = pos; result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_gen_value(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, param, value) { if (!data.params) data.params = {}; if (typeof value === 'undefined') { value = undefined; } else { value = value[1]; } data.params[param.toLowerCase()] = value; }(pos0, result0[0], result0[1]); } if (result0 === null) { pos = pos0; } return result0; } function parse_gen_value() { var result0; result0 = parse_token(); if (result0 === null) { result0 = parse_host(); if (result0 === null) { result0 = parse_quoted_string(); } } return result0; } function parse_Content_Disposition() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_disp_type(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_disp_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_disp_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_disp_type() { var result0; if (input.substr(pos, 6).toLowerCase() === "render") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"render\""); } } if (result0 === null) { if (input.substr(pos, 7).toLowerCase() === "session") { result0 = input.substr(pos, 7); pos += 7; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"session\""); } } if (result0 === null) { if (input.substr(pos, 4).toLowerCase() === "icon") { result0 = input.substr(pos, 4); pos += 4; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"icon\""); } } if (result0 === null) { if (input.substr(pos, 5).toLowerCase() === "alert") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"alert\""); } } if (result0 === null) { result0 = parse_token(); } } } } return result0; } function parse_disp_param() { var result0; result0 = parse_handling_param(); if (result0 === null) { result0 = parse_generic_param(); } return result0; } function parse_handling_param() { var result0, result1, result2; var pos0; pos0 = pos; if (input.substr(pos, 8).toLowerCase() === "handling") { result0 = input.substr(pos, 8); pos += 8; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"handling\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { if (input.substr(pos, 8).toLowerCase() === "optional") { result2 = input.substr(pos, 8); pos += 8; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"optional\""); } } if (result2 === null) { if (input.substr(pos, 8).toLowerCase() === "required") { result2 = input.substr(pos, 8); pos += 8; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"required\""); } } if (result2 === null) { result2 = parse_token(); } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Content_Encoding() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_token(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Content_Length() { var result0, result1; var pos0; pos0 = pos; result1 = parse_DIGIT(); if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_DIGIT(); } } else { result0 = null; } if (result0 !== null) { result0 = function (offset, length) { data = parseInt(length.join('')); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Content_Type() { var result0; var pos0; pos0 = pos; result0 = parse_media_type(); if (result0 !== null) { result0 = function (offset) { data = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_media_type() { var result0, result1, result2, result3, result4, result5; var pos0, pos1; pos0 = pos; result0 = parse_m_type(); if (result0 !== null) { result1 = parse_SLASH(); if (result1 !== null) { result2 = parse_m_subtype(); if (result2 !== null) { result3 = []; pos1 = pos; result4 = parse_SEMI(); if (result4 !== null) { result5 = parse_m_parameter(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos1; } } else { result4 = null; pos = pos1; } while (result4 !== null) { result3.push(result4); pos1 = pos; result4 = parse_SEMI(); if (result4 !== null) { result5 = parse_m_parameter(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos1; } } else { result4 = null; pos = pos1; } } if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_m_type() { var result0; result0 = parse_discrete_type(); if (result0 === null) { result0 = parse_composite_type(); } return result0; } function parse_discrete_type() { var result0; if (input.substr(pos, 4).toLowerCase() === "text") { result0 = input.substr(pos, 4); pos += 4; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"text\""); } } if (result0 === null) { if (input.substr(pos, 5).toLowerCase() === "image") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"image\""); } } if (result0 === null) { if (input.substr(pos, 5).toLowerCase() === "audio") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"audio\""); } } if (result0 === null) { if (input.substr(pos, 5).toLowerCase() === "video") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"video\""); } } if (result0 === null) { if (input.substr(pos, 11).toLowerCase() === "application") { result0 = input.substr(pos, 11); pos += 11; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"application\""); } } if (result0 === null) { result0 = parse_extension_token(); } } } } } return result0; } function parse_composite_type() { var result0; if (input.substr(pos, 7).toLowerCase() === "message") { result0 = input.substr(pos, 7); pos += 7; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"message\""); } } if (result0 === null) { if (input.substr(pos, 9).toLowerCase() === "multipart") { result0 = input.substr(pos, 9); pos += 9; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"multipart\""); } } if (result0 === null) { result0 = parse_extension_token(); } } return result0; } function parse_extension_token() { var result0; result0 = parse_token(); if (result0 === null) { result0 = parse_x_token(); } return result0; } function parse_x_token() { var result0, result1; var pos0; pos0 = pos; if (input.substr(pos, 2).toLowerCase() === "x-") { result0 = input.substr(pos, 2); pos += 2; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"x-\""); } } if (result0 !== null) { result1 = parse_token(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_m_subtype() { var result0; result0 = parse_extension_token(); if (result0 === null) { result0 = parse_token(); } return result0; } function parse_m_parameter() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_token(); if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_m_value(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_m_value() { var result0; result0 = parse_token(); if (result0 === null) { result0 = parse_quoted_string(); } return result0; } function parse_CSeq() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_CSeq_value(); if (result0 !== null) { result1 = parse_LWS(); if (result1 !== null) { result2 = parse_Method(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_CSeq_value() { var result0, result1; var pos0; pos0 = pos; result1 = parse_DIGIT(); if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_DIGIT(); } } else { result0 = null; } if (result0 !== null) { result0 = function (offset, cseq_value) { data.value = parseInt(cseq_value.join('')); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Expires() { var result0; var pos0; pos0 = pos; result0 = parse_delta_seconds(); if (result0 !== null) { result0 = function (offset, expires) { data = expires; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Event() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_event_type(); if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_generic_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_generic_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, event_type) { data.event = event_type.join('').toLowerCase(); }(pos0, result0[0]); } if (result0 === null) { pos = pos0; } return result0; } function parse_event_type() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_token_nodot(); if (result0 !== null) { result1 = []; pos1 = pos; if (input.charCodeAt(pos) === 46) { result2 = "."; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result2 !== null) { result3 = parse_token_nodot(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; if (input.charCodeAt(pos) === 46) { result2 = "."; pos++; } else { result2 = null; if (reportFailures === 0) { matchFailed("\".\""); } } if (result2 !== null) { result3 = parse_token_nodot(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_From() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_SIP_URI_noparams(); if (result0 === null) { result0 = parse_name_addr(); } if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_from_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_from_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { var tag = data.tag; try { data = new NameAddrHeader(data.uri, data.display_name, data.params); if (tag) { data.setParam('tag', tag); } } catch (e) { data = -1; } }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_from_param() { var result0; result0 = parse_tag_param(); if (result0 === null) { result0 = parse_generic_param(); } return result0; } function parse_tag_param() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 3).toLowerCase() === "tag") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"tag\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_token(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, tag) { data.tag = tag; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_Max_Forwards() { var result0, result1; var pos0; pos0 = pos; result1 = parse_DIGIT(); if (result1 !== null) { result0 = []; while (result1 !== null) { result0.push(result1); result1 = parse_DIGIT(); } } else { result0 = null; } if (result0 !== null) { result0 = function (offset, forwards) { data = parseInt(forwards.join('')); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Min_Expires() { var result0; var pos0; pos0 = pos; result0 = parse_delta_seconds(); if (result0 !== null) { result0 = function (offset, min_expires) { data = min_expires; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Name_Addr_Header() { var result0, result1, result2, result3, result4, result5, result6; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = []; result1 = parse_display_name(); while (result1 !== null) { result0.push(result1); result1 = parse_display_name(); } if (result0 !== null) { result1 = parse_LAQUOT(); if (result1 !== null) { result2 = parse_SIP_URI(); if (result2 !== null) { result3 = parse_RAQUOT(); if (result3 !== null) { result4 = []; pos2 = pos; result5 = parse_SEMI(); if (result5 !== null) { result6 = parse_generic_param(); if (result6 !== null) { result5 = [result5, result6]; } else { result5 = null; pos = pos2; } } else { result5 = null; pos = pos2; } while (result5 !== null) { result4.push(result5); pos2 = pos; result5 = parse_SEMI(); if (result5 !== null) { result6 = parse_generic_param(); if (result6 !== null) { result5 = [result5, result6]; } else { result5 = null; pos = pos2; } } else { result5 = null; pos = pos2; } } if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { try { data = new NameAddrHeader(data.uri, data.display_name, data.params); } catch (e) { data = -1; } }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Proxy_Authenticate() { var result0; result0 = parse_challenge(); return result0; } function parse_challenge() { var result0, result1, result2, result3, result4, result5; var pos0, pos1; pos0 = pos; if (input.substr(pos, 6).toLowerCase() === "digest") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"Digest\""); } } if (result0 !== null) { result1 = parse_LWS(); if (result1 !== null) { result2 = parse_digest_cln(); if (result2 !== null) { result3 = []; pos1 = pos; result4 = parse_COMMA(); if (result4 !== null) { result5 = parse_digest_cln(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos1; } } else { result4 = null; pos = pos1; } while (result4 !== null) { result3.push(result4); pos1 = pos; result4 = parse_COMMA(); if (result4 !== null) { result5 = parse_digest_cln(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos1; } } else { result4 = null; pos = pos1; } } if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } if (result0 === null) { result0 = parse_other_challenge(); } return result0; } function parse_other_challenge() { var result0, result1, result2, result3, result4, result5; var pos0, pos1; pos0 = pos; result0 = parse_token(); if (result0 !== null) { result1 = parse_LWS(); if (result1 !== null) { result2 = parse_auth_param(); if (result2 !== null) { result3 = []; pos1 = pos; result4 = parse_COMMA(); if (result4 !== null) { result5 = parse_auth_param(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos1; } } else { result4 = null; pos = pos1; } while (result4 !== null) { result3.push(result4); pos1 = pos; result4 = parse_COMMA(); if (result4 !== null) { result5 = parse_auth_param(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos1; } } else { result4 = null; pos = pos1; } } if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_auth_param() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_token(); if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_token(); if (result2 === null) { result2 = parse_quoted_string(); } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_digest_cln() { var result0; result0 = parse_realm(); if (result0 === null) { result0 = parse_domain(); if (result0 === null) { result0 = parse_nonce(); if (result0 === null) { result0 = parse_opaque(); if (result0 === null) { result0 = parse_stale(); if (result0 === null) { result0 = parse_algorithm(); if (result0 === null) { result0 = parse_qop_options(); if (result0 === null) { result0 = parse_auth_param(); } } } } } } } return result0; } function parse_realm() { var result0, result1, result2; var pos0; pos0 = pos; if (input.substr(pos, 5).toLowerCase() === "realm") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"realm\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_realm_value(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_realm_value() { var result0; var pos0; pos0 = pos; result0 = parse_quoted_string_clean(); if (result0 !== null) { result0 = function (offset, realm) { data.realm = realm; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_domain() { var result0, result1, result2, result3, result4, result5, result6; var pos0, pos1; pos0 = pos; if (input.substr(pos, 6).toLowerCase() === "domain") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"domain\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_LDQUOT(); if (result2 !== null) { result3 = parse_URI(); if (result3 !== null) { result4 = []; pos1 = pos; result6 = parse_SP(); if (result6 !== null) { result5 = []; while (result6 !== null) { result5.push(result6); result6 = parse_SP(); } } else { result5 = null; } if (result5 !== null) { result6 = parse_URI(); if (result6 !== null) { result5 = [result5, result6]; } else { result5 = null; pos = pos1; } } else { result5 = null; pos = pos1; } while (result5 !== null) { result4.push(result5); pos1 = pos; result6 = parse_SP(); if (result6 !== null) { result5 = []; while (result6 !== null) { result5.push(result6); result6 = parse_SP(); } } else { result5 = null; } if (result5 !== null) { result6 = parse_URI(); if (result6 !== null) { result5 = [result5, result6]; } else { result5 = null; pos = pos1; } } else { result5 = null; pos = pos1; } } if (result4 !== null) { result5 = parse_RDQUOT(); if (result5 !== null) { result0 = [result0, result1, result2, result3, result4, result5]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_URI() { var result0; result0 = parse_absoluteURI(); if (result0 === null) { result0 = parse_abs_path(); } return result0; } function parse_nonce() { var result0, result1, result2; var pos0; pos0 = pos; if (input.substr(pos, 5).toLowerCase() === "nonce") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"nonce\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_nonce_value(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_nonce_value() { var result0; var pos0; pos0 = pos; result0 = parse_quoted_string_clean(); if (result0 !== null) { result0 = function (offset, nonce) { data.nonce = nonce; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_opaque() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 6).toLowerCase() === "opaque") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"opaque\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_quoted_string_clean(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, opaque) { data.opaque = opaque; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_stale() { var result0, result1, result2; var pos0, pos1; pos0 = pos; if (input.substr(pos, 5).toLowerCase() === "stale") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"stale\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { pos1 = pos; if (input.substr(pos, 4).toLowerCase() === "true") { result2 = input.substr(pos, 4); pos += 4; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"true\""); } } if (result2 !== null) { result2 = function (offset) { data.stale = true; }(pos1); } if (result2 === null) { pos = pos1; } if (result2 === null) { pos1 = pos; if (input.substr(pos, 5).toLowerCase() === "false") { result2 = input.substr(pos, 5); pos += 5; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"false\""); } } if (result2 !== null) { result2 = function (offset) { data.stale = false; }(pos1); } if (result2 === null) { pos = pos1; } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_algorithm() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 9).toLowerCase() === "algorithm") { result0 = input.substr(pos, 9); pos += 9; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"algorithm\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { if (input.substr(pos, 3).toLowerCase() === "md5") { result2 = input.substr(pos, 3); pos += 3; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"MD5\""); } } if (result2 === null) { if (input.substr(pos, 8).toLowerCase() === "md5-sess") { result2 = input.substr(pos, 8); pos += 8; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"MD5-sess\""); } } if (result2 === null) { result2 = parse_token(); } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, algorithm) { data.algorithm = algorithm.toUpperCase(); }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_qop_options() { var result0, result1, result2, result3, result4, result5, result6; var pos0, pos1, pos2; pos0 = pos; if (input.substr(pos, 3).toLowerCase() === "qop") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"qop\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_LDQUOT(); if (result2 !== null) { pos1 = pos; result3 = parse_qop_value(); if (result3 !== null) { result4 = []; pos2 = pos; if (input.charCodeAt(pos) === 44) { result5 = ","; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result5 !== null) { result6 = parse_qop_value(); if (result6 !== null) { result5 = [result5, result6]; } else { result5 = null; pos = pos2; } } else { result5 = null; pos = pos2; } while (result5 !== null) { result4.push(result5); pos2 = pos; if (input.charCodeAt(pos) === 44) { result5 = ","; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\",\""); } } if (result5 !== null) { result6 = parse_qop_value(); if (result6 !== null) { result5 = [result5, result6]; } else { result5 = null; pos = pos2; } } else { result5 = null; pos = pos2; } } if (result4 !== null) { result3 = [result3, result4]; } else { result3 = null; pos = pos1; } } else { result3 = null; pos = pos1; } if (result3 !== null) { result4 = parse_RDQUOT(); if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_qop_value() { var result0; var pos0; pos0 = pos; if (input.substr(pos, 8).toLowerCase() === "auth-int") { result0 = input.substr(pos, 8); pos += 8; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"auth-int\""); } } if (result0 === null) { if (input.substr(pos, 4).toLowerCase() === "auth") { result0 = input.substr(pos, 4); pos += 4; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"auth\""); } } if (result0 === null) { result0 = parse_token(); } } if (result0 !== null) { result0 = function (offset, qop_value) { data.qop || (data.qop = []); data.qop.push(qop_value.toLowerCase()); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Proxy_Require() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_token(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Record_Route() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_rec_route(); if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_rec_route(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_rec_route(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { var idx, length; length = data.multi_header.length; for (idx = 0; idx < length; idx++) { if (data.multi_header[idx].parsed === null) { data = null; break; } } if (data !== null) { data = data.multi_header; } else { data = -1; } }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_rec_route() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_name_addr(); if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_generic_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_generic_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { var header; if (!data.multi_header) data.multi_header = []; try { header = new NameAddrHeader(data.uri, data.display_name, data.params); delete data.uri; delete data.display_name; delete data.params; } catch (e) { header = null; } data.multi_header.push({ 'possition': pos, 'offset': offset, 'parsed': header }); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Reason() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; if (input.substr(pos, 3).toLowerCase() === "sip") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"SIP\""); } } if (result0 === null) { result0 = parse_token(); } if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_reason_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_reason_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, protocol) { data.protocol = protocol.toLowerCase(); if (!data.params) data.params = {}; if (data.params.text && data.params.text[0] === '"') { var text = data.params.text; data.text = text.substring(1, text.length - 1); delete data.params.text; } }(pos0, result0[0]); } if (result0 === null) { pos = pos0; } return result0; } function parse_reason_param() { var result0; result0 = parse_reason_cause(); if (result0 === null) { result0 = parse_generic_param(); } return result0; } function parse_reason_cause() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 5).toLowerCase() === "cause") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"cause\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result3 = parse_DIGIT(); if (result3 !== null) { result2 = []; while (result3 !== null) { result2.push(result3); result3 = parse_DIGIT(); } } else { result2 = null; } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, cause) { data.cause = parseInt(cause.join('')); }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_Require() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_token(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Route() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_route_param(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_route_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_route_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_route_param() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_name_addr(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_generic_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_generic_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Subscription_State() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_substate_value(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_subexp_params(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_subexp_params(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_substate_value() { var result0; var pos0; pos0 = pos; if (input.substr(pos, 6).toLowerCase() === "active") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"active\""); } } if (result0 === null) { if (input.substr(pos, 7).toLowerCase() === "pending") { result0 = input.substr(pos, 7); pos += 7; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"pending\""); } } if (result0 === null) { if (input.substr(pos, 10).toLowerCase() === "terminated") { result0 = input.substr(pos, 10); pos += 10; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"terminated\""); } } if (result0 === null) { result0 = parse_token(); } } } if (result0 !== null) { result0 = function (offset) { data.state = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_subexp_params() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 6).toLowerCase() === "reason") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"reason\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_event_reason_value(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, reason) { if (typeof reason !== 'undefined') data.reason = reason; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; pos1 = pos; if (input.substr(pos, 7).toLowerCase() === "expires") { result0 = input.substr(pos, 7); pos += 7; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"expires\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_delta_seconds(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, expires) { if (typeof expires !== 'undefined') data.expires = expires; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } if (result0 === null) { pos0 = pos; pos1 = pos; if (input.substr(pos, 11).toLowerCase() === "retry_after") { result0 = input.substr(pos, 11); pos += 11; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"retry_after\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_delta_seconds(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, retry_after) { if (typeof retry_after !== 'undefined') data.retry_after = retry_after; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } if (result0 === null) { result0 = parse_generic_param(); } } } return result0; } function parse_event_reason_value() { var result0; if (input.substr(pos, 11).toLowerCase() === "deactivated") { result0 = input.substr(pos, 11); pos += 11; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"deactivated\""); } } if (result0 === null) { if (input.substr(pos, 9).toLowerCase() === "probation") { result0 = input.substr(pos, 9); pos += 9; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"probation\""); } } if (result0 === null) { if (input.substr(pos, 8).toLowerCase() === "rejected") { result0 = input.substr(pos, 8); pos += 8; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"rejected\""); } } if (result0 === null) { if (input.substr(pos, 7).toLowerCase() === "timeout") { result0 = input.substr(pos, 7); pos += 7; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"timeout\""); } } if (result0 === null) { if (input.substr(pos, 6).toLowerCase() === "giveup") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"giveup\""); } } if (result0 === null) { if (input.substr(pos, 10).toLowerCase() === "noresource") { result0 = input.substr(pos, 10); pos += 10; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"noresource\""); } } if (result0 === null) { if (input.substr(pos, 9).toLowerCase() === "invariant") { result0 = input.substr(pos, 9); pos += 9; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"invariant\""); } } if (result0 === null) { result0 = parse_token(); } } } } } } } return result0; } function parse_Subject() { var result0; result0 = parse_TEXT_UTF8_TRIM(); result0 = result0 !== null ? result0 : ""; return result0; } function parse_Supported() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_token(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_token(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } result0 = result0 !== null ? result0 : ""; return result0; } function parse_To() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_SIP_URI_noparams(); if (result0 === null) { result0 = parse_name_addr(); } if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_to_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_to_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { var tag = data.tag; try { data = new NameAddrHeader(data.uri, data.display_name, data.params); if (tag) { data.setParam('tag', tag); } } catch (e) { data = -1; } }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_to_param() { var result0; result0 = parse_tag_param(); if (result0 === null) { result0 = parse_generic_param(); } return result0; } function parse_Via() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_via_param(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_via_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_COMMA(); if (result2 !== null) { result3 = parse_via_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_via_param() { var result0, result1, result2, result3, result4, result5; var pos0, pos1; pos0 = pos; result0 = parse_sent_protocol(); if (result0 !== null) { result1 = parse_LWS(); if (result1 !== null) { result2 = parse_sent_by(); if (result2 !== null) { result3 = []; pos1 = pos; result4 = parse_SEMI(); if (result4 !== null) { result5 = parse_via_params(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos1; } } else { result4 = null; pos = pos1; } while (result4 !== null) { result3.push(result4); pos1 = pos; result4 = parse_SEMI(); if (result4 !== null) { result5 = parse_via_params(); if (result5 !== null) { result4 = [result4, result5]; } else { result4 = null; pos = pos1; } } else { result4 = null; pos = pos1; } } if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_via_params() { var result0; result0 = parse_via_ttl(); if (result0 === null) { result0 = parse_via_maddr(); if (result0 === null) { result0 = parse_via_received(); if (result0 === null) { result0 = parse_via_branch(); if (result0 === null) { result0 = parse_response_port(); if (result0 === null) { result0 = parse_generic_param(); } } } } } return result0; } function parse_via_ttl() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 3).toLowerCase() === "ttl") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"ttl\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_ttl(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, via_ttl_value) { data.ttl = via_ttl_value; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_via_maddr() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 5).toLowerCase() === "maddr") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"maddr\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_host(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, via_maddr) { data.maddr = via_maddr; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_via_received() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 8).toLowerCase() === "received") { result0 = input.substr(pos, 8); pos += 8; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"received\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_IPv4address(); if (result2 === null) { result2 = parse_IPv6address(); } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, via_received) { data.received = via_received; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_via_branch() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 6).toLowerCase() === "branch") { result0 = input.substr(pos, 6); pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"branch\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_token(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, via_branch) { data.branch = via_branch; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_response_port() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; if (input.substr(pos, 5).toLowerCase() === "rport") { result0 = input.substr(pos, 5); pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"rport\""); } } if (result0 !== null) { pos2 = pos; result1 = parse_EQUAL(); if (result1 !== null) { result2 = []; result3 = parse_DIGIT(); while (result3 !== null) { result2.push(result3); result3 = parse_DIGIT(); } if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { if (typeof response_port !== 'undefined') data.rport = response_port.join(''); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_sent_protocol() { var result0, result1, result2, result3, result4; var pos0; pos0 = pos; result0 = parse_protocol_name(); if (result0 !== null) { result1 = parse_SLASH(); if (result1 !== null) { result2 = parse_token(); if (result2 !== null) { result3 = parse_SLASH(); if (result3 !== null) { result4 = parse_transport(); if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_protocol_name() { var result0; var pos0; pos0 = pos; if (input.substr(pos, 3).toLowerCase() === "sip") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"SIP\""); } } if (result0 === null) { result0 = parse_token(); } if (result0 !== null) { result0 = function (offset, via_protocol) { data.protocol = via_protocol; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_transport() { var result0; var pos0; pos0 = pos; if (input.substr(pos, 3).toLowerCase() === "udp") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"UDP\""); } } if (result0 === null) { if (input.substr(pos, 3).toLowerCase() === "tcp") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"TCP\""); } } if (result0 === null) { if (input.substr(pos, 3).toLowerCase() === "tls") { result0 = input.substr(pos, 3); pos += 3; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"TLS\""); } } if (result0 === null) { if (input.substr(pos, 4).toLowerCase() === "sctp") { result0 = input.substr(pos, 4); pos += 4; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"SCTP\""); } } if (result0 === null) { result0 = parse_token(); } } } } if (result0 !== null) { result0 = function (offset, via_transport) { data.transport = via_transport; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_sent_by() { var result0, result1, result2; var pos0, pos1; pos0 = pos; result0 = parse_via_host(); if (result0 !== null) { pos1 = pos; result1 = parse_COLON(); if (result1 !== null) { result2 = parse_via_port(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos1; } } else { result1 = null; pos = pos1; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_via_host() { var result0; var pos0; pos0 = pos; result0 = parse_IPv4address(); if (result0 === null) { result0 = parse_IPv6reference(); if (result0 === null) { result0 = parse_hostname(); } } if (result0 !== null) { result0 = function (offset) { data.host = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_via_port() { var result0, result1, result2, result3, result4; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_DIGIT(); result0 = result0 !== null ? result0 : ""; if (result0 !== null) { result1 = parse_DIGIT(); result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result2 = parse_DIGIT(); result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result3 = parse_DIGIT(); result3 = result3 !== null ? result3 : ""; if (result3 !== null) { result4 = parse_DIGIT(); result4 = result4 !== null ? result4 : ""; if (result4 !== null) { result0 = [result0, result1, result2, result3, result4]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, via_sent_by_port) { data.port = parseInt(via_sent_by_port.join('')); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_ttl() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_DIGIT(); if (result0 !== null) { result1 = parse_DIGIT(); result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result2 = parse_DIGIT(); result2 = result2 !== null ? result2 : ""; if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, ttl) { return parseInt(ttl.join('')); }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_WWW_Authenticate() { var result0; result0 = parse_challenge(); return result0; } function parse_Session_Expires() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_s_e_expires(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_s_e_params(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_s_e_params(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_s_e_expires() { var result0; var pos0; pos0 = pos; result0 = parse_delta_seconds(); if (result0 !== null) { result0 = function (offset, expires) { data.expires = expires; }(pos0, result0); } if (result0 === null) { pos = pos0; } return result0; } function parse_s_e_params() { var result0; result0 = parse_s_e_refresher(); if (result0 === null) { result0 = parse_generic_param(); } return result0; } function parse_s_e_refresher() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 9).toLowerCase() === "refresher") { result0 = input.substr(pos, 9); pos += 9; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"refresher\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { if (input.substr(pos, 3).toLowerCase() === "uac") { result2 = input.substr(pos, 3); pos += 3; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"uac\""); } } if (result2 === null) { if (input.substr(pos, 3).toLowerCase() === "uas") { result2 = input.substr(pos, 3); pos += 3; } else { result2 = null; if (reportFailures === 0) { matchFailed("\"uas\""); } } } if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, s_e_refresher_value) { data.refresher = s_e_refresher_value.toLowerCase(); }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_extension_header() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_token(); if (result0 !== null) { result1 = parse_HCOLON(); if (result1 !== null) { result2 = parse_header_value(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_header_value() { var result0, result1; result0 = []; result1 = parse_TEXT_UTF8char(); if (result1 === null) { result1 = parse_UTF8_CONT(); if (result1 === null) { result1 = parse_LWS(); } } while (result1 !== null) { result0.push(result1); result1 = parse_TEXT_UTF8char(); if (result1 === null) { result1 = parse_UTF8_CONT(); if (result1 === null) { result1 = parse_LWS(); } } } return result0; } function parse_message_body() { var result0, result1; result0 = []; result1 = parse_OCTET(); while (result1 !== null) { result0.push(result1); result1 = parse_OCTET(); } return result0; } function parse_uuid_URI() { var result0, result1; var pos0; pos0 = pos; if (input.substr(pos, 5) === "uuid:") { result0 = "uuid:"; pos += 5; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"uuid:\""); } } if (result0 !== null) { result1 = parse_uuid(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_uuid() { var result0, result1, result2, result3, result4, result5, result6, result7, result8; var pos0, pos1; pos0 = pos; pos1 = pos; result0 = parse_hex8(); if (result0 !== null) { if (input.charCodeAt(pos) === 45) { result1 = "-"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result1 !== null) { result2 = parse_hex4(); if (result2 !== null) { if (input.charCodeAt(pos) === 45) { result3 = "-"; pos++; } else { result3 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result3 !== null) { result4 = parse_hex4(); if (result4 !== null) { if (input.charCodeAt(pos) === 45) { result5 = "-"; pos++; } else { result5 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result5 !== null) { result6 = parse_hex4(); if (result6 !== null) { if (input.charCodeAt(pos) === 45) { result7 = "-"; pos++; } else { result7 = null; if (reportFailures === 0) { matchFailed("\"-\""); } } if (result7 !== null) { result8 = parse_hex12(); if (result8 !== null) { result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, uuid) { data = input.substring(pos + 5, offset); }(pos0, result0[0]); } if (result0 === null) { pos = pos0; } return result0; } function parse_hex4() { var result0, result1, result2, result3; var pos0; pos0 = pos; result0 = parse_HEXDIG(); if (result0 !== null) { result1 = parse_HEXDIG(); if (result1 !== null) { result2 = parse_HEXDIG(); if (result2 !== null) { result3 = parse_HEXDIG(); if (result3 !== null) { result0 = [result0, result1, result2, result3]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_hex8() { var result0, result1; var pos0; pos0 = pos; result0 = parse_hex4(); if (result0 !== null) { result1 = parse_hex4(); if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_hex12() { var result0, result1, result2; var pos0; pos0 = pos; result0 = parse_hex4(); if (result0 !== null) { result1 = parse_hex4(); if (result1 !== null) { result2 = parse_hex4(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_Refer_To() { var result0, result1, result2, result3; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_SIP_URI_noparams(); if (result0 === null) { result0 = parse_name_addr(); } if (result0 !== null) { result1 = []; pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_generic_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } while (result2 !== null) { result1.push(result2); pos2 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_generic_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos2; } } else { result2 = null; pos = pos2; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { try { data = new NameAddrHeader(data.uri, data.display_name, data.params); } catch (e) { data = -1; } }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_Replaces() { var result0, result1, result2, result3; var pos0, pos1; pos0 = pos; result0 = parse_call_id(); if (result0 !== null) { result1 = []; pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_replaces_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } while (result2 !== null) { result1.push(result2); pos1 = pos; result2 = parse_SEMI(); if (result2 !== null) { result3 = parse_replaces_param(); if (result3 !== null) { result2 = [result2, result3]; } else { result2 = null; pos = pos1; } } else { result2 = null; pos = pos1; } } if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos0; } } else { result0 = null; pos = pos0; } return result0; } function parse_call_id() { var result0, result1, result2; var pos0, pos1, pos2; pos0 = pos; pos1 = pos; result0 = parse_word(); if (result0 !== null) { pos2 = pos; if (input.charCodeAt(pos) === 64) { result1 = "@"; pos++; } else { result1 = null; if (reportFailures === 0) { matchFailed("\"@\""); } } if (result1 !== null) { result2 = parse_word(); if (result2 !== null) { result1 = [result1, result2]; } else { result1 = null; pos = pos2; } } else { result1 = null; pos = pos2; } result1 = result1 !== null ? result1 : ""; if (result1 !== null) { result0 = [result0, result1]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset) { data.call_id = input.substring(pos, offset); }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function parse_replaces_param() { var result0; result0 = parse_to_tag(); if (result0 === null) { result0 = parse_from_tag(); if (result0 === null) { result0 = parse_early_flag(); if (result0 === null) { result0 = parse_generic_param(); } } } return result0; } function parse_to_tag() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 6) === "to-tag") { result0 = "to-tag"; pos += 6; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"to-tag\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_token(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, to_tag) { data.to_tag = to_tag; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_from_tag() { var result0, result1, result2; var pos0, pos1; pos0 = pos; pos1 = pos; if (input.substr(pos, 8) === "from-tag") { result0 = "from-tag"; pos += 8; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"from-tag\""); } } if (result0 !== null) { result1 = parse_EQUAL(); if (result1 !== null) { result2 = parse_token(); if (result2 !== null) { result0 = [result0, result1, result2]; } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } } else { result0 = null; pos = pos1; } if (result0 !== null) { result0 = function (offset, from_tag) { data.from_tag = from_tag; }(pos0, result0[2]); } if (result0 === null) { pos = pos0; } return result0; } function parse_early_flag() { var result0; var pos0; pos0 = pos; if (input.substr(pos, 10) === "early-only") { result0 = "early-only"; pos += 10; } else { result0 = null; if (reportFailures === 0) { matchFailed("\"early-only\""); } } if (result0 !== null) { result0 = function (offset) { data.early_only = true; }(pos0); } if (result0 === null) { pos = pos0; } return result0; } function cleanupExpected(expected) { expected.sort(); var lastExpected = null; var cleanExpected = []; for (var i = 0; i < expected.length; i++) { if (expected[i] !== lastExpected) { cleanExpected.push(expected[i]); lastExpected = expected[i]; } } return cleanExpected; } function computeErrorPosition() { /* * The first idea was to use |String.split| to break the input up to the * error position along newlines and derive the line and column from * there. However IE's |split| implementation is so broken that it was * enough to prevent it. */ var line = 1; var column = 1; var seenCR = false; for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) { var ch = input.charAt(i); if (ch === "\n") { if (!seenCR) { line++; } column = 1; seenCR = false; } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { line++; column = 1; seenCR = true; } else { column++; seenCR = false; } } return { line: line, column: column }; } var URI = __webpack_require__(8); var NameAddrHeader = __webpack_require__(11); var data = {}; var result = parseFunctions[startRule](); /* * The parser is now in one of the following three states: * * 1. The parser successfully parsed the whole input. * * - |result !== null| * - |pos === input.length| * - |rightmostFailuresExpected| may or may not contain something * * 2. The parser successfully parsed only a part of the input. * * - |result !== null| * - |pos < input.length| * - |rightmostFailuresExpected| may or may not contain something * * 3. The parser did not successfully parse any part of the input. * * - |result === null| * - |pos === 0| * - |rightmostFailuresExpected| contains at least one failure * * All code following this comment (including called functions) must * handle these states. */ if (result === null || pos !== input.length) { var offset = Math.max(pos, rightmostFailuresPos); var found = offset < input.length ? input.charAt(offset) : null; var errorPosition = computeErrorPosition(); new this.SyntaxError(cleanupExpected(rightmostFailuresExpected), found, offset, errorPosition.line, errorPosition.column); return -1; } return data; }, /* Returns the parser source code. */ toSource: function toSource() { return this._source; } }; /* Thrown when a parser encounters a syntax error. */ result.SyntaxError = function (expected, found, offset, line, column) { function buildMessage(expected, found) { var expectedHumanized, foundHumanized; switch (expected.length) { case 0: expectedHumanized = "end of input"; break; case 1: expectedHumanized = expected[0]; break; default: expectedHumanized = expected.slice(0, expected.length - 1).join(", ") + " or " + expected[expected.length - 1]; } foundHumanized = found ? quote(found) : "end of input"; return "Expected " + expectedHumanized + " but " + foundHumanized + " found."; } this.name = "SyntaxError"; this.expected = expected; this.found = found; this.message = buildMessage(expected, found); this.offset = offset; this.line = line; this.column = column; }; result.SyntaxError.prototype = Error.prototype; return result; }(); }), /* 4 */ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["e"] = extractVersion; /* harmony export (immutable) */ __webpack_exports__["g"] = wrapPeerConnectionEvent; /* harmony export (immutable) */ __webpack_exports__["c"] = disableLog; /* harmony export (immutable) */ __webpack_exports__["d"] = disableWarnings; /* harmony export (immutable) */ __webpack_exports__["f"] = log; /* harmony export (immutable) */ __webpack_exports__["a"] = deprecated; /* harmony export (immutable) */ __webpack_exports__["b"] = detectBrowser; /* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. */ /* eslint-env node */ let logDisabled_ = true; let deprecationWarnings_ = true; /** * Extract browser version out of the provided user agent string. * * @param {!string} uastring userAgent string. * @param {!string} expr Regular expression used as match criteria. * @param {!number} pos position in the version string to be returned. * @return {!number} browser version. */ function extractVersion(uastring, expr, pos) { const match = uastring.match(expr); return match && match.length >= pos && parseInt(match[pos], 10); } // Wraps the peerconnection event eventNameToWrap in a function // which returns the modified event object (or false to prevent // the event). function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) { if (!window.RTCPeerConnection) { return; } const proto = window.RTCPeerConnection.prototype; const nativeAddEventListener = proto.addEventListener; proto.addEventListener = function (nativeEventName, cb) { if (nativeEventName !== eventNameToWrap) { return nativeAddEventListener.apply(this, arguments); } const wrappedCallback = e => { const modifiedEvent = wrapper(e); if (modifiedEvent) { cb(modifiedEvent); } }; this._eventMap = this._eventMap || {}; this._eventMap[cb] = wrappedCallback; return nativeAddEventListener.apply(this, [nativeEventName, wrappedCallback]); }; const nativeRemoveEventListener = proto.removeEventListener; proto.removeEventListener = function (nativeEventName, cb) { if (nativeEventName !== eventNameToWrap || !this._eventMap || !this._eventMap[cb]) { return nativeRemoveEventListener.apply(this, arguments); } const unwrappedCb = this._eventMap[cb]; delete this._eventMap[cb]; return nativeRemoveEventListener.apply(this, [nativeEventName, unwrappedCb]); }; Object.defineProperty(proto, 'on' + eventNameToWrap, { get() { return this['_on' + eventNameToWrap]; }, set(cb) { if (this['_on' + eventNameToWrap]) { this.removeEventListener(eventNameToWrap, this['_on' + eventNameToWrap]); delete this['_on' + eventNameToWrap]; } if (cb) { this.addEventListener(eventNameToWrap, this['_on' + eventNameToWrap] = cb); } }, enumerable: true, configurable: true }); } function disableLog(bool) { if (typeof bool !== 'boolean') { return new Error('Argument type: ' + typeof bool + '. Please use a boolean.'); } logDisabled_ = bool; return bool ? 'adapter.js logging disabled' : 'adapter.js logging enabled'; } /** * Disable or enable deprecation warnings * @param {!boolean} bool set to true to disable warnings. */ function disableWarnings(bool) { if (typeof bool !== 'boolean') { return new Error('Argument type: ' + typeof bool + '. Please use a boolean.'); } deprecationWarnings_ = !bool; return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled'); } function log() { if (typeof window === 'object') { if (logDisabled_) { return; } if (typeof console !== 'undefined' && typeof console.log === 'function') { console.log.apply(console, arguments); } } } /** * Shows a deprecation warning suggesting the modern and spec-compatible API. */ function deprecated(oldMethod, newMethod) { if (!deprecationWarnings_) { return; } console.warn(oldMethod + ' is deprecated, please use ' + newMethod + ' instead.'); } /** * Browser detector. * * @return {object} result containing browser and version * properties. */ function detectBrowser(window) { const { navigator } = window; // Returned result object. const result = { browser: null, version: null }; // Fail early if it's not a browser if (typeof window === 'undefined' || !window.navigator) { result.browser = 'Not a browser.'; return result; } if (navigator.mozGetUserMedia) { // Firefox. result.browser = 'firefox'; result.version = extractVersion(navigator.userAgent, /Firefox\/(\d+)\./, 1); } else if (navigator.webkitGetUserMedia) { // Chrome, Chromium, Webview, Opera. // Version matches Chrome/WebRTC version. result.browser = 'chrome'; result.version = extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2); } else if (navigator.mediaDevices && navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)) { // Edge. result.browser = 'edge'; result.version = extractVersion(navigator.userAgent, /Edge\/(\d+).(\d+)$/, 2); } else if (window.RTCPeerConnection && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) { // Safari. result.browser = 'safari'; result.version = extractVersion(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1); } else { // Default fallthrough: not supported. result.browser = 'Not a supported browser.'; return result; } return result; } }), /* 5 */ (function(module, exports, __webpack_require__) { "use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _classCallCheck(instance, Constructor) { if (!(instance 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; } var sdp_transform = __webpack_require__(13); var JsSIP_C = __webpack_require__(1); var Utils = __webpack_require__(2); var NameAddrHeader = __webpack_require__(11); var Grammar = __webpack_require__(3); var debug = __webpack_require__(0)('JsSIP:SIPMessage'); /** * -param {String} method request method * -param {String} ruri request uri * -param {UA} ua * -param {Object} params parameters that will have priority over ua.configuration parameters: *
* - cseq, call_id, from_tag, from_uri, from_display_name, to_uri, to_tag, route_set * -param {Object} [headers] extra headers * -param {String} [body] */ var OutgoingRequest = /*#__PURE__*/ function () { function OutgoingRequest(method, ruri, ua, params, extraHeaders, body) { _classCallCheck(this, OutgoingRequest); // Mandatory parameters check. if (!method || !ruri || !ua) { return null; } params = params || {}; this.ua = ua; this.headers = {}; this.method = method; this.ruri = ruri; this.body = body; this.extraHeaders = Utils.cloneArray(extraHeaders); // Fill the Common SIP Request Headers. // Route. if (params.route_set) { this.setHeader('route', params.route_set); } else if (ua.configuration.use_preloaded_route) { this.setHeader('route', "<".concat(ua.transport.sip_uri, ";lr>")); } // Via. // Empty Via header. Will be filled by the client transaction. this.setHeader('via', ''); // Max-Forwards. this.setHeader('max-forwards', JsSIP_C.MAX_FORWARDS); // To var to = params.to_display_name || params.to_display_name === 0 ? "\"".concat(params.to_display_name, "\" ") : ''; to += "<".concat(params.to_uri || ruri, ">"); to += params.to_tag ? ";tag=".concat(params.to_tag) : ''; this.to = NameAddrHeader.parse(to); this.setHeader('to', to); // From. var from; if (params.from_display_name || params.from_display_name === 0) { from = "\"".concat(params.from_display_name, "\" "); } else if (ua.configuration.display_name) { from = "\"".concat(ua.configuration.display_name, "\" "); } else { from = ''; } from += "<".concat(params.from_uri || ua.configuration.uri, ">;tag="); from += params.from_tag || Utils.newTag(); this.from = NameAddrHeader.parse(from); this.setHeader('from', from); // Call-ID. var call_id = params.call_id || ua.configuration.jssip_id + Utils.createRandomToken(15); this.call_id = call_id; this.setHeader('call-id', call_id); // CSeq. var cseq = params.cseq || Math.floor(Math.random() * 10000); this.cseq = cseq; this.setHeader('cseq', "".concat(cseq, " ").concat(method)); } /** * Replace the the given header by the given value. * -param {String} name header name * -param {String | Array} value header value */ _createClass(OutgoingRequest, [{ key: "setHeader", value: function setHeader(name, value) { // Remove the header from extraHeaders if present. var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i'); for (var idx = 0; idx < this.extraHeaders.length; idx++) { if (regexp.test(this.extraHeaders[idx])) { this.extraHeaders.splice(idx, 1); } } this.headers[Utils.headerize(name)] = Array.isArray(value) ? value : [value]; } /** * Get the value of the given header name at the given position. * -param {String} name header name * -returns {String|undefined} Returns the specified header, null if header doesn't exist. */ }, { key: "getHeader", value: function getHeader(name) { var headers = this.headers[Utils.headerize(name)]; if (headers) { if (headers[0]) { return headers[0]; } } else { var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i'); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this.extraHeaders[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var header = _step.value; if (regexp.test(header)) { return header.substring(header.indexOf(':') + 1).trim(); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } return; } /** * Get the header/s of the given name. * -param {String} name header name * -returns {Array} Array with all the headers of the specified name. */ }, { key: "getHeaders", value: function getHeaders(name) { var headers = this.headers[Utils.headerize(name)]; var result = []; if (headers) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = headers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var header = _step2.value; result.push(header); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } return result; } else { var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i'); var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = this.extraHeaders[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _header = _step3.value; if (regexp.test(_header)) { result.push(_header.substring(_header.indexOf(':') + 1).trim()); } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return != null) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } return result; } } /** * Verify the existence of the given header. * -param {String} name header name * -returns {boolean} true if header with given name exists, false otherwise */ }, { key: "hasHeader", value: function hasHeader(name) { if (this.headers[Utils.headerize(name)]) { return true; } else { var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i'); var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = this.extraHeaders[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var header = _step4.value; if (regexp.test(header)) { return true; } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return != null) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } } return false; } /** * Parse the current body as a SDP and store the resulting object * into this.sdp. * -param {Boolean} force: Parse even if this.sdp already exists. * * Returns this.sdp. */ }, { key: "parseSDP", value: function parseSDP(force) { if (!force && this.sdp) { return this.sdp; } else { this.sdp = sdp_transform.parse(this.body || ''); return this.sdp; } } }, { key: "toString", value: function toString() { var msg = "".concat(this.method, " ").concat(this.ruri, " SIP/2.0\r\n"); for (var headerName in this.headers) { if (Object.prototype.hasOwnProperty.call(this.headers, headerName)) { var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = this.headers[headerName][Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var headerValue = _step5.value; msg += "".concat(headerName, ": ").concat(headerValue, "\r\n"); } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return != null) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } } } var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { for (var _iterator6 = this.extraHeaders[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { var header = _step6.value; msg += "".concat(header.trim(), "\r\n"); } // Supported. } catch (err) { _didIteratorError6 = true; _iteratorError6 = err; } finally { try { if (!_iteratorNormalCompletion6 && _iterator6.return != null) { _iterator6.return(); } } finally { if (_didIteratorError6) { throw _iteratorError6; } } } var supported = []; switch (this.method) { case JsSIP_C.REGISTER: supported.push('path', 'gruu'); break; case JsSIP_C.INVITE: if (this.ua.configuration.session_timers) { supported.push('timer'); } if (this.ua.contact.pub_gruu || this.ua.contact.temp_gruu) { supported.push('gruu'); } supported.push('ice', 'replaces'); break; case JsSIP_C.UPDATE: if (this.ua.configuration.session_timers) { supported.push('timer'); } supported.push('ice'); break; } supported.push('outbound'); var userAgent = this.ua.configuration.user_agent || JsSIP_C.USER_AGENT; // Allow. msg += "Allow: ".concat(JsSIP_C.ALLOWED_METHODS, "\r\n"); msg += "Supported: ".concat(supported, "\r\n"); msg += "User-Agent: ".concat(userAgent, "\r\n"); if (this.body) { var length = Utils.str_utf8_length(this.body); msg += "Content-Length: ".concat(length, "\r\n\r\n"); msg += this.body; } else { msg += 'Content-Length: 0\r\n\r\n'; } return msg; } }, { key: "clone", value: function clone() { var request = new OutgoingRequest(this.method, this.ruri, this.ua); Object.keys(this.headers).forEach(function (name) { request.headers[name] = this.headers[name].slice(); }, this); request.body = this.body; request.extraHeaders = Utils.cloneArray(this.extraHeaders); request.to = this.to; request.from = this.from; request.call_id = this.call_id; request.cseq = this.cseq; return request; } }]); return OutgoingRequest; }(); var InitialOutgoingInviteRequest = /*#__PURE__*/ function (_OutgoingRequest) { _inherits(InitialOutgoingInviteRequest, _OutgoingRequest); function InitialOutgoingInviteRequest(ruri, ua, params, extraHeaders, body) { var _this; _classCallCheck(this, InitialOutgoingInviteRequest); _this = _possibleConstructorReturn(this, _getPrototypeOf(InitialOutgoingInviteRequest).call(this, JsSIP_C.INVITE, ruri, ua, params, extraHeaders, body)); _this.transaction = null; return _this; } _createClass(InitialOutgoingInviteRequest, [{ key: "cancel", value: function cancel(reason) { this.transaction.cancel(reason); } }, { key: "clone", value: function clone() { var request = new InitialOutgoingInviteRequest(this.ruri, this.ua); Object.keys(this.headers).forEach(function (name) { request.headers[name] = this.headers[name].slice(); }, this); request.body = this.body; request.extraHeaders = Utils.cloneArray(this.extraHeaders); request.to = this.to; request.from = this.from; request.call_id = this.call_id; request.cseq = this.cseq; request.transaction = this.transaction; return request; } }]); return InitialOutgoingInviteRequest; }(OutgoingRequest); var IncomingMessage = /*#__PURE__*/ function () { function IncomingMessage() { _classCallCheck(this, IncomingMessage); this.data = null; this.headers = null; this.method = null; this.via = null; this.via_branch = null; this.call_id = null; this.cseq = null; this.from = null; this.from_tag = null; this.to = null; this.to_tag = null; this.body = null; this.sdp = null; } /** * Insert a header of the given name and value into the last position of the * header array. */ _createClass(IncomingMessage, [{ key: "addHeader", value: function addHeader(name, value) { var header = { raw: value }; name = Utils.headerize(name); if (this.headers[name]) { this.headers[name].push(header); } else { this.headers[name] = [header]; } } /** * Get the value of the given header name at the given position. */ }, { key: "getHeader", value: function getHeader(name) { var header = this.headers[Utils.headerize(name)]; if (header) { if (header[0]) { return header[0].raw; } } else { return; } } /** * Get the header/s of the given name. */ }, { key: "getHeaders", value: function getHeaders(name) { var headers = this.headers[Utils.headerize(name)]; var result = []; if (!headers) { return []; } var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { for (var _iterator7 = headers[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { var header = _step7.value; result.push(header.raw); } } catch (err) { _didIteratorError7 = true; _iteratorError7 = err; } finally { try { if (!_iteratorNormalCompletion7 && _iterator7.return != null) { _iterator7.return(); } } finally { if (_didIteratorError7) { throw _iteratorError7; } } } return result; } /** * Verify the existence of the given header. */ }, { key: "hasHeader", value: function hasHeader(name) { return this.headers[Utils.headerize(name)] ? true : false; } /** * Parse the given header on the given index. * -param {String} name header name * -param {Number} [idx=0] header index * -returns {Object|undefined} Parsed header object, undefined if the header * is not present or in case of a parsing error. */ }, { key: "parseHeader", value: function parseHeader(name) { var idx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; name = Utils.headerize(name); if (!this.headers[name]) { debug("header \"".concat(name, "\" not present")); return; } else if (idx >= this.headers[name].length) { debug("not so many \"".concat(name, "\" headers present")); return; } var header = this.headers[name][idx]; var value = header.raw; if (header.parsed) { return header.parsed; } // Substitute '-' by '_' for grammar rule matching. var parsed = Grammar.parse(value, name.replace(/-/g, '_')); if (parsed === -1) { this.headers[name].splice(idx, 1); // delete from headers debug("error parsing \"".concat(name, "\" header field with value \"").concat(value, "\"")); return; } else { header.parsed = parsed; return parsed; } } /** * Message Header attribute selector. Alias of parseHeader. * -param {String} name header name * -param {Number} [idx=0] header index * -returns {Object|undefined} Parsed header object, undefined if the header * is not present or in case of a parsing error. * * -example * message.s('via',3).port */ }, { key: "s", value: function s(name, idx) { return this.parseHeader(name, idx); } /** * Replace the value of the given header by the value. * -param {String} name header name * -param {String} value header value */ }, { key: "setHeader", value: function setHeader(name, value) { var header = { raw: value }; this.headers[Utils.headerize(name)] = [header]; } /** * Parse the current body as a SDP and store the resulting object * into this.sdp. * -param {Boolean} force: Parse even if this.sdp already exists. * * Returns this.sdp. */ }, { key: "parseSDP", value: function parseSDP(force) { if (!force && this.sdp) { return this.sdp; } else { this.sdp = sdp_transform.parse(this.body || ''); return this.sdp; } } }, { key: "toString", value: function toString() { return this.data; } }]); return IncomingMessage; }(); var IncomingRequest = /*#__PURE__*/ function (_IncomingMessage) { _inherits(IncomingRequest, _IncomingMessage); function IncomingRequest(ua) { var _this2; _classCallCheck(this, IncomingRequest); _this2 = _possibleConstructorReturn(this, _getPrototypeOf(IncomingRequest).call(this)); _this2.ua = ua; _this2.headers = {}; _this2.ruri = null; _this2.transport = null; _this2.server_transaction = null; return _this2; } /** * Stateful reply. * -param {Number} code status code * -param {String} reason reason phrase * -param {Object} headers extra headers * -param {String} body body * -param {Function} [onSuccess] onSuccess callback * -param {Function} [onFailure] onFailure callback */ _createClass(IncomingRequest, [{ key: "reply", value: function reply(code, reason, extraHeaders, body, onSuccess, onFailure) { var supported = []; var to = this.getHeader('To'); code = code || null; reason = reason || null; // Validate code and reason values. if (!code || code < 100 || code > 699) { throw new TypeError("Invalid status_code: ".concat(code)); } else if (reason && typeof reason !== 'string' && !(reason instanceof String)) { throw new TypeError("Invalid reason_phrase: ".concat(reason)); } reason = reason || JsSIP_C.REASON_PHRASE[code] || ''; extraHeaders = Utils.cloneArray(extraHeaders); var response = "SIP/2.0 ".concat(code, " ").concat(reason, "\r\n"); if (this.method === JsSIP_C.INVITE && code > 100 && code <= 200) { var headers = this.getHeaders('record-route'); var _iteratorNormalCompletion8 = true; var _didIteratorError8 = false; var _iteratorError8 = undefined; try { for (var _iterator8 = headers[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { var header = _step8.value; response += "Record-Route: ".concat(header, "\r\n"); } } catch (err) { _didIteratorError8 = true; _iteratorError8 = err; } finally { try { if (!_iteratorNormalCompletion8 && _iterator8.return != null) { _iterator8.return(); } } finally { if (_didIteratorError8) { throw _iteratorError8; } } } } var vias = this.getHeaders('via'); var _iteratorNormalCompletion9 = true; var _didIteratorError9 = false; var _iteratorError9 = undefined; try { for (var _iterator9 = vias[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { var via = _step9.value; response += "Via: ".concat(via, "\r\n"); } } catch (err) { _didIteratorError9 = true; _iteratorError9 = err; } finally { try { if (!_iteratorNormalCompletion9 && _iterator9.return != null) { _iterator9.return(); } } finally { if (_didIteratorError9) { throw _iteratorError9; } } } if (!this.to_tag && code > 100) { to += ";tag=".concat(Utils.newTag()); } else if (this.to_tag && !this.s('to').hasParam('tag')) { to += ";tag=".concat(this.to_tag); } response += "To: ".concat(to, "\r\n"); response += "From: ".concat(this.getHeader('From'), "\r\n"); response += "Call-ID: ".concat(this.call_id, "\r\n"); response += "CSeq: ".concat(this.cseq, " ").concat(this.method, "\r\n"); var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { for (var _iterator10 = extraHeaders[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { var _header2 = _step10.value; response += "".concat(_header2.trim(), "\r\n"); } // Supported. } catch (err) { _didIteratorError10 = true; _iteratorError10 = err; } finally { try { if (!_iteratorNormalCompletion10 && _iterator10.return != null) { _iterator10.return(); } } finally { if (_didIteratorError10) { throw _iteratorError10; } } } switch (this.method) { case JsSIP_C.INVITE: if (this.ua.configuration.session_timers) { supported.push('timer'); } if (this.ua.contact.pub_gruu || this.ua.contact.temp_gruu) { supported.push('gruu'); } supported.push('ice', 'replaces'); break; case JsSIP_C.UPDATE: if (this.ua.configuration.session_timers) { supported.push('timer'); } if (body) { supported.push('ice'); } supported.push('replaces'); } supported.push('outbound'); // Allow and Accept. if (this.method === JsSIP_C.OPTIONS) { response += "Allow: ".concat(JsSIP_C.ALLOWED_METHODS, "\r\n"); response += "Accept: ".concat(JsSIP_C.ACCEPTED_BODY_TYPES, "\r\n"); } else if (code === 405) { response += "Allow: ".concat(JsSIP_C.ALLOWED_METHODS, "\r\n"); } else if (code === 415) { response += "Accept: ".concat(JsSIP_C.ACCEPTED_BODY_TYPES, "\r\n"); } response += "Supported: ".concat(supported, "\r\n"); if (body) { var length = Utils.str_utf8_length(body); response += 'Content-Type: application/sdp\r\n'; response += "Content-Length: ".concat(length, "\r\n\r\n"); response += body; } else { response += "Content-Length: ".concat(0, "\r\n\r\n"); } this.server_transaction.receiveResponse(code, response, onSuccess, onFailure); } /** * Stateless reply. * -param {Number} code status code * -param {String} reason reason phrase */ }, { key: "reply_sl", value: function reply_sl() { var code = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var vias = this.getHeaders('via'); // Validate code and reason values. if (!code || code < 100 || code > 699) { throw new TypeError("Invalid status_code: ".concat(code)); } else if (reason && typeof reason !== 'string' && !(reason instanceof String)) { throw new TypeError("Invalid reason_phrase: ".concat(reason)); } reason = reason || JsSIP_C.REASON_PHRASE[code] || ''; var response = "SIP/2.0 ".concat(code, " ").concat(reason, "\r\n"); var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { for (var _iterator11 = vias[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { var via = _step11.value; response += "Via: ".concat(via, "\r\n"); } } catch (err) { _didIteratorError11 = true; _iteratorError11 = err; } finally { try { if (!_iteratorNormalCompletion11 && _iterator11.return != null) { _iterator11.return(); } } finally { if (_didIteratorError11) { throw _iteratorError11; } } } var to = this.getHeader('To'); if (!this.to_tag && code > 100) { to += ";tag=".concat(Utils.newTag()); } else if (this.to_tag && !this.s('to').hasParam('tag')) { to += ";tag=".concat(this.to_tag); } response += "To: ".concat(to, "\r\n"); response += "From: ".concat(this.getHeader('From'), "\r\n"); response += "Call-ID: ".concat(this.call_id, "\r\n"); response += "CSeq: ".concat(this.cseq, " ").concat(this.method, "\r\n"); response += "Content-Length: ".concat(0, "\r\n\r\n"); this.transport.send(response); } }]); return IncomingRequest; }(IncomingMessage); var IncomingResponse = /*#__PURE__*/ function (_IncomingMessage2) { _inherits(IncomingResponse, _IncomingMessage2); function IncomingResponse() { var _this3; _classCallCheck(this, IncomingResponse); _this3 = _possibleConstructorReturn(this, _getPrototypeOf(IncomingResponse).call(this)); _this3.headers = {}; _this3.status_code = null; _this3.reason_phrase = null; return _this3; } return IncomingResponse; }(IncomingMessage); module.exports = { OutgoingRequest: OutgoingRequest, InitialOutgoingInviteRequest: InitialOutgoingInviteRequest, IncomingRequest: IncomingRequest, IncomingResponse: IncomingResponse }; }), /* 6 */ (function(module, exports, __webpack_require__) { "use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var ConfigurationError = /*#__PURE__*/ function (_Error) { _inherits(ConfigurationError, _Error); function ConfigurationError(parameter, value) { var _this; _classCallCheck(this, ConfigurationError); _this = _possibleConstructorReturn(this, _getPrototypeOf(ConfigurationError).call(this)); _this.code = 1; _this.name = 'CONFIGURATION_ERROR'; _this.parameter = parameter; _this.value = value; _this.message = !_this.value ? "Missing parameter: ".concat(_this.parameter) : "Invalid value ".concat(JSON.stringify(_this.value), " for parameter \"").concat(_this.parameter, "\""); return _this; } return ConfigurationError; }(_wrapNativeSuper(Error)); var InvalidStateError = /*#__PURE__*/ function (_Error2) { _inherits(InvalidStateError, _Error2); function InvalidStateError(status) { var _this2; _classCallCheck(this, InvalidStateError); _this2 = _possibleConstructorReturn(this, _getPrototypeOf(InvalidStateError).call(this)); _this2.code = 2; _this2.name = 'INVALID_STATE_ERROR'; _this2.status = status; _this2.message = "Invalid status: ".concat(status); return _this2; } return InvalidStateError; }(_wrapNativeSuper(Error)); var NotSupportedError = /*#__PURE__*/ function (_Error3) { _inherits(NotSupportedError, _Error3); function NotSupportedError(message) { var _this3; _classCallCheck(this, NotSupportedError); _this3 = _possibleConstructorReturn(this, _getPrototypeOf(NotSupportedError).call(this)); _this3.code = 3; _this3.name = 'NOT_SUPPORTED_ERROR'; _this3.message = message; return _this3; } return NotSupportedError; }(_wrapNativeSuper(Error)); var NotReadyError = /*#__PURE__*/ function (_Error4) { _inherits(NotReadyError, _Error4); function NotReadyError(message) { var _this4; _classCallCheck(this, NotReadyError); _this4 = _possibleConstructorReturn(this, _getPrototypeOf(NotReadyError).call(this)); _this4.code = 4; _this4.name = 'NOT_READY_ERROR'; _this4.message = message; return _this4; } return NotReadyError; }(_wrapNativeSuper(Error)); module.exports = { ConfigurationError: ConfigurationError, InvalidStateError: InvalidStateError, NotSupportedError: NotSupportedError, NotReadyError: NotReadyError }; }), /* 7 */ (function(module, exports) { // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function (n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function (type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || isObject(this._events.error) && !this._events.error.length) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } else { // At least give some kind of context to the user var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); err.context = er; throw err; } } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: args = Array.prototype.slice.call(arguments, 1); handler.apply(this, args); } } else if (isObject(handler)) { args = Array.prototype.slice.call(arguments, 1); listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function (type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener;else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener);else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function (type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function (type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || isFunction(list.listener) && list.listener === listener) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || list[i].listener && list[i].listener === listener) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function (type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {};else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else if (listeners) { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function (type) { var ret; if (!this._events || !this._events[type]) ret = [];else if (isFunction(this._events[type])) ret = [this._events[type]];else ret = this._events[type].slice(); return ret; }; EventEmitter.prototype.listenerCount = function (type) { if (this._events) { var evlistener = this._events[type]; if (isFunction(evlistener)) return 1;else if (evlistener) return evlistener.length; } return 0; }; EventEmitter.listenerCount = function (emitter, type) { return emitter.listenerCount(type); }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } }), /* 8 */ (function(module, exports, __webpack_require__) { "use strict"; function _classCallCheck(instance, Constructor) { if (!(instance 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; } var JsSIP_C = __webpack_require__(1); var Utils = __webpack_require__(2); var Grammar = __webpack_require__(3); /** * -param {String} [scheme] * -param {String} [user] * -param {String} host * -param {String} [port] * -param {Object} [parameters] * -param {Object} [headers] * */ module.exports = /*#__PURE__*/ function () { _createClass(URI, null, [{ key: "parse", /** * Parse the given string and returns a JsSIP.URI instance or undefined if * it is an invalid URI. */ value: function parse(uri) { uri = Grammar.parse(uri, 'SIP_URI'); if (uri !== -1) { return uri; } else { return undefined; } } }]); function URI(scheme, user, host, port) { var parameters = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; var headers = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}; _classCallCheck(this, URI); // Checks. if (!host) { throw new TypeError('missing or invalid "host" parameter'); } // Initialize parameters. this._parameters = {}; this._headers = {}; this._scheme = scheme || JsSIP_C.SIP; this._user = user; this._host = host; this._port = port; for (var param in parameters) { if (Object.prototype.hasOwnProperty.call(parameters, param)) { this.setParam(param, parameters[param]); } } for (var header in headers) { if (Object.prototype.hasOwnProperty.call(headers, header)) { this.setHeader(header, headers[header]); } } } _createClass(URI, [{ key: "setParam", value: function setParam(key, value) { if (key) { this._parameters[key.toLowerCase()] = typeof value === 'undefined' || value === null ? null : value.toString(); } } }, { key: "getParam", value: function getParam(key) { if (key) { return this._parameters[key.toLowerCase()]; } } }, { key: "hasParam", value: function hasParam(key) { if (key) { return this._parameters.hasOwnProperty(key.toLowerCase()) && true || false; } } }, { key: "deleteParam", value: function deleteParam(parameter) { parameter = parameter.toLowerCase(); if (this._parameters.hasOwnProperty(parameter)) { var value = this._parameters[parameter]; delete this._parameters[parameter]; return value; } } }, { key: "clearParams", value: function clearParams() { this._parameters = {}; } }, { key: "setHeader", value: function setHeader(name, value) { this._headers[Utils.headerize(name)] = Array.isArray(value) ? value : [value]; } }, { key: "getHeader", value: function getHeader(name) { if (name) { return this._headers[Utils.headerize(name)]; } } }, { key: "hasHeader", value: function hasHeader(name) { if (name) { return this._headers.hasOwnProperty(Utils.headerize(name)) && true || false; } } }, { key: "deleteHeader", value: function deleteHeader(header) { header = Utils.headerize(header); if (this._headers.hasOwnProperty(header)) { var value = this._headers[header]; delete this._headers[header]; return value; } } }, { key: "clearHeaders", value: function clearHeaders() { this._headers = {}; } }, { key: "clone", value: function clone() { return new URI(this._scheme, this._user, this._host, this._port, JSON.parse(JSON.stringify(this._parameters)), JSON.parse(JSON.stringify(this._headers))); } }, { key: "toString", value: function toString() { var headers = []; var uri = "".concat(this._scheme, ":"); if (this._user) { uri += "".concat(Utils.escapeUser(this._user), "@"); } uri += this._host; if (this._port || this._port === 0) { uri += ":".concat(this._port); } for (var parameter in this._parameters) { if (Object.prototype.hasOwnProperty.call(this._parameters, parameter)) { uri += ";".concat(parameter); if (this._parameters[parameter] !== null) { uri += "=".concat(this._parameters[parameter]); } } } for (var header in this._headers) { if (Object.prototype.hasOwnProperty.call(this._headers, header)) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this._headers[header][Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var item = _step.value; headers.push("".concat(header, "=").concat(item)); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } } if (headers.length > 0) { uri += "?".concat(headers.join('&')); } return uri; } }, { key: "toAor", value: function toAor(show_port) { var aor = "".concat(this._scheme, ":"); if (this._user) { aor += "".concat(Utils.escapeUser(this._user), "@"); } aor += this._host; if (show_port && (this._port || this._port === 0)) { aor += ":".concat(this._port); } return aor; } }, { key: "scheme", get: function get() { return this._scheme; }, set: function set(value) { this._scheme = value.toLowerCase(); } }, { key: "user", get: function get() { return this._user; }, set: function set(value) { this._user = value; } }, { key: "host", get: function get() { return this._host; }, set: function set(value) { this._host = value.toLowerCase(); } }, { key: "port", get: function get() { return this._port; }, set: function set(value) { this._port = value === 0 ? value : parseInt(value, 10) || null; } }]); return URI; }(); }), /* 9 */ (function(module, exports, __webpack_require__) { "use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance 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 _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } var EventEmitter = __webpack_require__(7).EventEmitter; var JsSIP_C = __webpack_require__(1); var SIPMessage = __webpack_require__(5); var Timers = __webpack_require__(16); var debugnict = __webpack_require__(0)('JsSIP:NonInviteClientTransaction'); var debugict = __webpack_require__(0)('JsSIP:InviteClientTransaction'); var debugact = __webpack_require__(0)('JsSIP:AckClientTransaction'); var debugnist = __webpack_require__(0)('JsSIP:NonInviteServerTransaction'); var debugist = __webpack_require__(0)('JsSIP:InviteServerTransaction'); var C = { // Transaction states. STATUS_TRYING: 1, STATUS_PROCEEDING: 2, STATUS_CALLING: 3, STATUS_ACCEPTED: 4, STATUS_COMPLETED: 5, STATUS_TERMINATED: 6, STATUS_CONFIRMED: 7, // Transaction types. NON_INVITE_CLIENT: 'nict', NON_INVITE_SERVER: 'nist', INVITE_CLIENT: 'ict', INVITE_SERVER: 'ist' }; var NonInviteClientTransaction = /*#__PURE__*/ function (_EventEmitter) { _inherits(NonInviteClientTransaction, _EventEmitter); function NonInviteClientTransaction(ua, transport, request, eventHandlers) { var _this; _classCallCheck(this, NonInviteClientTransaction); _this = _possibleConstructorReturn(this, _getPrototypeOf(NonInviteClientTransaction).call(this)); _this.type = C.NON_INVITE_CLIENT; _this.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000)); _this.ua = ua; _this.transport = transport; _this.request = request; _this.eventHandlers = eventHandlers; var via = "SIP/2.0/".concat(transport.via_transport); via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this.id); _this.request.setHeader('via', via); _this.ua.newTransaction(_assertThisInitialized(_assertThisInitialized(_this))); return _this; } _createClass(NonInviteClientTransaction, [{ key: "stateChanged", value: function stateChanged(state) { this.state = state; this.emit('stateChanged'); } }, { key: "send", value: function send() { var _this2 = this; this.stateChanged(C.STATUS_TRYING); this.F = setTimeout(function () { _this2.timer_F(); }, Timers.TIMER_F); if (!this.transport.send(this.request)) { this.onTransportError(); } } }, { key: "onTransportError", value: function onTransportError() { debugnict("transport error occurred, deleting transaction ".concat(this.id)); clearTimeout(this.F); clearTimeout(this.K); this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); this.eventHandlers.onTransportError(); } }, { key: "timer_F", value: function timer_F() { debugnict("Timer F expired for transaction ".concat(this.id)); this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); this.eventHandlers.onRequestTimeout(); } }, { key: "timer_K", value: function timer_K() { this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } }, { key: "receiveResponse", value: function receiveResponse(response) { var _this3 = this; var status_code = response.status_code; if (status_code < 200) { switch (this.state) { case C.STATUS_TRYING: case C.STATUS_PROCEEDING: this.stateChanged(C.STATUS_PROCEEDING); this.eventHandlers.onReceiveResponse(response); break; } } else { switch (this.state) { case C.STATUS_TRYING: case C.STATUS_PROCEEDING: this.stateChanged(C.STATUS_COMPLETED); clearTimeout(this.F); if (status_code === 408) { this.eventHandlers.onRequestTimeout(); } else { this.eventHandlers.onReceiveResponse(response); } this.K = setTimeout(function () { _this3.timer_K(); }, Timers.TIMER_K); break; case C.STATUS_COMPLETED: break; } } } }, { key: "C", get: function get() { return C; } }]); return NonInviteClientTransaction; }(EventEmitter); var InviteClientTransaction = /*#__PURE__*/ function (_EventEmitter2) { _inherits(InviteClientTransaction, _EventEmitter2); function InviteClientTransaction(ua, transport, request, eventHandlers) { var _this4; _classCallCheck(this, InviteClientTransaction); _this4 = _possibleConstructorReturn(this, _getPrototypeOf(InviteClientTransaction).call(this)); _this4.type = C.INVITE_CLIENT; _this4.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000)); _this4.ua = ua; _this4.transport = transport; _this4.request = request; _this4.eventHandlers = eventHandlers; request.transaction = _assertThisInitialized(_assertThisInitialized(_this4)); var via = "SIP/2.0/".concat(transport.via_transport); via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this4.id); _this4.request.setHeader('via', via); _this4.ua.newTransaction(_assertThisInitialized(_assertThisInitialized(_this4))); return _this4; } _createClass(InviteClientTransaction, [{ key: "stateChanged", value: function stateChanged(state) { this.state = state; this.emit('stateChanged'); } }, { key: "send", value: function send() { var _this5 = this; this.stateChanged(C.STATUS_CALLING); this.B = setTimeout(function () { _this5.timer_B(); }, Timers.TIMER_B); if (!this.transport.send(this.request)) { this.onTransportError(); } } }, { key: "onTransportError", value: function onTransportError() { clearTimeout(this.B); clearTimeout(this.D); clearTimeout(this.M); if (this.state !== C.STATUS_ACCEPTED) { debugict("transport error occurred, deleting transaction ".concat(this.id)); this.eventHandlers.onTransportError(); } this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } // RFC 6026 7.2. }, { key: "timer_M", value: function timer_M() { debugict("Timer M expired for transaction ".concat(this.id)); if (this.state === C.STATUS_ACCEPTED) { clearTimeout(this.B); this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } } // RFC 3261 17.1.1. }, { key: "timer_B", value: function timer_B() { debugict("Timer B expired for transaction ".concat(this.id)); if (this.state === C.STATUS_CALLING) { this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); this.eventHandlers.onRequestTimeout(); } } }, { key: "timer_D", value: function timer_D() { debugict("Timer D expired for transaction ".concat(this.id)); clearTimeout(this.B); this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } }, { key: "sendACK", value: function sendACK(response) { var _this6 = this; var ack = new SIPMessage.OutgoingRequest(JsSIP_C.ACK, this.request.ruri, this.ua, { 'route_set': this.request.getHeaders('route'), 'call_id': this.request.getHeader('call-id'), 'cseq': this.request.cseq }); ack.setHeader('from', this.request.getHeader('from')); ack.setHeader('via', this.request.getHeader('via')); ack.setHeader('to', response.getHeader('to')); this.D = setTimeout(function () { _this6.timer_D(); }, Timers.TIMER_D); this.transport.send(ack); } }, { key: "cancel", value: function cancel(reason) { // Send only if a provisional response (>100) has been received. if (this.state !== C.STATUS_PROCEEDING) { return; } var cancel = new SIPMessage.OutgoingRequest(JsSIP_C.CANCEL, this.request.ruri, this.ua, { 'route_set': this.request.getHeaders('route'), 'call_id': this.request.getHeader('call-id'), 'cseq': this.request.cseq }); cancel.setHeader('from', this.request.getHeader('from')); cancel.setHeader('via', this.request.getHeader('via')); cancel.setHeader('to', this.request.getHeader('to')); if (reason) { cancel.setHeader('reason', reason); } this.transport.send(cancel); } }, { key: "receiveResponse", value: function receiveResponse(response) { var _this7 = this; var status_code = response.status_code; if (status_code >= 100 && status_code <= 199) { switch (this.state) { case C.STATUS_CALLING: this.stateChanged(C.STATUS_PROCEEDING); this.eventHandlers.onReceiveResponse(response); break; case C.STATUS_PROCEEDING: this.eventHandlers.onReceiveResponse(response); break; } } else if (status_code >= 200 && status_code <= 299) { switch (this.state) { case C.STATUS_CALLING: case C.STATUS_PROCEEDING: this.stateChanged(C.STATUS_ACCEPTED); this.M = setTimeout(function () { _this7.timer_M(); }, Timers.TIMER_M); this.eventHandlers.onReceiveResponse(response); break; case C.STATUS_ACCEPTED: this.eventHandlers.onReceiveResponse(response); break; } } else if (status_code >= 300 && status_code <= 699) { switch (this.state) { case C.STATUS_CALLING: case C.STATUS_PROCEEDING: this.stateChanged(C.STATUS_COMPLETED); this.sendACK(response); this.eventHandlers.onReceiveResponse(response); break; case C.STATUS_COMPLETED: this.sendACK(response); break; } } } }, { key: "C", get: function get() { return C; } }]); return InviteClientTransaction; }(EventEmitter); var AckClientTransaction = /*#__PURE__*/ function (_EventEmitter3) { _inherits(AckClientTransaction, _EventEmitter3); function AckClientTransaction(ua, transport, request, eventHandlers) { var _this8; _classCallCheck(this, AckClientTransaction); _this8 = _possibleConstructorReturn(this, _getPrototypeOf(AckClientTransaction).call(this)); _this8.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000)); _this8.transport = transport; _this8.request = request; _this8.eventHandlers = eventHandlers; var via = "SIP/2.0/".concat(transport.via_transport); via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this8.id); _this8.request.setHeader('via', via); return _this8; } _createClass(AckClientTransaction, [{ key: "send", value: function send() { if (!this.transport.send(this.request)) { this.onTransportError(); } } }, { key: "onTransportError", value: function onTransportError() { debugact("transport error occurred for transaction ".concat(this.id)); this.eventHandlers.onTransportError(); } }, { key: "C", get: function get() { return C; } }]); return AckClientTransaction; }(EventEmitter); var NonInviteServerTransaction = /*#__PURE__*/ function (_EventEmitter4) { _inherits(NonInviteServerTransaction, _EventEmitter4); function NonInviteServerTransaction(ua, transport, request) { var _this9; _classCallCheck(this, NonInviteServerTransaction); _this9 = _possibleConstructorReturn(this, _getPrototypeOf(NonInviteServerTransaction).call(this)); _this9.type = C.NON_INVITE_SERVER; _this9.id = request.via_branch; _this9.ua = ua; _this9.transport = transport; _this9.request = request; _this9.last_response = ''; request.server_transaction = _assertThisInitialized(_assertThisInitialized(_this9)); _this9.state = C.STATUS_TRYING; ua.newTransaction(_assertThisInitialized(_assertThisInitialized(_this9))); return _this9; } _createClass(NonInviteServerTransaction, [{ key: "stateChanged", value: function stateChanged(state) { this.state = state; this.emit('stateChanged'); } }, { key: "timer_J", value: function timer_J() { debugnist("Timer J expired for transaction ".concat(this.id)); this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } }, { key: "onTransportError", value: function onTransportError() { if (!this.transportError) { this.transportError = true; debugnist("transport error occurred, deleting transaction ".concat(this.id)); clearTimeout(this.J); this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } } }, { key: "receiveResponse", value: function receiveResponse(status_code, response, onSuccess, onFailure) { var _this10 = this; if (status_code === 100) { /* RFC 4320 4.1 * 'A SIP element MUST NOT * send any provisional response with a * Status-Code other than 100 to a non-INVITE request.' */ switch (this.state) { case C.STATUS_TRYING: this.stateChanged(C.STATUS_PROCEEDING); if (!this.transport.send(response)) { this.onTransportError(); } break; case C.STATUS_PROCEEDING: this.last_response = response; if (!this.transport.send(response)) { this.onTransportError(); if (onFailure) { onFailure(); } } else if (onSuccess) { onSuccess(); } break; } } else if (status_code >= 200 && status_code <= 699) { switch (this.state) { case C.STATUS_TRYING: case C.STATUS_PROCEEDING: this.stateChanged(C.STATUS_COMPLETED); this.last_response = response; this.J = setTimeout(function () { _this10.timer_J(); }, Timers.TIMER_J); if (!this.transport.send(response)) { this.onTransportError(); if (onFailure) { onFailure(); } } else if (onSuccess) { onSuccess(); } break; case C.STATUS_COMPLETED: break; } } } }, { key: "C", get: function get() { return C; } }]); return NonInviteServerTransaction; }(EventEmitter); var InviteServerTransaction = /*#__PURE__*/ function (_EventEmitter5) { _inherits(InviteServerTransaction, _EventEmitter5); function InviteServerTransaction(ua, transport, request) { var _this11; _classCallCheck(this, InviteServerTransaction); _this11 = _possibleConstructorReturn(this, _getPrototypeOf(InviteServerTransaction).call(this)); _this11.type = C.INVITE_SERVER; _this11.id = request.via_branch; _this11.ua = ua; _this11.transport = transport; _this11.request = request; _this11.last_response = ''; request.server_transaction = _assertThisInitialized(_assertThisInitialized(_this11)); _this11.state = C.STATUS_PROCEEDING; ua.newTransaction(_assertThisInitialized(_assertThisInitialized(_this11))); _this11.resendProvisionalTimer = null; request.reply(100); return _this11; } _createClass(InviteServerTransaction, [{ key: "stateChanged", value: function stateChanged(state) { this.state = state; this.emit('stateChanged'); } }, { key: "timer_H", value: function timer_H() { debugist("Timer H expired for transaction ".concat(this.id)); if (this.state === C.STATUS_COMPLETED) { debugist('ACK not received, dialog will be terminated'); } this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } }, { key: "timer_I", value: function timer_I() { this.stateChanged(C.STATUS_TERMINATED); } // RFC 6026 7.1. }, { key: "timer_L", value: function timer_L() { debugist("Timer L expired for transaction ".concat(this.id)); if (this.state === C.STATUS_ACCEPTED) { this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } } }, { key: "onTransportError", value: function onTransportError() { if (!this.transportError) { this.transportError = true; debugist("transport error occurred, deleting transaction ".concat(this.id)); if (this.resendProvisionalTimer !== null) { clearInterval(this.resendProvisionalTimer); this.resendProvisionalTimer = null; } clearTimeout(this.L); clearTimeout(this.H); clearTimeout(this.I); this.stateChanged(C.STATUS_TERMINATED); this.ua.destroyTransaction(this); } } }, { key: "resend_provisional", value: function resend_provisional() { if (!this.transport.send(this.last_response)) { this.onTransportError(); } } // INVITE Server Transaction RFC 3261 17.2.1. }, { key: "receiveResponse", value: function receiveResponse(status_code, response, onSuccess, onFailure) { var _this12 = this; if (status_code >= 100 && status_code <= 199) { switch (this.state) { case C.STATUS_PROCEEDING: if (!this.transport.send(response)) { this.onTransportError(); } this.last_response = response; break; } } if (status_code > 100 && status_code <= 199 && this.state === C.STATUS_PROCEEDING) { // Trigger the resendProvisionalTimer only for the first non 100 provisional response. if (this.resendProvisionalTimer === null) { this.resendProvisionalTimer = setInterval(function () { _this12.resend_provisional(); }, Timers.PROVISIONAL_RESPONSE_INTERVAL); } } else if (status_code >= 200 && status_code <= 299) { switch (this.state) { case C.STATUS_PROCEEDING: this.stateChanged(C.STATUS_ACCEPTED); this.last_response = response; this.L = setTimeout(function () { _this12.timer_L(); }, Timers.TIMER_L); if (this.resendProvisionalTimer !== null) { clearInterval(this.resendProvisionalTimer); this.resendProvisionalTimer = null; } /* falls through */ case C.STATUS_ACCEPTED: // Note that this point will be reached for proceeding this.state also. if (!this.transport.send(response)) { this.onTransportError(); if (onFailure) { onFailure(); } } else if (onSuccess) { onSuccess(); } break; } } else if (status_code >= 300 && status_code <= 699) { switch (this.state) { case C.STATUS_PROCEEDING: if (this.resendProvisionalTimer !== null) { clearInterval(this.resendProvisionalTimer); this.resendProvisionalTimer = null; } if (!this.transport.send(response)) { this.onTransportError(); if (onFailure) { onFailure(); } } else { this.stateChanged(C.STATUS_COMPLETED); this.H = setTimeout(function () { _this12.timer_H(); }, Timers.TIMER_H); if (onSuccess) { onSuccess(); } } break; } } } }, { key: "C", get: function get() { return C; } }]); return InviteServerTransaction; }(EventEmitter); /** * INVITE: * _true_ if retransmission * _false_ new request * * ACK: * _true_ ACK to non2xx response * _false_ ACK must be passed to TU (accepted state) * ACK to 2xx response * * CANCEL: * _true_ no matching invite transaction * _false_ matching invite transaction and no final response sent * * OTHER: * _true_ retransmission * _false_ new request */ function checkTransaction(_ref, request) { var _transactions = _ref._transactions; var tr; switch (request.method) { case JsSIP_C.INVITE: tr = _transactions.ist[request.via_branch]; if (tr) { switch (tr.state) { case C.STATUS_PROCEEDING: tr.transport.send(tr.last_response); break; // RFC 6026 7.1 Invite retransmission. // Received while in C.STATUS_ACCEPTED state. Absorb it. case C.STATUS_ACCEPTED: break; } return true; } break; case JsSIP_C.ACK: tr = _transactions.ist[request.via_branch]; // RFC 6026 7.1. if (tr) { if (tr.state === C.STATUS_ACCEPTED) { return false; } else if (tr.state === C.STATUS_COMPLETED) { tr.state = C.STATUS_CONFIRMED; tr.I = setTimeout(function () { tr.timer_I(); }, Timers.TIMER_I); return true; } } // ACK to 2XX Response. else { return false; } break; case JsSIP_C.CANCEL: tr = _transactions.ist[request.via_branch]; if (tr) { request.reply_sl(200); if (tr.state === C.STATUS_PROCEEDING) { return false; } else { return true; } } else { request.reply_sl(481); return true; } default: // Non-INVITE Server Transaction RFC 3261 17.2.2. tr = _transactions.nist[request.via_branch]; if (tr) { switch (tr.state) { case C.STATUS_TRYING: break; case C.STATUS_PROCEEDING: case C.STATUS_COMPLETED: tr.transport.send(tr.last_response); break; } return true; } break; } } module.exports = { C: C, NonInviteClientTransaction: NonInviteClientTransaction, InviteClientTransaction: InviteClientTransaction, AckClientTransaction: AckClientTransaction, NonInviteServerTransaction: NonInviteServerTransaction, InviteServerTransaction: InviteServerTransaction, checkTransaction: checkTransaction }; }), /* 10 */ (function(module, exports, __webpack_require__) { "use strict"; function _classCallCheck(instance, Constructor) { if (!(instance 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; } var JsSIP_C = __webpack_require__(1); var DigestAuthentication = __webpack_require__(31); var Transactions = __webpack_require__(9); var debug = __webpack_require__(0)('JsSIP:RequestSender'); // Default event handlers. var EventHandlers = { onRequestTimeout: function onRequestTimeout() {}, onTransportError: function onTransportError() {}, onReceiveResponse: function onReceiveResponse() {}, onAuthenticated: function onAuthenticated() {} }; module.exports = /*#__PURE__*/ function () { function RequestSender(ua, request, eventHandlers) { _classCallCheck(this, RequestSender); this._ua = ua; this._eventHandlers = eventHandlers; this._method = request.method; this._request = request; this._auth = null; this._challenged = false; this._staled = false; // Define the undefined handlers. for (var handler in EventHandlers) { if (Object.prototype.hasOwnProperty.call(EventHandlers, handler)) { if (!this._eventHandlers[handler]) { this._eventHandlers[handler] = EventHandlers[handler]; } } } // If ua is in closing process or even closed just allow sending Bye and ACK. if (ua.status === ua.C.STATUS_USER_CLOSED && (this._method !== JsSIP_C.BYE || this._method !== JsSIP_C.ACK)) { this._eventHandlers.onTransportError(); } } /** * Create the client transaction and send the message. */ _createClass(RequestSender, [{ key: "send", value: function send() { var _this = this; var eventHandlers = { onRequestTimeout: function onRequestTimeout() { _this._eventHandlers.onRequestTimeout(); }, onTransportError: function onTransportError() { _this._eventHandlers.onTransportError(); }, onReceiveResponse: function onReceiveResponse(response) { _this._receiveResponse(response); } }; switch (this._method) { case 'INVITE': this.clientTransaction = new Transactions.InviteClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers); break; case 'ACK': this.clientTransaction = new Transactions.AckClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers); break; default: this.clientTransaction = new Transactions.NonInviteClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers); } this.clientTransaction.send(); } /** * Called from client transaction when receiving a correct response to the request. * Authenticate request if needed or pass the response back to the applicant. */ }, { key: "_receiveResponse", value: function _receiveResponse(response) { var challenge; var authorization_header_name; var status_code = response.status_code; /* * Authentication * Authenticate once. _challenged_ flag used to avoid infinite authentications. */ if ((status_code === 401 || status_code === 407) && (this._ua.configuration.password !== null || this._ua.configuration.ha1 !== null)) { // Get and parse the appropriate WWW-Authenticate or Proxy-Authenticate header. if (response.status_code === 401) { challenge = response.parseHeader('www-authenticate'); authorization_header_name = 'authorization'; } else { challenge = response.parseHeader('proxy-authenticate'); authorization_header_name = 'proxy-authorization'; } // Verify it seems a valid challenge. if (!challenge) { debug("".concat(response.status_code, " with wrong or missing challenge, cannot authenticate")); this._eventHandlers.onReceiveResponse(response); return; } if (!this._challenged || !this._staled && challenge.stale === true) { if (!this._auth) { this._auth = new DigestAuthentication({ username: this._ua.configuration.authorization_user, password: this._ua.configuration.password, realm: this._ua.configuration.realm, ha1: this._ua.configuration.ha1 }); } // Verify that the challenge is really valid. if (!this._auth.authenticate(this._request, challenge)) { this._eventHandlers.onReceiveResponse(response); return; } this._challenged = true; // Update ha1 and realm in the UA. this._ua.set('realm', this._auth.get('realm')); this._ua.set('ha1', this._auth.get('ha1')); if (challenge.stale) { this._staled = true; } this._request = this._request.clone(); this._request.cseq += 1; this._request.setHeader('cseq', "".concat(this._request.cseq, " ").concat(this._method)); this._request.setHeader(authorization_header_name, this._auth.toString()); this._eventHandlers.onAuthenticated(this._request); this.send(); } else { this._eventHandlers.onReceiveResponse(response); } } else { this._eventHandlers.onReceiveResponse(response); } } }]); return RequestSender; }(); }), /* 11 */ (function(module, exports, __webpack_require__) { "use strict"; function _classCallCheck(instance, Constructor) { if (!(instance 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; } var URI = __webpack_require__(8); var Grammar = __webpack_require__(3); module.exports = /*#__PURE__*/ function () { _createClass(NameAddrHeader, null, [{ key: "parse", /** * Parse the given string and returns a NameAddrHeader instance or undefined if * it is an invalid NameAddrHeader. */ value: function parse(name_addr_header) { name_addr_header = Grammar.parse(name_addr_header, 'Name_Addr_Header'); if (name_addr_header !== -1) { return name_addr_header; } else { return undefined; } } }]); function NameAddrHeader(uri, display_name, parameters) { _classCallCheck(this, NameAddrHeader); // Checks. if (!uri || !(uri instanceof URI)) { throw new TypeError('missing or invalid "uri" parameter'); } // Initialize parameters. this._uri = uri; this._parameters = {}; this._display_name = display_name; for (var param in parameters) { if (Object.prototype.hasOwnProperty.call(parameters, param)) { this.setParam(param, parameters[param]); } } } _createClass(NameAddrHeader, [{ key: "setParam", value: function setParam(key, value) { if (key) { this._parameters[key.toLowerCase()] = typeof value === 'undefined' || value === null ? null : value.toString(); } } }, { key: "getParam", value: function getParam(key) { if (key) { return this._parameters[key.toLowerCase()]; } } }, { key: "hasParam", value: function hasParam(key) { if (key) { return this._parameters.hasOwnProperty(key.toLowerCase()) && true || false; } } }, { key: "deleteParam", value: function deleteParam(parameter) { parameter = parameter.toLowerCase(); if (this._parameters.hasOwnProperty(parameter)) { var value = this._parameters[parameter]; delete this._parameters[parameter]; return value; } } }, { key: "clearParams", value: function clearParams() { this._parameters = {}; } }, { key: "clone", value: function clone() { return new NameAddrHeader(this._uri.clone(), this._display_name, JSON.parse(JSON.stringify(this._parameters))); } }, { key: "toString", value: function toString() { var body = this._display_name || this._display_name === 0 ? "\"".concat(this._display_name, "\" ") : ''; body += "<".concat(this._uri.toString(), ">"); for (var parameter in this._parameters) { if (Object.prototype.hasOwnProperty.call(this._parameters, parameter)) { body += ";".concat(parameter); if (this._parameters[parameter] !== null) { body += "=".concat(this._parameters[parameter]); } } } return body; } }, { key: "uri", get: function get() { return this._uri; } }, { key: "display_name", get: function get() { return this._display_name; }, set: function set(value) { this._display_name = value === 0 ? '0' : value; } }]); return NameAddrHeader; }(); }), /* 12 */ (function(module, exports) { module.exports = {"_from":"jssip","_id":"jssip@3.3.3","_inBundle":false,"_integrity":"sha512-SL+JkaY3w0n5Bbg7/NL/3wPTcjnkGM5IKUm6VRYYRyQTDiTR0ezLeqGjWACK2O/brT5l2QfR46AZ1iXMSLl4Dg==","_location":"/jssip","_phantomChildren":{"ms":"2.1.1"},"_requested":{"type":"tag","registry":true,"raw":"jssip","name":"jssip","escapedName":"jssip","rawSpec":"","saveSpec":null,"fetchSpec":"latest"},"_requiredBy":["#USER","/"],"_resolved":"https://registry.npmjs.org/jssip/-/jssip-3.3.3.tgz","_shasum":"d111efe06c926bf6752726668cf9e35f0c2f94fa","_spec":"jssip","_where":"/Users/entronica/eclipse-workspace/phone-js","author":{"name":"José Luis Millán","email":"jmillan@aliax.net","url":"https://github.com/jmillan"},"bugs":{"url":"https://github.com/versatica/JsSIP/issues"},"bundleDependencies":false,"contributors":[{"name":"Iñaki Baz Castillo","email":"ibc@aliax.net","url":"https://github.com/ibc"},{"name":"Saúl Ibarra Corretgé","email":"saghul@gmail.com","url":"https://github.com/saghul"}],"dependencies":{"debug":"^4.1.1","events":"^3.0.0","sdp-transform":"^2.7.0"},"deprecated":false,"description":"the Javascript SIP library","devDependencies":{"@babel/core":"^7.2.2","@babel/preset-env":"^7.2.3","ansi-colors":"^3.2.3","browserify":"^16.2.3","eslint":"^5.11.1","fancy-log":"^1.3.3","gulp":"^4.0.0","gulp-babel":"^8.0.0","gulp-eslint":"^5.0.0","gulp-expect-file":"^1.0.0","gulp-header":"^2.0.7","gulp-nodeunit-runner":"^0.2.2","gulp-plumber":"^1.2.1","gulp-rename":"^1.4.0","gulp-uglify-es":"^1.0.4","pegjs":"^0.7.0","vinyl-buffer":"^1.0.1","vinyl-source-stream":"^2.0.0"},"homepage":"https://jssip.net","keywords":["sip","websocket","webrtc","node","browser","library"],"license":"MIT","main":"lib-es5/JsSIP.js","name":"jssip","repository":{"type":"git","url":"git+https://github.com/versatica/JsSIP.git"},"scripts":{"prepublishOnly":"gulp babel","test":"gulp test"},"title":"JsSIP","version":"3.3.3"} }), /* 13 */ (function(module, exports, __webpack_require__) { var parser = __webpack_require__(27); var writer = __webpack_require__(28); exports.write = writer; exports.parse = parser.parse; exports.parseFmtpConfig = parser.parseFmtpConfig; exports.parseParams = parser.parseParams; exports.parsePayloads = parser.parsePayloads; exports.parseRemoteCandidates = parser.parseRemoteCandidates; exports.parseImageAttributes = parser.parseImageAttributes; exports.parseSimulcastStreamList = parser.parseSimulcastStreamList; }), /* 14 */ (function(module, exports) { var grammar = module.exports = { v: [{ name: 'version', reg: /^(\d*)$/ }], o: [{ //o=- 20518 0 IN IP4 203.0.113.1 // NB: sessionId will be a String in most cases because it is huge name: 'origin', reg: /^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/, names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'], format: '%s %s %d %s IP%d %s' }], // default parsing of these only (though some of these feel outdated) s: [{ name: 'name' }], i: [{ name: 'description' }], u: [{ name: 'uri' }], e: [{ name: 'email' }], p: [{ name: 'phone' }], z: [{ name: 'timezones' }], // TODO: this one can actually be parsed properly.. r: [{ name: 'repeats' }], // TODO: this one can also be parsed properly //k: [{}], // outdated thing ignored t: [{ //t=0 0 name: 'timing', reg: /^(\d*) (\d*)/, names: ['start', 'stop'], format: '%d %d' }], c: [{ //c=IN IP4 10.47.197.26 name: 'connection', reg: /^IN IP(\d) (\S*)/, names: ['version', 'ip'], format: 'IN IP%d %s' }], b: [{ //b=AS:4000 push: 'bandwidth', reg: /^(TIAS|AS|CT|RR|RS):(\d*)/, names: ['type', 'limit'], format: '%s:%s' }], m: [{ //m=video 51744 RTP/AVP 126 97 98 34 31 // NB: special - pushes to session // TODO: rtp/fmtp should be filtered by the payloads found here? reg: /^(\w*) (\d*) ([\w\/]*)(?: (.*))?/, names: ['type', 'port', 'protocol', 'payloads'], format: '%s %d %s %s' }], a: [{ //a=rtpmap:110 opus/48000/2 push: 'rtp', reg: /^rtpmap:(\d*) ([\w\-\.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/, names: ['payload', 'codec', 'rate', 'encoding'], format: function (o) { return o.encoding ? 'rtpmap:%d %s/%s/%s' : o.rate ? 'rtpmap:%d %s/%s' : 'rtpmap:%d %s'; } }, { //a=fmtp:108 profile-level-id=24;object=23;bitrate=64000 //a=fmtp:111 minptime=10; useinbandfec=1 push: 'fmtp', reg: /^fmtp:(\d*) ([\S| ]*)/, names: ['payload', 'config'], format: 'fmtp:%d %s' }, { //a=control:streamid=0 name: 'control', reg: /^control:(.*)/, format: 'control:%s' }, { //a=rtcp:65179 IN IP4 193.84.77.194 name: 'rtcp', reg: /^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/, names: ['port', 'netType', 'ipVer', 'address'], format: function (o) { return o.address != null ? 'rtcp:%d %s IP%d %s' : 'rtcp:%d'; } }, { //a=rtcp-fb:98 trr-int 100 push: 'rtcpFbTrrInt', reg: /^rtcp-fb:(\*|\d*) trr-int (\d*)/, names: ['payload', 'value'], format: 'rtcp-fb:%d trr-int %d' }, { //a=rtcp-fb:98 nack rpsi push: 'rtcpFb', reg: /^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/, names: ['payload', 'type', 'subtype'], format: function (o) { return o.subtype != null ? 'rtcp-fb:%s %s %s' : 'rtcp-fb:%s %s'; } }, { //a=extmap:2 urn:ietf:params:rtp-hdrext:toffset //a=extmap:1/recvonly URI-gps-string push: 'ext', reg: /^extmap:(\d+)(?:\/(\w+))? (\S*)(?: (\S*))?/, names: ['value', 'direction', 'uri', 'config'], format: function (o) { return 'extmap:%d' + (o.direction ? '/%s' : '%v') + ' %s' + (o.config ? ' %s' : ''); } }, { //a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32 push: 'crypto', reg: /^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/, names: ['id', 'suite', 'config', 'sessionConfig'], format: function (o) { return o.sessionConfig != null ? 'crypto:%d %s %s %s' : 'crypto:%d %s %s'; } }, { //a=setup:actpass name: 'setup', reg: /^setup:(\w*)/, format: 'setup:%s' }, { //a=mid:1 name: 'mid', reg: /^mid:([^\s]*)/, format: 'mid:%s' }, { //a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a name: 'msid', reg: /^msid:(.*)/, format: 'msid:%s' }, { //a=ptime:20 name: 'ptime', reg: /^ptime:(\d*)/, format: 'ptime:%d' }, { //a=maxptime:60 name: 'maxptime', reg: /^maxptime:(\d*)/, format: 'maxptime:%d' }, { //a=sendrecv name: 'direction', reg: /^(sendrecv|recvonly|sendonly|inactive)/ }, { //a=ice-lite name: 'icelite', reg: /^(ice-lite)/ }, { //a=ice-ufrag:F7gI name: 'iceUfrag', reg: /^ice-ufrag:(\S*)/, format: 'ice-ufrag:%s' }, { //a=ice-pwd:x9cml/YzichV2+XlhiMu8g name: 'icePwd', reg: /^ice-pwd:(\S*)/, format: 'ice-pwd:%s' }, { //a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33 name: 'fingerprint', reg: /^fingerprint:(\S*) (\S*)/, names: ['type', 'hash'], format: 'fingerprint:%s %s' }, { //a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host //a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10 //a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10 //a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10 //a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10 push: 'candidates', reg: /^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/, names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'], format: function (o) { var str = 'candidate:%s %d %s %d %s %d typ %s'; str += o.raddr != null ? ' raddr %s rport %d' : '%v%v'; // NB: candidate has three optional chunks, so %void middles one if it's missing str += o.tcptype != null ? ' tcptype %s' : '%v'; if (o.generation != null) { str += ' generation %d'; } str += o['network-id'] != null ? ' network-id %d' : '%v'; str += o['network-cost'] != null ? ' network-cost %d' : '%v'; return str; } }, { //a=end-of-candidates (keep after the candidates line for readability) name: 'endOfCandidates', reg: /^(end-of-candidates)/ }, { //a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ... name: 'remoteCandidates', reg: /^remote-candidates:(.*)/, format: 'remote-candidates:%s' }, { //a=ice-options:google-ice name: 'iceOptions', reg: /^ice-options:(\S*)/, format: 'ice-options:%s' }, { //a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1 push: 'ssrcs', reg: /^ssrc:(\d*) ([\w_-]*)(?::(.*))?/, names: ['id', 'attribute', 'value'], format: function (o) { var str = 'ssrc:%d'; if (o.attribute != null) { str += ' %s'; if (o.value != null) { str += ':%s'; } } return str; } }, { //a=ssrc-group:FEC 1 2 //a=ssrc-group:FEC-FR 3004364195 1080772241 push: 'ssrcGroups', // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E reg: /^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/, names: ['semantics', 'ssrcs'], format: 'ssrc-group:%s %s' }, { //a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV name: 'msidSemantic', reg: /^msid-semantic:\s?(\w*) (\S*)/, names: ['semantic', 'token'], format: 'msid-semantic: %s %s' // space after ':' is not accidental }, { //a=group:BUNDLE audio video push: 'groups', reg: /^group:(\w*) (.*)/, names: ['type', 'mids'], format: 'group:%s %s' }, { //a=rtcp-mux name: 'rtcpMux', reg: /^(rtcp-mux)/ }, { //a=rtcp-rsize name: 'rtcpRsize', reg: /^(rtcp-rsize)/ }, { //a=sctpmap:5000 webrtc-datachannel 1024 name: 'sctpmap', reg: /^sctpmap:([\w_\/]*) (\S*)(?: (\S*))?/, names: ['sctpmapNumber', 'app', 'maxMessageSize'], format: function (o) { return o.maxMessageSize != null ? 'sctpmap:%s %s %s' : 'sctpmap:%s %s'; } }, { //a=x-google-flag:conference name: 'xGoogleFlag', reg: /^x-google-flag:([^\s]*)/, format: 'x-google-flag:%s' }, { //a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0 push: 'rids', reg: /^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/, names: ['id', 'direction', 'params'], format: function (o) { return o.params ? 'rid:%s %s %s' : 'rid:%s %s'; } }, { //a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250] //a=imageattr:* send [x=800,y=640] recv * //a=imageattr:100 recv [x=320,y=240] push: 'imageattrs', reg: new RegExp( //a=imageattr:97 '^imageattr:(\\d+|\\*)' + //send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] '[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)' + //recv [x=330,y=250] '(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?'), names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'], format: function (o) { return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : ''); } }, { //a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8 //a=simulcast:recv 1;4,5 send 6;7 name: 'simulcast', reg: new RegExp( //a=simulcast: '^simulcast:' + //send 1,2,3;~4,~5 '(send|recv) ([a-zA-Z0-9\\-_~;,]+)' + //space + recv 6;~7,~8 '(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?' + //end '$'), names: ['dir1', 'list1', 'dir2', 'list2'], format: function (o) { return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : ''); } }, { //Old simulcast draft 03 (implemented by Firefox) // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03 //a=simulcast: recv pt=97;98 send pt=97 //a=simulcast: send rid=5;6;7 paused=6,7 name: 'simulcast_03', reg: /^simulcast:[\s\t]+([\S+\s\t]+)$/, names: ['value'], format: 'simulcast: %s' }, { //a=framerate:25 //a=framerate:29.97 name: 'framerate', reg: /^framerate:(\d+(?:$|\.\d+))/, format: 'framerate:%s' }, { // RFC4570 //a=source-filter: incl IN IP4 239.5.2.31 10.1.15.5 name: 'sourceFilter', reg: /^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/, names: ['filterMode', 'netType', 'addressTypes', 'destAddress', 'srcList'], format: 'source-filter: %s %s %s %s %s' }, { //a=bundle-only name: 'bundleOnly', reg: /^(bundle-only)/ }, { //a=label:1 name: 'label', reg: /^label:(.+)/, format: 'label:%s' }, { // RFC version 26 for SCTP over DTLS // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-5 name: 'sctpPort', reg: /^sctp-port:(\d+)$/, format: 'sctp-port:%s' }, { // RFC version 26 for SCTP over DTLS // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-6 name: 'maxMessageSize', reg: /^max-message-size:(\d+)$/, format: 'max-message-size:%s' }, { // any a= that we don't understand is kepts verbatim on media.invalid push: 'invalid', names: ['value'] }] }; // set sensible defaults to avoid polluting the grammar with boring details Object.keys(grammar).forEach(function (key) { var objs = grammar[key]; objs.forEach(function (obj) { if (!obj.reg) { obj.reg = /(.*)/; } if (!obj.format) { obj.format = '%s'; } }); }); }), /* 15 */ (function(module, exports) { // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout() { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } })(); function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch (e) { try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch (e) { // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e) { try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e) { // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while (len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return []; }; process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/'; }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function () { return 0; }; }), /* 16 */ (function(module, exports, __webpack_require__) { "use strict"; var T1 = 500, T2 = 4000, T4 = 5000; module.exports = { T1: T1, T2: T2, T4: T4, TIMER_B: 64 * T1, TIMER_D: 0 * T1, TIMER_F: 64 * T1, TIMER_H: 64 * T1, TIMER_I: 0 * T1, TIMER_J: 0 * T1, TIMER_K: 0 * T4, TIMER_L: 64 * T1, TIMER_M: 64 * T1, PROVISIONAL_RESPONSE_INTERVAL: 60000 // See RFC 3261 Section 13.3.1.1 }; }), /* 17 */ (function(module, exports, __webpack_require__) { "use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 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 _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } /* globals RTCPeerConnection: false, RTCSessionDescription: false */ var EventEmitter = __webpack_require__(7).EventEmitter; var sdp_transform = __webpack_require__(13); var JsSIP_C = __webpack_require__(1); var Exceptions = __webpack_require__(6); var Transactions = __webpack_require__(9); var Utils = __webpack_require__(2); var Timers = __webpack_require__(16); var SIPMessage = __webpack_require__(5); var Dialog = __webpack_require__(32); var RequestSender = __webpack_require__(10); var RTCSession_DTMF = __webpack_require__(34); var RTCSession_Info = __webpack_require__(35); var RTCSession_ReferNotifier = __webpack_require__(36); var RTCSession_ReferSubscriber = __webpack_require__(37); var debug = __webpack_require__(0)('JsSIP:RTCSession'); var debugerror = __webpack_require__(0)('JsSIP:ERROR:RTCSession'); var PhoneLogger = __webpack_require__(59); var PhoneNetwork = __webpack_require__(61); debugerror.log = console.warn.bind(console); var C = { // RTCSession states. STATUS_NULL: 0, STATUS_INVITE_SENT: 1, STATUS_1XX_RECEIVED: 2, STATUS_INVITE_RECEIVED: 3, STATUS_WAITING_FOR_ANSWER: 4, STATUS_ANSWERED: 5, STATUS_WAITING_FOR_ACK: 6, STATUS_CANCELED: 7, STATUS_TERMINATED: 8, STATUS_CONFIRMED: 9 }; /** * Local variables. */ var holdMediaTypes = ['audio', 'video']; module.exports = /*#__PURE__*/ function (_EventEmitter) { _inherits(RTCSession, _EventEmitter); _createClass(RTCSession, null, [{ key: "C", /** * Expose C object. */ get: function get() { return C; } }]); function RTCSession(ua) { var _this; _classCallCheck(this, RTCSession); debug('new'); _this = _possibleConstructorReturn(this, _getPrototypeOf(RTCSession).call(this)); _this._id = null; _this._ua = ua; _this._status = C.STATUS_NULL; _this._dialog = null; _this._earlyDialogs = {}; _this._contact = null; _this._from_tag = null; _this._to_tag = null; // The RTCPeerConnection instance (public attribute). _this._connection = null; // Prevent races on serial PeerConnction operations. _this._connectionPromiseQueue = Promise.resolve(); // Incoming/Outgoing request being currently processed. _this._request = null; // Cancel state for initial outgoing request. _this._is_canceled = false; _this._cancel_reason = ''; // RTCSession confirmation flag. _this._is_confirmed = false; // Is late SDP being negotiated. _this._late_sdp = false; // Default rtcOfferConstraints and rtcAnswerConstrainsts (passed in connect() or answer()). _this._rtcOfferConstraints = null; _this._rtcAnswerConstraints = null; // Local MediaStream. _this._localMediaStream = null; _this._localMediaStreamLocallyGenerated = false; // Flag to indicate PeerConnection ready for new actions. _this._rtcReady = true; // SIP Timers. _this._timers = { ackTimer: null, expiresTimer: null, invite2xxTimer: null, userNoAnswerTimer: null }; // Session info. _this._direction = null; _this._local_identity = null; _this._remote_identity = null; _this._start_time = null; _this._end_time = null; _this._tones = null; // Mute/Hold state. _this._audioMuted = false; _this._videoMuted = false; _this._localHold = false; _this._remoteHold = false; // Session Timers (RFC 4028). _this._sessionTimers = { enabled: _this._ua.configuration.session_timers, refreshMethod: _this._ua.configuration.session_timers_refresh_method, defaultExpires: JsSIP_C.SESSION_EXPIRES, currentExpires: null, running: false, refresher: false, timer: null // A setTimeout. }; // Map of ReferSubscriber instances indexed by the REFER's CSeq number. _this._referSubscribers = {}; // Custom session empty object for high level use. _this._data = {}; return _this; } /** * User API */ // Expose RTCSession constants as a property of the RTCSession instance. _createClass(RTCSession, [{ key: "isInProgress", value: function isInProgress() { switch (this._status) { case C.STATUS_NULL: case C.STATUS_INVITE_SENT: case C.STATUS_1XX_RECEIVED: case C.STATUS_INVITE_RECEIVED: case C.STATUS_WAITING_FOR_ANSWER: return true; default: return false; } } }, { key: "isEstablished", value: function isEstablished() { switch (this._status) { case C.STATUS_ANSWERED: case C.STATUS_WAITING_FOR_ACK: case C.STATUS_CONFIRMED: return true; default: return false; } } }, { key: "isEnded", value: function isEnded() { switch (this._status) { case C.STATUS_CANCELED: case C.STATUS_TERMINATED: return true; default: return false; } } }, { key: "isMuted", value: function isMuted() { return { audio: this._audioMuted, video: this._videoMuted }; } }, { key: "isOnHold", value: function isOnHold() { return { local: this._localHold, remote: this._remoteHold }; } }, { key: "connect", value: function connect(target) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var initCallback = arguments.length > 2 ? arguments[2] : undefined; debug('connect()'); var originalTarget = target; var eventHandlers = options.eventHandlers || {}; var extraHeaders = Utils.cloneArray(options.extraHeaders); var mediaConstraints = options.mediaConstraints || { audio: true, video: true }; var mediaStream = options.mediaStream || null; var pcConfig = options.pcConfig || { iceServers: [] }; var rtcConstraints = options.rtcConstraints || null; var rtcOfferConstraints = options.rtcOfferConstraints || null; this._rtcOfferConstraints = rtcOfferConstraints; this._rtcAnswerConstraints = options.rtcAnswerConstraints || null; this._data = options.data || this._data; // Check target. if (target === undefined) { throw new TypeError('Not enough arguments'); } // Check Session Status. if (this._status !== C.STATUS_NULL) { throw new Exceptions.InvalidStateError(this._status); } // Check WebRTC support. if (!window.RTCPeerConnection) { throw new Exceptions.NotSupportedError('WebRTC not supported'); } // Check target validity. target = this._ua.normalizeTarget(target); if (!target) { throw new TypeError("Invalid target: ".concat(originalTarget)); } // Session Timers. if (this._sessionTimers.enabled) { if (Utils.isDecimal(options.sessionTimersExpires)) { if (options.sessionTimersExpires >= JsSIP_C.MIN_SESSION_EXPIRES) { this._sessionTimers.defaultExpires = options.sessionTimersExpires; } else { this._sessionTimers.defaultExpires = JsSIP_C.SESSION_EXPIRES; } } } // Set event handlers. for (var event in eventHandlers) { if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) { this.on(event, eventHandlers[event]); } } // Session parameter initialization. this._from_tag = Utils.newTag(); // Set anonymous property. var anonymous = options.anonymous || false; var requestParams = { from_tag: this._from_tag }; this._contact = this._ua.contact.toString({ anonymous: anonymous, outbound: true }); if (anonymous) { requestParams.from_display_name = 'Anonymous'; requestParams.from_uri = 'sip:anonymous@anonymous.invalid'; extraHeaders.push("P-Preferred-Identity: ".concat(this._ua.configuration.uri.toString())); extraHeaders.push('Privacy: id'); } extraHeaders.push("Contact: ".concat(this._contact)); extraHeaders.push('Content-Type: application/sdp'); if (this._sessionTimers.enabled) { extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.defaultExpires)); } this._request = new SIPMessage.InitialOutgoingInviteRequest(target, this._ua, requestParams, extraHeaders); this._id = this._request.call_id + this._from_tag; // Create a new RTCPeerConnection instance. this._createRTCConnection(pcConfig, rtcConstraints); // Set internal properties. this._direction = 'outgoing'; this._local_identity = this._request.from; this._remote_identity = this._request.to; // User explicitly provided a newRTCSession callback for this session. if (initCallback) { initCallback(this); } this._newRTCSession('local', this._request); this._sendInitialRequest(mediaConstraints, rtcOfferConstraints, mediaStream); } }, { key: "init_incoming", value: function init_incoming(request, initCallback) { var _this2 = this; debug('init_incoming()'); var expires; var contentType = request.getHeader('Content-Type'); // Check body and content type. if (request.body && contentType !== 'application/sdp') { request.reply(415); return; } // Session parameter initialization. this._status = C.STATUS_INVITE_RECEIVED; this._from_tag = request.from_tag; this._id = request.call_id + this._from_tag; this._request = request; this._contact = this._ua.contact.toString(); // Get the Expires header value if exists. if (request.hasHeader('expires')) { expires = request.getHeader('expires') * 1000; } /* Set the to_tag before * replying a response code that will create a dialog. */ request.to_tag = Utils.newTag(); // An error on dialog creation will fire 'failed' event. if (!this._createDialog(request, 'UAS', true)) { request.reply(500, 'Missing Contact header field'); return; } if (request.body) { this._late_sdp = false; } else { this._late_sdp = true; } this._status = C.STATUS_WAITING_FOR_ANSWER; // Set userNoAnswerTimer. this._timers.userNoAnswerTimer = setTimeout(function () { request.reply(408); _this2._failed('local', null, JsSIP_C.causes.NO_ANSWER); }, this._ua.configuration.no_answer_timeout); /* Set expiresTimer * RFC3261 13.3.1 */ if (expires) { this._timers.expiresTimer = setTimeout(function () { if (_this2._status === C.STATUS_WAITING_FOR_ANSWER) { request.reply(487); _this2._failed('system', null, JsSIP_C.causes.EXPIRES); } }, expires); } // Set internal properties. this._direction = 'incoming'; this._local_identity = request.to; this._remote_identity = request.from; // A init callback was specifically defined. if (initCallback) { initCallback(this); } // Fire 'newRTCSession' event. this._newRTCSession('remote', request); // The user may have rejected the call in the 'newRTCSession' event. if (this._status === C.STATUS_TERMINATED) { return; } // Reply 180. request.reply(180, null, ["Contact: ".concat(this._contact)]); // Fire 'progress' event. // TODO: Document that 'response' field in 'progress' event is null for incoming calls. this._progress('local', null); } /** * Answer the call. */ }, { key: "answer", value: function answer() { var _this3 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; debug('answer()'); var request = this._request; var extraHeaders = Utils.cloneArray(options.extraHeaders); var mediaConstraints = options.mediaConstraints || {}; var mediaStream = options.mediaStream || null; var pcConfig = options.pcConfig || { iceServers: [] }; var rtcConstraints = options.rtcConstraints || null; var rtcAnswerConstraints = options.rtcAnswerConstraints || null; var tracks; var peerHasAudioLine = false; var peerHasVideoLine = false; var peerOffersFullAudio = false; var peerOffersFullVideo = false; this._rtcAnswerConstraints = rtcAnswerConstraints; this._rtcOfferConstraints = options.rtcOfferConstraints || null; this._data = options.data || this._data; // Check Session Direction and Status. if (this._direction !== 'incoming') { throw new Exceptions.NotSupportedError('"answer" not supported for outgoing RTCSession'); } // Check Session status. if (this._status !== C.STATUS_WAITING_FOR_ANSWER) { throw new Exceptions.InvalidStateError(this._status); } // Session Timers. if (this._sessionTimers.enabled) { if (Utils.isDecimal(options.sessionTimersExpires)) { if (options.sessionTimersExpires >= JsSIP_C.MIN_SESSION_EXPIRES) { this._sessionTimers.defaultExpires = options.sessionTimersExpires; } else { this._sessionTimers.defaultExpires = JsSIP_C.SESSION_EXPIRES; } } } this._status = C.STATUS_ANSWERED; // An error on dialog creation will fire 'failed' event. if (!this._createDialog(request, 'UAS')) { request.reply(500, 'Error creating dialog'); return; } clearTimeout(this._timers.userNoAnswerTimer); extraHeaders.unshift("Contact: ".concat(this._contact)); // Determine incoming media from incoming SDP offer (if any). var sdp = request.parseSDP(); // Make sure sdp.media is an array, not the case if there is only one media. if (!Array.isArray(sdp.media)) { sdp.media = [sdp.media]; } // Go through all medias in SDP to find offered capabilities to answer with. var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = sdp.media[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var m = _step.value; if (m.type === 'audio') { peerHasAudioLine = true; if (!m.direction || m.direction === 'sendrecv') { peerOffersFullAudio = true; } } if (m.type === 'video') { peerHasVideoLine = true; if (!m.direction || m.direction === 'sendrecv') { peerOffersFullVideo = true; } } } // Remove audio from mediaStream if suggested by mediaConstraints. } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } if (mediaStream && mediaConstraints.audio === false) { tracks = mediaStream.getAudioTracks(); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = tracks[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var track = _step2.value; mediaStream.removeTrack(track); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } // Remove video from mediaStream if suggested by mediaConstraints. if (mediaStream && mediaConstraints.video === false) { tracks = mediaStream.getVideoTracks(); var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = tracks[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _track = _step3.value; mediaStream.removeTrack(_track); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return != null) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } // Set audio constraints based on incoming stream if not supplied. if (!mediaStream && mediaConstraints.audio === undefined) { mediaConstraints.audio = peerOffersFullAudio; } // Set video constraints based on incoming stream if not supplied. if (!mediaStream && mediaConstraints.video === undefined) { mediaConstraints.video = peerOffersFullVideo; } // Don't ask for audio if the incoming offer has no audio section. if (!mediaStream && !peerHasAudioLine) { mediaConstraints.audio = false; } // Don't ask for video if the incoming offer has no video section. if (!mediaStream && !peerHasVideoLine) { mediaConstraints.video = false; } // Create a new RTCPeerConnection instance. // TODO: This may throw an error, should react. this._createRTCConnection(pcConfig, rtcConstraints); Promise.resolve() // Handle local MediaStream. .then(function () { // A local MediaStream is given, use it. if (mediaStream) { return mediaStream; } // Audio and/or video requested, prompt getUserMedia. else if (mediaConstraints.audio || mediaConstraints.video) { _this3._localMediaStreamLocallyGenerated = true; return navigator.mediaDevices.getUserMedia(mediaConstraints).catch(function (error) { if (_this3._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } request.reply(480); _this3._failed('local', null, JsSIP_C.causes.USER_DENIED_MEDIA_ACCESS); debugerror('emit "getusermediafailed" [error:%o]', error); _this3.emit('getusermediafailed', error); throw new Error('getUserMedia() failed'); }); } }) // Attach MediaStream to RTCPeerconnection. .then(function (stream) { if (_this3._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } _this3._localMediaStream = stream; if (stream) { var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); if(isSafari) { _this3._connection.addStream(stream); } else { stream.getTracks().forEach(function (track) { _this3._connection.addTrack(track, stream); }); } } }) // Set remote description. .then(function () { if (_this3._late_sdp) { return; } var e = { originator: 'remote', type: 'offer', sdp: request.body }; debug('emit "sdp"'); _this3.emit('sdp', e); var offer = new RTCSessionDescription({ type: 'offer', sdp: e.sdp }); _this3._connectionPromiseQueue = _this3._connectionPromiseQueue.then(function () { return _this3._connection.setRemoteDescription(offer); }).catch(function (error) { request.reply(488); _this3._failed('system', null, JsSIP_C.causes.WEBRTC_ERROR); debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error); _this3.emit('peerconnection:setremotedescriptionfailed', error); throw new Error('peerconnection.setRemoteDescription() failed'); }); return _this3._connectionPromiseQueue; }) // Create local description. .then(function () { if (_this3._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } // TODO: Is this event already useful? _this3._connecting(request); if (!_this3._late_sdp) { return _this3._createLocalDescription('answer', rtcAnswerConstraints).catch(function () { request.reply(500); throw new Error('_createLocalDescription() failed'); }); } else { return _this3._createLocalDescription('offer', _this3._rtcOfferConstraints).catch(function () { request.reply(500); throw new Error('_createLocalDescription() failed'); }); } }) // Send reply. .then(function (desc) { if (_this3._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } _this3._handleSessionTimersInIncomingRequest(request, extraHeaders); request.reply(200, null, extraHeaders, desc, function () { _this3._status = C.STATUS_WAITING_FOR_ACK; _this3._setInvite2xxTimer(request, desc); _this3._setACKTimer(); _this3._accepted('local'); }, function () { _this3._failed('system', null, JsSIP_C.causes.CONNECTION_ERROR); }); }).catch(function (error) { if (_this3._status === C.STATUS_TERMINATED) { return; } debugerror(error); }); } /** * Terminate the call. */ }, { key: "terminate", value: function terminate() { var _this4 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; debug('terminate()'); var cause = options.cause || JsSIP_C.causes.BYE; var extraHeaders = Utils.cloneArray(options.extraHeaders); var body = options.body; var cancel_reason; var status_code = options.status_code; var reason_phrase = options.reason_phrase; // Check Session Status. if (this._status === C.STATUS_TERMINATED) { throw new Exceptions.InvalidStateError(this._status); } switch (this._status) { // - UAC - case C.STATUS_NULL: case C.STATUS_INVITE_SENT: case C.STATUS_1XX_RECEIVED: debug('canceling session'); if (status_code && (status_code < 200 || status_code >= 700)) { throw new TypeError("Invalid status_code: ".concat(status_code)); } else if (status_code) { reason_phrase = reason_phrase || JsSIP_C.REASON_PHRASE[status_code] || ''; cancel_reason = "SIP ;cause=".concat(status_code, " ;text=\"").concat(reason_phrase, "\""); } // Check Session Status. if (this._status === C.STATUS_NULL || this._status === C.STATUS_INVITE_SENT) { this._is_canceled = true; this._cancel_reason = cancel_reason; } else if (this._status === C.STATUS_1XX_RECEIVED) { this._request.cancel(cancel_reason); } this._status = C.STATUS_CANCELED; this._failed('local', null, JsSIP_C.causes.CANCELED); break; // - UAS - case C.STATUS_WAITING_FOR_ANSWER: case C.STATUS_ANSWERED: debug('rejecting session'); status_code = status_code || 480; if (status_code < 300 || status_code >= 700) { throw new TypeError("Invalid status_code: ".concat(status_code)); } this._request.reply(status_code, reason_phrase, extraHeaders, body); this._failed('local', null, JsSIP_C.causes.REJECTED); break; case C.STATUS_WAITING_FOR_ACK: case C.STATUS_CONFIRMED: debug('terminating session'); reason_phrase = options.reason_phrase || JsSIP_C.REASON_PHRASE[status_code] || ''; if (status_code && (status_code < 200 || status_code >= 700)) { throw new TypeError("Invalid status_code: ".concat(status_code)); } else if (status_code) { extraHeaders.push("Reason: SIP ;cause=".concat(status_code, "; text=\"").concat(reason_phrase, "\"")); } /* RFC 3261 section 15 (Terminating a session): * * "...the callee's UA MUST NOT send a BYE on a confirmed dialog * until it has received an ACK for its 2xx response or until the server * transaction times out." */ if (this._status === C.STATUS_WAITING_FOR_ACK && this._direction === 'incoming' && this._request.server_transaction.state !== Transactions.C.STATUS_TERMINATED) { // Save the dialog for later restoration. var dialog = this._dialog; // Send the BYE as soon as the ACK is received... this.receiveRequest = function (_ref) { var method = _ref.method; if (method === JsSIP_C.ACK) { _this4.sendRequest(JsSIP_C.BYE, { extraHeaders: extraHeaders, body: body }); dialog.terminate(); } }; // .., or when the INVITE transaction times out this._request.server_transaction.on('stateChanged', function () { if (_this4._request.server_transaction.state === Transactions.C.STATUS_TERMINATED) { _this4.sendRequest(JsSIP_C.BYE, { extraHeaders: extraHeaders, body: body }); dialog.terminate(); } }); this._ended('local', null, cause); // Restore the dialog into 'this' in order to be able to send the in-dialog BYE :-). this._dialog = dialog; // Restore the dialog into 'ua' so the ACK can reach 'this' session. this._ua.newDialog(dialog); } else { this.sendRequest(JsSIP_C.BYE, { extraHeaders: extraHeaders, body: body }); this._ended('local', null, cause); } } } }, { key: "sendDTMF", value: function sendDTMF(tones) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; debug('sendDTMF() | tones: %s', tones); var position = 0; var duration = options.duration || null; var interToneGap = options.interToneGap || null; if (tones === undefined) { throw new TypeError('Not enough arguments'); } // Check Session Status. if (this._status !== C.STATUS_CONFIRMED && this._status !== C.STATUS_WAITING_FOR_ACK) { throw new Exceptions.InvalidStateError(this._status); } // Convert to string. if (typeof tones === 'number') { tones = tones.toString(); } // Check tones. if (!tones || typeof tones !== 'string' || !tones.match(/^[0-9A-DR#*,]+$/i)) { throw new TypeError("Invalid tones: ".concat(tones)); } // Check duration. if (duration && !Utils.isDecimal(duration)) { throw new TypeError("Invalid tone duration: ".concat(duration)); } else if (!duration) { duration = RTCSession_DTMF.C.DEFAULT_DURATION; } else if (duration < RTCSession_DTMF.C.MIN_DURATION) { debug("\"duration\" value is lower than the minimum allowed, setting it to ".concat(RTCSession_DTMF.C.MIN_DURATION, " milliseconds")); duration = RTCSession_DTMF.C.MIN_DURATION; } else if (duration > RTCSession_DTMF.C.MAX_DURATION) { debug("\"duration\" value is greater than the maximum allowed, setting it to ".concat(RTCSession_DTMF.C.MAX_DURATION, " milliseconds")); duration = RTCSession_DTMF.C.MAX_DURATION; } else { duration = Math.abs(duration); } options.duration = duration; // Check interToneGap. if (interToneGap && !Utils.isDecimal(interToneGap)) { throw new TypeError("Invalid interToneGap: ".concat(interToneGap)); } else if (!interToneGap) { interToneGap = RTCSession_DTMF.C.DEFAULT_INTER_TONE_GAP; } else if (interToneGap < RTCSession_DTMF.C.MIN_INTER_TONE_GAP) { debug("\"interToneGap\" value is lower than the minimum allowed, setting it to ".concat(RTCSession_DTMF.C.MIN_INTER_TONE_GAP, " milliseconds")); interToneGap = RTCSession_DTMF.C.MIN_INTER_TONE_GAP; } else { interToneGap = Math.abs(interToneGap); } if (this._tones) { // Tones are already queued, just add to the queue. this._tones += tones; return; } this._tones = tones; // Send the first tone. _sendDTMF.call(this); function _sendDTMF() { var _this5 = this; var timeout; if (this._status === C.STATUS_TERMINATED || !this._tones || position >= this._tones.length) { // Stop sending DTMF. this._tones = null; return; } var tone = this._tones[position]; position += 1; if (tone === ',') { timeout = 2000; } else { var dtmf = new RTCSession_DTMF(this); options.eventHandlers = { onFailed: function onFailed() { _this5._tones = null; } }; dtmf.send(tone, options); timeout = duration + interToneGap; } // Set timeout for the next tone. setTimeout(_sendDTMF.bind(this), timeout); } } }, { key: "sendInfo", value: function sendInfo(contentType, body) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; debug('sendInfo()'); // Check Session Status. if (this._status !== C.STATUS_CONFIRMED && this._status !== C.STATUS_WAITING_FOR_ACK) { throw new Exceptions.InvalidStateError(this._status); } var info = new RTCSession_Info(this); info.send(contentType, body, options); } /** * Mute */ }, { key: "mute", value: function mute() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { audio: true, video: false }; debug('mute()'); var audioMuted = false, videoMuted = false; if (this._audioMuted === false && options.audio) { audioMuted = true; this._audioMuted = true; this._toggleMuteAudio(true); } if (this._videoMuted === false && options.video) { videoMuted = true; this._videoMuted = true; this._toggleMuteVideo(true); } if (audioMuted === true || videoMuted === true) { this._onmute({ audio: audioMuted, video: videoMuted }); } } /** * Unmute */ }, { key: "unmute", value: function unmute() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { audio: true, video: true }; debug('unmute()'); var audioUnMuted = false, videoUnMuted = false; if (this._audioMuted === true && options.audio) { audioUnMuted = true; this._audioMuted = false; if (this._localHold === false) { this._toggleMuteAudio(false); } } if (this._videoMuted === true && options.video) { videoUnMuted = true; this._videoMuted = false; if (this._localHold === false) { this._toggleMuteVideo(false); } } if (audioUnMuted === true || videoUnMuted === true) { this._onunmute({ audio: audioUnMuted, video: videoUnMuted }); } } /** * Hold */ }, { key: "hold", value: function hold() { var _this6 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var done = arguments.length > 1 ? arguments[1] : undefined; debug('hold()'); if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) { return false; } if (this._localHold === true) { return false; } if (!this._isReadyToReOffer()) { return false; } this._localHold = true; this._onhold('local'); var eventHandlers = { succeeded: function succeeded() { if (done) { done(); } }, failed: function failed() { _this6.terminate({ cause: JsSIP_C.causes.WEBRTC_ERROR, status_code: 500, reason_phrase: 'Hold Failed' }); } }; if (options.useUpdate) { this._sendUpdate({ sdpOffer: true, eventHandlers: eventHandlers, extraHeaders: options.extraHeaders }); } else { this._sendReinvite({ eventHandlers: eventHandlers, extraHeaders: options.extraHeaders }); } return true; } }, { key: "unhold", value: function unhold() { var _this7 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var done = arguments.length > 1 ? arguments[1] : undefined; debug('unhold()'); if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) { return false; } if (this._localHold === false) { return false; } if (!this._isReadyToReOffer()) { return false; } this._localHold = false; this._onunhold('local'); var eventHandlers = { succeeded: function succeeded() { if (done) { done(); } }, failed: function failed() { _this7.terminate({ cause: JsSIP_C.causes.WEBRTC_ERROR, status_code: 500, reason_phrase: 'Unhold Failed' }); } }; if (options.useUpdate) { this._sendUpdate({ sdpOffer: true, eventHandlers: eventHandlers, extraHeaders: options.extraHeaders }); } else { this._sendReinvite({ eventHandlers: eventHandlers, extraHeaders: options.extraHeaders }); } return true; } }, { key: "renegotiate", value: function renegotiate() { var _this8 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var done = arguments.length > 1 ? arguments[1] : undefined; debug('renegotiate()'); var rtcOfferConstraints = options.rtcOfferConstraints || null; if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) { return false; } if (!this._isReadyToReOffer()) { return false; } var eventHandlers = { succeeded: function succeeded() { if (done) { done(); } }, failed: function failed() { _this8.terminate({ cause: JsSIP_C.causes.WEBRTC_ERROR, status_code: 500, reason_phrase: 'Media Renegotiation Failed' }); } }; this._setLocalMediaStatus(); if (options.useUpdate) { this._sendUpdate({ sdpOffer: true, eventHandlers: eventHandlers, rtcOfferConstraints: rtcOfferConstraints, extraHeaders: options.extraHeaders }); } else { this._sendReinvite({ eventHandlers: eventHandlers, rtcOfferConstraints: rtcOfferConstraints, extraHeaders: options.extraHeaders }); } return true; } /** * Refer */ }, { key: "refer", value: function refer(target, options) { var _this9 = this; debug('refer()'); var originalTarget = target; if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) { return false; } // Check target validity. target = this._ua.normalizeTarget(target); if (!target) { throw new TypeError("Invalid target: ".concat(originalTarget)); } var referSubscriber = new RTCSession_ReferSubscriber(this); referSubscriber.sendRefer(target, options); // Store in the map. var id = referSubscriber.id; this._referSubscribers[id] = referSubscriber; // Listen for ending events so we can remove it from the map. referSubscriber.on('requestFailed', function () { delete _this9._referSubscribers[id]; }); referSubscriber.on('accepted', function () { delete _this9._referSubscribers[id]; }); referSubscriber.on('failed', function () { delete _this9._referSubscribers[id]; }); return referSubscriber; } /** * Send a generic in-dialog Request */ }, { key: "sendRequest", value: function sendRequest(method, options) { debug('sendRequest()'); return this._dialog.sendRequest(method, options); } /** * In dialog Request Reception */ }, { key: "receiveRequest", value: function receiveRequest(request) { var _this10 = this; debug('receiveRequest()'); if (request.method === JsSIP_C.CANCEL) { /* RFC3261 15 States that a UAS may have accepted an invitation while a CANCEL * was in progress and that the UAC MAY continue with the session established by * any 2xx response, or MAY terminate with BYE. JsSIP does continue with the * established session. So the CANCEL is processed only if the session is not yet * established. */ /* * Terminate the whole session in case the user didn't accept (or yet send the answer) * nor reject the request opening the session. */ if (this._status === C.STATUS_WAITING_FOR_ANSWER || this._status === C.STATUS_ANSWERED) { this._status = C.STATUS_CANCELED; this._request.reply(487); this._failed('remote', request, JsSIP_C.causes.CANCELED); } } else { // Requests arriving here are in-dialog requests. switch (request.method) { case JsSIP_C.ACK: if (this._status !== C.STATUS_WAITING_FOR_ACK) { return; } // Update signaling status. this._status = C.STATUS_CONFIRMED; clearTimeout(this._timers.ackTimer); clearTimeout(this._timers.invite2xxTimer); if (this._late_sdp) { if (!request.body) { this.terminate({ cause: JsSIP_C.causes.MISSING_SDP, status_code: 400 }); break; } var e = { originator: 'remote', type: 'answer', sdp: request.body }; debug('emit "sdp"'); this.emit('sdp', e); var answer = new RTCSessionDescription({ type: 'answer', sdp: e.sdp }); this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () { return _this10._connection.setRemoteDescription(answer); }).then(function () { if (!_this10._is_confirmed) { _this10._confirmed('remote', request); } }).catch(function (error) { _this10.terminate({ cause: JsSIP_C.causes.BAD_MEDIA_DESCRIPTION, status_code: 488 }); debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error); _this10.emit('peerconnection:setremotedescriptionfailed', error); }); } else if (!this._is_confirmed) { this._confirmed('remote', request); } break; case JsSIP_C.BYE: if (this._status === C.STATUS_CONFIRMED) { request.reply(200); this._ended('remote', request, JsSIP_C.causes.BYE); } else if (this._status === C.STATUS_INVITE_RECEIVED) { request.reply(200); this._request.reply(487, 'BYE Received'); this._ended('remote', request, JsSIP_C.causes.BYE); } else { request.reply(403, 'Wrong Status'); } break; case JsSIP_C.INVITE: if (this._status === C.STATUS_CONFIRMED) { if (request.hasHeader('replaces')) { this._receiveReplaces(request); } else { this._receiveReinvite(request); } } else { request.reply(403, 'Wrong Status'); } break; case JsSIP_C.INFO: if (this._status === C.STATUS_1XX_RECEIVED || this._status === C.STATUS_WAITING_FOR_ANSWER || this._status === C.STATUS_ANSWERED || this._status === C.STATUS_WAITING_FOR_ACK || this._status === C.STATUS_CONFIRMED) { var contentType = request.getHeader('content-type'); if (contentType && contentType.match(/^application\/dtmf-relay/i)) { new RTCSession_DTMF(this).init_incoming(request); } else if (contentType !== undefined) { new RTCSession_Info(this).init_incoming(request); } else { request.reply(415); } } else { request.reply(403, 'Wrong Status'); } break; case JsSIP_C.UPDATE: if (this._status === C.STATUS_CONFIRMED) { this._receiveUpdate(request); } else { request.reply(403, 'Wrong Status'); } break; case JsSIP_C.REFER: if (this._status === C.STATUS_CONFIRMED) { this._receiveRefer(request); } else { request.reply(403, 'Wrong Status'); } break; case JsSIP_C.NOTIFY: if (this._status === C.STATUS_CONFIRMED) { this._receiveNotify(request); } else { request.reply(403, 'Wrong Status'); } break; default: request.reply(501); } } } /** * Session Callbacks */ }, { key: "onTransportError", value: function onTransportError() { debugerror('onTransportError()'); if (this._status !== C.STATUS_TERMINATED) { this.terminate({ status_code: 500, reason_phrase: JsSIP_C.causes.CONNECTION_ERROR, cause: JsSIP_C.causes.CONNECTION_ERROR }); } } }, { key: "onRequestTimeout", value: function onRequestTimeout() { debugerror('onRequestTimeout()'); if (this._status !== C.STATUS_TERMINATED) { this.terminate({ status_code: 408, reason_phrase: JsSIP_C.causes.REQUEST_TIMEOUT, cause: JsSIP_C.causes.REQUEST_TIMEOUT }); } } }, { key: "onDialogError", value: function onDialogError() { debugerror('onDialogError()'); if (this._status !== C.STATUS_TERMINATED) { this.terminate({ status_code: 500, reason_phrase: JsSIP_C.causes.DIALOG_ERROR, cause: JsSIP_C.causes.DIALOG_ERROR }); } } // Called from DTMF handler. }, { key: "newDTMF", value: function newDTMF(data) { debug('newDTMF()'); this.emit('newDTMF', data); } // Called from Info handler. }, { key: "newInfo", value: function newInfo(data) { debug('newInfo()'); this.emit('newInfo', data); } /** * Check if RTCSession is ready for an outgoing re-INVITE or UPDATE with SDP. */ }, { key: "_isReadyToReOffer", value: function _isReadyToReOffer() { if (!this._rtcReady) { debug('_isReadyToReOffer() | internal WebRTC status not ready'); return false; } // No established yet. if (!this._dialog) { debug('_isReadyToReOffer() | session not established yet'); return false; } // Another INVITE transaction is in progress. if (this._dialog.uac_pending_reply === true || this._dialog.uas_pending_reply === true) { debug('_isReadyToReOffer() | there is another INVITE/UPDATE transaction in progress'); return false; } return true; } }, { key: "_close", value: function _close() { debug('close()'); if (this._status === C.STATUS_TERMINATED) { return; } this._status = C.STATUS_TERMINATED; // Terminate RTC. if (this._connection) { try { this._connection.close(); } catch (error) { debugerror('close() | error closing the RTCPeerConnection: %o', error); } } // Close local MediaStream if it was not given by the user. if (this._localMediaStream && this._localMediaStreamLocallyGenerated) { debug('close() | closing local MediaStream'); Utils.closeMediaStream(this._localMediaStream); } // Terminate signaling. // Clear SIP timers. for (var timer in this._timers) { if (Object.prototype.hasOwnProperty.call(this._timers, timer)) { clearTimeout(this._timers[timer]); } } // Clear Session Timers. clearTimeout(this._sessionTimers.timer); // Terminate confirmed dialog. if (this._dialog) { this._dialog.terminate(); delete this._dialog; } // Terminate early dialogs. for (var dialog in this._earlyDialogs) { if (Object.prototype.hasOwnProperty.call(this._earlyDialogs, dialog)) { this._earlyDialogs[dialog].terminate(); delete this._earlyDialogs[dialog]; } } // Terminate REFER subscribers. for (var subscriber in this._referSubscribers) { if (Object.prototype.hasOwnProperty.call(this._referSubscribers, subscriber)) { delete this._referSubscribers[subscriber]; } } this._ua.destroyRTCSession(this); } /** * Private API. */ /** * RFC3261 13.3.1.4 * Response retransmissions cannot be accomplished by transaction layer * since it is destroyed when receiving the first 2xx answer */ }, { key: "_setInvite2xxTimer", value: function _setInvite2xxTimer(request, body) { var timeout = Timers.T1; function invite2xxRetransmission() { if (this._status !== C.STATUS_WAITING_FOR_ACK) { return; } request.reply(200, null, ["Contact: ".concat(this._contact)], body); if (timeout < Timers.T2) { timeout = timeout * 2; if (timeout > Timers.T2) { timeout = Timers.T2; } } this._timers.invite2xxTimer = setTimeout(invite2xxRetransmission.bind(this), timeout); } this._timers.invite2xxTimer = setTimeout(invite2xxRetransmission.bind(this), timeout); } /** * RFC3261 14.2 * If a UAS generates a 2xx response and never receives an ACK, * it SHOULD generate a BYE to terminate the dialog. */ }, { key: "_setACKTimer", value: function _setACKTimer() { var _this11 = this; this._timers.ackTimer = setTimeout(function () { if (_this11._status === C.STATUS_WAITING_FOR_ACK) { debug('no ACK received, terminating the session'); clearTimeout(_this11._timers.invite2xxTimer); _this11.sendRequest(JsSIP_C.BYE); _this11._ended('remote', null, JsSIP_C.causes.NO_ACK); } }, Timers.TIMER_H); } }, { key: "_createRTCConnection", value: function _createRTCConnection(pcConfig, rtcConstraints) { var _this12 = this; this._connection = new RTCPeerConnection(pcConfig, rtcConstraints); this._connection.addEventListener('iceconnectionstatechange', function () { var state = _this12._connection.iceConnectionState; // TODO: Do more with different states. if (state === 'failed') { _this12.terminate({ cause: JsSIP_C.causes.RTP_TIMEOUT, status_code: 408, reason_phrase: JsSIP_C.causes.RTP_TIMEOUT }); } }); debug('emit "peerconnection"'); this.emit('peerconnection', { peerconnection: this._connection }); } }, { key: "_createLocalDescription", value: function _createLocalDescription(type, constraints) { var _this13 = this; debug('createLocalDescription()'); if (type !== 'offer' && type !== 'answer') throw new Error("createLocalDescription() | invalid type \"".concat(type, "\"")); var connection = this._connection; this._rtcReady = false; return Promise.resolve() // Create Offer or Answer. .then(function () { if (type === 'offer') { return connection.createOffer(constraints).catch(function (error) { debugerror('emit "peerconnection:createofferfailed" [error:%o]', error); _this13.emit('peerconnection:createofferfailed', error); return Promise.reject(error); }); } else { return connection.createAnswer(constraints).catch(function (error) { debugerror('emit "peerconnection:createanswerfailed" [error:%o]', error); _this13.emit('peerconnection:createanswerfailed', error); return Promise.reject(error); }); } }) // Set local description. .then(function (desc) { return connection.setLocalDescription(desc).catch(function (error) { _this13._rtcReady = true; debugerror('emit "peerconnection:setlocaldescriptionfailed" [error:%o]', error); _this13.emit('peerconnection:setlocaldescriptionfailed', error); return Promise.reject(error); }); }).then(function () { // Resolve right away if 'pc.iceGatheringState' is 'complete'. if (connection.iceGatheringState === 'complete') { _this13._rtcReady = true; var e = { originator: 'local', type: type, sdp: connection.localDescription.sdp }; debug('emit "sdp"'); _this13.emit('sdp', e); return Promise.resolve(e.sdp); } // Add 'pc.onicencandidate' event handler to resolve on last candidate. return new Promise(function (resolve) { var finished = false; var listener; var ready = function ready() { connection.removeEventListener('icecandidate', listener); finished = true; _this13._rtcReady = true; var e = { originator: 'local', type: type, sdp: connection.localDescription.sdp }; debug('emit "sdp"'); _this13.emit('sdp', e); resolve(e.sdp); }; connection.addEventListener('icecandidate', listener = function listener(event) { var candidate = event.candidate; if (candidate) { _this13.emit('icecandidate', { candidate: candidate, ready: ready }); } else if (!finished) { ready(); } }); }); }); } /** * Dialog Management */ }, { key: "_createDialog", value: function _createDialog(message, type, early) { var local_tag = type === 'UAS' ? message.to_tag : message.from_tag; var remote_tag = type === 'UAS' ? message.from_tag : message.to_tag; var id = message.call_id + local_tag + remote_tag; var early_dialog = this._earlyDialogs[id]; // Early Dialog. if (early) { if (early_dialog) { return true; } else { early_dialog = new Dialog(this, message, type, Dialog.C.STATUS_EARLY); // Dialog has been successfully created. if (early_dialog.error) { debug(early_dialog.error); this._failed('remote', message, JsSIP_C.causes.INTERNAL_ERROR); return false; } else { this._earlyDialogs[id] = early_dialog; return true; } } } // Confirmed Dialog. else { this._from_tag = message.from_tag; this._to_tag = message.to_tag; // In case the dialog is in _early_ state, update it. if (early_dialog) { early_dialog.update(message, type); this._dialog = early_dialog; delete this._earlyDialogs[id]; return true; } // Otherwise, create a _confirmed_ dialog. var dialog = new Dialog(this, message, type); if (dialog.error) { debug(dialog.error); this._failed('remote', message, JsSIP_C.causes.INTERNAL_ERROR); return false; } else { this._dialog = dialog; return true; } } } /** * In dialog INVITE Reception */ }, { key: "_receiveReinvite", value: function _receiveReinvite(request) { var _this14 = this; debug('receiveReinvite()'); var contentType = request.getHeader('Content-Type'); var data = { request: request, callback: undefined, reject: reject.bind(this) }; var rejected = false; function reject() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; rejected = true; var status_code = options.status_code || 403; var reason_phrase = options.reason_phrase || ''; var extraHeaders = Utils.cloneArray(options.extraHeaders); if (this._status !== C.STATUS_CONFIRMED) { return false; } if (status_code < 300 || status_code >= 700) { throw new TypeError("Invalid status_code: ".concat(status_code)); } request.reply(status_code, reason_phrase, extraHeaders); } // Emit 'reinvite'. this.emit('reinvite', data); if (rejected) { return; } this._late_sdp = false; // Request without SDP. if (!request.body) { this._late_sdp = true; this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () { return _this14._createLocalDescription('offer', _this14._rtcOfferConstraints); }).then(function (sdp) { sendAnswer.call(_this14, sdp); }).catch(function () { request.reply(500); }); return; } // Request with SDP. if (contentType !== 'application/sdp') { debug('invalid Content-Type'); request.reply(415); return; } this._processInDialogSdpOffer(request) // Send answer. .then(function (desc) { if (_this14._status === C.STATUS_TERMINATED) { return; } sendAnswer.call(_this14, desc); }).catch(function (error) { debugerror(error); }); function sendAnswer(desc) { var _this15 = this; var extraHeaders = ["Contact: ".concat(this._contact)]; this._handleSessionTimersInIncomingRequest(request, extraHeaders); if (this._late_sdp) { desc = this._mangleOffer(desc); } request.reply(200, null, extraHeaders, desc, function () { _this15._status = C.STATUS_WAITING_FOR_ACK; _this15._setInvite2xxTimer(request, desc); _this15._setACKTimer(); }); // If callback is given execute it. if (typeof data.callback === 'function') { data.callback(); } } } /** * In dialog UPDATE Reception */ }, { key: "_receiveUpdate", value: function _receiveUpdate(request) { var _this16 = this; debug('receiveUpdate()'); var contentType = request.getHeader('Content-Type'); var data = { request: request, callback: undefined, reject: reject.bind(this) }; var rejected = false; function reject() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; rejected = true; var status_code = options.status_code || 403; var reason_phrase = options.reason_phrase || ''; var extraHeaders = Utils.cloneArray(options.extraHeaders); if (this._status !== C.STATUS_CONFIRMED) { return false; } if (status_code < 300 || status_code >= 700) { throw new TypeError("Invalid status_code: ".concat(status_code)); } request.reply(status_code, reason_phrase, extraHeaders); } // Emit 'update'. this.emit('update', data); if (rejected) { return; } if (!request.body) { sendAnswer.call(this, null); return; } if (contentType !== 'application/sdp') { debug('invalid Content-Type'); request.reply(415); return; } this._processInDialogSdpOffer(request) // Send answer. .then(function (desc) { if (_this16._status === C.STATUS_TERMINATED) { return; } sendAnswer.call(_this16, desc); }).catch(function (error) { debugerror(error); }); function sendAnswer(desc) { var extraHeaders = ["Contact: ".concat(this._contact)]; this._handleSessionTimersInIncomingRequest(request, extraHeaders); request.reply(200, null, extraHeaders, desc); // If callback is given execute it. if (typeof data.callback === 'function') { data.callback(); } } } }, { key: "_processInDialogSdpOffer", value: function _processInDialogSdpOffer(request) { var _this17 = this; debug('_processInDialogSdpOffer()'); var sdp = request.parseSDP(); var hold = false; var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = sdp.media[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var m = _step4.value; if (holdMediaTypes.indexOf(m.type) === -1) { continue; } var direction = m.direction || sdp.direction || 'sendrecv'; if (direction === 'sendonly' || direction === 'inactive') { hold = true; } // If at least one of the streams is active don't emit 'hold'. else { hold = false; break; } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return != null) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } var e = { originator: 'remote', type: 'offer', sdp: request.body }; debug('emit "sdp"'); this.emit('sdp', e); var offer = new RTCSessionDescription({ type: 'offer', sdp: e.sdp }); this._connectionPromiseQueue = this._connectionPromiseQueue // Set remote description. .then(function () { if (_this17._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } return _this17._connection.setRemoteDescription(offer).catch(function (error) { request.reply(488); debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error); _this17.emit('peerconnection:setremotedescriptionfailed', error); throw new Error('peerconnection.setRemoteDescription() failed'); }); }).then(function () { if (_this17._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } if (_this17._remoteHold === true && hold === false) { _this17._remoteHold = false; _this17._onunhold('remote'); } else if (_this17._remoteHold === false && hold === true) { _this17._remoteHold = true; _this17._onhold('remote'); } }) // Create local description. .then(function () { if (_this17._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } return _this17._createLocalDescription('answer', _this17._rtcAnswerConstraints).catch(function () { request.reply(500); throw new Error('_createLocalDescription() failed'); }); }); return this._connectionPromiseQueue; } /** * In dialog Refer Reception */ }, { key: "_receiveRefer", value: function _receiveRefer(request) { var _this18 = this; debug('receiveRefer()'); if (!request.refer_to) { debug('no Refer-To header field present in REFER'); request.reply(400); return; } if (request.refer_to.uri.scheme !== JsSIP_C.SIP) { debug('Refer-To header field points to a non-SIP URI scheme'); request.reply(416); return; } // Reply before the transaction timer expires. request.reply(202); var notifier = new RTCSession_ReferNotifier(this, request.cseq); debug('emit "refer"'); // Emit 'refer'. this.emit('refer', { request: request, accept: function accept(initCallback, options) { _accept.call(_this18, initCallback, options); }, reject: function reject() { _reject.call(_this18); } }); function _accept(initCallback) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; initCallback = typeof initCallback === 'function' ? initCallback : null; if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) { return false; } var session = new RTCSession(this._ua); session.on('progress', function (_ref2) { var response = _ref2.response; notifier.notify(response.status_code, response.reason_phrase); }); session.on('accepted', function (_ref3) { var response = _ref3.response; notifier.notify(response.status_code, response.reason_phrase); }); session.on('_failed', function (_ref4) { var message = _ref4.message, cause = _ref4.cause; if (message) { notifier.notify(message.status_code, message.reason_phrase); } else { notifier.notify(487, cause); } }); // Consider the Replaces header present in the Refer-To URI. if (request.refer_to.uri.hasHeader('replaces')) { var replaces = decodeURIComponent(request.refer_to.uri.getHeader('replaces')); options.extraHeaders = Utils.cloneArray(options.extraHeaders); options.extraHeaders.push("Replaces: ".concat(replaces)); } session.connect(request.refer_to.uri.toAor(), options, initCallback); } function _reject() { notifier.notify(603); } } /** * In dialog Notify Reception */ }, { key: "_receiveNotify", value: function _receiveNotify(request) { debug('receiveNotify()'); if (!request.event) { request.reply(400); } switch (request.event.event) { case 'refer': { var id; var referSubscriber; if (request.event.params && request.event.params.id) { id = request.event.params.id; referSubscriber = this._referSubscribers[id]; } else if (Object.keys(this._referSubscribers).length === 1) { referSubscriber = this._referSubscribers[Object.keys(this._referSubscribers)[0]]; } else { request.reply(400, 'Missing event id parameter'); return; } if (!referSubscriber) { request.reply(481, 'Subscription does not exist'); return; } referSubscriber.receiveNotify(request); request.reply(200); break; } default: { request.reply(489); } } } /** * INVITE with Replaces Reception */ }, { key: "_receiveReplaces", value: function _receiveReplaces(request) { var _this20 = this; debug('receiveReplaces()'); function _accept2(initCallback) { var _this19 = this; if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) { return false; } var session = new RTCSession(this._ua); // Terminate the current session when the new one is confirmed. session.on('confirmed', function () { _this19.terminate(); }); session.init_incoming(request, initCallback); } function _reject2() { debug('Replaced INVITE rejected by the user'); request.reply(486); } // Emit 'replace'. this.emit('replaces', { request: request, accept: function accept(initCallback) { _accept2.call(_this20, initCallback); }, reject: function reject() { _reject2.call(_this20); } }); } /** * Initial Request Sender */ }, { key: "_sendInitialRequest", value: function _sendInitialRequest(mediaConstraints, rtcOfferConstraints, mediaStream) { var _this21 = this; var request_sender = new RequestSender(this._ua, this._request, { onRequestTimeout: function onRequestTimeout() { _this21.onRequestTimeout(); }, onTransportError: function onTransportError() { _this21.onTransportError(); }, // Update the request on authentication. onAuthenticated: function onAuthenticated(request) { _this21._request = request; }, onReceiveResponse: function onReceiveResponse(response) { _this21._receiveInviteResponse(response); } }); // This Promise is resolved within the next iteration, so the app has now // a chance to set events such as 'peerconnection' and 'connecting'. Promise.resolve() // Get a stream if required. .then(function () { // A stream is given, let the app set events such as 'peerconnection' and 'connecting'. if (mediaStream) { return mediaStream; } // Request for user media access. else if (mediaConstraints.audio || mediaConstraints.video) { _this21._localMediaStreamLocallyGenerated = true; return navigator.mediaDevices.getUserMedia(mediaConstraints).catch(function (error) { if (_this21._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } _this21._failed('local', null, JsSIP_C.causes.USER_DENIED_MEDIA_ACCESS); debugerror('emit "getusermediafailed" [error:%o]', error); _this21.emit('getusermediafailed', error); throw error; }); } }).then(function (stream) { if (_this21._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } _this21._localMediaStream = stream; if (stream) { var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); if(isSafari) { _this21._connection.addStream(stream); } else { stream.getTracks().forEach(function (track) { _this21._connection.addTrack(track, stream); }); } } // TODO: should this be triggered here? _this21._connecting(_this21._request); return _this21._createLocalDescription('offer', rtcOfferConstraints).catch(function (error) { _this21._failed('local', null, JsSIP_C.causes.WEBRTC_ERROR); throw error; }); }).then(function (desc) { if (_this21._is_canceled || _this21._status === C.STATUS_TERMINATED) { throw new Error('terminated'); } _this21._request.body = desc; _this21._status = C.STATUS_INVITE_SENT; debug('emit "sending" [request:%o]', _this21._request); // Emit 'sending' so the app can mangle the body before the request is sent. _this21.emit('sending', { request: _this21._request }); request_sender.send(); }).catch(function (error) { if (_this21._status === C.STATUS_TERMINATED) { return; } debugerror(error); }); } /** * Reception of Response for Initial INVITE */ }, { key: "_receiveInviteResponse", value: function _receiveInviteResponse(response) { var _this22 = this; debug('receiveInviteResponse()'); // Handle 2XX retransmissions and responses from forked requests. if (this._dialog && response.status_code >= 200 && response.status_code <= 299) { /* * If it is a retransmission from the endpoint that established * the dialog, send an ACK */ if (this._dialog.id.call_id === response.call_id && this._dialog.id.local_tag === response.from_tag && this._dialog.id.remote_tag === response.to_tag) { this.sendRequest(JsSIP_C.ACK); return; } // If not, send an ACK and terminate. else { var dialog = new Dialog(this, response, 'UAC'); if (dialog.error !== undefined) { debug(dialog.error); return; } this.sendRequest(JsSIP_C.ACK); this.sendRequest(JsSIP_C.BYE); return; } } // Proceed to cancellation if the user requested. if (this._is_canceled) { if (response.status_code >= 100 && response.status_code < 200) { this._request.cancel(this._cancel_reason); } else if (response.status_code >= 200 && response.status_code < 299) { this._acceptAndTerminate(response); } return; } if (this._status !== C.STATUS_INVITE_SENT && this._status !== C.STATUS_1XX_RECEIVED) { return; } switch (true) { case /^100$/.test(response.status_code): this._status = C.STATUS_1XX_RECEIVED; break; case /^1[0-9]{2}$/.test(response.status_code): { // Do nothing with 1xx responses without To tag. if (!response.to_tag) { debug('1xx response received without to tag'); break; } // Create Early Dialog if 1XX comes with contact. if (response.hasHeader('contact')) { // An error on dialog creation will fire 'failed' event. if (!this._createDialog(response, 'UAC', true)) { break; } } this._status = C.STATUS_1XX_RECEIVED; this._progress('remote', response); if (!response.body) { break; } var e = { originator: 'remote', type: 'answer', sdp: response.body }; debug('emit "sdp"'); this.emit('sdp', e); var answer = new RTCSessionDescription({ type: 'answer', sdp: e.sdp }); this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () { return _this22._connection.setRemoteDescription(answer); }).catch(function (error) { debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error); _this22.emit('peerconnection:setremotedescriptionfailed', error); }); break; } case /^2[0-9]{2}$/.test(response.status_code): { this._status = C.STATUS_CONFIRMED; if (!response.body) { this._acceptAndTerminate(response, 400, JsSIP_C.causes.MISSING_SDP); this._failed('remote', response, JsSIP_C.causes.BAD_MEDIA_DESCRIPTION); break; } // An error on dialog creation will fire 'failed' event. if (!this._createDialog(response, 'UAC')) { break; } var _e = { originator: 'remote', type: 'answer', sdp: response.body }; debug('emit "sdp"'); this.emit('sdp', _e); var _answer = new RTCSessionDescription({ type: 'answer', sdp: _e.sdp }); this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () { // Be ready for 200 with SDP after a 180/183 with SDP. // We created a SDP 'answer' for it, so check the current signaling state. if (_this22._connection.signalingState === 'stable') { return _this22._connection.createOffer(_this22._rtcOfferConstraints).then(function (offer) { return _this22._connection.setLocalDescription(offer); }).catch(function (error) { _this22._acceptAndTerminate(response, 500, error.toString()); _this22._failed('local', response, JsSIP_C.causes.WEBRTC_ERROR); }); } }).then(function () { _this22._connection.setRemoteDescription(_answer).then(function () { // Handle Session Timers. _this22._handleSessionTimersInIncomingResponse(response); _this22._accepted('remote', response); _this22.sendRequest(JsSIP_C.ACK); _this22._confirmed('local', null); }).catch(function (error) { _this22._acceptAndTerminate(response, 488, 'Not Acceptable Here'); _this22._failed('remote', response, JsSIP_C.causes.BAD_MEDIA_DESCRIPTION); debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error); _this22.emit('peerconnection:setremotedescriptionfailed', error); }); }); break; } default: { var cause = Utils.sipErrorCause(response.status_code); this._failed('remote', response, cause); } } } /** * Send Re-INVITE */ }, { key: "_sendReinvite", value: function _sendReinvite() { var _this23 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; debug('sendReinvite()'); var extraHeaders = Utils.cloneArray(options.extraHeaders); var eventHandlers = options.eventHandlers || {}; var rtcOfferConstraints = options.rtcOfferConstraints || this._rtcOfferConstraints || null; var succeeded = false; extraHeaders.push("Contact: ".concat(this._contact)); extraHeaders.push('Content-Type: application/sdp'); // Session Timers. if (this._sessionTimers.running) { extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(this._sessionTimers.refresher ? 'uac' : 'uas')); } this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () { return _this23._createLocalDescription('offer', rtcOfferConstraints); }).then(function (sdp) { sdp = _this23._mangleOffer(sdp); var e = { originator: 'local', type: 'offer', sdp: sdp }; debug('emit "sdp"'); _this23.emit('sdp', e); _this23.sendRequest(JsSIP_C.INVITE, { extraHeaders: extraHeaders, body: sdp, eventHandlers: { onSuccessResponse: function onSuccessResponse(response) { onSucceeded.call(_this23, response); succeeded = true; }, onErrorResponse: function onErrorResponse(response) { onFailed.call(_this23, response); }, onTransportError: function onTransportError() { _this23.onTransportError(); // Do nothing because session ends. }, onRequestTimeout: function onRequestTimeout() { _this23.onRequestTimeout(); // Do nothing because session ends. }, onDialogError: function onDialogError() { _this23.onDialogError(); // Do nothing because session ends. } } }); }).catch(function () { onFailed(); }); function onSucceeded(response) { var _this24 = this; if (this._status === C.STATUS_TERMINATED) { return; } this.sendRequest(JsSIP_C.ACK); // If it is a 2XX retransmission exit now. if (succeeded) { return; } // Handle Session Timers. this._handleSessionTimersInIncomingResponse(response); // Must have SDP answer. if (!response.body) { onFailed.call(this); return; } else if (response.getHeader('Content-Type') !== 'application/sdp') { onFailed.call(this); return; } var e = { originator: 'remote', type: 'answer', sdp: response.body }; debug('emit "sdp"'); this.emit('sdp', e); var answer = new RTCSessionDescription({ type: 'answer', sdp: e.sdp }); this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () { return _this24._connection.setRemoteDescription(answer); }).then(function () { if (eventHandlers.succeeded) { eventHandlers.succeeded(response); } }).catch(function (error) { onFailed.call(_this24); debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error); _this24.emit('peerconnection:setremotedescriptionfailed', error); }); } function onFailed(response) { if (eventHandlers.failed) { eventHandlers.failed(response); } } } /** * Send UPDATE */ }, { key: "_sendUpdate", value: function _sendUpdate() { var _this25 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; debug('sendUpdate()'); var extraHeaders = Utils.cloneArray(options.extraHeaders); var eventHandlers = options.eventHandlers || {}; var rtcOfferConstraints = options.rtcOfferConstraints || this._rtcOfferConstraints || null; var sdpOffer = options.sdpOffer || false; var succeeded = false; extraHeaders.push("Contact: ".concat(this._contact)); // Session Timers. if (this._sessionTimers.running) { extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(this._sessionTimers.refresher ? 'uac' : 'uas')); } if (sdpOffer) { extraHeaders.push('Content-Type: application/sdp'); this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () { return _this25._createLocalDescription('offer', rtcOfferConstraints); }).then(function (sdp) { sdp = _this25._mangleOffer(sdp); var e = { originator: 'local', type: 'offer', sdp: sdp }; debug('emit "sdp"'); _this25.emit('sdp', e); _this25.sendRequest(JsSIP_C.UPDATE, { extraHeaders: extraHeaders, body: sdp, eventHandlers: { onSuccessResponse: function onSuccessResponse(response) { onSucceeded.call(_this25, response); succeeded = true; }, onErrorResponse: function onErrorResponse(response) { onFailed.call(_this25, response); }, onTransportError: function onTransportError() { _this25.onTransportError(); // Do nothing because session ends. }, onRequestTimeout: function onRequestTimeout() { _this25.onRequestTimeout(); // Do nothing because session ends. }, onDialogError: function onDialogError() { _this25.onDialogError(); // Do nothing because session ends. } } }); }).catch(function () { onFailed.call(_this25); }); } // No SDP. else { this.sendRequest(JsSIP_C.UPDATE, { extraHeaders: extraHeaders, eventHandlers: { onSuccessResponse: function onSuccessResponse(response) { onSucceeded.call(_this25, response); }, onErrorResponse: function onErrorResponse(response) { onFailed.call(_this25, response); }, onTransportError: function onTransportError() { _this25.onTransportError(); // Do nothing because session ends. }, onRequestTimeout: function onRequestTimeout() { _this25.onRequestTimeout(); // Do nothing because session ends. }, onDialogError: function onDialogError() { _this25.onDialogError(); // Do nothing because session ends. } } }); } function onSucceeded(response) { var _this26 = this; if (this._status === C.STATUS_TERMINATED) { return; } // If it is a 2XX retransmission exit now. if (succeeded) { return; } // Handle Session Timers. this._handleSessionTimersInIncomingResponse(response); // Must have SDP answer. if (sdpOffer) { if (!response.body) { onFailed.call(this); return; } else if (response.getHeader('Content-Type') !== 'application/sdp') { onFailed.call(this); return; } var e = { originator: 'remote', type: 'answer', sdp: response.body }; debug('emit "sdp"'); this.emit('sdp', e); var answer = new RTCSessionDescription({ type: 'answer', sdp: e.sdp }); this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () { return _this26._connection.setRemoteDescription(answer); }).then(function () { if (eventHandlers.succeeded) { eventHandlers.succeeded(response); } }).catch(function (error) { onFailed.call(_this26); debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error); _this26.emit('peerconnection:setremotedescriptionfailed', error); }); } // No SDP answer. else if (eventHandlers.succeeded) { eventHandlers.succeeded(response); } } function onFailed(response) { if (eventHandlers.failed) { eventHandlers.failed(response); } } } }, { key: "_acceptAndTerminate", value: function _acceptAndTerminate(response, status_code, reason_phrase) { debug('acceptAndTerminate()'); var extraHeaders = []; if (status_code) { reason_phrase = reason_phrase || JsSIP_C.REASON_PHRASE[status_code] || ''; extraHeaders.push("Reason: SIP ;cause=".concat(status_code, "; text=\"").concat(reason_phrase, "\"")); } // An error on dialog creation will fire 'failed' event. if (this._dialog || this._createDialog(response, 'UAC')) { this.sendRequest(JsSIP_C.ACK); this.sendRequest(JsSIP_C.BYE, { extraHeaders: extraHeaders }); } // Update session status. this._status = C.STATUS_TERMINATED; } /** * Correctly set the SDP direction attributes if the call is on local hold */ }, { key: "_mangleOffer", value: function _mangleOffer(sdp) { if (!this._localHold && !this._remoteHold) { return sdp; } sdp = sdp_transform.parse(sdp); // Local hold. if (this._localHold && !this._remoteHold) { debug('mangleOffer() | me on hold, mangling offer'); var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = sdp.media[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var m = _step5.value; if (holdMediaTypes.indexOf(m.type) === -1) { continue; } if (!m.direction) { m.direction = 'sendonly'; } else if (m.direction === 'sendrecv') { m.direction = 'sendonly'; } else if (m.direction === 'recvonly') { m.direction = 'inactive'; } } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return != null) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } } // Local and remote hold. else if (this._localHold && this._remoteHold) { debug('mangleOffer() | both on hold, mangling offer'); var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { for (var _iterator6 = sdp.media[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { var _m = _step6.value; if (holdMediaTypes.indexOf(_m.type) === -1) { continue; } _m.direction = 'inactive'; } } catch (err) { _didIteratorError6 = true; _iteratorError6 = err; } finally { try { if (!_iteratorNormalCompletion6 && _iterator6.return != null) { _iterator6.return(); } } finally { if (_didIteratorError6) { throw _iteratorError6; } } } } // Remote hold. else if (this._remoteHold) { debug('mangleOffer() | remote on hold, mangling offer'); var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { for (var _iterator7 = sdp.media[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { var _m2 = _step7.value; if (holdMediaTypes.indexOf(_m2.type) === -1) { continue; } if (!_m2.direction) { _m2.direction = 'recvonly'; } else if (_m2.direction === 'sendrecv') { _m2.direction = 'recvonly'; } else if (_m2.direction === 'recvonly') { _m2.direction = 'inactive'; } } } catch (err) { _didIteratorError7 = true; _iteratorError7 = err; } finally { try { if (!_iteratorNormalCompletion7 && _iterator7.return != null) { _iterator7.return(); } } finally { if (_didIteratorError7) { throw _iteratorError7; } } } } return sdp_transform.write(sdp); } }, { key: "_setLocalMediaStatus", value: function _setLocalMediaStatus() { var enableAudio = true, enableVideo = true; if (this._localHold || this._remoteHold) { enableAudio = false; enableVideo = false; } if (this._audioMuted) { enableAudio = false; } if (this._videoMuted) { enableVideo = false; } this._toggleMuteAudio(!enableAudio); this._toggleMuteVideo(!enableVideo); } /** * Handle SessionTimers for an incoming INVITE or UPDATE. * @param {IncomingRequest} request * @param {Array} responseExtraHeaders Extra headers for the 200 response. */ }, { key: "_handleSessionTimersInIncomingRequest", value: function _handleSessionTimersInIncomingRequest(request, responseExtraHeaders) { if (!this._sessionTimers.enabled) { return; } var session_expires_refresher; if (request.session_expires && request.session_expires >= JsSIP_C.MIN_SESSION_EXPIRES) { this._sessionTimers.currentExpires = request.session_expires; session_expires_refresher = request.session_expires_refresher || 'uas'; } else { this._sessionTimers.currentExpires = this._sessionTimers.defaultExpires; session_expires_refresher = 'uas'; } responseExtraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(session_expires_refresher)); this._sessionTimers.refresher = session_expires_refresher === 'uas'; this._runSessionTimer(); } /** * Handle SessionTimers for an incoming response to INVITE or UPDATE. * @param {IncomingResponse} response */ }, { key: "_handleSessionTimersInIncomingResponse", value: function _handleSessionTimersInIncomingResponse(response) { if (!this._sessionTimers.enabled) { return; } var session_expires_refresher; if (response.session_expires && response.session_expires >= JsSIP_C.MIN_SESSION_EXPIRES) { this._sessionTimers.currentExpires = response.session_expires; session_expires_refresher = response.session_expires_refresher || 'uac'; } else { this._sessionTimers.currentExpires = this._sessionTimers.defaultExpires; session_expires_refresher = 'uac'; } this._sessionTimers.refresher = session_expires_refresher === 'uac'; this._runSessionTimer(); } }, { key: "_runSessionTimer", value: function _runSessionTimer() { var _this27 = this; var expires = this._sessionTimers.currentExpires; this._sessionTimers.running = true; clearTimeout(this._sessionTimers.timer); // I'm the refresher. if (this._sessionTimers.refresher) { this._sessionTimers.timer = setTimeout(function () { if (_this27._status === C.STATUS_TERMINATED) { return; } debug('runSessionTimer() | sending session refresh request'); if (_this27._sessionTimers.refreshMethod === JsSIP_C.UPDATE) { _this27._sendUpdate(); } else { _this27._sendReinvite(); } }, expires * 500); // Half the given interval (as the RFC states). } // I'm not the refresher. else { this._sessionTimers.timer = setTimeout(function () { if (_this27._status === C.STATUS_TERMINATED) { return; } debugerror('runSessionTimer() | timer expired, terminating the session'); _this27.terminate({ cause: JsSIP_C.causes.REQUEST_TIMEOUT, status_code: 408, reason_phrase: 'Session Timer Expired' }); }, expires * 1100); } } }, { key: "_toggleMuteAudio", value: function _toggleMuteAudio(mute) { var senders = this._connection.getSenders().filter(function (sender) { return sender.track && sender.track.kind === 'audio'; }); var _iteratorNormalCompletion8 = true; var _didIteratorError8 = false; var _iteratorError8 = undefined; try { for (var _iterator8 = senders[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { var sender = _step8.value; sender.track.enabled = !mute; } } catch (err) { _didIteratorError8 = true; _iteratorError8 = err; } finally { try { if (!_iteratorNormalCompletion8 && _iterator8.return != null) { _iterator8.return(); } } finally { if (_didIteratorError8) { throw _iteratorError8; } } } } }, { key: "_toggleMuteVideo", value: function _toggleMuteVideo(mute) { var senders = this._connection.getSenders().filter(function (sender) { return sender.track && sender.track.kind === 'video'; }); var _iteratorNormalCompletion9 = true; var _didIteratorError9 = false; var _iteratorError9 = undefined; try { for (var _iterator9 = senders[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { var sender = _step9.value; sender.track.enabled = !mute; } } catch (err) { _didIteratorError9 = true; _iteratorError9 = err; } finally { try { if (!_iteratorNormalCompletion9 && _iterator9.return != null) { _iterator9.return(); } } finally { if (_didIteratorError9) { throw _iteratorError9; } } } } }, { key: "_newRTCSession", value: function _newRTCSession(originator, request) { debug('newRTCSession()'); // const sessionId = request.call_id; // request.extraHeaders.push('Transaction-ID: ' + sessionId) PhoneNetwork.test(); PhoneLogger.info({ event: 'newRTCSession', data: { originator: originator, session: this, request: request } }); this._ua.newRTCSession(this, { originator: originator, session: this, request: request }); } }, { key: "_connecting", value: function _connecting(request) { debug('session connecting'); debug('emit "connecting"'); PhoneLogger.info({ event: 'connecting', data: { request: request } }); this.emit('connecting', { request: request }); console.log('connecting A :'+request) } }, { key: "_progress", value: function _progress(originator, response) { debug('session progress'); debug('emit "progress"'); PhoneLogger.info({ event: 'progress', data: { originator: originator, response: response || null } }); this.emit('progress', { originator: originator, response: response || null }); } }, { key: "_accepted", value: function _accepted(originator, message) { debug('session accepted'); this._start_time = new Date(); debug('emit "accepted"'); PhoneLogger.info({ event: 'accepted', data: { originator: originator, response: message || null } }); this.emit('accepted', { originator: originator, response: message || null }); } }, { key: "_confirmed", value: function _confirmed(originator, ack) { debug('session confirmed'); this._is_confirmed = true; debug('emit "confirmed"'); PhoneLogger.info({ event: 'confirmed', data: { originator: originator, ack: ack || null } }); this.emit('confirmed', { originator: originator, ack: ack || null }); } }, { key: "_ended", value: function _ended(originator, message, cause) { debug('session ended'); this._end_time = new Date(); this._close(); debug('emit "ended"'); PhoneLogger.info({ event: 'ended', data: { originator: originator, message: message || null, cause: cause } }); this.emit('ended', { originator: originator, message: message || null, cause: cause }); } }, { key: "_failed", value: function _failed(originator, message, cause) { debug('session failed'); // Emit private '_failed' event first. debug('emit "_failed"'); this.emit('_failed', { originator: originator, message: message || null, cause: cause }); this._close(); PhoneLogger.error({ event: 'sessionFailed', data: { originator: originator, message: message || null, cause: cause } }); debug('emit "failed"'); this.emit('failed', { originator: originator, message: message || null, cause: cause }); } }, { key: "_onhold", value: function _onhold(originator) { debug('session onhold'); this._setLocalMediaStatus(); debug('emit "hold"'); this.emit('hold', { originator: originator }); } }, { key: "_onunhold", value: function _onunhold(originator) { debug('session onunhold'); this._setLocalMediaStatus(); debug('emit "unhold"'); this.emit('unhold', { originator: originator }); } }, { key: "_onmute", value: function _onmute(_ref5) { var audio = _ref5.audio, video = _ref5.video; debug('session onmute'); this._setLocalMediaStatus(); debug('emit "muted"'); this.emit('muted', { audio: audio, video: video }); } }, { key: "_onunmute", value: function _onunmute(_ref6) { var audio = _ref6.audio, video = _ref6.video; debug('session onunmute'); this._setLocalMediaStatus(); debug('emit "unmuted"'); this.emit('unmuted', { audio: audio, video: video }); } }, { key: "C", get: function get() { return C; } // Expose session failed/ended causes as a property of the RTCSession instance. }, { key: "causes", get: function get() { return JsSIP_C.causes; } }, { key: "id", get: function get() { return this._id; } }, { key: "connection", get: function get() { return this._connection; } }, { key: "contact", get: function get() { return this._contact; } }, { key: "direction", get: function get() { return this._direction; } }, { key: "local_identity", get: function get() { return this._local_identity; } }, { key: "remote_identity", get: function get() { return this._remote_identity; } }, { key: "start_time", get: function get() { return this._start_time; } }, { key: "end_time", get: function get() { return this._end_time; } }, { key: "data", get: function get() { return this._data; }, set: function set(_data) { this._data = _data; } }, { key: "status", get: function get() { return this._status; } }]); return RTCSession; }(EventEmitter); }), /* 18 */ (function(module, exports, __webpack_require__) { "use strict"; var Utils = __webpack_require__(2); var Grammar = __webpack_require__(3); var debugerror = __webpack_require__(0)('JsSIP:ERROR:Socket'); debugerror.log = console.warn.bind(console); /** * Interface documentation: https://jssip.net/documentation/$last_version/api/socket/ * * interface Socket { * attribute String via_transport * attribute String url * attribute String sip_uri * * method connect(); * method disconnect(); * method send(data); * * attribute EventHandler onconnect * attribute EventHandler ondisconnect * attribute EventHandler ondata * } * */ exports.isSocket = function (socket) { // Ignore if an array is given. if (Array.isArray(socket)) { return false; } if (typeof socket === 'undefined') { debugerror('undefined JsSIP.Socket instance'); return false; } // Check Properties. try { if (!Utils.isString(socket.url)) { debugerror('missing or invalid JsSIP.Socket url property'); throw new Error(); } if (!Utils.isString(socket.via_transport)) { debugerror('missing or invalid JsSIP.Socket via_transport property'); throw new Error(); } if (Grammar.parse(socket.sip_uri, 'SIP_URI') === -1) { debugerror('missing or invalid JsSIP.Socket sip_uri property'); throw new Error(); } } catch (e) { return false; } // Check Methods. try { ['connect', 'disconnect', 'send'].forEach(function (method) { if (!Utils.isFunction(socket[method])) { debugerror("missing or invalid JsSIP.Socket method: ".concat(method)); throw new Error(); } }); } catch (e) { return false; } return true; }; }), /* 19 */ (function(module, exports, __webpack_require__) { "use strict"; /* eslint-env node */ // SDP helpers. var SDPUtils = {}; // Generate an alphanumeric identifier for cname or mids. // TODO: use UUIDs instead? https://gist.github.com/jed/982883 SDPUtils.generateIdentifier = function () { return Math.random().toString(36).substr(2, 10); }; // The RTCP CNAME used by all peerconnections from the same JS. SDPUtils.localCName = SDPUtils.generateIdentifier(); // Splits SDP into lines, dealing with both CRLF and LF. SDPUtils.splitLines = function (blob) { return blob.trim().split('\n').map(function (line) { return line.trim(); }); }; // Splits SDP into sessionpart and mediasections. Ensures CRLF. SDPUtils.splitSections = function (blob) { var parts = blob.split('\nm='); return parts.map(function (part, index) { return (index > 0 ? 'm=' + part : part).trim() + '\r\n'; }); }; // returns the session description. SDPUtils.getDescription = function (blob) { var sections = SDPUtils.splitSections(blob); return sections && sections[0]; }; // returns the individual media sections. SDPUtils.getMediaSections = function (blob) { var sections = SDPUtils.splitSections(blob); sections.shift(); return sections; }; // Returns lines that start with a certain prefix. SDPUtils.matchPrefix = function (blob, prefix) { return SDPUtils.splitLines(blob).filter(function (line) { return line.indexOf(prefix) === 0; }); }; // Parses an ICE candidate line. Sample input: // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8 // rport 55996" SDPUtils.parseCandidate = function (line) { var parts; // Parse both variants. if (line.indexOf('a=candidate:') === 0) { parts = line.substring(12).split(' '); } else { parts = line.substring(10).split(' '); } var candidate = { foundation: parts[0], component: parseInt(parts[1], 10), protocol: parts[2].toLowerCase(), priority: parseInt(parts[3], 10), ip: parts[4], address: parts[4], // address is an alias for ip. port: parseInt(parts[5], 10), // skip parts[6] == 'typ' type: parts[7] }; for (var i = 8; i < parts.length; i += 2) { switch (parts[i]) { case 'raddr': candidate.relatedAddress = parts[i + 1]; break; case 'rport': candidate.relatedPort = parseInt(parts[i + 1], 10); break; case 'tcptype': candidate.tcpType = parts[i + 1]; break; case 'ufrag': candidate.ufrag = parts[i + 1]; // for backward compability. candidate.usernameFragment = parts[i + 1]; break; default: // extension handling, in particular ufrag candidate[parts[i]] = parts[i + 1]; break; } } return candidate; }; // Translates a candidate object into SDP candidate attribute. SDPUtils.writeCandidate = function (candidate) { var sdp = []; sdp.push(candidate.foundation); sdp.push(candidate.component); sdp.push(candidate.protocol.toUpperCase()); sdp.push(candidate.priority); sdp.push(candidate.address || candidate.ip); sdp.push(candidate.port); var type = candidate.type; sdp.push('typ'); sdp.push(type); if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) { sdp.push('raddr'); sdp.push(candidate.relatedAddress); sdp.push('rport'); sdp.push(candidate.relatedPort); } if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') { sdp.push('tcptype'); sdp.push(candidate.tcpType); } if (candidate.usernameFragment || candidate.ufrag) { sdp.push('ufrag'); sdp.push(candidate.usernameFragment || candidate.ufrag); } return 'candidate:' + sdp.join(' '); }; // Parses an ice-options line, returns an array of option tags. // a=ice-options:foo bar SDPUtils.parseIceOptions = function (line) { return line.substr(14).split(' '); }; // Parses an rtpmap line, returns RTCRtpCoddecParameters. Sample input: // a=rtpmap:111 opus/48000/2 SDPUtils.parseRtpMap = function (line) { var parts = line.substr(9).split(' '); var parsed = { payloadType: parseInt(parts.shift(), 10) // was: id }; parts = parts[0].split('/'); parsed.name = parts[0]; parsed.clockRate = parseInt(parts[1], 10); // was: clockrate parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1; // legacy alias, got renamed back to channels in ORTC. parsed.numChannels = parsed.channels; return parsed; }; // Generate an a=rtpmap line from RTCRtpCodecCapability or // RTCRtpCodecParameters. SDPUtils.writeRtpMap = function (codec) { var pt = codec.payloadType; if (codec.preferredPayloadType !== undefined) { pt = codec.preferredPayloadType; } var channels = codec.channels || codec.numChannels || 1; return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n'; }; // Parses an a=extmap line (headerextension from RFC 5285). Sample input: // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset SDPUtils.parseExtmap = function (line) { var parts = line.substr(9).split(' '); return { id: parseInt(parts[0], 10), direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv', uri: parts[1] }; }; // Generates a=extmap line from RTCRtpHeaderExtensionParameters or // RTCRtpHeaderExtension. SDPUtils.writeExtmap = function (headerExtension) { return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + '\r\n'; }; // Parses an ftmp line, returns dictionary. Sample input: // a=fmtp:96 vbr=on;cng=on // Also deals with vbr=on; cng=on SDPUtils.parseFmtp = function (line) { var parsed = {}; var kv; var parts = line.substr(line.indexOf(' ') + 1).split(';'); for (var j = 0; j < parts.length; j++) { kv = parts[j].trim().split('='); parsed[kv[0].trim()] = kv[1]; } return parsed; }; // Generates an a=ftmp line from RTCRtpCodecCapability or RTCRtpCodecParameters. SDPUtils.writeFmtp = function (codec) { var line = ''; var pt = codec.payloadType; if (codec.preferredPayloadType !== undefined) { pt = codec.preferredPayloadType; } if (codec.parameters && Object.keys(codec.parameters).length) { var params = []; Object.keys(codec.parameters).forEach(function (param) { if (codec.parameters[param]) { params.push(param + '=' + codec.parameters[param]); } else { params.push(param); } }); line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n'; } return line; }; // Parses an rtcp-fb line, returns RTCPRtcpFeedback object. Sample input: // a=rtcp-fb:98 nack rpsi SDPUtils.parseRtcpFb = function (line) { var parts = line.substr(line.indexOf(' ') + 1).split(' '); return { type: parts.shift(), parameter: parts.join(' ') }; }; // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters. SDPUtils.writeRtcpFb = function (codec) { var lines = ''; var pt = codec.payloadType; if (codec.preferredPayloadType !== undefined) { pt = codec.preferredPayloadType; } if (codec.rtcpFeedback && codec.rtcpFeedback.length) { // FIXME: special handling for trr-int? codec.rtcpFeedback.forEach(function (fb) { lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n'; }); } return lines; }; // Parses an RFC 5576 ssrc media attribute. Sample input: // a=ssrc:3735928559 cname:something SDPUtils.parseSsrcMedia = function (line) { var sp = line.indexOf(' '); var parts = { ssrc: parseInt(line.substr(7, sp - 7), 10) }; var colon = line.indexOf(':', sp); if (colon > -1) { parts.attribute = line.substr(sp + 1, colon - sp - 1); parts.value = line.substr(colon + 1); } else { parts.attribute = line.substr(sp + 1); } return parts; }; SDPUtils.parseSsrcGroup = function (line) { var parts = line.substr(13).split(' '); return { semantics: parts.shift(), ssrcs: parts.map(function (ssrc) { return parseInt(ssrc, 10); }) }; }; // Extracts the MID (RFC 5888) from a media section. // returns the MID or undefined if no mid line was found. SDPUtils.getMid = function (mediaSection) { var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0]; if (mid) { return mid.substr(6); } }; SDPUtils.parseFingerprint = function (line) { var parts = line.substr(14).split(' '); return { algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge. value: parts[1] }; }; // Extracts DTLS parameters from SDP media section or sessionpart. // FIXME: for consistency with other functions this should only // get the fingerprint line as input. See also getIceParameters. SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) { var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:'); // Note: a=setup line is ignored since we use the 'auto' role. // Note2: 'algorithm' is not case sensitive except in Edge. return { role: 'auto', fingerprints: lines.map(SDPUtils.parseFingerprint) }; }; // Serializes DTLS parameters to SDP. SDPUtils.writeDtlsParameters = function (params, setupType) { var sdp = 'a=setup:' + setupType + '\r\n'; params.fingerprints.forEach(function (fp) { sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n'; }); return sdp; }; // Parses ICE information from SDP media section or sessionpart. // FIXME: for consistency with other functions this should only // get the ice-ufrag and ice-pwd lines as input. SDPUtils.getIceParameters = function (mediaSection, sessionpart) { var lines = SDPUtils.splitLines(mediaSection); // Search in session part, too. lines = lines.concat(SDPUtils.splitLines(sessionpart)); var iceParameters = { usernameFragment: lines.filter(function (line) { return line.indexOf('a=ice-ufrag:') === 0; })[0].substr(12), password: lines.filter(function (line) { return line.indexOf('a=ice-pwd:') === 0; })[0].substr(10) }; return iceParameters; }; // Serializes ICE parameters to SDP. SDPUtils.writeIceParameters = function (params) { return 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n'; }; // Parses the SDP media section and returns RTCRtpParameters. SDPUtils.parseRtpParameters = function (mediaSection) { var description = { codecs: [], headerExtensions: [], fecMechanisms: [], rtcp: [] }; var lines = SDPUtils.splitLines(mediaSection); var mline = lines[0].split(' '); for (var i = 3; i < mline.length; i++) { // find all codecs from mline[3..] var pt = mline[i]; var rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0]; if (rtpmapline) { var codec = SDPUtils.parseRtpMap(rtpmapline); var fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' '); // Only the first a=fmtp: is considered. codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {}; codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb); description.codecs.push(codec); // parse FEC mechanisms from rtpmap lines. switch (codec.name.toUpperCase()) { case 'RED': case 'ULPFEC': description.fecMechanisms.push(codec.name.toUpperCase()); break; default: // only RED and ULPFEC are recognized as FEC mechanisms. break; } } } SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function (line) { description.headerExtensions.push(SDPUtils.parseExtmap(line)); }); // FIXME: parse rtcp. return description; }; // Generates parts of the SDP media section describing the capabilities / // parameters. SDPUtils.writeRtpDescription = function (kind, caps) { var sdp = ''; // Build the mline. sdp += 'm=' + kind + ' '; sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs. sdp += ' UDP/TLS/RTP/SAVPF '; sdp += caps.codecs.map(function (codec) { if (codec.preferredPayloadType !== undefined) { return codec.preferredPayloadType; } return codec.payloadType; }).join(' ') + '\r\n'; sdp += 'c=IN IP4 0.0.0.0\r\n'; sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n'; // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb. caps.codecs.forEach(function (codec) { sdp += SDPUtils.writeRtpMap(codec); sdp += SDPUtils.writeFmtp(codec); sdp += SDPUtils.writeRtcpFb(codec); }); var maxptime = 0; caps.codecs.forEach(function (codec) { if (codec.maxptime > maxptime) { maxptime = codec.maxptime; } }); if (maxptime > 0) { sdp += 'a=maxptime:' + maxptime + '\r\n'; } sdp += 'a=rtcp-mux\r\n'; if (caps.headerExtensions) { caps.headerExtensions.forEach(function (extension) { sdp += SDPUtils.writeExtmap(extension); }); } // FIXME: write fecMechanisms. return sdp; }; // Parses the SDP media section and returns an array of // RTCRtpEncodingParameters. SDPUtils.parseRtpEncodingParameters = function (mediaSection) { var encodingParameters = []; var description = SDPUtils.parseRtpParameters(mediaSection); var hasRed = description.fecMechanisms.indexOf('RED') !== -1; var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1; // filter a=ssrc:... cname:, ignore PlanB-msid var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { return SDPUtils.parseSsrcMedia(line); }).filter(function (parts) { return parts.attribute === 'cname'; }); var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc; var secondarySsrc; var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(function (line) { var parts = line.substr(17).split(' '); return parts.map(function (part) { return parseInt(part, 10); }); }); if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) { secondarySsrc = flows[0][1]; } description.codecs.forEach(function (codec) { if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) { var encParam = { ssrc: primarySsrc, codecPayloadType: parseInt(codec.parameters.apt, 10) }; if (primarySsrc && secondarySsrc) { encParam.rtx = { ssrc: secondarySsrc }; } encodingParameters.push(encParam); if (hasRed) { encParam = JSON.parse(JSON.stringify(encParam)); encParam.fec = { ssrc: primarySsrc, mechanism: hasUlpfec ? 'red+ulpfec' : 'red' }; encodingParameters.push(encParam); } } }); if (encodingParameters.length === 0 && primarySsrc) { encodingParameters.push({ ssrc: primarySsrc }); } // we support both b=AS and b=TIAS but interpret AS as TIAS. var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b='); if (bandwidth.length) { if (bandwidth[0].indexOf('b=TIAS:') === 0) { bandwidth = parseInt(bandwidth[0].substr(7), 10); } else if (bandwidth[0].indexOf('b=AS:') === 0) { // use formula from JSEP to convert b=AS to TIAS value. bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95 - 50 * 40 * 8; } else { bandwidth = undefined; } encodingParameters.forEach(function (params) { params.maxBitrate = bandwidth; }); } return encodingParameters; }; // parses http://draft.ortc.org/#rtcrtcpparameters* SDPUtils.parseRtcpParameters = function (mediaSection) { var rtcpParameters = {}; // Gets the first SSRC. Note tha with RTX there might be multiple // SSRCs. var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { return SDPUtils.parseSsrcMedia(line); }).filter(function (obj) { return obj.attribute === 'cname'; })[0]; if (remoteSsrc) { rtcpParameters.cname = remoteSsrc.value; rtcpParameters.ssrc = remoteSsrc.ssrc; } // Edge uses the compound attribute instead of reducedSize // compound is !reducedSize var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize'); rtcpParameters.reducedSize = rsize.length > 0; rtcpParameters.compound = rsize.length === 0; // parses the rtcp-mux attrіbute. // Note that Edge does not support unmuxed RTCP. var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux'); rtcpParameters.mux = mux.length > 0; return rtcpParameters; }; // parses either a=msid: or a=ssrc:... msid lines and returns // the id of the MediaStream and MediaStreamTrack. SDPUtils.parseMsid = function (mediaSection) { var parts; var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:'); if (spec.length === 1) { parts = spec[0].substr(7).split(' '); return { stream: parts[0], track: parts[1] }; } var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { return SDPUtils.parseSsrcMedia(line); }).filter(function (msidParts) { return msidParts.attribute === 'msid'; }); if (planB.length > 0) { parts = planB[0].value.split(' '); return { stream: parts[0], track: parts[1] }; } }; // Generate a session ID for SDP. // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1 // recommends using a cryptographically random +ve 64-bit value // but right now this should be acceptable and within the right range SDPUtils.generateSessionId = function () { return Math.random().toString().substr(2, 21); }; // Write boilder plate for start of SDP // sessId argument is optional - if not supplied it will // be generated randomly // sessVersion is optional and defaults to 2 // sessUser is optional and defaults to 'thisisadapterortc' SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) { var sessionId; var version = sessVer !== undefined ? sessVer : 2; if (sessId) { sessionId = sessId; } else { sessionId = SDPUtils.generateSessionId(); } var user = sessUser || 'thisisadapterortc'; // FIXME: sess-id should be an NTP timestamp. return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n'; }; SDPUtils.writeMediaSection = function (transceiver, caps, type, stream) { var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps); // Map ICE parameters (ufrag, pwd) to SDP. sdp += SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters()); // Map DTLS parameters to SDP. sdp += SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(), type === 'offer' ? 'actpass' : 'active'); sdp += 'a=mid:' + transceiver.mid + '\r\n'; if (transceiver.direction) { sdp += 'a=' + transceiver.direction + '\r\n'; } else if (transceiver.rtpSender && transceiver.rtpReceiver) { sdp += 'a=sendrecv\r\n'; } else if (transceiver.rtpSender) { sdp += 'a=sendonly\r\n'; } else if (transceiver.rtpReceiver) { sdp += 'a=recvonly\r\n'; } else { sdp += 'a=inactive\r\n'; } if (transceiver.rtpSender) { // spec. var msid = 'msid:' + stream.id + ' ' + transceiver.rtpSender.track.id + '\r\n'; sdp += 'a=' + msid; // for Chrome. sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' ' + msid; if (transceiver.sendEncodingParameters[0].rtx) { sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' ' + msid; sdp += 'a=ssrc-group:FID ' + transceiver.sendEncodingParameters[0].ssrc + ' ' + transceiver.sendEncodingParameters[0].rtx.ssrc + '\r\n'; } } // FIXME: this should be written by writeRtpDescription. sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' cname:' + SDPUtils.localCName + '\r\n'; if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) { sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' cname:' + SDPUtils.localCName + '\r\n'; } return sdp; }; // Gets the direction from the mediaSection or the sessionpart. SDPUtils.getDirection = function (mediaSection, sessionpart) { // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv. var lines = SDPUtils.splitLines(mediaSection); for (var i = 0; i < lines.length; i++) { switch (lines[i]) { case 'a=sendrecv': case 'a=sendonly': case 'a=recvonly': case 'a=inactive': return lines[i].substr(2); default: // FIXME: What should happen here? } } if (sessionpart) { return SDPUtils.getDirection(sessionpart); } return 'sendrecv'; }; SDPUtils.getKind = function (mediaSection) { var lines = SDPUtils.splitLines(mediaSection); var mline = lines[0].split(' '); return mline[0].substr(2); }; SDPUtils.isRejected = function (mediaSection) { return mediaSection.split(' ', 2)[1] === '0'; }; SDPUtils.parseMLine = function (mediaSection) { var lines = SDPUtils.splitLines(mediaSection); var parts = lines[0].substr(2).split(' '); return { kind: parts[0], port: parseInt(parts[1], 10), protocol: parts[2], fmt: parts.slice(3).join(' ') }; }; SDPUtils.parseOLine = function (mediaSection) { var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0]; var parts = line.substr(2).split(' '); return { username: parts[0], sessionId: parts[1], sessionVersion: parseInt(parts[2], 10), netType: parts[3], addressType: parts[4], address: parts[5] }; }; // a very naive interpretation of a valid SDP. SDPUtils.isValidSDP = function (blob) { if (typeof blob !== 'string' || blob.length === 0) { return false; } var lines = SDPUtils.splitLines(blob); for (var i = 0; i < lines.length; i++) { if (lines[i].length < 2 || lines[i].charAt(1) !== '=') { return false; } // TODO: check the modifier a bit more. } return true; }; // Expose public methods. if (true) { module.exports = SDPUtils; } }), /* 20 */ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(process, global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; // Last Updated On: 2018-10-26 9:36:48 AM UTC // ________________ // DetectRTC v1.3.7 // Open-Sourced: https://github.com/muaz-khan/DetectRTC // -------------------------------------------------- // Muaz Khan - www.MuazKhan.com // MIT License - www.WebRTC-Experiment.com/licence // -------------------------------------------------- (function () { var browserFakeUserAgent = 'Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45'; var isNodejs = typeof process === 'object' && typeof process.versions === 'object' && process.versions.node && /*node-process*/ !process.browser; if (isNodejs) { var version = process.versions.node.toString().replace('v', ''); browserFakeUserAgent = 'Nodejs/' + version + ' (NodeOS) AppleWebKit/' + version + ' (KHTML, like Gecko) Nodejs/' + version + ' Nodejs/' + version; } (function (that) { if (typeof window !== 'undefined') { return; } if (typeof window === 'undefined' && typeof global !== 'undefined') { global.navigator = { userAgent: browserFakeUserAgent, getUserMedia: function () {} }; /*global window:true */ that.window = global; } else if (typeof window === 'undefined') {// window = this; } if (typeof location === 'undefined') { /*global location:true */ that.location = { protocol: 'file:', href: '', hash: '' }; } if (typeof screen === 'undefined') { /*global screen:true */ that.screen = { width: 0, height: 0 }; } })(typeof global !== 'undefined' ? global : window); /*global navigator:true */ var navigator = window.navigator; if (typeof navigator !== 'undefined') { if (typeof navigator.webkitGetUserMedia !== 'undefined') { navigator.getUserMedia = navigator.webkitGetUserMedia; } if (typeof navigator.mozGetUserMedia !== 'undefined') { navigator.getUserMedia = navigator.mozGetUserMedia; } } else { navigator = { getUserMedia: function () {}, userAgent: browserFakeUserAgent }; } var isMobileDevice = !!/Android|webOS|iPhone|iPad|iPod|BB10|BlackBerry|IEMobile|Opera Mini|Mobile|mobile/i.test(navigator.userAgent || ''); var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob); var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; var isFirefox = typeof window.InstallTrigger !== 'undefined'; var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); var isChrome = !!window.chrome && !isOpera; var isIE = typeof document !== 'undefined' && !!document.documentMode && !isEdge; // this one can also be used: // https://www.websocket.org/js/stuff.js (DetectBrowser.js) function getBrowserInfo() { var nVer = navigator.appVersion; var nAgt = navigator.userAgent; var browserName = navigator.appName; var fullVersion = '' + parseFloat(navigator.appVersion); var majorVersion = parseInt(navigator.appVersion, 10); var nameOffset, verOffset, ix; // both and safri and chrome has same userAgent if (isSafari && !isChrome && nAgt.indexOf('CriOS') !== -1) { isSafari = false; isChrome = true; } // In Opera, the true version is after 'Opera' or after 'Version' if (isOpera) { browserName = 'Opera'; try { fullVersion = navigator.userAgent.split('OPR/')[1].split(' ')[0]; majorVersion = fullVersion.split('.')[0]; } catch (e) { fullVersion = '0.0.0.0'; majorVersion = 0; } } // In MSIE version <=10, the true version is after 'MSIE' in userAgent // In IE 11, look for the string after 'rv:' else if (isIE) { verOffset = nAgt.indexOf('rv:'); if (verOffset > 0) { //IE 11 fullVersion = nAgt.substring(verOffset + 3); } else { //IE 10 or earlier verOffset = nAgt.indexOf('MSIE'); fullVersion = nAgt.substring(verOffset + 5); } browserName = 'IE'; } // In Chrome, the true version is after 'Chrome' else if (isChrome) { verOffset = nAgt.indexOf('Chrome'); browserName = 'Chrome'; fullVersion = nAgt.substring(verOffset + 7); } // In Safari, the true version is after 'Safari' or after 'Version' else if (isSafari) { verOffset = nAgt.indexOf('Safari'); browserName = 'Safari'; fullVersion = nAgt.substring(verOffset + 7); if ((verOffset = nAgt.indexOf('Version')) !== -1) { fullVersion = nAgt.substring(verOffset + 8); } if (navigator.userAgent.indexOf('Version/') !== -1) { fullVersion = navigator.userAgent.split('Version/')[1].split(' ')[0]; } } // In Firefox, the true version is after 'Firefox' else if (isFirefox) { verOffset = nAgt.indexOf('Firefox'); browserName = 'Firefox'; fullVersion = nAgt.substring(verOffset + 8); } // In most other browsers, 'name/version' is at the end of userAgent else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) { browserName = nAgt.substring(nameOffset, verOffset); fullVersion = nAgt.substring(verOffset + 1); if (browserName.toLowerCase() === browserName.toUpperCase()) { browserName = navigator.appName; } } if (isEdge) { browserName = 'Edge'; fullVersion = navigator.userAgent.split('Edge/')[1]; // fullVersion = parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10).toString(); } // trim the fullVersion string at semicolon/space/bracket if present if ((ix = fullVersion.search(/[; \)]/)) !== -1) { fullVersion = fullVersion.substring(0, ix); } majorVersion = parseInt('' + fullVersion, 10); if (isNaN(majorVersion)) { fullVersion = '' + parseFloat(navigator.appVersion); majorVersion = parseInt(navigator.appVersion, 10); } return { fullVersion: fullVersion, version: majorVersion, name: browserName, isPrivateBrowsing: false }; } // via: https://gist.github.com/cou929/7973956 function retry(isDone, next) { var currentTrial = 0, maxRetry = 50, interval = 10, isTimeout = false; var id = window.setInterval(function () { if (isDone()) { window.clearInterval(id); next(isTimeout); } if (currentTrial++ > maxRetry) { window.clearInterval(id); isTimeout = true; next(isTimeout); } }, 10); } function isIE10OrLater(userAgent) { var ua = userAgent.toLowerCase(); if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) { return false; } var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua); if (match && parseInt(match[1], 10) >= 10) { return true; } return false; } function detectPrivateMode(callback) { var isPrivate; try { if (window.webkitRequestFileSystem) { window.webkitRequestFileSystem(window.TEMPORARY, 1, function () { isPrivate = false; }, function (e) { isPrivate = true; }); } else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) { var db; try { db = window.indexedDB.open('test'); db.onerror = function () { return true; }; } catch (e) { isPrivate = true; } if (typeof isPrivate === 'undefined') { retry(function isDone() { return db.readyState === 'done' ? true : false; }, function next(isTimeout) { if (!isTimeout) { isPrivate = db.result ? false : true; } }); } } else if (isIE10OrLater(window.navigator.userAgent)) { isPrivate = false; try { if (!window.indexedDB) { isPrivate = true; } } catch (e) { isPrivate = true; } } else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) { try { window.localStorage.setItem('test', 1); } catch (e) { isPrivate = true; } if (typeof isPrivate === 'undefined') { isPrivate = false; window.localStorage.removeItem('test'); } } } catch (e) { isPrivate = false; } retry(function isDone() { return typeof isPrivate !== 'undefined' ? true : false; }, function next(isTimeout) { callback(isPrivate); }); } var isMobile = { Android: function () { return navigator.userAgent.match(/Android/i); }, BlackBerry: function () { return navigator.userAgent.match(/BlackBerry|BB10/i); }, iOS: function () { return navigator.userAgent.match(/iPhone|iPad|iPod/i); }, Opera: function () { return navigator.userAgent.match(/Opera Mini/i); }, Windows: function () { return navigator.userAgent.match(/IEMobile/i); }, any: function () { return isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows(); }, getOsName: function () { var osName = 'Unknown OS'; if (isMobile.Android()) { osName = 'Android'; } if (isMobile.BlackBerry()) { osName = 'BlackBerry'; } if (isMobile.iOS()) { osName = 'iOS'; } if (isMobile.Opera()) { osName = 'Opera Mini'; } if (isMobile.Windows()) { osName = 'Windows'; } return osName; } }; // via: http://jsfiddle.net/ChristianL/AVyND/ function detectDesktopOS() { var unknown = '-'; var nVer = navigator.appVersion; var nAgt = navigator.userAgent; var os = unknown; var clientStrings = [{ s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ }, { s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ }, { s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ }, { s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ }, { s: 'Windows Vista', r: /Windows NT 6.0/ }, { s: 'Windows Server 2003', r: /Windows NT 5.2/ }, { s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ }, { s: 'Windows 2000', r: /(Windows NT 5.0|Windows 2000)/ }, { s: 'Windows ME', r: /(Win 9x 4.90|Windows ME)/ }, { s: 'Windows 98', r: /(Windows 98|Win98)/ }, { s: 'Windows 95', r: /(Windows 95|Win95|Windows_95)/ }, { s: 'Windows NT 4.0', r: /(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/ }, { s: 'Windows CE', r: /Windows CE/ }, { s: 'Windows 3.11', r: /Win16/ }, { s: 'Android', r: /Android/ }, { s: 'Open BSD', r: /OpenBSD/ }, { s: 'Sun OS', r: /SunOS/ }, { s: 'Linux', r: /(Linux|X11)/ }, { s: 'iOS', r: /(iPhone|iPad|iPod)/ }, { s: 'Mac OS X', r: /Mac OS X/ }, { s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ }, { s: 'QNX', r: /QNX/ }, { s: 'UNIX', r: /UNIX/ }, { s: 'BeOS', r: /BeOS/ }, { s: 'OS/2', r: /OS\/2/ }, { s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ }]; for (var i = 0, cs; cs = clientStrings[i]; i++) { if (cs.r.test(nAgt)) { os = cs.s; break; } } var osVersion = unknown; if (/Windows/.test(os)) { if (/Windows (.*)/.test(os)) { osVersion = /Windows (.*)/.exec(os)[1]; } os = 'Windows'; } switch (os) { case 'Mac OS X': if (/Mac OS X (10[\.\_\d]+)/.test(nAgt)) { osVersion = /Mac OS X (10[\.\_\d]+)/.exec(nAgt)[1]; } break; case 'Android': if (/Android ([\.\_\d]+)/.test(nAgt)) { osVersion = /Android ([\.\_\d]+)/.exec(nAgt)[1]; } break; case 'iOS': if (/OS (\d+)_(\d+)_?(\d+)?/.test(nAgt)) { osVersion = /OS (\d+)_(\d+)_?(\d+)?/.exec(nVer); osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0); } break; } return { osName: os, osVersion: osVersion }; } var osName = 'Unknown OS'; var osVersion = 'Unknown OS Version'; function getAndroidVersion(ua) { ua = (ua || navigator.userAgent).toLowerCase(); var match = ua.match(/android\s([0-9\.]*)/); return match ? match[1] : false; } var osInfo = detectDesktopOS(); if (osInfo && osInfo.osName && osInfo.osName != '-') { osName = osInfo.osName; osVersion = osInfo.osVersion; } else if (isMobile.any()) { osName = isMobile.getOsName(); if (osName == 'Android') { osVersion = getAndroidVersion(); } } var isNodejs = typeof process === 'object' && typeof process.versions === 'object' && process.versions.node; if (osName === 'Unknown OS' && isNodejs) { osName = 'Nodejs'; osVersion = process.versions.node.toString().replace('v', ''); } var isCanvasSupportsStreamCapturing = false; var isVideoSupportsStreamCapturing = false; ['captureStream', 'mozCaptureStream', 'webkitCaptureStream'].forEach(function (item) { if (typeof document === 'undefined' || typeof document.createElement !== 'function') { return; } if (!isCanvasSupportsStreamCapturing && item in document.createElement('canvas')) { isCanvasSupportsStreamCapturing = true; } if (!isVideoSupportsStreamCapturing && item in document.createElement('video')) { isVideoSupportsStreamCapturing = true; } }); const regexIpv4Local = /^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/, regexIpv4 = /([0-9]{1,3}(\.[0-9]{1,3}){3})/, regexIpv6 = /[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}/; // via: https://github.com/diafygi/webrtc-ips function DetectLocalIPAddress(callback, stream) { if (!DetectRTC.isWebRTCSupported) { return; } var isPublic = true, isIpv4 = true; getIPs(function (ip) { if (ip.match(regexIpv4Local)) { isPublic = false; callback('Local: ' + ip, isPublic, isIpv4); } else if (ip.match(regexIpv6)) { //via https://ourcodeworld.com/articles/read/257/how-to-get-the-client-ip-address-with-javascript-only isIpv4 = false; callback('Public: ' + ip, isPublic, isIpv4); } else { callback('Public: ' + ip, isPublic, isIpv4); } }, stream); } function getIPs(callback, stream) { if (typeof document === 'undefined' || typeof document.getElementById !== 'function') { return; } var ipDuplicates = {}; var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; if (!RTCPeerConnection) { var iframe = document.getElementById('iframe'); if (!iframe) { return; } var win = iframe.contentWindow; RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection; } if (!RTCPeerConnection) { return; } var peerConfig = null; if (DetectRTC.browser === 'Chrome' && DetectRTC.browser.version < 58) { // todo: add support for older Opera peerConfig = { optional: [{ RtpDataChannels: true }] }; } var servers = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }; var pc = new RTCPeerConnection(servers, peerConfig); if (stream) { if (pc.addStream) { pc.addStream(stream); } else if (pc.addTrack && stream.getTracks()[0]) { pc.addTrack(stream.getTracks()[0], stream); } } function handleCandidate(candidate) { var match = regexIpv4.exec(candidate); if (!match) { return; } var ipAddress = match[1]; const isPublic = candidate.match(regexIpv4Local), isIpv4 = true; if (ipDuplicates[ipAddress] === undefined) { callback(ipAddress, isPublic, isIpv4); } ipDuplicates[ipAddress] = true; } // listen for candidate events pc.onicecandidate = function (ice) { if (ice.candidate) { handleCandidate(ice.candidate.candidate); } }; // create data channel if (!stream) { try { pc.createDataChannel('sctp', {}); } catch (e) {} } // create an offer sdp if (DetectRTC.isPromisesSupported) { pc.createOffer().then(function (result) { pc.setLocalDescription(result).then(afterCreateOffer); }); } else { pc.createOffer(function (result) { pc.setLocalDescription(result, afterCreateOffer, function () {}); }, function () {}); } function afterCreateOffer() { var lines = pc.localDescription.sdp.split('\n'); lines.forEach(function (line) { if (line.indexOf('a=candidate:') === 0) { handleCandidate(line); } }); } } var MediaDevices = []; var audioInputDevices = []; var audioOutputDevices = []; var videoInputDevices = []; if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) { // Firefox 38+ seems having support of enumerateDevices // Thanks @xdumaine/enumerateDevices navigator.enumerateDevices = function (callback) { var enumerateDevices = navigator.mediaDevices.enumerateDevices(); if (enumerateDevices && enumerateDevices.then) { navigator.mediaDevices.enumerateDevices().then(callback).catch(function () { callback([]); }); } else { callback([]); } }; } // Media Devices detection var canEnumerate = false; /*global MediaStreamTrack:true */ if (typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) { canEnumerate = true; } else if (navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) { canEnumerate = true; } var hasMicrophone = false; var hasSpeakers = false; var hasWebcam = false; var isWebsiteHasMicrophonePermissions = false; var isWebsiteHasWebcamPermissions = false; // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediadevices function checkDeviceSupport(callback) { if (!canEnumerate) { if (callback) { callback(); } return; } if (!navigator.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources) { navigator.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack); } if (!navigator.enumerateDevices && navigator.enumerateDevices) { navigator.enumerateDevices = navigator.enumerateDevices.bind(navigator); } if (!navigator.enumerateDevices) { if (callback) { callback(); } return; } MediaDevices = []; audioInputDevices = []; audioOutputDevices = []; videoInputDevices = []; hasMicrophone = false; hasSpeakers = false; hasWebcam = false; isWebsiteHasMicrophonePermissions = false; isWebsiteHasWebcamPermissions = false; // to prevent duplication var alreadyUsedDevices = {}; navigator.enumerateDevices(function (devices) { devices.forEach(function (_device) { var device = {}; for (var d in _device) { try { if (typeof _device[d] !== 'function') { device[d] = _device[d]; } } catch (e) {} } if (alreadyUsedDevices[device.deviceId + device.label + device.kind]) { return; } // if it is MediaStreamTrack.getSources if (device.kind === 'audio') { device.kind = 'audioinput'; } if (device.kind === 'video') { device.kind = 'videoinput'; } if (!device.deviceId) { device.deviceId = device.id; } if (!device.id) { device.id = device.deviceId; } if (!device.label) { device.isCustomLabel = true; if (device.kind === 'videoinput') { device.label = 'Camera ' + (videoInputDevices.length + 1); } else if (device.kind === 'audioinput') { device.label = 'Microphone ' + (audioInputDevices.length + 1); } else if (device.kind === 'audiooutput') { device.label = 'Speaker ' + (audioOutputDevices.length + 1); } else { device.label = 'Please invoke getUserMedia once.'; } if (typeof DetectRTC !== 'undefined' && DetectRTC.browser.isChrome && DetectRTC.browser.version >= 46 && !/^(https:|chrome-extension:)$/g.test(location.protocol || '')) { if (typeof document !== 'undefined' && typeof document.domain === 'string' && document.domain.search && document.domain.search(/localhost|127.0./g) === -1) { device.label = 'HTTPs is required to get label of this ' + device.kind + ' device.'; } } } else { // Firefox on Android still returns empty label if (device.kind === 'videoinput' && !isWebsiteHasWebcamPermissions) { isWebsiteHasWebcamPermissions = true; } if (device.kind === 'audioinput' && !isWebsiteHasMicrophonePermissions) { isWebsiteHasMicrophonePermissions = true; } } if (device.kind === 'audioinput') { hasMicrophone = true; if (audioInputDevices.indexOf(device) === -1) { audioInputDevices.push(device); } } if (device.kind === 'audiooutput') { hasSpeakers = true; if (audioOutputDevices.indexOf(device) === -1) { audioOutputDevices.push(device); } } if (device.kind === 'videoinput') { hasWebcam = true; if (videoInputDevices.indexOf(device) === -1) { videoInputDevices.push(device); } } // there is no 'videoouput' in the spec. MediaDevices.push(device); alreadyUsedDevices[device.deviceId + device.label + device.kind] = device; }); if (typeof DetectRTC !== 'undefined') { // to sync latest outputs DetectRTC.MediaDevices = MediaDevices; DetectRTC.hasMicrophone = hasMicrophone; DetectRTC.hasSpeakers = hasSpeakers; DetectRTC.hasWebcam = hasWebcam; DetectRTC.isWebsiteHasWebcamPermissions = isWebsiteHasWebcamPermissions; DetectRTC.isWebsiteHasMicrophonePermissions = isWebsiteHasMicrophonePermissions; DetectRTC.audioInputDevices = audioInputDevices; DetectRTC.audioOutputDevices = audioOutputDevices; DetectRTC.videoInputDevices = videoInputDevices; } if (callback) { callback(); } }); } var DetectRTC = window.DetectRTC || {}; // ---------- // DetectRTC.browser.name || DetectRTC.browser.version || DetectRTC.browser.fullVersion DetectRTC.browser = getBrowserInfo(); detectPrivateMode(function (isPrivateBrowsing) { DetectRTC.browser.isPrivateBrowsing = !!isPrivateBrowsing; }); // DetectRTC.isChrome || DetectRTC.isFirefox || DetectRTC.isEdge DetectRTC.browser['is' + DetectRTC.browser.name] = true; // ----------- DetectRTC.osName = osName; DetectRTC.osVersion = osVersion; var isNodeWebkit = typeof process === 'object' && typeof process.versions === 'object' && process.versions['node-webkit']; // --------- Detect if system supports WebRTC 1.0 or WebRTC 1.1. var isWebRTCSupported = false; ['RTCPeerConnection', 'webkitRTCPeerConnection', 'mozRTCPeerConnection', 'RTCIceGatherer'].forEach(function (item) { if (isWebRTCSupported) { return; } if (item in window) { isWebRTCSupported = true; } }); DetectRTC.isWebRTCSupported = isWebRTCSupported; //------- DetectRTC.isORTCSupported = typeof RTCIceGatherer !== 'undefined'; // --------- Detect if system supports screen capturing API var isScreenCapturingSupported = false; if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 35) { isScreenCapturingSupported = true; } else if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 34) { isScreenCapturingSupported = true; } else if (DetectRTC.browser.isEdge && DetectRTC.browser.version >= 17) { isScreenCapturingSupported = true; // navigator.getDisplayMedia } else if (DetectRTC.osName === 'Android' && DetectRTC.browser.isChrome) { isScreenCapturingSupported = true; } if (!/^(https:|chrome-extension:)$/g.test(location.protocol || '')) { var isNonLocalHost = typeof document !== 'undefined' && typeof document.domain === 'string' && document.domain.search && document.domain.search(/localhost|127.0./g) === -1; if (isNonLocalHost && (DetectRTC.browser.isChrome || DetectRTC.browser.isEdge || DetectRTC.browser.isOpera)) { isScreenCapturingSupported = false; } else if (DetectRTC.browser.isFirefox) { isScreenCapturingSupported = false; } } DetectRTC.isScreenCapturingSupported = isScreenCapturingSupported; // --------- Detect if WebAudio API are supported var webAudio = { isSupported: false, isCreateMediaStreamSourceSupported: false }; ['AudioContext', 'webkitAudioContext', 'mozAudioContext', 'msAudioContext'].forEach(function (item) { if (webAudio.isSupported) { return; } if (item in window) { webAudio.isSupported = true; if (window[item] && 'createMediaStreamSource' in window[item].prototype) { webAudio.isCreateMediaStreamSourceSupported = true; } } }); DetectRTC.isAudioContextSupported = webAudio.isSupported; DetectRTC.isCreateMediaStreamSourceSupported = webAudio.isCreateMediaStreamSourceSupported; // ---------- Detect if SCTP/RTP channels are supported. var isRtpDataChannelsSupported = false; if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 31) { isRtpDataChannelsSupported = true; } DetectRTC.isRtpDataChannelsSupported = isRtpDataChannelsSupported; var isSCTPSupportd = false; if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 28) { isSCTPSupportd = true; } else if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 25) { isSCTPSupportd = true; } else if (DetectRTC.browser.isOpera && DetectRTC.browser.version >= 11) { isSCTPSupportd = true; } DetectRTC.isSctpDataChannelsSupported = isSCTPSupportd; // --------- DetectRTC.isMobileDevice = isMobileDevice; // "isMobileDevice" boolean is defined in "getBrowserInfo.js" // ------ var isGetUserMediaSupported = false; if (navigator.getUserMedia) { isGetUserMediaSupported = true; } else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { isGetUserMediaSupported = true; } if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 46 && !/^(https:|chrome-extension:)$/g.test(location.protocol || '')) { if (typeof document !== 'undefined' && typeof document.domain === 'string' && document.domain.search && document.domain.search(/localhost|127.0./g) === -1) { isGetUserMediaSupported = 'Requires HTTPs'; } } if (DetectRTC.osName === 'Nodejs') { isGetUserMediaSupported = false; } DetectRTC.isGetUserMediaSupported = isGetUserMediaSupported; var displayResolution = ''; if (screen.width) { var width = screen.width ? screen.width : ''; var height = screen.height ? screen.height : ''; displayResolution += '' + width + ' x ' + height; } DetectRTC.displayResolution = displayResolution; function getAspectRatio(w, h) { function gcd(a, b) { return b == 0 ? a : gcd(b, a % b); } var r = gcd(w, h); return w / r / (h / r); } DetectRTC.displayAspectRatio = getAspectRatio(screen.width, screen.height).toFixed(2); // ---------- DetectRTC.isCanvasSupportsStreamCapturing = isCanvasSupportsStreamCapturing; DetectRTC.isVideoSupportsStreamCapturing = isVideoSupportsStreamCapturing; if (DetectRTC.browser.name == 'Chrome' && DetectRTC.browser.version >= 53) { if (!DetectRTC.isCanvasSupportsStreamCapturing) { DetectRTC.isCanvasSupportsStreamCapturing = 'Requires chrome flag: enable-experimental-web-platform-features'; } if (!DetectRTC.isVideoSupportsStreamCapturing) { DetectRTC.isVideoSupportsStreamCapturing = 'Requires chrome flag: enable-experimental-web-platform-features'; } } // ------ DetectRTC.DetectLocalIPAddress = DetectLocalIPAddress; DetectRTC.isWebSocketsSupported = 'WebSocket' in window && 2 === window.WebSocket.CLOSING; DetectRTC.isWebSocketsBlocked = !DetectRTC.isWebSocketsSupported; if (DetectRTC.osName === 'Nodejs') { DetectRTC.isWebSocketsSupported = true; DetectRTC.isWebSocketsBlocked = false; } DetectRTC.checkWebSocketsSupport = function (callback) { callback = callback || function () {}; try { var starttime; var websocket = new WebSocket('wss://echo.websocket.org:443/'); websocket.onopen = function () { DetectRTC.isWebSocketsBlocked = false; starttime = new Date().getTime(); websocket.send('ping'); }; websocket.onmessage = function () { DetectRTC.WebsocketLatency = new Date().getTime() - starttime + 'ms'; callback(); websocket.close(); websocket = null; }; websocket.onerror = function () { DetectRTC.isWebSocketsBlocked = true; callback(); }; } catch (e) { DetectRTC.isWebSocketsBlocked = true; callback(); } }; // ------- DetectRTC.load = function (callback) { callback = callback || function () {}; checkDeviceSupport(callback); }; // check for microphone/camera support! if (typeof checkDeviceSupport === 'function') {// checkDeviceSupport(); } if (typeof MediaDevices !== 'undefined') { DetectRTC.MediaDevices = MediaDevices; } else { DetectRTC.MediaDevices = []; } DetectRTC.hasMicrophone = hasMicrophone; DetectRTC.hasSpeakers = hasSpeakers; DetectRTC.hasWebcam = hasWebcam; DetectRTC.isWebsiteHasWebcamPermissions = isWebsiteHasWebcamPermissions; DetectRTC.isWebsiteHasMicrophonePermissions = isWebsiteHasMicrophonePermissions; DetectRTC.audioInputDevices = audioInputDevices; DetectRTC.audioOutputDevices = audioOutputDevices; DetectRTC.videoInputDevices = videoInputDevices; // ------ var isSetSinkIdSupported = false; if (typeof document !== 'undefined' && typeof document.createElement === 'function' && 'setSinkId' in document.createElement('video')) { isSetSinkIdSupported = true; } DetectRTC.isSetSinkIdSupported = isSetSinkIdSupported; // ----- var isRTPSenderReplaceTracksSupported = false; if (DetectRTC.browser.isFirefox && typeof mozRTCPeerConnection !== 'undefined' /*&& DetectRTC.browser.version > 39*/ ) { /*global mozRTCPeerConnection:true */ if ('getSenders' in mozRTCPeerConnection.prototype) { isRTPSenderReplaceTracksSupported = true; } } else if (DetectRTC.browser.isChrome && typeof webkitRTCPeerConnection !== 'undefined') { /*global webkitRTCPeerConnection:true */ if ('getSenders' in webkitRTCPeerConnection.prototype) { isRTPSenderReplaceTracksSupported = true; } } DetectRTC.isRTPSenderReplaceTracksSupported = isRTPSenderReplaceTracksSupported; //------ var isRemoteStreamProcessingSupported = false; if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 38) { isRemoteStreamProcessingSupported = true; } DetectRTC.isRemoteStreamProcessingSupported = isRemoteStreamProcessingSupported; //------- var isApplyConstraintsSupported = false; /*global MediaStreamTrack:true */ if (typeof MediaStreamTrack !== 'undefined' && 'applyConstraints' in MediaStreamTrack.prototype) { isApplyConstraintsSupported = true; } DetectRTC.isApplyConstraintsSupported = isApplyConstraintsSupported; //------- var isMultiMonitorScreenCapturingSupported = false; if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 43) { // version 43 merely supports platforms for multi-monitors // version 44 will support exact multi-monitor selection i.e. you can select any monitor for screen capturing. isMultiMonitorScreenCapturingSupported = true; } DetectRTC.isMultiMonitorScreenCapturingSupported = isMultiMonitorScreenCapturingSupported; DetectRTC.isPromisesSupported = !!('Promise' in window); // version is generated by "grunt" DetectRTC.version = '1.3.7'; if (typeof DetectRTC === 'undefined') { window.DetectRTC = {}; } var MediaStream = window.MediaStream; if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') { MediaStream = webkitMediaStream; } if (typeof MediaStream !== 'undefined' && typeof MediaStream === 'function') { DetectRTC.MediaStream = Object.keys(MediaStream.prototype); } else DetectRTC.MediaStream = false; if (typeof MediaStreamTrack !== 'undefined') { DetectRTC.MediaStreamTrack = Object.keys(MediaStreamTrack.prototype); } else DetectRTC.MediaStreamTrack = false; var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; if (typeof RTCPeerConnection !== 'undefined') { DetectRTC.RTCPeerConnection = Object.keys(RTCPeerConnection.prototype); } else DetectRTC.RTCPeerConnection = false; window.DetectRTC = DetectRTC; if (true /* && !!module.exports*/ ) { module.exports = DetectRTC; } if (true) { !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () { return DetectRTC; }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } })(); /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15), __webpack_require__(21))) }), /* 21 */ (function(module, exports) { var g; // This works in non-strict mode g = function () { return this; }(); try { // This works if eval is allowed (see CSP) g = g || Function("return this")() || (1, eval)("this"); } catch (e) { // This works if the window reference is available if (typeof window === "object") g = window; } // g can still be undefined, but nothing to do about it... // We return undefined, instead of nothing here, so it's // easier to handle this case. if(!global) { ...} module.exports = g; }), /* 22 */ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! * jQuery JavaScript Library v3.3.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://jquery.org/license * * Date: 2018-01-20T17:24Z */ (function (global, factory) { "use strict"; if (typeof module === "object" && typeof module.exports === "object") { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. // For environments that do not have a `window` with a `document` // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); // See ticket #14549 for more info. module.exports = global.document ? factory(global, true) : function (w) { if (!w.document) { throw new Error("jQuery requires a window with a document"); } return factory(w); }; } else { factory(global); } // Pass this if window is not defined yet })(typeof window !== "undefined" ? window : this, function (window, noGlobal) { // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common // enough that all such attempts are guarded in a try block. "use strict"; var arr = []; var document = window.document; var getProto = Object.getPrototypeOf; var slice = arr.slice; var concat = arr.concat; var push = arr.push; var indexOf = arr.indexOf; var class2type = {}; var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call(Object); var support = {}; var isFunction = function isFunction(obj) { // Support: Chrome <=57, Firefox <=52 // In some browsers, typeof returns "function" for HTML elements // (i.e., `typeof document.createElement( "object" ) === "function"`). // We don't want to classify *any* DOM node as a function. return typeof obj === "function" && typeof obj.nodeType !== "number"; }; var isWindow = function isWindow(obj) { return obj != null && obj === obj.window; }; var preservedScriptAttributes = { type: true, src: true, noModule: true }; function DOMEval(code, doc, node) { doc = doc || document; var i, script = doc.createElement("script"); script.text = code; if (node) { for (i in preservedScriptAttributes) { if (node[i]) { script[i] = node[i]; } } } doc.head.appendChild(script).parentNode.removeChild(script); } function toType(obj) { if (obj == null) { return obj + ""; } // Support: Android <=2.3 only (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj; } /* global Symbol */ // Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module var version = "3.3.1", // Define a local copy of jQuery jQuery = function (selector, context) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init(selector, context); }, // Support: Android <=4.0 only // Make sure we trim BOM and NBSP rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function () { return slice.call(this); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function (num) { // Return all the elements in a clean array if (num == null) { return slice.call(this); } // Return just the one element from the set return num < 0 ? this[num + this.length] : this[num]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function (elems) { // Build a new jQuery matched element set var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function (callback) { return jQuery.each(this, callback); }, map: function (callback) { return this.pushStack(jQuery.map(this, function (elem, i) { return callback.call(elem, i, elem); })); }, slice: function () { return this.pushStack(slice.apply(this, arguments)); }, first: function () { return this.eq(0); }, last: function () { return this.eq(-1); }, eq: function (i) { var len = this.length, j = +i + (i < 0 ? len : 0); return this.pushStack(j >= 0 && j < len ? [this[j]] : []); }, end: function () { return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, sort: arr.sort, splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function () { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if (typeof target === "boolean") { deep = target; // Skip the boolean and the target target = arguments[i] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if (typeof target !== "object" && !isFunction(target)) { target = {}; } // Extend jQuery itself if only one argument is passed if (i === length) { target = this; i--; } for (; i < length; i++) { // Only deal with non-null/undefined values if ((options = arguments[i]) != null) { // Extend the base object for (name in options) { src = target[name]; copy = options[name]; // Prevent never-ending loop if (target === copy) { continue; } // Recurse if we're merging plain objects or arrays if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) { if (copyIsArray) { copyIsArray = false; clone = src && Array.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[name] = jQuery.extend(deep, clone, copy); // Don't bring in undefined values } else if (copy !== undefined) { target[name] = copy; } } } } // Return the modified object return target; }; jQuery.extend({ // Unique for each copy of jQuery on the page expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""), // Assume jQuery is ready without the ready module isReady: true, error: function (msg) { throw new Error(msg); }, noop: function () {}, isPlainObject: function (obj) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if (!obj || toString.call(obj) !== "[object Object]") { return false; } proto = getProto(obj); // Objects with no prototype (e.g., `Object.create( null )`) are plain if (!proto) { return true; } // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call(proto, "constructor") && proto.constructor; return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString; }, isEmptyObject: function (obj) { /* eslint-disable no-unused-vars */ // See https://github.com/eslint/eslint/issues/6125 var name; for (name in obj) { return false; } return true; }, // Evaluates a script in a global context globalEval: function (code) { DOMEval(code); }, each: function (obj, callback) { var length, i = 0; if (isArrayLike(obj)) { length = obj.length; for (; i < length; i++) { if (callback.call(obj[i], i, obj[i]) === false) { break; } } } else { for (i in obj) { if (callback.call(obj[i], i, obj[i]) === false) { break; } } } return obj; }, // Support: Android <=4.0 only trim: function (text) { return text == null ? "" : (text + "").replace(rtrim, ""); }, // results is for internal usage only makeArray: function (arr, results) { var ret = results || []; if (arr != null) { if (isArrayLike(Object(arr))) { jQuery.merge(ret, typeof arr === "string" ? [arr] : arr); } else { push.call(ret, arr); } } return ret; }, inArray: function (elem, arr, i) { return arr == null ? -1 : indexOf.call(arr, elem, i); }, // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit merge: function (first, second) { var len = +second.length, j = 0, i = first.length; for (; j < len; j++) { first[i++] = second[j]; } first.length = i; return first; }, grep: function (elems, callback, invert) { var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for (; i < length; i++) { callbackInverse = !callback(elems[i], i); if (callbackInverse !== callbackExpect) { matches.push(elems[i]); } } return matches; }, // arg is for internal usage only map: function (elems, callback, arg) { var length, value, i = 0, ret = []; // Go through the array, translating each of the items to their new values if (isArrayLike(elems)) { length = elems.length; for (; i < length; i++) { value = callback(elems[i], i, arg); if (value != null) { ret.push(value); } } // Go through every key on the object, } else { for (i in elems) { value = callback(elems[i], i, arg); if (value != null) { ret.push(value); } } } // Flatten any nested arrays return concat.apply([], ret); }, // A global GUID counter for objects guid: 1, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support }); if (typeof Symbol === "function") { jQuery.fn[Symbol.iterator] = arr[Symbol.iterator]; } // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) { class2type["[object " + name + "]"] = name.toLowerCase(); }); function isArrayLike(obj) { // Support: real iOS 8.2 only (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, type = toType(obj); if (isFunction(obj) || isWindow(obj)) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj; } var Sizzle = /*! * Sizzle CSS Selector Engine v2.3.3 * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2016-08-08 */ function (window) { var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, // Local document vars setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, // Instance-specific data expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function (a, b) { if (a === b) { hasDuplicate = true; } return 0; }, // Instance methods hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function (list, elem) { var i = 0, len = list.length; for (; i < len; i++) { if (list[i] === elem) { return i; } } return -1; }, booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp(whitespace + "+", "g"), rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"), rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"), rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"), rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"), rpseudo = new RegExp(pseudos), ridentifier = new RegExp("^" + identifier + "$"), matchExpr = { "ID": new RegExp("^#(" + identifier + ")"), "CLASS": new RegExp("^\\.(" + identifier + ")"), "TAG": new RegExp("^(" + identifier + "|[*])"), "ATTR": new RegExp("^" + attributes), "PSEUDO": new RegExp("^" + pseudos), "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"), "bool": new RegExp("^(?:" + booleans + ")$", "i"), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i") }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"), funescape = function (_, escaped, escapedWhitespace) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint // Support: Firefox<24 // Workaround erroneous numeric interpretation of +"0x" return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint String.fromCharCode(high + 0x10000) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00); }, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function (ch, asCodePoint) { if (asCodePoint) { // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER if (ch === "\0") { return "\uFFFD"; } // Control characters and (dependent upon position) numbers get escaped as code points return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " "; } // Other potentially-special ASCII characters get backslash-escaped return "\\" + ch; }, // Used for iframes // See setDocument() // Removing the function wrapper causes a "Permission Denied" // error in IE unloadHandler = function () { setDocument(); }, disabledAncestor = addCombinator(function (elem) { return elem.disabled === true && ("form" in elem || "label" in elem); }, { dir: "parentNode", next: "legend" }); // Optimize for push.apply( _, NodeList ) try { push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); // Support: Android<4.0 // Detect silently failing push.apply arr[preferredDoc.childNodes.length].nodeType; } catch (e) { push = { apply: arr.length ? // Leverage slice if possible function (target, els) { push_native.apply(target, slice.call(els)); } : // Support: IE<9 // Otherwise append directly function (target, els) { var j = target.length, i = 0; // Can't trust NodeList.length while (target[j++] = els[i++]) {} target.length = j - 1; } }; } function Sizzle(selector, context, results, seed) { var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, // nodeType defaults to 9, since context defaults to document nodeType = context ? context.nodeType : 9; results = results || []; // Return early from calls with invalid selector or context if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { return results; } // Try to shortcut find operations (as opposed to filters) in HTML documents if (!seed) { if ((context ? context.ownerDocument || context : preferredDoc) !== document) { setDocument(context); } context = context || document; if (documentIsHTML) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { // ID selector if (m = match[1]) { // Document context if (nodeType === 9) { if (elem = context.getElementById(m)) { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if (elem.id === m) { results.push(elem); return results; } } else { return results; } // Element context } else { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) { results.push(elem); return results; } } // Type selector } else if (match[2]) { push.apply(results, context.getElementsByTagName(selector)); return results; // Class selector } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) { push.apply(results, context.getElementsByClassName(m)); return results; } } // Take advantage of querySelectorAll if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) { if (nodeType !== 1) { newContext = context; newSelector = selector; // qSA looks outside Element context, which is not what we want // Thanks to Andrew Dupont for this workaround technique // Support: IE <=8 // Exclude object elements } else if (context.nodeName.toLowerCase() !== "object") { // Capture the context ID, setting it first if necessary if (nid = context.getAttribute("id")) { nid = nid.replace(rcssescape, fcssescape); } else { context.setAttribute("id", nid = expando); } // Prefix every selector in the list groups = tokenize(selector); i = groups.length; while (i--) { groups[i] = "#" + nid + " " + toSelector(groups[i]); } newSelector = groups.join(","); // Expand context for sibling selectors newContext = rsibling.test(selector) && testContext(context.parentNode) || context; } if (newSelector) { try { push.apply(results, newContext.querySelectorAll(newSelector)); return results; } catch (qsaError) {} finally { if (nid === expando) { context.removeAttribute("id"); } } } } } } // All others return select(selector.replace(rtrim, "$1"), context, results, seed); } /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var keys = []; function cache(key, value) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if (keys.push(key + " ") > Expr.cacheLength) { // Only keep the most recent entries delete cache[keys.shift()]; } return cache[key + " "] = value; } return cache; } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction(fn) { fn[expando] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created element and returns a boolean result */ function assert(fn) { var el = document.createElement("fieldset"); try { return !!fn(el); } catch (e) { return false; } finally { // Remove from its parent by default if (el.parentNode) { el.parentNode.removeChild(el); } // release memory in IE el = null; } } /** * Adds the same handler for all of the specified attrs * @param {String} attrs Pipe-separated list of attributes * @param {Function} handler The method that will be applied */ function addHandle(attrs, handler) { var arr = attrs.split("|"), i = arr.length; while (i--) { Expr.attrHandle[arr[i]] = handler; } } /** * Checks document order of two siblings * @param {Element} a * @param {Element} b * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b */ function siblingCheck(a, b) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes if (diff) { return diff; } // Check if b follows a if (cur) { while (cur = cur.nextSibling) { if (cur === b) { return -1; } } } return a ? 1 : -1; } /** * Returns a function to use in pseudos for input types * @param {String} type */ function createInputPseudo(type) { return function (elem) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } /** * Returns a function to use in pseudos for buttons * @param {String} type */ function createButtonPseudo(type) { return function (elem) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && elem.type === type; }; } /** * Returns a function to use in pseudos for :enabled/:disabled * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo(disabled) { // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function (elem) { // Only certain elements can match :enabled or :disabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled if ("form" in elem) { // Check for inherited disabledness on relevant non-disabled elements: // * listed form-associated elements in a disabled fieldset // https://html.spec.whatwg.org/multipage/forms.html#category-listed // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled // * option elements in a disabled optgroup // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled // All such elements have a "form" property. if (elem.parentNode && elem.disabled === false) { // Option elements defer to a parent optgroup if present if ("label" in elem) { if ("label" in elem.parentNode) { return elem.parentNode.disabled === disabled; } else { return elem.disabled === disabled; } } // Support: IE 6 - 11 // Use the isDisabled shortcut property to check for disabled fieldset ancestors return elem.isDisabled === disabled || // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && disabledAncestor(elem) === disabled; } return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't // even exist on them, let alone have a boolean value. } else if ("label" in elem) { return elem.disabled === disabled; } // Remaining elements are neither :enabled nor :disabled return false; }; } /** * Returns a function to use in pseudos for positionals * @param {Function} fn */ function createPositionalPseudo(fn) { return markFunction(function (argument) { argument = +argument; return markFunction(function (seed, matches) { var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length; // Match elements found at the specified indexes while (i--) { if (seed[j = matchIndexes[i]]) { seed[j] = !(matches[j] = seed[j]); } } }); }); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext(context) { return context && typeof context.getElementsByTagName !== "undefined" && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function (elem) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function (node) { var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected if (doc === document || doc.nodeType !== 9 || !doc.documentElement) { return document; } // Update global variables document = doc; docElem = document.documentElement; documentIsHTML = !isXML(document); // Support: IE 9-11, Edge // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) if (preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow) { // Support: IE 11, Edge if (subWindow.addEventListener) { subWindow.addEventListener("unload", unloadHandler, false); // Support: IE 9 - 10 only } else if (subWindow.attachEvent) { subWindow.attachEvent("onunload", unloadHandler); } } /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) support.attributes = assert(function (el) { el.className = "i"; return !el.getAttribute("className"); }); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert(function (el) { el.appendChild(document.createComment("")); return !el.getElementsByTagName("*").length; }); // Support: IE<9 support.getElementsByClassName = rnative.test(document.getElementsByClassName); // Support: IE<10 // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test support.getById = assert(function (el) { docElem.appendChild(el).id = expando; return !document.getElementsByName || !document.getElementsByName(expando).length; }); // ID filter and find if (support.getById) { Expr.filter["ID"] = function (id) { var attrId = id.replace(runescape, funescape); return function (elem) { return elem.getAttribute("id") === attrId; }; }; Expr.find["ID"] = function (id, context) { if (typeof context.getElementById !== "undefined" && documentIsHTML) { var elem = context.getElementById(id); return elem ? [elem] : []; } }; } else { Expr.filter["ID"] = function (id) { var attrId = id.replace(runescape, funescape); return function (elem) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut Expr.find["ID"] = function (id, context) { if (typeof context.getElementById !== "undefined" && documentIsHTML) { var node, i, elems, elem = context.getElementById(id); if (elem) { // Verify the id attribute node = elem.getAttributeNode("id"); if (node && node.value === id) { return [elem]; } // Fall back on getElementsByName elems = context.getElementsByName(id); i = 0; while (elem = elems[i++]) { node = elem.getAttributeNode("id"); if (node && node.value === id) { return [elem]; } } } return []; } }; } // Tag Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) { if (typeof context.getElementsByTagName !== "undefined") { return context.getElementsByTagName(tag); // DocumentFragment nodes don't have gEBTN } else if (support.qsa) { return context.querySelectorAll(tag); } } : function (tag, context) { var elem, tmp = [], i = 0, // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName(tag); // Filter out possible comments if (tag === "*") { while (elem = results[i++]) { if (elem.nodeType === 1) { tmp.push(elem); } } return tmp; } return results; }; // Class Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) { if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) { return context.getElementsByClassName(className); } }; /* QSA/matchesSelector ---------------------------------------------------------------------- */ // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21) // We allow this because of a bug in IE8/9 that throws an error // whenever `document.activeElement` is accessed on an iframe // So, we allow :focus to pass through QSA all the time to avoid the IE error // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; if (support.qsa = rnative.test(document.querySelectorAll)) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function (el) { // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, // since its presence should be enough // https://bugs.jquery.com/ticket/12359 docElem.appendChild(el).innerHTML = "" + ""; // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section if (el.querySelectorAll("[msallowcapture^='']").length) { rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")"); } // Support: IE8 // Boolean attributes and "value" are not treated correctly if (!el.querySelectorAll("[selected]").length) { rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")"); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if (!el.querySelectorAll("[id~=" + expando + "-]").length) { rbuggyQSA.push("~="); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if (!el.querySelectorAll(":checked").length) { rbuggyQSA.push(":checked"); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if (!el.querySelectorAll("a#" + expando + "+*").length) { rbuggyQSA.push(".#.+[+~]"); } }); assert(function (el) { el.innerHTML = "" + ""; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = document.createElement("input"); input.setAttribute("type", "hidden"); el.appendChild(input).setAttribute("name", "D"); // Support: IE8 // Enforce case-sensitivity of name attribute if (el.querySelectorAll("[name=d]").length) { rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?="); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if (el.querySelectorAll(":enabled").length !== 2) { rbuggyQSA.push(":enabled", ":disabled"); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild(el).disabled = true; if (el.querySelectorAll(":disabled").length !== 2) { rbuggyQSA.push(":enabled", ":disabled"); } // Opera 10-11 does not throw on post-comma invalid pseudos el.querySelectorAll("*,:x"); rbuggyQSA.push(",.*:"); }); } if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) { assert(function (el) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call(el, "*"); // This should fail with an exception // Gecko does not error, returns false instead matches.call(el, "[s!='']:x"); rbuggyMatches.push("!=", pseudos); }); } rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|")); rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|")); /* Contains ---------------------------------------------------------------------- */ hasCompare = rnative.test(docElem.compareDocumentPosition); // Element contains another // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)); } : function (a, b) { if (b) { while (b = b.parentNode) { if (b === a) { return true; } } } return false; }; /* Sorting ---------------------------------------------------------------------- */ // Document order sorting sortOrder = hasCompare ? function (a, b) { // Flag for duplicate removal if (a === b) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if (compare) { return compare; } // Calculate position if both inputs belong to the same document compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : // Otherwise we know they are disconnected 1; // Disconnected nodes if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) { // Choose the first element that is related to our preferred document if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) { return -1; } if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) { return 1; } // Maintain original order return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; } return compare & 4 ? -1 : 1; } : function (a, b) { // Exit early if the nodes are identical if (a === b) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b]; // Parentless nodes are either documents or disconnected if (!aup || !bup) { return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; // If the nodes are siblings, we can do a quick check } else if (aup === bup) { return siblingCheck(a, b); } // Otherwise we need full lists of their ancestors for comparison cur = a; while (cur = cur.parentNode) { ap.unshift(cur); } cur = b; while (cur = cur.parentNode) { bp.unshift(cur); } // Walk down the tree looking for a discrepancy while (ap[i] === bp[i]) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck(ap[i], bp[i]) : // Otherwise nodes in our document sort first ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; }; return document; }; Sizzle.matches = function (expr, elements) { return Sizzle(expr, null, null, elements); }; Sizzle.matchesSelector = function (elem, expr) { // Set document vars if needed if ((elem.ownerDocument || elem) !== document) { setDocument(elem); } // Make sure that attribute selectors are quoted expr = expr.replace(rattributeQuotes, "='$1']"); if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) { try { var ret = matches.call(elem, expr); // IE 9's matchesSelector returns false on disconnected nodes if (ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11) { return ret; } } catch (e) {} } return Sizzle(expr, document, null, [elem]).length > 0; }; Sizzle.contains = function (context, elem) { // Set document vars if needed if ((context.ownerDocument || context) !== document) { setDocument(context); } return contains(context, elem); }; Sizzle.attr = function (elem, name) { // Set document vars if needed if ((elem.ownerDocument || elem) !== document) { setDocument(elem); } var fn = Expr.attrHandle[name.toLowerCase()], // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined; return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; }; Sizzle.escape = function (sel) { return (sel + "").replace(rcssescape, fcssescape); }; Sizzle.error = function (msg) { throw new Error("Syntax error, unrecognized expression: " + msg); }; /** * Document sorting and removing duplicates * @param {ArrayLike} results */ Sizzle.uniqueSort = function (results) { var elem, duplicates = [], j = 0, i = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; sortInput = !support.sortStable && results.slice(0); results.sort(sortOrder); if (hasDuplicate) { while (elem = results[i++]) { if (elem === results[i]) { j = duplicates.push(i); } } while (j--) { results.splice(duplicates[j], 1); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; return results; }; /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function (elem) { var node, ret = "", i = 0, nodeType = elem.nodeType; if (!nodeType) { // If no nodeType, this is expected to be an array while (node = elem[i++]) { // Do not traverse comment nodes ret += getText(node); } } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if (typeof elem.textContent === "string") { return elem.textContent; } else { // Traverse its children for (elem = elem.firstChild; elem; elem = elem.nextSibling) { ret += getText(elem); } } } else if (nodeType === 3 || nodeType === 4) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function (match) { match[1] = match[1].replace(runescape, funescape); // Move the given value to match[3] whether quoted or unquoted match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape); if (match[2] === "~=") { match[3] = " " + match[3] + " "; } return match.slice(0, 4); }, "CHILD": function (match) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[1] = match[1].toLowerCase(); if (match[1].slice(0, 3) === "nth") { // nth-* requires argument if (!match[3]) { Sizzle.error(match[0]); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd")); match[5] = +(match[7] + match[8] || match[3] === "odd"); // other types prohibit arguments } else if (match[3]) { Sizzle.error(match[0]); } return match; }, "PSEUDO": function (match) { var excess, unquoted = !match[6] && match[2]; if (matchExpr["CHILD"].test(match[0])) { return null; } // Accept quoted arguments as-is if (match[3]) { match[2] = match[4] || match[5] || ""; // Strip excess characters from unquoted arguments } else if (unquoted && rpseudo.test(unquoted) && ( // Get excess from tokenize (recursively) excess = tokenize(unquoted, true)) && ( // advance to the next closing parenthesis excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) { // excess is a negative index match[0] = match[0].slice(0, excess); match[2] = unquoted.slice(0, excess); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice(0, 3); } }, filter: { "TAG": function (nodeNameSelector) { var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); return nodeNameSelector === "*" ? function () { return true; } : function (elem) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function (className) { var pattern = classCache[className + " "]; return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) { return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || ""); }); }, "ATTR": function (name, operator, check) { return function (elem) { var result = Sizzle.attr(elem, name); if (result == null) { return operator === "!="; } if (!operator) { return true; } result += ""; return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false; }; }, "CHILD": function (type, what, argument, first, last) { var simple = type.slice(0, 3) !== "nth", forward = type.slice(-4) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function (elem) { return !!elem.parentNode; } : function (elem, context, xml) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; if (parent) { // :(first|last|only)-(child|of-type) if (simple) { while (dir) { node = elem; while (node = node[dir]) { if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [forward ? parent.firstChild : parent.lastChild]; // non-xml :nth-child(...) stores cache data on `parent` if (forward && useCache) { // Seek `elem` from a previously-cached index // ...in a gzip-friendly way node = parent; outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); cache = uniqueCache[type] || []; nodeIndex = cache[0] === dirruns && cache[1]; diff = nodeIndex && cache[2]; node = nodeIndex && parent.childNodes[nodeIndex]; while (node = ++nodeIndex && node && node[dir] || ( // Fallback to seeking `elem` from the start diff = nodeIndex = 0) || start.pop()) { // When found, cache indexes on `parent` and break if (node.nodeType === 1 && ++diff && node === elem) { uniqueCache[type] = [dirruns, nodeIndex, diff]; break; } } } else { // Use previously-cached element index if available if (useCache) { // ...in a gzip-friendly way node = elem; outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); cache = uniqueCache[type] || []; nodeIndex = cache[0] === dirruns && cache[1]; diff = nodeIndex; } // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if (diff === false) { // Use the same loop as above to seek `elem` from the start while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) { // Cache the index of each encountered element if (useCache) { outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); uniqueCache[type] = [dirruns, diff]; } if (node === elem) { break; } } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || diff % first === 0 && diff / first >= 0; } }; }, "PSEUDO": function (pseudo, argument) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if (fn[expando]) { return fn(argument); } // But maintain support for old signatures if (fn.length > 1) { args = [pseudo, pseudo, "", argument]; return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) { var idx, matched = fn(seed, argument), i = matched.length; while (i--) { idx = indexOf(seed, matched[i]); seed[idx] = !(matches[idx] = matched[i]); } }) : function (elem) { return fn(elem, 0, args); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction(function (selector) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile(selector.replace(rtrim, "$1")); return matcher[expando] ? markFunction(function (seed, matches, context, xml) { var elem, unmatched = matcher(seed, null, xml, []), i = seed.length; // Match elements unmatched by `matcher` while (i--) { if (elem = unmatched[i]) { seed[i] = !(matches[i] = elem); } } }) : function (elem, context, xml) { input[0] = elem; matcher(input, null, xml, results); // Don't keep the element (issue #299) input[0] = null; return !results.pop(); }; }), "has": markFunction(function (selector) { return function (elem) { return Sizzle(selector, elem).length > 0; }; }), "contains": markFunction(function (text) { text = text.replace(runescape, funescape); return function (elem) { return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1; }; }), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction(function (lang) { // lang value must be a valid identifier if (!ridentifier.test(lang || "")) { Sizzle.error("unsupported lang: " + lang); } lang = lang.replace(runescape, funescape).toLowerCase(); return function (elem) { var elemLang; do { if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf(lang + "-") === 0; } } while ((elem = elem.parentNode) && elem.nodeType === 1); return false; }; }), // Miscellaneous "target": function (elem) { var hash = window.location && window.location.hash; return hash && hash.slice(1) === elem.id; }, "root": function (elem) { return elem === docElem; }, "focus": function (elem) { return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, // Boolean properties "enabled": createDisabledPseudo(false), "disabled": createDisabledPseudo(true), "checked": function (elem) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected; }, "selected": function (elem) { // Accessing this property makes selected-by-default // options in Safari work properly if (elem.parentNode) { elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function (elem) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for (elem = elem.firstChild; elem; elem = elem.nextSibling) { if (elem.nodeType < 6) { return false; } } return true; }, "parent": function (elem) { return !Expr.pseudos["empty"](elem); }, // Element/input types "header": function (elem) { return rheader.test(elem.nodeName); }, "input": function (elem) { return rinputs.test(elem.nodeName); }, "button": function (elem) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function (elem) { var attr; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text"); }, // Position-in-collection "first": createPositionalPseudo(function () { return [0]; }), "last": createPositionalPseudo(function (matchIndexes, length) { return [length - 1]; }), "eq": createPositionalPseudo(function (matchIndexes, length, argument) { return [argument < 0 ? argument + length : argument]; }), "even": createPositionalPseudo(function (matchIndexes, length) { var i = 0; for (; i < length; i += 2) { matchIndexes.push(i); } return matchIndexes; }), "odd": createPositionalPseudo(function (matchIndexes, length) { var i = 1; for (; i < length; i += 2) { matchIndexes.push(i); } return matchIndexes; }), "lt": createPositionalPseudo(function (matchIndexes, length, argument) { var i = argument < 0 ? argument + length : argument; for (; --i >= 0;) { matchIndexes.push(i); } return matchIndexes; }), "gt": createPositionalPseudo(function (matchIndexes, length, argument) { var i = argument < 0 ? argument + length : argument; for (; ++i < length;) { matchIndexes.push(i); } return matchIndexes; }) } }; Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Add button/input type pseudos for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) { Expr.pseudos[i] = createInputPseudo(i); } for (i in { submit: true, reset: true }) { Expr.pseudos[i] = createButtonPseudo(i); } // Easy API for creating new setFilters function setFilters() {} setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function (selector, parseOnly) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + " "]; if (cached) { return parseOnly ? 0 : cached.slice(0); } soFar = selector; groups = []; preFilters = Expr.preFilter; while (soFar) { // Comma and first run if (!matched || (match = rcomma.exec(soFar))) { if (match) { // Don't consume trailing commas as valid soFar = soFar.slice(match[0].length) || soFar; } groups.push(tokens = []); } matched = false; // Combinators if (match = rcombinators.exec(soFar)) { matched = match.shift(); tokens.push({ value: matched, // Cast descendant combinators to space type: match[0].replace(rtrim, " ") }); soFar = soFar.slice(matched.length); } // Filters for (type in Expr.filter) { if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) { matched = match.shift(); tokens.push({ value: matched, type: type, matches: match }); soFar = soFar.slice(matched.length); } } if (!matched) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : // Cache the tokens tokenCache(selector, groups).slice(0); }; function toSelector(tokens) { var i = 0, len = tokens.length, selector = ""; for (; i < len; i++) { selector += tokens[i].value; } return selector; } function addCombinator(matcher, combinator, base) { var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function (elem, context, xml) { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { return matcher(elem, context, xml); } } return false; } : // Check against all ancestor/preceding elements function (elem, context, xml) { var oldCache, uniqueCache, outerCache, newCache = [dirruns, doneName]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if (xml) { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { if (matcher(elem, context, xml)) { return true; } } } } else { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { outerCache = elem[expando] || (elem[expando] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {}); if (skip && skip === elem.nodeName.toLowerCase()) { elem = elem[dir] || elem; } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) { // Assign to newCache so results back-propagate to previous elements return newCache[2] = oldCache[2]; } else { // Reuse newcache so results back-propagate to previous elements uniqueCache[key] = newCache; // A match means we're done; a fail means we have to keep checking if (newCache[2] = matcher(elem, context, xml)) { return true; } } } } } return false; }; } function elementMatcher(matchers) { return matchers.length > 1 ? function (elem, context, xml) { var i = matchers.length; while (i--) { if (!matchers[i](elem, context, xml)) { return false; } } return true; } : matchers[0]; } function multipleContexts(selector, contexts, results) { var i = 0, len = contexts.length; for (; i < len; i++) { Sizzle(selector, contexts[i], results); } return results; } function condense(unmatched, map, filter, context, xml) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for (; i < len; i++) { if (elem = unmatched[i]) { if (!filter || filter(elem, context, xml)) { newUnmatched.push(elem); if (mapped) { map.push(i); } } } } return newUnmatched; } function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { if (postFilter && !postFilter[expando]) { postFilter = setMatcher(postFilter); } if (postFinder && !postFinder[expando]) { postFinder = setMatcher(postFinder, postSelector); } return markFunction(function (seed, results, context, xml) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || (seed ? preFilter : preexisting || postFilter) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if (matcher) { matcher(matcherIn, matcherOut, context, xml); } // Apply postFilter if (postFilter) { temp = condense(matcherOut, postMap); postFilter(temp, [], context, xml); // Un-match failing elements by moving them back to matcherIn i = temp.length; while (i--) { if (elem = temp[i]) { matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); } } } if (seed) { if (postFinder || preFilter) { if (postFinder) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while (i--) { if (elem = matcherOut[i]) { // Restore matcherIn since elem is not yet a final match temp.push(matcherIn[i] = elem); } } postFinder(null, matcherOut = [], temp, xml); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while (i--) { if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) { seed[temp] = !(results[temp] = elem); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut); if (postFinder) { postFinder(null, results, matcherOut, xml); } else { push.apply(results, matcherOut); } } }); } function matcherFromTokens(tokens) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[" "], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator(function (elem) { return elem === checkContext; }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) { return indexOf(checkContext, elem) > -1; }, implicitRelative, true), matchers = [function (elem, context, xml) { var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); // Avoid hanging onto element (issue #299) checkContext = null; return ret; }]; for (; i < len; i++) { if (matcher = Expr.relative[tokens[i].type]) { matchers = [addCombinator(elementMatcher(matchers), matcher)]; } else { matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); // Return special upon seeing a positional matcher if (matcher[expando]) { // Find the next relative operator (if any) for proper handling j = ++i; for (; j < len; j++) { if (Expr.relative[tokens[j].type]) { break; } } return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*` tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === " " ? "*" : "" })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens)); } matchers.push(matcher); } } return elementMatcher(matchers); } function matcherFromGroupMatchers(elementMatchers, setMatchers) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find["TAG"]("*", outermost), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length; if (outermost) { outermostContext = context === document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id for (; i !== len && (elem = elems[i]) != null; i++) { if (byElement && elem) { j = 0; if (!context && elem.ownerDocument !== document) { setDocument(elem); xml = !documentIsHTML; } while (matcher = elementMatchers[j++]) { if (matcher(elem, context || document, xml)) { results.push(elem); break; } } if (outermost) { dirruns = dirrunsUnique; } } // Track unmatched elements for set filters if (bySet) { // They will have gone through all possible matchers if (elem = !matcher && elem) { matchedCount--; } // Lengthen the array for every element, matched or not if (seed) { unmatched.push(elem); } } } // `i` is now the count of elements visited above, and adding it to `matchedCount` // makes the latter nonnegative. matchedCount += i; // Apply set filters to unmatched elements // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` // equals `i`), unless we didn't visit _any_ elements in the above loop because we have // no element matchers and no seed. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that // case, which will result in a "00" `matchedCount` that differs from `i` but is also // numerically zero. if (bySet && i !== matchedCount) { j = 0; while (matcher = setMatchers[j++]) { matcher(unmatched, setMatched, context, xml); } if (seed) { // Reintegrate element matches to eliminate the need for sorting if (matchedCount > 0) { while (i--) { if (!(unmatched[i] || setMatched[i])) { setMatched[i] = pop.call(results); } } } // Discard index placeholder values to get only actual matches setMatched = condense(setMatched); } // Add matches to results push.apply(results, setMatched); // Seedless set matches succeeding multiple successful matchers stipulate sorting if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) { Sizzle.uniqueSort(results); } } // Override manipulation of globals by nested matchers if (outermost) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction(superMatcher) : superMatcher; } compile = Sizzle.compile = function (selector, match /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + " "]; if (!cached) { // Generate a function of recursive functions that can be used to check each element if (!match) { match = tokenize(selector); } i = match.length; while (i--) { cached = matcherFromTokens(match[i]); if (cached[expando]) { setMatchers.push(cached); } else { elementMatchers.push(cached); } } // Cache the compiled function cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); // Save selector and tokenization cached.selector = selector; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function (selector, context, results, seed) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, match = !seed && tokenize(selector = compiled.selector || selector); results = results || []; // Try to minimize operations if there is only one selector in the list and no seed // (the latter of which guarantees us context) if (match.length === 1) { // Reduce context if the leading compound selector is an ID tokens = match[0] = match[0].slice(0); if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0]; if (!context) { return results; // Precompiled matchers will still verify ancestry, so step up a level } else if (compiled) { context = context.parentNode; } selector = selector.slice(tokens.shift().value.length); } // Fetch a seed set for right-to-left matching i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length; while (i--) { token = tokens[i]; // Abort if we hit a combinator if (Expr.relative[type = token.type]) { break; } if (find = Expr.find[type]) { // Search, expanding context for leading sibling combinators if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) { // If seed is empty or no tokens remain, we can return early tokens.splice(i, 1); selector = seed.length && toSelector(tokens); if (!selector) { push.apply(results, seed); return results; } break; } } } } // Compile and execute a filtering function if one is not provided // Provide `match` to avoid retokenization if we modified the selector above (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context); return results; }; // One-time assignments // Sort stability support.sortStable = expando.split("").sort(sortOrder).join("") === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = !!hasDuplicate; // Initialize against the default document setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* support.sortDetached = assert(function (el) { // Should return 1, but returns 4 (following) return el.compareDocumentPosition(document.createElement("fieldset")) & 1; }); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if (!assert(function (el) { el.innerHTML = ""; return el.firstChild.getAttribute("href") === "#"; })) { addHandle("type|href|height|width", function (elem, name, isXML) { if (!isXML) { return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2); } }); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") if (!support.attributes || !assert(function (el) { el.innerHTML = ""; el.firstChild.setAttribute("value", ""); return el.firstChild.getAttribute("value") === ""; })) { addHandle("value", function (elem, name, isXML) { if (!isXML && elem.nodeName.toLowerCase() === "input") { return elem.defaultValue; } }); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if (!assert(function (el) { return el.getAttribute("disabled") == null; })) { addHandle(booleans, function (elem, name, isXML) { var val; if (!isXML) { return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; } }); } return Sizzle; }(window); jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; // Deprecated jQuery.expr[":"] = jQuery.expr.pseudos; jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; jQuery.escapeSelector = Sizzle.escape; var dir = function (elem, dir, until) { var matched = [], truncate = until !== undefined; while ((elem = elem[dir]) && elem.nodeType !== 9) { if (elem.nodeType === 1) { if (truncate && jQuery(elem).is(until)) { break; } matched.push(elem); } } return matched; }; var siblings = function (n, elem) { var matched = []; for (; n; n = n.nextSibling) { if (n.nodeType === 1 && n !== elem) { matched.push(n); } } return matched; }; var rneedsContext = jQuery.expr.match.needsContext; function nodeName(elem, name) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); } ; var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; // Implement the identical functionality for filter and not function winnow(elements, qualifier, not) { if (isFunction(qualifier)) { return jQuery.grep(elements, function (elem, i) { return !!qualifier.call(elem, i, elem) !== not; }); } // Single element if (qualifier.nodeType) { return jQuery.grep(elements, function (elem) { return elem === qualifier !== not; }); } // Arraylike of elements (jQuery, arguments, Array) if (typeof qualifier !== "string") { return jQuery.grep(elements, function (elem) { return indexOf.call(qualifier, elem) > -1 !== not; }); } // Filtered directly for both simple and complex selectors return jQuery.filter(qualifier, elements, not); } jQuery.filter = function (expr, elems, not) { var elem = elems[0]; if (not) { expr = ":not(" + expr + ")"; } if (elems.length === 1 && elem.nodeType === 1) { return jQuery.find.matchesSelector(elem, expr) ? [elem] : []; } return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { return elem.nodeType === 1; })); }; jQuery.fn.extend({ find: function (selector) { var i, ret, len = this.length, self = this; if (typeof selector !== "string") { return this.pushStack(jQuery(selector).filter(function () { for (i = 0; i < len; i++) { if (jQuery.contains(self[i], this)) { return true; } } })); } ret = this.pushStack([]); for (i = 0; i < len; i++) { jQuery.find(selector, self[i], ret); } return len > 1 ? jQuery.uniqueSort(ret) : ret; }, filter: function (selector) { return this.pushStack(winnow(this, selector || [], false)); }, not: function (selector) { return this.pushStack(winnow(this, selector || [], true)); }, is: function (selector) { return !!winnow(this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length; } }); // Initialize a jQuery object // A central reference to the root jQuery(document) var rootjQuery, // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) // Shortcut simple #id case for speed rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function (selector, context, root) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if (!selector) { return this; } // Method init() accepts an alternate rootjQuery // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; // Handle HTML strings if (typeof selector === "string") { if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [null, selector, null]; } else { match = rquickExpr.exec(selector); } // Match html or make sure no context is specified for #id if (match && (match[1] || !context)) { // HANDLE: $(html) -> $(array) if (match[1]) { context = context instanceof jQuery ? context[0] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); // HANDLE: $(html, props) if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { for (match in context) { // Properties of context are called as methods if possible if (isFunction(this[match])) { this[match](context[match]); // ...and otherwise set as attributes } else { this.attr(match, context[match]); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById(match[2]); if (elem) { // Inject the element directly into the jQuery object this[0] = elem; this.length = 1; } return this; } // HANDLE: $(expr, $(...)) } else if (!context || context.jquery) { return (context || root).find(selector); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor(context).find(selector); } // HANDLE: $(DOMElement) } else if (selector.nodeType) { this[0] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if (isFunction(selector)) { return root.ready !== undefined ? root.ready(selector) : // Execute immediately if ready is not present selector(jQuery); } return jQuery.makeArray(selector, this); }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; // Initialize central reference rootjQuery = jQuery(document); var rparentsprev = /^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend({ has: function (target) { var targets = jQuery(target, this), l = targets.length; return this.filter(function () { var i = 0; for (; i < l; i++) { if (jQuery.contains(this, targets[i])) { return true; } } }); }, closest: function (selectors, context) { var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== "string" && jQuery(selectors); // Positional selectors never match, since there's no _selection_ context if (!rneedsContext.test(selectors)) { for (; i < l; i++) { for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { // Always skip document fragments if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) { matched.push(cur); break; } } } } return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); }, // Determine the position of an element within the set index: function (elem) { // No argument, return index in parent if (!elem) { return this[0] && this[0].parentNode ? this.first().prevAll().length : -1; } // Index in selector if (typeof elem === "string") { return indexOf.call(jQuery(elem), this[0]); } // Locate the position of the desired element return indexOf.call(this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[0] : elem); }, add: function (selector, context) { return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context)))); }, addBack: function (selector) { return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector)); } }); function sibling(cur, dir) { while ((cur = cur[dir]) && cur.nodeType !== 1) {} return cur; } jQuery.each({ parent: function (elem) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function (elem) { return dir(elem, "parentNode"); }, parentsUntil: function (elem, i, until) { return dir(elem, "parentNode", until); }, next: function (elem) { return sibling(elem, "nextSibling"); }, prev: function (elem) { return sibling(elem, "previousSibling"); }, nextAll: function (elem) { return dir(elem, "nextSibling"); }, prevAll: function (elem) { return dir(elem, "previousSibling"); }, nextUntil: function (elem, i, until) { return dir(elem, "nextSibling", until); }, prevUntil: function (elem, i, until) { return dir(elem, "previousSibling", until); }, siblings: function (elem) { return siblings((elem.parentNode || {}).firstChild, elem); }, children: function (elem) { return siblings(elem.firstChild); }, contents: function (elem) { if (nodeName(elem, "iframe")) { return elem.contentDocument; } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only // Treat the template element as a regular one in browsers that // don't support it. if (nodeName(elem, "template")) { elem = elem.content || elem; } return jQuery.merge([], elem.childNodes); } }, function (name, fn) { jQuery.fn[name] = function (until, selector) { var matched = jQuery.map(this, fn, until); if (name.slice(-5) !== "Until") { selector = until; } if (selector && typeof selector === "string") { matched = jQuery.filter(selector, matched); } if (this.length > 1) { // Remove duplicates if (!guaranteedUnique[name]) { jQuery.uniqueSort(matched); } // Reverse order for parents* and prev-derivatives if (rparentsprev.test(name)) { matched.reverse(); } } return this.pushStack(matched); }; }); var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; // Convert String-formatted options into Object-formatted ones function createOptions(options) { var object = {}; jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) { object[flag] = true; }); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function (options) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options); var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists memory, // Flag to know if list was already fired fired, // Flag to prevent firing locked, // Actual callback list list = [], // Queue of execution data for repeatable lists queue = [], // Index of currently firing callback (modified by add/remove as needed) firingIndex = -1, // Fire callbacks fire = function () { // Enforce single-firing locked = locked || options.once; // Execute callbacks for all pending executions, // respecting firingIndex overrides and runtime changes fired = firing = true; for (; queue.length; firingIndex = -1) { memory = queue.shift(); while (++firingIndex < list.length) { // Run callback and check for early termination if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) { // Jump to end and forget the data so .add doesn't re-fire firingIndex = list.length; memory = false; } } } // Forget the data if we're done with it if (!options.memory) { memory = false; } firing = false; // Clean up if we're done firing for good if (locked) { // Keep an empty list if we have data for future add calls if (memory) { list = []; // Otherwise, this object is spent } else { list = ""; } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function () { if (list) { // If we have memory from a past run, we should fire after adding if (memory && !firing) { firingIndex = list.length - 1; queue.push(memory); } (function add(args) { jQuery.each(args, function (_, arg) { if (isFunction(arg)) { if (!options.unique || !self.has(arg)) { list.push(arg); } } else if (arg && arg.length && toType(arg) !== "string") { // Inspect recursively add(arg); } }); })(arguments); if (memory && !firing) { fire(); } } return this; }, // Remove a callback from the list remove: function () { jQuery.each(arguments, function (_, arg) { var index; while ((index = jQuery.inArray(arg, list, index)) > -1) { list.splice(index, 1); // Handle firing indexes if (index <= firingIndex) { firingIndex--; } } }); return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function (fn) { return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function () { if (list) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function () { locked = queue = []; list = memory = ""; return this; }, disabled: function () { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function () { locked = queue = []; if (!memory && !firing) { list = memory = ""; } return this; }, locked: function () { return !!locked; }, // Call all callbacks with the given context and arguments fireWith: function (context, args) { if (!locked) { args = args || []; args = [context, args.slice ? args.slice() : args]; queue.push(args); if (!firing) { fire(); } } return this; }, // Call all the callbacks with the given arguments fire: function () { self.fireWith(this, arguments); return this; }, // To know if the callbacks have already been called at least once fired: function () { return !!fired; } }; return self; }; function Identity(v) { return v; } function Thrower(ex) { throw ex; } function adoptValue(value, resolve, reject, noValue) { var method; try { // Check for promise aspect first to privilege synchronous behavior if (value && isFunction(method = value.promise)) { method.call(value).done(resolve).fail(reject); // Other thenables } else if (value && isFunction(method = value.then)) { method.call(value, resolve, reject); // Other non-thenables } else { // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: // * false: [ value ].slice( 0 ) => resolve( value ) // * true: [ value ].slice( 1 ) => resolve() resolve.apply(undefined, [value].slice(noValue)); } // For Promises/A+, convert exceptions into rejections // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch (value) { // Support: Android 4.0 only // Strict mode functions invoked without .call/.apply get global-object context reject.apply(undefined, [value]); } } jQuery.extend({ Deferred: function (func) { var tuples = [// action, add listener, callbacks, // ... .then handlers, argument index, [final state] ["notify", "progress", jQuery.Callbacks("memory"), jQuery.Callbacks("memory"), 2], ["resolve", "done", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 1, "rejected"]], state = "pending", promise = { state: function () { return state; }, always: function () { deferred.done(arguments).fail(arguments); return this; }, "catch": function (fn) { return promise.then(null, fn); }, // Keep pipe for back-compat pipe: function () /* fnDone, fnFail, fnProgress */ { var fns = arguments; return jQuery.Deferred(function (newDefer) { jQuery.each(tuples, function (i, tuple) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[tuple[1]](function () { var returned = fn && fn.apply(this, arguments); if (returned && isFunction(returned.promise)) { returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject); } else { newDefer[tuple[0] + "With"](this, fn ? [returned] : arguments); } }); }); fns = null; }).promise(); }, then: function (onFulfilled, onRejected, onProgress) { var maxDepth = 0; function resolve(depth, deferred, handler, special) { return function () { var that = this, args = arguments, mightThrow = function () { var returned, then; // Support: Promises/A+ section 2.3.3.3.3 // https://promisesaplus.com/#point-59 // Ignore double-resolution attempts if (depth < maxDepth) { return; } returned = handler.apply(that, args); // Support: Promises/A+ section 2.3.1 // https://promisesaplus.com/#point-48 if (returned === deferred.promise()) { throw new TypeError("Thenable self-resolution"); } // Support: Promises/A+ sections 2.3.3.1, 3.5 // https://promisesaplus.com/#point-54 // https://promisesaplus.com/#point-75 // Retrieve `then` only once then = returned && ( // Support: Promises/A+ section 2.3.4 // https://promisesaplus.com/#point-64 // Only check objects and functions for thenability typeof returned === "object" || typeof returned === "function") && returned.then; // Handle a returned thenable if (isFunction(then)) { // Special processors (notify) just wait for resolution if (special) { then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special)); // Normal processors (resolve) also hook into progress } else { // ...and disregard older resolution values maxDepth++; then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith)); } // Handle all other returned values } else { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if (handler !== Identity) { that = undefined; args = [returned]; } // Process the value(s) // Default process is resolve (special || deferred.resolveWith)(that, args); } }, // Only normal processors (resolve) catch and reject exceptions process = special ? mightThrow : function () { try { mightThrow(); } catch (e) { if (jQuery.Deferred.exceptionHook) { jQuery.Deferred.exceptionHook(e, process.stackTrace); } // Support: Promises/A+ section 2.3.3.3.4.1 // https://promisesaplus.com/#point-61 // Ignore post-resolution exceptions if (depth + 1 >= maxDepth) { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if (handler !== Thrower) { that = undefined; args = [e]; } deferred.rejectWith(that, args); } } }; // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve proterminatemises immediately to dodge false rejection from // subsequent errors if (depth) { process(); } else { // Call an optional hook to record the stack, in case of exception // since it's otherwise lost when execution goes async if (jQuery.Deferred.getStackHook) { process.stackTrace = jQuery.Deferred.getStackHook(); } window.setTimeout(process); } }; } return jQuery.Deferred(function (newDefer) { // progress_handlers.add( ... ) tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith)); // fulfilled_handlers.add( ... ) tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity)); // rejected_handlers.add( ... ) tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower)); }).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function (obj) { return obj != null ? jQuery.extend(obj, promise) : promise; } }, deferred = {}; // Add list-specific methods jQuery.each(tuples, function (i, tuple) { var list = tuple[2], stateString = tuple[5]; // promise.progress = list.add // promise.done = list.add // promise.fail = list.add promise[tuple[1]] = list.add; // Handle state if (stateString) { list.add(function () { // state = "resolved" (i.e., fulfilled) // state = "rejected" state = stateString; }, // rejected_callbacks.disable // fulfilled_callbacks.disable tuples[3 - i][2].disable, // rejected_handlers.disable // fulfilled_handlers.disable tuples[3 - i][3].disable, // progress_callbacks.lock tuples[0][2].lock, // progress_handlers.lock tuples[0][3].lock); } // progress_handlers.fire // fulfilled_handlers.fire // rejected_handlers.fire list.add(tuple[3].fire); // deferred.notify = function() { deferred.notifyWith(...) } // deferred.resolve = function() { deferred.resolveWith(...) } // deferred.reject = function() { deferred.rejectWith(...) } deferred[tuple[0]] = function () { deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments); return this; }; // deferred.notifyWith = list.fireWith // deferred.resolveWith = list.fireWith // deferred.rejectWith = list.fireWith deferred[tuple[0] + "With"] = list.fireWith; }); // Make the deferred a promise promise.promise(deferred); // Call given func if any if (func) { func.call(deferred, deferred); } // All done! return deferred; }, // Deferred helper when: function (singleValue) { var // count of uncompleted subordinates remaining = arguments.length, // count of unprocessed arguments i = remaining, // subordinate fulfillment data resolveContexts = Array(i), resolveValues = slice.call(arguments), // the master Deferred master = jQuery.Deferred(), // subordinate callback factory updateFunc = function (i) { return function (value) { resolveContexts[i] = this; resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value; if (! --remaining) { master.resolveWith(resolveContexts, resolveValues); } }; }; // Single- and empty arguments are adopted like Promise.resolve if (remaining <= 1) { adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, !remaining); // Use .then() to unwrap secondary thenables (cf. gh-3000) if (master.state() === "pending" || isFunction(resolveValues[i] && resolveValues[i].then)) { return master.then(); } } // Multiple arguments are aggregated like Promise.all array elements while (i--) { adoptValue(resolveValues[i], updateFunc(i), master.reject); } return master.promise(); } }); // These usually indicate a programmer mistake during development, // warn about them ASAP rather than swallowing them by default. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; jQuery.Deferred.exceptionHook = function (error, stack) { // Support: IE 8 - 9 only // Console exists when dev tools are open, which can happen at any time if (window.console && window.console.warn && error && rerrorNames.test(error.name)) { window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack); } }; jQuery.readyException = function (error) { window.setTimeout(function () { throw error; }); }; // The deferred used on DOM ready var readyList = jQuery.Deferred(); jQuery.fn.ready = function (fn) { readyList.then(fn) // Wrap jQuery.readyException in a function so that the lookup // happens at the time of error handling instead of callback // registration. .catch(function (error) { jQuery.readyException(error); }); return this; }; jQuery.extend({ // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Handle when the DOM is ready ready: function (wait) { // Abort if there are pending holds or we're already ready if (wait === true ? --jQuery.readyWait : jQuery.isReady) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if (wait !== true && --jQuery.readyWait > 0) { return; } // If there are functions bound, to execute readyList.resolveWith(document, [jQuery]); } }); jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method function completed() { document.removeEventListener("DOMContentLoaded", completed); window.removeEventListener("load", completed); jQuery.ready(); } // Catch cases where $(document).ready() is called // after the browser event has already occurred. // Support: IE <=9 - 10 only // Older IE sometimes signals "interactive" too soon if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout(jQuery.ready); } else { // Use the handy event callback document.addEventListener("DOMContentLoaded", completed); // A fallback to window.onload, that will always work window.addEventListener("load", completed); } // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function var access = function (elems, fn, key, value, chainable, emptyGet, raw) { var i = 0, len = elems.length, bulk = key == null; // Sets many values if (toType(key) === "object") { chainable = true; for (i in key) { access(elems, fn, i, key[i], true, emptyGet, raw); } // Sets one value } else if (value !== undefined) { chainable = true; if (!isFunction(value)) { raw = true; } if (bulk) { // Bulk operations run against the entire set if (raw) { fn.call(elems, value); fn = null; // ...except when executing function values } else { bulk = fn; fn = function (elem, key, value) { return bulk.call(jQuery(elem), value); }; } } if (fn) { for (; i < len; i++) { fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key))); } } } if (chainable) { return elems; } // Gets if (bulk) { return fn.call(elems); } return len ? fn(elems[0], key) : emptyGet; }; // Matches dashed string for camelizing var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace() function fcamelCase(all, letter) { return letter.toUpperCase(); } // Convert dashed to camelCase; used by the css and data modules // Support: IE <=9 - 11, Edge 12 - 15 // Microsoft forgot to hump their vendor prefix (#9572) function camelCase(string) { return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase); } var acceptData = function (owner) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType; }; function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { cache: function (owner) { // Check if the owner object already has a cache var value = owner[this.expando]; // If not, create one if (!value) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if (acceptData(owner)) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if (owner.nodeType) { owner[this.expando] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty(owner, this.expando, { value: value, configurable: true }); } } } return value; }, set: function (owner, data, value) { var prop, cache = this.cache(owner); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if (typeof data === "string") { cache[camelCase(data)] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for (prop in data) { cache[camelCase(prop)] = data[prop]; } } return cache; }, get: function (owner, key) { return key === undefined ? this.cache(owner) : // Always use camelCase key (gh-2257) owner[this.expando] && owner[this.expando][camelCase(key)]; }, access: function (owner, key, value) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if (key === undefined || key && typeof key === "string" && value === undefined) { return this.get(owner, key); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set(owner, key, value); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }, remove: function (owner, key) { var i, cache = owner[this.expando]; if (cache === undefined) { return; } if (key !== undefined) { // Support array or space separated string of keys if (Array.isArray(key)) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map(camelCase); } else { key = camelCase(key); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [key] : key.match(rnothtmlwhite) || []; } i = key.length; while (i--) { delete cache[key[i]]; } } // Remove the expando if there's no more data if (key === undefined || jQuery.isEmptyObject(cache)) { // Support: Chrome <=35 - 45 // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if (owner.nodeType) { owner[this.expando] = undefined; } else { delete owner[this.expando]; } } }, hasData: function (owner) { var cache = owner[this.expando]; return cache !== undefined && !jQuery.isEmptyObject(cache); } }; var dataPriv = new Data(); var dataUser = new Data(); // Implementation Summary // // 1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage // paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; function getData(data) { if (data === "true") { return true; } if (data === "false") { return false; } if (data === "null") { return null; } // Only convert to a number if it doesn't change the string if (data === +data + "") { return +data; } if (rbrace.test(data)) { return JSON.parse(data); } return data; } function dataAttr(elem, key, data) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if (data === undefined && elem.nodeType === 1) { name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase(); data = elem.getAttribute(name); if (typeof data === "string") { try { data = getData(data); } catch (e) {} // Make sure we set the data so it isn't changed later dataUser.set(elem, key, data); } else { data = undefined; } } return data; } jQuery.extend({ hasData: function (elem) { return dataUser.hasData(elem) || dataPriv.hasData(elem); }, data: function (elem, name, data) { return dataUser.access(elem, name, data); }, removeData: function (elem, name) { dataUser.remove(elem, name); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function (elem, name, data) { return dataPriv.access(elem, name, data); }, _removeData: function (elem, name) { dataPriv.remove(elem, name); } }); jQuery.fn.extend({ data: function (key, value) { var i, name, data, elem = this[0], attrs = elem && elem.attributes; // Gets all values if (key === undefined) { if (this.length) { data = dataUser.get(elem); if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) { i = attrs.length; while (i--) { // Support: IE 11 only // The attrs elements can be null (#14894) if (attrs[i]) { name = attrs[i].name; if (name.indexOf("data-") === 0) { name = camelCase(name.slice(5)); dataAttr(elem, name, data[name]); } } } dataPriv.set(elem, "hasDataAttrs", true); } } return data; } // Sets multiple values if (typeof key === "object") { return this.each(function () { dataUser.set(this, key); }); } return access(this, function (value) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if (elem && value === undefined) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get(elem, key); if (data !== undefined) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs data = dataAttr(elem, key); if (data !== undefined) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each(function () { // We always store the camelCased key dataUser.set(this, key, value); }); }, null, value, arguments.length > 1, null, true); }, removeData: function (key) { return this.each(function () { dataUser.remove(this, key); }); } }); jQuery.extend({ queue: function (elem, type, data) { var queue; if (elem) { type = (type || "fx") + "queue"; queue = dataPriv.get(elem, type); // Speed up dequeue by getting out quickly if this is just a lookup if (data) { if (!queue || Array.isArray(data)) { queue = dataPriv.access(elem, type, jQuery.makeArray(data)); } else { queue.push(data); } } return queue || []; } }, dequeue: function (elem, type) { type = type || "fx"; var queue = jQuery.queue(elem, type), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks(elem, type), next = function () { jQuery.dequeue(elem, type); }; // If the fx queue is dequeued, always remove the progress sentinel if (fn === "inprogress") { fn = queue.shift(); startLength--; } if (fn) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if (type === "fx") { queue.unshift("inprogress"); } // Clear up the last queue stop function delete hooks.stop; fn.call(elem, next, hooks); } if (!startLength && hooks) { hooks.empty.fire(); } }, // Not public - generate a queueHooks object, or return the current one _queueHooks: function (elem, type) { var key = type + "queueHooks"; return dataPriv.get(elem, key) || dataPriv.access(elem, key, { empty: jQuery.Callbacks("once memory").add(function () { dataPriv.remove(elem, [type + "queue", key]); }) }); } }); jQuery.fn.extend({ queue: function (type, data) { var setter = 2; if (typeof type !== "string") { data = type; type = "fx"; setter--; } if (arguments.length < setter) { return jQuery.queue(this[0], type); } return data === undefined ? this : this.each(function () { var queue = jQuery.queue(this, type, data); // Ensure a hooks for this queue jQuery._queueHooks(this, type); if (type === "fx" && queue[0] !== "inprogress") { jQuery.dequeue(this, type); } }); }, dequeue: function (type) { return this.each(function () { jQuery.dequeue(this, type); }); }, clearQueue: function (type) { return this.queue(type || "fx", []); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function (type, obj) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function () { if (! --count) { defer.resolveWith(elements, [elements]); } }; if (typeof type !== "string") { obj = type; type = undefined; } type = type || "fx"; while (i--) { tmp = dataPriv.get(elements[i], type + "queueHooks"); if (tmp && tmp.empty) { count++; tmp.empty.add(resolve); } } resolve(); return defer.promise(obj); } }); var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"); var cssExpand = ["Top", "Right", "Bottom", "Left"]; var isHiddenWithinTree = function (elem, el) { // isHiddenWithinTree might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; // Inline style trumps all return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style // Support: Firefox <=43 - 45 // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. jQuery.contains(elem.ownerDocument, elem) && jQuery.css(elem, "display") === "none"; }; var swap = function (elem, options, callback, args) { var ret, name, old = {}; // Remember the old values, and insert the new ones for (name in options) { old[name] = elem.style[name]; elem.style[name] = options[name]; } ret = callback.apply(elem, args || []); // Revert the old values for (name in options) { elem.style[name] = old[name]; } return ret; }; function adjustCSS(elem, prop, valueParts, tween) { var adjusted, scale, maxIterations = 20, currentValue = tween ? function () { return tween.cur(); } : function () { return jQuery.css(elem, prop, ""); }, initial = currentValue(), unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"), // Starting value computation is required for potential unit mismatches initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop)); if (initialInUnit && initialInUnit[3] !== unit) { // Support: Firefox <=54 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) initial = initial / 2; // Trust units reported by jQuery.css unit = unit || initialInUnit[3]; // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; while (maxIterations--) { // Evaluate and update our best guess (doubling guesses that zero out). // Finish if the scale equals or crosses 1 (making the old*new product non-positive). jQuery.style(elem, prop, initialInUnit + unit); if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) { maxIterations = 0; } initialInUnit = initialInUnit / scale; } initialInUnit = initialInUnit * 2; jQuery.style(elem, prop, initialInUnit + unit); // Make sure we update the tween properties later on valueParts = valueParts || []; } if (valueParts) { initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2]; if (tween) { tween.unit = unit; tween.start = initialInUnit; tween.end = adjusted; } } return adjusted; } var defaultDisplayMap = {}; function getDefaultDisplay(elem) { var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[nodeName]; if (display) { return display; } temp = doc.body.appendChild(doc.createElement(nodeName)); display = jQuery.css(temp, "display"); temp.parentNode.removeChild(temp); if (display === "none") { display = "block"; } defaultDisplayMap[nodeName] = display; return display; } function showHide(elements, show) { var display, elem, values = [], index = 0, length = elements.length; // Determine new display value for elements that need to change for (; index < length; index++) { elem = elements[index]; if (!elem.style) { continue; } display = elem.style.display; if (show) { // Since we force visibility upon cascade-hidden elements, an immediate (and slow) // check is required in this first loop unless we have a nonempty display value (either // inline or about-to-be-restored) if (display === "none") { values[index] = dataPriv.get(elem, "display") || null; if (!values[index]) { elem.style.display = ""; } } if (elem.style.display === "" && isHiddenWithinTree(elem)) { values[index] = getDefaultDisplay(elem); } } else { if (display !== "none") { values[index] = "none"; // Remember what we're overwriting dataPriv.set(elem, "display", display); } } } // Set the display of the elements in a second loop to avoid constant reflow for (index = 0; index < length; index++) { if (values[index] != null) { elements[index].style.display = values[index]; } } return elements; } jQuery.fn.extend({ show: function () { return showHide(this, true); }, hide: function () { return showHide(this); }, toggle: function (state) { if (typeof state === "boolean") { return state ? this.show() : this.hide(); } return this.each(function () { if (isHiddenWithinTree(this)) { jQuery(this).show(); } else { jQuery(this).hide(); } }); } }); var rcheckableType = /^(?:checkbox|radio)$/i; var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i; var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; // We have to close these tags to support XHTML (#13200) var wrapMap = { // Support: IE <=9 only option: [1, ""], // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten // this by omitting or other required elements. thead: [1, "", "
"], col: [2, "", "
"], tr: [2, "", "
"], td: [3, "", "
"], _default: [0, "", ""] }; // Support: IE <=9 only wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; function getAll(context, tag) { // Support: IE <=9 - 11 only // Use typeof to avoid zero-argument method invocation on host objects (#15151) var ret; if (typeof context.getElementsByTagName !== "undefined") { ret = context.getElementsByTagName(tag || "*"); } else if (typeof context.querySelectorAll !== "undefined") { ret = context.querySelectorAll(tag || "*"); } else { ret = []; } if (tag === undefined || tag && nodeName(context, tag)) { return jQuery.merge([context], ret); } return ret; } // Mark scripts as having already been evaluated function setGlobalEval(elems, refElements) { var i = 0, l = elems.length; for (; i < l; i++) { dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval")); } } var rhtml = /<|&#?\w+;/; function buildFragment(elems, context, scripts, selection, ignored) { var elem, tmp, tag, wrap, contains, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; for (; i < l; i++) { elem = elems[i]; if (elem || elem === 0) { // Add nodes directly if (toType(elem) === "object") { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge(nodes, elem.nodeType ? [elem] : elem); // Convert non-html into a text node } else if (!rhtml.test(elem)) { nodes.push(context.createTextNode(elem)); // Convert html into DOM nodes } else { tmp = tmp || fragment.appendChild(context.createElement("div")); // Deserialize a standard representation tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase(); wrap = wrapMap[tag] || wrapMap._default; tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; // Descend through wrappers to the right content j = wrap[0]; while (j--) { tmp = tmp.lastChild; } // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge(nodes, tmp.childNodes); // Remember the top-level container tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392) tmp.textContent = ""; } } } // Remove wrapper from fragment fragment.textContent = ""; i = 0; while (elem = nodes[i++]) { // Skip elements already in the context collection (trac-4087) if (selection && jQuery.inArray(elem, selection) > -1) { if (ignored) { ignored.push(elem); } continue; } contains = jQuery.contains(elem.ownerDocument, elem); // Append to fragment tmp = getAll(fragment.appendChild(elem), "script"); // Preserve script evaluation history if (contains) { setGlobalEval(tmp); } // Capture executables if (scripts) { j = 0; while (elem = tmp[j++]) { if (rscriptType.test(elem.type || "")) { scripts.push(elem); } } } } return fragment; } (function () { var fragment = document.createDocumentFragment(), div = fragment.appendChild(document.createElement("div")), input = document.createElement("input"); // Support: Android 4.0 - 4.3 only // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) input.setAttribute("type", "radio"); input.setAttribute("checked", "checked"); input.setAttribute("name", "t"); div.appendChild(input); // Support: Android <=4.1 only // Older WebKit doesn't clone checked state correctly in fragments support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; // Support: IE <=11 only // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = ""; support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; })(); var documentElement = document.documentElement; var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } // Support: IE <=9 only // See #13393 for more info function safeActiveElement() { try { return document.activeElement; } catch (err) {} } function on(elem, types, selector, data, fn, one) { var origFn, type; // Types can be a map of types/handlers if (typeof types === "object") { // ( types-Object, selector, data ) if (typeof selector !== "string") { // ( types-Object, data ) data = data || selector; selector = undefined; } for (type in types) { on(elem, type, selector, data, types[type], one); } return elem; } if (data == null && fn == null) { // ( types, fn ) fn = selector; data = selector = undefined; } else if (fn == null) { if (typeof selector === "string") { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if (fn === false) { fn = returnFalse; } else if (!fn) { return elem; } if (one === 1) { origFn = fn; fn = function (event) { // Can use an empty set, since event contains the info jQuery().off(event); return origFn.apply(this, arguments); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); } return elem.each(function () { jQuery.event.add(this, types, fn, data, selector); }); } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function (elem, types, handler, data, selector) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get(elem); // Don't attach events to noData or text/comment nodes (but allow plain objects) if (!elemData) { return; } // Caller can pass in an object of custom data in lieu of the handler if (handler.handler) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Ensure that invalid selectors throw exceptions at attach time // Evaluate against documentElement in case elem is a non-element node (e.g., document) if (selector) { jQuery.find.matchesSelector(documentElement, selector); } // Make sure that the handler has a unique ID, used to find/remove it later if (!handler.guid) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if (!(events = elemData.events)) { events = elemData.events = {}; } if (!(eventHandle = elemData.handle)) { eventHandle = elemData.handle = function (e) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined; }; } // Handle multiple events separated by a space types = (types || "").match(rnothtmlwhite) || [""]; t = types.length; while (t--) { tmp = rtypenamespace.exec(types[t]) || []; type = origType = tmp[1]; namespaces = (tmp[2] || "").split(".").sort(); // There *must* be a type, no attaching namespace-only handlers if (!type) { continue; } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[type] || {}; // If selector defined, determine special event api type, otherwise given type type = (selector ? special.delegateType : special.bindType) || type; // Update special based on newly reset type special = jQuery.event.special[type] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend({ type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test(selector), namespace: namespaces.join(".") }, handleObjIn); // Init the event handler queue if we're the first if (!(handlers = events[type])) { handlers = events[type] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) { if (elem.addEventListener) { elem.addEventListener(type, eventHandle); } } } if (special.add) { special.add.call(elem, handleObj); if (!handleObj.handler.guid) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if (selector) { handlers.splice(handlers.delegateCount++, 0, handleObj); } else { handlers.push(handleObj); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[type] = true; } }, // Detach an event or set of events from an element remove: function (elem, types, handler, selector, mappedTypes) { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData(elem) && dataPriv.get(elem); if (!elemData || !(events = elemData.events)) { return; } // Once for each type.namespace in types; type may be omitted types = (types || "").match(rnothtmlwhite) || [""]; t = types.length; while (t--) { tmp = rtypenamespace.exec(types[t]) || []; type = origType = tmp[1]; namespaces = (tmp[2] || "").split(".").sort(); // Unbind all events (on this namespace, if provided) for the element if (!type) { for (type in events) { jQuery.event.remove(elem, type + types[t], handler, selector, true); } continue; } special = jQuery.event.special[type] || {}; type = (selector ? special.delegateType : special.bindType) || type; handlers = events[type] || []; tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); // Remove matching events origCount = j = handlers.length; while (j--) { handleObj = handlers[j]; if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) { handlers.splice(j, 1); if (handleObj.selector) { handlers.delegateCount--; } if (special.remove) { special.remove.call(elem, handleObj); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if (origCount && !handlers.length) { if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) { jQuery.removeEvent(elem, type, elemData.handle); } delete events[type]; } } // Remove data and the expando if it's no longer used if (jQuery.isEmptyObject(events)) { dataPriv.remove(elem, "handle events"); } }, dispatch: function (nativeEvent) { // Make a writable jQuery.Event from the native event object var event = jQuery.event.fix(nativeEvent); var i, j, ret, matched, handleObj, handlerQueue, args = new Array(arguments.length), handlers = (dataPriv.get(this, "events") || {})[event.type] || [], special = jQuery.event.special[event.type] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event; for (i = 1; i < arguments.length; i++) { args[i] = arguments[i]; } event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if (special.preDispatch && special.preDispatch.call(this, event) === false) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call(this, event, handlers); // Run delegates first; they may want to stop propagation beneath us i = 0; while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { event.currentTarget = matched.elem; j = 0; while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) { // Triggered event must either 1) have no namespace, or 2) have namespace(s) // a subset or equal to those in the bound event (both can have no namespace). if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) { event.handleObj = handleObj; event.data = handleObj.data; ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args); if (ret !== undefined) { if ((event.result = ret) === false) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if (special.postDispatch) { special.postDispatch.call(this, event); } return event.result; }, handlers: function (event, handlers) { var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers if (delegateCount && // Support: IE <=9 // Black-hole SVG instance trees (trac-13180) cur.nodeType && // Support: Firefox <=42 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11 only // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) !(event.type === "click" && event.button >= 1)) { for (; cur !== this; cur = cur.parentNode || this) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) { matchedHandlers = []; matchedSelectors = {}; for (i = 0; i < delegateCount; i++) { handleObj = handlers[i]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if (matchedSelectors[sel] === undefined) { matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length; } if (matchedSelectors[sel]) { matchedHandlers.push(handleObj); } } if (matchedHandlers.length) { handlerQueue.push({ elem: cur, handlers: matchedHandlers }); } } } } // Add the remaining (directly-bound) handlers cur = this; if (delegateCount < handlers.length) { handlerQueue.push({ elem: cur, handlers: handlers.slice(delegateCount) }); } return handlerQueue; }, addProp: function (name, hook) { Object.defineProperty(jQuery.Event.prototype, name, { enumerable: true, configurable: true, get: isFunction(hook) ? function () { if (this.originalEvent) { return hook(this.originalEvent); } } : function () { if (this.originalEvent) { return this.originalEvent[name]; } }, set: function (value) { Object.defineProperty(this, name, { enumerable: true, configurable: true, writable: true, value: value }); } }); }, fix: function (originalEvent) { return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent); }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function () { if (this !== safeActiveElement() && this.focus) { this.focus(); return false; } }, delegateType: "focusin" }, blur: { trigger: function () { if (this === safeActiveElement() && this.blur) { this.blur(); return false; } }, delegateType: "focusout" }, click: { // For checkbox, fire native event so checked state will be right trigger: function () { if (this.type === "checkbox" && this.click && nodeName(this, "input")) { this.click(); return false; } }, // For cross-browser consistency, don't fire native .click() on links _default: function (event) { return nodeName(event.target, "a"); } }, beforeunload: { postDispatch: function (event) { // Support: Firefox 20+ // Firefox doesn't alert if the returnValue field is not set. if (event.result !== undefined && event.originalEvent) { event.originalEvent.returnValue = event.result; } } } } }; jQuery.removeEvent = function (elem, type, handle) { // This "if" is needed for plain objects if (elem.removeEventListener) { elem.removeEventListener(type, handle); } }; jQuery.Event = function (src, props) { // Allow instantiation without the 'new' keyword if (!(this instanceof jQuery.Event)) { return new jQuery.Event(src, props); } // Event object if (src && src.type) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only src.returnValue === false ? returnTrue : returnFalse; // Create target properties // Support: Safari <=6 - 7 only // Target should not be a text node (#504, #13143) this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if (props) { jQuery.extend(this, props); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed this[jQuery.expando] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, isSimulated: false, preventDefault: function () { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if (e && !this.isSimulated) { e.preventDefault(); } }, stopPropagation: function () { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if (e && !this.isSimulated) { e.stopPropagation(); } }, stopImmediatePropagation: function () { var e = this.originalEvent; this.isImmediatePropagationStopped = returnTrue; if (e && !this.isSimulated) { e.stopImmediatePropagation(); } this.stopPropagation(); } }; // Includes all common event props including KeyEvent and MouseEvent specific props jQuery.each({ altKey: true, bubbles: true, cancelable: true, changedTouches: true, ctrlKey: true, detail: true, eventPhase: true, metaKey: true, pageX: true, pageY: true, shiftKey: true, view: true, "char": true, charCode: true, key: true, keyCode: true, button: true, buttons: true, clientX: true, clientY: true, offsetX: true, offsetY: true, pointerId: true, pointerType: true, screenX: true, screenY: true, targetTouches: true, toElement: true, touches: true, which: function (event) { var button = event.button; // Add which for key events if (event.which == null && rkeyEvent.test(event.type)) { return event.charCode != null ? event.charCode : event.keyCode; } // Add which for click: 1 === left; 2 === middle; 3 === right if (!event.which && button !== undefined && rmouseEvent.test(event.type)) { if (button & 1) { return 1; } if (button & 2) { return 3; } if (button & 4) { return 2; } return 0; } return event.which; } }, jQuery.event.addProp); // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout // // Support: Safari 7 only // Safari sends mouseenter too often; see: // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 // for the description of the bug (it existed in older Chrome versions as well). jQuery.each({ mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function (orig, fix) { jQuery.event.special[orig] = { delegateType: fix, bindType: fix, handle: function (event) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if (!related || related !== target && !jQuery.contains(target, related)) { event.type = handleObj.origType; ret = handleObj.handler.apply(this, arguments); event.type = fix; } return ret; } }; }); jQuery.fn.extend({ on: function (types, selector, data, fn) { return on(this, types, selector, data, fn); }, one: function (types, selector, data, fn) { return on(this, types, selector, data, fn, 1); }, off: function (types, selector, fn) { var handleObj, type; if (types && types.preventDefault && types.handleObj) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler); return this; } if (typeof types === "object") { // ( types-object [, selector] ) for (type in types) { this.off(type, selector, types[type]); } return this; } if (selector === false || typeof selector === "function") { // ( types [, fn] ) fn = selector; selector = undefined; } if (fn === false) { fn = returnFalse; } return this.each(function () { jQuery.event.remove(this, types, fn, selector); }); } }); var /* eslint-disable max-len */ // See https://github.com/eslint/eslint/issues/3229 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, /* eslint-enable */ // Support: IE <=10 - 11, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /\s*$/g; // Prefer a tbody over its parent table for containing new rows function manipulationTarget(elem, content) { if (nodeName(elem, "table") && nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) { return jQuery(elem).children("tbody")[0] || elem; } return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript(elem) { elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; return elem; } function restoreScript(elem) { if ((elem.type || "").slice(0, 5) === "true/") { elem.type = elem.type.slice(5); } else { elem.removeAttribute("type"); } return elem; } function cloneCopyEvent(src, dest) { var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; if (dest.nodeType !== 1) { return; } // 1. Copy private data: events, handlers, etc. if (dataPriv.hasData(src)) { pdataOld = dataPriv.access(src); pdataCur = dataPriv.set(dest, pdataOld); events = pdataOld.events; if (events) { delete pdataCur.handle; pdataCur.events = {}; for (type in events) { for (i = 0, l = events[type].length; i < l; i++) { jQuery.event.add(dest, type, events[type][i]); } } } } // 2. Copy user data if (dataUser.hasData(src)) { udataOld = dataUser.access(src); udataCur = jQuery.extend({}, udataOld); dataUser.set(dest, udataCur); } } // Fix IE bugs, see support tests function fixInput(src, dest) { var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button. if (nodeName === "input" && rcheckableType.test(src.type)) { dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options } else if (nodeName === "input" || nodeName === "textarea") { dest.defaultValue = src.defaultValue; } } function domManip(collection, args, callback, ignored) { // Flatten any nested arrays args = concat.apply([], args); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[0], valueIsFunction = isFunction(value); // We can't cloneNode fragments that contain checked, in WebKit if (valueIsFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) { return collection.each(function (index) { var self = collection.eq(index); if (valueIsFunction) { args[0] = value.call(this, index, self.html()); } domManip(self, args, callback, ignored); }); } if (l) { fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); first = fragment.firstChild; if (fragment.childNodes.length === 1) { fragment = first; } // Require either new content or an interest in ignored elements to invoke the callback if (first || ignored) { scripts = jQuery.map(getAll(fragment, "script"), disableScript); hasScripts = scripts.length; // Use the original fragment for the last item // instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for (; i < l; i++) { node = fragment; if (i !== iNoClone) { node = jQuery.clone(node, true, true); // Keep references to cloned scripts for later restoration if (hasScripts) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge(scripts, getAll(node, "script")); } } callback.call(collection[i], node, i); } if (hasScripts) { doc = scripts[scripts.length - 1].ownerDocument; // Reenable scripts jQuery.map(scripts, restoreScript); // Evaluate executable scripts on first document insertion for (i = 0; i < hasScripts; i++) { node = scripts[i]; if (rscriptType.test(node.type || "") && !dataPriv.access(node, "globalEval") && jQuery.contains(doc, node)) { if (node.src && (node.type || "").toLowerCase() !== "module") { // Optional AJAX dependency, but won't run scripts if not present if (jQuery._evalUrl) { jQuery._evalUrl(node.src); } } else { DOMEval(node.textContent.replace(rcleanScript, ""), doc, node); } } } } } } return collection; } function remove(elem, selector, keepData) { var node, nodes = selector ? jQuery.filter(selector, elem) : elem, i = 0; for (; (node = nodes[i]) != null; i++) { if (!keepData && node.nodeType === 1) { jQuery.cleanData(getAll(node)); } if (node.parentNode) { if (keepData && jQuery.contains(node.ownerDocument, node)) { setGlobalEval(getAll(node, "script")); } node.parentNode.removeChild(node); } } return elem; } jQuery.extend({ htmlPrefilter: function (html) { return html.replace(rxhtmlTag, "<$1>"); }, clone: function (elem, dataAndEvents, deepDataAndEvents) { var i, l, srcElements, destElements, clone = elem.cloneNode(true), inPage = jQuery.contains(elem.ownerDocument, elem); // Fix IE cloning issues if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) { // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll(clone); srcElements = getAll(elem); for (i = 0, l = srcElements.length; i < l; i++) { fixInput(srcElements[i], destElements[i]); } } // Copy the events from the original to the clone if (dataAndEvents) { if (deepDataAndEvents) { srcElements = srcElements || getAll(elem); destElements = destElements || getAll(clone); for (i = 0, l = srcElements.length; i < l; i++) { cloneCopyEvent(srcElements[i], destElements[i]); } } else { cloneCopyEvent(elem, clone); } } // Preserve script evaluation history destElements = getAll(clone, "script"); if (destElements.length > 0) { setGlobalEval(destElements, !inPage && getAll(elem, "script")); } // Return the cloned set return clone; }, cleanData: function (elems) { var data, elem, type, special = jQuery.event.special, i = 0; for (; (elem = elems[i]) !== undefined; i++) { if (acceptData(elem)) { if (data = elem[dataPriv.expando]) { if (data.events) { for (type in data.events) { if (special[type]) { jQuery.event.remove(elem, type); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent(elem, type, data.handle); } } } // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[dataPriv.expando] = undefined; } if (elem[dataUser.expando]) { // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[dataUser.expando] = undefined; } } } } }); jQuery.fn.extend({ detach: function (selector) { return remove(this, selector, true); }, remove: function (selector) { return remove(this, selector); }, text: function (value) { return access(this, function (value) { return value === undefined ? jQuery.text(this) : this.empty().each(function () { if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { this.textContent = value; } }); }, null, value, arguments.length); }, append: function () { return domManip(this, arguments, function (elem) { if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { var target = manipulationTarget(this, elem); target.appendChild(elem); } }); }, prepend: function () { return domManip(this, arguments, function (elem) { if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { var target = manipulationTarget(this, elem); target.insertBefore(elem, target.firstChild); } }); }, before: function () { return domManip(this, arguments, function (elem) { if (this.parentNode) { this.parentNode.insertBefore(elem, this); } }); }, after: function () { return domManip(this, arguments, function (elem) { if (this.parentNode) { this.parentNode.insertBefore(elem, this.nextSibling); } }); }, empty: function () { var elem, i = 0; for (; (elem = this[i]) != null; i++) { if (elem.nodeType === 1) { // Prevent memory leaks jQuery.cleanData(getAll(elem, false)); // Remove any remaining nodes elem.textContent = ""; } } return this; }, clone: function (dataAndEvents, deepDataAndEvents) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map(function () { return jQuery.clone(this, dataAndEvents, deepDataAndEvents); }); }, html: function (value) { return access(this, function (value) { var elem = this[0] || {}, i = 0, l = this.length; if (value === undefined && elem.nodeType === 1) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) { value = jQuery.htmlPrefilter(value); try { for (; i < l; i++) { elem = this[i] || {}; // Remove element nodes and prevent memory leaks if (elem.nodeType === 1) { jQuery.cleanData(getAll(elem, false)); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch (e) {} } if (elem) { this.empty().append(value); } }, null, value, arguments.length); }, replaceWith: function () { var ignored = []; // Make the changes, replacing each non-ignored context element with the new content return domManip(this, arguments, function (elem) { var parent = this.parentNode; if (jQuery.inArray(this, ignored) < 0) { jQuery.cleanData(getAll(this)); if (parent) { parent.replaceChild(elem, this); } } // Force callback invocation }, ignored); } }); jQuery.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function (name, original) { jQuery.fn[name] = function (selector) { var elems, ret = [], insert = jQuery(selector), last = insert.length - 1, i = 0; for (; i <= last; i++) { elems = i === last ? this : this.clone(true); jQuery(insert[i])[original](elems); // Support: Android <=4.0 only, PhantomJS 1 only // .get() because push.apply(_, arraylike) throws on ancient WebKit push.apply(ret, elems.get()); } return this.pushStack(ret); }; }); var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i"); var getStyles = function (elem) { // Support: IE <=11 only, Firefox <=30 (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" var view = elem.ownerDocument.defaultView; if (!view || !view.opener) { view = window; } return view.getComputedStyle(elem); }; var rboxStyle = new RegExp(cssExpand.join("|"), "i"); (function () { // Executing both pixelPosition & boxSizingReliable tests require only one layout // so they're executed at the same time to save the second computation. function computeStyleTests() { // This is a singleton, we need to execute it only once if (!div) { return; } container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0"; div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%"; documentElement.appendChild(container).appendChild(div); var divStyle = window.getComputedStyle(div); pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 // Some styles come back with percentage values, even though they shouldn't div.style.right = "60%"; pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; // Support: IE 9 - 11 only // Detect misreporting of content dimensions for box-sizing:border-box elements boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; // Support: IE 9 only // Detect overflow:scroll screwiness (gh-3699) div.style.position = "absolute"; scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; documentElement.removeChild(container); // Nullify the div so it wouldn't be stored in the memory and // it will also be a sign that checks already performed div = null; } function roundPixelMeasures(measure) { return Math.round(parseFloat(measure)); } var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableMarginLeftVal, container = document.createElement("div"), div = document.createElement("div"); // Finish early in limited (non-browser) environments if (!div.style) { return; } // Support: IE <=9 - 11 only // Style of cloned element affects source element cloned (#8908) div.style.backgroundClip = "content-box"; div.cloneNode(true).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; jQuery.extend(support, { boxSizingReliable: function () { computeStyleTests(); return boxSizingReliableVal; }, pixelBoxStyles: function () { computeStyleTests(); return pixelBoxStylesVal; }, pixelPosition: function () { computeStyleTests(); return pixelPositionVal; }, reliableMarginLeft: function () { computeStyleTests(); return reliableMarginLeftVal; }, scrollboxSize: function () { computeStyleTests(); return scrollboxSizeVal; } }); })(); function curCSS(elem, name, computed) { var width, minWidth, maxWidth, ret, // Support: Firefox 51+ // Retrieving style before computed somehow // fixes an issue with getting wrong values // on detached elements style = elem.style; computed = computed || getStyles(elem); // getPropertyValue is needed for: // .css('filter') (IE 9 only, #12537) // .css('--customProperty) (#3144) if (computed) { ret = computed.getPropertyValue(name) || computed[name]; if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) { ret = jQuery.style(elem, name); } // A tribute to the "awesome hack by Dean Edwards" // Android Browser returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret !== undefined ? // Support: IE <=9 - 11 only // IE returns zIndex value as an integer. ret + "" : ret; } function addGetHookIf(conditionFn, hookFn) { // Define the hook, we'll check on the first run if it's really needed. return { get: function () { if (conditionFn()) { // Hook not needed (or it's not possible to use it due // to missing dependency), remove it. delete this.get; return; } // Hook needed; redefine it so that the support test is not executed again. return (this.get = hookFn).apply(this, arguments); } }; } var // Swappable if display is none or starts with table // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" }, cssPrefixes = ["Webkit", "Moz", "ms"], emptyStyle = document.createElement("div").style; // Return a css property mapped to a potentially vendor prefixed property function vendorPropName(name) { // Shortcut for names that are not vendor prefixed if (name in emptyStyle) { return name; } // Check for vendor prefixed names var capName = name[0].toUpperCase() + name.slice(1), i = cssPrefixes.length; while (i--) { name = cssPrefixes[i] + capName; if (name in emptyStyle) { return name; } } } // Return a property mapped along what jQuery.cssProps suggests or to // a vendor prefixed property. function finalPropName(name) { var ret = jQuery.cssProps[name]; if (!ret) { ret = jQuery.cssProps[name] = vendorPropName(name) || name; } return ret; } function setPositiveNumber(elem, value, subtract) { // Any relative (+/-) values have already been // normalized at this point var matches = rcssNum.exec(value); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : value; } function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) { var i = dimension === "width" ? 1 : 0, extra = 0, delta = 0; // Adjustment may not be necessary if (box === (isBorderBox ? "border" : "content")) { return 0; } for (; i < 4; i += 2) { // Both box models exclude margin if (box === "margin") { delta += jQuery.css(elem, box + cssExpand[i], true, styles); } // If we get here with a content-box, we're seeking "padding" or "border" or "margin" if (!isBorderBox) { // Add padding delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles); // For "border" or "margin", add border if (box !== "padding") { delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); // But still keep track of it otherwise } else { extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); } // If we get here with a border-box (content + padding + border), we're seeking "content" or // "padding" or "margin" } else { // For "content", subtract padding if (box === "content") { delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles); } // For "content" or "padding", subtract border if (box !== "margin") { delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); } } } // Account for positive content-box scroll gutter when requested by providing computedVal if (!isBorderBox && computedVal >= 0) { // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border // Assuming integer scroll gutter, subtract the rest and round down delta += Math.max(0, Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - computedVal - delta - extra - 0.5)); } return delta; } function getWidthOrHeight(elem, dimension, extra) { // Start with computed style var styles = getStyles(elem), val = curCSS(elem, dimension, styles), isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", valueIsBorderBox = isBorderBox; // Support: Firefox <=54 // Return a confounding non-pixel value or feign ignorance, as appropriate. if (rnumnonpx.test(val)) { if (!extra) { return val; } val = "auto"; } // Check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = valueIsBorderBox && (support.boxSizingReliable() || val === elem.style[dimension]); // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) // Support: Android <=4.1 - 4.3 only // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) if (val === "auto" || !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") { val = elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)]; // offsetWidth/offsetHeight provide border-box values valueIsBorderBox = true; } // Normalize "" and auto val = parseFloat(val) || 0; // Adjust for the element's box model return val + boxModelAdjustment(elem, dimension, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589) val) + "px"; } jQuery.extend({ // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function (elem, computed) { if (computed) { // We should always get a number back from opacity var ret = curCSS(elem, "opacity"); return ret === "" ? "1" : ret; } } } }, // Don't automatically add "px" to these possibly-unitless properties cssNumber: { "animationIterationCount": true, "columnCount": true, "fillOpacity": true, "flexGrow": true, "flexShrink": true, "fontWeight": true, "lineHeight": true, "opacity": true, "order": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: {}, // Get and set the style property on a DOM Node style: function (elem, name, value, extra) { // Don't set styles on text and comment nodes if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = camelCase(name), isCustomProp = rcustomProp.test(name), style = elem.style; // Make sure that we're working with the right name. We don't // want to query the value if it is a CSS custom property // since they are user-defined. if (!isCustomProp) { name = finalPropName(origName); } // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; // Check if we're setting a value if (value !== undefined) { type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345) if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) { value = adjustCSS(elem, name, ret); // Fixes bug #9237 type = "number"; } // Make sure that null and NaN values aren't set (#7116) if (value == null || value !== value) { return; } // If a number was passed in, add the unit (except for certain CSS properties) if (type === "number") { value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px"); } // background-* props affect original clone's values if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) { style[name] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) { if (isCustomProp) { style.setProperty(name, value); } else { style[name] = value; } } } else { // If a hook was provided get the non-computed value from there if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) { return ret; } // Otherwise just get the value from the style object return style[name]; } }, css: function (elem, name, extra, styles) { var val, num, hooks, origName = camelCase(name), isCustomProp = rcustomProp.test(name); // Make sure that we're working with the right name. We don't // want to modify the value if it is a CSS custom property // since they are user-defined. if (!isCustomProp) { name = finalPropName(origName); } // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; // If a hook was provided get the computed value from there if (hooks && "get" in hooks) { val = hooks.get(elem, true, extra); } // Otherwise, if a way to get the computed value exists, use that if (val === undefined) { val = curCSS(elem, name, styles); } // Convert "normal" to computed value if (val === "normal" && name in cssNormalTransform) { val = cssNormalTransform[name]; } // Make numeric if forced or a qualifier was provided and val looks numeric if (extra === "" || extra) { num = parseFloat(val); return extra === true || isFinite(num) ? num || 0 : val; } return val; } }); jQuery.each(["height", "width"], function (i, dimension) { jQuery.cssHooks[dimension] = { get: function (elem, computed, extra) { if (computed) { // Certain elements can have dimension info if we invisibly show them // but it must have a current display style that would benefit return rdisplayswap.test(jQuery.css(elem, "display")) && ( // Support: Safari 8+ // Table columns in Safari have non-zero offsetWidth & zero // getBoundingClientRect().width unless display is changed. // Support: IE <=11 only // Running getBoundingClientRect on a disconnected node // in IE throws an error. !elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () { return getWidthOrHeight(elem, dimension, extra); }) : getWidthOrHeight(elem, dimension, extra); } }, set: function (elem, value, extra) { var matches, styles = getStyles(elem), isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", subtract = extra && boxModelAdjustment(elem, dimension, extra, isBorderBox, styles); // Account for unreliable border-box dimensions by comparing offset* to computed and // faking a content-box to get border and padding (gh-3699) if (isBorderBox && support.scrollboxSize() === styles.position) { subtract -= Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - parseFloat(styles[dimension]) - boxModelAdjustment(elem, dimension, "border", false, styles) - 0.5); } // Convert to pixels if value adjustment is needed if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || "px") !== "px") { elem.style[dimension] = value; value = jQuery.css(elem, dimension); } return setPositiveNumber(elem, value, subtract); } }; }); jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) { if (computed) { return (parseFloat(curCSS(elem, "marginLeft")) || elem.getBoundingClientRect().left - swap(elem, { marginLeft: 0 }, function () { return elem.getBoundingClientRect().left; })) + "px"; } }); // These hooks are used by animate to expand properties jQuery.each({ margin: "", padding: "", border: "Width" }, function (prefix, suffix) { jQuery.cssHooks[prefix + suffix] = { expand: function (value) { var i = 0, expanded = {}, // Assumes a single number if not a string parts = typeof value === "string" ? value.split(" ") : [value]; for (; i < 4; i++) { expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0]; } return expanded; } }; if (prefix !== "margin") { jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; } }); jQuery.fn.extend({ css: function (name, value) { return access(this, function (elem, name, value) { var styles, len, map = {}, i = 0; if (Array.isArray(name)) { styles = getStyles(elem); len = name.length; for (; i < len; i++) { map[name[i]] = jQuery.css(elem, name[i], false, styles); } return map; } return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name); }, name, value, arguments.length > 1); } }); function Tween(elem, options, prop, end, easing) { return new Tween.prototype.init(elem, options, prop, end, easing); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function (elem, options, prop, end, easing, unit) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px"); }, cur: function () { var hooks = Tween.propHooks[this.prop]; return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this); }, run: function (percent) { var eased, hooks = Tween.propHooks[this.prop]; if (this.options.duration) { this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration); } else { this.pos = eased = percent; } this.now = (this.end - this.start) * eased + this.start; if (this.options.step) { this.options.step.call(this.elem, this.now, this); } if (hooks && hooks.set) { hooks.set(this); } else { Tween.propHooks._default.set(this); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function (tween) { var result; // Use a property on the element directly when it is not a DOM element, // or when there is no matching style property that exists. if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) { return tween.elem[tween.prop]; } // Passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails. // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css(tween.elem, tween.prop, ""); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function (tween) { // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if (jQuery.fx.step[tween.prop]) { jQuery.fx.step[tween.prop](tween); } else if (tween.elem.nodeType === 1 && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) { jQuery.style(tween.elem, tween.prop, tween.now + tween.unit); } else { tween.elem[tween.prop] = tween.now; } } } }; // Support: IE <=9 only // Panic based approach to setting things on disconnected nodes Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function (tween) { if (tween.elem.nodeType && tween.elem.parentNode) { tween.elem[tween.prop] = tween.now; } } }; jQuery.easing = { linear: function (p) { return p; }, swing: function (p) { return 0.5 - Math.cos(p * Math.PI) / 2; }, _default: "swing" }; jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point jQuery.fx.step = {}; var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; function schedule() { if (inProgress) { if (document.hidden === false && window.requestAnimationFrame) { window.requestAnimationFrame(schedule); } else { window.setTimeout(schedule, jQuery.fx.interval); } jQuery.fx.tick(); } } // Animations created synchronously will run synchronously function createFxNow() { window.setTimeout(function () { fxNow = undefined; }); return fxNow = Date.now(); } // Generate parameters to create a standard animation function genFx(type, includeWidth) { var which, i = 0, attrs = { height: type }; // If we include width, step value is 1 to do all cssExpand values, // otherwise step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for (; i < 4; i += 2 - includeWidth) { which = cssExpand[i]; attrs["margin" + which] = attrs["padding" + which] = type; } if (includeWidth) { attrs.opacity = attrs.width = type; } return attrs; } function createTween(value, prop, animation) { var tween, collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]), index = 0, length = collection.length; for (; index < length; index++) { if (tween = collection[index].call(animation, prop, value)) { // We're done with this property return tween; } } } function defaultPrefilter(elem, props, opts) { var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = "width" in props || "height" in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree(elem), dataShow = dataPriv.get(elem, "fxshow"); // Queue-skipping animations hijack the fx hooks if (!opts.queue) { hooks = jQuery._queueHooks(elem, "fx"); if (hooks.unqueued == null) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function () { if (!hooks.unqueued) { oldfire(); } }; } hooks.unqueued++; anim.always(function () { // Ensure the complete handler is called before this completes anim.always(function () { hooks.unqueued--; if (!jQuery.queue(elem, "fx").length) { hooks.empty.fire(); } }); }); } // Detect show/hide animations for (prop in props) { value = props[prop]; if (rfxtypes.test(value)) { delete props[prop]; toggle = toggle || value === "toggle"; if (value === (hidden ? "hide" : "show")) { // Pretend to be hidden if this is a "show" and // there is still data from a stopped show/hide if (value === "show" && dataShow && dataShow[prop] !== undefined) { hidden = true; // Ignore all other no-op show/hide data } else { continue; } } orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop); } } // Bail out if this is a no-op like .hide().hide() propTween = !jQuery.isEmptyObject(props); if (!propTween && jQuery.isEmptyObject(orig)) { return; } // Restrict "overflow" and "display" styles during box animations if (isBox && elem.nodeType === 1) { // Support: IE <=9 - 11, Edge 12 - 15 // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY and Edge just mirrors // the overflowX value there. opts.overflow = [style.overflow, style.overflowX, style.overflowY]; // Identify a display type, preferring old show/hide data over the CSS cascade restoreDisplay = dataShow && dataShow.display; if (restoreDisplay == null) { restoreDisplay = dataPriv.get(elem, "display"); } display = jQuery.css(elem, "display"); if (display === "none") { if (restoreDisplay) { display = restoreDisplay; } else { // Get nonempty value(s) by temporarily forcing visibility showHide([elem], true); restoreDisplay = elem.style.display || restoreDisplay; display = jQuery.css(elem, "display"); showHide([elem]); } } // Animate inline elements as inline-block if (display === "inline" || display === "inline-block" && restoreDisplay != null) { if (jQuery.css(elem, "float") === "none") { // Restore the original display value at the end of pure show/hide animations if (!propTween) { anim.done(function () { style.display = restoreDisplay; }); if (restoreDisplay == null) { display = style.display; restoreDisplay = display === "none" ? "" : display; } } style.display = "inline-block"; } } } if (opts.overflow) { style.overflow = "hidden"; anim.always(function () { style.overflow = opts.overflow[0]; style.overflowX = opts.overflow[1]; style.overflowY = opts.overflow[2]; }); } // Implement show/hide animations propTween = false; for (prop in orig) { // General show/hide setup for this element animation if (!propTween) { if (dataShow) { if ("hidden" in dataShow) { hidden = dataShow.hidden; } } else { dataShow = dataPriv.access(elem, "fxshow", { display: restoreDisplay }); } // Store hidden/visible for toggle so `.stop().toggle()` "reverses" if (toggle) { dataShow.hidden = !hidden; } // Show elements before animating them if (hidden) { showHide([elem], true); } /* eslint-disable no-loop-func */ anim.done(function () { /* eslint-enable no-loop-func */ // The final step of a "hide" animation is actually hiding the element if (!hidden) { showHide([elem]); } dataPriv.remove(elem, "fxshow"); for (prop in orig) { jQuery.style(elem, prop, orig[prop]); } }); } // Per-property setup propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim); if (!(prop in dataShow)) { dataShow[prop] = propTween.start; if (hidden) { propTween.end = propTween.start; propTween.start = 0; } } } } function propFilter(props, specialEasing) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for (index in props) { name = camelCase(index); easing = specialEasing[name]; value = props[index]; if (Array.isArray(value)) { easing = value[1]; value = props[index] = value[0]; } if (index !== name) { props[name] = value; delete props[index]; } hooks = jQuery.cssHooks[name]; if (hooks && "expand" in hooks) { value = hooks.expand(value); delete props[name]; // Not quite $.extend, this won't overwrite existing keys. // Reusing 'index' because we have the correct "name" for (index in value) { if (!(index in props)) { props[index] = value[index]; specialEasing[index] = easing; } } } else { specialEasing[name] = easing; } } } function Animation(elem, properties, options) { var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always(function () { // Don't match elem in the :animated selector delete tick.elem; }), tick = function () { if (stopped) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max(0, animation.startTime + animation.duration - currentTime), // Support: Android 2.3 only // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; for (; index < length; index++) { animation.tweens[index].run(percent); } deferred.notifyWith(elem, [animation, percent, remaining]); // If there's more to do, yield if (percent < 1 && length) { return remaining; } // If this was an empty animation, synthesize a final progress notification if (!length) { deferred.notifyWith(elem, [animation, 1, 0]); } // Resolve the animation and report its conclusion deferred.resolveWith(elem, [animation]); return false; }, animation = deferred.promise({ elem: elem, props: jQuery.extend({}, properties), opts: jQuery.extend(true, { specialEasing: {}, easing: jQuery.easing._default }, options), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function (prop, end) { var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing); animation.tweens.push(tween); return tween; }, stop: function (gotoEnd) { var index = 0, // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if (stopped) { return this; } stopped = true; for (; index < length; index++) { animation.tweens[index].run(1); } // Resolve when we played the last frame; otherwise, reject if (gotoEnd) { deferred.notifyWith(elem, [animation, 1, 0]); deferred.resolveWith(elem, [animation, gotoEnd]); } else { deferred.rejectWith(elem, [animation, gotoEnd]); } return this; } }), props = animation.props; propFilter(props, animation.opts.specialEasing); for (; index < length; index++) { result = Animation.prefilters[index].call(animation, elem, props, animation.opts); if (result) { if (isFunction(result.stop)) { jQuery._queueHooks(animation.elem, animation.opts.queue).stop = result.stop.bind(result); } return result; } } jQuery.map(props, createTween, animation); if (isFunction(animation.opts.start)) { animation.opts.start.call(elem, animation); } // Attach callbacks from options animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always); jQuery.fx.timer(jQuery.extend(tick, { elem: elem, anim: animation, queue: animation.opts.queue })); return animation; } jQuery.Animation = jQuery.extend(Animation, { tweeners: { "*": [function (prop, value) { var tween = this.createTween(prop, value); adjustCSS(tween.elem, prop, rcssNum.exec(value), tween); return tween; }] }, tweener: function (props, callback) { if (isFunction(props)) { callback = props; props = ["*"]; } else { props = props.match(rnothtmlwhite); } var prop, index = 0, length = props.length; for (; index < length; index++) { prop = props[index]; Animation.tweeners[prop] = Animation.tweeners[prop] || []; Animation.tweeners[prop].unshift(callback); } }, prefilters: [defaultPrefilter], prefilter: function (callback, prepend) { if (prepend) { Animation.prefilters.unshift(callback); } else { Animation.prefilters.push(callback); } } }); jQuery.speed = function (speed, easing, fn) { var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { complete: fn || !fn && easing || isFunction(speed) && speed, duration: speed, easing: fn && easing || easing && !isFunction(easing) && easing }; // Go to the end state if fx are off if (jQuery.fx.off) { opt.duration = 0; } else { if (typeof opt.duration !== "number") { if (opt.duration in jQuery.fx.speeds) { opt.duration = jQuery.fx.speeds[opt.duration]; } else { opt.duration = jQuery.fx.speeds._default; } } } // Normalize opt.queue - true/undefined/null -> "fx" if (opt.queue == null || opt.queue === true) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function () { if (isFunction(opt.old)) { opt.old.call(this); } if (opt.queue) { jQuery.dequeue(this, opt.queue); } }; return opt; }; jQuery.fn.extend({ fadeTo: function (speed, to, easing, callback) { // Show any hidden elements after setting opacity to 0 return this.filter(isHiddenWithinTree).css("opacity", 0).show() // Animate to the value specified .end().animate({ opacity: to }, speed, easing, callback); }, animate: function (prop, speed, easing, callback) { var empty = jQuery.isEmptyObject(prop), optall = jQuery.speed(speed, easing, callback), doAnimation = function () { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation(this, jQuery.extend({}, prop), optall); // Empty animations, or finishing resolves immediately if (empty || dataPriv.get(this, "finish")) { anim.stop(true); } }; doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation); }, stop: function (type, clearQueue, gotoEnd) { var stopQueue = function (hooks) { var stop = hooks.stop; delete hooks.stop; stop(gotoEnd); }; if (typeof type !== "string") { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if (clearQueue && type !== false) { this.queue(type || "fx", []); } return this.each(function () { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = dataPriv.get(this); if (index) { if (data[index] && data[index].stop) { stopQueue(data[index]); } } else { for (index in data) { if (data[index] && data[index].stop && rrun.test(index)) { stopQueue(data[index]); } } } for (index = timers.length; index--;) { if (timers[index].elem === this && (type == null || timers[index].queue === type)) { timers[index].anim.stop(gotoEnd); dequeue = false; timers.splice(index, 1); } } // Start the next in the queue if the last step wasn't forced. // Timers currently will call their complete callbacks, which // will dequeue but only if they were gotoEnd. if (dequeue || !gotoEnd) { jQuery.dequeue(this, type); } }); }, finish: function (type) { if (type !== false) { type = type || "fx"; } return this.each(function () { var index, data = dataPriv.get(this), queue = data[type + "queue"], hooks = data[type + "queueHooks"], timers = jQuery.timers, length = queue ? queue.length : 0; // Enable finishing flag on private data data.finish = true; // Empty the queue first jQuery.queue(this, type, []); if (hooks && hooks.stop) { hooks.stop.call(this, true); } // Look for any active animations, and finish them for (index = timers.length; index--;) { if (timers[index].elem === this && timers[index].queue === type) { timers[index].anim.stop(true); timers.splice(index, 1); } } // Look for any animations in the old queue and finish them for (index = 0; index < length; index++) { if (queue[index] && queue[index].finish) { queue[index].finish.call(this); } } // Turn off finishing flag delete data.finish; }); } }); jQuery.each(["toggle", "show", "hide"], function (i, name) { var cssFn = jQuery.fn[name]; jQuery.fn[name] = function (speed, easing, callback) { return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback); }; }); // Generate shortcuts for custom animations jQuery.each({ slideDown: genFx("show"), slideUp: genFx("hide"), slideToggle: genFx("toggle"), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function (name, props) { jQuery.fn[name] = function (speed, easing, callback) { return this.animate(props, speed, easing, callback); }; }); jQuery.timers = []; jQuery.fx.tick = function () { var timer, i = 0, timers = jQuery.timers; fxNow = Date.now(); for (; i < timers.length; i++) { timer = timers[i]; // Run the timer and safely remove it when done (allowing for external removal) if (!timer() && timers[i] === timer) { timers.splice(i--, 1); } } if (!timers.length) { jQuery.fx.stop(); } fxNow = undefined; }; jQuery.fx.timer = function (timer) { jQuery.timers.push(timer); jQuery.fx.start(); }; jQuery.fx.interval = 13; jQuery.fx.start = function () { if (inProgress) { return; } inProgress = true; schedule(); }; jQuery.fx.stop = function () { inProgress = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function (time, type) { time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; type = type || "fx"; return this.queue(type, function (next, hooks) { var timeout = window.setTimeout(next, time); hooks.stop = function () { window.clearTimeout(timeout); }; }); }; (function () { var input = document.createElement("input"), select = document.createElement("select"), opt = select.appendChild(document.createElement("option")); input.type = "checkbox"; // Support: Android <=4.3 only // Default value for a checkbox should be "on" support.checkOn = input.value !== ""; // Support: IE <=11 only // Must access selectedIndex to make default options select support.optSelected = opt.selected; // Support: IE <=11 only // An input loses its value after becoming a radio input = document.createElement("input"); input.value = "t"; input.type = "radio"; support.radioValue = input.value === "t"; })(); var boolHook, attrHandle = jQuery.expr.attrHandle; jQuery.fn.extend({ attr: function (name, value) { return access(this, jQuery.attr, name, value, arguments.length > 1); }, removeAttr: function (name) { return this.each(function () { jQuery.removeAttr(this, name); }); } }); jQuery.extend({ attr: function (elem, name, value) { var ret, hooks, nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes if (nType === 3 || nType === 8 || nType === 2) { return; } // Fallback to prop when attributes are not supported if (typeof elem.getAttribute === "undefined") { return jQuery.prop(elem, name, value); } // Attribute hooks are determined by the lowercase version // Grab necessary hook if one is defined if (nType !== 1 || !jQuery.isXMLDoc(elem)) { hooks = jQuery.attrHooks[name.toLowerCase()] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined); } if (value !== undefined) { if (value === null) { jQuery.removeAttr(elem, name); return; } if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { return ret; } elem.setAttribute(name, value + ""); return value; } if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { return ret; } ret = jQuery.find.attr(elem, name); // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; }, attrHooks: { type: { set: function (elem, value) { if (!support.radioValue && value === "radio" && nodeName(elem, "input")) { var val = elem.value; elem.setAttribute("type", value); if (val) { elem.value = val; } return value; } } } }, removeAttr: function (elem, value) { var name, i = 0, // Attribute names can contain non-HTML whitespace characters // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 attrNames = value && value.match(rnothtmlwhite); if (attrNames && elem.nodeType === 1) { while (name = attrNames[i++]) { elem.removeAttribute(name); } } } }); // Hooks for boolean attributes boolHook = { set: function (elem, value, name) { if (value === false) { // Remove boolean attributes when set to false jQuery.removeAttr(elem, name); } else { elem.setAttribute(name, name); } return name; } }; jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) { var getter = attrHandle[name] || jQuery.find.attr; attrHandle[name] = function (elem, name, isXML) { var ret, handle, lowercaseName = name.toLowerCase(); if (!isXML) { // Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[lowercaseName]; attrHandle[lowercaseName] = ret; ret = getter(elem, name, isXML) != null ? lowercaseName : null; attrHandle[lowercaseName] = handle; } return ret; }; }); var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; jQuery.fn.extend({ prop: function (name, value) { return access(this, jQuery.prop, name, value, arguments.length > 1); }, removeProp: function (name) { return this.each(function () { delete this[jQuery.propFix[name] || name]; }); } }); jQuery.extend({ prop: function (elem, name, value) { var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes if (nType === 3 || nType === 8 || nType === 2) { return; } if (nType !== 1 || !jQuery.isXMLDoc(elem)) { // Fix name and attach hooks name = jQuery.propFix[name] || name; hooks = jQuery.propHooks[name]; } if (value !== undefined) { if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { return ret; } return elem[name] = value; } if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { return ret; } return elem[name]; }, propHooks: { tabIndex: { get: function (elem) { // Support: IE <=9 - 11 only // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr(elem, "tabindex"); if (tabindex) { return parseInt(tabindex, 10); } if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) { return 0; } return -1; } } }, propFix: { "for": "htmlFor", "class": "className" } }); // Support: IE <=11 only // Accessing the selectedIndex property // forces the browser to respect setting selected // on the option // The getter ensures a default option is selected // when in an optgroup // eslint rule "no-unused-expressions" is disabled for this code // since it considers such accessions noop if (!support.optSelected) { jQuery.propHooks.selected = { get: function (elem) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if (parent && parent.parentNode) { parent.parentNode.selectedIndex; } return null; }, set: function (elem) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if (parent) { parent.selectedIndex; if (parent.parentNode) { parent.parentNode.selectedIndex; } } } }; } jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () { jQuery.propFix[this.toLowerCase()] = this; }); // Strip and collapse whitespace according to HTML spec // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace function stripAndCollapse(value) { var tokens = value.match(rnothtmlwhite) || []; return tokens.join(" "); } function getClass(elem) { return elem.getAttribute && elem.getAttribute("class") || ""; } function classesToArray(value) { if (Array.isArray(value)) { return value; } if (typeof value === "string") { return value.match(rnothtmlwhite) || []; } return []; } jQuery.fn.extend({ addClass: function (value) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if (isFunction(value)) { return this.each(function (j) { jQuery(this).addClass(value.call(this, j, getClass(this))); }); } classes = classesToArray(value); if (classes.length) { while (elem = this[i++]) { curValue = getClass(elem); cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " "; if (cur) { j = 0; while (clazz = classes[j++]) { if (cur.indexOf(" " + clazz + " ") < 0) { cur += clazz + " "; } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse(cur); if (curValue !== finalValue) { elem.setAttribute("class", finalValue); } } } } return this; }, removeClass: function (value) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if (isFunction(value)) { return this.each(function (j) { jQuery(this).removeClass(value.call(this, j, getClass(this))); }); } if (!arguments.length) { return this.attr("class", ""); } classes = classesToArray(value); if (classes.length) { while (elem = this[i++]) { curValue = getClass(elem); // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " "; if (cur) { j = 0; while (clazz = classes[j++]) { // Remove *all* instances while (cur.indexOf(" " + clazz + " ") > -1) { cur = cur.replace(" " + clazz + " ", " "); } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse(cur); if (curValue !== finalValue) { elem.setAttribute("class", finalValue); } } } } return this; }, toggleClass: function (value, stateVal) { var type = typeof value, isValidValue = type === "string" || Array.isArray(value); if (typeof stateVal === "boolean" && isValidValue) { return stateVal ? this.addClass(value) : this.removeClass(value); } if (isFunction(value)) { return this.each(function (i) { jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal); }); } return this.each(function () { var className, i, self, classNames; if (isValidValue) { // Toggle individual class names i = 0; self = jQuery(this); classNames = classesToArray(value); while (className = classNames[i++]) { // Check each className given, space separated list if (self.hasClass(className)) { self.removeClass(className); } else { self.addClass(className); } } // Toggle whole class name } else if (value === undefined || type === "boolean") { className = getClass(this); if (className) { // Store className if set dataPriv.set(this, "__className__", className); } // If the element has a class name or if we're passed `false`, // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. if (this.setAttribute) { this.setAttribute("class", className || value === false ? "" : dataPriv.get(this, "__className__") || ""); } } }); }, hasClass: function (selector) { var className, elem, i = 0; className = " " + selector + " "; while (elem = this[i++]) { if (elem.nodeType === 1 && (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) { return true; } } return false; } }); var rreturn = /\r/g; jQuery.fn.extend({ val: function (value) { var hooks, ret, valueIsFunction, elem = this[0]; if (!arguments.length) { if (elem) { hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()]; if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) { return ret; } ret = elem.value; // Handle most common string cases if (typeof ret === "string") { return ret.replace(rreturn, ""); } // Handle cases where value is null/undef or number return ret == null ? "" : ret; } return; } valueIsFunction = isFunction(value); return this.each(function (i) { var val; if (this.nodeType !== 1) { return; } if (valueIsFunction) { val = value.call(this, i, jQuery(this).val()); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if (val == null) { val = ""; } else if (typeof val === "number") { val += ""; } else if (Array.isArray(val)) { val = jQuery.map(val, function (value) { return value == null ? "" : value + ""; }); } hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; // If set returns undefined, fall back to normal setting if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) { this.value = val; } }); } }); jQuery.extend({ valHooks: { option: { get: function (elem) { var val = jQuery.find.attr(elem, "value"); return val != null ? val : // Support: IE <=10 - 11 only // option.text throws exceptions (#14686, #14858) // Strip and collapse whitespace // https://html.spec.whatwg.org/#strip-and-collapse-whitespace stripAndCollapse(jQuery.text(elem)); } }, select: { get: function (elem) { var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one", values = one ? null : [], max = one ? index + 1 : options.length; if (index < 0) { i = max; } else { i = one ? index : 0; } // Loop through all the selected options for (; i < max; i++) { option = options[i]; // Support: IE <=9 only // IE8-9 doesn't update selected after form reset (#2551) if ((option.selected || i === index) && // Don't return options that are disabled or in a disabled optgroup !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, "optgroup"))) { // Get the specific value for the option value = jQuery(option).val(); // We don't need an array for one selects if (one) { return value; } // Multi-Selects return an array values.push(value); } } return values; }, set: function (elem, value) { var optionSet, option, options = elem.options, values = jQuery.makeArray(value), i = options.length; while (i--) { option = options[i]; /* eslint-disable no-cond-assign */ if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) { optionSet = true; } /* eslint-enable no-cond-assign */ } // Force browsers to behave consistently when non-matching value is set if (!optionSet) { elem.selectedIndex = -1; } return values; } } } }); // Radios and checkboxes getter/setter jQuery.each(["radio", "checkbox"], function () { jQuery.valHooks[this] = { set: function (elem, value) { if (Array.isArray(value)) { return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1; } } }; if (!support.checkOn) { jQuery.valHooks[this].get = function (elem) { return elem.getAttribute("value") === null ? "on" : elem.value; }; } }); // Return jQuery for attributes-only inclusion support.focusin = "onfocusin" in window; var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function (e) { e.stopPropagation(); }; jQuery.extend(jQuery.event, { trigger: function (event, data, elem, onlyHandlers) { var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [elem || document], type = hasOwn.call(event, "type") ? event.type : event, namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : []; cur = lastElement = tmp = elem = elem || document; // Don't do events on text and comment nodes if (elem.nodeType === 3 || elem.nodeType === 8) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if (rfocusMorph.test(type + jQuery.event.triggered)) { return; } if (type.indexOf(".") > -1) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split("."); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf(":") < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === "object" && event); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3; event.namespace = namespaces.join("."); event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; // Clean up the event in case it is being reused event.result = undefined; if (!event.target) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [event] : jQuery.makeArray(data, [event]); // Allow special events to draw outside the lines special = jQuery.event.special[type] || {}; if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if (!onlyHandlers && !special.noBubble && !isWindow(elem)) { bubbleType = special.delegateType || type; if (!rfocusMorph.test(bubbleType + type)) { cur = cur.parentNode; } for (; cur; cur = cur.parentNode) { eventPath.push(cur); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if (tmp === (elem.ownerDocument || document)) { eventPath.push(tmp.defaultView || tmp.parentWindow || window); } } // Fire handlers on the event path i = 0; while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { lastElement = cur; event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = (dataPriv.get(cur, "events") || {})[event.type] && dataPriv.get(cur, "handle"); if (handle) { handle.apply(cur, data); } // Native handler handle = ontype && cur[ontype]; if (handle && handle.apply && acceptData(cur)) { event.result = handle.apply(cur, data); if (event.result === false) { event.preventDefault(); } } } event.type = type; // If nobody prevented the default action, do it now if (!onlyHandlers && !event.isDefaultPrevented()) { if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) if (ontype && isFunction(elem[type]) && !isWindow(elem)) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ontype]; if (tmp) { elem[ontype] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; if (event.isPropagationStopped()) { lastElement.addEventListener(type, stopPropagationCallback); } elem[type](); if (event.isPropagationStopped()) { lastElement.removeEventListener(type, stopPropagationCallback); } jQuery.event.triggered = undefined; if (tmp) { elem[ontype] = tmp; } } } } return event.result; }, // Piggyback on a donor event to simulate a different one // Used only for `focus(in | out)` events simulate: function (type, elem, event) { var e = jQuery.extend(new jQuery.Event(), event, { type: type, isSimulated: true }); jQuery.event.trigger(e, null, elem); } }); jQuery.fn.extend({ trigger: function (type, data) { return this.each(function () { jQuery.event.trigger(type, data, this); }); }, triggerHandler: function (type, data) { var elem = this[0]; if (elem) { return jQuery.event.trigger(type, data, elem, true); } } }); // Support: Firefox <=44 // Firefox doesn't have focus(in | out) events // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 // // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 // focus(in | out) events fire after focus & blur events, // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 if (!support.focusin) { jQuery.each({ focus: "focusin", blur: "focusout" }, function (orig, fix) { // Attach a single capturing handler on the document while someone wants focusin/focusout var handler = function (event) { jQuery.event.simulate(fix, event.target, jQuery.event.fix(event)); }; jQuery.event.special[fix] = { setup: function () { var doc = this.ownerDocument || this, attaches = dataPriv.access(doc, fix); if (!attaches) { doc.addEventListener(orig, handler, true); } dataPriv.access(doc, fix, (attaches || 0) + 1); }, teardown: function () { var doc = this.ownerDocument || this, attaches = dataPriv.access(doc, fix) - 1; if (!attaches) { doc.removeEventListener(orig, handler, true); dataPriv.remove(doc, fix); } else { dataPriv.access(doc, fix, attaches); } } }; }); } var location = window.location; var nonce = Date.now(); var rquery = /\?/; // Cross-browser xml parsing jQuery.parseXML = function (data) { var xml; if (!data || typeof data !== "string") { return null; } // Support: IE 9 - 11 only // IE throws on parseFromString with invalid input. try { xml = new window.DOMParser().parseFromString(data, "text/xml"); } catch (e) { xml = undefined; } if (!xml || xml.getElementsByTagName("parsererror").length) { jQuery.error("Invalid XML: " + data); } return xml; }; var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; function buildParams(prefix, obj, traditional, add) { var name; if (Array.isArray(obj)) { // Serialize array item. jQuery.each(obj, function (i, v) { if (traditional || rbracket.test(prefix)) { // Treat each array item as a scalar. add(prefix, v); } else { // Item is non-scalar (array or object), encode its numeric index. buildParams(prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", v, traditional, add); } }); } else if (!traditional && toType(obj) === "object") { // Serialize object item. for (name in obj) { buildParams(prefix + "[" + name + "]", obj[name], traditional, add); } } else { // Serialize scalar item. add(prefix, obj); } } // Serialize an array of form elements or a set of // key/values into a query string jQuery.param = function (a, traditional) { var prefix, s = [], add = function (key, valueOrFunction) { // If value is a function, invoke it and use its return value var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction; s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value); }; // If an array was passed in, assume that it is an array of form elements. if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) { // Serialize the form elements jQuery.each(a, function () { add(this.name, this.value); }); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for (prefix in a) { buildParams(prefix, a[prefix], traditional, add); } } // Return the resulting serialization return s.join("&"); }; jQuery.fn.extend({ serialize: function () { return jQuery.param(this.serializeArray()); }, serializeArray: function () { return this.map(function () { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop(this, "elements"); return elements ? jQuery.makeArray(elements) : this; }).filter(function () { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type)); }).map(function (i, elem) { var val = jQuery(this).val(); if (val == null) { return null; } if (Array.isArray(val)) { return jQuery.map(val, function (val) { return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; }); } return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; }).get(); } }); var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = "*/".concat("*"), // Anchor tag for parsing the document origin originAnchor = document.createElement("a"); originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports(structure) { // dataTypeExpression is optional and defaults to "*" return function (dataTypeExpression, func) { if (typeof dataTypeExpression !== "string") { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || []; if (isFunction(func)) { // For each dataType in the dataTypeExpression while (dataType = dataTypes[i++]) { // Prepend if requested if (dataType[0] === "+") { dataType = dataType.slice(1) || "*"; (structure[dataType] = structure[dataType] || []).unshift(func); // Otherwise append } else { (structure[dataType] = structure[dataType] || []).push(func); } } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) { var inspected = {}, seekingTransport = structure === transports; function inspect(dataType) { var selected; inspected[dataType] = true; jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) { var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) { options.dataTypes.unshift(dataTypeOrTransport); inspect(dataTypeOrTransport); return false; } else if (seekingTransport) { return !(selected = dataTypeOrTransport); } }); return selected; } return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*"); } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend(target, src) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for (key in src) { if (src[key] !== undefined) { (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key]; } } if (deep) { jQuery.extend(true, target, deep); } return target; } /* Handles responses to an ajax request: * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses(s, jqXHR, responses) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while (dataTypes[0] === "*") { dataTypes.shift(); if (ct === undefined) { ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); } } // Check if we're dealing with a known content-type if (ct) { for (type in contents) { if (contents[type] && contents[type].test(ct)) { dataTypes.unshift(type); break; } } } // Check to see if we have a response for the expected dataType if (dataTypes[0] in responses) { finalDataType = dataTypes[0]; } else { // Try convertible dataTypes for (type in responses) { if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) { finalDataType = type; break; } if (!firstDataType) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if (finalDataType) { if (finalDataType !== dataTypes[0]) { dataTypes.unshift(finalDataType); } return responses[finalDataType]; } } /* Chain conversions given the request and the original response * Also sets the responseXXX fields on the jqXHR instance */ function ajaxConvert(s, response, jqXHR, isSuccess) { var conv2, current, conv, tmp, prev, converters = {}, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if (dataTypes[1]) { for (conv in s.converters) { converters[conv.toLowerCase()] = s.converters[conv]; } } current = dataTypes.shift(); // Convert to each sequential dataType while (current) { if (s.responseFields[current]) { jqXHR[s.responseFields[current]] = response; } // Apply the dataFilter if provided if (!prev && isSuccess && s.dataFilter) { response = s.dataFilter(response, s.dataType); } prev = current; current = dataTypes.shift(); if (current) { // There's only work to do if current dataType is non-auto if (current === "*") { current = prev; // Convert response if prev dataType is non-auto and differs from current } else if (prev !== "*" && prev !== current) { // Seek a direct converter conv = converters[prev + " " + current] || converters["* " + current]; // If none found, seek a pair if (!conv) { for (conv2 in converters) { // If conv2 outputs current tmp = conv2.split(" "); if (tmp[1] === current) { // If prev can be converted to accepted input conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]]; if (conv) { // Condense equivalence converters if (conv === true) { conv = converters[conv2]; // Otherwise, insert the intermediate dataType } else if (converters[conv2] !== true) { current = tmp[0]; dataTypes.unshift(tmp[1]); } break; } } } } // Apply converter (if not an equivalence) if (conv !== true) { // Unless errors are allowed to bubble, catch and return them if (conv && s.throws) { response = conv(response); } else { try { response = conv(response); } catch (e) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } } } return { state: "success", data: response }; } jQuery.extend({ // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {}, ajaxSettings: { url: location.href, type: "GET", isLocal: rlocalProtocol.test(location.protocol), global: true, processData: true, async: true, contentType: "application/x-www-form-urlencoded; charset=UTF-8", /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { "*": allTypes, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, // Data converters // Keys separate source (or catchall "*") and destination types with a single space converters: { // Convert anything to text "* text": String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": JSON.parse, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { url: true, context: true } }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function (target, settings) { return settings ? // Building a settings object ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : // Extending ajaxSettings ajaxExtend(jQuery.ajaxSettings, target); }, ajaxPrefilter: addToPrefiltersOrTransports(prefilters), ajaxTransport: addToPrefiltersOrTransports(transports), // Main method ajax: function (url, options) { // If url is an object, simulate pre-1.5 signature if (typeof url === "object") { options = url; url = undefined; } // Force options to be an object options = options || {}; var transport, // URL without anti-cache param cacheURL, // Response headers responseHeadersString, responseHeaders, // timeout handle timeoutTimer, // Url cleanup var urlAnchor, // Request state (becomes false upon send and true upon completion) completed, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // uncached part of the url uncached, // Create the final options object s = jQuery.ajaxSetup({}, options), // Callbacks context callbackContext = s.context || s, // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks("once memory"), // Status-dependent callbacks statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Builds headers hashtable if needed getResponseHeader: function (key) { var match; if (completed) { if (!responseHeaders) { responseHeaders = {}; while (match = rheaders.exec(responseHeadersString)) { responseHeaders[match[1].toLowerCase()] = match[2]; } } match = responseHeaders[key.toLowerCase()]; } return match == null ? null : match; }, // Raw string getAllResponseHeaders: function () { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function (name, value) { if (completed == null) { name = requestHeadersNames[name.toLowerCase()] = requestHeadersNames[name.toLowerCase()] || name; requestHeaders[name] = value; } return this; }, // Overrides response content-type header overrideMimeType: function (type) { if (completed == null) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function (map) { var code; if (map) { if (completed) { // Execute the appropriate callbacks jqXHR.always(map[jqXHR.status]); } else { // Lazy-add the new callbacks in a way that preserves old ones for (code in map) { statusCode[code] = [statusCode[code], map[code]]; } } } return this; }, // Cancel the request abort: function (statusText) { var finalText = statusText || strAbort; if (transport) { transport.abort(finalText); } done(0, finalText); return this; } }; // Attach deferreds deferred.promise(jqXHR); // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available s.url = ((url || s.url || location.href) + "").replace(rprotocol, location.protocol + "//"); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""]; // A cross-domain request is in order when the origin doesn't match the current origin. if (s.crossDomain == null) { urlAnchor = document.createElement("a"); // Support: IE <=8 - 11, Edge 12 - 15 // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { urlAnchor.href = s.url; // Support: IE <=8 - 11 only // Anchor's host property isn't correctly set when s.url is relative urlAnchor.href = urlAnchor.href; s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; } catch (e) { // If there is an error parsing the URL, assume it is crossDomain, // it can be rejected by the transport if it is invalid s.crossDomain = true; } } // Convert data if not already a string if (s.data && s.processData && typeof s.data !== "string") { s.data = jQuery.param(s.data, s.traditional); } // Apply prefilters inspectPrefiltersOrTransports(prefilters, s, options, jqXHR); // If request was aborted inside a prefilter, stop there if (completed) { return jqXHR; } // We can fire global events as of now if asked to // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) fireGlobals = jQuery.event && s.global; // Watch for a new set of requests if (fireGlobals && jQuery.active++ === 0) { jQuery.event.trigger("ajaxStart"); } // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test(s.type); // Save the URL in case we're toying with the If-Modified-Since // and/or If-None-Match header later on // Remove hash to simplify url manipulation cacheURL = s.url.replace(rhash, ""); // More options handling for requests with no content if (!s.hasContent) { // Remember the hash so we can put it back uncached = s.url.slice(cacheURL.length); // If data is available and should be processed, append data to url if (s.data && (s.processData || typeof s.data === "string")) { cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data; // #9682: remove data so that it's not used in an eventual retry delete s.data; } // Add or update anti-cache param if needed if (s.cache === false) { cacheURL = cacheURL.replace(rantiCache, "$1"); uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++ + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658) } else if (s.data && s.processData && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) { s.data = s.data.replace(r20, "+"); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if (s.ifModified) { if (jQuery.lastModified[cacheURL]) { jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]); } if (jQuery.etag[cacheURL]) { jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]); } } // Set the correct header, if data is being sent if (s.data && s.hasContent && s.contentType !== false || options.contentType) { jqXHR.setRequestHeader("Content-Type", s.contentType); } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]); // Check for headers option for (i in s.headers) { jqXHR.setRequestHeader(i, s.headers[i]); } // Allow custom headers/mimetypes and early abort if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) { // Abort if not done already and return return jqXHR.abort(); } // Aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds completeDeferred.add(s.complete); jqXHR.done(s.success); jqXHR.fail(s.error); // Get transport transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR); // If no transport, we auto-abort if (!transport) { done(-1, "No Transport"); } else { jqXHR.readyState = 1; // Send global event if (fireGlobals) { globalEventContext.trigger("ajaxSend", [jqXHR, s]); } // If request was aborted inside ajaxSend, stop there if (completed) { return jqXHR; } // Timeout if (s.async && s.timeout > 0) { timeoutTimer = window.setTimeout(function () { jqXHR.abort("timeout"); }, s.timeout); } try { completed = false; transport.send(requestHeaders, done); } catch (e) { // Rethrow post-completion exceptions if (completed) { throw e; } // Propagate others as results done(-1, e); } } // Callback for when everything is done function done(status, nativeStatusText, responses, headers) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Ignore repeat invocations if (completed) { return; } completed = true; // Clear timeout if it exists if (timeoutTimer) { window.clearTimeout(timeoutTimer); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful isSuccess = status >= 200 && status < 300 || status === 304; // Get response data if (responses) { response = ajaxHandleResponses(s, jqXHR, responses); } // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert(s, response, jqXHR, isSuccess); // If successful, handle type chaining if (isSuccess) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if (s.ifModified) { modified = jqXHR.getResponseHeader("Last-Modified"); if (modified) { jQuery.lastModified[cacheURL] = modified; } modified = jqXHR.getResponseHeader("etag"); if (modified) { jQuery.etag[cacheURL] = modified; } } // if no content if (status === 204 || s.type === "HEAD") { statusText = "nocontent"; // if not modified } else if (status === 304) { statusText = "notmodified"; // If we have data, let's convert it } else { statusText = response.state; success = response.data; error = response.error; isSuccess = !error; } } else { // Extract error from statusText and normalize for non-aborts error = statusText; if (status || !statusText) { statusText = "error"; if (status < 0) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = (nativeStatusText || statusText) + ""; // Success/Error if (isSuccess) { deferred.resolveWith(callbackContext, [success, statusText, jqXHR]); } else { deferred.rejectWith(callbackContext, [jqXHR, statusText, error]); } // Status-dependent callbacks jqXHR.statusCode(statusCode); statusCode = undefined; if (fireGlobals) { globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]); } // Complete completeDeferred.fireWith(callbackContext, [jqXHR, statusText]); if (fireGlobals) { globalEventContext.trigger("ajaxComplete", [jqXHR, s]); // Handle the global AJAX counter if (! --jQuery.active) { jQuery.event.trigger("ajaxStop"); } } } return jqXHR; }, getJSON: function (url, data, callback) { return jQuery.get(url, data, callback, "json"); }, getScript: function (url, callback) { return jQuery.get(url, undefined, callback, "script"); } }); jQuery.each(["get", "post"], function (i, method) { jQuery[method] = function (url, data, callback, type) { // Shift arguments if data argument was omitted if (isFunction(data)) { type = type || callback; callback = data; data = undefined; } // The url can be an options object (which then must have .url) return jQuery.ajax(jQuery.extend({ url: url, type: method, dataType: type, data: data, success: callback }, jQuery.isPlainObject(url) && url)); }; }); jQuery._evalUrl = function (url) { return jQuery.ajax({ url: url, // Make this explicit, since user can override this through ajaxSetup (#11264) type: "GET", dataType: "script", cache: true, async: false, global: false, "throws": true }); }; jQuery.fn.extend({ wrapAll: function (html) { var wrap; if (this[0]) { if (isFunction(html)) { html = html.call(this[0]); } // The elements to wrap the target around wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); if (this[0].parentNode) { wrap.insertBefore(this[0]); } wrap.map(function () { var elem = this; while (elem.firstElementChild) { elem = elem.firstElementChild; } return elem; }).append(this); } return this; }, wrapInner: function (html) { if (isFunction(html)) { return this.each(function (i) { jQuery(this).wrapInner(html.call(this, i)); }); } return this.each(function () { var self = jQuery(this), contents = self.contents(); if (contents.length) { contents.wrapAll(html); } else { self.append(html); } }); }, wrap: function (html) { var htmlIsFunction = isFunction(html); return this.each(function (i) { jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html); }); }, unwrap: function (selector) { this.parent(selector).not("body").each(function () { jQuery(this).replaceWith(this.childNodes); }); return this; } }); jQuery.expr.pseudos.hidden = function (elem) { return !jQuery.expr.pseudos.visible(elem); }; jQuery.expr.pseudos.visible = function (elem) { return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); }; jQuery.ajaxSettings.xhr = function () { try { return new window.XMLHttpRequest(); } catch (e) {} }; var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 0: 200, // Support: IE <=9 only // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 }, xhrSupported = jQuery.ajaxSettings.xhr(); support.cors = !!xhrSupported && "withCredentials" in xhrSupported; support.ajax = xhrSupported = !!xhrSupported; jQuery.ajaxTransport(function (options) { var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if (support.cors || xhrSupported && !options.crossDomain) { return { send: function (headers, complete) { var i, xhr = options.xhr(); xhr.open(options.type, options.url, options.async, options.username, options.password); // Apply custom fields if provided if (options.xhrFields) { for (i in options.xhrFields) { xhr[i] = options.xhrFields[i]; } } // Override mime type if needed if (options.mimeType && xhr.overrideMimeType) { xhr.overrideMimeType(options.mimeType); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if (!options.crossDomain && !headers["X-Requested-With"]) { headers["X-Requested-With"] = "XMLHttpRequest"; } // Set headers for (i in headers) { xhr.setRequestHeader(i, headers[i]); } // Callback callback = function (type) { return function () { if (callback) { callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; if (type === "abort") { xhr.abort(); } else if (type === "error") { // Support: IE <=9 only // On a manual native abort, IE9 throws // errors on any property access that is not readyState if (typeof xhr.status !== "number") { complete(0, "error"); } else { complete( // File: protocol always yields status 0; see #8605, #14207 xhr.status, xhr.statusText); } } else { complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText, // Support: IE <=9 only // IE9 has no XHR2 but throws on binary (trac-11426) // For XHR2 non-text, let the caller handle it (gh-2498) (xhr.responseType || "text") !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders()); } } }; }; // Listen to events xhr.onload = callback(); errorCallback = xhr.onerror = xhr.ontimeout = callback("error"); // Support: IE 9 only // Use onreadystatechange to replace onabort // to handle uncaught aborts if (xhr.onabort !== undefined) { xhr.onabort = errorCallback; } else { xhr.onreadystatechange = function () { // Check readyState before timeout as it changes if (xhr.readyState === 4) { // Allow onerror to be called first, // but that will not handle a native abort // Also, save errorCallback to a variable // as xhr.onerror cannot be accessed window.setTimeout(function () { if (callback) { errorCallback(); } }); } }; } // Create the abort callback callback = callback("abort"); try { // Do send the request (this may raise an exception) xhr.send(options.hasContent && options.data || null); } catch (e) { // #14683: Only rethrow if this hasn't been notified as an error yet if (callback) { throw e; } } }, abort: function () { if (callback) { callback(); } } }; } }); // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) jQuery.ajaxPrefilter(function (s) { if (s.crossDomain) { s.contents.script = false; } }); // Install script dataType jQuery.ajaxSetup({ accepts: { script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function (text) { jQuery.globalEval(text); return text; } } }); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter("script", function (s) { if (s.cache === undefined) { s.cache = false; } if (s.crossDomain) { s.type = "GET"; } }); // Bind script tag hack transport jQuery.ajaxTransport("script", function (s) { // This transport only deals with cross domain requests if (s.crossDomain) { var script, callback; return { send: function (_, complete) { script = jQuery("