




Object.isEmpty = function(obj)
{
for (var i in obj)
return false;
return true;
}

Object.values = function(obj)
{
var keys = Object.keys(obj);
var result = [];

for (var i = 0; i < keys.length; ++i)
result.push(obj[keys[i]]);
return result;
}

String.prototype.hasSubstring = function(string, caseInsensitive)
{
if (!caseInsensitive)
return this.indexOf(string) !== -1;
return this.match(new RegExp(string.escapeForRegExp(), "i"));
}

String.prototype.findAll = function(string)
{
var matches = [];
var i = this.indexOf(string);
while (i !== -1) {
matches.push(i);
i = this.indexOf(string, i + string.length);
}
return matches;
}

String.prototype.lineEndings = function()
{
if (!this._lineEndings) {
this._lineEndings = this.findAll("\n");
this._lineEndings.push(this.length);
}
return this._lineEndings;
}

String.prototype.escapeCharacters = function(chars)
{
var foundChar = false;
for (var i = 0; i < chars.length; ++i) {
if (this.indexOf(chars.charAt(i)) !== -1) {
foundChar = true;
break;
}
}

if (!foundChar)
return this;

var result = "";
for (var i = 0; i < this.length; ++i) {
if (chars.indexOf(this.charAt(i)) !== -1)
result += "\\";
result += this.charAt(i);
}

return result;
}

String.prototype.escapeForRegExp = function()
{
return this.escapeCharacters("^[]{}()\\.$*+?|");
}

String.prototype.escapeHTML = function()
{
return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"); 
}

String.prototype.collapseWhitespace = function()
{
return this.replace(/[\s\xA0]+/g, " ");
}

String.prototype.trimMiddle = function(maxLength)
{
if (this.length <= maxLength)
return this;
var leftHalf = maxLength >> 1;
var rightHalf = maxLength - leftHalf - 1;
return this.substr(0, leftHalf) + "\u2026" + this.substr(this.length - rightHalf, rightHalf);
}

String.prototype.trimEnd = function(maxLength)
{
if (this.length <= maxLength)
return this;
return this.substr(0, maxLength - 1) + "\u2026";
}

String.prototype.trimURL = function(baseURLDomain)
{
var result = this.replace(/^(https|http|file):\/\//i, "");
if (baseURLDomain)
result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp(), "i"), "");
return result;
}


function sanitizeHref(href)
{
return href && href.trim().toLowerCase().startsWith("javascript:") ? "" : href;
}

String.prototype.removeURLFragment = function()
{
var fragmentIndex = this.indexOf("#");
if (fragmentIndex == -1)
fragmentIndex = this.length;
return this.substring(0, fragmentIndex);
}

String.prototype.startsWith = function(substring)
{
return !this.lastIndexOf(substring, 0);
}

String.prototype.endsWith = function(substring)
{
return this.indexOf(substring, this.length - substring.length) !== -1;
}

Number.constrain = function(num, min, max)
{
if (num < min)
num = min;
else if (num > max)
num = max;
return num;
}

Date.prototype.toISO8601Compact = function()
{
function leadZero(x)
{
return x > 9 ? '' + x : '0' + x
}
return this.getFullYear() +
leadZero(this.getMonth() + 1) +
leadZero(this.getDate()) + 'T' +
leadZero(this.getHours()) +
leadZero(this.getMinutes()) +
leadZero(this.getSeconds());
}

Object.defineProperty(Array.prototype, "remove",
{

value: function(value, onlyFirst)
{
if (onlyFirst) {
var index = this.indexOf(value);
if (index !== -1)
this.splice(index, 1);
return;
}

var length = this.length;
for (var i = 0; i < length; ++i) {
if (this[i] === value)
this.splice(i, 1);
}
}
});

Object.defineProperty(Array.prototype, "keySet",
{

value: function()
{
var keys = {};
for (var i = 0; i < this.length; ++i)
keys[this[i]] = true;
return keys;
}
});

Object.defineProperty(Array.prototype, "upperBound",
{

value: function(value)
{
var first = 0;
var count = this.length;
while (count > 0) {
var step = count >> 1;
var middle = first + step;
if (value >= this[middle]) {
first = middle + 1;
count -= step + 1;
} else
count = step;
}
return first;
}
});

Object.defineProperty(Array.prototype, "rotate",
{

value: function(index)
{
var result = [];
for (var i = index; i < index + this.length; ++i)
result.push(this[i % this.length]);
return result;
}
});

Object.defineProperty(Uint32Array.prototype, "sort", {
value: Array.prototype.sort
});

(function() {
var partition = {

value: function(comparator, left, right, pivotIndex)
{
function swap(array, i1, i2)
{
var temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}

var pivotValue = this[pivotIndex];
swap(this, right, pivotIndex);
var storeIndex = left;
for (var i = left; i < right; ++i) {
if (comparator(this[i], pivotValue) < 0) {
swap(this, storeIndex, i);
++storeIndex;
}
}
swap(this, right, storeIndex);
return storeIndex;
}
};
Object.defineProperty(Array.prototype, "partition", partition);
Object.defineProperty(Uint32Array.prototype, "partition", partition);

var sortRange = {

value: function(comparator, leftBound, rightBound, k)
{
function quickSortFirstK(array, comparator, left, right, k)
{
if (right <= left)
return;
var pivotIndex = Math.floor(Math.random() * (right - left)) + left;
var pivotNewIndex = array.partition(comparator, left, right, pivotIndex);
quickSortFirstK(array, comparator, left, pivotNewIndex - 1, k);
if (pivotNewIndex < left + k - 1)
quickSortFirstK(array, comparator, pivotNewIndex + 1, right, k);
}

if (leftBound === 0 && rightBound === (this.length - 1) && k === this.length)
this.sort(comparator);
else
quickSortFirstK(this, comparator, leftBound, rightBound, k);
return this;
}
}
Object.defineProperty(Array.prototype, "sortRange", sortRange);
Object.defineProperty(Uint32Array.prototype, "sortRange", sortRange);
})();

Object.defineProperty(Array.prototype, "qselect",
{

value: function(k, comparator)
{
if (k < 0 || k >= this.length)
return;
if (!comparator)
comparator = function(a, b) { return a - b; }

var low = 0;
var high = this.length - 1;
for (;;) {
var pivotPosition = this.partition(comparator, low, high, Math.floor((high + low) / 2));
if (pivotPosition === k)
return this[k];
else if (pivotPosition > k)
high = pivotPosition - 1;
else
low = pivotPosition + 1;
}
}
});


function binarySearch(object, array, comparator)
{
var first = 0;
var last = array.length - 1;

while (first <= last) {
var mid = (first + last) >> 1;
var c = comparator(object, array[mid]);
if (c > 0)
first = mid + 1;
else if (c < 0)
last = mid - 1;
else
return mid;
}


return -(first + 1);
}

Object.defineProperty(Array.prototype, "binaryIndexOf",
{

value: function(value, comparator)
{
var result = binarySearch(value, this, comparator);
return result >= 0 ? result : -1;
}
});

Object.defineProperty(Array.prototype, "select",
{

value: function(field)
{
var result = new Array(this.length);
for (var i = 0; i < this.length; ++i)
result[i] = this[i][field];
return result;
}
});


function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
{
var index = binarySearch(anObject, aList, aFunction);
if (index < 0)

return -index - 1;
else {

while (index > 0 && aFunction(anObject, aList[index - 1]) === 0)
index--;
return index;
}
}

Array.convert = function(list)
{

return Array.prototype.slice.call(list);
}


String.sprintf = function(format, var_arg)
{
return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
}

String.tokenizeFormatString = function(format, formatters)
{
var tokens = [];
var substitutionIndex = 0;

function addStringToken(str)
{
tokens.push({ type: "string", value: str });
}

function addSpecifierToken(specifier, precision, substitutionIndex)
{
tokens.push({ type: "specifier", specifier: specifier, precision: precision, substitutionIndex: substitutionIndex });
}

function isDigit(c)
{
return !!/[0-9]/.exec(c);
}

var index = 0;
for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) {
addStringToken(format.substring(index, precentIndex));
index = precentIndex + 1;

if (isDigit(format[index])) {

var number = parseInt(format.substring(index), 10);
while (isDigit(format[index]))
++index;



if (number > 0 && format[index] === "$") {
substitutionIndex = (number - 1);
++index;
}
}

var precision = -1;
if (format[index] === ".") {


++index;
precision = parseInt(format.substring(index), 10);
if (isNaN(precision))
precision = 0;

while (isDigit(format[index]))
++index;
}

if (!(format[index] in formatters)) {
addStringToken(format.substring(precentIndex, index + 1));
++index;
continue;
}

addSpecifierToken(format[index], precision, substitutionIndex);

++substitutionIndex;
++index;
}

addStringToken(format.substring(index));

return tokens;
}

String.standardFormatters = {
d: function(substitution)
{
return !isNaN(substitution) ? substitution : 0;
},

f: function(substitution, token)
{
if (substitution && token.precision > -1)
substitution = substitution.toFixed(token.precision);
return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
},

s: function(substitution)
{
return substitution;
}
}

String.vsprintf = function(format, substitutions)
{
return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult;
}

String.format = function(format, substitutions, formatters, initialValue, append)
{
if (!format || !substitutions || !substitutions.length)
return { formattedResult: append(initialValue, format), unusedSubstitutions: substitutions };

function prettyFunctionName()
{
return "String.format(\"" + format + "\", \"" + substitutions.join("\", \"") + "\")";
}

function warn(msg)
{
console.warn(prettyFunctionName() + ": " + msg);
}

function error(msg)
{
console.error(prettyFunctionName() + ": " + msg);
}

var result = initialValue;
var tokens = String.tokenizeFormatString(format, formatters);
var usedSubstitutionIndexes = {};

for (var i = 0; i < tokens.length; ++i) {
var token = tokens[i];

if (token.type === "string") {
result = append(result, token.value);
continue;
}

if (token.type !== "specifier") {
error("Unknown token type \"" + token.type + "\" found.");
continue;
}

if (token.substitutionIndex >= substitutions.length) {


error("not enough substitution arguments. Had " + substitutions.length + " but needed " + (token.substitutionIndex + 1) + ", so substitution was skipped.");
result = append(result, "%" + (token.precision > -1 ? token.precision : "") + token.specifier);
continue;
}

usedSubstitutionIndexes[token.substitutionIndex] = true;

if (!(token.specifier in formatters)) {

warn("unsupported format character \u201C" + token.specifier + "\u201D. Treating as a string.");
result = append(result, substitutions[token.substitutionIndex]);
continue;
}

result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token));
}

var unusedSubstitutions = [];
for (var i = 0; i < substitutions.length; ++i) {
if (i in usedSubstitutionIndexes)
continue;
unusedSubstitutions.push(substitutions[i]);
}

return { formattedResult: result, unusedSubstitutions: unusedSubstitutions };
}


function createSearchRegex(query, caseSensitive, isRegex)
{
var regexFlags = caseSensitive ? "g" : "gi";
var regexObject;

if (isRegex) {
try {
regexObject = new RegExp(query, regexFlags);
} catch (e) {

}
}

if (!regexObject)
regexObject = createPlainTextSearchRegex(query, regexFlags);

return regexObject;
}


function createPlainTextSearchRegex(query, flags)
{

var regexSpecialCharacters = "[](){}+-*.,?\\^$|";
var regex = "";
for (var i = 0; i < query.length; ++i) {
var c = query.charAt(i);
if (regexSpecialCharacters.indexOf(c) != -1)
regex += "\\";
regex += c;
}
return new RegExp(regex, flags || "");
}


function countRegexMatches(regex, content)
{
var text = content;
var result = 0;
var match;
while (text && (match = regex.exec(text))) {
if (match[0].length > 0)
++result;
text = text.substring(match.index + 1);
}
return result;
}


function numberToStringWithSpacesPadding(value, symbolsCount)
{
var numberString = value.toString();
var paddingLength = Math.max(0, symbolsCount - numberString.length);
var paddingString = Array(paddingLength + 1).join("\u00a0");
return paddingString + numberString;
}


var Map = function()
{
this._map = {};
this._size = 0;
}

Map._lastObjectIdentifier = 0;

Map.prototype = {

put: function(key, value)
{
var objectIdentifier = key.__identifier;
if (!objectIdentifier) {
objectIdentifier = ++Map._lastObjectIdentifier;
key.__identifier = objectIdentifier;
}
if (!this._map[objectIdentifier])
++this._size;
this._map[objectIdentifier] = [key, value];
},


remove: function(key)
{
var result = this._map[key.__identifier];
delete this._map[key.__identifier];
--this._size;
return result ? result[1] : undefined;
},


keys: function()
{
return this._list(0);
},

values: function()
{
return this._list(1);
},


_list: function(index)
{
var result = new Array(this._size);
var i = 0;
for (var objectIdentifier in this._map)
result[i++] = this._map[objectIdentifier][index];
return result;
},


get: function(key)
{
var entry = this._map[key.__identifier];
return entry ? entry[1] : undefined;
},

size: function()
{
return this._size;
},

clear: function()
{
this._map = {};
this._size = 0;
}
}

function loadXHR(url, async, callback) 
{
function onReadyStateChanged() 
{
if (xhr.readyState !== XMLHttpRequest.DONE)
return;

if (xhr.status === 200) {
callback(xhr.responseText);
return;
}

callback(null); 
}

var xhr = new XMLHttpRequest();
xhr.open("GET", url, async);
if (async)
xhr.onreadystatechange = onReadyStateChanged;        
xhr.send(null);

if (!async) {
if (xhr.status === 200) 
return xhr.responseText;
return null;
}
return null;
}


function StringPool()
{
this.reset();
}

StringPool.prototype = {

intern: function(string)
{

if (string === "__proto__")
return "__proto__";
var result = this._strings[string];
if (result === undefined) {
this._strings[string] = string;
result = string;
}
return result;
},

reset: function()
{
this._strings = Object.create(null);
},


internObjectStrings: function(obj, depthLimit)
{
if (typeof depthLimit !== "number")
depthLimit = 100;
else if (--depthLimit < 0)
throw "recursion depth limit reached in StringPool.deepIntern(), perhaps attempting to traverse cyclical references?";

for (var field in obj) {
switch (typeof obj[field]) {
case "string":
obj[field] = this.intern(obj[field]);
break;
case "object":
this.internObjectStrings(obj[field], depthLimit);
break;
}
}
}
}

var _importedScripts = {};


function importScript(scriptName)
{
if (_importedScripts[scriptName])
return;
_importedScripts[scriptName] = true;
var xhr = new XMLHttpRequest();
xhr.open("GET", scriptName, false);
xhr.send(null);
window.eval(xhr.responseText + "\n//@ sourceURL=" + scriptName);
}







__whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true};

difflib = {
defaultJunkFunction: function (c) {
return __whitespace.hasOwnProperty(c);
},

stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); },

stringAsLines: function (str) {
var lfpos = str.indexOf("\n");
var crpos = str.indexOf("\r");
var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r";

var lines = str.split(linebreak);
for (var i = 0; i < lines.length; i++) {
lines[i] = difflib.stripLinebreaks(lines[i]);
}

return lines;
},


__reduce: function (func, list, initial) {
if (initial != null) {
var value = initial;
var idx = 0;
} else if (list) {
var value = list[0];
var idx = 1;
} else {
return null;
}

for (; idx < list.length; idx++) {
value = func(value, list[idx]);
}

return value;
},


__ntuplecomp: function (a, b) {
var mlen = Math.max(a.length, b.length);
for (var i = 0; i < mlen; i++) {
if (a[i] < b[i]) return -1;
if (a[i] > b[i]) return 1;
}

return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1);
},

__calculate_ratio: function (matches, length) {
return length ? 2.0 * matches / length : 1.0;
},




__isindict: function (dict) {
return function (key) { return dict.hasOwnProperty(key); };
},


__dictget: function (dict, key, defaultValue) {
return dict.hasOwnProperty(key) ? dict[key] : defaultValue;
},  

SequenceMatcher: function (a, b, isjunk) {
this.set_seqs = function (a, b) {
this.set_seq1(a);
this.set_seq2(b);
}

this.set_seq1 = function (a) {
if (a == this.a) return;
this.a = a;
this.matching_blocks = this.opcodes = null;
}

this.set_seq2 = function (b) {
if (b == this.b) return;
this.b = b;
this.matching_blocks = this.opcodes = this.fullbcount = null;
this.__chain_b();
}

this.__chain_b = function () {
var b = this.b;
var n = b.length;
var b2j = this.b2j = {};
var populardict = {};
for (var i = 0; i < b.length; i++) {
var elt = b[i];
if (b2j.hasOwnProperty(elt)) {
var indices = b2j[elt];
if (n >= 200 && indices.length * 100 > n) {
populardict[elt] = 1;
delete b2j[elt];
} else {
indices.push(i);
}
} else {
b2j[elt] = [i];
}
}

for (var elt in populardict) {
if (populardict.hasOwnProperty(elt)) {
delete b2j[elt];
}
}

var isjunk = this.isjunk;
var junkdict = {};
if (isjunk) {
for (var elt in populardict) {
if (populardict.hasOwnProperty(elt) && isjunk(elt)) {
junkdict[elt] = 1;
delete populardict[elt];
}
}
for (var elt in b2j) {
if (b2j.hasOwnProperty(elt) && isjunk(elt)) {
junkdict[elt] = 1;
delete b2j[elt];
}
}
}

this.isbjunk = difflib.__isindict(junkdict);
this.isbpopular = difflib.__isindict(populardict);
}

this.find_longest_match = function (alo, ahi, blo, bhi) {
var a = this.a;
var b = this.b;
var b2j = this.b2j;
var isbjunk = this.isbjunk;
var besti = alo;
var bestj = blo;
var bestsize = 0;
var j = null;

var j2len = {};
var nothing = [];
for (var i = alo; i < ahi; i++) {
var newj2len = {};
var jdict = difflib.__dictget(b2j, a[i], nothing);
for (var jkey in jdict) {
if (jdict.hasOwnProperty(jkey)) {
j = jdict[jkey];
if (j < blo) continue;
if (j >= bhi) break;
newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1;
if (k > bestsize) {
besti = i - k + 1;
bestj = j - k + 1;
bestsize = k;
}
}
}
j2len = newj2len;
}

while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
besti--;
bestj--;
bestsize++;
}

while (besti + bestsize < ahi && bestj + bestsize < bhi &&
!isbjunk(b[bestj + bestsize]) &&
a[besti + bestsize] == b[bestj + bestsize]) {
bestsize++;
}

while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
besti--;
bestj--;
bestsize++;
}

while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) &&
a[besti + bestsize] == b[bestj + bestsize]) {
bestsize++;
}

return [besti, bestj, bestsize];
}

this.get_matching_blocks = function () {
if (this.matching_blocks != null) return this.matching_blocks;
var la = this.a.length;
var lb = this.b.length;

var queue = [[0, la, 0, lb]];
var matching_blocks = [];
var alo, ahi, blo, bhi, qi, i, j, k, x;
while (queue.length) {
qi = queue.pop();
alo = qi[0];
ahi = qi[1];
blo = qi[2];
bhi = qi[3];
x = this.find_longest_match(alo, ahi, blo, bhi);
i = x[0];
j = x[1];
k = x[2];

if (k) {
matching_blocks.push(x);
if (alo < i && blo < j)
queue.push([alo, i, blo, j]);
if (i+k < ahi && j+k < bhi)
queue.push([i + k, ahi, j + k, bhi]);
}
}

matching_blocks.sort(difflib.__ntuplecomp);

var i1 = j1 = k1 = block = 0;
var non_adjacent = [];
for (var idx in matching_blocks) {
if (matching_blocks.hasOwnProperty(idx)) {
block = matching_blocks[idx];
i2 = block[0];
j2 = block[1];
k2 = block[2];
if (i1 + k1 == i2 && j1 + k1 == j2) {
k1 += k2;
} else {
if (k1) non_adjacent.push([i1, j1, k1]);
i1 = i2;
j1 = j2;
k1 = k2;
}
}
}

if (k1) non_adjacent.push([i1, j1, k1]);

non_adjacent.push([la, lb, 0]);
this.matching_blocks = non_adjacent;
return this.matching_blocks;
}

this.get_opcodes = function () {
if (this.opcodes != null) return this.opcodes;
var i = 0;
var j = 0;
var answer = [];
this.opcodes = answer;
var block, ai, bj, size, tag;
var blocks = this.get_matching_blocks();
for (var idx in blocks) {
if (blocks.hasOwnProperty(idx)) {
block = blocks[idx];
ai = block[0];
bj = block[1];
size = block[2];
tag = '';
if (i < ai && j < bj) {
tag = 'replace';
} else if (i < ai) {
tag = 'delete';
} else if (j < bj) {
tag = 'insert';
}
if (tag) answer.push([tag, i, ai, j, bj]);
i = ai + size;
j = bj + size;

if (size) answer.push(['equal', ai, i, bj, j]);
}
}

return answer;
}



this.get_grouped_opcodes = function (n) {
if (!n) n = 3;
var codes = this.get_opcodes();
if (!codes) codes = [["equal", 0, 1, 0, 1]];
var code, tag, i1, i2, j1, j2;
if (codes[0][0] == 'equal') {
code = codes[0];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2];
}
if (codes[codes.length - 1][0] == 'equal') {
code = codes[codes.length - 1];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)];
}

var nn = n + n;
var groups = [];
for (var idx in codes) {
if (codes.hasOwnProperty(idx)) {
code = codes[idx];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
if (tag == 'equal' && i2 - i1 > nn) {
groups.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]);
i1 = Math.max(i1, i2-n);
j1 = Math.max(j1, j2-n);
}

groups.push([tag, i1, i2, j1, j2]);
}
}

if (groups && groups[groups.length - 1][0] == 'equal') groups.pop();

return groups;
}

this.ratio = function () {
matches = difflib.__reduce(
function (sum, triple) { return sum + triple[triple.length - 1]; },
this.get_matching_blocks(), 0);
return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
}

this.quick_ratio = function () {
var fullbcount, elt;
if (this.fullbcount == null) {
this.fullbcount = fullbcount = {};
for (var i = 0; i < this.b.length; i++) {
elt = this.b[i];
fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1;
}
}
fullbcount = this.fullbcount;

var avail = {};
var availhas = difflib.__isindict(avail);
var matches = numb = 0;
for (var i = 0; i < this.a.length; i++) {
elt = this.a[i];
if (availhas(elt)) {
numb = avail[elt];
} else {
numb = difflib.__dictget(fullbcount, elt, 0);
}
avail[elt] = numb - 1;
if (numb > 0) matches++;
}

return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
}

this.real_quick_ratio = function () {
var la = this.a.length;
var lb = this.b.length;
return _calculate_ratio(Math.min(la, lb), la + lb);
}

this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction;
this.a = this.b = null;
this.set_seqs(a, b);
}
}






Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
{
var startNode;
var startOffset = 0;
var endNode;
var endOffset = 0;

if (!stayWithinNode)
stayWithinNode = this;

if (!direction || direction === "backward" || direction === "both") {
var node = this;
while (node) {
if (node === stayWithinNode) {
if (!startNode)
startNode = stayWithinNode;
break;
}

if (node.nodeType === Node.TEXT_NODE) {
var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
for (var i = start; i >= 0; --i) {
if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
startNode = node;
startOffset = i + 1;
break;
}
}
}

if (startNode)
break;

node = node.traversePreviousNode(stayWithinNode);
}

if (!startNode) {
startNode = stayWithinNode;
startOffset = 0;
}
} else {
startNode = this;
startOffset = offset;
}

if (!direction || direction === "forward" || direction === "both") {
node = this;
while (node) {
if (node === stayWithinNode) {
if (!endNode)
endNode = stayWithinNode;
break;
}

if (node.nodeType === Node.TEXT_NODE) {
var start = (node === this ? offset : 0);
for (var i = start; i < node.nodeValue.length; ++i) {
if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
endNode = node;
endOffset = i;
break;
}
}
}

if (endNode)
break;

node = node.traverseNextNode(stayWithinNode);
}

if (!endNode) {
endNode = stayWithinNode;
endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length;
}
} else {
endNode = this;
endOffset = offset;
}

var result = this.ownerDocument.createRange();
result.setStart(startNode, startOffset);
result.setEnd(endNode, endOffset);

return result;
}

Node.prototype.traverseNextTextNode = function(stayWithin)
{
var node = this.traverseNextNode(stayWithin);
if (!node)
return;

while (node && node.nodeType !== Node.TEXT_NODE)
node = node.traverseNextNode(stayWithin);

return node;
}

Node.prototype.rangeBoundaryForOffset = function(offset)
{
var node = this.traverseNextTextNode(this);
while (node && offset > node.nodeValue.length) {
offset -= node.nodeValue.length;
node = node.traverseNextTextNode(this);
}
if (!node)
return { container: this, offset: 0 };
return { container: node, offset: offset };
}

Element.prototype.removeStyleClass = function(className)
{
this.classList.remove(className);
}

Element.prototype.removeMatchingStyleClasses = function(classNameRegex)
{
var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)");
if (regex.test(this.className))
this.className = this.className.replace(regex, " ");
}

Element.prototype.addStyleClass = function(className)
{
this.classList.add(className);
}

Element.prototype.hasStyleClass = function(className)
{
return this.classList.contains(className);
}

Element.prototype.positionAt = function(x, y)
{
this.style.left = x + "px";
this.style.top = y + "px";
}

Element.prototype.pruneEmptyTextNodes = function()
{
var sibling = this.firstChild;
while (sibling) {
var nextSibling = sibling.nextSibling;
if (sibling.nodeType === this.TEXT_NODE && sibling.nodeValue === "")
this.removeChild(sibling);
sibling = nextSibling;
}
}

Element.prototype.isScrolledToBottom = function()
{

return this.scrollTop + this.clientHeight === this.scrollHeight;
}

Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
{
for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
for (var i = 0; i < nameArray.length; ++i)
if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
return node;
return null;
}

Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
{
return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
}

Node.prototype.enclosingNodeOrSelfWithClass = function(className)
{
for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className))
return node;
return null;
}

Node.prototype.enclosingNodeWithClass = function(className)
{
if (!this.parentNode)
return null;
return this.parentNode.enclosingNodeOrSelfWithClass(className);
}

Element.prototype.query = function(query)
{
return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

Element.prototype.removeChildren = function()
{
if (this.firstChild)
this.textContent = "";
}

Element.prototype.isInsertionCaretInside = function()
{
var selection = window.getSelection();
if (!selection.rangeCount || !selection.isCollapsed)
return false;
var selectionRange = selection.getRangeAt(0);
return selectionRange.startContainer.isSelfOrDescendant(this);
}


Element.prototype.createChild = function(elementName, className)
{
var element = this.ownerDocument.createElement(elementName);
if (className)
element.className = className;
this.appendChild(element);
return element;
}

DocumentFragment.prototype.createChild = Element.prototype.createChild;


Element.prototype.createTextChild = function(text)
{
var element = this.ownerDocument.createTextNode(text);
this.appendChild(element);
return element;
}

DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild;


Element.prototype.totalOffsetLeft = function()
{
return this.totalOffset().left;
}


Element.prototype.totalOffsetTop = function()
{
return this.totalOffset().top;

}

Element.prototype.totalOffset = function()
{
var totalLeft = 0;
var totalTop = 0;

for (var element = this; element; element = element.offsetParent) {
totalLeft += element.offsetLeft;
totalTop += element.offsetTop;
if (this !== element) {
totalLeft += element.clientLeft - element.scrollLeft;
totalTop += element.clientTop - element.scrollTop;
}
}

return { left: totalLeft, top: totalTop };
}

Element.prototype.scrollOffset = function()
{
var curLeft = 0;
var curTop = 0;
for (var element = this; element; element = element.scrollParent) {
curLeft += element.scrollLeft;
curTop += element.scrollTop;
}
return { left: curLeft, top: curTop };
}


function AnchorBox(x, y, width, height)
{
this.x = x || 0;
this.y = y || 0;
this.width = width || 0;
this.height = height || 0;
}


Element.prototype.offsetRelativeToWindow = function(targetWindow)
{
var elementOffset = new AnchorBox();
var curElement = this;
var curWindow = this.ownerDocument.defaultView;
while (curWindow && curElement) {
elementOffset.x += curElement.totalOffsetLeft();
elementOffset.y += curElement.totalOffsetTop();
if (curWindow === targetWindow)
break;

curElement = curWindow.frameElement;
curWindow = curWindow.parent;
}

return elementOffset;
}


Element.prototype.boxInWindow = function(targetWindow)
{
targetWindow = targetWindow || this.ownerDocument.defaultView;

var anchorBox = this.offsetRelativeToWindow(window);
anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x);
anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBox.y);

return anchorBox;
}


Element.prototype.setTextAndTitle = function(text)
{
this.textContent = text;
this.title = text;
}

KeyboardEvent.prototype.__defineGetter__("data", function()
{


switch (this.type) {
case "keypress":
if (!this.ctrlKey && !this.metaKey)
return String.fromCharCode(this.charCode);
else
return "";
case "keydown":
case "keyup":
if (!this.ctrlKey && !this.metaKey && !this.altKey)
return String.fromCharCode(this.which);
else
return "";
}
});


Event.prototype.consume = function(preventDefault)
{
this.stopImmediatePropagation();
if (preventDefault)
this.preventDefault();
this.handled = true;
}

Text.prototype.select = function(start, end)
{
start = start || 0;
end = end || this.textContent.length;

if (start < 0)
start = end + start;

var selection = this.ownerDocument.defaultView.getSelection();
selection.removeAllRanges();
var range = this.ownerDocument.createRange();
range.setStart(this, start);
range.setEnd(this, end);
selection.addRange(range);
return this;
}

Element.prototype.selectionLeftOffset = function()
{


var selection = window.getSelection();
if (!selection.containsNode(this, true))
return null;

var leftOffset = selection.anchorOffset;
var node = selection.anchorNode;

while (node !== this) {
while (node.previousSibling) {
node = node.previousSibling;
leftOffset += node.textContent.length;
}
node = node.parentNode;
}

return leftOffset;
}

Node.prototype.isAncestor = function(node)
{
if (!node)
return false;

var currentNode = node.parentNode;
while (currentNode) {
if (this === currentNode)
return true;
currentNode = currentNode.parentNode;
}
return false;
}

Node.prototype.isDescendant = function(descendant)
{
return !!descendant && descendant.isAncestor(this);
}

Node.prototype.isSelfOrAncestor = function(node)
{
return !!node && (node === this || this.isAncestor(node));
}

Node.prototype.isSelfOrDescendant = function(node)
{
return !!node && (node === this || this.isDescendant(node));
}

Node.prototype.traverseNextNode = function(stayWithin)
{
var node = this.firstChild;
if (node)
return node;

if (stayWithin && this === stayWithin)
return null;

node = this.nextSibling;
if (node)
return node;

node = this;
while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin))
node = node.parentNode;
if (!node)
return null;

return node.nextSibling;
}

Node.prototype.traversePreviousNode = function(stayWithin)
{
if (stayWithin && this === stayWithin)
return null;
var node = this.previousSibling;
while (node && node.lastChild)
node = node.lastChild;
if (node)
return node;
return this.parentNode;
}

HTMLTextAreaElement.prototype.moveCursorToEnd = function()
{
var length = this.value.length;
this.setSelectionRange(length, length);
}

function isEnterKey(event) {

return event.keyCode !== 229 && event.keyIdentifier === "Enter";
}

function consumeEvent(e)
{
e.consume();
}






function TreeOutline(listNode, nonFocusable)
{

this.children = [];
this.selectedTreeElement = null;
this._childrenListNode = listNode;
this.childrenListElement = this._childrenListNode;
this._childrenListNode.removeChildren();
this.expandTreeElementsWhenArrowing = false;
this.root = true;
this.hasChildren = false;
this.expanded = true;
this.selected = false;
this.treeOutline = this;
this.comparator = null;
this.searchable = false;
this.searchInputElement = null;

this.setFocusable(!nonFocusable);
this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true);
this._childrenListNode.addEventListener("keypress", this._treeKeyPress.bind(this), true);

this._treeElementsMap = new Map();
this._expandedStateMap = new Map();
}

TreeOutline.prototype.setFocusable = function(focusable)
{
if (focusable)
this._childrenListNode.setAttribute("tabIndex", 0);
else
this._childrenListNode.removeAttribute("tabIndex");
}

TreeOutline.prototype.appendChild = function(child)
{
var insertionIndex;
if (this.treeOutline.comparator)
insertionIndex = insertionIndexForObjectInListSortedByFunction(child, this.children, this.treeOutline.comparator);
else
insertionIndex = this.children.length;
this.insertChild(child, insertionIndex);
}

TreeOutline.prototype.insertChild = function(child, index)
{
if (!child)
throw("child can't be undefined or null");

var previousChild = (index > 0 ? this.children[index - 1] : null);
if (previousChild) {
previousChild.nextSibling = child;
child.previousSibling = previousChild;
} else {
child.previousSibling = null;
}

var nextChild = this.children[index];
if (nextChild) {
nextChild.previousSibling = child;
child.nextSibling = nextChild;
} else {
child.nextSibling = null;
}

this.children.splice(index, 0, child);
this.hasChildren = true;
child.parent = this;
child.treeOutline = this.treeOutline;
child.treeOutline._rememberTreeElement(child);

var current = child.children[0];
while (current) {
current.treeOutline = this.treeOutline;
current.treeOutline._rememberTreeElement(current);
current = current.traverseNextTreeElement(false, child, true);
}

if (child.hasChildren && typeof(child.treeOutline._expandedStateMap.get(child.representedObject)) !== "undefined")
child.expanded = child.treeOutline._expandedStateMap.get(child.representedObject);

if (!this._childrenListNode) {
this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
this._childrenListNode.parentTreeElement = this;
this._childrenListNode.classList.add("children");
if (this.hidden)
this._childrenListNode.classList.add("hidden");
}

child._attach();
}

TreeOutline.prototype.removeChildAtIndex = function(childIndex)
{
if (childIndex < 0 || childIndex >= this.children.length)
throw("childIndex out of range");

var child = this.children[childIndex];
this.children.splice(childIndex, 1);

var parent = child.parent;
if (child.deselect()) {
if (child.previousSibling)
child.previousSibling.select();
else if (child.nextSibling)
child.nextSibling.select();
else
parent.select();
}

if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;

if (child.treeOutline) {
child.treeOutline._forgetTreeElement(child);
child.treeOutline._forgetChildrenRecursive(child);
}

child._detach();
child.treeOutline = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}

TreeOutline.prototype.removeChild = function(child)
{
if (!child)
throw("child can't be undefined or null");

var childIndex = this.children.indexOf(child);
if (childIndex === -1)
throw("child not found in this node's children");

this.removeChildAtIndex.call(this, childIndex);
}

TreeOutline.prototype.removeChildren = function()
{
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
child.deselect();

if (child.treeOutline) {
child.treeOutline._forgetTreeElement(child);
child.treeOutline._forgetChildrenRecursive(child);
}

child._detach();
child.treeOutline = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}

this.children = [];
}

TreeOutline.prototype._rememberTreeElement = function(element)
{
if (!this._treeElementsMap.get(element.representedObject))
this._treeElementsMap.put(element.representedObject, []);


var elements = this._treeElementsMap.get(element.representedObject);
if (elements.indexOf(element) !== -1)
return;


elements.push(element);
}

TreeOutline.prototype._forgetTreeElement = function(element)
{
if (this._treeElementsMap.get(element.representedObject))
this._treeElementsMap.get(element.representedObject).remove(element, true);
}

TreeOutline.prototype._forgetChildrenRecursive = function(parentElement)
{
var child = parentElement.children[0];
while (child) {
this._forgetTreeElement(child);
child = child.traverseNextTreeElement(false, parentElement, true);
}
}

TreeOutline.prototype.getCachedTreeElement = function(representedObject)
{
if (!representedObject)
return null;

var elements = this._treeElementsMap.get(representedObject);
if (elements && elements.length)
return elements[0];
return null;
}

TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent)
{
if (!representedObject)
return null;

var cachedElement = this.getCachedTreeElement(representedObject);
if (cachedElement)
return cachedElement;



var item;
var found = false;
for (var i = 0; i < this.children.length; ++i) {
item = this.children[i];
if (item.representedObject === representedObject || isAncestor(item.representedObject, representedObject)) {
found = true;
break;
}
}

if (!found)
return null;



var ancestors = [];
var currentObject = representedObject;
while (currentObject) {
ancestors.unshift(currentObject);
if (currentObject === item.representedObject)
break;
currentObject = getParent(currentObject);
}


for (var i = 0; i < ancestors.length; ++i) {


if (ancestors[i] === representedObject)
continue;


item = this.findTreeElement(ancestors[i], isAncestor, getParent);
if (item)
item.onpopulate();
}

return this.getCachedTreeElement(representedObject);
}

TreeOutline.prototype.treeElementFromPoint = function(x, y)
{
var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
if (!node)
return null;

var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
if (listNode)
return listNode.parentTreeElement || listNode.treeElement;
return null;
}

TreeOutline.prototype._treeKeyPress = function(event)
{
if (!this.searchable || WebInspector.isBeingEdited(this._childrenListNode))
return;

var searchText = String.fromCharCode(event.charCode);

if (searchText.trim() !== searchText)
return;

this._startSearch(searchText);
event.consume(true);
}

TreeOutline.prototype._treeKeyDown = function(event)
{
if (event.target !== this._childrenListNode)
return;

if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
return;

var handled = false;
var nextSelectedElement;
if (event.keyIdentifier === "Up" && !event.altKey) {
nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
handled = nextSelectedElement ? true : false;
} else if (event.keyIdentifier === "Down" && !event.altKey) {
nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
handled = nextSelectedElement ? true : false;
} else if (event.keyIdentifier === "Left") {
if (this.selectedTreeElement.expanded) {
if (event.altKey)
this.selectedTreeElement.collapseRecursively();
else
this.selectedTreeElement.collapse();
handled = true;
} else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
handled = true;
if (this.selectedTreeElement.parent.selectable) {
nextSelectedElement = this.selectedTreeElement.parent;
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.parent;
handled = nextSelectedElement ? true : false;
} else if (this.selectedTreeElement.parent)
this.selectedTreeElement.parent.collapse();
}
} else if (event.keyIdentifier === "Right") {
if (!this.selectedTreeElement.revealed()) {
this.selectedTreeElement.reveal();
handled = true;
} else if (this.selectedTreeElement.hasChildren) {
handled = true;
if (this.selectedTreeElement.expanded) {
nextSelectedElement = this.selectedTreeElement.children[0];
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.nextSibling;
handled = nextSelectedElement ? true : false;
} else {
if (event.altKey)
this.selectedTreeElement.expandRecursively();
else
this.selectedTreeElement.expand();
}
}
} else if (event.keyCode === 8   || event.keyCode === 46  )
handled = this.selectedTreeElement.ondelete();
else if (isEnterKey(event))
handled = this.selectedTreeElement.onenter();
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
handled = this.selectedTreeElement.onspace();

if (nextSelectedElement) {
nextSelectedElement.reveal();
nextSelectedElement.select(false, true);
}

if (handled)
event.consume(true);
}

TreeOutline.prototype.expand = function()
{

}

TreeOutline.prototype.collapse = function()
{

}

TreeOutline.prototype.revealed = function()
{
return true;
}

TreeOutline.prototype.reveal = function()
{

}

TreeOutline.prototype.select = function()
{

}


TreeOutline.prototype.revealAndSelect = function(omitFocus)
{

}


TreeOutline.prototype._startSearch = function(searchText)
{
if (!this.searchInputElement || !this.searchable)
return;

this._searching = true;

if (this.searchStarted)
this.searchStarted();

this.searchInputElement.value = searchText;

function focusSearchInput()
{
this.searchInputElement.focus();
}
window.setTimeout(focusSearchInput.bind(this), 0);
this._searchTextChanged();
this._boundSearchTextChanged = this._searchTextChanged.bind(this);
this.searchInputElement.addEventListener("paste", this._boundSearchTextChanged);
this.searchInputElement.addEventListener("cut", this._boundSearchTextChanged);
this.searchInputElement.addEventListener("keypress", this._boundSearchTextChanged);
this._boundSearchInputKeyDown = this._searchInputKeyDown.bind(this);
this.searchInputElement.addEventListener("keydown", this._boundSearchInputKeyDown);
this._boundSearchInputBlur = this._searchInputBlur.bind(this);
this.searchInputElement.addEventListener("blur", this._boundSearchInputBlur);
}

TreeOutline.prototype._searchTextChanged = function()
{
function updateSearch()
{
var nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, false);
if (!nextSelectedElement)
nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.children[0], false);
this._showSearchMatchElement(nextSelectedElement);
}

window.setTimeout(updateSearch.bind(this), 0);
}

TreeOutline.prototype._showSearchMatchElement = function(treeElement)
{
this._currentSearchMatchElement = treeElement;
if (treeElement) {
this._childrenListNode.classList.add("search-match-found");
this._childrenListNode.classList.remove("search-match-not-found");
treeElement.revealAndSelect(true);
} else {
this._childrenListNode.classList.remove("search-match-found");
this._childrenListNode.classList.add("search-match-not-found");
}
}

TreeOutline.prototype._searchInputKeyDown = function(event)
{
if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey)
return;

var handled = false;
var nextSelectedElement;
if (event.keyIdentifier === "Down") {
nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, true);
handled = true;
} else if (event.keyIdentifier === "Up") {
nextSelectedElement = this._previousSearchMatch(this.searchInputElement.value, this.selectedTreeElement);
handled = true;
} else if (event.keyCode === 27  ) {
this._searchFinished();
handled = true;
} else if (isEnterKey(event)) {
var lastSearchMatchElement = this._currentSearchMatchElement;
this._searchFinished();
lastSearchMatchElement.onenter();
handled = true;
}

if (nextSelectedElement)
this._showSearchMatchElement(nextSelectedElement);

if (handled)
event.consume(true);
else
window.setTimeout(this._boundSearchTextChanged, 0); 
}


TreeOutline.prototype._nextSearchMatch = function(searchText, startTreeElement, skipStartTreeElement)
{
var currentTreeElement = startTreeElement;
var skipCurrentTreeElement = skipStartTreeElement;
while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) {
currentTreeElement = currentTreeElement.traverseNextTreeElement(true, null, true);
skipCurrentTreeElement = false;
}

return currentTreeElement;
}


TreeOutline.prototype._previousSearchMatch = function(searchText, startTreeElement)
{
var currentTreeElement = startTreeElement;
var skipCurrentTreeElement = true;
while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) {
currentTreeElement = currentTreeElement.traversePreviousTreeElement(true, true);
skipCurrentTreeElement = false;
}

return currentTreeElement;
}

TreeOutline.prototype._searchInputBlur = function(event)
{
this._searchFinished();
}

TreeOutline.prototype._searchFinished = function()
{
if (!this._searching)
return;

delete this._searching;
this._childrenListNode.classList.remove("search-match-found");
this._childrenListNode.classList.remove("search-match-not-found");
delete this._currentSearchMatchElement;

this.searchInputElement.value = "";
this.searchInputElement.removeEventListener("paste", this._boundSearchTextChanged);
this.searchInputElement.removeEventListener("cut", this._boundSearchTextChanged);
delete this._boundSearchTextChanged;

this.searchInputElement.removeEventListener("keydown", this._boundSearchInputKeyDown);
delete this._boundSearchInputKeyDown;

this.searchInputElement.removeEventListener("blur", this._boundSearchInputBlur);
delete this._boundSearchInputBlur;

if (this.searchFinished)
this.searchFinished();

this.treeOutline._childrenListNode.focus();
}

TreeOutline.prototype.stopSearch = function()
{
this._searchFinished();
}


function TreeElement(title, representedObject, hasChildren)
{
this._title = title;
this.representedObject = (representedObject || {});

this._hidden = false;
this._selectable = true;
this.expanded = false;
this.selected = false;
this.hasChildren = hasChildren;
this.children = [];
this.treeOutline = null;
this.parent = null;
this.previousSibling = null;
this.nextSibling = null;
this._listItemNode = null;
}

TreeElement.prototype = {
arrowToggleWidth: 10,

get selectable() {
if (this._hidden)
return false;
return this._selectable;
},

set selectable(x) {
this._selectable = x;
},

get listItemElement() {
return this._listItemNode;
},

get childrenListElement() {
return this._childrenListNode;
},

get title() {
return this._title;
},

set title(x) {
this._title = x;
this._setListItemNodeContent();
},

get tooltip() {
return this._tooltip;
},

set tooltip(x) {
this._tooltip = x;
if (this._listItemNode)
this._listItemNode.title = x ? x : "";
},

get hasChildren() {
return this._hasChildren;
},

set hasChildren(x) {
if (this._hasChildren === x)
return;

this._hasChildren = x;

if (!this._listItemNode)
return;

if (x)
this._listItemNode.classList.add("parent");
else {
this._listItemNode.classList.remove("parent");
this.collapse();
}
},

get hidden() {
return this._hidden;
},

set hidden(x) {
if (this._hidden === x)
return;

this._hidden = x;

if (x) {
if (this._listItemNode)
this._listItemNode.classList.add("hidden");
if (this._childrenListNode)
this._childrenListNode.classList.add("hidden");
} else {
if (this._listItemNode)
this._listItemNode.classList.remove("hidden");
if (this._childrenListNode)
this._childrenListNode.classList.remove("hidden");
}
},

get shouldRefreshChildren() {
return this._shouldRefreshChildren;
},

set shouldRefreshChildren(x) {
this._shouldRefreshChildren = x;
if (x && this.expanded)
this.expand();
},

_setListItemNodeContent: function()
{
if (!this._listItemNode)
return;

if (typeof this._title === "string")
this._listItemNode.textContent = this._title;
else {
this._listItemNode.removeChildren();
if (this._title)
this._listItemNode.appendChild(this._title);
}
}
}

TreeElement.prototype.appendChild = TreeOutline.prototype.appendChild;
TreeElement.prototype.insertChild = TreeOutline.prototype.insertChild;
TreeElement.prototype.removeChild = TreeOutline.prototype.removeChild;
TreeElement.prototype.removeChildAtIndex = TreeOutline.prototype.removeChildAtIndex;
TreeElement.prototype.removeChildren = TreeOutline.prototype.removeChildren;

TreeElement.prototype._attach = function()
{
if (!this._listItemNode || this.parent._shouldRefreshChildren) {
if (this._listItemNode && this._listItemNode.parentNode)
this._listItemNode.parentNode.removeChild(this._listItemNode);

this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li");
this._listItemNode.treeElement = this;
this._setListItemNodeContent();
this._listItemNode.title = this._tooltip ? this._tooltip : "";

if (this.hidden)
this._listItemNode.classList.add("hidden");
if (this.hasChildren)
this._listItemNode.classList.add("parent");
if (this.expanded)
this._listItemNode.classList.add("expanded");
if (this.selected)
this._listItemNode.classList.add("selected");

this._listItemNode.addEventListener("mousedown", TreeElement.treeElementMouseDown, false);
this._listItemNode.addEventListener("click", TreeElement.treeElementToggled, false);
this._listItemNode.addEventListener("dblclick", TreeElement.treeElementDoubleClicked, false);

this.onattach();
}

var nextSibling = null;
if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode)
nextSibling = this.nextSibling._listItemNode;
this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling);
if (this._childrenListNode)
this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
if (this.selected)
this.select();
if (this.expanded)
this.expand();
}

TreeElement.prototype._detach = function()
{
if (this._listItemNode && this._listItemNode.parentNode)
this._listItemNode.parentNode.removeChild(this._listItemNode);
if (this._childrenListNode && this._childrenListNode.parentNode)
this._childrenListNode.parentNode.removeChild(this._childrenListNode);
}

TreeElement.treeElementMouseDown = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement || !element.treeElement.selectable)
return;

if (element.treeElement.isEventWithinDisclosureTriangle(event))
return;

element.treeElement.selectOnMouseDown(event);
}

TreeElement.treeElementToggled = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement)
return;

var toggleOnClick = element.treeElement.toggleOnClick && !element.treeElement.selectable;
var isInTriangle = element.treeElement.isEventWithinDisclosureTriangle(event);
if (!toggleOnClick && !isInTriangle)
return;

if (element.treeElement.expanded) {
if (event.altKey)
element.treeElement.collapseRecursively();
else
element.treeElement.collapse();
} else {
if (event.altKey)
element.treeElement.expandRecursively();
else
element.treeElement.expand();
}
event.consume();
}

TreeElement.treeElementDoubleClicked = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement)
return;

var handled = element.treeElement.ondblclick.call(element.treeElement, event);
if (handled)
return;
if (element.treeElement.hasChildren && !element.treeElement.expanded)
element.treeElement.expand();
}

TreeElement.prototype.collapse = function()
{
if (this._listItemNode)
this._listItemNode.classList.remove("expanded");
if (this._childrenListNode)
this._childrenListNode.classList.remove("expanded");

this.expanded = false;

if (this.treeOutline)
this.treeOutline._expandedStateMap.put(this.representedObject, false);

this.oncollapse();
}

TreeElement.prototype.collapseRecursively = function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextTreeElement(false, this, true);
}
}

TreeElement.prototype.expand = function()
{
if (!this.hasChildren || (this.expanded && !this._shouldRefreshChildren && this._childrenListNode))
return;





this.expanded = true;
if (this.treeOutline)
this.treeOutline._expandedStateMap.put(this.representedObject, true);

if (this.treeOutline && (!this._childrenListNode || this._shouldRefreshChildren)) {
if (this._childrenListNode && this._childrenListNode.parentNode)
this._childrenListNode.parentNode.removeChild(this._childrenListNode);

this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
this._childrenListNode.parentTreeElement = this;
this._childrenListNode.classList.add("children");

if (this.hidden)
this._childrenListNode.classList.add("hidden");

this.onpopulate();

for (var i = 0; i < this.children.length; ++i)
this.children[i]._attach();

delete this._shouldRefreshChildren;
}

if (this._listItemNode) {
this._listItemNode.classList.add("expanded");
if (this._childrenListNode && this._childrenListNode.parentNode != this._listItemNode.parentNode)
this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
}

if (this._childrenListNode)
this._childrenListNode.classList.add("expanded");

this.onexpand();
}

TreeElement.prototype.expandRecursively = function(maxDepth)
{
var item = this;
var info = {};
var depth = 0;




if (typeof maxDepth === "undefined" || typeof maxDepth === "null")
maxDepth = 3;

while (item) {
if (depth < maxDepth)
item.expand();
item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
depth += info.depthChange;
}
}

TreeElement.prototype.hasAncestor = function(ancestor) {
if (!ancestor)
return false;

var currentNode = this.parent;
while (currentNode) {
if (ancestor === currentNode)
return true;
currentNode = currentNode.parent;
}

return false;
}

TreeElement.prototype.reveal = function()
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}

this.onreveal(this);
}

TreeElement.prototype.revealed = function()
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
return false;
currentAncestor = currentAncestor.parent;
}

return true;
}

TreeElement.prototype.selectOnMouseDown = function(event)
{
if (this.select(false, true))
event.consume(true);
}


TreeElement.prototype.select = function(omitFocus, selectedByUser)
{
if (!this.treeOutline || !this.selectable || this.selected)
return false;

if (this.treeOutline.selectedTreeElement)
this.treeOutline.selectedTreeElement.deselect();

this.selected = true;

if(!omitFocus)
this.treeOutline._childrenListNode.focus();


if (!this.treeOutline)
return false;
this.treeOutline.selectedTreeElement = this;
if (this._listItemNode)
this._listItemNode.classList.add("selected");

return this.onselect(selectedByUser);
}


TreeElement.prototype.revealAndSelect = function(omitFocus)
{
this.reveal();
this.select(omitFocus);
}


TreeElement.prototype.deselect = function(supressOnDeselect)
{
if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
return false;

this.selected = false;
this.treeOutline.selectedTreeElement = null;
if (this._listItemNode)
this._listItemNode.classList.remove("selected");
return true;
}


TreeElement.prototype.onpopulate = function() { }
TreeElement.prototype.onenter = function() { }
TreeElement.prototype.ondelete = function() { }
TreeElement.prototype.onspace = function() { }
TreeElement.prototype.onattach = function() { }
TreeElement.prototype.onexpand = function() { }
TreeElement.prototype.oncollapse = function() { }
TreeElement.prototype.ondblclick = function() { }
TreeElement.prototype.onreveal = function() { }

TreeElement.prototype.onselect = function(selectedByUser) { }


TreeElement.prototype.traverseNextTreeElement = function(skipUnrevealed, stayWithin, dontPopulate, info)
{
if (!dontPopulate && this.hasChildren)
this.onpopulate();

if (info)
info.depthChange = 0;

var element = skipUnrevealed ? (this.revealed() ? this.children[0] : null) : this.children[0];
if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) {
if (info)
info.depthChange = 1;
return element;
}

if (this === stayWithin)
return null;

element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
if (element)
return element;

element = this;
while (element && !element.root && !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) {
if (info)
info.depthChange -= 1;
element = element.parent;
}

if (!element)
return null;

return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
}


TreeElement.prototype.traversePreviousTreeElement = function(skipUnrevealed, dontPopulate)
{
var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
if (!dontPopulate && element && element.hasChildren)
element.onpopulate();

while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
if (!dontPopulate && element.hasChildren)
element.onpopulate();
element = (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]);
}

if (element)
return element;

if (!this.parent || this.parent.root)
return null;

return this.parent;
}

TreeElement.prototype.isEventWithinDisclosureTriangle = function(event)
{

var paddingLeftValue = window.getComputedStyle(this._listItemNode).getPropertyCSSValue("padding-left");
var computedLeftPadding = paddingLeftValue ? paddingLeftValue.getFloatValue(CSSPrimitiveValue.CSS_PX) : 0;
var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding;
return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
}





var WebInspector = {
_panelDescriptors: function()
{
this.panels = {};
WebInspector.inspectorView = new WebInspector.InspectorView();
var parentElement = document.getElementById("main");
WebInspector.inspectorView.show(parentElement);
WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, this._panelSelected, this);

var elements = new WebInspector.ElementsPanelDescriptor();
var resources = new WebInspector.PanelDescriptor("resources", WebInspector.UIString("Resources"), "ResourcesPanel", "ResourcesPanel.js");
var network = new WebInspector.NetworkPanelDescriptor();
var scripts = new WebInspector.ScriptsPanelDescriptor();
var timeline = new WebInspector.PanelDescriptor("timeline", WebInspector.UIString("Timeline"), "TimelinePanel", "TimelinePanel.js");
var profiles = new WebInspector.PanelDescriptor("profiles", WebInspector.UIString("Profiles"), "ProfilesPanel", "ProfilesPanel.js");
var audits = new WebInspector.PanelDescriptor("audits", WebInspector.UIString("Audits"), "AuditsPanel", "AuditsPanel.js");
var console = new WebInspector.PanelDescriptor("console", WebInspector.UIString("Console"), "ConsolePanel");
var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console];

var panelDescriptors = [];
if (WebInspector.WorkerManager.isWorkerFrontend()) {
panelDescriptors.push(scripts);
panelDescriptors.push(timeline);
panelDescriptors.push(profiles);
panelDescriptors.push(console);
return panelDescriptors;
}
var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console];
var hiddenPanels = InspectorFrontendHost.hiddenPanels();
for (var i = 0; i < allDescriptors.length; ++i) {
if (hiddenPanels.indexOf(allDescriptors[i].name()) === -1)
panelDescriptors.push(allDescriptors[i]);
}
return panelDescriptors;
},

_panelSelected: function()
{
this._toggleConsoleButton.disabled = WebInspector.inspectorView.currentPanel().name === "console";
},

_createGlobalStatusBarItems: function()
{
var bottomStatusBarContainer = document.getElementById("bottom-status-bar-container");
this._dockToggleButton = new WebInspector.StatusBarButton("", "dock-status-bar-item", 3);
this._dockToggleButton.makeLongClickEnabled(this._createDockOptions.bind(this));
this._dockToggleButton.addEventListener("click", this._toggleAttach.bind(this), false);
this._updateDockButtonState();

var mainStatusBar = document.getElementById("main-status-bar");
mainStatusBar.insertBefore(this._dockToggleButton.element, bottomStatusBarContainer);

this._toggleConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show console."), "console-status-bar-item");
this._toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);
mainStatusBar.insertBefore(this._toggleConsoleButton.element, bottomStatusBarContainer);

if (!WebInspector.WorkerManager.isWorkerFrontend()) {
this._nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
this._nodeSearchButton.addEventListener("click", this.toggleSearchingForNode, this);
mainStatusBar.insertBefore(this._nodeSearchButton.element, bottomStatusBarContainer);
}

mainStatusBar.appendChild(this.settingsController.statusBarItem);
},

_createDockOptions: function()
{
var alternateDockToggleButton1 = new WebInspector.StatusBarButton("Dock to main window.", "dock-status-bar-item", 3);
var alternateDockToggleButton2 = new WebInspector.StatusBarButton("Undock into separate window.", "dock-status-bar-item", 3);

if (this.attached) {
alternateDockToggleButton1.state = WebInspector.settings.dockToRight.get() ? "bottom" : "right";
alternateDockToggleButton2.state = "undock";
} else {
alternateDockToggleButton1.state = WebInspector.settings.dockToRight.get() ? "bottom" : "right";
alternateDockToggleButton2.state = WebInspector.settings.dockToRight.get() ? "right" : "bottom";
}

alternateDockToggleButton1.addEventListener("click", onClick.bind(this), false);
alternateDockToggleButton2.addEventListener("click", onClick.bind(this), false);

function onClick(e)
{
var state = e.target.state;
if (state === "undock")
this._toggleAttach();
else if (state === "right") {
if (!this.attached)
this._toggleAttach();
WebInspector.settings.dockToRight.set(true);
} else if (state === "bottom") {
if (!this.attached)
this._toggleAttach();
WebInspector.settings.dockToRight.set(false);
}
}

return [alternateDockToggleButton1, alternateDockToggleButton2];
},

_updateDockButtonState: function()
{
if (!this._dockToggleButton)
return;

if (this.attached) {
this._dockToggleButton.disabled = false;
this._dockToggleButton.state = "undock";
this._dockToggleButton.title = WebInspector.UIString("Undock into separate window.");
} else {
this._dockToggleButton.disabled = this._isDockingUnavailable;
this._dockToggleButton.state = WebInspector.settings.dockToRight.get() ? "right" : "bottom";
this._dockToggleButton.title = WebInspector.UIString("Dock to main window.");
}
},

_toggleAttach: function()
{
if (!this._attached) {
InspectorFrontendHost.requestAttachWindow();
WebInspector.userMetrics.WindowDocked.record();
} else {
InspectorFrontendHost.requestDetachWindow();
WebInspector.userMetrics.WindowUndocked.record();
}
},

_toggleConsoleButtonClicked: function()
{
if (this._toggleConsoleButton.disabled)
return;

this._toggleConsoleButton.toggled = !this._toggleConsoleButton.toggled;

var animationType = window.event && window.event.shiftKey ? WebInspector.Drawer.AnimationType.Slow : WebInspector.Drawer.AnimationType.Normal;
if (this._toggleConsoleButton.toggled) {
this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
this.drawer.show(this.consoleView, animationType);
this._consoleWasShown = true;
} else {
this._toggleConsoleButton.title = WebInspector.UIString("Show console.");
this.drawer.hide(animationType);
delete this._consoleWasShown;
}
},


showViewInDrawer: function(statusBarElement, view, onclose)
{
this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
this._toggleConsoleButton.toggled = false;
this._closePreviousDrawerView();

var drawerStatusBarHeader = document.createElement("div");
drawerStatusBarHeader.className = "drawer-header status-bar-item";
drawerStatusBarHeader.appendChild(statusBarElement);
drawerStatusBarHeader.onclose = onclose;

var closeButton = drawerStatusBarHeader.createChild("span");
closeButton.textContent = WebInspector.UIString("\u00D7");
closeButton.addStyleClass("drawer-header-close-button");
closeButton.addEventListener("click", this.closeViewInDrawer.bind(this), false);

document.getElementById("panel-status-bar").firstElementChild.appendChild(drawerStatusBarHeader);
this._drawerStatusBarHeader = drawerStatusBarHeader;
this.drawer.show(view, WebInspector.Drawer.AnimationType.Immediately);
},

closeViewInDrawer: function()
{
if (this._drawerStatusBarHeader) {
this._closePreviousDrawerView();


if (!this._consoleWasShown)
this.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
else
this._toggleConsoleButtonClicked();
}
},

_closePreviousDrawerView: function()
{
if (this._drawerStatusBarHeader) {
this._drawerStatusBarHeader.parentElement.removeChild(this._drawerStatusBarHeader);
if (this._drawerStatusBarHeader.onclose)
this._drawerStatusBarHeader.onclose();
delete this._drawerStatusBarHeader;
}
},

get attached()
{
return this._attached;
},

set attached(x)
{
if (this._attached === x)
return;

this._attached = x;

if (x)
document.body.removeStyleClass("detached");
else
document.body.addStyleClass("detached");

this._setCompactMode(x && !WebInspector.settings.dockToRight.get());
this._updateDockButtonState();
},

isCompactMode: function()
{
return this.attached && !WebInspector.settings.dockToRight.get();
},

_setCompactMode: function(x)
{
var body = document.body;
if (x)
body.addStyleClass("compact");
else
body.removeStyleClass("compact");
WebInspector.windowResize();
},

_updateErrorAndWarningCounts: function()
{
var errorWarningElement = document.getElementById("error-warning-count");
if (!errorWarningElement)
return;

var errors = WebInspector.console.errors;
var warnings = WebInspector.console.warnings;
if (!errors && !warnings) {
errorWarningElement.addStyleClass("hidden");
return;
}

errorWarningElement.removeStyleClass("hidden");

errorWarningElement.removeChildren();

if (errors) {
var errorImageElement = document.createElement("img");
errorImageElement.id = "error-count-img";
errorWarningElement.appendChild(errorImageElement);
var errorElement = document.createElement("span");
errorElement.id = "error-count";
errorElement.textContent = errors;
errorWarningElement.appendChild(errorElement);
}

if (warnings) {
var warningsImageElement = document.createElement("img");
warningsImageElement.id = "warning-count-img";
errorWarningElement.appendChild(warningsImageElement);
var warningsElement = document.createElement("span");
warningsElement.id = "warning-count";
warningsElement.textContent = warnings;
errorWarningElement.appendChild(warningsElement);
}

if (errors) {
if (warnings) {
if (errors == 1) {
if (warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d error, %d warning", errors, warnings);
else
errorWarningElement.title = WebInspector.UIString("%d error, %d warnings", errors, warnings);
} else if (warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d errors, %d warning", errors, warnings);
else
errorWarningElement.title = WebInspector.UIString("%d errors, %d warnings", errors, warnings);
} else if (errors == 1)
errorWarningElement.title = WebInspector.UIString("%d error", errors);
else
errorWarningElement.title = WebInspector.UIString("%d errors", errors);
} else if (warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d warning", warnings);
else if (warnings)
errorWarningElement.title = WebInspector.UIString("%d warnings", warnings);
else
errorWarningElement.title = null;
},

get inspectedPageDomain()
{
var parsedURL = WebInspector.inspectedPageURL && WebInspector.inspectedPageURL.asParsedURL();
return parsedURL ? parsedURL.host : "";
},

_initializeCapability: function(name, callback, error, result)
{
Capabilities[name] = result;
if (callback)
callback();
},

_zoomIn: function()
{
++this._zoomLevel;
this._requestZoom();
},

_zoomOut: function()
{
--this._zoomLevel;
this._requestZoom();
},

_resetZoom: function()
{
this._zoomLevel = 0;
this._requestZoom();
},

_requestZoom: function()
{
WebInspector.settings.zoomLevel.set(this._zoomLevel);
InspectorFrontendHost.setZoomFactor(Math.pow(1.2, this._zoomLevel));
},

toggleSearchingForNode: function()
{
var enabled = !this._nodeSearchButton.toggled;

function callback(error)
{
if (!error)
this._nodeSearchButton.toggled = enabled;
}
WebInspector.domAgent.setInspectModeEnabled(enabled, callback.bind(this));
},

_profilesLinkifier: function(title)
{
var profileStringMatches = WebInspector.ProfileURLRegExp.exec(title);
if (profileStringMatches) {
var profilesPanel =   WebInspector.panel("profiles");
title = WebInspector.ProfilesPanel._instance.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]);
}
return title;
},

_debuggerPaused: function()
{

WebInspector.panel("scripts");
}
}

WebInspector.Events = {
InspectorClosing: "InspectorClosing"
}

{(function parseQueryParameters()
{
WebInspector.queryParamsObject = {};
var queryParams = window.location.search;
if (!queryParams)
return;
var params = queryParams.substring(1).split("&");
for (var i = 0; i < params.length; ++i) {
var pair = params[i].split("=");
WebInspector.queryParamsObject[pair[0]] = pair[1];
}
})();}

WebInspector.loaded = function()
{
InspectorBackend.loadFromJSONIfNeeded("../Inspector.json");

if (WebInspector.WorkerManager.isDedicatedWorkerFrontend()) {

WebInspector.doLoadedDone();
return;
}

var ws;
if ("ws" in WebInspector.queryParamsObject)
ws = "ws://" + WebInspector.queryParamsObject.ws;
else if ("page" in WebInspector.queryParamsObject) {
var page = WebInspector.queryParamsObject.page;
var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host;
ws = "ws://" + host + "/devtools/page/" + page;
}

if (ws) {
WebInspector.socket = new WebSocket(ws);
WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); }
WebInspector.socket.onerror = function(error) { console.error(error); }
WebInspector.socket.onopen = function() {
InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket);
WebInspector.doLoadedDone();
}
return;
}

WebInspector.doLoadedDone();


if (InspectorFrontendHost.isStub) {
InspectorFrontendAPI.dispatchQueryParameters();
WebInspector._doLoadedDoneWithCapabilities();
}
}

WebInspector.doLoadedDone = function()
{

WebInspector.installPortStyles();
if (WebInspector.socket)
document.body.addStyleClass("remote");

if (WebInspector.queryParamsObject.toolbarColor && WebInspector.queryParamsObject.textColor)
WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbarColor, WebInspector.queryParamsObject.textColor);

InspectorFrontendHost.loaded();
WebInspector.WorkerManager.loaded();

DebuggerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "debuggerCausesRecompilation", null));
DebuggerAgent.supportsSeparateScriptCompilationAndExecution(WebInspector._initializeCapability.bind(WebInspector, "separateScriptCompilationAndExecutionEnabled", null));
ProfilerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "profilerCausesRecompilation", null));
ProfilerAgent.isSampling(WebInspector._initializeCapability.bind(WebInspector, "samplingCPUProfiler", null));
ProfilerAgent.hasHeapProfiler(WebInspector._initializeCapability.bind(WebInspector, "heapProfilerPresent", null));
TimelineAgent.supportsFrameInstrumentation(WebInspector._initializeCapability.bind(WebInspector, "timelineSupportsFrameInstrumentation", null));
PageAgent.canOverrideDeviceMetrics(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceMetrics", null));
PageAgent.canOverrideGeolocation(WebInspector._initializeCapability.bind(WebInspector, "canOverrideGeolocation", null));
PageAgent.canOverrideDeviceOrientation(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceOrientation", WebInspector._doLoadedDoneWithCapabilities.bind(WebInspector)));
}

WebInspector._doLoadedDoneWithCapabilities = function()
{
WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
this._registerShortcuts();


WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));

this.console = new WebInspector.ConsoleModel();
this.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this);
this.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
this.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._updateErrorAndWarningCounts, this);

WebInspector.CSSCompletions.requestCSSNameCompletions();

this.drawer = new WebInspector.Drawer();

this.networkManager = new WebInspector.NetworkManager();
this.resourceTreeModel = new WebInspector.ResourceTreeModel(this.networkManager);
this.debuggerModel = new WebInspector.DebuggerModel();
this.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
this.networkLog = new WebInspector.NetworkLog();
this.domAgent = new WebInspector.DOMAgent();
this.runtimeModel = new WebInspector.RuntimeModel(this.resourceTreeModel);

this.consoleView = new WebInspector.ConsoleView(WebInspector.WorkerManager.isWorkerFrontend());

InspectorBackend.registerInspectorDispatcher(this);

this.cssModel = new WebInspector.CSSStyleModel();
this.timelineManager = new WebInspector.TimelineManager();
this.userAgentSupport = new WebInspector.UserAgentSupport();

this.searchController = new WebInspector.SearchController();
this.advancedSearchController = new WebInspector.AdvancedSearchController();
this.settingsController = new WebInspector.SettingsController();

this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();

this._zoomLevel = WebInspector.settings.zoomLevel.get();
if (this._zoomLevel)
this._requestZoom();

var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
this.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
this.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });

this.workspace = new WebInspector.Workspace();
this.workspaceController = new WebInspector.WorkspaceController(this.workspace);

this.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, this.debuggerModel, this.workspace);

this.scriptSnippetModel = new WebInspector.ScriptSnippetModel(this.workspace);
new WebInspector.DebuggerScriptMapping(this.workspace);
new WebInspector.NetworkUISourceCodeProvider(this.workspace);
new WebInspector.StylesSourceMapping(this.workspace);
if (WebInspector.experimentsSettings.sass.isEnabled())
new WebInspector.SASSSourceMapping(this.workspace);

new WebInspector.PresentationConsoleMessageHelper(this.workspace);

this._createGlobalStatusBarItems();

WebInspector._installDockToRight();

this.toolbar = new WebInspector.Toolbar();
WebInspector.startBatchUpdate();
var panelDescriptors = this._panelDescriptors();
for (var i = 0; i < panelDescriptors.length; ++i)
WebInspector.inspectorView.addPanel(panelDescriptors[i]);
WebInspector.endBatchUpdate();

this.addMainEventListeners(document);
WebInspector.registerLinkifierPlugin(this._profilesLinkifier.bind(this));

window.addEventListener("resize", this.windowResize.bind(this), true);

var errorWarningCount = document.getElementById("error-warning-count");
errorWarningCount.addEventListener("click", this.showConsole.bind(this), false);
this._updateErrorAndWarningCounts();

this.extensionServer.initExtensions();

this.console.enableAgent();

function showInitialPanel()
{
if (!WebInspector.inspectorView.currentPanel())
WebInspector.showPanel(WebInspector.settings.lastActivePanel.get());
}

InspectorAgent.enable(showInitialPanel);
this.databaseModel = new WebInspector.DatabaseModel();
this.domStorageModel = new WebInspector.DOMStorageModel();

if (!Capabilities.profilerCausesRecompilation || WebInspector.settings.profilerEnabled.get())
ProfilerAgent.enable();

if (WebInspector.settings.showPaintRects.get())
PageAgent.setShowPaintRects(true);

if (WebInspector.settings.javaScriptDisabled.get())
PageAgent.setScriptExecutionDisabled(true);

this.domAgent._emulateTouchEventsChanged();

WebInspector.WorkerManager.loadCompleted();
InspectorFrontendAPI.loadCompleted();
}

WebInspector._installDockToRight = function()
{

WebInspector.settings.dockToRight.set(WebInspector.queryParamsObject.dockSide === "right");

if (WebInspector.settings.dockToRight.get())
document.body.addStyleClass("dock-to-right");

if (WebInspector.attached)
WebInspector._setCompactMode(!WebInspector.settings.dockToRight.get());

WebInspector.settings.dockToRight.addChangeListener(listener.bind(this));

function listener(event)
{
var value = WebInspector.settings.dockToRight.get();
if (value) {
InspectorFrontendHost.requestSetDockSide("right");
document.body.addStyleClass("dock-to-right");
} else {
InspectorFrontendHost.requestSetDockSide("bottom");
document.body.removeStyleClass("dock-to-right");
}
if (WebInspector.attached)
WebInspector._setCompactMode(!value);
else
WebInspector._updateDockButtonState();
}
}

var windowLoaded = function()
{
var localizedStringsURL = InspectorFrontendHost.localizedStringsURL();
if (localizedStringsURL) {
var localizedStringsScriptElement = document.createElement("script");
localizedStringsScriptElement.addEventListener("load", WebInspector.loaded.bind(WebInspector), false);
localizedStringsScriptElement.type = "text/javascript";
localizedStringsScriptElement.src = localizedStringsURL;
document.head.appendChild(localizedStringsScriptElement);
} else
WebInspector.loaded();

WebInspector.attached = WebInspector.queryParamsObject.docked === "true";

window.removeEventListener("DOMContentLoaded", windowLoaded, false);
delete windowLoaded;
};

window.addEventListener("DOMContentLoaded", windowLoaded, false);







var messagesToDispatch = [];

WebInspector.dispatchQueueIsEmpty = function() {
return messagesToDispatch.length == 0;
}

WebInspector.dispatch = function(message) {
messagesToDispatch.push(message);
setTimeout(function() {
InspectorBackend.dispatch(messagesToDispatch.shift());
}, 0);
}

WebInspector.dispatchMessageFromBackend = function(messageObject)
{
WebInspector.dispatch(messageObject);
}

WebInspector.windowResize = function(event)
{
if (WebInspector.inspectorView)
WebInspector.inspectorView.doResize();
if (WebInspector.drawer)
WebInspector.drawer.resize();
if (WebInspector.toolbar)
WebInspector.toolbar.resize();
if (WebInspector.settingsController)
WebInspector.settingsController.resize();
}

WebInspector.setDockingUnavailable = function(unavailable)
{
this._isDockingUnavailable = unavailable;
this._updateDockButtonState();
}

WebInspector.close = function(event)
{
if (this._isClosing)
return;
this._isClosing = true;
this.notifications.dispatchEventToListeners(WebInspector.Events.InspectorClosing);
InspectorFrontendHost.closeWindow();
}

WebInspector.documentClick = function(event)
{
var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
if (!anchor || anchor.target === "_blank")
return;


event.consume(true);

function followLink()
{
if (WebInspector.isBeingEdited(event.target) || WebInspector._showAnchorLocation(anchor))
return;

const profileMatch = WebInspector.ProfileURLRegExp.exec(anchor.href);
if (profileMatch) {
WebInspector.showProfileForURL(anchor.href);
return;
}

var parsedURL = anchor.href.asParsedURL();
if (parsedURL && parsedURL.scheme === "webkit-link-action") {
if (parsedURL.host === "show-panel") {
var panel = parsedURL.path.substring(1);
if (WebInspector.panel(panel))
WebInspector.showPanel(panel);
}
return;
}

InspectorFrontendHost.openInNewTab(anchor.href);
}

if (WebInspector.followLinkTimeout)
clearTimeout(WebInspector.followLinkTimeout);

if (anchor.preventFollowOnDoubleClick) {


if (event.detail === 1)
WebInspector.followLinkTimeout = setTimeout(followLink, 333);
return;
}

followLink();
}

WebInspector.openResource = function(resourceURL, inResourcesPanel)
{
var resource = WebInspector.resourceForURL(resourceURL);
if (inResourcesPanel && resource)
WebInspector.showPanel("resources").showResource(resource);
else
InspectorFrontendHost.openInNewTab(resourceURL);
}

WebInspector._registerShortcuts = function()
{
var shortcut = WebInspector.KeyboardShortcut;
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
var keys = [
shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta),
shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta)
];
section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));

var keys = [
shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
];
section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));

section.addKey(shortcut.shortcutToString(shortcut.Keys.Esc), WebInspector.UIString("Toggle console"));
section.addKey(shortcut.shortcutToString("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));

var advancedSearchShortcut = WebInspector.AdvancedSearchController.createShortcut();
section.addKey(advancedSearchShortcut.name, WebInspector.UIString("Search across all sources"));

var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
section.addKey(openResourceShortcut.name, WebInspector.UIString("Go to source"));

if (WebInspector.isMac()) {
keys = [
shortcut.shortcutToString("g", shortcut.Modifiers.Meta),
shortcut.shortcutToString("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
}

var goToShortcut = WebInspector.GoToLineDialog.createShortcut();
section.addKey(goToShortcut.name, WebInspector.UIString("Go to line"));
}

WebInspector.documentKeyDown = function(event)
{
const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF"; 

if (event.keyIdentifier === "F1" ||
(event.keyIdentifier === helpKey && event.shiftKey && (!WebInspector.isBeingEdited(event.target) || event.metaKey))) {
this.settingsController.showSettingsScreen(WebInspector.SettingsScreen.Tabs.Shortcuts);
event.consume(true);
return;
}

if (WebInspector.currentFocusElement() && WebInspector.currentFocusElement().handleKeyEvent) {
WebInspector.currentFocusElement().handleKeyEvent(event);
if (event.handled) {
event.consume(true);
return;
}
}

if (WebInspector.inspectorView.currentPanel()) {
WebInspector.inspectorView.currentPanel().handleShortcut(event);
if (event.handled) {
event.consume(true);
return;
}
}

if (WebInspector.searchController.handleShortcut(event))
return;
if (WebInspector.advancedSearchController.handleShortcut(event))
return;

switch (event.keyIdentifier) {
case "U+004F": 
if (!event.shiftKey && !event.altKey && WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
WebInspector.showPanel("scripts").showGoToSourceDialog();
event.consume(true);
}
break;
case "U+0052": 
if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
PageAgent.reload(event.shiftKey);
event.consume(true);
}
break;
case "F5":
if (!WebInspector.isMac()) {
PageAgent.reload(event.ctrlKey || event.shiftKey);
event.consume(true);
}
break;
}

var isValidZoomShortcut = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) &&
!event.altKey &&
!InspectorFrontendHost.isStub;
switch (event.keyCode) {
case 107: 
case 187: 
if (isValidZoomShortcut) {
WebInspector._zoomIn();
event.consume(true);
}
break;
case 109: 
case 189: 
if (isValidZoomShortcut) {
WebInspector._zoomOut();
event.consume(true);
}
break;
case 48: 

if (isValidZoomShortcut && !event.shiftKey) {
WebInspector._resetZoom();
event.consume(true);
}
break;
}



if (event.keyIdentifier === "U+0043") { 
if (WebInspector.isMac())
var isNodeSearchKey = event.metaKey && !event.ctrlKey && !event.altKey && event.shiftKey;
else
var isNodeSearchKey = event.ctrlKey && !event.metaKey && !event.altKey && event.shiftKey;

if (isNodeSearchKey) {
this.toggleSearchingForNode();
event.consume(true);
return;
}
return;
}
}

WebInspector.postDocumentKeyDown = function(event)
{
if (event.handled)
return;

if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {

if (!this._toggleConsoleButton.toggled && WebInspector.drawer.visible)
this.closeViewInDrawer();
else
this._toggleConsoleButtonClicked();
}
}

WebInspector.documentCanCopy = function(event)
{
if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
event.preventDefault();
}

WebInspector.documentCopy = function(event)
{
if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
WebInspector.inspectorView.currentPanel().handleCopyEvent(event);
WebInspector.documentCopyEventFired(event);
}

WebInspector.documentCopyEventFired = function(event)
{
}

WebInspector.contextMenuEventFired = function(event)
{
if (event.handled || event.target.hasStyleClass("popup-glasspane"))
event.preventDefault();
}

WebInspector.showConsole = function()
{
if (WebInspector._toggleConsoleButton && !WebInspector._toggleConsoleButton.toggled) {
if (WebInspector.drawer.visible)
this._closePreviousDrawerView();
WebInspector._toggleConsoleButtonClicked();
}
}

WebInspector.showPanel = function(panel)
{
return WebInspector.inspectorView.showPanel(panel);
}

WebInspector.panel = function(panel)
{
return WebInspector.inspectorView.panel(panel);
}

WebInspector.bringToFront = function()
{
InspectorFrontendHost.bringToFront();
}


WebInspector.log = function(message, messageLevel, showConsole)
{

var self = this;


function isLogAvailable()
{
return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console;
}


function flushQueue()
{
var queued = WebInspector.log.queued;
if (!queued)
return;

for (var i = 0; i < queued.length; ++i)
logMessage(queued[i]);

delete WebInspector.log.queued;
}



function flushQueueIfAvailable()
{
if (!isLogAvailable())
return;

clearInterval(WebInspector.log.interval);
delete WebInspector.log.interval;

flushQueue();
}


function logMessage(message)
{

var msg = WebInspector.ConsoleMessage.create(
WebInspector.ConsoleMessage.MessageSource.Other,
messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
message);

self.console.addMessage(msg);
if (showConsole)
WebInspector.showConsole();
}


if (!isLogAvailable()) {
if (!WebInspector.log.queued)
WebInspector.log.queued = [];

WebInspector.log.queued.push(message);

if (!WebInspector.log.interval)
WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000);

return;
}


flushQueue();


logMessage(message);
}

WebInspector.showErrorMessage = function(error)
{
WebInspector.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true);
}

WebInspector.inspect = function(payload, hints)
{
var object = WebInspector.RemoteObject.fromPayload(payload);
if (object.subtype === "node") {
function callback(nodeId)
{
WebInspector._updateFocusedNode(nodeId);
object.release();
}
object.pushNodeToFrontend(callback);
return;
}

if (hints.databaseId)
WebInspector.showPanel("resources").selectDatabase(WebInspector.databaseModel.databaseForId(hints.databaseId));
else if (hints.domStorageId)
WebInspector.showPanel("resources").selectDOMStorage(WebInspector.domStorageModel.storageForId(hints.domStorageId));

object.release();
}

WebInspector._updateFocusedNode = function(nodeId)
{
if (WebInspector._nodeSearchButton.toggled) {
InspectorFrontendHost.bringToFront();
WebInspector._nodeSearchButton.toggled = false;
}
WebInspector.showPanel("elements").revealAndSelectNode(nodeId);
}

WebInspector._showAnchorLocation = function(anchor)
{
if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
return true;
var preferredPanel = this.panels[anchor.preferredPanel];
if (preferredPanel && WebInspector._showAnchorLocationInPanel(anchor, preferredPanel))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("scripts")))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("resources")))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("network")))
return true;
return false;
}

WebInspector._showAnchorLocationInPanel = function(anchor, panel)
{
if (!panel || !panel.canShowAnchorLocation(anchor))
return false;


if (anchor.hasStyleClass("webkit-html-external-link")) {
anchor.removeStyleClass("webkit-html-external-link");
anchor.addStyleClass("webkit-html-resource-link");
}

WebInspector.inspectorView.showPanelForAnchorNavigation(panel);
panel.showAnchorLocation(anchor);
return true;
}

WebInspector.showProfileForURL = function(url)
{
WebInspector.showPanel("profiles").showProfileForURL(url);
}

WebInspector.evaluateInConsole = function(expression, showResultOnly)
{
this.showConsole();
this.consoleView.evaluateUsingTextPrompt(expression, showResultOnly);
}

WebInspector.addMainEventListeners = function(doc)
{
doc.addEventListener("keydown", this.documentKeyDown.bind(this), true);
doc.addEventListener("keydown", this.postDocumentKeyDown.bind(this), false);
doc.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
doc.addEventListener("copy", this.documentCopy.bind(this), true);
doc.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);
doc.addEventListener("click", this.documentClick.bind(this), true);
}

WebInspector.ProfileURLRegExp = /webkit-profile:\/\/(.+)\/(.+)#([0-9]+)/;





WebInspector.UIString = function(string, vararg)
{
if (Preferences.localizeUI) {
if (window.localizedStrings && string in window.localizedStrings)
string = window.localizedStrings[string];
else {
if (!(string in WebInspector._missingLocalizedStrings)) {
console.warn("Localized string \"" + string + "\" not found.");
WebInspector._missingLocalizedStrings[string] = true;
}

if (Preferences.showMissingLocalizedStrings)
string += " (not localized)";
}
}
return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
}

WebInspector._missingLocalizedStrings = {};






WebInspector.installDragHandle = function(element, elementDragStart, elementDrag, elementDragEnd, cursor)
{
element.addEventListener("mousedown", WebInspector._elementDragStart.bind(WebInspector, elementDragStart, elementDrag, elementDragEnd, cursor), false);
}


WebInspector._elementDragStart = function(elementDragStart, elementDrag, elementDragEnd, cursor, event)
{

if (event.button || (WebInspector.isMac() && event.ctrlKey))
return;

if (WebInspector._elementDraggingEventListener)
return;

if (elementDragStart && !elementDragStart(event))
return;

if (WebInspector._elementDraggingGlassPane) {
WebInspector._elementDraggingGlassPane.dispose();
delete WebInspector._elementDraggingGlassPane;
}

var targetDocument = event.target.ownerDocument;

WebInspector._elementDraggingEventListener = elementDrag;
WebInspector._elementEndDraggingEventListener = elementDragEnd;
WebInspector._mouseOutWhileDraggingTargetDocument = targetDocument;

targetDocument.addEventListener("mousemove", WebInspector._elementDraggingEventListener, true);
targetDocument.addEventListener("mouseup", WebInspector._elementDragEnd, true);
targetDocument.addEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);

targetDocument.body.style.cursor = cursor;

event.preventDefault();
}

WebInspector._mouseOutWhileDragging = function()
{
WebInspector._unregisterMouseOutWhileDragging();
WebInspector._elementDraggingGlassPane = new WebInspector.GlassPane();
}

WebInspector._unregisterMouseOutWhileDragging = function()
{
if (!WebInspector._mouseOutWhileDraggingTargetDocument)
return;
WebInspector._mouseOutWhileDraggingTargetDocument.removeEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);
delete WebInspector._mouseOutWhileDraggingTargetDocument;
}

WebInspector._elementDragEnd = function(event)
{
var targetDocument = event.target.ownerDocument;
targetDocument.removeEventListener("mousemove", WebInspector._elementDraggingEventListener, true);
targetDocument.removeEventListener("mouseup", WebInspector._elementDragEnd, true);
WebInspector._unregisterMouseOutWhileDragging();

targetDocument.body.style.removeProperty("cursor");

if (WebInspector._elementDraggingGlassPane)
WebInspector._elementDraggingGlassPane.dispose();

var elementDragEnd = WebInspector._elementEndDraggingEventListener;

delete WebInspector._elementDraggingGlassPane;
delete WebInspector._elementDraggingEventListener;
delete WebInspector._elementEndDraggingEventListener;

event.preventDefault();
if (elementDragEnd)
elementDragEnd(event);
}


WebInspector.GlassPane = function()
{
this.element = document.createElement("div");
this.element.style.cssText = "position:absolute;top:0;bottom:0;left:0;right:0;background-color:transparent;z-index:1000;";
this.element.id = "glass-pane-for-drag";
document.body.appendChild(this.element);
}

WebInspector.GlassPane.prototype = {
dispose: function()
{
if (this.element.parentElement)
this.element.parentElement.removeChild(this.element);
}
}

WebInspector.animateStyle = function(animations, duration, callback)
{
var interval;
var complete = 0;
var hasCompleted = false;

const intervalDuration = (1000 / 30); 
const animationsLength = animations.length;
const propertyUnit = {opacity: ""};
const defaultUnit = "px";

function cubicInOut(t, b, c, d)
{
if ((t/=d/2) < 1) return c/2*t*t*t + b;
return c/2*((t-=2)*t*t + 2) + b;
}


for (var i = 0; i < animationsLength; ++i) {
var animation = animations[i];
var element = null, start = null, end = null, key = null;
for (key in animation) {
if (key === "element")
element = animation[key];
else if (key === "start")
start = animation[key];
else if (key === "end")
end = animation[key];
}

if (!element || !end)
continue;

if (!start) {
var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
start = {};
for (key in end)
start[key] = parseInt(computedStyle.getPropertyValue(key), 10);
animation.start = start;
} else
for (key in start)
element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
}

function animateLoop()
{
if (hasCompleted)
return;


complete += intervalDuration;
var next = complete + intervalDuration;


for (var i = 0; i < animationsLength; ++i) {
var animation = animations[i];
var element = animation.element;
var start = animation.start;
var end = animation.end;
if (!element || !end)
continue;

var style = element.style;
for (key in end) {
var endValue = end[key];
if (next < duration) {
var startValue = start[key];
var newValue = cubicInOut(complete, startValue, endValue - startValue, duration);
style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
} else
style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
}
}


if (complete >= duration) {
hasCompleted = true;
clearInterval(interval);
if (callback)
callback();
}
}

function forceComplete()
{
if (hasCompleted)
return;

complete = duration;
animateLoop();
}

function cancel()
{
hasCompleted = true;
clearInterval(interval);
}

interval = setInterval(animateLoop, intervalDuration);
return {
cancel: cancel,
forceComplete: forceComplete
};
}

WebInspector.isBeingEdited = function(element)
{
if (element.hasStyleClass("text-prompt") || element.nodeName === "INPUT")
return true;

if (!WebInspector.__editingCount)
return false;

while (element) {
if (element.__editing)
return true;
element = element.parentElement;
}
return false;
}

WebInspector.markBeingEdited = function(element, value)
{
if (value) {
if (element.__editing)
return false;
element.__editing = true;
WebInspector.__editingCount = (WebInspector.__editingCount || 0) + 1;
} else {
if (!element.__editing)
return false;
delete element.__editing;
--WebInspector.__editingCount;
}
return true;
}


WebInspector.EditingConfig = function(commitHandler, cancelHandler, context)
{
this.commitHandler = commitHandler;
this.cancelHandler = cancelHandler
this.context = context;


this.pasteHandler;


this.multiline;


this.customFinishHandler;
}

WebInspector.EditingConfig.prototype = {
setPasteHandler: function(pasteHandler)
{
this.pasteHandler = pasteHandler;
},

setMultiline: function(multiline)
{
this.multiline = multiline;
},

setCustomFinishHandler: function(customFinishHandler)
{
this.customFinishHandler = customFinishHandler;
}
}

WebInspector.CSSNumberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;

WebInspector.StyleValueDelimiters = " \xA0\t\n\"':;,/()";



WebInspector._valueModificationDirection = function(event)
{
var direction = null;
if (event.type === "mousewheel") {
if (event.wheelDeltaY > 0)
direction = "Up";
else if (event.wheelDeltaY < 0)
direction = "Down";
} else {
if (event.keyIdentifier === "Up" || event.keyIdentifier === "PageUp")
direction = "Up";
else if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
direction = "Down";        
}
return direction;
}


WebInspector._modifiedHexValue = function(hexString, event)
{
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return hexString;

var number = parseInt(hexString, 16);
if (isNaN(number) || !isFinite(number))
return hexString;

var maxValue = Math.pow(16, hexString.length) - 1;
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var delta;

if (arrowKeyOrMouseWheelEvent)
delta = (direction === "Up") ? 1 : -1;
else
delta = (event.keyIdentifier === "PageUp") ? 16 : -16;

if (event.shiftKey)
delta *= 16;

var result = number + delta;
if (result < 0)
result = 0; 
else if (result > maxValue)
return hexString;


var resultString = result.toString(16).toUpperCase();
for (var i = 0, lengthDelta = hexString.length - resultString.length; i < lengthDelta; ++i)
resultString = "0" + resultString;
return resultString;
}


WebInspector._modifiedFloatNumber = function(number, event)
{
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return number;

var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");



var changeAmount = 1;
if (event.shiftKey && !arrowKeyOrMouseWheelEvent)
changeAmount = 100;
else if (event.shiftKey || !arrowKeyOrMouseWheelEvent)
changeAmount = 10;
else if (event.altKey)
changeAmount = 0.1;

if (direction === "Down")
changeAmount *= -1;



var result = Number((number + changeAmount).toFixed(6));
if (!String(result).match(WebInspector.CSSNumberRegex))
return null;

return result;
}


WebInspector.handleElementValueModifications = function(event, element, finishHandler, suggestionHandler, customNumberHandler)
{
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
if (!arrowKeyOrMouseWheelEvent && !pageKeyPressed)
return false;

var selection = window.getSelection();
if (!selection.rangeCount)
return false;

var selectionRange = selection.getRangeAt(0);
if (!selectionRange.commonAncestorContainer.isSelfOrDescendant(element))
return false;

var originalValue = element.textContent;
var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StyleValueDelimiters, element);
var wordString = wordRange.toString();

if (suggestionHandler && suggestionHandler(wordString))
return false;

var replacementString;
var prefix, suffix, number;

var matches;
matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString);
if (matches && matches.length) {
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedHexValue(matches[2], event);

if (customNumberHandler)
number = customNumberHandler(number);

replacementString = prefix + number + suffix;
} else {
matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);
if (matches && matches.length) {
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedFloatNumber(parseFloat(matches[2]), event);


if (number === null)                
return false;

if (customNumberHandler)
number = customNumberHandler(number);

replacementString = prefix + number + suffix;
}
}

if (replacementString) {
var replacementTextNode = document.createTextNode(replacementString);

wordRange.deleteContents();
wordRange.insertNode(replacementTextNode);

var finalSelectionRange = document.createRange();
finalSelectionRange.setStart(replacementTextNode, 0);
finalSelectionRange.setEnd(replacementTextNode, replacementString.length);

selection.removeAllRanges();
selection.addRange(finalSelectionRange);

event.handled = true;
event.preventDefault();

if (finishHandler)
finishHandler(originalValue, replacementString);

return true;
}
return false;
}


WebInspector.startEditing = function(element, config)
{
if (!WebInspector.markBeingEdited(element, true))
return null;

config = config || new WebInspector.EditingConfig(function() {}, function() {});
var committedCallback = config.commitHandler;
var cancelledCallback = config.cancelHandler;
var pasteCallback = config.pasteHandler;
var context = config.context;
var oldText = getContent(element);
var moveDirection = "";

element.addStyleClass("editing");

var oldTabIndex = element.getAttribute("tabIndex");
if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
element.tabIndex = 0;

function blurEventListener() {
editingCommitted.call(element);
}

function getContent(element) {
if (element.tagName === "INPUT" && element.type === "text")
return element.value;
else
return element.textContent;
}


function cleanUpAfterEditing()
{
WebInspector.markBeingEdited(element, false);

this.removeStyleClass("editing");

if (typeof oldTabIndex !== "number")
element.removeAttribute("tabIndex");
else
this.tabIndex = oldTabIndex;
this.scrollTop = 0;
this.scrollLeft = 0;

element.removeEventListener("blur", blurEventListener, false);
element.removeEventListener("keydown", keyDownEventListener, true);
if (pasteCallback)
element.removeEventListener("paste", pasteEventListener, true);

WebInspector.restoreFocusFromElement(element);
}


function editingCancelled()
{
if (this.tagName === "INPUT" && this.type === "text")
this.value = oldText;
else
this.textContent = oldText;

cleanUpAfterEditing.call(this);

cancelledCallback(this, context);
}


function editingCommitted()
{
cleanUpAfterEditing.call(this);

committedCallback(this, getContent(this), oldText, context, moveDirection);
}

function defaultFinishHandler(event)
{
var isMetaOrCtrl = WebInspector.isMac() ?
event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
return "commit";
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
return "cancel";
else if (event.keyIdentifier === "U+0009") 
return "move-" + (event.shiftKey ? "backward" : "forward");
}

function handleEditingResult(result, event)
{
if (result === "commit") {
editingCommitted.call(element);
event.consume(true);
} else if (result === "cancel") {
editingCancelled.call(element);
event.consume(true);
} else if (result && result.startsWith("move-")) {
moveDirection = result.substring(5);
if (event.keyIdentifier !== "U+0009")
blurEventListener();
}
}

function pasteEventListener(event)
{
var result = pasteCallback(event);
handleEditingResult(result, event);
}

function keyDownEventListener(event)
{
var handler = config.customFinishHandler || defaultFinishHandler;
var result = handler(event);
handleEditingResult(result, event);
}

element.addEventListener("blur", blurEventListener, false);
element.addEventListener("keydown", keyDownEventListener, true);
if (pasteCallback)
element.addEventListener("paste", pasteEventListener, true);

WebInspector.setCurrentFocusElement(element);
return {
cancel: editingCancelled.bind(element),
commit: editingCommitted.bind(element)
};
}


Number.secondsToString = function(seconds, higherResolution)
{
if (seconds === 0)
return "0";

var ms = seconds * 1000;
if (higherResolution && ms < 1000)
return WebInspector.UIString("%.3fms", ms);
else if (ms < 1000)
return WebInspector.UIString("%.0fms", ms);

if (seconds < 60)
return WebInspector.UIString("%.2fs", seconds);

var minutes = seconds / 60;
if (minutes < 60)
return WebInspector.UIString("%.1fmin", minutes);

var hours = minutes / 60;
if (hours < 24)
return WebInspector.UIString("%.1fhrs", hours);

var days = hours / 24;
return WebInspector.UIString("%.1f days", days);
}


Number.bytesToString = function(bytes, higherResolution)
{
if (typeof higherResolution === "undefined")
higherResolution = true;

if (bytes < 1024)
return WebInspector.UIString("%.0fB", bytes);

var kilobytes = bytes / 1024;
if (higherResolution && kilobytes < 1024)
return WebInspector.UIString("%.2fKB", kilobytes);
else if (kilobytes < 1024)
return WebInspector.UIString("%.0fKB", kilobytes);

var megabytes = kilobytes / 1024;
if (higherResolution)
return WebInspector.UIString("%.2fMB", megabytes);
else
return WebInspector.UIString("%.0fMB", megabytes);
}

Number.withThousandsSeparator = function(num)
{
var str = num + "";
var re = /(\d+)(\d{3})/;
while (str.match(re))
str = str.replace(re, "$1\u2009$2"); 
return str;
}

WebInspector.useLowerCaseMenuTitles = function()
{
return WebInspector.platform() === "windows" && Preferences.useLowerCaseMenuTitlesOnWindows;
}

WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append)
{
return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append);
}

WebInspector.openLinkExternallyLabel = function()
{
return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in new tab" : "Open Link in New Tab");
}

WebInspector.copyLinkAddressLabel = function()
{
return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy link address" : "Copy Link Address");
}

WebInspector.platform = function()
{
if (!WebInspector._platform)
WebInspector._platform = InspectorFrontendHost.platform();
return WebInspector._platform;
}

WebInspector.isMac = function()
{
if (typeof WebInspector._isMac === "undefined")
WebInspector._isMac = WebInspector.platform() === "mac";

return WebInspector._isMac;
}

WebInspector.isWin = function()
{
if (typeof WebInspector._isWin === "undefined")
WebInspector._isWin = WebInspector.platform() === "windows";

return WebInspector._isWin;
}

WebInspector.PlatformFlavor = {
WindowsVista: "windows-vista",
MacTiger: "mac-tiger",
MacLeopard: "mac-leopard",
MacSnowLeopard: "mac-snowleopard"
}

WebInspector.platformFlavor = function()
{
function detectFlavor()
{
const userAgent = navigator.userAgent;

if (WebInspector.platform() === "windows") {
var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
if (match && match[1] >= 6)
return WebInspector.PlatformFlavor.WindowsVista;
return null;
} else if (WebInspector.platform() === "mac") {
var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/);
if (!match || match[1] != 10)
return WebInspector.PlatformFlavor.MacSnowLeopard;
switch (Number(match[2])) {
case 4:
return WebInspector.PlatformFlavor.MacTiger;
case 5:
return WebInspector.PlatformFlavor.MacLeopard;
case 6:
default:
return WebInspector.PlatformFlavor.MacSnowLeopard;
}
}
}

if (!WebInspector._platformFlavor)
WebInspector._platformFlavor = detectFlavor();

return WebInspector._platformFlavor;
}

WebInspector.port = function()
{
if (!WebInspector._port)
WebInspector._port = InspectorFrontendHost.port();

return WebInspector._port;
}

WebInspector.installPortStyles = function()
{
var platform = WebInspector.platform();
document.body.addStyleClass("platform-" + platform);
var flavor = WebInspector.platformFlavor();
if (flavor)
document.body.addStyleClass("platform-" + flavor);
var port = WebInspector.port();
document.body.addStyleClass("port-" + port);
}

WebInspector._windowFocused = function(event)
{
if (event.target.document.nodeType === Node.DOCUMENT_NODE)
document.body.removeStyleClass("inactive");
}

WebInspector._windowBlurred = function(event)
{
if (event.target.document.nodeType === Node.DOCUMENT_NODE)
document.body.addStyleClass("inactive");
}

WebInspector.previousFocusElement = function()
{
return WebInspector._previousFocusElement;
}

WebInspector.currentFocusElement = function()
{
return WebInspector._currentFocusElement;
}

WebInspector._focusChanged = function(event)
{
WebInspector.setCurrentFocusElement(event.target);
}

WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet(); 
WebInspector._isTextEditingElement = function(element)
{
if (element instanceof HTMLInputElement)
return element.type in WebInspector._textInputTypes;

if (element instanceof HTMLTextAreaElement)
return true;

return false;
}

WebInspector.setCurrentFocusElement = function(x)
{
if (WebInspector._currentFocusElement !== x)
WebInspector._previousFocusElement = WebInspector._currentFocusElement;
WebInspector._currentFocusElement = x;

if (WebInspector._currentFocusElement) {
WebInspector._currentFocusElement.focus();




var selection = window.getSelection();
if (!WebInspector._isTextEditingElement(WebInspector._currentFocusElement) && selection.isCollapsed && !WebInspector._currentFocusElement.isInsertionCaretInside()) {
var selectionRange = WebInspector._currentFocusElement.ownerDocument.createRange();
selectionRange.setStart(WebInspector._currentFocusElement, 0);
selectionRange.setEnd(WebInspector._currentFocusElement, 0);

selection.removeAllRanges();
selection.addRange(selectionRange);
}
} else if (WebInspector._previousFocusElement)
WebInspector._previousFocusElement.blur();
}

WebInspector.restoreFocusFromElement = function(element)
{
if (element && element.isSelfOrAncestor(WebInspector.currentFocusElement()))
WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
}

WebInspector.setToolbarColors = function(backgroundColor, color)
{
if (!WebInspector._themeStyleElement) {
WebInspector._themeStyleElement = document.createElement("style");
document.head.appendChild(WebInspector._themeStyleElement);
}
WebInspector._themeStyleElement.textContent =
"#toolbar {\
             background-image: none !important;\
             background-color: " + backgroundColor + " !important;\
         }\
         \
         .toolbar-label {\
             color: " + color + " !important;\
             text-shadow: none;\
         }";
}

WebInspector.resetToolbarColors = function()
{
if (WebInspector._themeStyleElement)
WebInspector._themeStyleElement.textContent = "";
}


WebInspector.highlightSearchResult = function(element, offset, length, domChanges)
{
var result = WebInspector.highlightSearchResults(element, [{offset: offset, length: length }], domChanges);
return result.length ? result[0] : null;
}


WebInspector.highlightSearchResults = function(element, resultRanges, changes)
{
return WebInspector.highlightRangesWithStyleClass(element, resultRanges, "webkit-search-result", changes);
}


WebInspector.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes)
{
changes = changes || [];
var highlightNodes = [];
var lineText = element.textContent;
var ownerDocument = element.ownerDocument;
var textNodeSnapshot = ownerDocument.evaluate(".//text()", element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

var snapshotLength = textNodeSnapshot.snapshotLength;
if (snapshotLength === 0)
return highlightNodes;

var nodeRanges = [];
var rangeEndOffset = 0;
for (var i = 0; i < snapshotLength; ++i) {
var range = {};
range.offset = rangeEndOffset;
range.length = textNodeSnapshot.snapshotItem(i).textContent.length;
rangeEndOffset = range.offset + range.length;
nodeRanges.push(range);
}

var startIndex = 0;
for (var i = 0; i < resultRanges.length; ++i) {
var startOffset = resultRanges[i].offset;
var endOffset = startOffset + resultRanges[i].length;

while (startIndex < snapshotLength && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
startIndex++;
var endIndex = startIndex;
while (endIndex < snapshotLength && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
endIndex++;
if (endIndex === snapshotLength)
break;

var highlightNode = ownerDocument.createElement("span");
highlightNode.className = styleClass;
highlightNode.textContent = lineText.substring(startOffset, endOffset);

var lastTextNode = textNodeSnapshot.snapshotItem(endIndex);
var lastText = lastTextNode.textContent;
lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
changes.push({ node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent });

if (startIndex === endIndex) {
lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
changes.push({ node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement });
highlightNodes.push(highlightNode);

var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement });
} else {
var firstTextNode = textNodeSnapshot.snapshotItem(startIndex);
var firstText = firstTextNode.textContent;
var anchorElement = firstTextNode.nextSibling;

firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement });
highlightNodes.push(highlightNode);

firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
changes.push({ node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent });

for (var j = startIndex + 1; j < endIndex; j++) {
var textNode = textNodeSnapshot.snapshotItem(j);
var text = textNode.textContent;
textNode.textContent = "";
changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
}
}
startIndex = endIndex;
nodeRanges[startIndex].offset = endOffset;
nodeRanges[startIndex].length = lastTextNode.textContent.length;

}
return highlightNodes;
}

WebInspector.applyDomChanges = function(domChanges)
{
for (var i = 0, size = domChanges.length; i < size; ++i) {
var entry = domChanges[i];
switch (entry.type) {
case "added":
entry.parent.insertBefore(entry.node, entry.nextSibling);
break;
case "changed":
entry.node.textContent = entry.newText;
break;
}
}
}

WebInspector.revertDomChanges = function(domChanges)
{
for (var i = domChanges.length - 1; i >= 0; --i) {
var entry = domChanges[i];
switch (entry.type) {
case "added":
if (entry.node.parentElement)
entry.node.parentElement.removeChild(entry.node);
break;
case "changed":
entry.node.textContent = entry.oldText;
break;
}
}
}

WebInspector._coalescingLevel = 0;

WebInspector.startBatchUpdate = function()
{
if (!WebInspector._coalescingLevel)
WebInspector._postUpdateHandlers = new Map();
WebInspector._coalescingLevel++;
}

WebInspector.endBatchUpdate = function()
{
if (--WebInspector._coalescingLevel)
return;

var handlers = WebInspector._postUpdateHandlers;
delete WebInspector._postUpdateHandlers;

var keys = handlers.keys();
for (var i = 0; i < keys.length; ++i) {
var object = keys[i];
var methods = handlers.get(object).keys();
for (var j = 0; j < methods.length; ++j)
methods[j].call(object);
}
}


WebInspector.invokeOnceAfterBatchUpdate = function(object, method)
{
if (!WebInspector._coalescingLevel) {
method.call(object);
return;
}

var methods = WebInspector._postUpdateHandlers.get(object);
if (!methods) {
methods = new Map();
WebInspector._postUpdateHandlers.put(object, methods);
}
methods.put(method);
}

;(function() {

function windowLoaded()
{
window.addEventListener("focus", WebInspector._windowFocused, false);
window.addEventListener("blur", WebInspector._windowBlurred, false);
document.addEventListener("focus", WebInspector._focusChanged.bind(this), true);
window.removeEventListener("DOMContentLoaded", windowLoaded, false);
}

window.addEventListener("DOMContentLoaded", windowLoaded, false);

})();






function InspectorBackendClass()
{
this._lastCallbackId = 1;
this._pendingResponsesCount = 0;
this._callbacks = {};
this._domainDispatchers = {};
this._eventArgs = {};
this._replyArgs = {};

this.dumpInspectorTimeStats = false;
this.dumpInspectorProtocolMessages = false;
this._initialized = false;
}

InspectorBackendClass.prototype = {
_wrap: function(callback, method)
{
var callbackId = this._lastCallbackId++;
if (!callback)
callback = function() {};

this._callbacks[callbackId] = callback;
callback.methodName = method;
if (this.dumpInspectorTimeStats)
callback.sendRequestTime = Date.now();

return callbackId;
},

registerCommand: function(method, signature, replyArgs)
{
var domainAndMethod = method.split(".");
var agentName = domainAndMethod[0] + "Agent";
if (!window[agentName])
window[agentName] = {};

window[agentName][domainAndMethod[1]] = this._sendMessageToBackend.bind(this, method, signature);
window[agentName][domainAndMethod[1]]["invoke"] = this._invoke.bind(this, method, signature);
this._replyArgs[method] = replyArgs;

this._initialized = true;
},

registerEvent: function(eventName, params)
{
this._eventArgs[eventName] = params;

this._initialized = true;
},

_invoke: function(method, signature, args, callback)
{
this._wrapCallbackAndSendMessageObject(method, args, callback);
},

_sendMessageToBackend: function(method, signature, vararg)
{
var args = Array.prototype.slice.call(arguments, 2);
var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : null;

var params = {};
var hasParams = false;
for (var i = 0; i < signature.length; ++i) {
var param = signature[i];
var paramName = param["name"];
var typeName = param["type"];
var optionalFlag = param["optional"];

if (!args.length && !optionalFlag) {
console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
return;
}

var value = args.shift();
if (optionalFlag && typeof value === "undefined") {
continue;
}

if (typeof value !== typeName) {
console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
return;
}

params[paramName] = value;
hasParams = true;
}

if (args.length === 1 && !callback) {
if (typeof args[0] !== "undefined") {
console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
return;
}
}

this._wrapCallbackAndSendMessageObject(method, hasParams ? params : null, callback);
},

_wrapCallbackAndSendMessageObject: function(method, params, callback)
{
var messageObject = {};
messageObject.method = method;
if (params)
messageObject.params = params;
messageObject.id = this._wrap(callback, method);

if (this.dumpInspectorProtocolMessages)
console.log("frontend: " + JSON.stringify(messageObject));

++this._pendingResponsesCount;
this.sendMessageObjectToBackend(messageObject);
},

sendMessageObjectToBackend: function(messageObject)
{
var message = JSON.stringify(messageObject);
InspectorFrontendHost.sendMessageToBackend(message);
},

registerDomainDispatcher: function(domain, dispatcher)
{
this._domainDispatchers[domain] = dispatcher;
},

dispatch: function(message)
{
if (this.dumpInspectorProtocolMessages)
console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));

var messageObject = (typeof message === "string") ? JSON.parse(message) : message;

if ("id" in messageObject) { 
if (messageObject.error) {
if (messageObject.error.code !== -32000)
this.reportProtocolError(messageObject);
}

var callback = this._callbacks[messageObject.id];
if (callback) {
var argumentsArray = [];
if (messageObject.result) {
var paramNames = this._replyArgs[callback.methodName];
if (paramNames) {
for (var i = 0; i < paramNames.length; ++i)
argumentsArray.push(messageObject.result[paramNames[i]]);
}
}

var processingStartTime;
if (this.dumpInspectorTimeStats && callback.methodName)
processingStartTime = Date.now();

argumentsArray.unshift(messageObject.error ? messageObject.error.message : null);
callback.apply(null, argumentsArray);
--this._pendingResponsesCount;
delete this._callbacks[messageObject.id];

if (this.dumpInspectorTimeStats && callback.methodName)
console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
}

if (this._scripts && !this._pendingResponsesCount)
this.runAfterPendingDispatches();

return;
} else {
var method = messageObject.method.split(".");
var domainName = method[0];
var functionName = method[1];
if (!(domainName in this._domainDispatchers)) {
console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
return;
}
var dispatcher = this._domainDispatchers[domainName];
if (!(functionName in dispatcher)) {
console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
return;
}

if (!this._eventArgs[messageObject.method]) {
console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
return;
}

var params = [];
if (messageObject.params) {
var paramNames = this._eventArgs[messageObject.method];
for (var i = 0; i < paramNames.length; ++i)
params.push(messageObject.params[paramNames[i]]);
}

var processingStartTime;
if (this.dumpInspectorTimeStats)
processingStartTime = Date.now();

dispatcher[functionName].apply(dispatcher, params);

if (this.dumpInspectorTimeStats)
console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
}
},

reportProtocolError: function(messageObject)
{
console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error);
},


runAfterPendingDispatches: function(script)
{
if (!this._scripts)
this._scripts = [];

if (script)
this._scripts.push(script);

if (!this._pendingResponsesCount) {
var scripts = this._scripts;
this._scripts = []
for (var id = 0; id < scripts.length; ++id)
scripts[id].call(this);
}
},

loadFromJSONIfNeeded: function(jsonUrl)
{
if (this._initialized)
return;

var xhr = new XMLHttpRequest();
xhr.open("GET", jsonUrl, false);
xhr.send(null);

var schema = JSON.parse(xhr.responseText);
var jsTypes = { integer: "number", array: "object" };
var rawTypes = {};

var domains = schema["domains"];
for (var i = 0; i < domains.length; ++i) {
var domain = domains[i];
for (var j = 0; domain.types && j < domain.types.length; ++j) {
var type = domain.types[j];
rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type;
}
}

var result = [];
for (var i = 0; i < domains.length; ++i) {
var domain = domains[i];

var commands = domain["commands"] || [];    
for (var j = 0; j < commands.length; ++j) {
var command = commands[j];
var parameters = command["parameters"];
var paramsText = [];
for (var k = 0; parameters && k < parameters.length; ++k) {
var parameter = parameters[k];

var type;
if (parameter.type)
type = jsTypes[parameter.type] || parameter.type;
else {
var ref = parameter["$ref"];
if (ref.indexOf(".") !== -1)
type = rawTypes[ref];
else
type = rawTypes[domain.domain + "." + ref];
}

var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}";
paramsText.push(text);
}

var returnsText = [];
var returns = command["returns"] || [];
for (var k = 0; k < returns.length; ++k) {
var parameter = returns[k];
returnsText.push("\"" + parameter.name + "\"");
}
result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "]);");
}

for (var j = 0; domain.events && j < domain.events.length; ++j) {
var event = domain.events[j];
var paramsText = [];
for (var k = 0; event.parameters && k < event.parameters.length; ++k) {
var parameter = event.parameters[k];
paramsText.push("\"" + parameter.name + "\"");
}
result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);");
}

result.push("InspectorBackend.register" + domain.domain + "Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"" + domain.domain + "\");");
}
eval(result.join("\n"));
}
}

InspectorBackend = new InspectorBackendClass();











InspectorBackend.registerInspectorDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Inspector");
InspectorBackend.registerEvent("Inspector.evaluateForTestInFrontend", ["testCallId", "script"]);
InspectorBackend.registerEvent("Inspector.inspect", ["object", "hints"]);
InspectorBackend.registerCommand("Inspector.enable", [], []);
InspectorBackend.registerCommand("Inspector.disable", [], []);


InspectorBackend.registerMemoryDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Memory");
InspectorBackend.registerCommand("Memory.getDOMNodeCount", [], ["domGroups", "strings"]);
InspectorBackend.registerCommand("Memory.getProcessMemoryDistribution", [], ["distribution"]);


InspectorBackend.registerPageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Page");
InspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]);
InspectorBackend.registerEvent("Page.loadEventFired", ["timestamp"]);
InspectorBackend.registerEvent("Page.frameNavigated", ["frame"]);
InspectorBackend.registerEvent("Page.frameDetached", ["frameId"]);
InspectorBackend.registerCommand("Page.enable", [], []);
InspectorBackend.registerCommand("Page.disable", [], []);
InspectorBackend.registerCommand("Page.addScriptToEvaluateOnLoad", [{"name": "scriptSource", "type": "string", "optional": false}], ["identifier"]);
InspectorBackend.registerCommand("Page.removeScriptToEvaluateOnLoad", [{"name": "identifier", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.reload", [{"name": "ignoreCache", "type": "boolean", "optional": true}, {"name": "scriptToEvaluateOnLoad", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("Page.navigate", [{"name": "url", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.getCookies", [], ["cookies", "cookiesString"]);
InspectorBackend.registerCommand("Page.deleteCookie", [{"name": "cookieName", "type": "string", "optional": false}, {"name": "domain", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.getResourceTree", [], ["frameTree"]);
InspectorBackend.registerCommand("Page.getResourceContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], ["content", "base64Encoded"]);
InspectorBackend.registerCommand("Page.searchInResource", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Page.searchInResources", [{"name": "text", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Page.setDocumentContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "html", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.canOverrideDeviceMetrics", [], ["result"]);
InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "fontScaleFactor", "type": "number", "optional": false}, {"name": "fitWindow", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.setShowPaintRects", [{"name": "result", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.getScriptExecutionStatus", [], ["result"]);
InspectorBackend.registerCommand("Page.setScriptExecutionDisabled", [{"name": "value", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.setGeolocationOverride", [{"name": "latitude", "type": "number", "optional": true}, {"name": "longitude", "type": "number", "optional": true}, {"name": "accuracy", "type": "number", "optional": true}], []);
InspectorBackend.registerCommand("Page.clearGeolocationOverride", [], []);
InspectorBackend.registerCommand("Page.canOverrideGeolocation", [], ["result"]);
InspectorBackend.registerCommand("Page.setDeviceOrientationOverride", [{"name": "alpha", "type": "number", "optional": false}, {"name": "beta", "type": "number", "optional": false}, {"name": "gamma", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Page.clearDeviceOrientationOverride", [], []);
InspectorBackend.registerCommand("Page.canOverrideDeviceOrientation", [], ["result"]);
InspectorBackend.registerCommand("Page.setTouchEmulationEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);


InspectorBackend.registerRuntimeDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Runtime");
InspectorBackend.registerEvent("Runtime.executionContextCreated", ["context"]);
InspectorBackend.registerCommand("Runtime.evaluate", [{"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "contextId", "type": "number", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Runtime.callFunctionOn", [{"name": "objectId", "type": "string", "optional": false}, {"name": "functionDeclaration", "type": "string", "optional": false}, {"name": "arguments", "type": "object", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Runtime.getProperties", [{"name": "objectId", "type": "string", "optional": false}, {"name": "ownProperties", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Runtime.releaseObject", [{"name": "objectId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Runtime.releaseObjectGroup", [{"name": "objectGroup", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Runtime.run", [], []);
InspectorBackend.registerCommand("Runtime.setReportExecutionContextCreation", [{"name": "enabled", "type": "boolean", "optional": false}], []);


InspectorBackend.registerConsoleDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Console");
InspectorBackend.registerEvent("Console.messageAdded", ["message"]);
InspectorBackend.registerEvent("Console.messageRepeatCountUpdated", ["count"]);
InspectorBackend.registerEvent("Console.messagesCleared", []);
InspectorBackend.registerCommand("Console.enable", [], []);
InspectorBackend.registerCommand("Console.disable", [], []);
InspectorBackend.registerCommand("Console.clearMessages", [], []);
InspectorBackend.registerCommand("Console.setMonitoringXHREnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Console.addInspectedNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Console.addInspectedHeapObject", [{"name": "heapObjectId", "type": "number", "optional": false}], []);


InspectorBackend.registerNetworkDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Network");
InspectorBackend.registerEvent("Network.requestWillBeSent", ["requestId", "frameId", "loaderId", "documentURL", "request", "timestamp", "initiator", "redirectResponse"]);
InspectorBackend.registerEvent("Network.requestServedFromCache", ["requestId"]);
InspectorBackend.registerEvent("Network.responseReceived", ["requestId", "frameId", "loaderId", "timestamp", "type", "response"]);
InspectorBackend.registerEvent("Network.dataReceived", ["requestId", "timestamp", "dataLength", "encodedDataLength"]);
InspectorBackend.registerEvent("Network.loadingFinished", ["requestId", "timestamp"]);
InspectorBackend.registerEvent("Network.loadingFailed", ["requestId", "timestamp", "errorText", "canceled"]);
InspectorBackend.registerEvent("Network.requestServedFromMemoryCache", ["requestId", "frameId", "loaderId", "documentURL", "timestamp", "initiator", "resource"]);
InspectorBackend.registerEvent("Network.webSocketWillSendHandshakeRequest", ["requestId", "timestamp", "request"]);
InspectorBackend.registerEvent("Network.webSocketHandshakeResponseReceived", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.webSocketCreated", ["requestId", "url"]);
InspectorBackend.registerEvent("Network.webSocketClosed", ["requestId", "timestamp"]);
InspectorBackend.registerEvent("Network.webSocketFrameReceived", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.webSocketFrameError", ["requestId", "timestamp", "errorMessage"]);
InspectorBackend.registerEvent("Network.webSocketFrameSent", ["requestId", "timestamp", "response"]);
InspectorBackend.registerCommand("Network.enable", [], []);
InspectorBackend.registerCommand("Network.disable", [], []);
InspectorBackend.registerCommand("Network.setUserAgentOverride", [{"name": "userAgent", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Network.setExtraHTTPHeaders", [{"name": "headers", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Network.getResponseBody", [{"name": "requestId", "type": "string", "optional": false}], ["body", "base64Encoded"]);
InspectorBackend.registerCommand("Network.replayXHR", [{"name": "requestId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Network.canClearBrowserCache", [], ["result"]);
InspectorBackend.registerCommand("Network.clearBrowserCache", [], []);
InspectorBackend.registerCommand("Network.canClearBrowserCookies", [], ["result"]);
InspectorBackend.registerCommand("Network.clearBrowserCookies", [], []);
InspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDisabled", "type": "boolean", "optional": false}], []);


InspectorBackend.registerDatabaseDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Database");
InspectorBackend.registerEvent("Database.addDatabase", ["database"]);
InspectorBackend.registerCommand("Database.enable", [], []);
InspectorBackend.registerCommand("Database.disable", [], []);
InspectorBackend.registerCommand("Database.getDatabaseTableNames", [{"name": "databaseId", "type": "string", "optional": false}], ["tableNames"]);
InspectorBackend.registerCommand("Database.executeSQL", [{"name": "databaseId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "values", "sqlError"]);


InspectorBackend.registerIndexedDBDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "IndexedDB");
InspectorBackend.registerCommand("IndexedDB.enable", [], []);
InspectorBackend.registerCommand("IndexedDB.disable", [], []);
InspectorBackend.registerCommand("IndexedDB.requestDatabaseNamesForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["securityOriginWithDatabaseNames"]);
InspectorBackend.registerCommand("IndexedDB.requestDatabase", [{"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}], ["databaseWithObjectStores"]);
InspectorBackend.registerCommand("IndexedDB.requestData", [{"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}, {"name": "indexName", "type": "string", "optional": false}, {"name": "skipCount", "type": "number", "optional": false}, {"name": "pageSize", "type": "number", "optional": false}, {"name": "keyRange", "type": "object", "optional": true}], ["objectStoreDataEntries", "hasMore"]);


InspectorBackend.registerDOMStorageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOMStorage");
InspectorBackend.registerEvent("DOMStorage.addDOMStorage", ["storage"]);
InspectorBackend.registerEvent("DOMStorage.domStorageUpdated", ["storageId"]);
InspectorBackend.registerCommand("DOMStorage.enable", [], []);
InspectorBackend.registerCommand("DOMStorage.disable", [], []);
InspectorBackend.registerCommand("DOMStorage.getDOMStorageEntries", [{"name": "storageId", "type": "string", "optional": false}], ["entries"]);
InspectorBackend.registerCommand("DOMStorage.setDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], ["success"]);
InspectorBackend.registerCommand("DOMStorage.removeDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}], ["success"]);


InspectorBackend.registerApplicationCacheDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "ApplicationCache");
InspectorBackend.registerEvent("ApplicationCache.applicationCacheStatusUpdated", ["frameId", "manifestURL", "status"]);
InspectorBackend.registerEvent("ApplicationCache.networkStateUpdated", ["isNowOnline"]);
InspectorBackend.registerCommand("ApplicationCache.getFramesWithManifests", [], ["frameIds"]);
InspectorBackend.registerCommand("ApplicationCache.enable", [], []);
InspectorBackend.registerCommand("ApplicationCache.getManifestForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["manifestURL"]);
InspectorBackend.registerCommand("ApplicationCache.getApplicationCacheForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["applicationCache"]);


InspectorBackend.registerFileSystemDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "FileSystem");
InspectorBackend.registerCommand("FileSystem.enable", [], []);
InspectorBackend.registerCommand("FileSystem.disable", [], []);
InspectorBackend.registerCommand("FileSystem.requestFileSystemRoot", [{"name": "origin", "type": "string", "optional": false}, {"name": "type", "type": "string", "optional": false}], ["errorCode", "root"]);
InspectorBackend.registerCommand("FileSystem.requestDirectoryContent", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "entries"]);
InspectorBackend.registerCommand("FileSystem.requestMetadata", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "metadata"]);
InspectorBackend.registerCommand("FileSystem.requestFileContent", [{"name": "url", "type": "string", "optional": false}, {"name": "readAsText", "type": "boolean", "optional": false}, {"name": "start", "type": "number", "optional": true}, {"name": "end", "type": "number", "optional": true}, {"name": "charset", "type": "string", "optional": true}], ["errorCode", "content", "charset"]);
InspectorBackend.registerCommand("FileSystem.deleteEntry", [{"name": "url", "type": "string", "optional": false}], ["errorCode"]);


InspectorBackend.registerDOMDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOM");
InspectorBackend.registerEvent("DOM.documentUpdated", []);
InspectorBackend.registerEvent("DOM.setChildNodes", ["parentId", "nodes"]);
InspectorBackend.registerEvent("DOM.attributeModified", ["nodeId", "name", "value"]);
InspectorBackend.registerEvent("DOM.attributeRemoved", ["nodeId", "name"]);
InspectorBackend.registerEvent("DOM.inlineStyleInvalidated", ["nodeIds"]);
InspectorBackend.registerEvent("DOM.characterDataModified", ["nodeId", "characterData"]);
InspectorBackend.registerEvent("DOM.childNodeCountUpdated", ["nodeId", "childNodeCount"]);
InspectorBackend.registerEvent("DOM.childNodeInserted", ["parentNodeId", "previousNodeId", "node"]);
InspectorBackend.registerEvent("DOM.childNodeRemoved", ["parentNodeId", "nodeId"]);
InspectorBackend.registerEvent("DOM.shadowRootPushed", ["hostId", "root"]);
InspectorBackend.registerEvent("DOM.shadowRootPopped", ["hostId", "rootId"]);
InspectorBackend.registerCommand("DOM.getDocument", [], ["root"]);
InspectorBackend.registerCommand("DOM.requestChildNodes", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("DOM.querySelector", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.querySelectorAll", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeIds"]);
InspectorBackend.registerCommand("DOM.setNodeName", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.setNodeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.removeNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("DOM.setAttributeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.setAttributesAsText", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "name", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("DOM.removeAttribute", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.getEventListenersForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["listeners"]);
InspectorBackend.registerCommand("DOM.getOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}], ["outerHTML"]);
InspectorBackend.registerCommand("DOM.setOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "outerHTML", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.performSearch", [{"name": "query", "type": "string", "optional": false}], ["searchId", "resultCount"]);
InspectorBackend.registerCommand("DOM.getSearchResults", [{"name": "searchId", "type": "string", "optional": false}, {"name": "fromIndex", "type": "number", "optional": false}, {"name": "toIndex", "type": "number", "optional": false}], ["nodeIds"]);
InspectorBackend.registerCommand("DOM.discardSearchResults", [{"name": "searchId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.requestNode", [{"name": "objectId", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.setInspectModeEnabled", [{"name": "enabled", "type": "boolean", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.highlightRect", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.highlightNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("DOM.hideHighlight", [], []);
InspectorBackend.registerCommand("DOM.highlightFrame", [{"name": "frameId", "type": "string", "optional": false}, {"name": "contentColor", "type": "object", "optional": true}, {"name": "contentOutlineColor", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.pushNodeByPathToFrontend", [{"name": "path", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.resolveNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["object"]);
InspectorBackend.registerCommand("DOM.getAttributes", [{"name": "nodeId", "type": "number", "optional": false}], ["attributes"]);
InspectorBackend.registerCommand("DOM.moveTo", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "targetNodeId", "type": "number", "optional": false}, {"name": "insertBeforeNodeId", "type": "number", "optional": true}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.undo", [], []);
InspectorBackend.registerCommand("DOM.redo", [], []);
InspectorBackend.registerCommand("DOM.markUndoableState", [], []);


InspectorBackend.registerCSSDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "CSS");
InspectorBackend.registerEvent("CSS.mediaQueryResultChanged", []);
InspectorBackend.registerEvent("CSS.styleSheetChanged", ["styleSheetId"]);
InspectorBackend.registerEvent("CSS.namedFlowCreated", ["namedFlow"]);
InspectorBackend.registerEvent("CSS.namedFlowRemoved", ["documentNodeId", "flowName"]);
InspectorBackend.registerEvent("CSS.regionLayoutUpdated", ["namedFlow"]);
InspectorBackend.registerCommand("CSS.enable", [], []);
InspectorBackend.registerCommand("CSS.disable", [], []);
InspectorBackend.registerCommand("CSS.getMatchedStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "includePseudo", "type": "boolean", "optional": true}, {"name": "includeInherited", "type": "boolean", "optional": true}], ["matchedCSSRules", "pseudoElements", "inherited"]);
InspectorBackend.registerCommand("CSS.getInlineStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["inlineStyle", "attributesStyle"]);
InspectorBackend.registerCommand("CSS.getComputedStyleForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["computedStyle"]);
InspectorBackend.registerCommand("CSS.getAllStyleSheets", [], ["headers"]);
InspectorBackend.registerCommand("CSS.getStyleSheet", [{"name": "styleSheetId", "type": "string", "optional": false}], ["styleSheet"]);
InspectorBackend.registerCommand("CSS.getStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}], ["text"]);
InspectorBackend.registerCommand("CSS.setStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "text", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("CSS.setPropertyText", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "overwrite", "type": "boolean", "optional": false}], ["style"]);
InspectorBackend.registerCommand("CSS.toggleProperty", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "disable", "type": "boolean", "optional": false}], ["style"]);
InspectorBackend.registerCommand("CSS.setRuleSelector", [{"name": "ruleId", "type": "object", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
InspectorBackend.registerCommand("CSS.addRule", [{"name": "contextNodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
InspectorBackend.registerCommand("CSS.getSupportedCSSProperties", [], ["cssProperties"]);
InspectorBackend.registerCommand("CSS.forcePseudoState", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "forcedPseudoClasses", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("CSS.startSelectorProfiler", [], []);
InspectorBackend.registerCommand("CSS.stopSelectorProfiler", [], ["profile"]);
InspectorBackend.registerCommand("CSS.getNamedFlowCollection", [{"name": "documentNodeId", "type": "number", "optional": false}], ["namedFlows"]);


InspectorBackend.registerTimelineDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Timeline");
InspectorBackend.registerEvent("Timeline.eventRecorded", ["record"]);
InspectorBackend.registerCommand("Timeline.start", [{"name": "maxCallStackDepth", "type": "number", "optional": true}], []);
InspectorBackend.registerCommand("Timeline.stop", [], []);
InspectorBackend.registerCommand("Timeline.setIncludeMemoryDetails", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Timeline.supportsFrameInstrumentation", [], ["result"]);


InspectorBackend.registerDebuggerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Debugger");
InspectorBackend.registerEvent("Debugger.globalObjectCleared", []);
InspectorBackend.registerEvent("Debugger.scriptParsed", ["scriptId", "url", "startLine", "startColumn", "endLine", "endColumn", "isContentScript", "sourceMapURL"]);
InspectorBackend.registerEvent("Debugger.scriptFailedToParse", ["url", "scriptSource", "startLine", "errorLine", "errorMessage"]);
InspectorBackend.registerEvent("Debugger.breakpointResolved", ["breakpointId", "location"]);
InspectorBackend.registerEvent("Debugger.paused", ["callFrames", "reason", "data"]);
InspectorBackend.registerEvent("Debugger.resumed", []);
InspectorBackend.registerCommand("Debugger.causesRecompilation", [], ["result"]);
InspectorBackend.registerCommand("Debugger.supportsSeparateScriptCompilationAndExecution", [], ["result"]);
InspectorBackend.registerCommand("Debugger.enable", [], []);
InspectorBackend.registerCommand("Debugger.disable", [], []);
InspectorBackend.registerCommand("Debugger.setBreakpointsActive", [{"name": "active", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.setBreakpointByUrl", [{"name": "lineNumber", "type": "number", "optional": false}, {"name": "url", "type": "string", "optional": true}, {"name": "urlRegex", "type": "string", "optional": true}, {"name": "columnNumber", "type": "number", "optional": true}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "locations"]);
InspectorBackend.registerCommand("Debugger.setBreakpoint", [{"name": "location", "type": "object", "optional": false}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "actualLocation"]);
InspectorBackend.registerCommand("Debugger.removeBreakpoint", [{"name": "breakpointId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.continueToLocation", [{"name": "location", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.stepOver", [], []);
InspectorBackend.registerCommand("Debugger.stepInto", [], []);
InspectorBackend.registerCommand("Debugger.stepOut", [], []);
InspectorBackend.registerCommand("Debugger.pause", [], []);
InspectorBackend.registerCommand("Debugger.resume", [], []);
InspectorBackend.registerCommand("Debugger.searchInContent", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Debugger.canSetScriptSource", [], ["result"]);
InspectorBackend.registerCommand("Debugger.setScriptSource", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "scriptSource", "type": "string", "optional": false}, {"name": "preview", "type": "boolean", "optional": true}], ["callFrames", "result"]);
InspectorBackend.registerCommand("Debugger.restartFrame", [{"name": "callFrameId", "type": "string", "optional": false}], ["callFrames", "result"]);
InspectorBackend.registerCommand("Debugger.getScriptSource", [{"name": "scriptId", "type": "string", "optional": false}], ["scriptSource"]);
InspectorBackend.registerCommand("Debugger.getFunctionDetails", [{"name": "functionId", "type": "string", "optional": false}], ["details"]);
InspectorBackend.registerCommand("Debugger.setPauseOnExceptions", [{"name": "state", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.evaluateOnCallFrame", [{"name": "callFrameId", "type": "string", "optional": false}, {"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Debugger.compileScript", [{"name": "expression", "type": "string", "optional": false}, {"name": "sourceURL", "type": "string", "optional": false}], ["scriptId", "syntaxErrorMessage"]);
InspectorBackend.registerCommand("Debugger.runScript", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "contextId", "type": "number", "optional": true}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Debugger.setOverlayMessage", [{"name": "message", "type": "string", "optional": true}], []);


InspectorBackend.registerCommand("DOMDebugger.setDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);


InspectorBackend.registerProfilerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Profiler");
InspectorBackend.registerEvent("Profiler.addProfileHeader", ["header"]);
InspectorBackend.registerEvent("Profiler.addHeapSnapshotChunk", ["uid", "chunk"]);
InspectorBackend.registerEvent("Profiler.finishHeapSnapshot", ["uid"]);
InspectorBackend.registerEvent("Profiler.setRecordingProfile", ["isProfiling"]);
InspectorBackend.registerEvent("Profiler.resetProfiles", []);
InspectorBackend.registerEvent("Profiler.reportHeapSnapshotProgress", ["done", "total"]);
InspectorBackend.registerCommand("Profiler.causesRecompilation", [], ["result"]);
InspectorBackend.registerCommand("Profiler.isSampling", [], ["result"]);
InspectorBackend.registerCommand("Profiler.hasHeapProfiler", [], ["result"]);
InspectorBackend.registerCommand("Profiler.enable", [], []);
InspectorBackend.registerCommand("Profiler.disable", [], []);
InspectorBackend.registerCommand("Profiler.start", [], []);
InspectorBackend.registerCommand("Profiler.stop", [], []);
InspectorBackend.registerCommand("Profiler.getProfileHeaders", [], ["headers"]);
InspectorBackend.registerCommand("Profiler.getProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], ["profile"]);
InspectorBackend.registerCommand("Profiler.removeProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Profiler.clearProfiles", [], []);
InspectorBackend.registerCommand("Profiler.takeHeapSnapshot", [], []);
InspectorBackend.registerCommand("Profiler.collectGarbage", [], []);
InspectorBackend.registerCommand("Profiler.getObjectByHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Profiler.getHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}], ["heapSnapshotObjectId"]);


InspectorBackend.registerWorkerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Worker");
InspectorBackend.registerEvent("Worker.workerCreated", ["workerId", "url", "inspectorConnected"]);
InspectorBackend.registerEvent("Worker.workerTerminated", ["workerId"]);
InspectorBackend.registerEvent("Worker.dispatchMessageFromWorker", ["workerId", "message"]);
InspectorBackend.registerEvent("Worker.disconnectedFromWorker", []);
InspectorBackend.registerCommand("Worker.enable", [], []);
InspectorBackend.registerCommand("Worker.disable", [], []);
InspectorBackend.registerCommand("Worker.sendMessageToWorker", [{"name": "workerId", "type": "number", "optional": false}, {"name": "message", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Worker.connectToWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Worker.disconnectFromWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Worker.setAutoconnectToWorkers", [{"name": "value", "type": "boolean", "optional": false}], []);


InspectorBackend.registerWebGLDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "WebGL");
InspectorBackend.registerCommand("WebGL.enable", [], []);
InspectorBackend.registerCommand("WebGL.disable", [], []);
InspectorBackend.registerCommand("WebGL.dropTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("WebGL.captureFrame", [], ["traceLogId"]);
InspectorBackend.registerCommand("WebGL.getTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], ["traceLog"]);
InspectorBackend.registerCommand("WebGL.replayTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}, {"name": "stepNo", "type": "number", "optional": false}], ["screenshotDataUrl"]);







if (!window.InspectorExtensionRegistry) {


WebInspector.InspectorExtensionRegistryStub = function()
{
}

WebInspector.InspectorExtensionRegistryStub.prototype = {
getExtensionsAsync: function()
{
}
}

var InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub();

}





InspectorFrontendAPI = {
_pendingCommands: [],

isDebuggingEnabled: function()
{
return WebInspector.debuggerModel.debuggerEnabled();
},

setDebuggingEnabled: function(enabled)
{
if (enabled) {
WebInspector.debuggerModel.enableDebugger();
WebInspector.showPanel("scripts");
} else
WebInspector.debuggerModel.disableDebugger();
},

isTimelineProfilingEnabled: function()
{
return WebInspector.panels.timeline && WebInspector.panels.timeline.timelineProfilingEnabled;
},

setTimelineProfilingEnabled: function(enabled)
{
WebInspector.showPanel("timeline").setTimelineProfilingEnabled(enabled);
},

isProfilingJavaScript: function()
{
return WebInspector.panels.profiles && WebInspector.CPUProfileType.instance && WebInspector.CPUProfileType.instance.isRecordingProfile();
},

startProfilingJavaScript: function()
{
WebInspector.showPanel("profiles").enableProfiler();
if (WebInspector.CPUProfileType.instance)
WebInspector.CPUProfileType.instance.startRecordingProfile();
},

stopProfilingJavaScript: function()
{
WebInspector.showPanel("profiles");
if (WebInspector.CPUProfileType.instance)
WebInspector.CPUProfileType.instance.stopRecordingProfile();
},

setAttachedWindow: function(attached)
{
WebInspector.attached = attached;
},

showConsole: function()
{
WebInspector.showPanel("console");
},

showMainResourceForFrame: function(frameId)
{

},

showResources: function()
{
WebInspector.showPanel("resources");
},

setDockingUnavailable: function(unavailable)
{
WebInspector.setDockingUnavailable(unavailable);
},

enterInspectElementMode: function()
{
WebInspector.toggleSearchingForNode();
},

savedURL: function(url)
{
WebInspector.fileManager.savedURL(url);
},

appendedToURL: function(url)
{
WebInspector.fileManager.appendedToURL(url);
},

setToolbarColors: function(backgroundColor, color)
{
WebInspector.setToolbarColors(backgroundColor, color);
},

evaluateForTest: function(callId, script)
{
WebInspector.evaluateForTestInFrontend(callId, script);
},

dispatch: function(signature)
{
if (InspectorFrontendAPI._isLoaded) {
var methodName = signature.shift();
return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature);
}
InspectorFrontendAPI._pendingCommands.push(signature);
},

dispatchQueryParameters: function()
{
if ("dispatch" in WebInspector.queryParamsObject)
InspectorFrontendAPI.dispatch(JSON.parse(window.decodeURI(WebInspector.queryParamsObject["dispatch"])));
},


loadTimelineFromURL: function(url) 
{
WebInspector.showPanel("timeline").loadFromURL(url);
},

loadCompleted: function()
{
InspectorFrontendAPI._isLoaded = true;
for (var i = 0; i < InspectorFrontendAPI._pendingCommands.length; ++i)
InspectorFrontendAPI.dispatch(InspectorFrontendAPI._pendingCommands[i]);
InspectorFrontendAPI._pendingCommands = [];
if (window.opener)
window.opener.postMessage(["loadCompleted"], "*");
}
}

if (window.opener) {
function onMessageFromOpener(event)
{
if (event.source === window.opener)
InspectorFrontendAPI.dispatch(event.data);
}
window.addEventListener("message", onMessageFromOpener, true);
}






WebInspector.Object = function() {
}

WebInspector.Object.prototype = {

addEventListener: function(eventType, listener, thisObject)
{
console.assert(listener);

if (!this._listeners)
this._listeners = {};
if (!this._listeners[eventType])
this._listeners[eventType] = [];
this._listeners[eventType].push({ thisObject: thisObject, listener: listener });
},


removeEventListener: function(eventType, listener, thisObject)
{
console.assert(listener);

if (!this._listeners || !this._listeners[eventType])
return;
var listeners = this._listeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
if (listener && listeners[i].listener === listener && listeners[i].thisObject === thisObject)
listeners.splice(i, 1);
else if (!listener && thisObject && listeners[i].thisObject === thisObject)
listeners.splice(i, 1);
}

if (!listeners.length)
delete this._listeners[eventType];
},

removeAllListeners: function()
{
delete this._listeners;
},


hasEventListeners: function(eventType)
{
if (!this._listeners || !this._listeners[eventType])
return false;
return true;
},


dispatchEventToListeners: function(eventType, eventData)
{
if (!this._listeners || !this._listeners[eventType])
return false;

var event = new WebInspector.Event(this, eventType, eventData);
var listeners = this._listeners[eventType].slice(0);
for (var i = 0; i < listeners.length; ++i) {
listeners[i].listener.call(listeners[i].thisObject, event);
if (event._stoppedPropagation)
break;
}

return event.defaultPrevented;
}
}


WebInspector.Event = function(target, type, data)
{
this.target = target;
this.type = type;
this.data = data;
this.defaultPrevented = false;
this._stoppedPropagation = false;
}

WebInspector.Event.prototype = {
stopPropagation: function()
{
this._stoppedPropagation = true;
},

preventDefault: function()
{
this.defaultPrevented = true;
},


consume: function(preventDefault)
{
this.stopPropagation();
if (preventDefault)
this.preventDefault();
}
}

WebInspector.notifications = new WebInspector.Object();






var Preferences = {
maxInlineTextChildLength: 80,
minConsoleHeight: 75,
minSidebarWidth: 100,
minElementsSidebarWidth: 200,
minScriptsSidebarWidth: 200,
styleRulesExpandedState: {},
showMissingLocalizedStrings: false,
useLowerCaseMenuTitlesOnWindows: false,
sharedWorkersDebugNote: undefined,
localizeUI: true,
exposeDisableCache: false,
applicationTitle: "Web Inspector - %s",
showDockToRight: false,
exposeFileSystemInspection: false
}

var Capabilities = {
samplingCPUProfiler: false,
debuggerCausesRecompilation: true,
separateScriptCompilationAndExecutionEnabled: false,
profilerCausesRecompilation: true,
heapProfilerPresent: false,
canOverrideDeviceMetrics: false,
timelineSupportsFrameInstrumentation: false,
canOverrideGeolocation: false,
canOverrideDeviceOrientation: false,
}


WebInspector.Settings = function()
{
this._eventSupport = new WebInspector.Object();

this.colorFormat = this.createSetting("colorFormat", "hex");
this.consoleHistory = this.createSetting("consoleHistory", []);
this.debuggerEnabled = this.createSetting("debuggerEnabled", false);
this.domWordWrap = this.createSetting("domWordWrap", true);
this.profilerEnabled = this.createSetting("profilerEnabled", false);
this.eventListenersFilter = this.createSetting("eventListenersFilter", "all");
this.lastActivePanel = this.createSetting("lastActivePanel", "elements");
this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application");
this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false);
this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false);
this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true);
this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
this.resourceViewTab = this.createSetting("resourceViewTab", "preview");
this.showInheritedComputedStyleProperties = this.createSetting("showInheritedComputedStyleProperties", false);
this.showUserAgentStyles = this.createSetting("showUserAgentStyles", true);
this.watchExpressions = this.createSetting("watchExpressions", []);
this.breakpoints = this.createSetting("breakpoints", []);
this.eventListenerBreakpoints = this.createSetting("eventListenerBreakpoints", []);
this.domBreakpoints = this.createSetting("domBreakpoints", []);
this.xhrBreakpoints = this.createSetting("xhrBreakpoints", []);
this.sourceMapsEnabled = this.createSetting("sourceMapsEnabled", false);
this.cacheDisabled = this.createSetting("cacheDisabled", false);
this.overrideUserAgent = this.createSetting("overrideUserAgent", "");
this.userAgent = this.createSetting("userAgent", "");
this.deviceMetrics = this.createSetting("deviceMetrics", "");
this.deviceFitWindow = this.createSetting("deviceFitWindow", false);
this.showScriptFolders = this.createSetting("showScriptFolders", true);
this.dockToRight = this.createSetting("dockToRight", false);
this.emulateTouchEvents = this.createSetting("emulateTouchEvents", false);
this.showPaintRects = this.createSetting("showPaintRects", false);
this.zoomLevel = this.createSetting("zoomLevel", 0);
this.savedURLs = this.createSetting("savedURLs", {});
this.javaScriptDisabled = this.createSetting("javaScriptDisabled", false);
this.geolocationOverride = this.createSetting("geolocationOverride", "");
this.deviceOrientationOverride = this.createSetting("deviceOrientationOverride", "");
this.showHeapSnapshotObjectsHiddenProperties = this.createSetting("showHeaSnapshotObjectsHiddenProperties", false);
this.searchInContentScripts = this.createSetting("searchInContentScripts", false);
this.textEditorIndent = this.createSetting("textEditorIndent", "    ");



if (this.breakpoints.get().length > 500000)
this.breakpoints.set([]);
}

WebInspector.Settings.prototype = {

createSetting: function(key, defaultValue)
{
return new WebInspector.Setting(key, defaultValue, this._eventSupport);
}
}


WebInspector.Setting = function(name, defaultValue, eventSupport)
{
this._name = name;
this._defaultValue = defaultValue;
this._eventSupport = eventSupport;
}

WebInspector.Setting.prototype = {
addChangeListener: function(listener, thisObject)
{
this._eventSupport.addEventListener(this._name, listener, thisObject);
},

removeChangeListener: function(listener, thisObject)
{
this._eventSupport.removeEventListener(this._name, listener, thisObject);
},

get name()
{
return this._name;
},

get: function()
{
if (typeof this._value !== "undefined")
return this._value;

this._value = this._defaultValue;
if (window.localStorage != null && this._name in window.localStorage) {
try {
this._value = JSON.parse(window.localStorage[this._name]);
} catch(e) {
window.localStorage.removeItem(this._name);
}
}
return this._value;
},

set: function(value)
{
this._value = value;
if (window.localStorage != null) {
try {
window.localStorage[this._name] = JSON.stringify(value);
} catch(e) {
console.error("Error saving setting with name:" + this._name);
}
}
this._eventSupport.dispatchEventToListeners(this._name, value);
}
}


WebInspector.ExperimentsSettings = function()
{
this._setting = WebInspector.settings.createSetting("experiments", {});
this._experiments = [];
this._enabledForTest = {};


this.showShadowDOM = this._createExperiment("showShadowDOM", "Show shadow DOM");
this.snippetsSupport = this._createExperiment("snippetsSupport", "Snippets support");
this.nativeMemorySnapshots = this._createExperiment("nativeMemorySnapshots", "Native memory profiling");
this.liveNativeMemoryChart = this._createExperiment("liveNativeMemoryChart", "Live native memory chart");
this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection");
this.webGLInspection = this._createExperiment("webGLInspection ", "WebGL inspection");
this.mainThreadMonitoring = this._createExperiment("mainThreadMonitoring", "Show CPU activity in Timeline");
this.geolocationOverride = this._createExperiment("geolocationOverride", "Override Device Geolocation");
this.deviceOrientationOverride = this._createExperiment("deviceOrientationOverride", "Override Device Orientation");
this.sass = this._createExperiment("sass", "Support for SASS");
this.codemirror = this._createExperiment("codemirror", "Use CodeMirror editor");
this.cssRegions = this._createExperiment("cssRegions", "CSS Regions Support");

this._cleanUpSetting();
}

WebInspector.ExperimentsSettings.prototype = {

get experiments()
{
return this._experiments.slice();
},


get experimentsEnabled()
{
return "experiments" in WebInspector.queryParamsObject;
},


_createExperiment: function(experimentName, experimentTitle)
{
var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle);
this._experiments.push(experiment);
return experiment;
},


isEnabled: function(experimentName)
{
if (this._enabledForTest[experimentName])
return true;

if (!this.experimentsEnabled)
return false;

var experimentsSetting = this._setting.get();
return experimentsSetting[experimentName];
},


setEnabled: function(experimentName, enabled)
{
var experimentsSetting = this._setting.get();
experimentsSetting[experimentName] = enabled;
this._setting.set(experimentsSetting);
},


_enableForTest: function(experimentName)
{
this._enabledForTest[experimentName] = true;
},

_cleanUpSetting: function()
{
var experimentsSetting = this._setting.get();
var cleanedUpExperimentSetting = {};
for (var i = 0; i < this._experiments.length; ++i) {
var experimentName = this._experiments[i].name;
if (experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName] = true;
}
this._setting.set(cleanedUpExperimentSetting);
}
}


WebInspector.Experiment = function(experimentsSettings, name, title)
{
this._name = name;
this._title = title;
this._experimentsSettings = experimentsSettings;
}

WebInspector.Experiment.prototype = {

get name()
{
return this._name;
},


get title()
{
return this._title;
},


isEnabled: function()
{
return this._experimentsSettings.isEnabled(this._name);
},


setEnabled: function(enabled)
{
return this._experimentsSettings.setEnabled(this._name, enabled);
},

enableForTest: function()
{
this._experimentsSettings._enableForTest(this._name);
}
}

WebInspector.settings = new WebInspector.Settings();
WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings();






WebInspector.View = function()
{
this.element = document.createElement("div");
this.element.__view = this;
this._visible = true;
this._isRoot = false;
this._isShowing = false;
this._children = [];
this._hideOnDetach = false;
this._cssFiles = [];
}

WebInspector.View._cssFileToVisibleViewCount = {};
WebInspector.View._cssFileToStyleElement = {};

WebInspector.View.prototype = {
markAsRoot: function()
{
this._isRoot = true;
},

isShowing: function()
{
return this._isShowing;
},

setHideOnDetach: function()
{
this._hideOnDetach = true;
},

_parentIsShowing: function()
{
return this._isRoot || (this._parentView && this._parentView.isShowing());
},

_callOnVisibleChildren: function(method)
{
for (var i = 0; i < this._children.length; ++i)
if (this._children[i]._visible)
method.call(this._children[i]);
},

_processWillShow: function()
{
this._loadCSSIfNeeded();
this._callOnVisibleChildren(this._processWillShow);
},

_processWasShown: function()
{
this._isShowing = true;
this.restoreScrollPositions();

this.wasShown();
this.onResize();

this._callOnVisibleChildren(this._processWasShown);
},

_processWillHide: function()
{
this.storeScrollPositions();

this._callOnVisibleChildren(this._processWillHide);

this.willHide();
this._isShowing = false;
},

_processWasHidden: function()
{
this._disableCSSIfNeeded();
this._callOnVisibleChildren(this._processWasHidden);
},

_processOnResize: function()
{
if (!this.isShowing())
return;

this.onResize();
this._callOnVisibleChildren(this._processOnResize);
},

wasShown: function()
{
},

willHide: function()
{
},

onResize: function()
{
},


show: function(parentElement, insertBefore)
{
WebInspector.View._assert(parentElement, "Attempt to attach view with no parent element");


if (this.element.parentElement !== parentElement) {
var currentParent = parentElement;
while (currentParent && !currentParent.__view)
currentParent = currentParent.parentElement;

if (currentParent) {
this._parentView = currentParent.__view;
this._parentView._children.push(this);
this._isRoot = false;
} else
WebInspector.View._assert(this._isRoot, "Attempt to attach view to orphan node");
} else if (this._visible)
return;

this._visible = true;
if (this._parentIsShowing())
this._processWillShow();

this.element.addStyleClass("visible");


if (this.element.parentElement !== parentElement) {
WebInspector.View._incrementViewCounter(parentElement, this.element);
if (insertBefore)
WebInspector.View._originalInsertBefore.call(parentElement, this.element, insertBefore);
else
WebInspector.View._originalAppendChild.call(parentElement, this.element);
}

if (this._parentIsShowing())
this._processWasShown();
},


detach: function(overrideHideOnDetach)
{
var parentElement = this.element.parentElement;
if (!parentElement)
return;

if (this._parentIsShowing())
this._processWillHide();

if (this._hideOnDetach && !overrideHideOnDetach) {
this.element.removeStyleClass("visible");
this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();
return;
}


WebInspector.View._decrementViewCounter(parentElement, this.element);
WebInspector.View._originalRemoveChild.call(parentElement, this.element);

this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();


if (this._parentView) {
var childIndex = this._parentView._children.indexOf(this);
WebInspector.View._assert(childIndex >= 0, "Attempt to remove non-child view");
this._parentView._children.splice(childIndex, 1);
this._parentView = null;
} else
WebInspector.View._assert(this._isRoot, "Removing non-root view from DOM");
},

detachChildViews: function()
{
var children = this._children.slice();
for (var i = 0; i < children.length; ++i)
children[i].detach();
},

elementsToRestoreScrollPositionsFor: function()
{
return [this.element];
},

storeScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
container._scrollTop = container.scrollTop;
container._scrollLeft = container.scrollLeft;
}
},

restoreScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
if (container._scrollTop)
container.scrollTop = container._scrollTop;
if (container._scrollLeft)
container.scrollLeft = container._scrollLeft;
}
},

canHighlightLine: function()
{
return false;
},

highlightLine: function(line)
{
},

doResize: function()
{
this._processOnResize();
},

registerRequiredCSS: function(cssFile)
{
this._cssFiles.push(cssFile);
},

_loadCSSIfNeeded: function()
{
for (var i = 0; i < this._cssFiles.length; ++i) {
var cssFile = this._cssFiles[i];

var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile];
WebInspector.View._cssFileToVisibleViewCount[cssFile] = (viewsWithCSSFile || 0) + 1;
if (!viewsWithCSSFile)
this._doLoadCSS(cssFile);
}
},

_doLoadCSS: function(cssFile)
{
var styleElement = WebInspector.View._cssFileToStyleElement[cssFile];
if (styleElement) {
styleElement.disabled = false;
return;
}

if (window.debugCSS) {  
styleElement = document.createElement("link");
styleElement.rel = "stylesheet";
styleElement.type = "text/css";
styleElement.href = cssFile;
} else {
var xhr = new XMLHttpRequest();
xhr.open("GET", cssFile, false);
xhr.send(null);

styleElement = document.createElement("style");
styleElement.type = "text/css";
styleElement.textContent = xhr.responseText;
}
document.head.insertBefore(styleElement, document.head.firstChild);

WebInspector.View._cssFileToStyleElement[cssFile] = styleElement;
},

_disableCSSIfNeeded: function()
{
for (var i = 0; i < this._cssFiles.length; ++i) {
var cssFile = this._cssFiles[i];

var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile];
viewsWithCSSFile--;
WebInspector.View._cssFileToVisibleViewCount[cssFile] = viewsWithCSSFile;

if (!viewsWithCSSFile)
this._doUnloadCSS(cssFile);
}
},

_doUnloadCSS: function(cssFile)
{
var styleElement = WebInspector.View._cssFileToStyleElement[cssFile];
styleElement.disabled = true;
},

printViewHierarchy: function()
{
var lines = [];
this._collectViewHierarchy("", lines);
console.log(lines.join("\n"));
},

_collectViewHierarchy: function(prefix, lines)
{
lines.push(prefix + "[" + this.element.className + "]" + (this._children.length ? " {" : ""));

for (var i = 0; i < this._children.length; ++i)
this._children[i]._collectViewHierarchy(prefix + "    ", lines);

if (this._children.length)
lines.push(prefix + "}");
},


defaultFocusedElement: function()
{
return this._defaultFocusedElement || this.element;
},


setDefaultFocusedElement: function(element)
{
this._defaultFocusedElement = element;
},

focus: function()
{
var element = this.defaultFocusedElement();
if (!element || element.isAncestor(document.activeElement))
return;

WebInspector.setCurrentFocusElement(element);
}
}

WebInspector.View.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.View._originalAppendChild = Element.prototype.appendChild;
WebInspector.View._originalInsertBefore = Element.prototype.insertBefore;
WebInspector.View._originalRemoveChild = Element.prototype.removeChild;
WebInspector.View._originalRemoveChildren = Element.prototype.removeChildren;

WebInspector.View._incrementViewCounter = function(parentElement, childElement)
{
var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0);
if (!count)
return;

while (parentElement) {
parentElement.__viewCounter = (parentElement.__viewCounter || 0) + count;
parentElement = parentElement.parentElement;
}
}

WebInspector.View._decrementViewCounter = function(parentElement, childElement)
{
var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0);
if (!count)
return;

while (parentElement) {
parentElement.__viewCounter -= count;
parentElement = parentElement.parentElement;
}
}

WebInspector.View._assert = function(condition, message)
{
if (!condition) {
console.trace();
throw new Error(message);
}
}

Element.prototype.appendChild = function(child)
{
WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
return WebInspector.View._originalAppendChild.call(this, child);
}

Element.prototype.insertBefore = function(child, anchor)
{
WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
return WebInspector.View._originalInsertBefore.call(this, child, anchor);
}


Element.prototype.removeChild = function(child)
{
WebInspector.View._assert(!child.__viewCounter && !child.__view, "Attempt to remove element containing view via regular DOM operation");
return WebInspector.View._originalRemoveChild.call(this, child);
}

Element.prototype.removeChildren = function()
{
WebInspector.View._assert(!this.__viewCounter, "Attempt to remove element containing view via regular DOM operation");
WebInspector.View._originalRemoveChildren.call(this);
}






WebInspector.HelpScreen = function(title)
{
WebInspector.View.call(this);
this.markAsRoot();
this.registerRequiredCSS("helpScreen.css");

this.element.className = "help-window-outer";
this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
this.element.tabIndex = 0;
this.element.addEventListener("focus", this._onBlur.bind(this), false);

if (title) {
var mainWindow = this.element.createChild("div", "help-window-main");
var captionWindow = mainWindow.createChild("div", "help-window-caption");
captionWindow.appendChild(this._createCloseButton());
this.contentElement = mainWindow.createChild("div", "help-content");
captionWindow.createChild("h1", "help-window-title").textContent = title;
}
}


WebInspector.HelpScreen._visibleScreen = null;

WebInspector.HelpScreen.prototype = {
_createCloseButton: function()
{
var closeButton = document.createElement("button");
closeButton.className = "help-close-button";
closeButton.textContent = "\u2716"; 
closeButton.addEventListener("click", this.hide.bind(this), false);
return closeButton;
},

showModal: function()
{
var visibleHelpScreen = WebInspector.HelpScreen._visibleScreen;
if (visibleHelpScreen === this)
return;

if (visibleHelpScreen)
visibleHelpScreen.hide();
WebInspector.HelpScreen._visibleScreen = this;
this.show(document.body);
this.focus();
},

hide: function()
{
if (!this.isShowing())
return;

WebInspector.HelpScreen._visibleScreen = null;

WebInspector.restoreFocusFromElement(this.element);
this.detach();
},


isClosingKey: function(keyCode)
{
return [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
WebInspector.KeyboardShortcut.Keys.Space.code,
].indexOf(keyCode) >= 0;
},

_onKeyDown: function(event)
{
if (this.isShowing() && this.isClosingKey(event.keyCode)) {
this.hide();
event.consume();
}
},

_onBlur: function(event)
{

if (this.isShowing() && !this.element.isSelfOrAncestor(event.target))
WebInspector.setCurrentFocusElement(this.element);
}
}

WebInspector.HelpScreen.prototype.__proto__ = WebInspector.View.prototype;





if (!window.InspectorFrontendHost) {


WebInspector.InspectorFrontendHostStub = function()
{
this._attachedWindowHeight = 0;
this.isStub = true;
WebInspector.documentCopyEventFired = this.documentCopy.bind(this);
}

WebInspector.InspectorFrontendHostStub.prototype = {
platform: function()
{
var match = navigator.userAgent.match(/Windows NT/);
if (match)
return "windows";
match = navigator.userAgent.match(/Mac OS X/);
if (match)
return "mac";
return "linux";
},

port: function()
{
return "unknown";
},

bringToFront: function()
{
this._windowVisible = true;
},

closeWindow: function()
{
this._windowVisible = false;
},

requestAttachWindow: function()
{
},

requestDetachWindow: function()
{
},

requestSetDockSide: function()
{
},

setAttachedWindowHeight: function(height)
{
},

moveWindowBy: function(x, y)
{
},

setInjectedScriptForOrigin: function(origin, script)
{
},

loaded: function()
{
},

localizedStringsURL: function()
{
return undefined;
},

hiddenPanels: function()
{
return WebInspector.queryParamsObject["hiddenPanels"] || "";
},

inspectedURLChanged: function(url)
{
document.title = WebInspector.UIString(Preferences.applicationTitle, url);
},

documentCopy: function(event)
{
if (!this._textToCopy)
return;
event.clipboardData.setData("text", this._textToCopy);
event.preventDefault();
delete this._textToCopy;
},

copyText: function(text)
{
this._textToCopy = text;
if (!document.execCommand("copy")) {
var screen = new WebInspector.ClipboardAccessDeniedScreen();
screen.showModal();
}
},

openInNewTab: function(url)
{
window.open(url, "_blank");
},

canSave: function()
{
return true;
},

save: function(url, content, forceSaveAs)
{
var builder = new WebKitBlobBuilder();
builder.append(content);
var blob = builder.getBlob("application/octet-stream");

var fr = new FileReader();
fr.onload = function(e) {

window.location = this.result;
}
fr.readAsDataURL(blob);
},

canAppend: function()
{
return false;
},

append: function(url, content)
{
},

sendMessageToBackend: function(message)
{
},

recordActionTaken: function(actionCode)
{
},

recordPanelShown: function(panelCode)
{
},

recordSettingChanged: function(settingCode)
{
},

loadResourceSynchronously: function(url)
{
return loadXHR(url);
},

setZoomFactor: function(zoom)
{
},

canInspectWorkers: function()
{
return true;
}
}

InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();
Preferences.localizeUI = false;


WebInspector.clipboardAccessDeniedMessage = function()
{
return "";
}


WebInspector.ClipboardAccessDeniedScreen = function()
{
WebInspector.HelpScreen.call(this, WebInspector.UIString("Clipboard access is denied"));
var platformMessage = WebInspector.clipboardAccessDeniedMessage();
if (platformMessage) {
var p = this.contentElement.createChild("p");
p.addStyleClass("help-section");
p.textContent = platformMessage;
}
}

WebInspector.ClipboardAccessDeniedScreen.prototype.__proto__ = WebInspector.HelpScreen.prototype;

}






WebInspector.FileManager = function()
{
}

WebInspector.FileManager.EventTypes = {
SavedURL: "SavedURL",
AppendedToURL: "AppendedToURL"
}

WebInspector.FileManager.prototype = {

canSave: function()
{
return InspectorFrontendHost.canSave();
},


canAppend: function()
{
return InspectorFrontendHost.canSave() && ("append" in InspectorFrontendHost);
},


save: function(url, content, forceSaveAs)
{

var savedURLs = WebInspector.settings.savedURLs.get();
delete savedURLs[url];
WebInspector.settings.savedURLs.set(savedURLs);
InspectorFrontendHost.save(url, content, forceSaveAs);
},


savedURL: function(url)
{
var savedURLs = WebInspector.settings.savedURLs.get();
savedURLs[url] = true;
WebInspector.settings.savedURLs.set(savedURLs);
this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.SavedURL, url);
},


isURLSaved: function(url)
{
var savedURLs = WebInspector.settings.savedURLs.get();
return savedURLs[url];
},


append: function(url, content)
{
InspectorFrontendHost.append(url, content);
},


appendedToURL: function(url)
{
this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.AppendedToURL, url);
}
}

WebInspector.FileManager.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.fileManager = new WebInspector.FileManager();






WebInspector.Checkbox = function(label, className, tooltip)
{
this.element = document.createElement('label');
this._inputElement = document.createElement('input');
this._inputElement.type = "checkbox";

this.element.className = className;
this.element.appendChild(this._inputElement);
this.element.appendChild(document.createTextNode(label));
if (tooltip)
this.element.title = tooltip;
}

WebInspector.Checkbox.prototype = {
set checked(checked)
{
this._inputElement.checked = checked;
},

get checked()
{
return this._inputElement.checked;
},

addEventListener: function(listener)
{
function listenerWrapper(event)
{
if (listener)
listener(event);
event.consume();
return true;
}

this._inputElement.addEventListener("click", listenerWrapper, false);
this.element.addEventListener("click", listenerWrapper, false);
}
}






WebInspector.ContextMenuItem = function(topLevelMenu, type, label, disabled, checked)
{
this._type = type;
this._label = label;
this._disabled = disabled;
this._checked = checked;
this._contextMenu = topLevelMenu;
if (type === "item" || type === "checkbox")
this._id = topLevelMenu.nextId();
}

WebInspector.ContextMenuItem.prototype = {
id: function()
{
return this._id;
},

type: function()
{
return this._type;
},

_buildDescriptor: function()
{
switch (this._type) {
case "item":
return { type: "item", id: this._id, label: this._label, enabled: !this._disabled };
case "separator":
return { type: "separator" };
case "checkbox":
return { type: "checkbox", id: this._id, label: this._label, checked: !!this._checked, enabled: !this._disabled };
}
}
}


WebInspector.ContextSubMenuItem = function(topLevelMenu, label, disabled)
{
WebInspector.ContextMenuItem.call(this, topLevelMenu, "subMenu", label, disabled);
this._items = [];
}

WebInspector.ContextSubMenuItem.prototype = {

appendItem: function(label, handler, disabled)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "item", label, disabled);
this._pushItem(item);
this._contextMenu._setHandler(item.id(), handler);
return item;
},

appendSubMenuItem: function(label, disabled)
{
var item = new WebInspector.ContextSubMenuItem(this._contextMenu, label, disabled);
this._pushItem(item);
return item;
},


appendCheckboxItem: function(label, handler, checked, disabled)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "checkbox", label, disabled, checked);
this._pushItem(item);
this._contextMenu._setHandler(item.id(), handler);
return item;
},

appendSeparator: function()
{
if (this._items.length)
this._pendingSeparator = true;
},

_pushItem: function(item)
{
if (this._pendingSeparator) {
this._items.push(new WebInspector.ContextMenuItem(this._contextMenu, "separator"));
delete this._pendingSeparator;
}
this._items.push(item);
},


isEmpty: function()
{
return !this._items.length;
},

_buildDescriptor: function()
{
var result = { type: "subMenu", label: this._label, enabled: !this._disabled, subItems: [] };
for (var i = 0; i < this._items.length; ++i)
result.subItems.push(this._items[i]._buildDescriptor());
return result;
}
}

WebInspector.ContextSubMenuItem.prototype.__proto__ = WebInspector.ContextMenuItem.prototype;


WebInspector.ContextMenu = function() {
WebInspector.ContextSubMenuItem.call(this, this, "");
this._handlers = {};
this._id = 0;
}

WebInspector.ContextMenu.prototype = {
nextId: function()
{
return this._id++;
},

show: function(event)
{
var menuObject = this._buildDescriptor();

if (menuObject.length) {
WebInspector._contextMenu = this;
InspectorFrontendHost.showContextMenu(event, menuObject);
}
event.consume();
},

_setHandler: function(id, handler)
{
if (handler)
this._handlers[id] = handler;
},

_buildDescriptor: function()
{
var result = [];
for (var i = 0; i < this._items.length; ++i)
result.push(this._items[i]._buildDescriptor());
return result;
},

_itemSelected: function(id)
{
if (this._handlers[id])
this._handlers[id].call(this);
},


appendApplicableItems: function(target)
{
for (var i = 0; i < WebInspector.ContextMenu._providers.length; ++i) {
var provider = WebInspector.ContextMenu._providers[i];
this.appendSeparator();
provider.appendApplicableItems(this, target);
this.appendSeparator();
}
}
}

WebInspector.ContextMenu.prototype.__proto__ = WebInspector.ContextSubMenuItem.prototype;


WebInspector.ContextMenu.Provider = function() { 
}

WebInspector.ContextMenu.Provider.prototype = {

appendApplicableItems: function(contextMenu, target) { }
}


WebInspector.ContextMenu.registerProvider = function(provider)
{
WebInspector.ContextMenu._providers.push(provider);
}

WebInspector.ContextMenu._providers = [];

WebInspector.contextMenuItemSelected = function(id)
{
if (WebInspector._contextMenu)
WebInspector._contextMenu._itemSelected(id);
}

WebInspector.contextMenuCleared = function()
{


}





if (!InspectorFrontendHost.showContextMenu) {


WebInspector.SoftContextMenu = function(items, parentMenu)
{
this._items = items;
this._parentMenu = parentMenu;
}

WebInspector.SoftContextMenu.prototype = {
show: function(event)
{
this._x = event.x;
this._y = event.y;
this._time = new Date().getTime();


var absoluteX = event.pageX;
var absoluteY = event.pageY;
var targetElement = event.target;
while (targetElement && window !== targetElement.ownerDocument.defaultView) {
var frameElement = targetElement.ownerDocument.defaultView.frameElement;
absoluteY += frameElement.totalOffsetTop();
absoluteX += frameElement.totalOffsetLeft();
targetElement = frameElement;
}


this._contextMenuElement = document.createElement("div");
this._contextMenuElement.className = "soft-context-menu";
this._contextMenuElement.tabIndex = 0;
this._contextMenuElement.style.top = absoluteY + "px";
this._contextMenuElement.style.left = absoluteX + "px";

this._contextMenuElement.addEventListener("mouseup", consumeEvent, false);
this._contextMenuElement.addEventListener("keydown", this._menuKeyDown.bind(this), false);

for (var i = 0; i < this._items.length; ++i)
this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));


if (!this._parentMenu) {
this._glassPaneElement = document.createElement("div");
this._glassPaneElement.className = "soft-context-menu-glass-pane";
this._glassPaneElement.tabIndex = 0;
this._glassPaneElement.addEventListener("mouseup", this._glassPaneMouseUp.bind(this), false);
this._glassPaneElement.appendChild(this._contextMenuElement);
document.body.appendChild(this._glassPaneElement);
this._focus();
} else
this._parentMenu._parentGlassPaneElement().appendChild(this._contextMenuElement);


if (document.body.offsetWidth <  this._contextMenuElement.offsetLeft + this._contextMenuElement.offsetWidth)
this._contextMenuElement.style.left = (absoluteX - this._contextMenuElement.offsetWidth) + "px";
if (document.body.offsetHeight < this._contextMenuElement.offsetTop + this._contextMenuElement.offsetHeight)
this._contextMenuElement.style.top = (document.body.offsetHeight - this._contextMenuElement.offsetHeight) + "px";

event.consume(true);
},

_parentGlassPaneElement: function()
{
if (this._glassPaneElement)
return this._glassPaneElement;
if (this._parentMenu)
return this._parentMenu._parentGlassPaneElement();
return null;
},

_createMenuItem: function(item)
{
if (item.type === "separator")
return this._createSeparator();

if (item.type === "subMenu")
return this._createSubMenu(item);

var menuItemElement = document.createElement("div");
menuItemElement.className = "soft-context-menu-item";

var checkMarkElement = document.createElement("span");
checkMarkElement.textContent = "\u2713 "; 
checkMarkElement.className = "soft-context-menu-item-checkmark";
if (!item.checked)
checkMarkElement.style.opacity = "0";

menuItemElement.appendChild(checkMarkElement);
menuItemElement.appendChild(document.createTextNode(item.label));

menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);


menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);

menuItemElement._actionId = item.id;
return menuItemElement;
},

_createSubMenu: function(item)
{
var menuItemElement = document.createElement("div");
menuItemElement.className = "soft-context-menu-item";
menuItemElement._subItems = item.subItems;


var checkMarkElement = document.createElement("span");
checkMarkElement.textContent = "\u2713 "; 
checkMarkElement.className = "soft-context-menu-item-checkmark";
checkMarkElement.style.opacity = "0";
menuItemElement.appendChild(checkMarkElement);

var subMenuArrowElement = document.createElement("span");
subMenuArrowElement.textContent = "\u25B6"; 
subMenuArrowElement.className = "soft-context-menu-item-submenu-arrow";

menuItemElement.appendChild(document.createTextNode(item.label));
menuItemElement.appendChild(subMenuArrowElement);

menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);


menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);

return menuItemElement;
},

_createSeparator: function()
{
var separatorElement = document.createElement("div");
separatorElement.className = "soft-context-menu-separator";
separatorElement._isSeparator = true;
separatorElement.addEventListener("mouseover", this._hideSubMenu.bind(this), false);
separatorElement.createChild("div", "separator-line");
return separatorElement;
},

_menuItemMouseDown: function(event)
{

event.consume(true);
},

_menuItemMouseUp: function(event)
{
this._triggerAction(event.target, event);
event.consume();
},

_focus: function()
{
this._contextMenuElement.focus();
},

_triggerAction: function(menuItemElement, event)
{
if (!menuItemElement._subItems) {
this._discardMenu(true, event);
if (typeof menuItemElement._actionId !== "undefined") {
WebInspector.contextMenuItemSelected(menuItemElement._actionId);
delete menuItemElement._actionId;
}
return;
}

this._showSubMenu(menuItemElement, event);
event.consume();
},

_showSubMenu: function(menuItemElement, event)
{
if (menuItemElement._subMenuTimer) {
clearTimeout(menuItemElement._subMenuTimer);
delete menuItemElement._subMenuTimer;
}
if (this._subMenu)
return;

this._subMenu = new WebInspector.SoftContextMenu(menuItemElement._subItems, this);
this._subMenu.show(this._buildMouseEventForSubMenu(menuItemElement));
},

_buildMouseEventForSubMenu: function(subMenuItemElement)
{
var subMenuOffset = { x: subMenuItemElement.offsetWidth - 3, y: subMenuItemElement.offsetTop - 1 };
var targetX = this._x + subMenuOffset.x;
var targetY = this._y + subMenuOffset.y;
var targetPageX = parseInt(this._contextMenuElement.style.left, 10) + subMenuOffset.x;
var targetPageY = parseInt(this._contextMenuElement.style.top, 10) + subMenuOffset.y;
return { x: targetX, y: targetY, pageX: targetPageX, pageY: targetPageY, consume: function() {} };
},

_hideSubMenu: function()
{
if (!this._subMenu)
return;
this._subMenu._discardSubMenus();
this._focus();
},

_menuItemMouseOver: function(event)
{
this._highlightMenuItem(event.target);
},

_menuItemMouseOut: function(event)
{
if (!this._subMenu || !event.relatedTarget) {
this._highlightMenuItem(null);
return;
}

var relatedTarget = event.relatedTarget;
if (this._contextMenuElement.isSelfOrAncestor(relatedTarget) || relatedTarget.hasStyleClass("soft-context-menu-glass-pane"))
this._highlightMenuItem(null);
},

_highlightMenuItem: function(menuItemElement)
{
if (this._highlightedMenuItemElement ===  menuItemElement)
return;

this._hideSubMenu();
if (this._highlightedMenuItemElement) {
this._highlightedMenuItemElement.removeStyleClass("soft-context-menu-item-mouse-over");
if (this._highlightedMenuItemElement._subItems && this._highlightedMenuItemElement._subMenuTimer) {
clearTimeout(this._highlightedMenuItemElement._subMenuTimer);
delete this._highlightedMenuItemElement._subMenuTimer;
}
}
this._highlightedMenuItemElement = menuItemElement;
if (this._highlightedMenuItemElement) {
this._highlightedMenuItemElement.addStyleClass("soft-context-menu-item-mouse-over");
this._contextMenuElement.focus();
if (this._highlightedMenuItemElement._subItems && !this._highlightedMenuItemElement._subMenuTimer)
this._highlightedMenuItemElement._subMenuTimer = setTimeout(this._showSubMenu.bind(this, this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement)), 150);
}
},

_highlightPrevious: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild;
while (menuItemElement && menuItemElement._isSeparator)
menuItemElement = menuItemElement.previousSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement);
},

_highlightNext: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild;
while (menuItemElement && menuItemElement._isSeparator)
menuItemElement = menuItemElement.nextSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement);
},

_menuKeyDown: function(event)
{
switch (event.keyIdentifier) {
case "Up":
this._highlightPrevious(); break;
case "Down":
this._highlightNext(); break;
case "Left":
if (this._parentMenu) {
this._highlightMenuItem(null);
this._parentMenu._focus();
}
break;
case "Right":
if (!this._highlightedMenuItemElement)
break;
if (this._highlightedMenuItemElement._subItems) {
this._showSubMenu(this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement));
this._subMenu._focus();
this._subMenu._highlightNext();
}
break;
case "U+001B": 
this._discardMenu(true, event); break;
case "Enter":
if (!isEnterKey(event))
break;

case "U+0020": 
if (this._highlightedMenuItemElement)
this._triggerAction(this._highlightedMenuItemElement, event);
break;
}
event.consume(true);
},

_glassPaneMouseUp: function(event)
{

if (event.x === this._x && event.y === this._y && new Date().getTime() - this._time < 300)
return;
this._discardMenu(true, event);
event.consume();
},


_discardMenu: function(closeParentMenus, event)
{
if (this._subMenu && !closeParentMenus)
return;
if (this._glassPaneElement) {
var glassPane = this._glassPaneElement;
delete this._glassPaneElement;

document.body.removeChild(glassPane);
if (this._parentMenu) {
delete this._parentMenu._subMenu;
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);
}

if (event)
event.consume(true);
} else if (this._parentMenu && this._contextMenuElement.parentElement) {
this._discardSubMenus();
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);

if (event)
event.consume(true);
}
},

_discardSubMenus: function()
{
if (this._subMenu)
this._subMenu._discardSubMenus();
if (this._contextMenuElement.parentElement)
this._contextMenuElement.parentElement.removeChild(this._contextMenuElement);
if (this._parentMenu)
delete this._parentMenu._subMenu;
}
}

InspectorFrontendHost.showContextMenu = function(event, items)
{
new WebInspector.SoftContextMenu(items).show(event);
}

}






WebInspector.KeyboardShortcut = function()
{
}


WebInspector.KeyboardShortcut.Modifiers = {
None: 0,   
Shift: 1,
Ctrl: 2,
Alt: 4,
Meta: 8,   
get CtrlOrMeta()
{

return WebInspector.isMac() ? this.Meta : this.Ctrl;
}
};

WebInspector.KeyboardShortcut.Keys = {
Backspace: { code: 8, name: "\u21a4" },
Tab: { code: 9, name: { mac: "\u21e5", other: "<Tab>" } },
Enter: { code: 13, name: { mac: "\u21a9", other: "<Enter>" } },
Esc: { code: 27, name: { mac: "\u238b", other: "<Esc>" } },
Space: { code: 32, name: "<Space>" },
PageUp: { code: 33,  name: { mac: "\u21de", other: "<PageUp>" } },      
PageDown: { code: 34, name: { mac: "\u21df", other: "<PageDown>" } },   
End: { code: 35, name: { mac: "\u2197", other: "<End>" } },             
Home: { code: 36, name: { mac: "\u2196", other: "<Home>" } },           
Left: { code: 37, name: "<Left>" },           
Up: { code: 38, name: "<Up>" },             
Right: { code: 39, name: "<Right>" },          
Down: { code: 40, name: "<Down>" },           
Delete: { code: 46, name: "<Del>" },
Zero: { code: 48, name: "0" },
F1: { code: 112, name: "F1" },
F2: { code: 113, name: "F2" },
F3: { code: 114, name: "F3" },
F4: { code: 115, name: "F4" },
F5: { code: 116, name: "F5" },
F6: { code: 117, name: "F6" },
F7: { code: 118, name: "F7" },
F8: { code: 119, name: "F8" },
F9: { code: 120, name: "F9" },
F10: { code: 121, name: "F10" },
F11: { code: 122, name: "F11" },
F12: { code: 123, name: "F12" },
Semicolon: { code: 186, name: ";" },
Plus: { code: 187, name: "+" },
Comma: { code: 188, name: "," },
Minus: { code: 189, name: "-" },
Period: { code: 190, name: "." },
Slash: { code: 191, name: "/" },
Apostrophe: { code: 192, name: "`" },
SingleQuote: { code: 222, name: "\'" }
};


WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
{
if (typeof keyCode === "string")
keyCode = keyCode.charCodeAt(0) - 32;
modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
}

WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
{
var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
if (keyboardEvent.shiftKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
if (keyboardEvent.ctrlKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
if (keyboardEvent.altKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
if (keyboardEvent.metaKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
}

WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event)
{
return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
}


WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
{
return {
key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
};
}


WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
{
return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
}

WebInspector.KeyboardShortcut._keyName = function(key)
{
if (typeof key === "string")
return key.toUpperCase();
if (typeof key.name === "string")
return key.name;
return key.name[WebInspector.platform()] || key.name.other;
}

WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
{
return (keyCode & 255) | (modifiers << 8);
};

WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
{
const cmdKey = "\u2318";
const optKey = "\u2325";
const shiftKey = "\u21e7";
const ctrlKey = "\u2303";

var isMac = WebInspector.isMac();
var res = "";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl)
res += isMac ? ctrlKey : "<Ctrl> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt)
res += isMac ? optKey : "<Alt> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift)
res += isMac ? shiftKey : "<Shift> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Meta)
res += isMac ? cmdKey : "<Win> + ";

return res;
};






WebInspector.TextPrompt = function(completions, stopCharacters)
{

this._proxyElement;
this._proxyElementDisplay = "inline-block";
this._loadCompletions = completions;
this._completionStopCharacters = stopCharacters;
this._suggestForceable = true;
}

WebInspector.TextPrompt.Events = {
ItemApplied: "text-prompt-item-applied",
ItemAccepted: "text-prompt-item-accepted"
};

WebInspector.TextPrompt.prototype = {
get proxyElement()
{
return this._proxyElement;
},

setSuggestForceable: function(x)
{
this._suggestForceable = x;
},

setSuggestBoxEnabled: function(className)
{
this._suggestBoxClassName = className;
},

renderAsBlock: function()
{
this._proxyElementDisplay = "block";
},


attach: function(element)
{
return this._attachInternal(element);
},


attachAndStartEditing: function(element, blurListener)
{
this._attachInternal(element);
this._startEditing(blurListener);
return this.proxyElement;
},

_attachInternal: function(element)
{
if (this.proxyElement)
throw "Cannot attach an attached TextPrompt";
this._element = element;

this._boundOnKeyDown = this.onKeyDown.bind(this);
this._boundOnMouseWheel = this.onMouseWheel.bind(this);
this._boundSelectStart = this._selectStart.bind(this);
this._proxyElement = element.ownerDocument.createElement("span");
this._proxyElement.style.display = this._proxyElementDisplay;
element.parentElement.insertBefore(this.proxyElement, element);
this.proxyElement.appendChild(element);
this._element.addStyleClass("text-prompt");
this._element.addEventListener("keydown", this._boundOnKeyDown, false);
this._element.addEventListener("mousewheel", this._boundOnMouseWheel, false);
this._element.addEventListener("selectstart", this._boundSelectStart, false);

if (typeof this._suggestBoxClassName === "string")
this._suggestBox = new WebInspector.TextPrompt.SuggestBox(this, this._element, this._suggestBoxClassName);

return this.proxyElement;
},

detach: function()
{
this._removeFromElement();
this.proxyElement.parentElement.insertBefore(this._element, this.proxyElement);
this.proxyElement.parentElement.removeChild(this.proxyElement);
this._element.removeStyleClass("text-prompt");
this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
this._element.removeEventListener("mousewheel", this._boundOnMouseWheel, false);
this._element.removeEventListener("selectstart", this._boundSelectStart, false);
delete this._proxyElement;
WebInspector.restoreFocusFromElement(this._element);
},

get text()
{
return this._element.textContent;
},

set text(x)
{
this._removeSuggestionAids();
if (!x) {

this._element.removeChildren();
this._element.appendChild(document.createElement("br"));
} else
this._element.textContent = x;

this.moveCaretToEndOfPrompt();
this._element.scrollIntoView();
},

_removeFromElement: function()
{
this.clearAutoComplete(true);
this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
this._element.removeEventListener("selectstart", this._boundSelectStart, false);
if (this._isEditing)
this._stopEditing();
if (this._suggestBox)
this._suggestBox.removeFromElement();
},

_startEditing: function(blurListener)
{
this._isEditing = true;
this._element.addStyleClass("editing");
if (blurListener) {
this._blurListener = blurListener;
this._element.addEventListener("blur", this._blurListener, false);
}
this._oldTabIndex = this._element.tabIndex;
if (this._element.tabIndex < 0)
this._element.tabIndex = 0;
WebInspector.setCurrentFocusElement(this._element);
},

_stopEditing: function()
{
this._element.tabIndex = this._oldTabIndex;
if (this._blurListener)
this._element.removeEventListener("blur", this._blurListener, false);
this._element.removeStyleClass("editing");
delete this._isEditing;
},

_removeSuggestionAids: function()
{
this.clearAutoComplete();
this.hideSuggestBox();
},

_selectStart: function(event)
{
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);

this._removeSuggestionAids();

function moveBackIfOutside()
{
delete this._selectionTimeout;
if (!this.isCaretInsidePrompt() && window.getSelection().isCollapsed) {
this.moveCaretToEndOfPrompt();
this.autoCompleteSoon();
}
}

this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
},


defaultKeyHandler: function(event, force)
{
this.clearAutoComplete();
this.autoCompleteSoon(force);
return false;
},

onMouseWheel: function(event)
{

},

onKeyDown: function(event)
{
var handled = false;
var invokeDefault = true;

switch (event.keyIdentifier) {
case "Up":
handled = this.upKeyPressed(event);
break;
case "Down":
handled = this.downKeyPressed(event);
break;
case "PageUp":
handled = this.pageUpKeyPressed(event);
break;
case "PageDown":
handled = this.pageDownKeyPressed(event);
break;
case "U+0009": 
handled = this.tabKeyPressed(event);
break;
case "Enter":
handled = this.enterKeyPressed(event);
break;
case "Left":
case "Home":
this._removeSuggestionAids();
invokeDefault = false;
break;
case "Right":
case "End":
if (this.isCaretAtEndOfPrompt())
handled = this.acceptAutoComplete();
else
this._removeSuggestionAids();
invokeDefault = false;
break;
case "U+001B": 
if (this.isSuggestBoxVisible()) {
this._suggestBox.hide();
handled = true;
}
break;
case "U+0020": 
if (this._suggestForceable && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
this.defaultKeyHandler(event, true);
handled = true;
}
break;
case "Alt":
case "Meta":
case "Shift":
case "Control":
invokeDefault = false;
break;
}

if (!handled && invokeDefault)
handled = this.defaultKeyHandler(event);

if (handled)
event.consume(true);

return handled;
},

acceptAutoComplete: function()
{
var result = false;
if (this.isSuggestBoxVisible())
result = this._suggestBox.acceptSuggestion();
if (!result)
result = this.acceptSuggestion();

return result;
},


clearAutoComplete: function(includeTimeout)
{
if (includeTimeout && this._completeTimeout) {
clearTimeout(this._completeTimeout);
delete this._completeTimeout;
}
delete this._waitingForCompletions;

if (!this.autoCompleteElement)
return;

if (this.autoCompleteElement.parentNode)
this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
delete this.autoCompleteElement;

if (!this._userEnteredRange || !this._userEnteredText)
return;

this._userEnteredRange.deleteContents();
this._element.pruneEmptyTextNodes();

var userTextNode = document.createTextNode(this._userEnteredText);
this._userEnteredRange.insertNode(userTextNode);

var selectionRange = document.createRange();
selectionRange.setStart(userTextNode, this._userEnteredText.length);
selectionRange.setEnd(userTextNode, this._userEnteredText.length);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(selectionRange);

delete this._userEnteredRange;
delete this._userEnteredText;
},


autoCompleteSoon: function(force)
{
var immediately = this.isSuggestBoxVisible() || force;
if (!this._completeTimeout)
this._completeTimeout = setTimeout(this.complete.bind(this, true, force), immediately ? 0 : 250);
},


complete: function(auto, force, reverse)
{
this.clearAutoComplete(true);
var selection = window.getSelection();
if (!selection.rangeCount)
return;

var selectionRange = selection.getRangeAt(0);
var isEmptyInput = selectionRange.commonAncestorContainer === this._element; 

var shouldExit;


if (auto && isEmptyInput && !force)
shouldExit = true;
else if (!auto && !isEmptyInput && !selectionRange.commonAncestorContainer.isDescendant(this._element))
shouldExit = true;
else if (auto && !force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible())
shouldExit = true;
else if (!selection.isCollapsed)
shouldExit = true;
else if (!force) {

var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.endOffset, this._completionStopCharacters, this._element, "forward");
if (wordSuffixRange.toString().length)
shouldExit = true;
}
if (shouldExit) {
this.hideSuggestBox();
return;
}

var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward");
this._waitingForCompletions = true;
this._loadCompletions(this, wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, !!reverse));
},

_boxForAnchorAtStart: function(selection, textRange)
{
var rangeCopy = selection.getRangeAt(0).cloneRange();
var anchorElement = document.createElement("span");
anchorElement.textContent = "\u200B";
textRange.insertNode(anchorElement);
var box = anchorElement.boxInWindow(window);
anchorElement.parentElement.removeChild(anchorElement);
selection.removeAllRanges();
selection.addRange(rangeCopy);
return box;
},


_buildCommonPrefix: function(completions, wordPrefixLength)
{
var commonPrefix = completions[0];
for (var i = 0; i < completions.length; ++i) {
var completion = completions[i];
var lastIndex = Math.min(commonPrefix.length, completion.length);
for (var j = wordPrefixLength; j < lastIndex; ++j) {
if (commonPrefix[j] !== completion[j]) {
commonPrefix = commonPrefix.substr(0, j);
break;
}
}
}
return commonPrefix;
},


_completionsReady: function(selection, auto, originalWordPrefixRange, reverse, completions)
{
if (!this._waitingForCompletions || !completions || !completions.length) {
this.hideSuggestBox();
return;
}
delete this._waitingForCompletions;

var selectionRange = selection.getRangeAt(0);

var fullWordRange = document.createRange();
fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset);
fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);

if (originalWordPrefixRange.toString() + selectionRange.toString() != fullWordRange.toString())
return;

this._userEnteredRange = fullWordRange;
this._userEnteredText = fullWordRange.toString();

if (this._suggestBox)
this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), completions, !this.isCaretAtEndOfPrompt());

var wordPrefixLength = originalWordPrefixRange.toString().length;

if (auto) {
var completionText = completions[0];
var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);

this._commonPrefix = commonPrefix;
} else {
if (completions.length === 1) {
var completionText = completions[0];
wordPrefixLength = completionText.length;
} else {
var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
wordPrefixLength = commonPrefix.length;

if (selection.isCollapsed)
var completionText = completions[0];
else {
var currentText = fullWordRange.toString();

var foundIndex = null;
for (var i = 0; i < completions.length; ++i) {
if (completions[i] === currentText)
foundIndex = i;
}

var nextIndex = foundIndex + (reverse ? -1 : 1);
if (foundIndex === null || nextIndex >= completions.length)
var completionText = completions[0];
else if (nextIndex < 0)
var completionText = completions[completions.length - 1];
else
var completionText = completions[nextIndex];
}
}
}

if (auto) {
if (this.isCaretAtEndOfPrompt()) {
this._userEnteredRange.deleteContents();
this._element.pruneEmptyTextNodes();
var finalSelectionRange = document.createRange();
var prefixText = completionText.substring(0, wordPrefixLength);
var suffixText = completionText.substring(wordPrefixLength);

var prefixTextNode = document.createTextNode(prefixText);
fullWordRange.insertNode(prefixTextNode);

this.autoCompleteElement = document.createElement("span");
this.autoCompleteElement.className = "auto-complete-text";
this.autoCompleteElement.textContent = suffixText;

prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling);

finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
}
} else
this.applySuggestion(completionText, completions.length > 1, originalWordPrefixRange);
},

_completeCommonPrefix: function()
{
if (!this.autoCompleteElement || !this._commonPrefix || !this._userEnteredText || !this._commonPrefix.startsWith(this._userEnteredText))
return;

if (!this.isSuggestBoxVisible()) {
this.acceptAutoComplete();
return;
}

this.autoCompleteElement.textContent = this._commonPrefix.substring(this._userEnteredText.length);
this.acceptSuggestion(true)
},


applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange)
{
var wordPrefixLength;
if (originalPrefixRange)
wordPrefixLength = originalPrefixRange.toString().length;
else
wordPrefixLength = this._userEnteredText ? this._userEnteredText.length : 0;

this._userEnteredRange.deleteContents();
this._element.pruneEmptyTextNodes();
var finalSelectionRange = document.createRange();
var completionTextNode = document.createTextNode(completionText);
this._userEnteredRange.insertNode(completionTextNode);
if (this.autoCompleteElement && this.autoCompleteElement.parentNode) {
this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
delete this.autoCompleteElement;
}

if (isIntermediateSuggestion)
finalSelectionRange.setStart(completionTextNode, wordPrefixLength);
else
finalSelectionRange.setStart(completionTextNode, completionText.length);

finalSelectionRange.setEnd(completionTextNode, completionText.length);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
if (isIntermediateSuggestion)
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied, { itemText: completionText });
},


acceptSuggestion: function(prefixAccepted)
{
if (this._isAcceptingSuggestion)
return false;

if (!this.autoCompleteElement || !this.autoCompleteElement.parentNode)
return false;

var text = this.autoCompleteElement.textContent;
var textNode = document.createTextNode(text);
this.autoCompleteElement.parentNode.replaceChild(textNode, this.autoCompleteElement);
delete this.autoCompleteElement;

var finalSelectionRange = document.createRange();
finalSelectionRange.setStart(textNode, text.length);
finalSelectionRange.setEnd(textNode, text.length);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(finalSelectionRange);

if (!prefixAccepted) {
this.hideSuggestBox();
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepted);
} else
this.autoCompleteSoon(true);

return true;
},

hideSuggestBox: function()
{
if (this.isSuggestBoxVisible())
this._suggestBox.hide();
},

isSuggestBoxVisible: function()
{
return this._suggestBox && this._suggestBox.visible;
},

isCaretInsidePrompt: function()
{
return this._element.isInsertionCaretInside();
},

isCaretAtEndOfPrompt: function()
{
var selection = window.getSelection();
if (!selection.rangeCount || !selection.isCollapsed)
return false;

var selectionRange = selection.getRangeAt(0);
var node = selectionRange.startContainer;
if (!node.isSelfOrDescendant(this._element))
return false;

if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length)
return false;

var foundNextText = false;
while (node) {
if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
if (foundNextText && (!this.autoCompleteElement || !this.autoCompleteElement.isAncestor(node)))
return false;
foundNextText = true;
}

node = node.traverseNextNode(this._element);
}

return true;
},

isCaretOnFirstLine: function()
{
var selection = window.getSelection();
var focusNode = selection.focusNode;
if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
return true;

if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\n") !== -1)
return false;
focusNode = focusNode.previousSibling;

while (focusNode) {
if (focusNode.nodeType !== Node.TEXT_NODE)
return true;
if (focusNode.textContent.indexOf("\n") !== -1)
return false;
focusNode = focusNode.previousSibling;
}

return true;
},

isCaretOnLastLine: function()
{
var selection = window.getSelection();
var focusNode = selection.focusNode;
if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
return true;

if (focusNode.textContent.substring(selection.focusOffset).indexOf("\n") !== -1)
return false;
focusNode = focusNode.nextSibling;

while (focusNode) {
if (focusNode.nodeType !== Node.TEXT_NODE)
return true;
if (focusNode.textContent.indexOf("\n") !== -1)
return false;
focusNode = focusNode.nextSibling;
}

return true;
},

moveCaretToEndOfPrompt: function()
{
var selection = window.getSelection();
var selectionRange = document.createRange();

var offset = this._element.childNodes.length;
selectionRange.setStart(this._element, offset);
selectionRange.setEnd(this._element, offset);

selection.removeAllRanges();
selection.addRange(selectionRange);
},

tabKeyPressed: function(event)
{
this._completeCommonPrefix();


return true;
},

enterKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.enterKeyPressed(event);

return false;
},

upKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.upKeyPressed(event);

return false;
},

downKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.downKeyPressed(event);

return false;
},

pageUpKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.pageUpKeyPressed(event);

return false;
},

pageDownKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.pageDownKeyPressed(event);

return false;
},
}

WebInspector.TextPrompt.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.TextPromptWithHistory = function(completions, stopCharacters)
{
WebInspector.TextPrompt.call(this, completions, stopCharacters);


this._data = [];


this._historyOffset = 1;


this._coalesceHistoryDupes = true;
}

WebInspector.TextPromptWithHistory.prototype = {
get historyData()
{

return this._data;
},

setCoalesceHistoryDupes: function(x)
{
this._coalesceHistoryDupes = x;
},


setHistoryData: function(data)
{
this._data = [].concat(data);
this._historyOffset = 1;
},


pushHistoryItem: function(text)
{
if (this._uncommittedIsTop) {
this._data.pop();
delete this._uncommittedIsTop;
}

this._historyOffset = 1;
if (this._coalesceHistoryDupes && text === this._currentHistoryItem())
return;
this._data.push(text);
},


_pushCurrentText: function()
{
if (this._uncommittedIsTop)
this._data.pop(); 
this._uncommittedIsTop = true;
this.clearAutoComplete(true);
this._data.push(this.text);
},


_previous: function()
{
if (this._historyOffset > this._data.length)
return undefined;
if (this._historyOffset === 1)
this._pushCurrentText();
++this._historyOffset;
return this._currentHistoryItem();
},


_next: function()
{
if (this._historyOffset === 1)
return undefined;
--this._historyOffset;
return this._currentHistoryItem();
},

_currentHistoryItem: function()
{
return this._data[this._data.length - this._historyOffset];
},


defaultKeyHandler: function(event, force)
{
var newText;
var isPrevious;

switch (event.keyIdentifier) {
case "Up":
if (!this.isCaretOnFirstLine())
break;
newText = this._previous();
isPrevious = true;
break;
case "Down":
if (!this.isCaretOnLastLine())
break;
newText = this._next();
break;
case "U+0050": 
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
newText = this._previous();
isPrevious = true;
}
break;
case "U+004E": 
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey)
newText = this._next();
break;
}

if (newText !== undefined) {
event.consume(true);
this.text = newText;

if (isPrevious) {
var firstNewlineIndex = this.text.indexOf("\n");
if (firstNewlineIndex === -1)
this.moveCaretToEndOfPrompt();
else {
var selection = window.getSelection();
var selectionRange = document.createRange();

selectionRange.setStart(this._element.firstChild, firstNewlineIndex);
selectionRange.setEnd(this._element.firstChild, firstNewlineIndex);

selection.removeAllRanges();
selection.addRange(selectionRange);
}
}

return true;
}

return WebInspector.TextPrompt.prototype.defaultKeyHandler.apply(this, arguments);
}
}

WebInspector.TextPromptWithHistory.prototype.__proto__ = WebInspector.TextPrompt.prototype;


WebInspector.TextPrompt.SuggestBox = function(textPrompt, inputElement, className)
{
this._textPrompt = textPrompt;
this._inputElement = inputElement;
this._selectedElement = null;
this._boundOnScroll = this._onscrollresize.bind(this, true);
this._boundOnResize = this._onscrollresize.bind(this, false);
window.addEventListener("scroll", this._boundOnScroll, true);
window.addEventListener("resize", this._boundOnResize, true);

this._bodyElement = inputElement.ownerDocument.body;
this._element = inputElement.ownerDocument.createElement("div");
this._element.className = "suggest-box " + (className || "");
this._element.addEventListener("mousedown", this._onboxmousedown.bind(this), true);
this.containerElement = this._element.createChild("div", "container");
this.contentElement = this.containerElement.createChild("div", "content");
}

WebInspector.TextPrompt.SuggestBox.prototype = {
get visible()
{
return !!this._element.parentElement;
},

get hasSelection()
{
return !!this._selectedElement;
},

_onscrollresize: function(isScroll, event)
{
if (isScroll && this._element.isAncestor(event.target) || !this.visible)
return;
this._updateBoxPositionWithExistingAnchor();
},

_updateBoxPositionWithExistingAnchor: function()
{
this._updateBoxPosition(this._anchorBox);
},


_updateBoxPosition: function(anchorBox)
{

this.contentElement.style.display = "inline-block";
document.body.appendChild(this.contentElement);
this.contentElement.positionAt(0, 0);
var contentWidth = this.contentElement.offsetWidth;
var contentHeight = this.contentElement.offsetHeight;
this.contentElement.style.display = "block";
this.containerElement.appendChild(this.contentElement);


this._anchorBox = anchorBox;
const spacer = 6;

const suggestBoxPaddingX = 21;
var maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
var paddedWidth = contentWidth + suggestBoxPaddingX;
var boxX = anchorBox.x;
if (width < paddedWidth) {

maxWidth = document.body.offsetWidth - spacer;
width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
boxX = document.body.offsetWidth - width;
}

const suggestBoxPaddingY = 2;
var boxY;
var aboveHeight = anchorBox.y;
var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height;
var maxHeight = Math.max(underHeight, aboveHeight) - spacer;
var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY;
if (underHeight >= aboveHeight) {

boxY = anchorBox.y + anchorBox.height;
this._element.removeStyleClass("above-anchor");
this._element.addStyleClass("under-anchor");
} else {

boxY = anchorBox.y - height;
this._element.removeStyleClass("under-anchor");
this._element.addStyleClass("above-anchor");
}

this._element.positionAt(boxX, boxY);
this._element.style.width = width + "px";
this._element.style.height = height + "px";
},

_onboxmousedown: function(event)
{
event.preventDefault();
},

hide: function()
{
if (!this.visible)
return;

this._element.parentElement.removeChild(this._element);
delete this._selectedElement;
},

removeFromElement: function()
{
window.removeEventListener("scroll", this._boundOnScroll, true);
window.removeEventListener("resize", this._boundOnResize, true);
this.hide();
},


_applySuggestion: function(text, isIntermediateSuggestion)
{
if (!this.visible || !(text || this._selectedElement))
return false;

var suggestion = text || this._selectedElement.textContent;
if (!suggestion)
return false;

this._textPrompt.applySuggestion(suggestion, isIntermediateSuggestion);
return true;
},


acceptSuggestion: function(text)
{
var result = this._applySuggestion(text, false);
this.hide();
if (!result)
return false;

this._textPrompt.acceptSuggestion();

return true;
},

_onNextItem: function(event, isPageScroll)
{
var children = this.contentElement.childNodes;
if (!children.length)
return false;

if (!this._selectedElement)
this._selectedElement = this.contentElement.firstChild;
else {
if (!isPageScroll)
this._selectedElement = this._selectedElement.nextSibling || this.contentElement.firstChild;
else {
var candidate = this._selectedElement;

for (var itemsLeft = this._rowCountPerViewport; itemsLeft; --itemsLeft) {
if (candidate.nextSibling)
candidate = candidate.nextSibling;
else
break;
}

this._selectedElement = candidate;
}
}
this._updateSelection();
this._applySuggestion(undefined, true);
return true;
},

_onPreviousItem: function(event, isPageScroll)
{
var children = this.contentElement.childNodes;
if (!children.length)
return false;

if (!this._selectedElement)
this._selectedElement = this.contentElement.lastChild;
else {
if (!isPageScroll)
this._selectedElement = this._selectedElement.previousSibling || this.contentElement.lastChild;
else {
var candidate = this._selectedElement;

for (var itemsLeft = this._rowCountPerViewport; itemsLeft; --itemsLeft) {
if (candidate.previousSibling)
candidate = candidate.previousSibling;
else
break;
}

this._selectedElement = candidate;
}
}
this._updateSelection();
this._applySuggestion(undefined, true);
return true;
},


updateSuggestions: function(anchorBox, completions, canShowForSingleItem)
{
if (this._suggestTimeout) {
clearTimeout(this._suggestTimeout);
delete this._suggestTimeout;
}
this._completionsReady(anchorBox, completions, canShowForSingleItem);
},

_onItemMouseDown: function(text, event)
{
this.acceptSuggestion(text);
event.consume(true);
},

_createItemElement: function(prefix, text)
{
var element = document.createElement("div");
element.className = "suggest-box-content-item source-code";
element.tabIndex = -1;
if (prefix && prefix.length && !text.indexOf(prefix)) {
var prefixElement = element.createChild("span", "prefix");
prefixElement.textContent = prefix;
var suffixElement = element.createChild("span", "suffix");
suffixElement.textContent = text.substring(prefix.length);
} else {
var suffixElement = element.createChild("span", "suffix");
suffixElement.textContent = text;
}
element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false);
return element;
},


_updateItems: function(items, canShowForSingleItem)
{
this.contentElement.removeChildren();

var userEnteredText = this._textPrompt._userEnteredText;
for (var i = 0; i < items.length; ++i) {
var item = items[i];
var currentItemElement = this._createItemElement(userEnteredText, item);
this.contentElement.appendChild(currentItemElement);
}

this._selectedElement = canShowForSingleItem ? this.contentElement.firstChild : null;
this._updateSelection();
},

_updateSelection: function()
{

for (var child = this.contentElement.firstChild; child; child = child.nextSibling) {
if (child !== this._selectedElement)
child.removeStyleClass("selected");
}
if (this._selectedElement) {
this._selectedElement.addStyleClass("selected");
this._selectedElement.scrollIntoViewIfNeeded(false);
}
},


_canShowBox: function(completions, canShowForSingleItem)
{
if (!completions || !completions.length)
return false;

if (completions.length > 1)
return true;


return canShowForSingleItem && completions[0] !== this._textPrompt._userEnteredText;
},

_rememberRowCountPerViewport: function()
{
if (!this.contentElement.firstChild)
return;

this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight);
},


_completionsReady: function(anchorBox, completions, canShowForSingleItem)
{
if (this._canShowBox(completions, canShowForSingleItem)) {
this._updateItems(completions, canShowForSingleItem);
this._updateBoxPosition(anchorBox);
if (!this.visible)
this._bodyElement.appendChild(this._element);
this._rememberRowCountPerViewport();
} else
this.hide();
},

upKeyPressed: function(event)
{
return this._onPreviousItem(event, false);
},

downKeyPressed: function(event)
{
return this._onNextItem(event, false);
},

pageUpKeyPressed: function(event)
{
return this._onPreviousItem(event, true);
},

pageDownKeyPressed: function(event)
{
return this._onNextItem(event, true);
},

enterKeyPressed: function(event)
{
var hasSelectedItem = !!this._selectedElement;
this.acceptSuggestion();



return hasSelectedItem;
},

tabKeyPressed: function(event)
{
return this.enterKeyPressed(event);
}
}






WebInspector.Popover = function(popoverHelper)
{
this.element = document.createElement("div");
this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll";

this._popupArrowElement = document.createElement("div");
this._popupArrowElement.className = "arrow";
this.element.appendChild(this._popupArrowElement);

this._contentDiv = document.createElement("div");
this._contentDiv.className = "content";
this._visible = false;
this._popoverHelper = popoverHelper;
}

WebInspector.Popover.prototype = {

show: function(contentElement, anchor, preferredWidth, preferredHeight)
{
if (this._disposed)
return;
this.contentElement = contentElement;


if (WebInspector.Popover._popoverElement)
document.body.removeChild(WebInspector.Popover._popoverElement);
WebInspector.Popover._popoverElement = this.element;


this.contentElement.positionAt(0, 0);
document.body.appendChild(this.contentElement);
preferredWidth = preferredWidth || this.contentElement.offsetWidth;
preferredHeight = preferredHeight || this.contentElement.offsetHeight;

this._contentDiv.appendChild(this.contentElement);
this.element.appendChild(this._contentDiv);
document.body.appendChild(this.element);
this._positionElement(anchor, preferredWidth, preferredHeight);
this._visible = true;
if (this._popoverHelper)
contentElement.addEventListener("mousemove", this._popoverHelper._killHidePopoverTimer.bind(this._popoverHelper), true);
},

hide: function()
{
if (WebInspector.Popover._popoverElement) {
delete WebInspector.Popover._popoverElement;
document.body.removeChild(this.element);
}
this._visible = false;
},

get visible()
{
return this._visible;
},

get disposed()
{
return this._disposed;
},

dispose: function()
{
if (this.visible)
this.hide();
this._disposed = true;
},

setCanShrink: function(canShrink)
{
this._hasFixedHeight = !canShrink;
this._contentDiv.addStyleClass("fixed-height");
},

_positionElement: function(anchorElement, preferredWidth, preferredHeight)
{
const borderWidth = 25;
const scrollerWidth = this._hasFixedHeight ? 0 : 11;
const arrowHeight = 15;
const arrowOffset = 10;
const borderRadius = 10;


preferredWidth = Math.max(preferredWidth, 50);
const totalWidth = window.innerWidth;
const totalHeight = window.innerHeight;

var anchorBox = anchorElement.boxInWindow(window);
var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };

var verticalAlignment;
var roomAbove = anchorBox.y;
var roomBelow = totalHeight - anchorBox.y - anchorBox.height;

if (roomAbove > roomBelow) {

if (anchorBox.y > newElementPosition.height + arrowHeight + borderRadius)
newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
else {
newElementPosition.y = borderRadius;
newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = borderRadius;
newElementPosition.height = preferredHeight;
}
}
verticalAlignment = "bottom";
} else {

newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
if (newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight) {
newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = totalHeight - preferredHeight - borderRadius;
newElementPosition.height = preferredHeight;
}
}

verticalAlignment = "top";
}

var horizontalAlignment;
if (anchorBox.x + newElementPosition.width < totalWidth) {
newElementPosition.x = Math.max(borderRadius, anchorBox.x - borderRadius - arrowOffset);
horizontalAlignment = "left";
} else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
newElementPosition.x = totalWidth - newElementPosition.width - borderRadius;
horizontalAlignment = "right";

var arrowRightPosition = Math.max(0, totalWidth - anchorBox.x - anchorBox.width - borderRadius - arrowOffset);
arrowRightPosition += anchorBox.width / 2;
arrowRightPosition = Math.min(arrowRightPosition, newElementPosition.width - borderRadius - arrowOffset);
this._popupArrowElement.style.right = arrowRightPosition + "px";
} else {
newElementPosition.x = borderRadius;
newElementPosition.width = totalWidth - borderRadius * 2;
newElementPosition.height += scrollerWidth;
horizontalAlignment = "left";
if (verticalAlignment === "bottom")
newElementPosition.y -= scrollerWidth;

this._popupArrowElement.style.left = Math.max(0, anchorBox.x - borderRadius * 2 - arrowOffset) + "px";
this._popupArrowElement.style.left += anchorBox.width / 2;
}

this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth);
this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
}
}


WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopover, onHide, disableOnClick)
{
this._panelElement = panelElement;
this._getAnchor = getAnchor;
this._showPopover = showPopover;
this._onHide = onHide;
this._disableOnClick = !!disableOnClick;
panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
panelElement.addEventListener("mouseout", this._mouseOut.bind(this), false);
this.setTimeout(1000);
}

WebInspector.PopoverHelper.prototype = {
setTimeout: function(timeout)
{
this._timeout = timeout;
},

_mouseDown: function(event)
{
if (this._disableOnClick || !event.target.isSelfOrDescendant(this._hoverElement))
this.hidePopover();
else {
this._killHidePopoverTimer();
this._handleMouseAction(event, true);
}
},

_mouseMove: function(event)
{

if (event.target.isSelfOrDescendant(this._hoverElement))
return;

this._startHidePopoverTimer();
this._handleMouseAction(event, false);
},

_mouseOut: function(event)
{
if (event.target === this._hoverElement)
this._startHidePopoverTimer();
},

_startHidePopoverTimer: function()
{

if (!this._popover || this._hidePopoverTimer)
return;

function doHide()
{
this._hidePopover();
delete this._hidePopoverTimer;
}
this._hidePopoverTimer = setTimeout(doHide.bind(this), this._timeout / 2);
},

_handleMouseAction: function(event, isMouseDown)
{
this._resetHoverTimer();
if (event.which && this._disableOnClick)
return;
this._hoverElement = this._getAnchor(event.target, event);
if (!this._hoverElement)
return;
const toolTipDelay = isMouseDown ? 0 : (this._popup ? this._timeout * 0.6 : this._timeout);
this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
},

_resetHoverTimer: function()
{
if (this._hoverTimer) {
clearTimeout(this._hoverTimer);
delete this._hoverTimer;
}
},

isPopoverVisible: function()
{
return !!this._popover;
},

hidePopover: function()
{
this._resetHoverTimer();
this._hidePopover();
},

_hidePopover: function()
{
if (!this._popover)
return;

if (this._onHide)
this._onHide();

this._popover.dispose();
delete this._popover;
this._hoverElement = null;
},

_mouseHover: function(element)
{
delete this._hoverTimer;

this._hidePopover();
this._popover = new WebInspector.Popover(this);
this._showPopover(element, this._popover);
},

_killHidePopoverTimer: function()
{
if (this._hidePopoverTimer) {
clearTimeout(this._hidePopoverTimer);
delete this._hidePopoverTimer;



this._resetHoverTimer();
}
}
}






WebInspector.Placard = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "placard";
this.element.placard = this;

this.titleElement = document.createElement("div");
this.titleElement.className = "title";

this.subtitleElement = document.createElement("div");
this.subtitleElement.className = "subtitle";

this.element.appendChild(this.subtitleElement);
this.element.appendChild(this.titleElement);

this.title = title;
this.subtitle = subtitle;
this.selected = false;
}

WebInspector.Placard.prototype = {

get title()
{
return this._title;
},

set title(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},


get subtitle()
{
return this._subtitle;
},

set subtitle(x)
{
if (this._subtitle === x)
return;
this._subtitle = x;
this.subtitleElement.textContent = x;
},


get selected()
{
return this._selected;
},

set selected(x)
{
if (x)
this.select();
else
this.deselect();
},

select: function()
{
if (this._selected)
return;
this._selected = true;
this.element.addStyleClass("selected");
},

deselect: function()
{
if (!this._selected)
return;
this._selected = false;
this.element.removeStyleClass("selected");
},

toggleSelected: function()
{
this.selected = !this.selected;
},

discard: function()
{
}
}






WebInspector.TabbedPane = function()
{
WebInspector.View.call(this);
this.registerRequiredCSS("tabbedPane.css");
this.element.addStyleClass("tabbed-pane");
this._headerElement = this.element.createChild("div", "tabbed-pane-header");
this._headerContentsElement = this._headerElement.createChild("div", "tabbed-pane-header-contents");
this._tabsElement = this._headerContentsElement.createChild("div", "tabbed-pane-header-tabs");
this._contentElement = this.element.createChild("div", "tabbed-pane-content");
this._tabs = [];
this._tabsHistory = [];
this._tabsById = {};
this.element.addEventListener("click", this.focus.bind(this), false);

this._dropDownButton = this._createDropDownButton();
}

WebInspector.TabbedPane.EventTypes = {
TabSelected: "TabSelected",
TabClosed: "TabClosed"
}

WebInspector.TabbedPane.prototype = {

get visibleView()
{
return this._currentTab ? this._currentTab.view : null;
},


get selectedTabId()
{
return this._currentTab ? this._currentTab.id : null;
},


set shrinkableTabs(shrinkableTabs)
{
this._shrinkableTabs = shrinkableTabs;
},


set closeableTabs(closeableTabs)
{
this._closeableTabs = closeableTabs;
},

defaultFocusedElement: function()
{
return this.visibleView ? this.visibleView.defaultFocusedElement() : null;
},


appendTab: function(id, tabTitle, view, tabTooltip, userGesture)
{
var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, this._closeableTabs, view, tabTooltip);
this._tabsById[id] = tab;

this._tabs.push(tab);
this._tabsHistory.push(tab);

if (this._tabsHistory[0] === tab)
this.selectTab(tab.id, userGesture);

this._updateTabElements();
},


closeTab: function(id, userGesture)
{
this._innerCloseTab(id, userGesture);
this._updateTabElements();
if (this._tabsHistory.length)
this.selectTab(this._tabsHistory[0].id, userGesture);
},


_innerCloseTab: function(id, userGesture)
{
if (this._currentTab && this._currentTab.id === id)
this._hideCurrentTab();

var tab = this._tabsById[id];
delete this._tabsById[id];

this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabs.splice(this._tabs.indexOf(tab), 1);
if (tab._shown)
this._hideTabElement(tab);

var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabClosed, eventData);
return true;
},


closeAllTabs: function(userGesture)
{
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i)
this._innerCloseTab(tabs[i].id, userGesture);
this._updateTabElements();
},


closeOtherTabs: function(id)
{
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i) {
if (tabs[i].id !== id)
this._innerCloseTab(tabs[i].id, true);
}
this._updateTabElements();
this.selectTab(id, true);
},


selectTab: function(id, userGesture)
{
var tab = this._tabsById[id];
if (!tab)
return;
if (this._currentTab && this._currentTab.id === id)
return;

this._hideCurrentTab();
this._showTab(tab);
this._currentTab = tab;

this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabsHistory.splice(0, 0, tab);

this._updateTabElements();

var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabSelected, eventData);
return true;
},


lastOpenedTabIds: function(tabsCount)
{
function tabToTabId(tab) {
return tab.id;
}

return this._tabsHistory.slice(0, tabsCount).map(tabToTabId);
},


changeTabTitle: function(id, tabTitle)
{
var tab = this._tabsById[id];
tab.title = tabTitle;
this._updateTabElements();
},


changeTabView: function(id, view)
{
var tab = this._tabsById[id];
if (this._currentTab && this._currentTab.id === tab.id) {
this._hideTab(tab);
tab.view = view;
this._showTab(tab);
} else
tab.view = view;
},


changeTabTooltip: function(id, tabTooltip)
{
var tab = this._tabsById[id];
tab.tooltip = tabTooltip;
},

onResize: function()
{
this._updateTabElements();
},

_updateTabElements: function()
{
WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements);
},

_innerUpdateTabElements: function()
{
if (!this.isShowing())
return;

if (!this._tabs.length)
this._contentElement.addStyleClass("has-no-tabs");
else
this._contentElement.removeStyleClass("has-no-tabs");

if (!this._measuredDropDownButtonWidth)
this._measureDropDownButton();

this._updateWidths();
this._updateTabsDropDown();
},


_showTabElement: function(index, tab)
{
if (index >= this._tabsElement.children.length)
this._tabsElement.appendChild(tab.tabElement);
else
this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]);
tab._shown = true;
},


_hideTabElement: function(tab)
{
this._tabsElement.removeChild(tab.tabElement);
tab._shown = false;
},

_createDropDownButton: function()
{
var dropDownContainer = document.createElement("div");
dropDownContainer.addStyleClass("tabbed-pane-header-tabs-drop-down-container");
var dropDownButton = dropDownContainer.createChild("div", "tabbed-pane-header-tabs-drop-down");
dropDownButton.appendChild(document.createTextNode("\u00bb"));
this._tabsSelect = dropDownButton.createChild("select", "tabbed-pane-header-tabs-drop-down-select");
this._tabsSelect.addEventListener("change", this._tabsSelectChanged.bind(this), false);
return dropDownContainer;
},

_totalWidth: function()
{
return this._headerContentsElement.getBoundingClientRect().width;
},

_updateTabsDropDown: function()
{
var tabsToShowIndexes = this._tabsToShowIndexes(this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth);

for (var i = 0; i < this._tabs.length; ++i) {
if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1)
this._hideTabElement(this._tabs[i]);
}
for (var i = 0; i < tabsToShowIndexes.length; ++i) {
var tab = this._tabs[tabsToShowIndexes[i]];
if (!tab._shown)
this._showTabElement(i, tab);
}

this._populateDropDownFromIndex();
},

_populateDropDownFromIndex: function()
{
if (this._dropDownButton.parentElement)
this._headerContentsElement.removeChild(this._dropDownButton);

this._tabsSelect.removeChildren();
var tabsToShow = [];
for (var i = 0; i < this._tabs.length; ++i) {
if (!this._tabs[i]._shown)
tabsToShow.push(this._tabs[i]);
continue;
}

function compareFunction(tab1, tab2)
{
return tab1.title.localeCompare(tab2.title);
}
tabsToShow.sort(compareFunction);

for (var i = 0; i < tabsToShow.length; ++i) {
var option = new Option(tabsToShow[i].title);
option.tab = tabsToShow[i];
this._tabsSelect.appendChild(option);
}
if (this._tabsSelect.options.length) {
this._headerContentsElement.appendChild(this._dropDownButton);
this._tabsSelect.selectedIndex = -1;
}
},

_tabsSelectChanged: function()
{
var options = this._tabsSelect.options;
var selectedOption = options[this._tabsSelect.selectedIndex];
this.selectTab(selectedOption.tab.id, true);
},

_measureDropDownButton: function()
{
this._dropDownButton.addStyleClass("measuring");
this._headerContentsElement.appendChild(this._dropDownButton);
this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width;
this._headerContentsElement.removeChild(this._dropDownButton);
this._dropDownButton.removeStyleClass("measuring");
},

_updateWidths: function()
{
var measuredWidths = this._measureWidths();
var maxWidth = this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE;

var i = 0;
for (var tabId in this._tabs) {
var tab = this._tabs[tabId];
tab.setWidth(Math.min(maxWidth, measuredWidths[i++]));
}
},

_measureWidths: function()
{

var measuringTabElements = [];
for (var tabId in this._tabs) {
var tab = this._tabs[tabId];
if (typeof tab._measuredWidth === "number")
continue;
var measuringTabElement = tab._createTabElement(true);
measuringTabElement.__tab = tab;
measuringTabElements.push(measuringTabElement);
this._tabsElement.appendChild(measuringTabElement);
}


for (var i = 0; i < measuringTabElements.length; ++i)
measuringTabElements[i].__tab._measuredWidth = measuringTabElements[i].getBoundingClientRect().width;


for (var i = 0; i < measuringTabElements.length; ++i)
measuringTabElements[i].parentElement.removeChild(measuringTabElements[i]);


var measuredWidths = [];
for (var tabId in this._tabs)
measuredWidths.push(this._tabs[tabId]._measuredWidth);

return measuredWidths;
},


_calculateMaxWidth: function(measuredWidths, totalWidth)
{
if (!measuredWidths.length)
return 0;

measuredWidths.sort(function(x, y) { return x - y });

var totalMeasuredWidth = 0;
for (var i = 0; i < measuredWidths.length; ++i)
totalMeasuredWidth += measuredWidths[i];

if (totalWidth >= totalMeasuredWidth)
return measuredWidths[measuredWidths.length - 1];

var totalExtraWidth = 0;
for (var i = measuredWidths.length - 1; i > 0; --i) {
var extraWidth = measuredWidths[i] - measuredWidths[i - 1];
totalExtraWidth += (measuredWidths.length - i) * extraWidth;

if (totalWidth + totalExtraWidth >= totalMeasuredWidth)
return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i); 
}

return totalWidth / measuredWidths.length;
},


_tabsToShowIndexes: function(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth)
{
var tabsToShowIndexes = [];

var totalTabsWidth = 0;
for (var i = 0; i < tabsHistory.length; ++i) {
totalTabsWidth += tabsHistory[i].width();
var minimalRequiredWidth = totalTabsWidth;
if (i !== tabsHistory.length - 1)
minimalRequiredWidth += measuredDropDownButtonWidth;
if (minimalRequiredWidth > totalWidth)
break;
tabsToShowIndexes.push(tabsOrdered.indexOf(tabsHistory[i]));
}

tabsToShowIndexes.sort(function(x, y) { return x - y });

return tabsToShowIndexes;
},

_hideCurrentTab: function()
{
if (!this._currentTab)
return;

this._hideTab(this._currentTab);
delete this._currentTab;
},


_showTab: function(tab)
{
tab.tabElement.addStyleClass("selected");
tab.view.show(this._contentElement);
},


_hideTab: function(tab)
{
tab.tabElement.removeStyleClass("selected");
tab.view.detach();
},

canHighlightLine: function()
{
return this._currentTab && this._currentTab.view && this._currentTab.view.canHighlightLine();
},

highlightLine: function(line)
{
if (this.canHighlightLine())
this._currentTab.view.highlightLine(line);
},


elementsToRestoreScrollPositionsFor: function()
{
return [ this._contentElement ];
},


_insertBefore: function(tab, index)
{
this._tabsElement.insertBefore(tab._tabElement, this._tabsElement.childNodes[index]);
var oldIndex = this._tabs.indexOf(tab);
this._tabs.splice(oldIndex, 1);
if (oldIndex < index)
--index;
this._tabs.splice(index, 0, tab);
}
}

WebInspector.TabbedPane.prototype.__proto__ = WebInspector.View.prototype;



WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, tooltip)
{
this._closeable = closeable;
this._tabbedPane = tabbedPane;
this._id = id;
this._title = title;
this._tooltip = tooltip;
this._view = view;
this._shown = false;
this._measuredWidth;
this._tabElement;
}

WebInspector.TabbedPaneTab.prototype = {

get id()
{
return this._id;
},


get title()
{
return this._title;
},

set title(title)
{
this._title = title;
if (this._titleElement)
this._titleElement.textContent = title;
delete this._measuredWidth;
},


get view()
{
return this._view;
},

set view(view)
{
this._view = view;
},


get tooltip()
{
return this._tooltip;
},

set tooltip(tooltip)
{
this._tooltip = tooltip;
if (this._titleElement)
this._titleElement.title = tooltip || "";
},


get tabElement()
{
if (typeof(this._tabElement) !== "undefined")
return this._tabElement;

this._createTabElement(false);
return this._tabElement;
},


width: function()
{
return this._width;
},


setWidth: function(width)
{
this.tabElement.style.width = width + "px";
this._width = width;
},


_createTabElement: function(measuring)
{
var tabElement = document.createElement("div");
tabElement.addStyleClass("tabbed-pane-header-tab");
tabElement.tabIndex = -1;

var titleElement = tabElement.createChild("span", "tabbed-pane-header-tab-title");
titleElement.textContent = this.title;
titleElement.title = this.tooltip || "";
if (!measuring)
this._titleElement = titleElement;

if (this._closeable) {
var closeButtonSpan = tabElement.createChild("span", "tabbed-pane-header-tab-close-button");
closeButtonSpan.textContent = "\u00D7"; 
}

if (measuring)
tabElement.addStyleClass("measuring");
else {
this._tabElement = tabElement;
tabElement.addEventListener("click", this._tabClicked.bind(this), false);
tabElement.addEventListener("mousedown", this._tabMouseDown.bind(this), false);
if (this._closeable) {
tabElement.addEventListener("contextmenu", this._tabContextMenu.bind(this), false);
WebInspector.installDragHandle(tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this), this._endTabDragging.bind(this), "pointer");
}
}

return tabElement;
},


_tabClicked: function(event)
{
if (this._closeable && (event.button === 1 || event.target.hasStyleClass("tabbed-pane-header-tab-close-button")))
this._tabbedPane.closeTab(this.id, true);
},


_tabMouseDown: function(event)
{
if (event.target.hasStyleClass("tabbed-pane-header-tab-close-button") || event.button === 1)
return;
this._tabbedPane.selectTab(this.id, true);
},

_tabContextMenu: function(event)
{
function close()
{
this._tabbedPane.closeTab(this.id, true);
}

function closeOthers()
{
this._tabbedPane.closeOtherTabs(this.id);
}

function closeAll()
{
this._tabbedPane.closeAllTabs(true);
}

var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Close"), close.bind(this));
contextMenu.appendItem(WebInspector.UIString("Close Others"), closeOthers.bind(this));
contextMenu.appendItem(WebInspector.UIString("Close All"), closeAll.bind(this));
contextMenu.show(event);
},


_startTabDragging: function(event)
{
if (event.target.hasStyleClass("tabbed-pane-header-tab-close-button"))
return false;
this._dragStartX = event.pageX;
return true;
},


_tabDragging: function(event)
{
var tabElements = this._tabbedPane._tabsElement.childNodes;
for (var i = 0; i < tabElements.length; ++i) {
var tabElement = tabElements[i];
if (tabElement === this._tabElement)
continue;

var intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft &&
this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft;
if (!intersects)
continue;

if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5)
break;

if (event.pageX - this._dragStartX > 0) {
tabElement = tabElement.nextSibling;
++i;
}

var oldOffsetLeft = this._tabElement.offsetLeft;
this._tabbedPane._insertBefore(this, i);
this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft;
break;
}

if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) {
this._tabElement.style.setProperty("left", "0px");
return;
}
if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) {
this._tabElement.style.setProperty("left", "0px");
return;
}

this._tabElement.style.setProperty("position", "relative");
this._tabElement.style.setProperty("left", (event.pageX - this._dragStartX) + "px");
},


_endTabDragging: function(event)
{
this._tabElement.style.removeProperty("position");
this._tabElement.style.removeProperty("left");
delete this._dragStartX;
}
}






WebInspector.Drawer = function()
{
this.element = document.getElementById("drawer");
this._savedHeight = 200; 
this._mainElement = document.getElementById("main");
this._toolbarElement = document.getElementById("toolbar");

this._floatingStatusBarContainer = document.getElementById("floating-status-bar-container");
WebInspector.installDragHandle(this._floatingStatusBarContainer, this._startStatusBarDragging.bind(this), this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), "row-resize");

this._drawerContentsElement = document.createElement("div");
this._drawerContentsElement.id = "drawer-contents";
this._drawerContentsElement.className = "drawer-contents";
this.element.appendChild(this._drawerContentsElement);
this._viewStatusBar = document.createElement("div");
this._bottomStatusBar = document.getElementById("bottom-status-bar-container");
}

WebInspector.Drawer.AnimationType = {
Immediately: 0,
Normal: 1,
Slow: 2
}

WebInspector.Drawer.prototype = {
get visible()
{
return !!this._view;
},

_constrainHeight: function(height)
{
return Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight);
},

show: function(view, animationType)
{
this.immediatelyFinishAnimation();

var drawerWasVisible = this.visible;

if (this._view) {
this._view.detach();
this._drawerContentsElement.removeChildren();
}

this._view = view;

var statusBarItems = this._view.statusBarItems || [];
this._viewStatusBar.removeChildren();
for (var i = 0; i < statusBarItems.length; ++i)
this._viewStatusBar.appendChild(statusBarItems[i]);

document.body.addStyleClass("drawer-visible");
this._floatingStatusBarContainer.insertBefore(document.getElementById("panel-status-bar"), this._floatingStatusBarContainer.firstElementChild);
this._bottomStatusBar.appendChild(this._viewStatusBar);
this._view.markAsRoot();
this._view.show(this._drawerContentsElement);

if (drawerWasVisible)
return;

var height = this._constrainHeight(this._savedHeight || this.element.offsetHeight);
var animations = [
{element: this.element, end: {height: height}},
{element: this._mainElement, end: {bottom: height}},
{element: this._floatingStatusBarContainer, start: {"padding-left": this._bottomStatusBar.offsetLeft}, end: {"padding-left": 0}},
{element: this._viewStatusBar, start: {opacity: 0}, end: {opacity: 1}}
];

function animationFinished()
{
WebInspector.inspectorView.currentPanel().doResize();
if (this._view && this._view.afterShow)
this._view.afterShow();
delete this._currentAnimation;
}

this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(animationType), animationFinished.bind(this));
if (animationType === WebInspector.Drawer.AnimationType.Immediately)
this._currentAnimation.forceComplete();
},

hide: function(animationType)
{
this.immediatelyFinishAnimation();
if (!this.visible)
return;

this._savedHeight = this.element.offsetHeight;

WebInspector.restoreFocusFromElement(this.element);



document.body.removeStyleClass("drawer-visible");
WebInspector.inspectorView.currentPanel().statusBarResized();
document.body.addStyleClass("drawer-visible");

var animations = [
{element: this._mainElement, end: {bottom: 0}},
{element: this.element, end: {height: 0}},
{element: this._floatingStatusBarContainer, start: {"padding-left": 0}, end: {"padding-left": this._bottomStatusBar.offsetLeft} },
{element: this._viewStatusBar, start: {opacity: 1}, end: {opacity: 0}}
];

function animationFinished()
{
WebInspector.inspectorView.currentPanel().doResize();
this._view.detach();
delete this._view;
this._bottomStatusBar.removeChildren();
this._bottomStatusBar.appendChild(document.getElementById("panel-status-bar"));
this._drawerContentsElement.removeChildren();
document.body.removeStyleClass("drawer-visible");
delete this._currentAnimation;
}

this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(animationType), animationFinished.bind(this));
if (animationType === WebInspector.Drawer.AnimationType.Immediately)
this._currentAnimation.forceComplete();
},

resize: function()
{
if (!this.visible)
return;

this._view.storeScrollPositions();
var height = this._constrainHeight(parseInt(this.element.style.height, 10));
this._mainElement.style.bottom = height + "px";
this.element.style.height = height + "px";
this._view.doResize();
},

immediatelyFinishAnimation: function()
{
if (this._currentAnimation)
this._currentAnimation.forceComplete();
},

_animationDuration: function(animationType)
{
switch (animationType) {
case WebInspector.Drawer.AnimationType.Slow:
return 2000;
case WebInspector.Drawer.AnimationType.Normal:
return 250;
default:
return 0;
}
},


_startStatusBarDragging: function(event)
{
if (!this.visible || event.target !== this._floatingStatusBarContainer)
return false;

this._view.storeScrollPositions();
this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop();
return true;
},

_statusBarDragging: function(event)
{
var height = window.innerHeight - event.pageY + this._statusBarDragOffset;
height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight);

this._mainElement.style.bottom = height + "px";
this.element.style.height = height + "px";
if (WebInspector.inspectorView.currentPanel())
WebInspector.inspectorView.currentPanel().doResize();
this._view.doResize();

event.consume(true);
},

_endStatusBarDragging: function(event)
{
this._savedHeight = this.element.offsetHeight;
delete this._statusBarDragOffset;

event.consume();
}
}


WebInspector.drawer = null;






WebInspector.ConsoleModel = function()
{
this.messages = [];
this.warnings = 0;
this.errors = 0;
this._interruptRepeatCount = false;
InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));
}

WebInspector.ConsoleModel.Events = {
ConsoleCleared: "console-cleared",
MessageAdded: "console-message-added",
RepeatCountUpdated: "repeat-count-updated"
}

WebInspector.ConsoleModel.prototype = {
enableAgent: function()
{
if (WebInspector.settings.monitoringXHREnabled.get())
ConsoleAgent.setMonitoringXHREnabled(true);

this._enablingConsole = true;
function callback()
{
delete this._enablingConsole;
}
ConsoleAgent.enable(callback.bind(this));
},


enablingConsole: function()
{
return !!this._enablingConsole;
},


addMessage: function(msg)
{
this.messages.push(msg);
this._previousMessage = msg;
this._incrementErrorWarningCount(msg);
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg);
this._interruptRepeatCount = false;
},


_incrementErrorWarningCount: function(msg)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
this.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
this.errors += msg.repeatDelta;
break;
}
},

requestClearMessages: function()
{
ConsoleAgent.clearMessages();
this.clearMessages();
},

clearMessages: function()
{
this.messages = [];

this.errors = 0;
this.warnings = 0;

this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
},

interruptRepeatCount: function()
{
this._interruptRepeatCount = true;
},


_messageRepeatCountUpdated: function(count)
{
var msg = this._previousMessage;
if (!msg)
return;

var prevRepeatCount = msg.totalRepeatCount;

if (!this._interruptRepeatCount) {
msg.repeatDelta = count - prevRepeatCount;
msg.repeatCount = msg.repeatCount + msg.repeatDelta;
msg.totalRepeatCount = count;
msg.updateRepeatCount();

this._incrementErrorWarningCount(msg);
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.RepeatCountUpdated, msg);
} else {
var msgCopy = msg.clone();
msgCopy.totalRepeatCount = count;
msgCopy.repeatCount = (count - prevRepeatCount) || 1;
msgCopy.repeatDelta = msgCopy.repeatCount;
this.addMessage(msgCopy);
}
}
}

WebInspector.ConsoleModel.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.ConsoleMessage = function(source, level, url, line, repeatCount)
{
this.source = source;
this.level = level;
this.url = url || null;
this.line = line || 0;
this.message = "";

repeatCount = repeatCount || 1;
this.repeatCount = repeatCount;
this.repeatDelta = repeatCount;
this.totalRepeatCount = repeatCount;
}

WebInspector.ConsoleMessage.prototype = {

isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},

updateRepeatCount: function()
{

},


clone: function()
{

},

location: function()
{

}
}


WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
}


WebInspector.ConsoleMessage.MessageSource = {
HTML: "html",
XML: "xml",
JS: "javascript",
Network: "network",
ConsoleAPI: "console-api",
Other: "other"
}

WebInspector.ConsoleMessage.MessageType = {
Log: "log",
Dir: "dir",
DirXML: "dirxml",
Trace: "trace",
StartGroup: "startGroup",
StartGroupCollapsed: "startGroupCollapsed",
EndGroup: "endGroup",
Assert: "assert",
Result: "result"
}

WebInspector.ConsoleMessage.MessageLevel = {
Tip: "tip",
Log: "log",
Warning: "warning",
Error: "error",
Debug: "debug"
}



WebInspector.ConsoleDispatcher = function(console)
{
this._console = console;
}

WebInspector.ConsoleDispatcher.prototype = {

messageAdded: function(payload)
{
var consoleMessage = WebInspector.ConsoleMessage.create(
payload.source,
payload.level,
payload.text,
payload.type,
payload.url,
payload.line,
payload.repeatCount,
payload.parameters,
payload.stackTrace,
payload.networkRequestId,
this._console._enablingConsole);
this._console.addMessage(consoleMessage);
},


messageRepeatCountUpdated: function(count)
{
this._console._messageRepeatCountUpdated(count);
},

messagesCleared: function()
{
if (!WebInspector.settings.preserveConsoleLog.get())
this._console.clearMessages();
}
}


WebInspector.console = null;






WebInspector.ConsoleMessageImpl = function(source, level, message, linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
WebInspector.ConsoleMessage.call(this, source, level, url, line, repeatCount);

this._linkifier = linkifier;
this.type = type || WebInspector.ConsoleMessage.MessageType.Log;
this._messageText = message;
this._parameters = parameters;
this._stackTrace = stackTrace;
this._request = requestId ? WebInspector.networkLog.requestForId(requestId) : null;
this._isOutdated = isOutdated;

this._customFormatters = {
"object": this._formatParameterAsObject,
"array":  this._formatParameterAsArray,
"node":   this._formatParameterAsNode,
"string": this._formatParameterAsString
};
}

WebInspector.ConsoleMessageImpl.prototype = {
_formatMessage: function()
{
this._formattedMessage = document.createElement("span");
this._formattedMessage.className = "console-message-text source-code";

if (this.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Trace:
this._messageElement = document.createTextNode("console.trace()");
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
var args = [WebInspector.UIString("Assertion failed:")];
if (this._parameters)
args = args.concat(this._parameters);
this._messageElement = this._format(args);
break;
case WebInspector.ConsoleMessage.MessageType.Dir:
var obj = this._parameters ? this._parameters[0] : undefined;
var args = ["%O", obj];
this._messageElement = this._format(args);
break;
default:
var args = this._parameters || [this._messageText];
this._messageElement = this._format(args);
}
} else if (this.source === WebInspector.ConsoleMessage.MessageSource.Network) {
if (this._request) {
this._stackTrace = this._request.initiator.stackTrace;
if (this._request.initiator && this._request.initiator.url) {
this.url = this._request.initiator.url;
this.line = this._request.initiator.lineNumber;
}
this._messageElement = document.createElement("span");
if (this.level === WebInspector.ConsoleMessage.MessageLevel.Error) {
this._messageElement.appendChild(document.createTextNode(this._request.requestMethod + " "));
this._messageElement.appendChild(WebInspector.linkifyRequestAsNode(this._request));
if (this._request.failed)
this._messageElement.appendChild(document.createTextNode(" " + this._request.localizedFailDescription));
else
this._messageElement.appendChild(document.createTextNode(" " + this._request.statusCode + " (" + this._request.statusText + ")"));
} else {
var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(this._messageText, WebInspector.linkifyRequestAsNode.bind(null, this._request, ""));
this._messageElement.appendChild(fragment);
}
} else {
if (this.url) {
var isExternal = !WebInspector.resourceForURL(this.url);
this._anchorElement = WebInspector.linkifyURLAsNode(this.url, this.url, "console-message-url", isExternal);
}
this._messageElement = this._format([this._messageText]);
}
} else {
var args = this._parameters || [this._messageText];
this._messageElement = this._format(args);
}

if (this.source !== WebInspector.ConsoleMessage.MessageSource.Network || this._request) {
if (this._stackTrace && this._stackTrace.length && this._stackTrace[0].url) {
this._anchorElement = this._linkifyCallFrame(this._stackTrace[0]);
} else if (this.url && this.url !== "undefined") {
this._anchorElement = this._linkifyLocation(this.url, this.line, 0);
}
}

this._formattedMessage.appendChild(this._messageElement);
if (this._anchorElement) {
this._formattedMessage.appendChild(document.createTextNode(" "));
this._formattedMessage.appendChild(this._anchorElement);
}

var dumpStackTrace = !!this._stackTrace && this._stackTrace.length && (this.source === WebInspector.ConsoleMessage.MessageSource.Network || this.level === WebInspector.ConsoleMessage.MessageLevel.Error || this.type === WebInspector.ConsoleMessage.MessageType.Trace);
if (dumpStackTrace) {
var ol = document.createElement("ol");
ol.className = "outline-disclosure";
var treeOutline = new TreeOutline(ol);

var content = this._formattedMessage;
var root = new TreeElement(content, null, true);
content.treeElementForTest = root;
treeOutline.appendChild(root);
if (this.type === WebInspector.ConsoleMessage.MessageType.Trace)
root.expand();

this._populateStackTraceTreeElement(root);
this._formattedMessage = ol;
}


this._message = this._messageElement.textContent;
},

get message()
{

var formattedMessage = this.formattedMessage;
return this._message;
},

get formattedMessage()
{
if (!this._formattedMessage)
this._formatMessage();
return this._formattedMessage;
},

_linkifyLocation: function(url, lineNumber, columnNumber)
{

lineNumber = lineNumber ? lineNumber - 1 : 0;
columnNumber = columnNumber ? columnNumber - 1 : 0;
return this._linkifier.linkifyLocation(url, lineNumber, columnNumber, "console-message-url");
},

_linkifyCallFrame: function(callFrame)
{
return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
},

isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},

_format: function(parameters)
{

var formattedResult = document.createElement("span");
if (!parameters.length)
return formattedResult;



for (var i = 0; i < parameters.length; ++i) {

if (parameters[i] instanceof WebInspector.RemoteObject)
continue;

if (typeof parameters[i] === "object")
parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]);
else
parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]);
}


var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result;


if (shouldFormatMessage) {

var result = this._formatWithSubstitutionString(parameters, formattedResult);
parameters = result.unusedSubstitutions;
if (parameters.length)
formattedResult.appendChild(document.createTextNode(" "));
}


for (var i = 0; i < parameters.length; ++i) {

if (shouldFormatMessage && parameters[i].type === "string")
formattedResult.appendChild(document.createTextNode(parameters[i].description));
else
formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
if (i < parameters.length - 1)
formattedResult.appendChild(document.createTextNode(" "));
}
return formattedResult;
},


_formatParameter: function(output, forceObjectFormat, includePreview)
{
var type;
if (forceObjectFormat)
type = "object";
else if (output instanceof WebInspector.RemoteObject)
type = output.subtype || output.type;
else
type = typeof output;

var formatter = this._customFormatters[type];
if (!formatter) {
formatter = this._formatParameterAsValue;
output = output.description;
}

var span = document.createElement("span");
span.className = "console-formatted-" + type + " source-code";
formatter.call(this, output, span, includePreview);
return span;
},

_formatParameterAsValue: function(val, elem)
{
elem.appendChild(document.createTextNode(val));
},

_formatParameterAsObject: function(obj, elem, includePreview)
{
this._formatParameterAsArrayOrObject(obj, obj.description, elem, includePreview);
},


_formatParameterAsArrayOrObject: function(obj, description, elem, includePreview)
{
var titleElement = document.createElement("span");
if (description)
titleElement.createTextChild(description);
if (includePreview && obj.preview) {
titleElement.addStyleClass("console-object-preview");
var lossless = this._appendObjectPreview(obj, description, titleElement);
if (lossless) {
elem.appendChild(titleElement);
return;
}
}
var section = new WebInspector.ObjectPropertiesSection(obj, titleElement);
section.enableContextMenu();
elem.appendChild(section.element);
},


_appendObjectPreview: function(obj, description, titleElement)
{
var preview = obj.preview;
var isArray = obj.subtype === "array";

if (description)
titleElement.createTextChild(" ");
titleElement.createTextChild(isArray ? "[" : "{");
for (var i = 0; i < preview.properties.length; ++i) {
if (i > 0)
titleElement.createTextChild(", ");

var property = preview.properties[i];
if (!isArray || property.name != i) {
titleElement.createChild("span", "name").textContent = property.name;
titleElement.createTextChild(": ");
}

var span = titleElement.createChild("span", "console-formatted-" + property.type);
if (property.type === "object") {
if (property.subtype === "node")
span.addStyleClass("console-formatted-preview-node");
else if (property.subtype === "regexp")
span.addStyleClass("console-formatted-string");
}
span.textContent = property.value;
}
if (preview.overflow)
titleElement.createChild("span").textContent = "\u2026";
titleElement.createTextChild(isArray ? "]" : "}");
return preview.lossless;
},

_formatParameterAsNode: function(object, elem)
{
function printNode(nodeId)
{
if (!nodeId) {


this._formatParameterAsObject(object, elem, false);
return;
}
var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
treeOutline.setVisible(true);
treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
treeOutline.element.addStyleClass("outline-disclosure");
if (!treeOutline.children[0].hasChildren)
treeOutline.element.addStyleClass("single-node");
elem.appendChild(treeOutline.element);
treeOutline.element.treeElementForTest = treeOutline.children[0];
}
object.pushNodeToFrontend(printNode.bind(this));
},

_formatParameterAsArray: function(array, elem)
{
if (array.preview) {
this._formatParameterAsArrayOrObject(array, "", elem, true);
return;
}

const maxFlatArrayLength = 100;
if (this._isOutdated || array.arrayLength() > maxFlatArrayLength)
this._formatParameterAsObject(array, elem, false);
else
array.getOwnProperties(this._printArray.bind(this, array, elem));
},

_formatParameterAsString: function(output, elem)
{
var span = document.createElement("span");
span.className = "console-formatted-string source-code";
span.appendChild(WebInspector.linkifyStringAsFragment(output.description));


elem.removeStyleClass("console-formatted-string");
elem.appendChild(document.createTextNode("\""));
elem.appendChild(span);
elem.appendChild(document.createTextNode("\""));
},

_printArray: function(array, elem, properties)
{
if (!properties)
return;

var elements = [];
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
var name = property.name;
if (!isNaN(name))
elements[name] = this._formatAsArrayEntry(property.value);
}

elem.appendChild(document.createTextNode("["));
var lastNonEmptyIndex = -1;

function appendUndefined(elem, index)
{
if (index - lastNonEmptyIndex <= 1)
return;
var span = elem.createChild(span, "console-formatted-undefined");
span.textContent = WebInspector.UIString("undefined × %d", index - lastNonEmptyIndex - 1);
}

var length = array.arrayLength();
for (var i = 0; i < length; ++i) {
var element = elements[i];
if (!element)
continue;

if (i - lastNonEmptyIndex > 1) {
appendUndefined(elem, i);
elem.appendChild(document.createTextNode(", "));
}

elem.appendChild(element);
lastNonEmptyIndex = i;
if (i < length - 1)
elem.appendChild(document.createTextNode(", "));
}
appendUndefined(elem, length);

elem.appendChild(document.createTextNode("]"));
},

_formatAsArrayEntry: function(output)
{

return this._formatParameter(output, output.subtype && output.subtype === "array", false);
},

_formatWithSubstitutionString: function(parameters, formattedResult)
{
var formatters = {}

function parameterFormatter(force, obj)
{
return this._formatParameter(obj, force, false);
}

function valueFormatter(obj)
{
return obj.description;
}


formatters.o = parameterFormatter.bind(this, false);
formatters.s = valueFormatter;
formatters.f = valueFormatter;

formatters.i = valueFormatter;
formatters.d = valueFormatter;


formatters.O = parameterFormatter.bind(this, true);

function append(a, b)
{
if (!(b instanceof Node))
a.appendChild(WebInspector.linkifyStringAsFragment(b.toString()));
else
a.appendChild(b);
return a;
}


return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append);
},

clearHighlight: function()
{
if (!this._formattedMessage)
return;

var highlightedMessage = this._formattedMessage;
delete this._formattedMessage;
delete this._anchorElement;
delete this._messageElement;
this._formatMessage();
this._element.replaceChild(this._formattedMessage, highlightedMessage);
},

highlightSearchResults: function(regexObject)
{
if (!this._formattedMessage)
return;

this._highlightSearchResultsInElement(regexObject, this._messageElement);
if (this._anchorElement)
this._highlightSearchResultsInElement(regexObject, this._anchorElement);

this._element.scrollIntoViewIfNeeded();
},

_highlightSearchResultsInElement: function(regexObject, element)
{
regexObject.lastIndex = 0;
var text = element.textContent;
var match = regexObject.exec(text);
var offset = 0;
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
WebInspector.highlightSearchResults(element, matchRanges);
},

matchesRegex: function(regexObject)
{
return regexObject.test(this._message) || (this._anchorElement && regexObject.test(this._anchorElement.textContent));
},

toMessageElement: function()
{
if (this._element)
return this._element;

var element = document.createElement("div");
element.message = this;
element.className = "console-message";

this._element = element;

switch (this.level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
element.addStyleClass("console-tip-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Log:
element.addStyleClass("console-log-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
element.addStyleClass("console-debug-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
element.addStyleClass("console-warning-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
element.addStyleClass("console-error-level");
break;
}

if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
element.addStyleClass("console-group-title");

element.appendChild(this.formattedMessage);

if (this.repeatCount > 1)
this.updateRepeatCount();

return element;
},

_populateStackTraceTreeElement: function(parentTreeElement)
{
for (var i = 0; i < this._stackTrace.length; i++) {
var frame = this._stackTrace[i];

var content = document.createElement("div");
var messageTextElement = document.createElement("span");
messageTextElement.className = "console-message-text source-code";
var functionName = frame.functionName || WebInspector.UIString("(anonymous function)");
messageTextElement.appendChild(document.createTextNode(functionName));
content.appendChild(messageTextElement);

if (frame.url) {
content.appendChild(document.createTextNode(" "));
var urlElement = this._linkifyCallFrame(frame);
content.appendChild(urlElement);
}

var treeElement = new TreeElement(content);
parentTreeElement.appendChild(treeElement);
}
},

updateRepeatCount: function() {
if (!this.repeatCountElement) {
this.repeatCountElement = document.createElement("span");
this.repeatCountElement.className = "bubble";

this._element.insertBefore(this.repeatCountElement, this._element.firstChild);
this._element.addStyleClass("repeated-message");
}
this.repeatCountElement.textContent = this.repeatCount;
},

toString: function()
{
var sourceString;
switch (this.source) {
case WebInspector.ConsoleMessage.MessageSource.HTML:
sourceString = "HTML";
break;
case WebInspector.ConsoleMessage.MessageSource.XML:
sourceString = "XML";
break;
case WebInspector.ConsoleMessage.MessageSource.JS:
sourceString = "JS";
break;
case WebInspector.ConsoleMessage.MessageSource.Network:
sourceString = "Network";
break;
case WebInspector.ConsoleMessage.MessageSource.ConsoleAPI:
sourceString = "ConsoleAPI";
break;
case WebInspector.ConsoleMessage.MessageSource.Other:
sourceString = "Other";
break;
}

var typeString;
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Log:
typeString = "Log";
break;
case WebInspector.ConsoleMessage.MessageType.Dir:
typeString = "Dir";
break;
case WebInspector.ConsoleMessage.MessageType.DirXML:
typeString = "Dir XML";
break;
case WebInspector.ConsoleMessage.MessageType.Trace:
typeString = "Trace";
break;
case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
case WebInspector.ConsoleMessage.MessageType.StartGroup:
typeString = "Start Group";
break;
case WebInspector.ConsoleMessage.MessageType.EndGroup:
typeString = "End Group";
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
typeString = "Assert";
break;
case WebInspector.ConsoleMessage.MessageType.Result:
typeString = "Result";
break;
}

var levelString;
switch (this.level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
levelString = "Tip";
break;
case WebInspector.ConsoleMessage.MessageLevel.Log:
levelString = "Log";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
levelString = "Warning";
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
levelString = "Debug";
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
levelString = "Error";
break;
}

return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
},

get text()
{
return this._messageText;
},

location: function()
{

var lineNumber = this.stackTrace ? this.stackTrace[0].lineNumber - 1 : this.line - 1;
var columnNumber = this.stackTrace && this.stackTrace[0].columnNumber ? this.stackTrace[0].columnNumber - 1 : 0;
return WebInspector.debuggerModel.createRawLocationByURL(this.url, lineNumber, columnNumber);
},

isEqual: function(msg)
{
if (!msg)
return false;

if (this._stackTrace) {
if (!msg._stackTrace)
return false;
var l = this._stackTrace;
var r = msg._stackTrace;
for (var i = 0; i < l.length; i++) {
if (l[i].url !== r[i].url ||
l[i].functionName !== r[i].functionName ||
l[i].lineNumber !== r[i].lineNumber ||
l[i].columnNumber !== r[i].columnNumber)
return false;
}
}

return (this.source === msg.source)
&& (this.type === msg.type)
&& (this.level === msg.level)
&& (this.line === msg.line)
&& (this.url === msg.url)
&& (this.message === msg.message)
&& (this._request === msg._request);
},

get stackTrace()
{
return this._stackTrace;
},


clone: function()
{
return WebInspector.ConsoleMessage.create(this.source, this.level, this._messageText, this.type, this.url, this.line, this.repeatCount, this._parameters, this._stackTrace, this._request ? this._request.requestId : undefined, this._isOutdated);
}
}

WebInspector.ConsoleMessageImpl.prototype.__proto__ = WebInspector.ConsoleMessage.prototype;





const ExpressionStopCharacters = " =:[({;,!+-*/&|^<>";


WebInspector.ConsoleView = function(hideContextSelector)
{
WebInspector.View.call(this);

this.element.id = "console-view";
this.messages = [];

this._clearConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear console log."), "clear-status-bar-item");
this._clearConsoleButton.addEventListener("click", this._requestClearMessages, this);

this._frameSelector = new WebInspector.StatusBarComboBox(this._frameChanged.bind(this), "console-context");
this._contextSelector = new WebInspector.StatusBarComboBox(this._contextChanged.bind(this), "console-context");

if (hideContextSelector) {
this._frameSelector.element.addStyleClass("hidden");
this._contextSelector.element.addStyleClass("hidden");
}

this.messagesElement = document.createElement("div");
this.messagesElement.id = "console-messages";
this.messagesElement.className = "monospace";
this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
this.element.appendChild(this.messagesElement);
this._scrolledToBottom = true;

this.promptElement = document.createElement("div");
this.promptElement.id = "console-prompt";
this.promptElement.className = "source-code";
this.promptElement.spellcheck = false;
this.messagesElement.appendChild(this.promptElement);
this.messagesElement.appendChild(document.createElement("br"));

this.topGroup = new WebInspector.ConsoleGroup(null);
this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
this.currentGroup = this.topGroup;

this._filterBarElement = document.createElement("div");
this._filterBarElement.className = "scope-bar status-bar-item";

function createDividerElement()
{
var dividerElement = document.createElement("div");
dividerElement.addStyleClass("scope-bar-divider");
this._filterBarElement.appendChild(dividerElement);
}

var updateFilterHandler = this._updateFilter.bind(this);

function createFilterElement(category, label)
{
var categoryElement = document.createElement("li");
categoryElement.category = category;
categoryElement.className = category;
categoryElement.addEventListener("click", updateFilterHandler, false);
categoryElement.textContent = label;

this._filterBarElement.appendChild(categoryElement);

return categoryElement;
}

this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All"));
createDividerElement.call(this);
this.errorElement = createFilterElement.call(this, "errors", WebInspector.UIString("Errors"));
this.warningElement = createFilterElement.call(this, "warnings", WebInspector.UIString("Warnings"));
this.logElement = createFilterElement.call(this, "logs", WebInspector.UIString("Logs"));

this.filter(this.allElement, false);
this._registerShortcuts();
this.registerRequiredCSS("textPrompt.css");

this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);

WebInspector.settings.monitoringXHREnabled.addChangeListener(this._monitoringXHREnabledSettingChanged.bind(this));

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);

this._linkifier = new WebInspector.Linkifier();

this.prompt = new WebInspector.TextPromptWithHistory(this.completionsForTextPrompt.bind(this), ExpressionStopCharacters + ".");
this.prompt.setSuggestBoxEnabled("generic-suggest");
this.prompt.renderAsBlock();
this.prompt.attach(this.promptElement);
this.prompt.proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false);
this.prompt.setHistoryData(WebInspector.settings.consoleHistory.get());

WebInspector.runtimeModel.contextLists().forEach(this._addFrame, this);
WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, this._frameAdded, this);
WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this);
}

WebInspector.ConsoleView.Events = {
ConsoleCleared: "console-cleared",
EntryAdded: "console-entry-added",
}

WebInspector.ConsoleView.prototype = {
get statusBarItems()
{
return [this._clearConsoleButton.element, this._frameSelector.element, this._contextSelector.element, this._filterBarElement];
},


_frameAdded: function(event)
{
var contextList =   event.data;
this._addFrame(contextList);
},


_addFrame: function(contextList)
{
var option = document.createElement("option");
option.text = contextList.displayName;
option.title = contextList.url;
option._contextList = contextList;
contextList._consoleOption = option;
this._frameSelector.addOption(option);
contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this._frameUpdated, this);
contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this._contextAdded, this);
this._frameChanged();
},


_frameRemoved: function(event)
{
var contextList =   event.data;
this._frameSelector.removeOption(contextList._consoleOption);
this._frameChanged();
},

_frameChanged: function()
{
var context = this._currentFrame();
if (!context) {
delete this._currentExecutionContext;
this._contextSelector.element.addStyleClass("hidden");
return;
}

var executionContexts = context.executionContexts();
if (executionContexts.length)
this._currentExecutionContext = executionContexts[0];

if (executionContexts.length === 1) {
this._contextSelector.element.addStyleClass("hidden");
return;
}
this._contextSelector.element.removeStyleClass("hidden");
this._contextSelector.removeOptions();
for (var i = 0; i < executionContexts.length; i++)
this._appendContextOption(executionContexts[i]);
},


_appendContextOption: function(executionContext)
{
if (!this._currentExecutionContext)
this._currentExecutionContext = executionContext;
var option = document.createElement("option");
option.text = executionContext.name;
option.title = executionContext.id;
option._executionContext = executionContext;
this._contextSelector.addOption(option);
},


_contextChanged: function(event)
{
var option = this._contextSelector.selectedOption();
this._currentExecutionContext = option ? option._executionContext : undefined;
},


_frameUpdated: function(event)
{
var contextList =   event.data;
var option = contextList._consoleOption;
option.text = contextList.displayName;
option.title = contextList.url;
},


_contextAdded: function(event)
{
var contextList =   event.data;
if (contextList === this._currentFrame())
this._frameChanged();
},


_currentFrame: function()
{
var option = this._frameSelector.selectedOption();
return option ? option._contextList : undefined;
},

_updateFilter: function(e)
{
var isMac = WebInspector.isMac();
var selectMultiple = false;
if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
selectMultiple = true;
if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
selectMultiple = true;

this.filter(e.target, selectMultiple);
},

filter: function(target, selectMultiple)
{
function unselectAll()
{
this.allElement.removeStyleClass("selected");
this.errorElement.removeStyleClass("selected");
this.warningElement.removeStyleClass("selected");
this.logElement.removeStyleClass("selected");

this.messagesElement.removeStyleClass("filter-all");
this.messagesElement.removeStyleClass("filter-errors");
this.messagesElement.removeStyleClass("filter-warnings");
this.messagesElement.removeStyleClass("filter-logs");
}

var targetFilterClass = "filter-" + target.category;

if (target.category === "all") {
if (target.hasStyleClass("selected")) {

return;
}

unselectAll.call(this);
} else {

if (this.allElement.hasStyleClass("selected")) {
this.allElement.removeStyleClass("selected");
this.messagesElement.removeStyleClass("filter-all");
}
}

if (!selectMultiple) {


unselectAll.call(this);

target.addStyleClass("selected");
this.messagesElement.addStyleClass(targetFilterClass);

return;
}

if (target.hasStyleClass("selected")) {


target.removeStyleClass("selected");
this.messagesElement.removeStyleClass(targetFilterClass);
} else {


target.addStyleClass("selected");
this.messagesElement.addStyleClass(targetFilterClass);
}
},

willHide: function()
{
this.prompt.hideSuggestBox();
this.prompt.clearAutoComplete(true);
},

wasShown: function()
{
if (!this.prompt.isCaretInsidePrompt())
this.prompt.moveCaretToEndOfPrompt();
},

afterShow: function()
{
WebInspector.setCurrentFocusElement(this.promptElement);
},

storeScrollPositions: function()
{
WebInspector.View.prototype.storeScrollPositions.call(this);
this._scrolledToBottom = this.messagesElement.isScrolledToBottom();
},

restoreScrollPositions: function()
{
if (this._scrolledToBottom)
this._immediatelyScrollIntoView();
else
WebInspector.View.prototype.restoreScrollPositions.call(this);
},

onResize: function()
{
this.restoreScrollPositions();
},

_isScrollIntoViewScheduled: function()
{
return !!this._scrollIntoViewTimer;
},

_scheduleScrollIntoView: function()
{
if (this._scrollIntoViewTimer)
return;

function scrollIntoView()
{
delete this._scrollIntoViewTimer;
this.promptElement.scrollIntoView(true);
}
this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20);
},

_immediatelyScrollIntoView: function()
{
this.promptElement.scrollIntoView(true);
this._cancelScheduledScrollIntoView();
},

_cancelScheduledScrollIntoView: function()
{
if (!this._isScrollIntoViewScheduled())
return;

clearTimeout(this._scrollIntoViewTimer);
delete this._scrollIntoViewTimer;
},


_consoleMessageAdded: function(event)
{
this._appendConsoleMessage(event.data);
},

_appendConsoleMessage: function(msg)
{


if (!this._isScrollIntoViewScheduled() && ((msg instanceof WebInspector.ConsoleCommandResult) || this.messagesElement.isScrolledToBottom()))
this._scheduleScrollIntoView();

this.messages.push(msg);

if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
var parentGroup = this.currentGroup.parentGroup
if (parentGroup)
this.currentGroup = parentGroup;
} else {
if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
var group = new WebInspector.ConsoleGroup(this.currentGroup);
this.currentGroup.messagesElement.appendChild(group.element);
this.currentGroup = group;
}

this.currentGroup.addMessage(msg);
}

this.dispatchEventToListeners(WebInspector.ConsoleView.Events.EntryAdded, msg);
},

_consoleCleared: function()
{
this._scrolledToBottom = true;
this.messages = [];

this.currentGroup = this.topGroup;
this.topGroup.messagesElement.removeChildren();

this.dispatchEventToListeners(WebInspector.ConsoleView.Events.ConsoleCleared);

this._linkifier.reset();
},

completionsForTextPrompt: function(textPrompt, wordRange, force, completionsReadyCallback)
{

var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, ExpressionStopCharacters, textPrompt.proxyElement, "backward");
var expressionString = expressionRange.toString();
var prefix = wordRange.toString();
this.completionsForExpression(expressionString, prefix, force, completionsReadyCallback);
},

completionsForExpression: function(expressionString, prefix, force, completionsReadyCallback)
{
var lastIndex = expressionString.length - 1;

var dotNotation = (expressionString[lastIndex] === ".");
var bracketNotation = (expressionString[lastIndex] === "[");

if (dotNotation || bracketNotation)
expressionString = expressionString.substr(0, lastIndex);

if (expressionString && parseInt(expressionString, 10) == expressionString) {

completionsReadyCallback([]);
return;
}

if (!prefix && !expressionString && !force) {
completionsReadyCallback([]);
return;
}

if (!expressionString && WebInspector.debuggerModel.selectedCallFrame())
WebInspector.debuggerModel.getSelectedCallFrameVariables(receivedPropertyNames.bind(this));
else
this.evalInInspectedWindow(expressionString, "completion", true, true, false, evaluated.bind(this));

function evaluated(result, wasThrown)
{
if (!result || wasThrown) {
completionsReadyCallback([]);
return;
}

function getCompletions(primitiveType)
{
var object;
if (primitiveType === "string")
object = new String("");
else if (primitiveType === "number")
object = new Number(0);
else if (primitiveType === "boolean")
object = new Boolean(false);
else
object = this;

var resultSet = {};
for (var o = object; o; o = o.__proto__) {
try {
var names = Object.getOwnPropertyNames(o);
for (var i = 0; i < names.length; ++i)
resultSet[names[i]] = true;
} catch (e) {
}
}
return resultSet;
}

if (result.type === "object" || result.type === "function")
result.callFunctionJSON(getCompletions, undefined, receivedPropertyNames.bind(this));
else if (result.type === "string" || result.type === "number" || result.type === "boolean")
this.evalInInspectedWindow("(" + getCompletions + ")(\"" + result.type + "\")", "completion", false, true, true, receivedPropertyNamesFromEval.bind(this));
}

function receivedPropertyNamesFromEval(notRelevant, wasThrown, result)
{
if (result && !wasThrown)
receivedPropertyNames.call(this, result.value);
else
completionsReadyCallback([]);
}

function receivedPropertyNames(propertyNames)
{
RuntimeAgent.releaseObjectGroup("completion");
if (!propertyNames) {
completionsReadyCallback([]);
return;
}
var includeCommandLineAPI = (!dotNotation && !bracketNotation);
if (includeCommandLineAPI) {
const commandLineAPI = ["dir", "dirxml", "keys", "values", "profile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear"];
for (var i = 0; i < commandLineAPI.length; ++i)
propertyNames[commandLineAPI[i]] = true;
}
this._reportCompletions(completionsReadyCallback, dotNotation, bracketNotation, expressionString, prefix, Object.keys(propertyNames));
}
},

_reportCompletions: function(completionsReadyCallback, dotNotation, bracketNotation, expressionString, prefix, properties) {
if (bracketNotation) {
if (prefix.length && prefix[0] === "'")
var quoteUsed = "'";
else
var quoteUsed = "\"";
}

var results = [];

if (!expressionString) {
const keywords = ["break", "case", "catch", "continue", "default", "delete", "do", "else", "finally", "for", "function", "if", "in",
"instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with"];
properties = properties.concat(keywords);
}

properties.sort();

for (var i = 0; i < properties.length; ++i) {
var property = properties[i];

if (dotNotation && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(property))
continue;

if (bracketNotation) {
if (!/^[0-9]+$/.test(property))
property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + quoteUsed;
property += "]";
}

if (property.length < prefix.length)
continue;
if (prefix.length && !property.startsWith(prefix))
continue;

results.push(property);
}
completionsReadyCallback(results);
},

_handleContextMenuEvent: function(event)
{
if (!window.getSelection().isCollapsed) {


return;
}

if (event.target.enclosingNodeOrSelfWithNodeName("a"))
return;

var contextMenu = new WebInspector.ContextMenu();

function monitoringXHRItemAction()
{
WebInspector.settings.monitoringXHREnabled.set(!WebInspector.settings.monitoringXHREnabled.get());
}
contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"), monitoringXHRItemAction.bind(this), WebInspector.settings.monitoringXHREnabled.get());

function preserveLogItemAction()
{
WebInspector.settings.preserveConsoleLog.set(!WebInspector.settings.preserveConsoleLog.get());
}
contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Preserve log upon navigation" : "Preserve Log upon Navigation"), preserveLogItemAction.bind(this), WebInspector.settings.preserveConsoleLog.get());

contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear console" : "Clear Console"), this._requestClearMessages.bind(this));
contextMenu.show(event);
},

_monitoringXHREnabledSettingChanged: function(event)
{
ConsoleAgent.setMonitoringXHREnabled(event.data);
},

_messagesClicked: function(event)
{
if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
this.prompt.moveCaretToEndOfPrompt();
},

_registerShortcuts: function()
{
this._shortcuts = {};

var shortcut = WebInspector.KeyboardShortcut;

if (WebInspector.isMac()) {
var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
this._shortcuts[shortcutK.key] = this._requestClearMessages.bind(this);
}

var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[shortcutL.key] = this._requestClearMessages.bind(this);

var shortcutM = shortcut.makeDescriptor("m", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift);
this._shortcuts[shortcutM.key] = this._dumpMemory.bind(this);

var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
var keys = WebInspector.isMac() ? [ shortcutK.name, shortcutL.name ] : [ shortcutL.name ];
section.addAlternateKeys(keys, WebInspector.UIString("Clear console"));

keys = [
shortcut.shortcutToString(shortcut.Keys.Tab),
shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous suggestion"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
keys = [
shortcut.shortcutToString(shortcut.Keys.Down),
shortcut.shortcutToString(shortcut.Keys.Up)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
keys = [
shortcut.shortcutToString("N", shortcut.Modifiers.Alt),
shortcut.shortcutToString("P", shortcut.Modifiers.Alt)
];
if (WebInspector.isMac())
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
},

_requestClearMessages: function()
{
WebInspector.console.requestClearMessages();
},

_promptKeyDown: function(event)
{
if (isEnterKey(event)) {
this._enterKeyPressed(event);
return;
}

var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcut];
if (handler) {
handler();
event.preventDefault();
return;
}
},


evalInInspectedWindow: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, callback)
{
if (WebInspector.debuggerModel.selectedCallFrame()) {
WebInspector.debuggerModel.evaluateOnSelectedCallFrame(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, callback);
return;
}

if (!expression) {

expression = "this";
}


function evalCallback(error, result, wasThrown)
{
if (error) {
console.error(error);
callback(null, false);
return;
}

if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result);
else
callback(WebInspector.RemoteObject.fromPayload(result), !!wasThrown);
}
RuntimeAgent.evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, this._currentExecutionContext ? this._currentExecutionContext.id : undefined, returnByValue, evalCallback);
},

evaluateUsingTextPrompt: function(expression, showResultOnly)
{
this._appendCommand(expression, this.prompt.text, false, showResultOnly);
},

_enterKeyPressed: function(event)
{
if (event.altKey || event.ctrlKey || event.shiftKey)
return;

event.consume(true);

this.prompt.clearAutoComplete(true);

var str = this.prompt.text;
if (!str.length)
return;
this._appendCommand(str, "", true, false);
},

runScript: function(scriptId)
{
DebuggerAgent.runScript(scriptId, this._currentExecutionContext ? this._currentExecutionContext.id : undefined, "console", false, runCallback.bind(this));
WebInspector.userMetrics.ConsoleEvaluated.record();


function runCallback(error, result, wasThrown)
{
if (error) {
console.error(error);
return;
}

this._printResult(result, wasThrown, null);
}
},

_printResult: function(result, wasThrown, originatingCommand)
{
if (!result)
return;

this._appendConsoleMessage(new WebInspector.ConsoleCommandResult(result, wasThrown, originatingCommand, this._linkifier));
},

_appendCommand: function(text, newPromptText, useCommandLineAPI, showResultOnly)
{
if (!showResultOnly) {
var commandMessage = new WebInspector.ConsoleCommand(text);
WebInspector.console.interruptRepeatCount();
this._appendConsoleMessage(commandMessage);
}
this.prompt.text = newPromptText;

function printResult(result, wasThrown)
{
if (!result)
return;

if (!showResultOnly) {
this.prompt.pushHistoryItem(text);
WebInspector.settings.consoleHistory.set(this.prompt.historyData.slice(-30));
}

this._printResult(result, wasThrown, commandMessage);
}
this.evalInInspectedWindow(text, "console", useCommandLineAPI, false, false, printResult.bind(this));

WebInspector.userMetrics.ConsoleEvaluated.record();
},

elementsToRestoreScrollPositionsFor: function()
{
return [this.messagesElement];
},

_dumpMemory: function()
{
function comparator(a, b)
{
if (a.size < b.size)
return 1;
if (a.size > b.size)
return -1;
return a.title.localeCompare(b.title);
}

function callback(error, groups)
{
var titles = [];
groups.sort(comparator);
for (var i = 0; i < groups.length; ++i) {
var suffix = groups[i].size > 0 ? " [" + groups[i].size + "]" : "";
titles.push(groups[i].title + suffix + (groups[i].documentURI ? " (" + groups[i].documentURI + ")" : ""));
}

var counter = 1;
var previousTitle = null;
for (var i = 0; i < titles.length; ++i) {
var title = titles[i];
if (title === previousTitle) {
counter++;
continue;
}
if (previousTitle)
WebInspector.log(counter > 1 ? counter + " x " + previousTitle : previousTitle);
previousTitle = title;
counter = 1;
}
WebInspector.log(counter > 1 ? counter + " x " + previousTitle : previousTitle);
}
MemoryAgent.getDOMNodeCount(callback);
}
}

WebInspector.ConsoleView.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.ConsoleCommand = function(command)
{
this.command = command;
}

WebInspector.ConsoleCommand.prototype = {
clearHighlight: function()
{
var highlightedMessage = this._formattedCommand;
delete this._formattedCommand;
this._formatCommand();
this._element.replaceChild(this._formattedCommand, highlightedMessage);
},

highlightSearchResults: function(regexObject)
{
regexObject.lastIndex = 0;
var text = this.command;
var match = regexObject.exec(text);
var offset = 0;
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
WebInspector.highlightSearchResults(this._formattedCommand, matchRanges);
this._element.scrollIntoViewIfNeeded();
},

matchesRegex: function(regexObject)
{
return regexObject.test(this.command);
},

toMessageElement: function()
{
if (!this._element) {
this._element = document.createElement("div");
this._element.command = this;
this._element.className = "console-user-command";

this._formatCommand();
this._element.appendChild(this._formattedCommand);
}
return this._element;
},

_formatCommand: function()
{
this._formattedCommand = document.createElement("span");
this._formattedCommand.className = "console-message-text source-code";
this._formattedCommand.textContent = this.command;
},
}


WebInspector.ConsoleCommandResult = function(result, wasThrown, originatingCommand, linkifier)
{
var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
this.originatingCommand = originatingCommand;
WebInspector.ConsoleMessageImpl.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, "", linkifier, WebInspector.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, [result]);
}

WebInspector.ConsoleCommandResult.prototype = {
toMessageElement: function()
{
var element = WebInspector.ConsoleMessageImpl.prototype.toMessageElement.call(this);
element.addStyleClass("console-user-command-result");
return element;
}
}

WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessageImpl.prototype;


WebInspector.ConsoleGroup = function(parentGroup)
{
this.parentGroup = parentGroup;

var element = document.createElement("div");
element.className = "console-group";
element.group = this;
this.element = element;

if (parentGroup) {
var bracketElement = document.createElement("div");
bracketElement.className = "console-group-bracket";
element.appendChild(bracketElement);
}

var messagesElement = document.createElement("div");
messagesElement.className = "console-group-messages";
element.appendChild(messagesElement);
this.messagesElement = messagesElement;
}

WebInspector.ConsoleGroup.prototype = {
addMessage: function(msg)
{
var element = msg.toMessageElement();

if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
this.messagesElement.parentNode.insertBefore(element, this.messagesElement);
element.addEventListener("click", this._titleClicked.bind(this), false);
var groupElement = element.enclosingNodeOrSelfWithClass("console-group");
if (groupElement && msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
groupElement.addStyleClass("collapsed");
} else
this.messagesElement.appendChild(element);

if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand)
element.previousSibling.addStyleClass("console-adjacent-user-command-result");
},

_titleClicked: function(event)
{
var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title");
if (groupTitleElement) {
var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group");
if (groupElement)
if (groupElement.hasStyleClass("collapsed"))
groupElement.removeStyleClass("collapsed");
else
groupElement.addStyleClass("collapsed");
groupTitleElement.scrollIntoViewIfNeeded(true);
}

event.consume(true);
}
}


WebInspector.consoleView = null;

WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
return new WebInspector.ConsoleMessageImpl(source, level, message, WebInspector.consoleView._linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated);
}






WebInspector.Panel = function(name)
{
WebInspector.View.call(this);
WebInspector.panels[name] = this;

this.element.addStyleClass("panel");
this.element.addStyleClass(name);
this._panelName = name;

this._shortcuts = {};

WebInspector.settings[this._sidebarWidthSettingName()] = WebInspector.settings.createSetting(this._sidebarWidthSettingName(), undefined);
}


WebInspector.Panel.counterRightMargin = 25;

WebInspector.Panel.prototype = {
get name()
{
return this._panelName;
},

show: function()
{
WebInspector.View.prototype.show.call(this, WebInspector.inspectorView.panelsElement());
},

wasShown: function()
{
var statusBarItems = this.statusBarItems;
if (statusBarItems) {
this._statusBarItemContainer = document.createElement("div");
for (var i = 0; i < statusBarItems.length; ++i)
this._statusBarItemContainer.appendChild(statusBarItems[i]);
document.getElementById("panel-status-bar").appendChild(this._statusBarItemContainer);
}

this.focus();
},

willHide: function()
{
if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
delete this._statusBarItemContainer;
},

reset: function()
{
this.searchCanceled();
},

defaultFocusedElement: function()
{
return this.sidebarTreeElement || this.element;
},

searchCanceled: function()
{
WebInspector.searchController.updateSearchMatchesCount(0, this);
},


performSearch: function(query)
{

this.searchCanceled();
},

jumpToNextSearchResult: function()
{
},

jumpToPreviousSearchResult: function()
{
},


canSearchAndReplace: function()
{
return false;
},


replaceSelectionWith: function(text)
{
},


replaceAllWith: function(query, text)
{
},


canFilter: function()
{
return false;
},


performFilter: function(query)
{
},


createSplitView: function(parentElement, position, defaultWidth)
{
if (this.splitView)
return;

if (!parentElement)
parentElement = this.element;

this.splitView = new WebInspector.SplitView(position || WebInspector.SplitView.SidebarPosition.Left, this._sidebarWidthSettingName(), defaultWidth);
this.splitView.show(parentElement);
this.splitView.addEventListener(WebInspector.SplitView.EventTypes.Resized, this.sidebarResized.bind(this));

this.sidebarElement = this.splitView.sidebarElement;
},


createSplitViewWithSidebarTree: function(parentElement, position, defaultWidth)
{
if (this.splitView)
return;

this.createSplitView(parentElement, position);

this.sidebarTreeElement = document.createElement("ol");
this.sidebarTreeElement.className = "sidebar-tree";
this.splitView.sidebarElement.appendChild(this.sidebarTreeElement);
this.splitView.sidebarElement.addStyleClass("sidebar");

this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
this.sidebarTree.panel = this;
},

_sidebarWidthSettingName: function()
{
return this._panelName + "SidebarWidth";
},



get statusBarItems()
{
},

sidebarResized: function(width)
{
},

statusBarResized: function()
{
},


canShowAnchorLocation: function(anchor)
{
return false;
},


showAnchorLocation: function(anchor)
{
},

elementsToRestoreScrollPositionsFor: function()
{
return [];
},

handleShortcut: function(event)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcutKey];
if (handler) {
handler(event);
event.handled = true;
}
},

registerShortcut: function(key, handler)
{
this._shortcuts[key] = handler;
},

unregisterShortcut: function(key)
{
delete this._shortcuts[key];
}
}

WebInspector.Panel.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.PanelDescriptor = function(name, title, className, scriptName, panel)
{
this._name = name;
this._title = title;
this._className = className;
this._scriptName = scriptName;
this._panel = panel;
}

WebInspector.PanelDescriptor.prototype = {

name: function()
{
return this._name;
},


title: function()
{
return this._title;
},


iconURL: function()
{
return this._iconURL;
},


setIconURL: function(iconURL)
{
this._iconURL = iconURL;
},


panel: function()
{
if (this._panel)
return this._panel;
if (this._scriptName)
importScript(this._scriptName);
this._panel = new WebInspector[this._className];
return this._panel;
}
}






WebInspector.InspectorView = function()
{
WebInspector.View.call(this);
this.markAsRoot();
this.element.id = "main-panels";
this.element.setAttribute("spellcheck", false);
this._history = [];
this._historyIterator = -1;
document.addEventListener("keydown", this._keyDown.bind(this), false);
document.addEventListener("keypress", this._keyPress.bind(this), false);
this._panelOrder = [];
this._panelDescriptors = {};


this._openBracketIdentifiers = ["U+005B", "U+00DB"].keySet();
this._closeBracketIdentifiers = ["U+005D", "U+00DD"].keySet();
this._footerElementContainer = this.element.createChild("div", "inspector-footer status-bar hidden");
this._panelsElement = this.element.createChild("div", "fill");
}

WebInspector.InspectorView.Events = {
PanelSelected: "PanelSelected"
}

WebInspector.InspectorView.prototype = {

addPanel: function(panelDescriptor)
{
this._panelOrder.push(panelDescriptor.name());
this._panelDescriptors[panelDescriptor.name()] = panelDescriptor;
WebInspector.toolbar.addPanel(panelDescriptor);
},


panel: function(panelName)
{
var panelDescriptor = this._panelDescriptors[panelName];
if (!panelDescriptor && this._panelOrder.length)
panelDescriptor = this._panelDescriptors[this._panelOrder[0]];
return panelDescriptor ? panelDescriptor.panel() : null;
},


showPanel: function(panelName)
{
var panel = this.panel(panelName);
if (panel)
this.setCurrentPanel(panel);
return panel;
},

currentPanel: function()
{
return this._currentPanel;
},


setCurrentPanel: function(x)
{
if (this._currentPanel === x)
return;

if (this._currentPanel)
this._currentPanel.detach();

this._currentPanel = x;

if (x) {
x.show();
this.dispatchEventToListeners(WebInspector.InspectorView.Events.PanelSelected);

WebInspector.searchController.cancelSearch();
}
for (var panelName in WebInspector.panels) {
if (WebInspector.panels[panelName] === x) {
WebInspector.settings.lastActivePanel.set(panelName);
this._pushToHistory(panelName);
WebInspector.userMetrics.panelShown(panelName);
}
}
},

_keyPress: function(event)
{
clearTimeout(this._keyDownTimer);
delete this._keyDownTimer;
},

_keyDown: function(event)
{



if (!WebInspector.isWin() || (!this._openBracketIdentifiers.hasOwnProperty(event.keyIdentifier) && !this._closeBracketIdentifiers.hasOwnProperty(event.keyIdentifier))) {
this._keyDownInternal(event);
return;
}

this._keyDownTimer = setTimeout(this._keyDownInternal.bind(this, event), 0);
},

_keyDownInternal: function(event)
{
if (this._openBracketIdentifiers.hasOwnProperty(event.keyIdentifier)) {
var isRotateLeft = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.shiftKey && !event.altKey;
if (isRotateLeft) {
var index = this._panelOrder.indexOf(this.currentPanel().name);
index = (index === 0) ? this._panelOrder.length - 1 : index - 1;
this.showPanel(this._panelOrder[index]);
event.consume(true);
return;
}

var isGoBack = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && event.altKey;
if (isGoBack && this._canGoBackInHistory()) {
this._goBackInHistory();
event.consume(true);
}
return;
}

if (this._closeBracketIdentifiers.hasOwnProperty(event.keyIdentifier)) {
var isRotateRight = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.shiftKey && !event.altKey;
if (isRotateRight) {
var index = this._panelOrder.indexOf(this.currentPanel().name);
index = (index + 1) % this._panelOrder.length;
this.showPanel(this._panelOrder[index]);
event.consume(true);
return;
}

var isGoForward = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && event.altKey;
if (isGoForward && this._canGoForwardInHistory()) {
this._goForwardInHistory();
event.consume(true);
}
return;
}
},

_canGoBackInHistory: function()
{
return this._historyIterator > 0;
},

_goBackInHistory: function()
{
this._inHistory = true;
this.setCurrentPanel(WebInspector.panels[this._history[--this._historyIterator]]);
delete this._inHistory;
},

_canGoForwardInHistory: function()
{
return this._historyIterator < this._history.length - 1;
},

_goForwardInHistory: function()
{
this._inHistory = true;
this.setCurrentPanel(WebInspector.panels[this._history[++this._historyIterator]]);
delete this._inHistory;
},

_pushToHistory: function(panelName)
{
if (this._inHistory)
return;

this._history.splice(this._historyIterator + 1, this._history.length - this._historyIterator - 1);
if (!this._history.length || this._history[this._history.length - 1] !== panelName)
this._history.push(panelName);
this._historyIterator = this._history.length - 1;
},

panelsElement: function()
{
return this._panelsElement;
},


setFooterElement: function(element)
{
if (element) {
this._footerElementContainer.removeStyleClass("hidden");
this._footerElementContainer.appendChild(element);
this._panelsElement.style.bottom = this._footerElementContainer.offsetHeight + "px";
} else {
this._footerElementContainer.addStyleClass("hidden");
this._footerElementContainer.removeChildren();
this._panelsElement.style.bottom = 0;
}
this.doResize();
},


showPanelForAnchorNavigation: function(panel)
{
WebInspector.searchController.disableSearchUntilExplicitAction();
this.setCurrentPanel(panel);
}
}

WebInspector.InspectorView.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.inspectorView = null;






WebInspector.AdvancedSearchController = function()
{
this._shortcut = WebInspector.AdvancedSearchController.createShortcut();
this._searchId = 0;

WebInspector.settings.advancedSearchConfig = WebInspector.settings.createSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false));

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
}

WebInspector.AdvancedSearchController.createShortcut = function()
{
if (WebInspector.isMac())
return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt);
else
return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift);
}

WebInspector.AdvancedSearchController.prototype = {

handleShortcut: function(event)
{
if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) === this._shortcut.key) {
if (!this._searchView || !this._searchView.isShowing() || this._searchView._search !== document.activeElement) {
WebInspector.showPanel("scripts");
this.show();
} else
this.close();
event.consume(true);
return true;
}
return false;
},

_frameNavigated: function()
{
this.resetSearch();
},


registerSearchScope: function(searchScope)
{

this._searchScope = searchScope;
},

show: function()
{
if (!this._searchView)
this._searchView = new WebInspector.SearchView(this);

if (this._searchView.isShowing())
this._searchView.focus();
else
WebInspector.showViewInDrawer(this._searchView._searchPanelElement, this._searchView, this.stopSearch.bind(this));
},

close: function()
{
this.stopSearch();
WebInspector.closeViewInDrawer();
},


_onSearchResult: function(searchId, searchResult)
{
if (searchId !== this._searchId)
return;

this._searchView.addSearchResult(searchResult);
if (!searchResult.searchMatches.length)
return;

if (!this._searchResultsPane) 
this._searchResultsPane = this._currentSearchScope.createSearchResultsPane(this._searchConfig);        
this._searchView.resultsPane = this._searchResultsPane; 
this._searchResultsPane.addSearchResult(searchResult);
},


_onSearchFinished: function(searchId, finished)
{
if (searchId !== this._searchId)
return;

if (!this._searchResultsPane)
this._searchView.nothingFound();

this._searchView.searchFinished(finished);
},


startSearch: function(searchConfig)
{
this.resetSearch();
++this._searchId;

this._searchConfig = searchConfig;

this._currentSearchScope = this._searchScope;

var totalSearchResultsCount = this._currentSearchScope.performSearch(searchConfig, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId));
this._searchView.searchStarted(totalSearchResultsCount);
},

resetSearch: function()
{
this.stopSearch();

if (this._searchResultsPane) {
this._searchView.resetResults();
delete this._searchResultsPane;
}
},

stopSearch: function()
{
if (this._currentSearchScope)
this._currentSearchScope.stopSearch();
}
}


WebInspector.SearchView = function(controller)
{
WebInspector.View.call(this);
this.registerRequiredCSS("textEditor.css");

this._controller = controller;

this.element.className = "search-view";

this._searchPanelElement = document.createElement("span");
this._searchPanelElement.className = "search-drawer-header";
this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false);

this._searchResultsElement = this.element.createChild("div");
this._searchResultsElement.className = "search-results";

this._searchLabel = this._searchPanelElement.createChild("span");
this._searchLabel.textContent = WebInspector.UIString("Search sources");
this._search = this._searchPanelElement.createChild("input");
this._search.setAttribute("type", "search");
this._search.addStyleClass("search-config-search");
this._search.setAttribute("results", "0");
this._search.setAttribute("size", 30);

this._ignoreCaseLabel = this._searchPanelElement.createChild("label");
this._ignoreCaseLabel.addStyleClass("search-config-label");
this._ignoreCaseCheckbox = this._ignoreCaseLabel.createChild("input");
this._ignoreCaseCheckbox.setAttribute("type", "checkbox");
this._ignoreCaseCheckbox.addStyleClass("search-config-checkbox");
this._ignoreCaseLabel.appendChild(document.createTextNode(WebInspector.UIString("Ignore case")));

this._regexLabel = this._searchPanelElement.createChild("label");
this._regexLabel.addStyleClass("search-config-label");
this._regexCheckbox = this._regexLabel.createChild("input");
this._regexCheckbox.setAttribute("type", "checkbox");
this._regexCheckbox.addStyleClass("search-config-checkbox");
this._regexLabel.appendChild(document.createTextNode(WebInspector.UIString("Regular expression")));

this._searchStatusBarElement = document.createElement("div");
this._searchStatusBarElement.className = "search-status-bar-item";
this._searchMessageElement = this._searchStatusBarElement.createChild("div");
this._searchMessageElement.className = "search-status-bar-message";

this._searchResultsMessageElement = document.createElement("span");
this._searchResultsMessageElement.className = "search-results-status-bar-message";

this._load();
}


WebInspector.SearchView.maxQueriesCount = 20;

WebInspector.SearchView.prototype = {
__proto__: WebInspector.View.prototype,


get statusBarItems()
{
return [this._searchStatusBarElement, this._searchResultsMessageElement];
},


get searchConfig()
{
return new WebInspector.SearchConfig(this._search.value, this._ignoreCaseCheckbox.checked, this._regexCheckbox.checked);
},


set resultsPane(resultsPane)
{
this.resetResults();
this._searchResultsElement.appendChild(resultsPane.element);
},


searchStarted: function(totalSearchResultsCount)
{
this.resetResults();
this._resetCounters();

this._searchMessageElement.textContent = WebInspector.UIString("Searching...");
this._progressIndicator = new WebInspector.ProgressIndicator();
this._progressIndicator.setTotalWork(totalSearchResultsCount);
this._progressIndicator.show(this._searchStatusBarElement);

this._updateSearchResultsMessage();

if (!this._searchingView)
this._searchingView = new WebInspector.EmptyView(WebInspector.UIString("Searching..."));
this._searchingView.show(this._searchResultsElement);
},

_updateSearchResultsMessage: function()
{
if (this._searchMatchesCount && this._searchResultsCount)
this._searchResultsMessageElement.textContent = WebInspector.UIString("Found %d matches in %d files.", this._searchMatchesCount, this._nonEmptySearchResultsCount);
else
this._searchResultsMessageElement.textContent = "";
},

resetResults: function()
{
if (this._searchingView)
this._searchingView.detach();
if (this._notFoundView)
this._notFoundView.detach();
this._searchResultsElement.removeChildren();
},

_resetCounters: function()
{
this._searchMatchesCount = 0;
this._searchResultsCount = 0;
this._nonEmptySearchResultsCount = 0;
},

nothingFound: function()
{
this.resetResults();

if (!this._notFoundView)
this._notFoundView = new WebInspector.EmptyView(WebInspector.UIString("No matches found."));
this._notFoundView.show(this._searchResultsElement);
this._searchResultsMessageElement.textContent = WebInspector.UIString("No matches found.");
},


addSearchResult: function(searchResult)
{
this._searchMatchesCount += searchResult.searchMatches.length;
this._searchResultsCount++;
if (searchResult.searchMatches.length)
this._nonEmptySearchResultsCount++;
this._updateSearchResultsMessage();
if (this._progressIndicator.isCanceled())
this._onCancel();
else
this._progressIndicator.setWorked(this._searchResultsCount);
},


searchFinished: function(finished)
{
this._progressIndicator.done();
this._searchMessageElement.textContent = finished ? WebInspector.UIString("Search finished.") : WebInspector.UIString("Search interrupted.");
},

focus: function()
{
WebInspector.setCurrentFocusElement(this._search);
this._search.select();
},

wasShown: function()
{
this.focus();
},

willHide: function()
{
this._controller.stopSearch();
},


_onKeyDown: function(event)
{
switch (event.keyCode) {
case WebInspector.KeyboardShortcut.Keys.Enter.code:
this._onAction();
break;
case WebInspector.KeyboardShortcut.Keys.Esc.code:
this._controller.close();
event.consume(true);
break;
}        
},

_save: function()
{
var searchConfig = new WebInspector.SearchConfig(this.searchConfig.query, this.searchConfig.ignoreCase, this.searchConfig.isRegex); 
WebInspector.settings.advancedSearchConfig.set(searchConfig);
},

_load: function()
{
var searchConfig = WebInspector.settings.advancedSearchConfig.get();
this._search.value = searchConfig.query;
this._ignoreCaseCheckbox.checked = searchConfig.ignoreCase;
this._regexCheckbox.checked = searchConfig.isRegex;
},

_onCancel: function()
{
this._controller.stopSearch();
this.focus();
},

_onAction: function()
{
if (!this.searchConfig.query || !this.searchConfig.query.length)
return;

this._save();
this._controller.startSearch(this.searchConfig);
}
}




WebInspector.SearchConfig = function(query, ignoreCase, isRegex)
{
this.query = query;
this.ignoreCase = ignoreCase;
this.isRegex = isRegex;
}


WebInspector.SearchScope = function()
{
}

WebInspector.SearchScope.prototype = {

performSearch: function(searchConfig, searchResultCallback, searchFinishedCallback) { },

stopSearch: function() { },


createSearchResultsPane: function(searchConfig) { }
}


WebInspector.SearchResult = function(offset, length)
{
this.offset = offset;
this.length = length;    
}


WebInspector.SearchResultsPane = function(searchConfig)
{
this._searchConfig = searchConfig;
this.element = document.createElement("div");
}

WebInspector.SearchResultsPane.prototype = {

get searchConfig()
{
return this._searchConfig;
},


addSearchResult: function(searchResult) { }
}


WebInspector.FileBasedSearchResultsPane = function(searchConfig)
{
WebInspector.SearchResultsPane.call(this, searchConfig);

this._searchResults = [];

this.element.id ="search-results-pane-file-based";

this._treeOutlineElement = document.createElement("ol");
this._treeOutlineElement.className = "search-results-outline-disclosure";
this.element.appendChild(this._treeOutlineElement);
this._treeOutline = new TreeOutline(this._treeOutlineElement);

this._matchesExpandedCount = 0;
}

WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount = 20;
WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce = 20;

WebInspector.FileBasedSearchResultsPane.prototype = {

_createAnchor: function(uiSourceCode, lineNumber, columnNumber)
{
var anchor = document.createElement("a");
anchor.preferredPanel = "scripts";
anchor.href = sanitizeHref(uiSourceCode.url);
anchor.uiSourceCode = uiSourceCode;
anchor.lineNumber = lineNumber;
return anchor;
},


addSearchResult: function(searchResult)
{
this._searchResults.push(searchResult);
var uiSourceCode = searchResult.uiSourceCode;
var searchMatches = searchResult.searchMatches;

var fileTreeElement = this._addFileTreeElement(uiSourceCode.url, searchMatches.length, this._searchResults.length - 1);
},


_fileTreeElementExpanded: function(searchResult, fileTreeElement)
{
if (fileTreeElement._initialized)
return;

var toIndex = Math.min(searchResult.searchMatches.length, WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce);
if (toIndex < searchResult.searchMatches.length) {
this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex - 1);
this._appendShowMoreMatchesElement(fileTreeElement, searchResult, toIndex - 1);
} else
this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex);

fileTreeElement._initialized = true;
},


_appendSearchMatches: function(fileTreeElement, searchResult, fromIndex, toIndex)
{
var uiSourceCode = searchResult.uiSourceCode;
var searchMatches = searchResult.searchMatches;

var regex = createSearchRegex(this._searchConfig.query, !this._searchConfig.ignoreCase, this._searchConfig.isRegex);
for (var i = fromIndex; i < toIndex; ++i) {
var lineNumber = searchMatches[i].lineNumber;
var lineContent = searchMatches[i].lineContent;
var matchRanges = this._regexMatchRanges(lineContent, regex);

var anchor = this._createAnchor(uiSourceCode, lineNumber, matchRanges[0].offset);

var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4);
var lineNumberSpan = document.createElement("span");
lineNumberSpan.addStyleClass("webkit-line-number");
lineNumberSpan.addStyleClass("search-match-line-number");
lineNumberSpan.textContent = numberString;
anchor.appendChild(lineNumberSpan);

var contentSpan = this._createContentSpan(lineContent, matchRanges);
anchor.appendChild(contentSpan);

var searchMatchElement = new TreeElement("", null, false);
fileTreeElement.appendChild(searchMatchElement);
searchMatchElement.listItemElement.className = "search-match source-code";
searchMatchElement.listItemElement.appendChild(anchor);
}
},


_appendShowMoreMatchesElement: function(fileTreeElement, searchResult, startMatchIndex)
{
var matchesLeftCount = searchResult.searchMatches.length - startMatchIndex;
var showMoreMatchesText = WebInspector.UIString("Show all matches (%d more).", matchesLeftCount);
var showMoreMatchesElement = new TreeElement(showMoreMatchesText, null, false);
fileTreeElement.appendChild(showMoreMatchesElement);
showMoreMatchesElement.listItemElement.addStyleClass("show-more-matches");
showMoreMatchesElement.onselect = this._showMoreMatchesElementSelected.bind(this, searchResult, startMatchIndex, showMoreMatchesElement);
},


_showMoreMatchesElementSelected: function(searchResult, startMatchIndex, showMoreMatchesElement)
{
var fileTreeElement = showMoreMatchesElement.parent;
fileTreeElement.removeChild(showMoreMatchesElement);
this._appendSearchMatches(fileTreeElement, searchResult, startMatchIndex, searchResult.searchMatches.length);
},


_addFileTreeElement: function(fileName, searchMatchesCount, searchResultIndex)
{
var fileTreeElement = new TreeElement("", null, true);
fileTreeElement.toggleOnClick = true;
fileTreeElement.selectable = false;

this._treeOutline.appendChild(fileTreeElement);
fileTreeElement.listItemElement.addStyleClass("search-result");

var fileNameSpan = document.createElement("span");
fileNameSpan.className = "search-result-file-name";
fileNameSpan.textContent = fileName;
fileTreeElement.listItemElement.appendChild(fileNameSpan);

var matchesCountSpan = document.createElement("span");
matchesCountSpan.className = "search-result-matches-count";
if (searchMatchesCount === 1)
matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount);
else
matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount);

fileTreeElement.listItemElement.appendChild(matchesCountSpan);

var searchResult = this._searchResults[searchResultIndex];
fileTreeElement.onexpand = this._fileTreeElementExpanded.bind(this, searchResult, fileTreeElement);


if (this._matchesExpandedCount < WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount)
fileTreeElement.expand();
this._matchesExpandedCount += searchResult.searchMatches.length;

return fileTreeElement; 
},


_regexMatchRanges: function(lineContent, regex)
{
regex.lastIndex = 0;
var match;
var offset = 0;
var matchRanges = [];
while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent)))
matchRanges.push(new WebInspector.SearchResult(match.index, match[0].length));

return matchRanges;
},


_createContentSpan: function(lineContent, matchRanges)
{
var contentSpan = document.createElement("span");
contentSpan.className = "search-match-content";
contentSpan.textContent = lineContent;
WebInspector.highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match");
return contentSpan;
}
}

WebInspector.FileBasedSearchResultsPane.prototype.__proto__ = WebInspector.SearchResultsPane.prototype;


WebInspector.FileBasedSearchResultsPane.SearchResult = function(uiSourceCode, searchMatches) {
this.uiSourceCode = uiSourceCode;
this.searchMatches = searchMatches;
}


WebInspector.advancedSearchController = null;






WebInspector.TimelineGrid = function()
{
this.element = document.createElement("div");

this._itemsGraphsElement = document.createElement("div");
this._itemsGraphsElement.id = "resources-graphs";
this.element.appendChild(this._itemsGraphsElement);

this._dividersElement = document.createElement("div");
this._dividersElement.className = "resources-dividers";
this.element.appendChild(this._dividersElement);

this._gridHeaderElement = document.createElement("div"); 

this._eventDividersElement = document.createElement("div");
this._eventDividersElement.className = "resources-event-dividers";
this._gridHeaderElement.appendChild(this._eventDividersElement);

this._dividersLabelBarElement = document.createElement("div");
this._dividersLabelBarElement.className = "resources-dividers-label-bar";
this._gridHeaderElement.appendChild(this._dividersLabelBarElement);

this.element.appendChild(this._gridHeaderElement);
}

WebInspector.TimelineGrid.prototype = {
get itemsGraphsElement()
{
return this._itemsGraphsElement;
},

get dividersElement()
{
return this._dividersElement;
},

get dividersLabelBarElement()
{
return this._dividersLabelBarElement;
},

get gridHeaderElement()
{
return this._gridHeaderElement;
},

removeDividers: function()
{
this._dividersElement.removeChildren();
this._dividersLabelBarElement.removeChildren();
},

updateDividers: function(calculator)
{
var dividersElementClientWidth = this._dividersElement.clientWidth;
var dividerCount = Math.round(dividersElementClientWidth / 64);
var slice = calculator.boundarySpan() / dividerCount;

this._currentDividerSlice = slice;


var divider = this._dividersElement.firstChild;
var dividerLabelBar = this._dividersLabelBarElement.firstChild;

var paddingLeft = calculator.paddingLeft;
for (var i = paddingLeft ? 0 : 1; i <= dividerCount; ++i) {
if (!divider) {
divider = document.createElement("div");
divider.className = "resources-divider";
this._dividersElement.appendChild(divider);

dividerLabelBar = document.createElement("div");
dividerLabelBar.className = "resources-divider";
var label = document.createElement("div");
label.className = "resources-divider-label";
dividerLabelBar._labelElement = label;
dividerLabelBar.appendChild(label);
this._dividersLabelBarElement.appendChild(dividerLabelBar);
}

if (i === (paddingLeft ? 0 : 1)) {
divider.addStyleClass("first");
dividerLabelBar.addStyleClass("first");
} else {
divider.removeStyleClass("first");
dividerLabelBar.removeStyleClass("first");
}

if (i === dividerCount) {
divider.addStyleClass("last");
dividerLabelBar.addStyleClass("last");
} else {
divider.removeStyleClass("last");
dividerLabelBar.removeStyleClass("last");
}

var left;
if (!slice) {
left = dividersElementClientWidth / dividerCount * i + paddingLeft;
dividerLabelBar._labelElement.textContent = "";
} else {
left = calculator.computePosition(calculator.minimumBoundary() + slice * i);
dividerLabelBar._labelElement.textContent = calculator.formatTime(slice * i);
}
var percentLeft = 100 * left / dividersElementClientWidth;
this._setDividerAndBarLeft(divider, dividerLabelBar, percentLeft);

divider = divider.nextSibling;
dividerLabelBar = dividerLabelBar.nextSibling;
}


while (divider) {
var nextDivider = divider.nextSibling;
this._dividersElement.removeChild(divider);
divider = nextDivider;
}
while (dividerLabelBar) {
var nextDivider = dividerLabelBar.nextSibling;
this._dividersLabelBarElement.removeChild(dividerLabelBar);
dividerLabelBar = nextDivider;
}
return true;
},

_setDividerAndBarLeft: function(divider, dividerLabelBar, percentLeft)
{
var percentStyleLeft = parseFloat(divider.style.left);
if (!isNaN(percentStyleLeft) && Math.abs(percentStyleLeft - percentLeft) < 0.1)
return;
divider.style.left = percentLeft + "%";
dividerLabelBar.style.left = percentLeft + "%";
},

addEventDivider: function(divider)
{
this._eventDividersElement.appendChild(divider);
},

addEventDividers: function(dividers)
{
this._gridHeaderElement.removeChild(this._eventDividersElement);
for (var i = 0; i < dividers.length; ++i) {
if (dividers[i])
this._eventDividersElement.appendChild(dividers[i]);
}
this._gridHeaderElement.appendChild(this._eventDividersElement);
},

removeEventDividers: function()
{
this._eventDividersElement.removeChildren();
},

hideEventDividers: function()
{
this._eventDividersElement.addStyleClass("hidden");
},

showEventDividers: function()
{
this._eventDividersElement.removeStyleClass("hidden");
},

setScrollAndDividerTop: function(scrollTop, dividersTop)
{
this._dividersElement.style.top = scrollTop + "px";
}
}


WebInspector.TimelineGrid.Calculator = function() { }

WebInspector.TimelineGrid.Calculator.prototype = {

computePosition: function(time) { },


formatTime: function(time) { },


minimumBoundary: function() { },


maximumBoundary: function() { },


boundarySpan: function() { }
}






WebInspector.ContentProvider = function() { }

WebInspector.ContentProvider.prototype = {

contentURL: function() { },


contentType: function() { },


requestContent: function(callback) { },


searchInContent: function(query, caseSensitive, isRegex, callback) { }
}


WebInspector.ContentProvider.SearchMatch = function(lineNumber, lineContent) {
this.lineNumber = lineNumber;
this.lineContent = lineContent;
}






WebInspector.Resource = function(request, url, documentURL, frameId, loaderId, type, mimeType, isHidden)
{
this._request = request;
this.url = url;
this._documentURL = documentURL;
this._frameId = frameId;
this._loaderId = loaderId;
this._type = type || WebInspector.resourceTypes.Other;
this._mimeType = mimeType;
this._isHidden = isHidden;

this._content;
this._contentEncoded;
this._pendingContentCallbacks = [];
if (this._request && !this._request.finished)
this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
}

WebInspector.Resource.Events = {
MessageAdded: "message-added",
MessagesCleared: "messages-cleared",
}

WebInspector.Resource.prototype = {

get request()
{
return this._request;
},


get url()
{
return this._url;
},

set url(x)
{
this._url = x;
this._parsedURL = new WebInspector.ParsedURL(x);
},

get parsedURL()
{
return this._parsedURL;
},


get documentURL()
{
return this._documentURL;
},


get frameId()
{
return this._frameId;
},


get loaderId()
{
return this._loaderId;
},


get displayName()
{
return this._parsedURL.displayName;
},


get type()
{
return this._request ? this._request.type : this._type;
},


get mimeType()
{
return this._request ? this._request.mimeType : this._mimeType;
},


get messages()
{
return this._messages || [];
},


addMessage: function(msg)
{
if (!msg.isErrorOrWarning() || !msg.message)
return;

if (!this._messages)
this._messages = [];
this._messages.push(msg);
this.dispatchEventToListeners(WebInspector.Resource.Events.MessageAdded, msg);
},


get errors()
{
return this._errors || 0;
},

set errors(x)
{
this._errors = x;
},


get warnings()
{
return this._warnings || 0;
},

set warnings(x)
{
this._warnings = x;
},

clearErrorsAndWarnings: function()
{
this._messages = [];
this._warnings = 0;
this._errors = 0;
this.dispatchEventToListeners(WebInspector.Resource.Events.MessagesCleared);
},


get content()
{
return this._content;
},


get contentEncoded()
{
return this._contentEncoded;
},


contentURL: function()
{
return this._url;
},


contentType: function()
{
return this.type;
},


requestContent: function(callback)
{
if (typeof this._content !== "undefined") {
callback(this._content, !!this._contentEncoded, this.canonicalMimeType());
return;
}

this._pendingContentCallbacks.push(callback);
if (!this._request || this._request.finished)
this._innerRequestContent();
},

canonicalMimeType: function()
{
return this.type.canonicalMimeType() || this.mimeType;
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{

function callbackWrapper(error, searchMatches)
{
callback(searchMatches || []);
}

if (this.frameId)
PageAgent.searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper);
else
callback([]);
},


populateImageSource: function(image)
{
function onResourceContent()
{
image.src = this._contentURL();
}

this.requestContent(onResourceContent.bind(this));
},


_contentURL: function()
{
const maxDataUrlSize = 1024 * 1024;

if (this._content == null || this._content.length > maxDataUrlSize)
return this.url;

return "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content;
},


_requestFinished: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
},


_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;


function contentLoaded(content, contentEncoded)
{
this._content = content;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content, this._contentEncoded, this.canonicalMimeType());
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}


function resourceContentLoaded(error, content, contentEncoded)
{
if (error)
console.error("Resource content request failed: " + error);
contentLoaded.call(this, error ? null : content, contentEncoded);
}

if (this.request) {

function requestContentLoaded(content, contentEncoded, mimeType)
{
contentLoaded.call(this, content, contentEncoded);
}

this.request.requestContent(requestContentLoaded.bind(this));
return;
}
PageAgent.getResourceContent(this.frameId, this.url, resourceContentLoaded.bind(this));
},


isHidden: function()
{
return !!this._isHidden;
}
}

WebInspector.Resource.prototype.__proto__ = WebInspector.Object.prototype;







WebInspector.NetworkRequest = function(requestId, url, documentURL, frameId, loaderId)
{
this._requestId = requestId;
this.url = url;
this._documentURL = documentURL;
this._frameId = frameId;
this._loaderId = loaderId;
this._startTime = -1;
this._endTime = -1;

this.statusCode = 0;
this.statusText = "";
this.requestMethod = "";
this.requestTime = 0;
this.receiveHeadersEnd = 0;

this._type = WebInspector.resourceTypes.Other;
this._content = undefined;
this._contentEncoded = false;
this._pendingContentCallbacks = [];
this._frames = [];
}

WebInspector.NetworkRequest.Events = {
FinishedLoading: "FinishedLoading",
TimingChanged: "TimingChanged",
RequestHeadersChanged: "RequestHeadersChanged",
ResponseHeadersChanged: "ResponseHeadersChanged",
}

WebInspector.NetworkRequest.prototype = {

get requestId()
{
return this._requestId;
},

set requestId(requestId)
{
this._requestId = requestId;
},


get url()
{
return this._url;
},

set url(x)
{
if (this._url === x)
return;

this._url = x;
this._parsedURL = new WebInspector.ParsedURL(x);
delete this._parsedQueryParameters;
},


get documentURL()
{
return this._documentURL;
},

get parsedURL()
{
return this._parsedURL;
},


get frameId()
{
return this._frameId;
},


get loaderId()
{
return this._loaderId;
},


get startTime()
{
return this._startTime || -1;
},

set startTime(x)
{
this._startTime = x;
},


get responseReceivedTime()
{
return this._responseReceivedTime || -1;
},

set responseReceivedTime(x)
{
this._responseReceivedTime = x;
},


get endTime()
{
return this._endTime || -1;
},

set endTime(x)
{
if (this.timing && this.timing.requestTime) {

this._endTime = Math.max(x, this.responseReceivedTime);
} else {

this._endTime = x;
if (this._responseReceivedTime > x)
this._responseReceivedTime = x;
}
},


get duration()
{
if (this._endTime === -1 || this._startTime === -1)
return -1;
return this._endTime - this._startTime;
},


get latency()
{
if (this._responseReceivedTime === -1 || this._startTime === -1)
return -1;
return this._responseReceivedTime - this._startTime;
},


get receiveDuration()
{
if (this._endTime === -1 || this._responseReceivedTime === -1)
return -1;
return this._endTime - this._responseReceivedTime;
},


get resourceSize()
{
return this._resourceSize || 0;
},

set resourceSize(x)
{
this._resourceSize = x;
},


get transferSize()
{
if (this.cached)
return 0;
if (this.statusCode === 304) 
return this.responseHeadersSize;
if (this._transferSize !== undefined)
return this._transferSize;










var bodySize = Number(this.responseHeaderValue("Content-Length") || this.resourceSize);
return this.responseHeadersSize + bodySize;
},


increaseTransferSize: function(x)
{
this._transferSize = (this._transferSize || 0) + x;
},


get finished()
{
return this._finished;
},

set finished(x)
{
if (this._finished === x)
return;

this._finished = x;

if (x) {
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading, this);
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
}
},


get failed()
{
return this._failed;
},

set failed(x)
{
this._failed = x;
},


get canceled()
{
return this._canceled;
},

set canceled(x)
{
this._canceled = x;
},


get cached()
{
return this._cached;
},

set cached(x)
{
this._cached = x;
if (x)
delete this._timing;
},


get timing()
{
return this._timing;
},

set timing(x)
{
if (x && !this._cached) {


this._startTime = x.requestTime;
this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0;

this._timing = x;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this);
}
},


get mimeType()
{
return this._mimeType;
},

set mimeType(x)
{
this._mimeType = x;
},


get displayName()
{
return this._parsedURL.displayName;
},


get folder()
{
var path = this._parsedURL.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1)
path = path.substring(0, indexOfQuery);
var lastSlashIndex = path.lastIndexOf("/");
return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : "";
},


get type()
{
return this._type;
},

set type(x)
{
this._type = x;
},


get redirectSource()
{
if (this.redirects && this.redirects.length > 0)
return this.redirects[this.redirects.length - 1];
return this._redirectSource;
},

set redirectSource(x)
{
this._redirectSource = x;
},


get requestHeaders()
{
return this._requestHeaders || [];
},

set requestHeaders(x)
{
this._requestHeaders = x;
delete this._sortedRequestHeaders;
delete this._requestCookies;

this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
},


get requestHeadersText()
{
if (this._requestHeadersText === undefined) {
this._requestHeadersText = this.requestMethod + " " + this.url + " HTTP/1.1\r\n";
for (var i = 0; i < this.requestHeaders; ++i)
this._requestHeadersText += this.requestHeaders[i].name + ": " + this.requestHeaders[i].value + "\r\n";
}
return this._requestHeadersText;
},

set requestHeadersText(x)
{
this._requestHeadersText = x;

this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
},


get requestHeadersSize()
{
return this.requestHeadersText.length;
},


get sortedRequestHeaders()
{
if (this._sortedRequestHeaders !== undefined)
return this._sortedRequestHeaders;

this._sortedRequestHeaders = [];
this._sortedRequestHeaders = this.requestHeaders.slice();
this._sortedRequestHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) });
return this._sortedRequestHeaders;
},


requestHeaderValue: function(headerName)
{
return this._headerValue(this.requestHeaders, headerName);
},


get requestCookies()
{
if (!this._requestCookies)
this._requestCookies = WebInspector.CookieParser.parseCookie(this.requestHeaderValue("Cookie"));
return this._requestCookies;
},


get requestFormData()
{
return this._requestFormData;
},

set requestFormData(x)
{
this._requestFormData = x;
delete this._parsedFormParameters;
},


get requestHttpVersion()
{
var firstLine = this.requestHeadersText.split(/\r\n/)[0];
var match = firstLine.match(/(HTTP\/\d+\.\d+)$/);
return match ? match[1] : undefined;
},


get responseHeaders()
{
return this._responseHeaders || [];
},

set responseHeaders(x)
{
this._responseHeaders = x;
delete this._sortedResponseHeaders;
delete this._responseCookies;

this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
},


get responseHeadersText()
{
if (this._responseHeadersText === undefined) {
this._responseHeadersText = "HTTP/1.1 " + this.statusCode + " " + this.statusText + "\r\n";
for (var i = 0; i < this.requestHeaders; ++i)
this._responseHeadersText += this.responseHeaders[i].name + ": " + this.responseHeaders[i].value + "\r\n";
}
return this._responseHeadersText;
},

set responseHeadersText(x)
{
this._responseHeadersText = x;

this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
},


get responseHeadersSize()
{
return this.responseHeadersText.length;
},


get sortedResponseHeaders()
{
if (this._sortedResponseHeaders !== undefined)
return this._sortedResponseHeaders;

this._sortedResponseHeaders = [];
this._sortedResponseHeaders = this.responseHeaders.slice();
this._sortedResponseHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) });
return this._sortedResponseHeaders;
},


responseHeaderValue: function(headerName)
{
return this._headerValue(this.responseHeaders, headerName);
},


get responseCookies()
{
if (!this._responseCookies)
this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.responseHeaderValue("Set-Cookie"));
return this._responseCookies;
},


get queryParameters()
{
if (this._parsedQueryParameters)
return this._parsedQueryParameters;
var queryString = this.url.split("?", 2)[1];
if (!queryString)
return null;
queryString = queryString.split("#", 2)[0];
this._parsedQueryParameters = this._parseParameters(queryString);
return this._parsedQueryParameters;
},


get formParameters()
{
if (this._parsedFormParameters)
return this._parsedFormParameters;
if (!this.requestFormData)
return null;
var requestContentType = this.requestContentType();
if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
return null;
this._parsedFormParameters = this._parseParameters(this.requestFormData);
return this._parsedFormParameters;
},


get responseHttpVersion()
{
var match = this.responseHeadersText.match(/^(HTTP\/\d+\.\d+)/);
return match ? match[1] : undefined;
},


_parseParameters: function(queryString)
{
function parseNameValue(pair)
{
var parameter = {};
var splitPair = pair.split("=", 2);

parameter.name = splitPair[0];
if (splitPair.length === 1)
parameter.value = "";
else
parameter.value = splitPair[1];
return parameter;
}
return queryString.split("&").map(parseNameValue);
},


_headerValue: function(headers, headerName)
{
headerName = headerName.toLowerCase();

var values = [];
for (var i = 0; i < headers.length; ++i) {
if (headers[i].name.toLowerCase() === headerName)
values.push(headers[i].value);
}

if (headerName === "set-cookie")
return values.join("\n");
return values.join(", ");
},


get content()
{
return this._content;
},


get contentEncoded()
{
return this._contentEncoded;
},


contentURL: function()
{
return this._url;
},


contentType: function()
{
return this._type;
},


requestContent: function(callback)
{



if (this.type === WebInspector.resourceTypes.WebSocket) {
callback(null, false, this._mimeType);
return;
}
if (typeof this._content !== "undefined") {
callback(this.content || null, this._contentEncoded, this._mimeType);
return;
}
this._pendingContentCallbacks.push(callback);
if (this.finished)
this._innerRequestContent();
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
},


isHttpFamily: function()
{
return !!this.url.match(/^https?:/i);
},


requestContentType: function()
{
return this.requestHeaderValue("Content-Type");
},


isPingRequest: function()
{
return "text/ping" === this.requestContentType();
},


hasErrorStatusCode: function()
{
return this.statusCode >= 400;
},


populateImageSource: function(image)
{

function onResourceContent(content, contentEncoded, mimeType)
{
const maxDataUrlSize = 1024 * 1024;

if (this._content == null || this._content.length > maxDataUrlSize)
return this.url;
image.src = "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content;
}

this.requestContent(onResourceContent.bind(this));
},

_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;


function onResourceContent(error, content, contentEncoded)
{
this._content = error ? null : content;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content, this._contentEncoded, this._mimeType);
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}
NetworkAgent.getResponseBody(this._requestId, onResourceContent.bind(this));
},


frames: function()
{
return this._frames;
},


frame: function(position)
{
return this._frames[position];
},


addFrameError: function(errorMessage, time)
{
var errorObject = {};
errorObject.errorMessage = errorMessage;
errorObject.time = time;
this._pushFrame(errorObject);
},


addFrame: function(response, time, sent)
{
response.time = time;
if (sent)
response.sent = true;
this._pushFrame(response);
},

_pushFrame: function(object)
{
if (this._frames.length >= 100) {
this._frames.splice(0, 10);
}
this._frames.push(object);
}
}

WebInspector.NetworkRequest.prototype.__proto__ = WebInspector.Object.prototype;






WebInspector.CSSStyleModel = function()
{
this._pendingCommandsMajorState = [];
this._sourceMappings = {};
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoRequested, this._undoRedoRequested, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoCompleted, this._undoRedoCompleted, this);
this._resourceBinding = new WebInspector.CSSStyleModelResourceBinding(this);
this._namedFlowCollections = {};
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._resetNamedFlowCollections, this);
InspectorBackend.registerCSSDispatcher(new WebInspector.CSSDispatcher(this));
CSSAgent.enable();
}


WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray)
{
var result = [];
for (var i = 0; i < ruleArray.length; ++i)
result.push(WebInspector.CSSRule.parsePayload(ruleArray[i]));
return result;
}

WebInspector.CSSStyleModel.Events = {
StyleSheetChanged: "StyleSheetChanged",
MediaQueryResultChanged: "MediaQueryResultChanged",
NamedFlowCreated: "NamedFlowCreated",
NamedFlowRemoved: "NamedFlowRemoved",
RegionLayoutUpdated: "RegionLayoutUpdated"
}

WebInspector.CSSStyleModel.prototype = {

getMatchedStylesAsync: function(nodeId, needPseudo, needInherited, userCallback)
{

function callback(userCallback, error, matchedPayload, pseudoPayload, inheritedPayload)
{
if (error) {
if (userCallback)
userCallback(null);
return;
}

var result = {};
if (matchedPayload)
result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(matchedPayload);

if (pseudoPayload) {
result.pseudoElements = [];
for (var i = 0; i < pseudoPayload.length; ++i) {
var entryPayload = pseudoPayload[i];
result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.rules) });
}
}

if (inheritedPayload) {
result.inherited = [];
for (var i = 0; i < inheritedPayload.length; ++i) {
var entryPayload = inheritedPayload[i];
var entry = {};
if (entryPayload.inlineStyle)
entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(entryPayload.inlineStyle);
if (entryPayload.matchedCSSRules)
entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.matchedCSSRules);
result.inherited.push(entry);
}
}

if (userCallback)
userCallback(result);
}

CSSAgent.getMatchedStylesForNode(nodeId, needPseudo, needInherited, callback.bind(null, userCallback));
},


getComputedStyleAsync: function(nodeId, userCallback)
{

function callback(userCallback, error, computedPayload)
{
if (error || !computedPayload)
userCallback(null);
else
userCallback(WebInspector.CSSStyleDeclaration.parseComputedStylePayload(computedPayload));
}

CSSAgent.getComputedStyleForNode(nodeId, callback.bind(null, userCallback));
},


getInlineStylesAsync: function(nodeId, userCallback)
{

function callback(userCallback, error, inlinePayload, attributesStylePayload)
{
if (error || !inlinePayload)
userCallback(null, null);
else
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(inlinePayload), attributesStylePayload ? WebInspector.CSSStyleDeclaration.parsePayload(attributesStylePayload) : null);
}

CSSAgent.getInlineStylesForNode(nodeId, callback.bind(null, userCallback));
},


forcePseudoState: function(nodeId, forcedPseudoClasses, userCallback)
{
CSSAgent.forcePseudoState(nodeId, forcedPseudoClasses || [], userCallback);
},


getNamedFlowCollectionAsync: function(documentNodeId, userCallback)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];
if (namedFlowCollection) {
userCallback(namedFlowCollection);
return;
}


function callback(userCallback, error, namedFlowPayload)
{
if (error || !namedFlowPayload)
userCallback(null);
else {
var namedFlowCollection = new WebInspector.NamedFlowCollection(namedFlowPayload);
this._namedFlowCollections[documentNodeId] = namedFlowCollection;
userCallback(namedFlowCollection);
}
}

CSSAgent.getNamedFlowCollection(documentNodeId, callback.bind(this, userCallback));
},


getFlowByNameAsync: function(documentNodeId, flowName, userCallback)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];
if (namedFlowCollection) {
userCallback(namedFlowCollection.flowByName(flowName));
return;
}


function callback(userCallback, namedFlowCollection)
{
if (!namedFlowCollection)
userCallback(null);
else
userCallback(namedFlowCollection.flowByName(flowName));
}

this.getNamedFlowCollectionAsync(documentNodeId, callback.bind(this, userCallback));
},


setRuleSelector: function(ruleId, nodeId, newSelector, successCallback, failureCallback)
{

function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
if (!selectedNodeIds)
return;
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
}


function callback(nodeId, successCallback, failureCallback, newSelector, error, rulePayload)
{
this._pendingCommandsMajorState.pop();
if (error)
failureCallback();
else {
WebInspector.domAgent.markUndoableState();
var ownerDocumentId = this._ownerDocumentId(nodeId);
if (ownerDocumentId)
WebInspector.domAgent.querySelectorAll(ownerDocumentId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
else
failureCallback();
}
}

this._pendingCommandsMajorState.push(true);
CSSAgent.setRuleSelector(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback, newSelector));
},


addRule: function(nodeId, selector, successCallback, failureCallback)
{

function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
if (!selectedNodeIds)
return;

var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
}


function callback(successCallback, failureCallback, selector, error, rulePayload)
{
this._pendingCommandsMajorState.pop();
if (error) {

failureCallback();
} else {
WebInspector.domAgent.markUndoableState();
var ownerDocumentId = this._ownerDocumentId(nodeId);
if (ownerDocumentId)
WebInspector.domAgent.querySelectorAll(ownerDocumentId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
else
failureCallback();
}
}

this._pendingCommandsMajorState.push(true);
CSSAgent.addRule(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector));
},

mediaQueryResultChanged: function()
{
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged);
},


_ownerDocumentId: function(nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return null;
return node.ownerDocument ? node.ownerDocument.id : null;
},


_fireStyleSheetChanged: function(styleSheetId)
{
if (!this._pendingCommandsMajorState.length)
return;

var majorChange = this._pendingCommandsMajorState[this._pendingCommandsMajorState.length - 1];

if (!majorChange || !styleSheetId || !this.hasEventListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged))
return;

this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, majorChange: majorChange });
},


_namedFlowCreated: function(namedFlowPayload)
{
var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];

if (!namedFlowCollection)
return;

namedFlowCollection._appendNamedFlow(namedFlow);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowCreated, namedFlow);
},


_namedFlowRemoved: function(documentNodeId, flowName)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];

if (!namedFlowCollection)
return;

namedFlowCollection._removeNamedFlow(flowName);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, { documentNodeId: documentNodeId, flowName: flowName });
},


_regionLayoutUpdated: function(namedFlowPayload)
{
var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];

if (!namedFlowCollection)
return;

namedFlowCollection._appendNamedFlow(namedFlow);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, namedFlow);
},


setStyleSheetText: function(styleSheetId, newText, majorChange, userCallback)
{
function callback(error)
{
this._pendingCommandsMajorState.pop();
if (!error && majorChange)
WebInspector.domAgent.markUndoableState();

if (!error && userCallback)
userCallback(error);
}
this._pendingCommandsMajorState.push(majorChange);
CSSAgent.setStyleSheetText(styleSheetId, newText, callback.bind(this));
},

_undoRedoRequested: function()
{
this._pendingCommandsMajorState.push(true);
},

_undoRedoCompleted: function()
{
this._pendingCommandsMajorState.pop();
},


getViaInspectorResourceForRule: function(rule, callback)
{
if (!rule.id) {
callback(null);
return;
}
this._resourceBinding._requestViaInspectorResource(rule.id.styleSheetId, callback);
},


resourceBinding: function()
{
return this._resourceBinding;
},


setSourceMapping: function(url, sourceMapping)
{
this._sourceMappings[url] = sourceMapping;
},

resetSourceMappings: function()
{
this._sourceMappings = {};
},

_resetNamedFlowCollections: function()
{
this._namedFlowCollections = {};
},


_rawLocationToUILocation: function(rawLocation)
{
var sourceMapping = this._sourceMappings[rawLocation.url];
return sourceMapping ? sourceMapping.rawLocationToUILocation(rawLocation) : null;
}
}

WebInspector.CSSStyleModel.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.CSSLocation = function(url, lineNumber)
{
this.url = url;
this.lineNumber = lineNumber;
}


WebInspector.CSSStyleDeclaration = function(payload)
{
this.id = payload.styleId;
this.width = payload.width;
this.height = payload.height;
this.range = payload.range;
this._shorthandValues = WebInspector.CSSStyleDeclaration.buildShorthandValueMap(payload.shorthandEntries);
this._livePropertyMap = {}; 
this._allProperties = []; 
this.__disabledProperties = {}; 
var payloadPropertyCount = payload.cssProperties.length;

var propertyIndex = 0;
for (var i = 0; i < payloadPropertyCount; ++i) {
var property = WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]);
this._allProperties.push(property);
if (property.disabled)
this.__disabledProperties[i] = property;
if (!property.active && !property.styleBased)
continue;
var name = property.name;
this[propertyIndex] = name;
this._livePropertyMap[name] = property;
++propertyIndex;
}
this.length = propertyIndex;
if ("cssText" in payload)
this.cssText = payload.cssText;
}


WebInspector.CSSStyleDeclaration.buildShorthandValueMap = function(shorthandEntries)
{
var result = {};
for (var i = 0; i < shorthandEntries.length; ++i)
result[shorthandEntries[i].name] = shorthandEntries[i].value;
return result;
}


WebInspector.CSSStyleDeclaration.parsePayload = function(payload)
{
return new WebInspector.CSSStyleDeclaration(payload);
}


WebInspector.CSSStyleDeclaration.parseComputedStylePayload = function(payload)
{
var newPayload =   { cssProperties: [], shorthandEntries: [], width: "", height: "" };
if (payload)
newPayload.cssProperties = payload;

return new WebInspector.CSSStyleDeclaration(newPayload);
}

WebInspector.CSSStyleDeclaration.prototype = {
get allProperties()
{
return this._allProperties;
},


getLiveProperty: function(name)
{
return this._livePropertyMap[name];
},


getPropertyValue: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.value : "";
},


getPropertyPriority: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.priority : "";
},


isPropertyImplicit: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.implicit : "";
},


longhandProperties: function(name)
{
var longhands = WebInspector.CSSCompletions.cssPropertiesMetainfo.longhands(name);
var result = [];
for (var i = 0; longhands && i < longhands.length; ++i) {
var property = this._livePropertyMap[longhands[i]];
if (property)
result.push(property);
}
return result;
},


shorthandValue: function(shorthandProperty)
{
return this._shorthandValues[shorthandProperty];
},


propertyAt: function(index)
{
return (index < this.allProperties.length) ? this.allProperties[index] : null;
},


pastLastSourcePropertyIndex: function()
{
for (var i = this.allProperties.length - 1; i >= 0; --i) {
var property = this.allProperties[i];
if (property.active || property.disabled)
return i + 1;
}
return 0;
},


newBlankProperty: function(index)
{
index = (typeof index === "undefined") ? this.pastLastSourcePropertyIndex() : index;
return new WebInspector.CSSProperty(this, index, "", "", "", "active", true, false, "");
},


insertPropertyAt: function(index, name, value, userCallback)
{

function callback(userCallback, error, payload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (!userCallback)
return;

if (error) {
console.error(error);
userCallback(null);
} else {
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
}
}

if (!this.id)
throw "No style id";

WebInspector.cssModel._pendingCommandsMajorState.push(true);
CSSAgent.setPropertyText(this.id, index, name + ": " + value + ";", false, callback.bind(this, userCallback));
},


appendProperty: function(name, value, userCallback)
{
this.insertPropertyAt(this.allProperties.length, name, value, userCallback);
}
}


WebInspector.CSSRule = function(payload)
{
this.id = payload.ruleId;
this.selectorText = payload.selectorText;
this.sourceLine = payload.sourceLine;
this.sourceURL = payload.sourceURL;
if (payload.sourceURL)
this._rawLocation = new WebInspector.CSSLocation(payload.sourceURL, payload.sourceLine);
this.origin = payload.origin;
this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style);
this.style.parentRule = this;
this.selectorRange = payload.selectorRange;
if (payload.media)
this.media = WebInspector.CSSMedia.parseMediaArrayPayload(payload.media);
}


WebInspector.CSSRule.parsePayload = function(payload)
{
return new WebInspector.CSSRule(payload);
}

WebInspector.CSSRule.prototype = {
get isUserAgent()
{
return this.origin === "user-agent";
},

get isUser()
{
return this.origin === "user";
},

get isViaInspector()
{
return this.origin === "inspector";
},

get isRegular()
{
return this.origin === "regular";
},


uiLocation: function()
{
if (!this._rawLocation)
return null;
return WebInspector.cssModel._rawLocationToUILocation(this._rawLocation);
}
}


WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, status, parsedOk, implicit, text)
{
this.ownerStyle = ownerStyle;
this.index = index;
this.name = name;
this.value = value;
this.priority = priority;
this.status = status;
this.parsedOk = parsedOk;
this.implicit = implicit;
this.text = text;
}


WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload)
{





var result = new WebInspector.CSSProperty(
ownerStyle, index, payload.name, payload.value, payload.priority || "", payload.status || "style", ("parsedOk" in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text);
return result;
}

WebInspector.CSSProperty.prototype = {
get propertyText()
{
if (this.text !== undefined)
return this.text;

if (this.name === "")
return "";
return this.name + ": " + this.value + (this.priority ? " !" + this.priority : "") + ";";
},

get isLive()
{
return this.active || this.styleBased;
},

get active()
{
return this.status === "active";
},

get styleBased()
{
return this.status === "style";
},

get inactive()
{
return this.status === "inactive";
},

get disabled()
{
return this.status === "disabled";
},


setText: function(propertyText, majorChange, overwrite, userCallback)
{

function enabledCallback(style)
{
if (userCallback)
userCallback(style);
}


function callback(error, stylePayload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (!error) {
if (majorChange)
WebInspector.domAgent.markUndoableState();
this.text = propertyText;
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
var newProperty = style.allProperties[this.index];

if (newProperty && this.disabled && !propertyText.match(/^\s*$/)) {
newProperty.setDisabled(false, enabledCallback);
return;
}

if (userCallback)
userCallback(style);
} else {
if (userCallback)
userCallback(null);
}
}

if (!this.ownerStyle)
throw "No ownerStyle for property";

if (!this.ownerStyle.id)
throw "No owner style id";


WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
CSSAgent.setPropertyText(this.ownerStyle.id, this.index, propertyText, overwrite, callback.bind(this));
},


setValue: function(newValue, majorChange, overwrite, userCallback)
{
var text = this.name + ": " + newValue + (this.priority ? " !" + this.priority : "") + ";"
this.setText(text, majorChange, overwrite, userCallback);
},


setDisabled: function(disabled, userCallback)
{
if (!this.ownerStyle && userCallback)
userCallback(null);
if (disabled === this.disabled && userCallback)
userCallback(this.ownerStyle);


function callback(error, stylePayload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (error) {
if (userCallback)
userCallback(null);
return;
}
WebInspector.domAgent.markUndoableState();
if (userCallback) {
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
userCallback(style);
}
}

if (!this.ownerStyle.id)
throw "No owner style id";

WebInspector.cssModel._pendingCommandsMajorState.push(false);
CSSAgent.toggleProperty(this.ownerStyle.id, this.index, disabled, callback.bind(this));
}
}


WebInspector.CSSMedia = function(payload)
{
this.text = payload.text;
this.source = payload.source;
this.sourceURL = payload.sourceURL || "";
this.sourceLine = typeof payload.sourceLine === "undefined" || this.source === "linkedSheet" ? -1 : payload.sourceLine;
}

WebInspector.CSSMedia.Source = {
LINKED_SHEET: "linkedSheet",
INLINE_SHEET: "inlineSheet",
MEDIA_RULE: "mediaRule",
IMPORT_RULE: "importRule"
};


WebInspector.CSSMedia.parsePayload = function(payload)
{
return new WebInspector.CSSMedia(payload);
}


WebInspector.CSSMedia.parseMediaArrayPayload = function(payload)
{
var result = [];
for (var i = 0; i < payload.length; ++i)
result.push(WebInspector.CSSMedia.parsePayload(payload[i]));
return result;
}


WebInspector.CSSStyleSheet = function(payload)
{
this.id = payload.styleSheetId;
this.rules = [];
this.styles = {};
for (var i = 0; i < payload.rules.length; ++i) {
var rule = WebInspector.CSSRule.parsePayload(payload.rules[i]);
this.rules.push(rule);
if (rule.style)
this.styles[rule.style.id] = rule.style;
}
if ("text" in payload)
this._text = payload.text;
}


WebInspector.CSSStyleSheet.createForId = function(styleSheetId, userCallback)
{

function callback(error, styleSheetPayload)
{
if (error)
userCallback(null);
else
userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
}
CSSAgent.getStyleSheet(styleSheetId, callback.bind(this));
}

WebInspector.CSSStyleSheet.prototype = {

getText: function()
{
return this._text;
},


setText: function(newText, majorChange, userCallback)
{

function callback(error)
{
if (!error)
WebInspector.domAgent.markUndoableState();

WebInspector.cssModel._pendingCommandsMajorState.pop();
if (userCallback)
userCallback(error);
}

WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
CSSAgent.setStyleSheetText(this.id, newText, callback.bind(this));
}
}


WebInspector.CSSStyleModelResourceBinding = function(cssModel)
{
this._cssModel = cssModel;
this._frameAndURLToStyleSheetId = {};
this._styleSheetIdToHeader = {};
this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetChanged, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
}

WebInspector.CSSStyleModelResourceBinding.prototype = {

setStyleContent: function(styleSource, content, majorChange, userCallback)
{
var resource = styleSource.resource();
if (this._styleSheetIdForResource(resource)) {
this._innerSetContent(resource, content, majorChange, userCallback, null);
return;
}
this._loadStyleSheetHeaders(this._innerSetContent.bind(this, resource, content, majorChange, userCallback));
},


_styleSheetIdForResource: function(resource)
{
return this._frameAndURLToStyleSheetId[resource.frameId + ":" + resource.url];
},


_inspectedURLChanged: function(event)
{

this._frameAndURLToStyleSheetId = {};
this._styleSheetIdToHeader = {};
},


_innerSetContent: function(resource, content, majorChange, userCallback, error)
{
if (error) {
userCallback(error);
return;
}

var styleSheetId = this._styleSheetIdForResource(resource);
if (!styleSheetId) {
userCallback("No stylesheet found: " + resource.frameId + ":" + resource.url);
return;
}

this._isSettingContent = true;
function callbackWrapper(error)
{
userCallback(error);
delete this._isSettingContent;
}
this._cssModel.setStyleSheetText(styleSheetId, content, majorChange, callbackWrapper.bind(this));
},


_loadStyleSheetHeaders: function(callback)
{

function didGetAllStyleSheets(error, infos)
{
if (error) {
callback(error);
return;
}

for (var i = 0; i < infos.length; ++i) {
var info = infos[i];
if (info.origin === "inspector") {
this._getOrCreateInspectorResource(info);
continue;
}
this._frameAndURLToStyleSheetId[info.frameId + ":" + info.sourceURL] = info.styleSheetId;
this._styleSheetIdToHeader[info.styleSheetId] = info;
}
callback(null);
}
CSSAgent.getAllStyleSheets(didGetAllStyleSheets.bind(this));
},


_styleSheetChanged: function(event)
{
if (this._isSettingContent)
return;

if (!event.data.majorChange)
return;


function callback(error, content)
{
if (!error)
this._innerStyleSheetChanged(event.data.styleSheetId, content);
}
CSSAgent.getStyleSheetText(event.data.styleSheetId, callback.bind(this));
},


_innerStyleSheetChanged: function(styleSheetId, content)
{
function setContent()
{
var header = this._styleSheetIdToHeader[styleSheetId];
if (!header)
return;

var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
if (!frame)
return;

var styleSheetURL = header.origin === "inspector" ? this._viaInspectorResourceURL(header.sourceURL) : header.sourceURL;

var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(styleSheetURL);
if (!uiSourceCode)
return;

if (uiSourceCode.contentType() === WebInspector.resourceTypes.Stylesheet)
uiSourceCode.addRevision(content);
}

if (!this._styleSheetIdToHeader[styleSheetId]) {
this._loadStyleSheetHeaders(setContent.bind(this));
return;
}
setContent.call(this);
},


_requestViaInspectorResource: function(styleSheetId, callback)
{
var header = this._styleSheetIdToHeader[styleSheetId];
if (header) {
callback(this._getOrCreateInspectorResource(header));
return;
}

function headersLoaded()
{
var header = this._styleSheetIdToHeader[styleSheetId];
if (header)
callback(this._getOrCreateInspectorResource(header));
else
callback(null);
}
this._loadStyleSheetHeaders(headersLoaded.bind(this));
},


_getOrCreateInspectorResource: function(header)
{
var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
if (!frame)
return null;

var viaInspectorURL = this._viaInspectorResourceURL(header.sourceURL);    
var inspectorResource = frame.resourceForURL(viaInspectorURL);
if (inspectorResource)
return inspectorResource;

var resource = frame.resourceForURL(header.sourceURL);
if (!resource)
return null;

this._frameAndURLToStyleSheetId[header.frameId + ":" + viaInspectorURL] = header.styleSheetId;
this._styleSheetIdToHeader[header.styleSheetId] = header;
inspectorResource = new WebInspector.Resource(null, viaInspectorURL, resource.documentURL, resource.frameId, resource.loaderId, WebInspector.resourceTypes.Stylesheet, "text/css", true);

function overrideRequestContent(callback)
{
function callbackWrapper(error, content)
{
callback(error ? "" : content, false, "text/css");
}
CSSAgent.getStyleSheetText(header.styleSheetId, callbackWrapper);
}
inspectorResource.requestContent = overrideRequestContent;
frame.addResource(inspectorResource);
return inspectorResource;
},


_viaInspectorResourceURL: function(documentURL)
{
var parsedURL = new WebInspector.ParsedURL(documentURL);
var fakeURL = "inspector://" + parsedURL.host + parsedURL.folderPathComponents;
if (!fakeURL.endsWith("/"))
fakeURL += "/";
fakeURL += "inspector-stylesheet";
return fakeURL;
}
}


WebInspector.CSSDispatcher = function(cssModel)
{
this._cssModel = cssModel;
}

WebInspector.CSSDispatcher.prototype = {
mediaQueryResultChanged: function()
{
this._cssModel.mediaQueryResultChanged();
},


styleSheetChanged: function(styleSheetId)
{
this._cssModel._fireStyleSheetChanged(styleSheetId);
},


namedFlowCreated: function(namedFlowPayload)
{
this._cssModel._namedFlowCreated(namedFlowPayload);
},


namedFlowRemoved: function(documentNodeId, flowName)
{
this._cssModel._namedFlowRemoved(documentNodeId, flowName);
},


regionLayoutUpdated: function(namedFlowPayload)
{
this._cssModel._regionLayoutUpdated(namedFlowPayload);
}
}


WebInspector.NamedFlow = function(payload)
{
this.documentNodeId = payload.documentNodeId;
this.name = payload.name;
this.overset = payload.overset;
this.content = payload.content;
this.regions = payload.regions;
}


WebInspector.NamedFlow.parsePayload = function(payload)
{
return new WebInspector.NamedFlow(payload);
}


WebInspector.NamedFlowCollection = function(payload)
{

this.namedFlowMap = {};

for (var i = 0; i < payload.length; ++i) {
var namedFlow = WebInspector.NamedFlow.parsePayload(payload[i]);
this.namedFlowMap[namedFlow.name] = namedFlow;
}
}

WebInspector.NamedFlowCollection.prototype = {

_appendNamedFlow: function(namedFlow)
{
this.namedFlowMap[namedFlow.name] = namedFlow;
},


_removeNamedFlow: function(flowName)
{
delete this.namedFlowMap[flowName];
},


flowByName: function(flowName)
{
var namedFlow = this.namedFlowMap[flowName];

if (!namedFlow)
return null;
return namedFlow;
}
}

WebInspector.cssModel = null;






WebInspector.NetworkManager = function()
{
WebInspector.Object.call(this);
this._dispatcher = new WebInspector.NetworkDispatcher(this);
if (WebInspector.settings.cacheDisabled.get())
NetworkAgent.setCacheDisabled(true);

NetworkAgent.enable();

WebInspector.settings.cacheDisabled.addChangeListener(this._cacheDisabledSettingChanged, this);

if (WebInspector.settings.userAgent.get())
this._userAgentSettingChanged();
WebInspector.settings.userAgent.addChangeListener(this._userAgentSettingChanged, this);
}

WebInspector.NetworkManager.EventTypes = {
RequestStarted: "RequestStarted",
RequestUpdated: "RequestUpdated",
RequestFinished: "RequestFinished",
RequestUpdateDropped: "RequestUpdateDropped"
}

WebInspector.NetworkManager._MIMETypes = {
"text/html":                   {"document": true},
"text/xml":                    {"document": true},
"text/plain":                  {"document": true},
"application/xhtml+xml":       {"document": true},
"text/css":                    {"stylesheet": true},
"text/xsl":                    {"stylesheet": true},
"image/jpeg":                  {"image": true},
"image/png":                   {"image": true},
"image/gif":                   {"image": true},
"image/bmp":                   {"image": true},
"image/svg+xml":               {"image": true},
"image/vnd.microsoft.icon":    {"image": true},
"image/webp":                  {"image": true},
"image/x-icon":                {"image": true},
"image/x-xbitmap":             {"image": true},
"font/ttf":                    {"font": true},
"font/opentype":               {"font": true},
"font/woff":                   {"font": true},
"application/x-font-type1":    {"font": true},
"application/x-font-ttf":      {"font": true},
"application/x-font-woff":     {"font": true},
"application/x-truetype-font": {"font": true},
"text/javascript":             {"script": true},
"text/ecmascript":             {"script": true},
"application/javascript":      {"script": true},
"application/ecmascript":      {"script": true},
"application/x-javascript":    {"script": true},
"application/json":            {"script": true},
"text/javascript1.1":          {"script": true},
"text/javascript1.2":          {"script": true},
"text/javascript1.3":          {"script": true},
"text/jscript":                {"script": true},
"text/livescript":             {"script": true},
}

WebInspector.NetworkManager.prototype = {

inflightRequestForURL: function(url)
{
return this._dispatcher._inflightRequestsByURL[url];
},


_cacheDisabledSettingChanged: function(event)
{
var enabled =   event.data;
NetworkAgent.setCacheDisabled(enabled);
},

_userAgentSettingChanged: function()
{
NetworkAgent.setUserAgentOverride(WebInspector.settings.userAgent.get());
}
}

WebInspector.NetworkManager.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.NetworkDispatcher = function(manager)
{
this._manager = manager;
this._inflightRequestsById = {};
this._inflightRequestsByURL = {};
InspectorBackend.registerNetworkDispatcher(this);
}

WebInspector.NetworkDispatcher.prototype = {

_headersMapToHeadersArray: function(headersMap)
{
var result = [];
for (var name in headersMap) {
var values = headersMap[name].split("\n");
for (var i = 0; i < values.length; ++i)
result.push({ name: name, value: values[i] });
}
return result;
},


_updateNetworkRequestWithRequest: function(networkRequest, request)
{
networkRequest.requestMethod = request.method;
networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
networkRequest.requestFormData = request.postData;
},


_updateNetworkRequestWithResponse: function(networkRequest, response)
{
if (!response)
return;

if (response.url && networkRequest.url !== response.url)
networkRequest.url = response.url;
networkRequest.mimeType = response.mimeType;
networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
if (response.headersText)
networkRequest.responseHeadersText = response.headersText;
if (response.requestHeaders)
networkRequest.requestHeaders = this._headersMapToHeadersArray(response.requestHeaders);
if (response.requestHeadersText)
networkRequest.requestHeadersText = response.requestHeadersText;

networkRequest.connectionReused = response.connectionReused;
networkRequest.connectionId = response.connectionId;

if (response.fromDiskCache)
networkRequest.cached = true;
else
networkRequest.timing = response.timing;

if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
WebInspector.console.addMessage(WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.Network,
WebInspector.ConsoleMessage.MessageLevel.Warning,
WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.type.title(), networkRequest.mimeType, networkRequest.url),
WebInspector.ConsoleMessage.MessageType.Log,
"",
0,
1,
[],
null,
networkRequest.requestId));
}
},


_mimeTypeIsConsistentWithType: function(networkRequest)
{






if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)
return true;

if (typeof networkRequest.type === "undefined"
|| networkRequest.type === WebInspector.resourceTypes.Other
|| networkRequest.type === WebInspector.resourceTypes.XHR
|| networkRequest.type === WebInspector.resourceTypes.WebSocket)
return true;

if (!networkRequest.mimeType)
return true; 

if (networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
return networkRequest.type.name() in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];

return false;
},


_updateNetworkRequestWithCachedResource: function(networkRequest, cachedResource)
{
networkRequest.type = WebInspector.resourceTypes[cachedResource.type];
networkRequest.resourceSize = cachedResource.bodySize;
this._updateNetworkRequestWithResponse(networkRequest, cachedResource.response);
},


_isNull: function(response)
{
if (!response)
return true;
return !response.status && !response.mimeType && (!response.headers || !Object.keys(response.headers).length);
},


requestWillBeSent: function(requestId, frameId, loaderId, documentURL, request, time, initiator, redirectResponse)
{
var networkRequest = this._inflightRequestsById[requestId];
if (networkRequest) {

if (!redirectResponse)
return;
this.responseReceived(requestId, frameId, loaderId, time, "Other", redirectResponse);
networkRequest = this._appendRedirect(requestId, time, request.url);
} else
networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, request.url, documentURL, initiator);
networkRequest.hasNetworkData = true;
this._updateNetworkRequestWithRequest(networkRequest, request);
networkRequest.startTime = time;

this._startNetworkRequest(networkRequest);
},


requestServedFromCache: function(requestId)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.cached = true;
},


responseReceived: function(requestId, frameId, loaderId, time, resourceType, response)
{

if (this._isNull(response))
return;

var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest) {

var eventData = {};
eventData.url = response.url;
eventData.frameId = frameId;
eventData.loaderId = loaderId;
eventData.resourceType = resourceType;
eventData.mimeType = response.mimeType;
this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, eventData);
return;
}

networkRequest.responseReceivedTime = time;
networkRequest.type = WebInspector.resourceTypes[resourceType];

this._updateNetworkRequestWithResponse(networkRequest, response);

this._updateNetworkRequest(networkRequest);
},


dataReceived: function(requestId, time, dataLength, encodedDataLength)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.resourceSize += dataLength;
if (encodedDataLength != -1)
networkRequest.increaseTransferSize(encodedDataLength);
networkRequest.endTime = time;

this._updateNetworkRequest(networkRequest);
},


loadingFinished: function(requestId, finishTime)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
this._finishNetworkRequest(networkRequest, finishTime);
},


loadingFailed: function(requestId, time, localizedDescription, canceled)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.failed = true;
networkRequest.canceled = canceled;
networkRequest.localizedFailDescription = localizedDescription;
this._finishNetworkRequest(networkRequest, time);
},


requestServedFromMemoryCache: function(requestId, frameId, loaderId, documentURL, time, initiator, cachedResource)
{
var networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, cachedResource.url, documentURL, initiator);
this._updateNetworkRequestWithCachedResource(networkRequest, cachedResource);
networkRequest.cached = true;
networkRequest.requestMethod = "GET";
this._startNetworkRequest(networkRequest);
networkRequest.startTime = networkRequest.responseReceivedTime = time;
this._finishNetworkRequest(networkRequest, time);
},


webSocketCreated: function(requestId, requestURL)
{
var networkRequest = new WebInspector.NetworkRequest(requestId, requestURL, "", "", "");
networkRequest.type = WebInspector.resourceTypes.WebSocket;
this._startNetworkRequest(networkRequest);
},


webSocketWillSendHandshakeRequest: function(requestId, time, request)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.requestMethod = "GET";
networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
networkRequest.webSocketRequestKey3 = request.requestKey3;
networkRequest.startTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketHandshakeResponseReceived: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
networkRequest.webSocketChallengeResponse = response.challengeResponse;
networkRequest.responseReceivedTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketFrameReceived: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.addFrame(response, time);
networkRequest.responseReceivedTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketFrameSent: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.addFrame(response, time, true);
networkRequest.responseReceivedTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketFrameError: function(requestId, time, errorMessage)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;

networkRequest.addFrameError(errorMessage, time);
networkRequest.responseReceivedTime = time;

this._updateNetworkRequest(networkRequest);
},


webSocketClosed: function(requestId, time)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
this._finishNetworkRequest(networkRequest, time);
},


_appendRedirect: function(requestId, time, redirectURL)
{
var originalNetworkRequest = this._inflightRequestsById[requestId];
var previousRedirects = originalNetworkRequest.redirects || [];
originalNetworkRequest.requestId = "redirected:" + requestId + "." + previousRedirects.length;
delete originalNetworkRequest.redirects;
if (previousRedirects.length > 0)
originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1];
this._finishNetworkRequest(originalNetworkRequest, time);
var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId,
redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator);
newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest);
return newNetworkRequest;
},


_startNetworkRequest: function(networkRequest)
{
this._inflightRequestsById[networkRequest.requestId] = networkRequest;
this._inflightRequestsByURL[networkRequest.url] = networkRequest;
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted, networkRequest);
},


_updateNetworkRequest: function(networkRequest)
{
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated, networkRequest);
},


_finishNetworkRequest: function(networkRequest, finishTime)
{
networkRequest.endTime = finishTime;
networkRequest.finished = true;
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest);
delete this._inflightRequestsById[networkRequest.requestId];
delete this._inflightRequestsByURL[networkRequest.url];
},


_dispatchEventToListeners: function(eventType, networkRequest)
{
this._manager.dispatchEventToListeners(eventType, networkRequest);
},


_createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator)
{
var networkRequest = new WebInspector.NetworkRequest(requestId, url, documentURL, frameId, loaderId);
networkRequest.initiator = initiator;
return networkRequest;
}
}


WebInspector.networkManager = null;






WebInspector.NetworkLog = function()
{
this._requests = [];
this._requestForId = {};
WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.OnLoad, this._onLoad, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._onDOMContentLoaded, this);
}

WebInspector.NetworkLog.prototype = {

get requests()
{
return this._requests;
},


pageLoadForRequest: function(request)
{
return request.__page;
},


_onMainFrameNavigated: function(event)
{
var mainFrame =   event.data;

this._currentPageLoad = null;
var oldRequests = this._requests.splice(0, this._requests.length);
for (var i = 0; i < oldRequests.length; ++i) {
var request = oldRequests[i];
if (request.loaderId === mainFrame.loaderId) {
if (!this._currentPageLoad)
this._currentPageLoad = new WebInspector.PageLoad(request);
this._requests.push(request);
request.__page = this._currentPageLoad;
}
}
},


_onRequestStarted: function(event)
{
var request =   event.data;
this._requests.push(request);
this._requestForId[request.requestId] = request;
request.__page = this._currentPageLoad;
},


_onDOMContentLoaded: function(event)
{
if (this._currentPageLoad)
this._currentPageLoad.contentLoadTime = event.data;
},


_onLoad: function(event)
{
if (this._currentPageLoad)
this._currentPageLoad.loadTime = event.data;
},


requestForId: function(requestId)
{
return this._requestForId[requestId];
}
}


WebInspector.networkLog = null;


WebInspector.PageLoad = function(mainRequest)
{
this.id = ++WebInspector.PageLoad._lastIdentifier;
this.url = mainRequest.url;
this.startTime = mainRequest.startTime;
}

WebInspector.PageLoad._lastIdentifier = 0;






WebInspector.ResourceTreeModel = function(networkManager)
{
networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this);

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);

PageAgent.enable();

NetworkAgent.enable();
this._fetchResourceTree();

InspectorBackend.registerPageDispatcher(new WebInspector.PageDispatcher(this));

this._pendingConsoleMessages = {};
}

WebInspector.ResourceTreeModel.EventTypes = {
FrameAdded: "FrameAdded",
FrameNavigated: "FrameNavigated",
FrameDetached: "FrameDetached",
MainFrameNavigated: "MainFrameNavigated",
ResourceAdded: "ResourceAdded",
WillLoadCachedResources: "WillLoadCachedResources",
CachedResourcesLoaded: "CachedResourcesLoaded",
DOMContentLoaded: "DOMContentLoaded",
OnLoad: "OnLoad",
InspectedURLChanged: "InspectedURLChanged"
}

WebInspector.ResourceTreeModel.prototype = {
_fetchResourceTree: function()
{
this._frames = {};
delete this._cachedResourcesProcessed;
PageAgent.getResourceTree(this._processCachedResources.bind(this));
},

_processCachedResources: function(error, mainFramePayload)
{
if (error) {
console.error(JSON.stringify(error));
return;
}

this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources);
WebInspector.inspectedPageURL = mainFramePayload.frame.url;
this._addFramesRecursively(null, mainFramePayload);
this._dispatchInspectedURLChanged();
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
this._cachedResourcesProcessed = true;
},

cachedResourcesLoaded: function()
{
return this._cachedResourcesProcessed;
},

_dispatchInspectedURLChanged: function()
{
InspectorFrontendHost.inspectedURLChanged(WebInspector.inspectedPageURL);
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, WebInspector.inspectedPageURL);
},


_addFrame: function(frame)
{
this._frames[frame.id] = frame;
if (frame.isMainFrame())
this.mainFrame = frame;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame);
},


_frameNavigated: function(framePayload)
{

if (!this._cachedResourcesProcessed)
return;
var frame = this._frames[framePayload.id];
if (frame) {

frame._navigate(framePayload);
} else {

var parentFrame = this._frames[framePayload.parentId];
frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload);
if (frame.isMainFrame() && this.mainFrame) {

this._frameDetached(this.mainFrame.id);
}
this._addFrame(frame);
}

if (frame.isMainFrame())
WebInspector.inspectedPageURL = frame.url;

this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frame);
if (frame.isMainFrame())
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, frame);


var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resources[i]);

if (frame.isMainFrame())
this._dispatchInspectedURLChanged();
},


_frameDetached: function(frameId)
{

if (!this._cachedResourcesProcessed)
return;

var frame = this._frames[frameId];
if (!frame)
return;

if (frame.parentFrame)
frame.parentFrame._removeChildFrame(frame);
else
frame._remove();
},


_onRequestFinished: function(event)
{
if (!this._cachedResourcesProcessed)
return;

var request =   event.data;
if (request.failed || request.type === WebInspector.resourceTypes.XHR)
return;

var frame = this._frames[request.frameId];
if (frame) {
var resource = frame._addRequest(request);
this._addPendingConsoleMessagesToResource(resource);
}
},


_onRequestUpdateDropped: function(event)
{
if (!this._cachedResourcesProcessed)
return;

var frameId = event.data.frameId;
var frame = this._frames[frameId];
if (!frame)
return;

var url = event.data.url;
if (frame._resourcesMap[url])
return;

var resource = new WebInspector.Resource(null, url, frame.url, frameId, event.data.loaderId, WebInspector.resourceTypes[event.data.resourceType], event.data.mimeType);
frame.addResource(resource);
},


frameForId: function(frameId)
{
return this._frames[frameId];
},


forAllResources: function(callback)
{
if (this.mainFrame)
return this.mainFrame._callForFrameResources(callback);
return false;
},


_consoleMessageAdded: function(event)
{
var msg =   event.data;
var resource = msg.url ? this.resourceForURL(msg.url) : null;
if (resource)
this._addConsoleMessageToResource(msg, resource);
else
this._addPendingConsoleMessage(msg);
},


_addPendingConsoleMessage: function(msg)
{
if (!msg.url)
return;
if (!this._pendingConsoleMessages[msg.url])
this._pendingConsoleMessages[msg.url] = [];
this._pendingConsoleMessages[msg.url].push(msg);
},


_addPendingConsoleMessagesToResource: function(resource)
{
var messages = this._pendingConsoleMessages[resource.url];
if (messages) {
for (var i = 0; i < messages.length; i++)
this._addConsoleMessageToResource(messages[i], resource);
delete this._pendingConsoleMessages[resource.url];
}
},


_addConsoleMessageToResource: function(msg, resource)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
resource.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
resource.errors += msg.repeatDelta;
break;
}
resource.addMessage(msg);
},

_consoleCleared: function()
{
function callback(resource)
{
resource.clearErrorsAndWarnings();
}

this._pendingConsoleMessages = {};
this.forAllResources(callback);
},


resourceForURL: function(url)
{

return this.mainFrame ? this.mainFrame.resourceForURL(url) : null;
},


_addFramesRecursively: function(parentFrame, frameTreePayload)
{
var framePayload = frameTreePayload.frame;
var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload);
this._addFrame(frame);

var frameResource = this._createResourceFromFramePayload(framePayload, framePayload.url, WebInspector.resourceTypes.Document, framePayload.mimeType);
if (frame.isMainFrame())
WebInspector.inspectedPageURL = frameResource.url;
frame.addResource(frameResource);

for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);

for (var i = 0; i < frameTreePayload.resources.length; ++i) {
var subresource = frameTreePayload.resources[i];
var resource = this._createResourceFromFramePayload(framePayload, subresource.url, WebInspector.resourceTypes[subresource.type], subresource.mimeType);
frame.addResource(resource);
}
},


_createResourceFromFramePayload: function(frame, url, type, mimeType)
{
return new WebInspector.Resource(null, url, frame.url, frame.id, frame.loaderId, type, mimeType);
}
}

WebInspector.ResourceTreeModel.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.ResourceTreeFrame = function(model, parentFrame, payload)
{
this._model = model;
this._parentFrame = parentFrame;

this._id = payload.id;
this._loaderId = payload.loaderId;
this._name = payload.name;
this._url = payload.url;
this._securityOrigin = payload.securityOrigin || "";
this._mimeType = payload.mimeType;


this._childFrames = [];


this._resourcesMap = {};

if (this._parentFrame)
this._parentFrame._childFrames.push(this);
}

WebInspector.ResourceTreeFrame.prototype = {

get id()
{
return this._id;
},


get name()
{
return this._name || "";
},


get url()
{
return this._url;
},


get securityOrigin()
{
return this._securityOrigin;
},


get loaderId()
{
return this._loaderId;
},


get parentFrame()
{
return this._parentFrame;
},


get childFrames()
{
return this._childFrames;
},


isMainFrame: function()
{
return !this._parentFrame;
},


_navigate: function(framePayload)
{
this._loaderId = framePayload.loaderId;
this._name = framePayload.name;
this._url = framePayload.url;
this._securityOrigin = framePayload.securityOrigin || "";
this._mimeType = framePayload.mimeType;

var mainResource = this._resourcesMap[this._url];
this._resourcesMap = {};
this._removeChildFrames();
if (mainResource && mainResource.loaderId === this._loaderId)
this.addResource(mainResource);
},


get mainResource()
{
return this._resourcesMap[this._url];
},


_removeChildFrame: function(frame)
{
this._childFrames.remove(frame);
frame._remove();
},

_removeChildFrames: function()
{
var copy = this._childFrames.slice();
for (var i = 0; i < copy.length; ++i)
this._removeChildFrame(copy[i]); 
},

_remove: function()
{
this._removeChildFrames();
delete this._model._frames[this.id];
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this);
},


addResource: function(resource)
{
if (this._resourcesMap[resource.url] === resource) {

return;
}
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
},


_addRequest: function(request)
{
var resource = this._resourcesMap[request.url];
if (resource && resource.request === request) {

return resource;
}
resource = new WebInspector.Resource(request, request.url, request.documentURL, request.frameId, request.loaderId, request.type, request.mimeType);
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
return resource;
},


resources: function()
{
var result = [];
for (var url in this._resourcesMap)
result.push(this._resourcesMap[url]);
return result;
},


resourceForURL: function(url)
{
var result;
function filter(resource)
{
if (resource.url === url) {
result = resource;
return true;
}
}
this._callForFrameResources(filter);
return result;
},


_callForFrameResources: function(callback)
{
for (var url in this._resourcesMap) {
if (callback(this._resourcesMap[url]))
return true;
}

for (var i = 0; i < this._childFrames.length; ++i) {
if (this._childFrames[i]._callForFrameResources(callback))
return true;
}
return false;
}
}


WebInspector.PageDispatcher = function(resourceTreeModel)
{
this._resourceTreeModel = resourceTreeModel;
}

WebInspector.PageDispatcher.prototype = {
domContentEventFired: function(time)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, time);
},

loadEventFired: function(time)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.OnLoad, time);
},

frameNavigated: function(frame)
{
this._resourceTreeModel._frameNavigated(frame);
},

frameDetached: function(frameId)
{
this._resourceTreeModel._frameDetached(frameId);
}
}


WebInspector.resourceTreeModel = null;






WebInspector.ParsedURL = function(url)
{
this.isValid = false;
this.url = url;
this.scheme = "";
this.host = "";
this.port = "";
this.path = "";
this.queryParams = "";
this.fragment = "";
this.folderPathComponents = "";
this.lastPathComponent = "";







var match = url.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
if (match) {
this.isValid = true;
this.scheme = match[1].toLowerCase();
this.host = match[2];
this.port = match[3];
this.path = match[4] || "/";
this.fragment = match[5];
} else {
if (this.url.startsWith("data:")) {
this.scheme = "data";
return;
}
if (this.url === "about:blank") {
this.scheme = "about";
return;
}
this.path = this.url;
}

if (this.path) {

var path = this.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1) {
this.queryParams = path.substring(indexOfQuery + 1)
path = path.substring(0, indexOfQuery);
}


var lastSlashIndex = path.lastIndexOf("/");
if (lastSlashIndex !== -1) {
this.folderPathComponents = path.substring(0, lastSlashIndex);
this.lastPathComponent = path.substring(lastSlashIndex + 1);
} else
this.lastPathComponent = path;
}
}


WebInspector.ParsedURL.completeURL = function(baseURL, href)
{
if (href) {

var trimmedHref = href.trim();
if (trimmedHref.startsWith("data:") || trimmedHref.startsWith("blob:") || trimmedHref.startsWith("javascript:"))
return href;


var parsedHref = trimmedHref.asParsedURL();
if (parsedHref && parsedHref.scheme)
return trimmedHref;
} else
return baseURL;

var parsedURL = baseURL.asParsedURL();
if (parsedURL) {
var path = href;
if (path.charAt(0) !== "/") {
var basePath = parsedURL.path;


var questionMarkIndex = basePath.indexOf("?");
if (questionMarkIndex > 0)
basePath = basePath.substring(0, questionMarkIndex);


var prefix;
if (path.charAt(0) === "?") {
var basePathCutIndex = basePath.indexOf("?");
if (basePathCutIndex !== -1)
prefix = basePath.substring(0, basePathCutIndex);
else
prefix = basePath;
} else
prefix = basePath.substring(0, basePath.lastIndexOf("/")) + "/";

path = prefix + path;
} else if (path.length > 1 && path.charAt(1) === "/") {

return parsedURL.scheme + ":" + path;
}
return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + path;
}
return null;
}

WebInspector.ParsedURL.prototype = {
get displayName()
{
if (this._displayName)
return this._displayName;

if (this.scheme === "data") {
this._displayName = this.url.trimEnd(20);
return this._displayName;
}

if (this.url === "about:blank")
return this.url;

this._displayName = this.lastPathComponent;
if (!this._displayName)
this._displayName = this.host;
if (!this._displayName && this.url)
this._displayName = this.url.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : "");
if (this._displayName === "/")
this._displayName = this.url;
return this._displayName;
}
}


String.prototype.asParsedURL = function()
{
var parsedURL = new WebInspector.ParsedURL(this.toString());
if (parsedURL.isValid)
return parsedURL;
return null;
}






WebInspector.resourceForURL = function(url)
{
return WebInspector.resourceTreeModel.resourceForURL(url);
}


WebInspector.forAllResources = function(callback)
{
WebInspector.resourceTreeModel.forAllResources(callback);
}


WebInspector.displayNameForURL = function(url)
{
if (!url)
return "";

var resource = WebInspector.resourceForURL(url);
if (resource)
return resource.displayName;

if (!WebInspector.inspectedPageURL)
return url.trimURL("");

var parsedURL = WebInspector.inspectedPageURL.asParsedURL();
var lastPathComponent = parsedURL ? parsedURL.lastPathComponent : parsedURL;
var index = WebInspector.inspectedPageURL.indexOf(lastPathComponent);
if (index !== -1 && index + lastPathComponent.length === WebInspector.inspectedPageURL.length) {
var baseURL = WebInspector.inspectedPageURL.substring(0, index);
if (url.startsWith(baseURL))
return url.substring(index);
}

return parsedURL ? url.trimURL(parsedURL.host) : url;
}


WebInspector.linkifyStringAsFragmentWithCustomLinkifier = function(string, linkifier)
{
var container = document.createDocumentFragment();
var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|www\.)[\w$\-_+*'=\|\/\\(){}[\]%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({%@&#~]/;
    var lineColumnRegEx = /:(\d+)(:(\d+))?$/;

    while (string) {
        var linkString = linkStringRegEx.exec(string);
        if (!linkString)
            break;

        linkString = linkString[0];
        var linkIndex = string.indexOf(linkString);
        var nonLink = string.substring(0, linkIndex);
        container.appendChild(document.createTextNode(nonLink));

        var title = linkString;
        var realURL = (linkString.startsWith("www.") ? "http://" + linkString : linkString);
        var lineColumnMatch = lineColumnRegEx.exec(realURL);
        var lineNumber;
        if (lineColumnMatch) {
            realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length);
            lineNumber = parseInt(lineColumnMatch[1], 10);
            lineNumber = isNaN(lineNumber) ? undefined : lineNumber;
        }

        var linkNode = linkifier(title, realURL, lineNumber);
        container.appendChild(linkNode);
        string = string.substring(linkIndex + linkString.length, string.length);
    }

    if (string)
        container.appendChild(document.createTextNode(string));

    return container;
}

WebInspector._linkifierPlugins = [];

/**
 * @param {function(string):string} plugin
 */
WebInspector.registerLinkifierPlugin = function(plugin)
{
    WebInspector._linkifierPlugins.push(plugin);
}

/**
 * @param {string} string
 * @return {DocumentFragment}
 */
WebInspector.linkifyStringAsFragment = function(string)
{
    /**
     * @param {string} title
     * @param {string} url
     * @param {number=} lineNumber
     * @return {Node}
     */
    function linkifier(title, url, lineNumber)
    {
        for (var i = 0; i < WebInspector._linkifierPlugins.length; ++i)
            title = WebInspector._linkifierPlugins[i](title);

        var isExternal = !WebInspector.resourceForURL(url);
        var urlNode = WebInspector.linkifyURLAsNode(url, title, undefined, isExternal);
        if (typeof(lineNumber) !== "undefined") {
            urlNode.lineNumber = lineNumber;
            urlNode.preferredPanel = "scripts";
        }
        
        return urlNode; 
    }
    
    return WebInspector.linkifyStringAsFragmentWithCustomLinkifier(string, linkifier);
}

/**
 * @param {string} url
 * @param {string=} linkText
 * @param {string=} classes
 * @param {boolean=} isExternal
 * @param {string=} tooltipText
 * @return {Element}
 */
WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, tooltipText)
{
    if (!linkText)
        linkText = url;
    classes = (classes ? classes + " " : "");
    classes += isExternal ? "webkit-html-external-link" : "webkit-html-resource-link";

    var a = document.createElement("a");
    a.href = sanitizeHref(url);
    a.className = classes;
    if (typeof tooltipText === "undefined")
        a.title = url;
    else if (typeof tooltipText !== "string" || tooltipText.length)
        a.title = tooltipText;
    a.textContent = linkText;
    a.style.maxWidth = "100%";
    if (isExternal)
        a.setAttribute("target", "_blank");

    return a;
}

/**
 * @param {string} url
 * @param {number=} lineNumber
 * @return {string}
 */
WebInspector.formatLinkText = function(url, lineNumber)
{
    var text = WebInspector.displayNameForURL(url);
    if (typeof lineNumber === "number")
        text += ":" + (lineNumber + 1);
    return text;
}

/**
 * @param {string} url
 * @param {number=} lineNumber
 * @param {string=} classes
 * @param {string=} tooltipText
 * @return {Element}
 */
WebInspector.linkifyResourceAsNode = function(url, lineNumber, classes, tooltipText)
{
    var linkText = WebInspector.formatLinkText(url, lineNumber);
    var anchor = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
    anchor.preferredPanel = "resources";
    anchor.lineNumber = lineNumber;
    return anchor;
}

/**
 * @param {WebInspector.NetworkRequest} request
 * @param {string=} classes
 * @return {Element}
 */
WebInspector.linkifyRequestAsNode = function(request, classes)
{
    var anchor = WebInspector.linkifyURLAsNode(request.url);
    anchor.preferredPanel = "network";
    anchor.requestId  = request.requestId;
    return anchor;
}

/* ResourceType.js */

/*
 * Copyright (C) 2012 Google Inc.  All rights reserved.
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @param {string} name
 * @param {string} title
 * @param {string} categoryTitle
 * @param {string} color
 * @param {boolean} isTextType
 */
WebInspector.ResourceType = function(name, title, categoryTitle, color, isTextType)
{
    this._name = name;
    this._title = title;
    this._categoryTitle = categoryTitle;
    this._color = color;
    this._isTextType = isTextType;
}

WebInspector.ResourceType.prototype = {
    /**
     * @return {string}
     */
    name: function()
    {
        return this._name;
    },

    /**
     * @return {string}
     */
    title: function()
    {
        return this._title;
    },

    /**
     * @return {string}
     */
    categoryTitle: function()
    {
        return this._categoryTitle;
    },

    /**
     * @return {string}
     */
    color: function()
    {
        return this._color;
    },

    /**
     * @return {boolean}
     */
    isTextType: function()
    {
        return this._isTextType;
    },

    /**
     * @return {string}
     */
    toString: function()
    {
        return this._name;
    },

    /**
     * @return {string}
     */
    canonicalMimeType: function()
    {
        if (this === WebInspector.resourceTypes.Document)
            return "text/html";
        if (this === WebInspector.resourceTypes.Script)
            return "text/javascript";
        if (this === WebInspector.resourceTypes.Stylesheet)
            return "text/css";
        return "";
    }
}

//Keep these in sync with WebCore::InspectorPageAgent::resourceTypeJson
WebInspector.resourceTypes = {
    Document: new WebInspector.ResourceType("document", "Document", "Documents", "rgb(47,102,236)", true),
    Stylesheet: new WebInspector.ResourceType("stylesheet", "Stylesheet", "Stylesheets", "rgb(157,231,119)", true),
    Image: new WebInspector.ResourceType("image", "Image", "Images", "rgb(164,60,255)", false),
    Script: new WebInspector.ResourceType("script", "Script", "Scripts", "rgb(255,121,0)", true),
    XHR: new WebInspector.ResourceType("xhr", "XHR", "XHR", "rgb(231,231,10)", true),
    Font: new WebInspector.ResourceType("font", "Font", "Fonts", "rgb(255,82,62)", false),
    WebSocket: new WebInspector.ResourceType("websocket", "WebSocket", "WebSockets", "rgb(186,186,186)", false), // FIXME: Decide the color.
    Other: new WebInspector.ResourceType("other", "Other", "Other", "rgb(186,186,186)", false)
}

/* TimelineManager.js */

/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.Object}
 */
WebInspector.TimelineManager = function()
{
    WebInspector.Object.call(this);
    this._dispatcher = new WebInspector.TimelineDispatcher(this);
    this._enablementCount = 0;
}

WebInspector.TimelineManager.EventTypes = {
    TimelineStarted: "TimelineStarted",
    TimelineStopped: "TimelineStopped",
    TimelineEventRecorded: "TimelineEventRecorded"
}

WebInspector.TimelineManager.prototype = {
    /**
     * @param {number=} maxCallStackDepth
     */
    start: function(maxCallStackDepth)
    {
        this._enablementCount++;
        if (this._enablementCount === 1)
            TimelineAgent.start(maxCallStackDepth, this._started.bind(this));
    },

    stop: function()
    {
        if (!this._enablementCount) {
            console.error("WebInspector.TimelineManager start/stop calls are unbalanced");
            return;
        }
        this._enablementCount--;
        if (!this._enablementCount)
            TimelineAgent.stop(this._stopped.bind(this));
    },

    _started: function()
    {
        this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStarted);
    },

    _stopped: function()
    {
        this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStopped);
    }
}

WebInspector.TimelineManager.prototype.__proto__ = WebInspector.Object.prototype;

/**
 * @constructor
 * @implements {TimelineAgent.Dispatcher}
 */
WebInspector.TimelineDispatcher = function(manager)
{
    this._manager = manager;
    InspectorBackend.registerTimelineDispatcher(this);
}

WebInspector.TimelineDispatcher.prototype = {
    eventRecorded: function(record)
    {
        this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, record);
    }
}

/**
 * @type {WebInspector.TimelineManager}
 */
WebInspector.timelineManager;

/* UserAgentSupport.js */

/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 */
WebInspector.UserAgentSupport = function()
{
    if (WebInspector.settings.deviceMetrics.get())
        this._deviceMetricsChanged();
    WebInspector.settings.deviceMetrics.addChangeListener(this._deviceMetricsChanged, this);
    WebInspector.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this);
    WebInspector.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this);
    WebInspector.settings.deviceOrientationOverride.addChangeListener(this._deviceOrientationChanged, this);
}

/**
 * @constructor
 * @param {number} width
 * @param {number} height
 * @param {number} fontScaleFactor
 */
WebInspector.UserAgentSupport.DeviceMetrics = function(width, height, fontScaleFactor)
{
    this.width = width;
    this.height = height;
    this.fontScaleFactor = fontScaleFactor;
}

/**
 * @return {WebInspector.UserAgentSupport.DeviceMetrics}
 */
WebInspector.UserAgentSupport.DeviceMetrics.parseSetting = function(value)
{
    if (value) {
        var splitMetrics = value.split("x");
        if (splitMetrics.length === 3)
            return new WebInspector.UserAgentSupport.DeviceMetrics(parseInt(splitMetrics[0], 10), parseInt(splitMetrics[1], 10), parseFloat(splitMetrics[2]));
    }
    return new WebInspector.UserAgentSupport.DeviceMetrics(0, 0, 1);
}

/**
 * @return {?WebInspector.UserAgentSupport.DeviceMetrics}
 */
WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput = function(widthString, heightString, fontScaleFactorString)
{
    function isUserInputValid(value, isInteger)
    {
        if (!value)
            return true;
        return isInteger ? /^[0]*[1-9][\d]*$/.test(value) : /^[0]*([1-9][\d]*(\.\d+)?|\.\d+)$/.test(value);
    }

    if (!widthString ^ !heightString)
        return null;

    var isWidthValid = isUserInputValid(widthString, true);
    var isHeightValid = isUserInputValid(heightString, true);
    var isFontScaleFactorValid = isUserInputValid(fontScaleFactorString, false);

    if (!isWidthValid && !isHeightValid && !isFontScaleFactorValid)
        return null;

    var width = isWidthValid ? parseInt(widthString || "0", 10) : -1;
    var height = isHeightValid ? parseInt(heightString || "0", 10) : -1;
    var fontScaleFactor = isFontScaleFactorValid ? parseFloat(fontScaleFactorString) : -1;

    return new WebInspector.UserAgentSupport.DeviceMetrics(width, height, fontScaleFactor);
}

WebInspector.UserAgentSupport.DeviceMetrics.prototype = {
    /**
     * @return {boolean}
     */
    isValid: function()
    {
        return this.isWidthValid() && this.isHeightValid() && this.isFontScaleFactorValid();
    },

    /**
     * @return {boolean}
     */
    isWidthValid: function()
    {
        return this.width >= 0;
    },

    /**
     * @return {boolean}
     */
    isHeightValid: function()
    {
        return this.height >= 0;
    },

    /**
     * @return {boolean}
     */
    isFontScaleFactorValid: function()
    {
        return this.fontScaleFactor > 0;
    },

    /**
     * @return {string}
     */
    toSetting: function()
    {
        if (!this.isValid())
            return "";

        return this.width && this.height ? this.width + "x" + this.height + "x" + this.fontScaleFactor : "";
    },

    /**
     * @return {string}
     */
    widthToInput: function()
    {
        return this.isWidthValid() && this.width ? String(this.width) : "";
    },

    /**
     * @return {string}
     */
    heightToInput: function()
    {
        return this.isHeightValid() && this.height ? String(this.height) : "";
    },

    /**
     * @return {string}
     */
    fontScaleFactorToInput: function()
    {
        return this.isFontScaleFactorValid() && this.fontScaleFactor ? String(this.fontScaleFactor) : "";
    }
}

/**
 * @constructor
 * @param {number} latitude
 * @param {number} longitude
 */
WebInspector.UserAgentSupport.GeolocationPosition = function(latitude, longitude, error)
{
    this.latitude = latitude;
    this.longitude = longitude;
    this.error = error;
}

WebInspector.UserAgentSupport.GeolocationPosition.prototype = {
    /**
     * @return {string}
     */
    toSetting: function()
    {
        return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : "";
    }
}

/**
 * @return {WebInspector.UserAgentSupport.GeolocationPosition}
 */
WebInspector.UserAgentSupport.GeolocationPosition.parseSetting = function(value)
{
    if (value) {
        var splitError = value.split(":");
        if (splitError.length === 2) {
            var splitPosition = splitError[0].split("@")
            if (splitPosition.length === 2)
                return new WebInspector.UserAgentSupport.GeolocationPosition(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]);
        }
    }
    return new WebInspector.UserAgentSupport.GeolocationPosition(0, 0, "");
}

/**
 * @return {?WebInspector.UserAgentSupport.GeolocationPosition}
 */
WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput = function(latitudeString, longitudeString, errorStatus)
{
    function isUserInputValid(value)
    {
        if (!value)
            return true;
        return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
    }

    if (!latitudeString ^ !latitudeString)
        return null;

    var isLatitudeValid = isUserInputValid(latitudeString);
    var isLongitudeValid = isUserInputValid(longitudeString);

    if (!isLatitudeValid && !isLongitudeValid)
        return null;

    var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
    var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;

    return new WebInspector.UserAgentSupport.GeolocationPosition(latitude, longitude, errorStatus ? "PositionUnavailable" : "");
}

WebInspector.UserAgentSupport.GeolocationPosition.clearGeolocationOverride = function()
{
    PageAgent.clearGeolocationOverride();
}

/**
 * @constructor
 * @param {number} alpha
 * @param {number} beta
 * @param {number} gamma
 */
WebInspector.UserAgentSupport.DeviceOrientation = function(alpha, beta, gamma)
{
    this.alpha = alpha;
    this.beta = beta;
    this.gamma = gamma;
}

WebInspector.UserAgentSupport.DeviceOrientation.prototype = {
    /**
     * @return {string}
     */
    toSetting: function()
    {
        return JSON.stringify(this);
    }
}

/**
 * @return {WebInspector.UserAgentSupport.DeviceOrientation}
 */
WebInspector.UserAgentSupport.DeviceOrientation.parseSetting = function(value)
{
    if (value) {
        var jsonObject = JSON.parse(value);
        return new WebInspector.UserAgentSupport.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
    }
    return new WebInspector.UserAgentSupport.DeviceOrientation(0, 0, 0);
}

/**
 * @return {?WebInspector.UserAgentSupport.DeviceOrientation}
 */
WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString)
{
    function isUserInputValid(value)
    {
        if (!value)
            return true;
        return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
    }

    if (!alphaString ^ !betaString ^ !gammaString)
        return null;

    var isAlphaValid = isUserInputValid(alphaString);
    var isBetaValid = isUserInputValid(betaString);
    var isGammaValid = isUserInputValid(gammaString);

    if (!isAlphaValid && !isBetaValid && !isGammaValid)
        return null;

    var alpha = isAlphaValid ? parseFloat(alphaString) : -1;
    var beta = isBetaValid ? parseFloat(betaString) : -1;
    var gamma = isGammaValid ? parseFloat(gammaString) : -1;

    return new WebInspector.UserAgentSupport.DeviceOrientation(alpha, beta, gamma);
}

WebInspector.UserAgentSupport.DeviceOrientation.clearDeviceOrientationOverride = function()
{
    PageAgent.clearDeviceOrientationOverride();
}

WebInspector.UserAgentSupport.prototype = {
    _deviceMetricsChanged: function()
    {
        var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(WebInspector.settings.deviceMetrics.get());
        if (metrics.isValid())
            PageAgent.setDeviceMetricsOverride(metrics.width, metrics.height, metrics.fontScaleFactor, WebInspector.settings.deviceFitWindow.get());
    },

    _geolocationPositionChanged: function()
    {
        var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseSetting(WebInspector.settings.geolocationOverride.get());
        if (geolocation.error)
            PageAgent.setGeolocationOverride();
        else
            PageAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150);
    },

    /**
     * @param {WebInspector.Event} event
     */
    _deviceOrientationChanged: function(event)
    {
        var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseSetting(WebInspector.settings.deviceOrientationOverride.get());
        PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
    }
}


/* Database.js */

/*
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @param {WebInspector.DatabaseModel} model
 */
WebInspector.Database = function(model, id, domain, name, version)
{
    this._model = model;
    this._id = id;
    this._domain = domain;
    this._name = name;
    this._version = version;
}

WebInspector.Database.prototype = {
    /** @return {string} */
    get id()
    {
        return this._id;
    },

    /** @return {string} */
    get name()
    {
        return this._name;
    },

    set name(x)
    {
        this._name = x;
    },

    /** @return {string} */
    get version()
    {
        return this._version;
    },

    set version(x)
    {
        this._version = x;
    },

    /** @return {string} */
    get domain()
    {
        return this._domain;
    },

    set domain(x)
    {
        this._domain = x;
    },

    /**
     * @param {function(Array.<string>)} callback
     */
    getTableNames: function(callback)
    {
        function sortingCallback(error, names)
        {
            if (!error)
                callback(names.sort());
        }
        DatabaseAgent.getDatabaseTableNames(this._id, sortingCallback);
    },

    /**
     * @param {string} query
     * @param {function(Array.<string>=, Array.<*>=)} onSuccess
     * @param {function(string)} onError
     */
    executeSql: function(query, onSuccess, onError)
    {
        /**
         * @param {?Protocol.Error} error
         * @param {Array.<string>=} columnNames
         * @param {Array.<*>=} values
         * @param {DatabaseAgent.Error=} errorObj
         */
        function callback(error, columnNames, values, errorObj)
        {
            if (error) {
                onError(error);
                return;
            }
            if (errorObj) {
                var message;
                if (errorObj.message)
                    message = errorObj.message;
                else if (errorObj.code == 2)
                    message = WebInspector.UIString("Database no longer has expected version.");
                else
                    message = WebInspector.UIString("An unexpected error %s occurred.", errorObj.code);
                onError(message);
                return;
            }
            onSuccess(columnNames, values);
        }
        DatabaseAgent.executeSQL(this._id, query, callback.bind(this));
    }
}

/**
 * @constructor
 * @extends {WebInspector.Object}
 */
WebInspector.DatabaseModel = function()
{
    this._databases = [];
    InspectorBackend.registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this));
    DatabaseAgent.enable();
}

WebInspector.DatabaseModel.Events = {
    DatabaseAdded: "DatabaseAdded"
}

WebInspector.DatabaseModel.prototype = {
    /**
     * @return {Array.<WebInspector.Database>}
     */
    databases: function()
    {
        var result = [];
        for (var databaseId in this._databases)
            result.push(this._databases[databaseId]);
        return result;
    },

    /**
     * @param {DatabaseAgent.DatabaseId} databaseId
     * @return {WebInspector.Database}
     */
    databaseForId: function(databaseId)
    {
        return this._databases[databaseId];
    },

    /**
     * @param {WebInspector.Database} database
     */
    _addDatabase: function(database)
    {
        this._databases.push(database);
        this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabaseAdded, database);
    }
}

WebInspector.DatabaseModel.prototype.__proto__ = WebInspector.Object.prototype;

/**
 * @constructor
 * @implements {DatabaseAgent.Dispatcher}
 * @param {WebInspector.DatabaseModel} model
 */
WebInspector.DatabaseDispatcher = function(model)
{
    this._model = model;
}

WebInspector.DatabaseDispatcher.prototype = {
    /**
     * @param {DatabaseAgent.Database} payload
     */
    addDatabase: function(payload)
    {
        this._model._addDatabase(new WebInspector.Database(
            this._model,
            payload.id,
            payload.domain,
            payload.name,
            payload.version));
    }
}

/**
 * @type {WebInspector.DatabaseModel}
 */
WebInspector.databaseModel = null;

/* DOMStorage.js */

/*
 * Copyright (C) 2008 Nokia Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 */
WebInspector.DOMStorage = function(id, domain, isLocalStorage)
{
    this._id = id;
    this._domain = domain;
    this._isLocalStorage = isLocalStorage;
}

WebInspector.DOMStorage.prototype = {
    /** @return {string} */
    get id()
    {
        return this._id;
    },

    /** @return {string} */
    get domain()
    {
        return this._domain;
    },

    /** @return {boolean} */
    get isLocalStorage()
    {
        return this._isLocalStorage;
    },

    /**
     * @param {function(?Protocol.Error, Array.<DOMStorageAgent.Entry>):void=} callback
     */
    getEntries: function(callback)
    {
        DOMStorageAgent.getDOMStorageEntries(this._id, callback);
    },

    /**
     * @param {string} key
     * @param {string} value
     * @param {function(?Protocol.Error, boolean):void=} callback
     */
    setItem: function(key, value, callback)
    {
        DOMStorageAgent.setDOMStorageItem(this._id, key, value, callback);
    },

    /**
     * @param {string} key
     * @param {function(?Protocol.Error, boolean):void=} callback
     */
    removeItem: function(key, callback)
    {
        DOMStorageAgent.removeDOMStorageItem(this._id, key, callback);
    }
}

/**
 * @constructor
 * @extends {WebInspector.Object}
 */
WebInspector.DOMStorageModel = function()
{
    this._storages = {};
    InspectorBackend.registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this));
    DOMStorageAgent.enable();
}

WebInspector.DOMStorageModel.Events = {
    DOMStorageAdded: "DOMStorageAdded",
    DOMStorageUpdated: "DOMStorageUpdated"
}

WebInspector.DOMStorageModel.prototype = {
    /**
     * @param {WebInspector.DOMStorage} domStorage
     */
    _addDOMStorage: function(domStorage)
    {
        this._storages[domStorage.id] = domStorage;
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, domStorage);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     */
    _domStorageUpdated: function(storageId)
    {
        this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageUpdated, this._storages[storageId]);
    },

    /**
     * @param {DOMStorageAgent.StorageId} storageId
     * @return {WebInspector.DOMStorage}
     */
    storageForId: function(storageId)
    {
        return this._storages[storageId];
    },

    /**
     * @return {Array.<WebInspector.DOMStorage>}
     */
    storages: function()
    {
        var result = [];
        for (var storageId in this._storages)
            result.push(this._storages[storageId]);
        return result;
    }
}

WebInspector.DOMStorageModel.prototype.__proto__ = WebInspector.Object.prototype;

/**
 * @constructor
 * @implements {DOMStorageAgent.Dispatcher}
 * @param {WebInspector.DOMStorageModel} model
 */
WebInspector.DOMStorageDispatcher = function(model)
{
    this._model = model;
}

WebInspector.DOMStorageDispatcher.prototype = {

    /**
     * @param {DOMStorageAgent.Entry} payload
     */
    addDOMStorage: function(payload)
    {
        this._model._addDOMStorage(new WebInspector.DOMStorage(
            payload.id,
            payload.origin,
            payload.isLocalStorage));
    },

    /**
     * @param {string} storageId
     */
    domStorageUpdated: function(storageId)
    {
        this._model._domStorageUpdated(storageId);
    }
}

/**
 * @type {WebInspector.DOMStorageModel}
 */
WebInspector.domStorageModel = null;

/* DataGrid.js */

/*
 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.         IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.View}
 * @param {function(WebInspector.DataGridNode, number, string, string)=} editCallback
 * @param {function(WebInspector.DataGridNode)=} deleteCallback
 */
WebInspector.DataGrid = function(columns, editCallback, deleteCallback)
{
    WebInspector.View.call(this);
    this.registerRequiredCSS("dataGrid.css");

    this.element.className = "data-grid";
    this.element.tabIndex = 0;
    this.element.addEventListener("keydown", this._keyDown.bind(this), false);

    this._headerTable = document.createElement("table");
    this._headerTable.className = "header";
    this._headerTableHeaders = {};

    this._dataTable = document.createElement("table");
    this._dataTable.className = "data";

    this._dataTable.addEventListener("mousedown", this._mouseDownInDataTable.bind(this), true);
    this._dataTable.addEventListener("click", this._clickInDataTable.bind(this), true);

    this._dataTable.addEventListener("contextmenu", this._contextMenuInDataTable.bind(this), true);

    // FIXME: Add a createCallback which is different from editCallback and has different
    // behavior when creating a new node.
    if (editCallback) {
        this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this), false);
        this._editCallback = editCallback;
    }
    if (deleteCallback)
        this._deleteCallback = deleteCallback;

    this.aligned = {};

    this._scrollContainer = document.createElement("div");
    this._scrollContainer.className = "data-container";
    this._scrollContainer.appendChild(this._dataTable);

    this.element.appendChild(this._headerTable);
    this.element.appendChild(this._scrollContainer);

    var headerRow = document.createElement("tr");
    var columnGroup = document.createElement("colgroup");
    this._columnCount = 0;

    for (var columnIdentifier in columns) {
        var column = columns[columnIdentifier];
        if (column.disclosure)
            this.disclosureColumnIdentifier = columnIdentifier;

        var col = document.createElement("col");
        if (column.width)
            col.style.width = column.width;
        column.element = col;
        columnGroup.appendChild(col);

        var cell = document.createElement("th");
        cell.className = columnIdentifier + "-column";
        cell.columnIdentifier = columnIdentifier;
        this._headerTableHeaders[columnIdentifier] = cell;

        var div = document.createElement("div");
        if (column.titleDOMFragment)
            div.appendChild(column.titleDOMFragment);
        else
            div.textContent = column.title;
        cell.appendChild(div);

        if (column.sort) {
            cell.addStyleClass("sort-" + column.sort);
            this._sortColumnCell = cell;
        }

        if (column.sortable) {
            cell.addEventListener("click", this._clickInHeaderCell.bind(this), false);
            cell.addStyleClass("sortable");
        }

        if (column.aligned)
            this.aligned[columnIdentifier] = column.aligned;

        headerRow.appendChild(cell);

        ++this._columnCount;
    }

    columnGroup.span = this._columnCount;

    var cell = document.createElement("th");
    cell.className = "corner";
    headerRow.appendChild(cell);

    this._headerTableColumnGroup = columnGroup;
    this._headerTable.appendChild(this._headerTableColumnGroup);
    this.headerTableBody.appendChild(headerRow);

    var fillerRow = document.createElement("tr");
    fillerRow.className = "filler";

    for (var columnIdentifier in columns) {
        var column = columns[columnIdentifier];
        var td = document.createElement("td");
        td.className = columnIdentifier + "-column";
        fillerRow.appendChild(td);
    }

    this._dataTableColumnGroup = columnGroup.cloneNode(true);
    this._dataTable.appendChild(this._dataTableColumnGroup);
    this.dataTableBody.appendChild(fillerRow);

    this.columns = columns || {};
    this._columnsArray = [];
    for (var columnIdentifier in columns) {
        columns[columnIdentifier].ordinal = this._columnsArray.length;
        columns[columnIdentifier].identifier = columnIdentifier;
        this._columnsArray.push(columns[columnIdentifier]);
    }

    for (var i = 0; i < this._columnsArray.length; ++i)
        this._columnsArray[i].bodyElement = this._dataTableColumnGroup.children[i];

    this.selectedNode = null;
    this.expandNodesWhenArrowing = false;
    this.setRootNode(new WebInspector.DataGridNode());
    this.indentWidth = 15;
    this.resizers = [];
    this._columnWidthsInitialized = false;
}

WebInspector.DataGrid.Events = {
    SelectedNode: "SelectedNode",
    DeselectedNode: "DeselectedNode"
}

/**
 * @param {Array.<string>} columnNames
 * @param {Array.<string>} values
 */
WebInspector.DataGrid.createSortableDataGrid = function(columnNames, values)
{
    var numColumns = columnNames.length;
    if (!numColumns)
        return null;

    var columns = {};

    for (var i = 0; i < columnNames.length; ++i) {
        var column = {};
        column.width = columnNames[i].length;
        column.title = columnNames[i];
        column.sortable = true;

        columns[columnNames[i]] = column;
    }

    var nodes = [];
    for (var i = 0; i < values.length / numColumns; ++i) {
        var data = {};
        for (var j = 0; j < columnNames.length; ++j)
            data[columnNames[j]] = values[numColumns * i + j];

        var node = new WebInspector.DataGridNode(data, false);
        node.selectable = false;
        nodes.push(node);
    }

    var dataGrid = new WebInspector.DataGrid(columns);
    var length = nodes.length;
    for (var i = 0; i < length; ++i)
        dataGrid.rootNode().appendChild(nodes[i]);

    dataGrid.addEventListener("sorting changed", sortDataGrid, this);

    function sortDataGrid()
    {
        var nodes = dataGrid._rootNode.children.slice();
        var sortColumnIdentifier = dataGrid.sortColumnIdentifier;
        var sortDirection = dataGrid.sortOrder === "ascending" ? 1 : -1;
        var columnIsNumeric = true;

        for (var i = 0; i < nodes.length; i++) {
            if (isNaN(Number(nodes[i].data[sortColumnIdentifier])))
                columnIsNumeric = false;
        }

        function comparator(dataGridNode1, dataGridNode2)
        {
            var item1 = dataGridNode1.data[sortColumnIdentifier];
            var item2 = dataGridNode2.data[sortColumnIdentifier];

            var comparison;
            if (columnIsNumeric) {
                // Sort numbers based on comparing their values rather than a lexicographical comparison.
                var number1 = parseFloat(item1);
                var number2 = parseFloat(item2);
                comparison = number1 < number2 ? -1 : (number1 > number2 ? 1 : 0);
            } else
                comparison = item1 < item2 ? -1 : (item1 > item2 ? 1 : 0);

            return sortDirection * comparison;
        }

        nodes.sort(comparator);
        dataGrid.rootNode().removeChildren();
        for (var i = 0; i < nodes.length; i++)
            dataGrid._rootNode.appendChild(nodes[i]);
    }
    return dataGrid;
}

WebInspector.DataGrid.prototype = {
    setRootNode: function(rootNode)
    {
        if (this._rootNode) {
            this._rootNode.removeChildren();
            this._rootNode.dataGrid = null;
            this._rootNode._isRoot = false;
        }
        this._rootNode = rootNode;
        rootNode._isRoot = true;
        rootNode.hasChildren = false;
        rootNode._expanded = true;
        rootNode._revealed = true;
        rootNode.dataGrid = this;
    },

    rootNode: function()
    {
        return this._rootNode;
    },

    get refreshCallback()
    {
        return this._refreshCallback;
    },

    set refreshCallback(refreshCallback)
    {
        this._refreshCallback = refreshCallback;
    },

    _ondblclick: function(event)
    {
        if (this._editing || this._editingNode)
            return;

        this._startEditing(event.target);
    },

    _startEditingColumnOfDataGridNode: function(node, column)
    {
        this._editing = true;
        this._editingNode = node;
        this._editingNode.select();

        var element = this._editingNode._element.children[column];
        WebInspector.startEditing(element, this._startEditingConfig(element));
        window.getSelection().setBaseAndExtent(element, 0, element, 1);
    },

    _startEditing: function(target)
    {
        var element = target.enclosingNodeOrSelfWithNodeName("td");
        if (!element)
            return;

        this._editingNode = this.dataGridNodeFromNode(target);
        if (!this._editingNode) {
            if (!this.creationNode)
                return;
            this._editingNode = this.creationNode;
        }

        // Force editing the 1st column when editing the creation node
        if (this._editingNode.isCreationNode)
            return this._startEditingColumnOfDataGridNode(this._editingNode, 0);

        this._editing = true;
        WebInspector.startEditing(element, this._startEditingConfig(element));

        window.getSelection().setBaseAndExtent(element, 0, element, 1);
    },


    _startEditingConfig: function(element)
    {
        return new WebInspector.EditingConfig(this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
    },

    _editingCommitted: function(element, newText, oldText, context, moveDirection)
    {
        // FIXME: We need more column identifiers here throughout this function.
        // Not needed yet since only editable DataGrid is DOM Storage, which is Key - Value.

        // FIXME: Better way to do this than regular expressions?
        var columnIdentifier = parseInt(element.className.match(/\b(\d+)-column\b/)[1], 10);

        var textBeforeEditing = this._editingNode.data[columnIdentifier];
        var currentEditingNode = this._editingNode;

        function moveToNextIfNeeded(wasChange) {
            if (!moveDirection)
                return;

            if (moveDirection === "forward") {
                if (currentEditingNode.isCreationNode && columnIdentifier === 0 && !wasChange)
                    return;

                if (columnIdentifier === 0)
                    return this._startEditingColumnOfDataGridNode(currentEditingNode, 1);

                var nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true);
                if (nextDataGridNode)
                    return this._startEditingColumnOfDataGridNode(nextDataGridNode, 0);
                if (currentEditingNode.isCreationNode && wasChange) {
                    this.addCreationNode(false);
                    return this._startEditingColumnOfDataGridNode(this.creationNode, 0);
                }
                return;
            }

            if (moveDirection === "backward") {
                if (columnIdentifier === 1)
                    return this._startEditingColumnOfDataGridNode(currentEditingNode, 0);
                    var nextDataGridNode = currentEditingNode.traversePreviousNode(true, null, true);

                if (nextDataGridNode)
                    return this._startEditingColumnOfDataGridNode(nextDataGridNode, 1);
                return;
            }
        }

        if (textBeforeEditing == newText) {
            this._editingCancelled(element);
            moveToNextIfNeeded.call(this, false);
            return;
        }

        // Update the text in the datagrid that we typed
        this._editingNode.data[columnIdentifier] = newText;

        // Make the callback - expects an editing node (table row), the column number that is being edited,
        // the text that used to be there, and the new text.
        this._editCallback(this._editingNode, columnIdentifier, textBeforeEditing, newText);

        if (this._editingNode.isCreationNode)
            this.addCreationNode(false);

        this._editingCancelled(element);
        moveToNextIfNeeded.call(this, true);
    },

    _editingCancelled: function(element)
    {
        delete this._editing;
        this._editingNode = null;
    },

    /**
     * @return {?string}
     */
    get sortColumnIdentifier()
    {
        if (!this._sortColumnCell)
            return null;
        return this._sortColumnCell.columnIdentifier;
    },

    /**
     * @return {?string}
     */
    get sortOrder()
    {
        if (!this._sortColumnCell || this._sortColumnCell.hasStyleClass("sort-ascending"))
            return "ascending";
        if (this._sortColumnCell.hasStyleClass("sort-descending"))
            return "descending";
        return null;
    },

    get headerTableBody()
    {
        if ("_headerTableBody" in this)
            return this._headerTableBody;

        this._headerTableBody = this._headerTable.getElementsByTagName("tbody")[0];
        if (!this._headerTableBody) {
            this._headerTableBody = this.element.ownerDocument.createElement("tbody");
            this._headerTable.insertBefore(this._headerTableBody, this._headerTable.tFoot);
        }

        return this._headerTableBody;
    },

    get dataTableBody()
    {
        if ("_dataTableBody" in this)
            return this._dataTableBody;

        this._dataTableBody = this._dataTable.getElementsByTagName("tbody")[0];
        if (!this._dataTableBody) {
            this._dataTableBody = this.element.ownerDocument.createElement("tbody");
            this._dataTable.insertBefore(this._dataTableBody, this._dataTable.tFoot);
        }

        return this._dataTableBody;
    },

    /**
     * @param {number=} maxDescentLevel
     */
    autoSizeColumns: function(minPercent, maxPercent, maxDescentLevel)
    {
        if (minPercent)
            minPercent = Math.min(minPercent, Math.floor(100 / this._columnCount));
        var widths = {};
        var columns = this.columns;
        for (var columnIdentifier in columns)
            widths[columnIdentifier] = (columns[columnIdentifier].title || "").length;

        maxDescentLevel = maxDescentLevel || 0;
        var children = this._enumerateChildren(this._rootNode, [], maxDescentLevel + 1);
        for (var i = 0; i < children.length; ++i) {
            var node = children[i];
            for (var columnIdentifier in columns) {
                var text = node.data[columnIdentifier] || "";
                if (text.length > widths[columnIdentifier])
                    widths[columnIdentifier] = text.length;
            }
        }

        var totalColumnWidths = 0;
        for (var columnIdentifier in columns)
            totalColumnWidths += widths[columnIdentifier];

        var recoupPercent = 0;
        for (var columnIdentifier in columns) {
            var width = Math.round(100 * widths[columnIdentifier] / totalColumnWidths);
            if (minPercent && width < minPercent) {
                recoupPercent += (minPercent - width);
                width = minPercent;
            } else if (maxPercent && width > maxPercent) {
                recoupPercent -= (width - maxPercent);
                width = maxPercent;
            }
            widths[columnIdentifier] = width;
        }

        while (minPercent && recoupPercent > 0) {
            for (var columnIdentifier in columns) {
                if (widths[columnIdentifier] > minPercent) {
                    --widths[columnIdentifier];
                    --recoupPercent;
                    if (!recoupPercent)
                        break;
                }
            }
        }

        while (maxPercent && recoupPercent < 0) {
            for (var columnIdentifier in columns) {
                if (widths[columnIdentifier] < maxPercent) {
                    ++widths[columnIdentifier];
                    ++recoupPercent;
                    if (!recoupPercent)
                        break;
                }
            }
        }

        for (var columnIdentifier in columns)
            columns[columnIdentifier].element.style.width = widths[columnIdentifier] + "%";
        this._columnWidthsInitialized = false;
        this.updateWidths();
    },

    _enumerateChildren: function(rootNode, result, maxLevel)
    {
        if (!rootNode._isRoot)
            result.push(rootNode);
        if (!maxLevel)
            return;
        for (var i = 0; i < rootNode.children.length; ++i)
            this._enumerateChildren(rootNode.children[i], result, maxLevel - 1);
        return result;
    },

    onResize: function()
    {
        this.updateWidths();
    },

    // Updates the widths of the table, including the positions of the column
    // resizers.
    //
    // IMPORTANT: This function MUST be called once after the element of the
    // DataGrid is attached to its parent element and every subsequent time the
    // width of the parent element is changed in order to make it possible to
    // resize the columns.
    //
    // If this function is not called after the DataGrid is attached to its
    // parent element, then the DataGrid's columns will not be resizable.
updateWidths: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;

var tableWidth = this._dataTable.offsetWidth;
var numColumns = headerTableColumns.length;


if (!this._columnWidthsInitialized && this.element.offsetWidth) {




for (var i = 0; i < numColumns; i++) {
var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWidth;
var percentWidth = ((columnWidth / tableWidth) * 100) + "%";
this._headerTableColumnGroup.children[i].style.width = percentWidth;
this._dataTableColumnGroup.children[i].style.width = percentWidth;
}
this._columnWidthsInitialized = true;
}
this._positionResizers();
this.dispatchEventToListeners("width changed");
},

columnWidthsMap: function()
{
var result = {};
for (var i = 0; i < this._columnsArray.length; ++i) {
var width = this._headerTableColumnGroup.children[i].style.width;
result[this._columnsArray[i].columnIdentifier] = parseFloat(width);
}
return result;
},

applyColumnWidthsMap: function(columnWidthsMap)
{
for (var columnIdentifier in this.columns) {
var column = this.columns[columnIdentifier];
var width = (columnWidthsMap[columnIdentifier] || 0) + "%";
this._headerTableColumnGroup.children[column.ordinal].style.width = width;
this._dataTableColumnGroup.children[column.ordinal].style.width = width;
}


delete this._columnWidthsInitialized;
this.updateWidths();
},

isColumnVisible: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
return !columnElement.hidden;
},

showColumn: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
if (!columnElement.hidden)
return;

columnElement.hidden = false;
columnElement.removeStyleClass("hidden");

var columnBodyElement = column.bodyElement;
columnBodyElement.hidden = false;
columnBodyElement.removeStyleClass("hidden");
},

hideColumn: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
if (columnElement.hidden)
return;

var oldWidth = parseFloat(columnElement.style.width);

columnElement.hidden = true;
columnElement.addStyleClass("hidden");
columnElement.style.width = 0;

var columnBodyElement = column.bodyElement;
columnBodyElement.hidden = true;
columnBodyElement.addStyleClass("hidden");
columnBodyElement.style.width = 0;

this._columnWidthsInitialized = false;
},

get scrollContainer()
{
return this._scrollContainer;
},

isScrolledToLastRow: function()
{
return this._scrollContainer.isScrolledToBottom();
},

scrollToLastRow: function()
{
this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight;
},

_positionResizers: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;
var numColumns = headerTableColumns.length;
var left = 0;
var previousResizer = null;


for (var i = 0; i < numColumns - 1; i++) {
var resizer = this.resizers[i];

if (!resizer) {


resizer = document.createElement("div");
resizer.addStyleClass("data-grid-resizer");

WebInspector.installDragHandle(resizer, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "col-resize");
this.element.appendChild(resizer);
this.resizers[i] = resizer;
}




left += this.headerTableBody.rows[0].cells[i].offsetWidth;

var columnIsVisible = !this._headerTableColumnGroup.children[i].hidden;
if (columnIsVisible) {
resizer.style.removeProperty("display");
resizer.style.left = left + "px";
resizer.leftNeighboringColumnID = i;
if (previousResizer)
previousResizer.rightNeighboringColumnID = i;
previousResizer = resizer;
} else {
resizer.style.setProperty("display", "none");
resizer.leftNeighboringColumnID = 0;
resizer.rightNeighboringColumnID = 0;
}
}
if (previousResizer)
previousResizer.rightNeighboringColumnID = numColumns - 1;
},

addCreationNode: function(hasChildren)
{
if (this.creationNode)
this.creationNode.makeNormal();

var emptyData = {};
for (var column in this.columns)
emptyData[column] = '';
this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren);
this.rootNode().appendChild(this.creationNode);
},

sortNodes: function(comparator, reverseMode)
{
function comparatorWrapper(a, b)
{
if (a._dataGridNode._data.summaryRow)
return 1;
if (b._dataGridNode._data.summaryRow)
return -1;

var aDataGirdNode = a._dataGridNode;
var bDataGirdNode = b._dataGridNode;
return reverseMode ? comparator(bDataGirdNode, aDataGirdNode) : comparator(aDataGirdNode, bDataGirdNode);
}

var tbody = this.dataTableBody;
var tbodyParent = tbody.parentElement;
tbodyParent.removeChild(tbody);

var childNodes = tbody.childNodes;
var fillerRow = childNodes[childNodes.length - 1];

var sortedRows = Array.prototype.slice.call(childNodes, 0, childNodes.length - 1);
sortedRows.sort(comparatorWrapper);
var sortedRowsLength = sortedRows.length;

tbody.removeChildren();
var previousSiblingNode = null;
for (var i = 0; i < sortedRowsLength; ++i) {
var row = sortedRows[i];
var node = row._dataGridNode;
node.previousSibling = previousSiblingNode;
if (previousSiblingNode)
previousSiblingNode.nextSibling = node;
tbody.appendChild(row);
previousSiblingNode = node;
}
if (previousSiblingNode)
previousSiblingNode.nextSibling = null;

tbody.appendChild(fillerRow);
tbodyParent.appendChild(tbody);
},

_keyDown: function(event)
{
if (!this.selectedNode || event.shiftKey || event.metaKey || event.ctrlKey || this._editing)
return;

var handled = false;
var nextSelectedNode;
if (event.keyIdentifier === "Up" && !event.altKey) {
nextSelectedNode = this.selectedNode.traversePreviousNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traversePreviousNode(true);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Down" && !event.altKey) {
nextSelectedNode = this.selectedNode.traverseNextNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traverseNextNode(true);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Left") {
if (this.selectedNode.expanded) {
if (event.altKey)
this.selectedNode.collapseRecursively();
else
this.selectedNode.collapse();
handled = true;
} else if (this.selectedNode.parent && !this.selectedNode.parent._isRoot) {
handled = true;
if (this.selectedNode.parent.selectable) {
nextSelectedNode = this.selectedNode.parent;
handled = nextSelectedNode ? true : false;
} else if (this.selectedNode.parent)
this.selectedNode.parent.collapse();
}
} else if (event.keyIdentifier === "Right") {
if (!this.selectedNode.revealed) {
this.selectedNode.reveal();
handled = true;
} else if (this.selectedNode.hasChildren) {
handled = true;
if (this.selectedNode.expanded) {
nextSelectedNode = this.selectedNode.children[0];
handled = nextSelectedNode ? true : false;
} else {
if (event.altKey)
this.selectedNode.expandRecursively();
else
this.selectedNode.expand();
}
}
} else if (event.keyCode === 8 || event.keyCode === 46) {
if (this._deleteCallback) {
handled = true;
this._deleteCallback(this.selectedNode);
}
} else if (isEnterKey(event)) {
if (this._editCallback) {
handled = true;


this._startEditing(this.selectedNode._element.children[0]);
}
}

if (nextSelectedNode) {
nextSelectedNode.reveal();
nextSelectedNode.select();
}

if (handled)
event.consume(true);
},

dataGridNodeFromNode: function(target)
{
var rowElement = target.enclosingNodeOrSelfWithNodeName("tr");
return rowElement && rowElement._dataGridNode;
},

dataGridNodeFromPoint: function(x, y)
{
var node = this._dataTable.ownerDocument.elementFromPoint(x, y);
var rowElement = node.enclosingNodeOrSelfWithNodeName("tr");
return rowElement && rowElement._dataGridNode;
},

_clickInHeaderCell: function(event)
{
var cell = event.target.enclosingNodeOrSelfWithNodeName("th");
if (!cell || !cell.columnIdentifier || !cell.hasStyleClass("sortable"))
return;

var sortOrder = this.sortOrder;

if (this._sortColumnCell)
this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");

if (cell == this._sortColumnCell) {
if (sortOrder === "ascending")
sortOrder = "descending";
else
sortOrder = "ascending";
}

this._sortColumnCell = cell;

cell.addStyleClass("sort-" + sortOrder);

this.dispatchEventToListeners("sorting changed");
},

markColumnAsSortedBy: function(columnIdentifier, sortOrder)
{
if (this._sortColumnCell)
this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");
this._sortColumnCell = this._headerTableHeaders[columnIdentifier];
this._sortColumnCell.addStyleClass("sort-" + sortOrder);
},

headerTableHeader: function(columnIdentifier)
{
return this._headerTableHeaders[columnIdentifier];
},

_mouseDownInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.selectable)
return;

if (gridNode.isEventWithinDisclosureTriangle(event))
return;

if (event.metaKey) {
if (gridNode.selected)
gridNode.deselect();
else
gridNode.select();
} else
gridNode.select();
},

_contextMenuInDataTable: function(event)
{
var contextMenu = new WebInspector.ContextMenu();

var gridNode = this.dataGridNodeFromNode(event.target);
if (this._refreshCallback && (!gridNode || gridNode !== this.creationNode))
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._refreshCallback.bind(this));

if (gridNode && gridNode.selectable && !gridNode.isEventWithinDisclosureTriangle(event)) {

if (this._editCallback) {
if (gridNode === this.creationNode)
contextMenu.appendItem(WebInspector.UIString("Add New"), this._startEditing.bind(this, event.target));
else
contextMenu.appendItem(WebInspector.UIString("Edit"), this._startEditing.bind(this, event.target));
}
if (this._deleteCallback && gridNode !== this.creationNode)
contextMenu.appendItem(WebInspector.UIString("Delete"), this._deleteCallback.bind(this, gridNode));
}

contextMenu.show(event);
},

_clickInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.hasChildren)
return;

if (!gridNode.isEventWithinDisclosureTriangle(event))
return;

if (gridNode.expanded) {
if (event.altKey)
gridNode.collapseRecursively();
else
gridNode.collapse();
} else {
if (event.altKey)
gridNode.expandRecursively();
else
gridNode.expand();
}
},

get resizeMethod()
{
if (typeof this._resizeMethod === "undefined")
return WebInspector.DataGrid.ResizeMethod.Nearest;
return this._resizeMethod;
},

set resizeMethod(method)
{
this._resizeMethod = method;
},


_startResizerDragging: function(event)
{
this._currentResizer = event.target;
return !!this._currentResizer.rightNeighboringColumnID
},

_resizerDragging: function(event)
{
var resizer = this._currentResizer;
if (!resizer)
return;



var dragPoint = event.clientX - this.element.totalOffsetLeft();


var leftCellIndex = resizer.leftNeighboringColumnID;
var rightCellIndex = resizer.rightNeighboringColumnID;
var firstRowCells = this.headerTableBody.rows[0].cells;
var leftEdgeOfPreviousColumn = 0;
for (var i = 0; i < leftCellIndex; i++)
leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;


if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.Last) {
rightCellIndex = this.resizers.length;
} else if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.First) {
leftEdgeOfPreviousColumn += firstRowCells[leftCellIndex].offsetWidth - firstRowCells[0].offsetWidth;
leftCellIndex = 0;
}

var rightEdgeOfNextColumn = leftEdgeOfPreviousColumn + firstRowCells[leftCellIndex].offsetWidth + firstRowCells[rightCellIndex].offsetWidth;


var leftMinimum = leftEdgeOfPreviousColumn + this.ColumnResizePadding;
var rightMaximum = rightEdgeOfNextColumn - this.ColumnResizePadding;

dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);

resizer.style.left = (dragPoint - this.CenterResizerOverBorderAdjustment) + "px";

var percentLeftColumn = (((dragPoint - leftEdgeOfPreviousColumn) / this._dataTable.offsetWidth) * 100) + "%";
this._headerTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;
this._dataTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;

var percentRightColumn = (((rightEdgeOfNextColumn - dragPoint) / this._dataTable.offsetWidth) * 100) + "%";
this._headerTableColumnGroup.children[rightCellIndex].style.width =  percentRightColumn;
this._dataTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn;

this._positionResizers();
event.preventDefault();
this.dispatchEventToListeners("width changed");
},

_endResizerDragging: function(event)
{
this._currentResizer = null;
this.dispatchEventToListeners("width changed");
},

ColumnResizePadding: 10,

CenterResizerOverBorderAdjustment: 3,
}

WebInspector.DataGrid.ResizeMethod = {
Nearest: "nearest",
First: "first",
Last: "last"
}

WebInspector.DataGrid.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.DataGridNode = function(data, hasChildren)
{
this._expanded = false;
this._selected = false;
this._shouldRefreshChildren = true;
this._data = data || {};
this.hasChildren = hasChildren || false;
this.children = [];
this.dataGrid = null;
this.parent = null;
this.previousSibling = null;
this.nextSibling = null;
this.disclosureToggleWidth = 10;
}

WebInspector.DataGridNode.prototype = {
selectable: true,

_isRoot: false,

get element()
{
if (this._element)
return this._element;

if (!this.dataGrid)
return null;

this._element = document.createElement("tr");
this._element._dataGridNode = this;

if (this.hasChildren)
this._element.addStyleClass("parent");
if (this.expanded)
this._element.addStyleClass("expanded");
if (this.selected)
this._element.addStyleClass("selected");
if (this.revealed)
this._element.addStyleClass("revealed");

this.createCells();
return this._element;
},

createCells: function()
{
for (var columnIdentifier in this.dataGrid.columns) {
var cell = this.createCell(columnIdentifier);
this._element.appendChild(cell);
}
},

get data()
{
return this._data;
},

set data(x)
{
this._data = x || {};
this.refresh();
},

get revealed()
{
if ("_revealed" in this)
return this._revealed;

var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor._isRoot) {
if (!currentAncestor.expanded) {
this._revealed = false;
return false;
}

currentAncestor = currentAncestor.parent;
}

this._revealed = true;
return true;
},

set hasChildren(x)
{
if (this._hasChildren === x)
return;

this._hasChildren = x;

if (!this._element)
return;

if (this._hasChildren)
{
this._element.addStyleClass("parent");
if (this.expanded)
this._element.addStyleClass("expanded");
}
else
{
this._element.removeStyleClass("parent");
this._element.removeStyleClass("expanded");
}
},

get hasChildren()
{
return this._hasChildren;
},

set revealed(x)
{
if (this._revealed === x)
return;

this._revealed = x;

if (this._element) {
if (this._revealed)
this._element.addStyleClass("revealed");
else
this._element.removeStyleClass("revealed");
}

for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = x && this.expanded;
},

get depth()
{
if ("_depth" in this)
return this._depth;
if (this.parent && !this.parent._isRoot)
this._depth = this.parent.depth + 1;
else
this._depth = 0;
return this._depth;
},

get leftPadding()
{
if (typeof(this._leftPadding) === "number")
return this._leftPadding;

this._leftPadding = this.depth * this.dataGrid.indentWidth;
return this._leftPadding;
},

get shouldRefreshChildren()
{
return this._shouldRefreshChildren;
},

set shouldRefreshChildren(x)
{
this._shouldRefreshChildren = x;
if (x && this.expanded)
this.expand();
},

get selected()
{
return this._selected;
},

set selected(x)
{
if (x)
this.select();
else
this.deselect();
},

get expanded()
{
return this._expanded;
},

set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},

refresh: function()
{
if (!this._element || !this.dataGrid)
return;

this._element.removeChildren();
this.createCells();
},

createCell: function(columnIdentifier)
{
var cell = document.createElement("td");
cell.className = columnIdentifier + "-column";

var alignment = this.dataGrid.aligned[columnIdentifier];
if (alignment)
cell.addStyleClass(alignment);

var div = document.createElement("div");
div.textContent = this.data[columnIdentifier];
cell.appendChild(div);

if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
cell.addStyleClass("disclosure");
if (this.leftPadding)
cell.style.setProperty("padding-left", this.leftPadding + "px");
}

return cell;
},


nodeHeight: function()
{
var rowHeight = 16;
if (!this.revealed)
return 0;
if (!this.expanded)
return rowHeight;
var result = rowHeight;
for (var i = 0; i < this.children.length; i++)
result += this.children[i].nodeHeight();
return result;
},


appendChild: function(child)
{
this.insertChild(child, this.children.length);
},


insertChild: function(child, index)
{
if (!child)
throw("insertChild: Node can't be undefined or null.");
if (child.parent === this)
throw("insertChild: Node is already a child of this node.");

if (child.parent)
child.parent.removeChild(child);

this.children.splice(index, 0, child);
this.hasChildren = true;

child.parent = this;
child.dataGrid = this.dataGrid;
child._recalculateSiblings(index);

delete child._depth;
delete child._revealed;
delete child._attached;
child._shouldRefreshChildren = true;

var current = child.children[0];
while (current) {
current.dataGrid = this.dataGrid;
delete current._depth;
delete current._revealed;
delete current._attached;
current._shouldRefreshChildren = true;
current = current.traverseNextNode(false, child, true);
}

if (this.expanded)
child._attach();
if (!this.revealed)
child.revealed = false;
},


removeChild: function(child)
{
if (!child)
throw("removeChild: Node can't be undefined or null.");
if (child.parent !== this)
throw("removeChild: Node is not a child of this node.");

child.deselect();
child._detach();

this.children.remove(child, true);

if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;

child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;

if (this.children.length <= 0)
this.hasChildren = false;
},

removeChildren: function()
{
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
child.deselect();
child._detach();

child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}

this.children = [];
this.hasChildren = false;
},

_recalculateSiblings: function(myIndex)
{
if (!this.parent)
return;

var previousChild = (myIndex > 0 ? this.parent.children[myIndex - 1] : null);

if (previousChild) {
previousChild.nextSibling = this;
this.previousSibling = previousChild;
} else
this.previousSibling = null;

var nextChild = this.parent.children[myIndex + 1];

if (nextChild) {
nextChild.previousSibling = this;
this.nextSibling = nextChild;
} else
this.nextSibling = null;
},

collapse: function()
{
if (this._isRoot)
return;
if (this._element)
this._element.removeStyleClass("expanded");

this._expanded = false;

for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = false;

this.dispatchEventToListeners("collapsed");
},

collapseRecursively: function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextNode(false, this, true);
}
},

expand: function()
{
if (!this.hasChildren || this.expanded)
return;
if (this._isRoot)
return;

if (this.revealed && !this._shouldRefreshChildren)
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = true;

if (this._shouldRefreshChildren) {
for (var i = 0; i < this.children.length; ++i)
this.children[i]._detach();

this.dispatchEventToListeners("populate");

if (this._attached) {
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
if (this.revealed)
child.revealed = true;
child._attach();
}
}

delete this._shouldRefreshChildren;
}

if (this._element)
this._element.addStyleClass("expanded");

this._expanded = true;

this.dispatchEventToListeners("expanded");
},

expandRecursively: function()
{
var item = this;
while (item) {
item.expand();
item = item.traverseNextNode(false, this);
}
},

reveal: function()
{
if (this._isRoot)
return;
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor._isRoot) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}

this.element.scrollIntoViewIfNeeded(false);

this.dispatchEventToListeners("revealed");
},


select: function(supressSelectedEvent)
{
if (!this.dataGrid || !this.selectable || this.selected)
return;

if (this.dataGrid.selectedNode)
this.dataGrid.selectedNode.deselect();

this._selected = true;
this.dataGrid.selectedNode = this;

if (this._element)
this._element.addStyleClass("selected");

if (!supressSelectedEvent) {
this.dispatchEventToListeners("selected");
this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.SelectedNode);
}
},

revealAndSelect: function()
{
if (this._isRoot)
return;
this.reveal();
this.select();
},


deselect: function(supressDeselectedEvent)
{
if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected)
return;

this._selected = false;
this.dataGrid.selectedNode = null;

if (this._element)
this._element.removeStyleClass("selected");

if (!supressDeselectedEvent) {
this.dispatchEventToListeners("deselected");
this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.DeselectedNode);
}
},

traverseNextNode: function(skipHidden, stayWithin, dontPopulate, info)
{
if (!dontPopulate && this.hasChildren)
this.dispatchEventToListeners("populate");

if (info)
info.depthChange = 0;

var node = (!skipHidden || this.revealed) ? this.children[0] : null;
if (node && (!skipHidden || this.expanded)) {
if (info)
info.depthChange = 1;
return node;
}

if (this === stayWithin)
return null;

node = (!skipHidden || this.revealed) ? this.nextSibling : null;
if (node)
return node;

node = this;
while (node && !node._isRoot && !((!skipHidden || node.revealed) ? node.nextSibling : null) && node.parent !== stayWithin) {
if (info)
info.depthChange -= 1;
node = node.parent;
}

if (!node)
return null;

return (!skipHidden || node.revealed) ? node.nextSibling : null;
},

traversePreviousNode: function(skipHidden, dontPopulate)
{
var node = (!skipHidden || this.revealed) ? this.previousSibling : null;
if (!dontPopulate && node && node.hasChildren)
node.dispatchEventToListeners("populate");

while (node && ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null)) {
if (!dontPopulate && node.hasChildren)
node.dispatchEventToListeners("populate");
node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null);
}

if (node)
return node;

if (!this.parent || this.parent._isRoot)
return null;

return this.parent;
},

isEventWithinDisclosureTriangle: function(event)
{
if (!this.hasChildren)
return false;
var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!cell.hasStyleClass("disclosure"))
return false;

var left = cell.totalOffsetLeft() + this.leftPadding;
return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth;
},

_attach: function()
{
if (!this.dataGrid || this._attached)
return;

this._attached = true;

var nextNode = null;
var previousNode = this.traversePreviousNode(true, true);
if (previousNode && previousNode.element.parentNode && previousNode.element.nextSibling)
nextNode = previousNode.element.nextSibling;
if (!nextNode)
nextNode = this.dataGrid.dataTableBody.firstChild;
this.dataGrid.dataTableBody.insertBefore(this.element, nextNode);

if (this.expanded)
for (var i = 0; i < this.children.length; ++i)
this.children[i]._attach();
},

_detach: function()
{
if (!this._attached)
return;

this._attached = false;

if (this._element && this._element.parentNode)
this._element.parentNode.removeChild(this._element);

for (var i = 0; i < this.children.length; ++i)
this.children[i]._detach();

this.wasDetached();
},

wasDetached: function()
{
},

savePosition: function()
{
if (this._savedPosition)
return;

if (!this.parent)
throw("savePosition: Node must have a parent.");
this._savedPosition = {
parent: this.parent,
index: this.parent.children.indexOf(this)
};
},

restorePosition: function()
{
if (!this._savedPosition)
return;

if (this.parent !== this._savedPosition.parent)
this._savedPosition.parent.insertChild(this, this._savedPosition.index);

delete this._savedPosition;
}
}

WebInspector.DataGridNode.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.CreationDataGridNode = function(data, hasChildren)
{
WebInspector.DataGridNode.call(this, data, hasChildren);
this.isCreationNode = true;
}

WebInspector.CreationDataGridNode.prototype = {
makeNormal: function()
{
delete this.isCreationNode;
delete this.makeNormal;
}
}

WebInspector.CreationDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;






WebInspector.ShowMoreDataGridNode = function(callback, startPosition, endPosition, chunkSize)
{
WebInspector.DataGridNode.call(this, {summaryRow:true}, false);
this._callback = callback;
this._startPosition = startPosition;
this._endPosition = endPosition;
this._chunkSize = chunkSize;

this.showNext = document.createElement("button");
this.showNext.setAttribute("type", "button");
this.showNext.addEventListener("click", this._showNextChunk.bind(this), false);
this.showNext.textContent = WebInspector.UIString("Show %d before", this._chunkSize);

this.showAll = document.createElement("button");
this.showAll.setAttribute("type", "button");
this.showAll.addEventListener("click", this._showAll.bind(this), false);

this.showLast = document.createElement("button");
this.showLast.setAttribute("type", "button");
this.showLast.addEventListener("click", this._showLastChunk.bind(this), false);
this.showLast.textContent = WebInspector.UIString("Show %d after", this._chunkSize);

this._updateLabels();
this.selectable = false;
}

WebInspector.ShowMoreDataGridNode.prototype = {
_showNextChunk: function()
{
this._callback(this._startPosition, this._startPosition + this._chunkSize);
},

_showAll: function()
{
this._callback(this._startPosition, this._endPosition);
},

_showLastChunk: function()
{
this._callback(this._endPosition - this._chunkSize, this._endPosition);
},

_updateLabels: function()
{
var totalSize = this._endPosition - this._startPosition;
if (totalSize > this._chunkSize) {
this.showNext.removeStyleClass("hidden");
this.showLast.removeStyleClass("hidden");
} else {
this.showNext.addStyleClass("hidden");
this.showLast.addStyleClass("hidden");
}
this.showAll.textContent = WebInspector.UIString("Show all %d", totalSize);
},

createCells: function()
{
var cell = document.createElement("td");
if (this.depth)
cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
cell.appendChild(this.showNext);
cell.appendChild(this.showAll);
cell.appendChild(this.showLast);
this._element.appendChild(cell);

var columns = this.dataGrid.columns;
var count = 0;
for (var c in columns)
++count;
while (--count > 0) {
cell = document.createElement("td");
this._element.appendChild(cell);
}
},


setStartPosition: function(from)
{
this._startPosition = from;
this._updateLabels();
},


setEndPosition: function(to)
{
this._endPosition = to;
this._updateLabels();
},


nodeHeight: function()
{
return 32;
},

dispose: function()
{
}
};

WebInspector.ShowMoreDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;






WebInspector.CookiesTable = function(cookieDomain, expandable, deleteCallback, refreshCallback)
{
WebInspector.View.call(this);
this.element.className = "fill";

this._cookieDomain = cookieDomain;

var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} };
columns[0].title = WebInspector.UIString("Name");
columns[0].sortable = true;
columns[0].disclosure = expandable;
columns[0].width = "24%";
columns[1].title = WebInspector.UIString("Value");
columns[1].sortable = true;
columns[1].width = "34%";
columns[2].title = WebInspector.UIString("Domain");
columns[2].sortable = true;
columns[2].width = "7%";
columns[3].title = WebInspector.UIString("Path");
columns[3].sortable = true;
columns[3].width = "7%";
columns[4].title = WebInspector.UIString("Expires");
columns[4].sortable = true;
columns[4].width = "7%";
columns[5].title = WebInspector.UIString("Size");
columns[5].aligned = "right";
columns[5].sortable = true;
columns[5].width = "7%";
columns[6].title = WebInspector.UIString("HTTP");
columns[6].aligned = "centered";
columns[6].sortable = true;
columns[6].width = "7%";
columns[7].title = WebInspector.UIString("Secure");
columns[7].aligned = "centered";
columns[7].sortable = true;
columns[7].width = "7%";

this._dataGrid = new WebInspector.DataGrid(columns, undefined, deleteCallback ? this._onDeleteFromGrid.bind(this, deleteCallback) : undefined);
this._dataGrid.addEventListener("sorting changed", this._rebuildTable, this);
this._dataGrid.refreshCallback = refreshCallback;

this._dataGrid.show(this.element);
this._data = [];
}

WebInspector.CookiesTable.prototype = {
updateWidths: function()
{
if (this._dataGrid)
this._dataGrid.updateWidths();
},

setCookies: function(cookies)
{
this._data = [{cookies: cookies}];
this._rebuildTable();
},

addCookiesFolder: function(folderName, cookies)
{
this._data.push({cookies: cookies, folderName: folderName});
this._rebuildTable();
},

get selectedCookie()
{
var node = this._dataGrid.selectedNode;
return node ? node.cookie : null;
},

_rebuildTable: function()
{
this._dataGrid.rootNode().removeChildren();
for (var i = 0; i < this._data.length; ++i) {
var item = this._data[i];
if (item.folderName) {
var groupData = [ item.folderName, "", "", "", "", this._totalSize(item.cookies), "", "" ];
var groupNode = new WebInspector.DataGridNode(groupData);
groupNode.selectable = true;
this._dataGrid.rootNode().appendChild(groupNode);
groupNode.element.addStyleClass("row-group");
this._populateNode(groupNode, item.cookies);
groupNode.expand();
} else
this._populateNode(this._dataGrid.rootNode(), item.cookies);
}
},


_populateNode: function(parentNode, cookies)
{
var selectedCookie = this.selectedCookie;
parentNode.removeChildren();
if (!cookies)
return;

this._sortCookies(cookies);
for (var i = 0; i < cookies.length; ++i) {
var cookieNode = this._createGridNode(cookies[i]);
parentNode.appendChild(cookieNode);
if (selectedCookie === cookies[i])
cookieNode.selected = true;
}
},

_totalSize: function(cookies)
{
var totalSize = 0;
for (var i = 0; cookies && i < cookies.length; ++i)
totalSize += cookies[i].size;
return totalSize;
},

_sortCookies: function(cookies)
{
var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1;

function localeCompare(field, cookie1, cookie2)
{
return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "")
}

function numberCompare(field, cookie1, cookie2)
{
return sortDirection * (cookie1[field] - cookie2[field]);
}

function expiresCompare(cookie1, cookie2)
{
if (cookie1.session !== cookie2.session)
return sortDirection * (cookie1.session ? 1 : -1);

if (cookie1.session)
return 0;

return sortDirection * (cookie1.expires - cookie2.expires);
}

var comparator;
switch (parseInt(this._dataGrid.sortColumnIdentifier, 10)) {
case 0: comparator = localeCompare.bind(this, "name"); break;
case 1: comparator = localeCompare.bind(this, "value"); break;
case 2: comparator = localeCompare.bind(this, "domain"); break;
case 3: comparator = localeCompare.bind(this, "path"); break;
case 4: comparator = expiresCompare; break;
case 5: comparator = numberCompare.bind(this, "size"); break;
case 6: comparator = localeCompare.bind(this, "httpOnly"); break;
case 7: comparator = localeCompare.bind(this, "secure"); break;
default: localeCompare.bind(this, "name");
}

cookies.sort(comparator);
},


_createGridNode: function(cookie)
{
var data = {};
data[0] = cookie.name;
data[1] = cookie.value;
data[2] = cookie.domain || "";
data[3] = cookie.path || "";
data[4] = cookie.type === WebInspector.Cookie.Type.Request ? "" :
(cookie.session ? WebInspector.UIString("Session") : new Date(cookie.expires).toGMTString());
data[5] = cookie.size;
const checkmark = "\u2713";
data[6] = (cookie.httpOnly ? checkmark : "");
data[7] = (cookie.secure ? checkmark : "");

var node = new WebInspector.DataGridNode(data);
node.cookie = cookie;
node.selectable = true;
return node;
},

_onDeleteFromGrid: function(deleteCallback, node)
{
deleteCallback(node.cookie);
}
}

WebInspector.CookiesTable.prototype.__proto__ = WebInspector.View.prototype;






WebInspector.CookieItemsView = function(treeElement, cookieDomain)
{
WebInspector.View.call(this);

this.element.addStyleClass("storage-view");

this._deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
this._deleteButton.visible = false;
this._deleteButton.addEventListener("click", this._deleteButtonClicked, this);

this._refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
this._refreshButton.addEventListener("click", this._refreshButtonClicked, this);

this._treeElement = treeElement;
this._cookieDomain = cookieDomain;

this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This site has no cookies."));
this._emptyView.show(this.element);

this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
}

WebInspector.CookieItemsView.prototype = {
get statusBarItems()
{
return [this._refreshButton.element, this._deleteButton.element];
},

wasShown: function()
{
this._update();
},

willHide: function()
{
this._deleteButton.visible = false;
},

_update: function()
{
WebInspector.Cookies.getCookiesAsync(this._updateWithCookies.bind(this));
},

_updateWithCookies: function(allCookies, isAdvanced)
{
this._cookies = isAdvanced ? this._filterCookiesForDomain(allCookies) : allCookies;

if (!this._cookies.length) {

this._emptyView.show(this.element);
this._deleteButton.visible = false;
if (this._cookiesTable)
this._cookiesTable.detach();
return;
}

if (!this._cookiesTable)
this._cookiesTable = isAdvanced ? new WebInspector.CookiesTable(this._cookieDomain, false, this._deleteCookie.bind(this), this._update.bind(this)) : new WebInspector.SimpleCookiesTable();

this._cookiesTable.setCookies(this._cookies);
this._emptyView.detach();
this._cookiesTable.show(this.element);
if (isAdvanced) {
this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length,
Number.bytesToString(this._totalSize));
this._deleteButton.visible = true;
}
},

_filterCookiesForDomain: function(allCookies)
{
var cookies = [];
var resourceURLsForDocumentURL = [];
this._totalSize = 0;

function populateResourcesForDocuments(resource)
{
var url = resource.documentURL.asParsedURL();
if (url && url.host == this._cookieDomain)
resourceURLsForDocumentURL.push(resource.url);
}
WebInspector.forAllResources(populateResourcesForDocuments.bind(this));

for (var i = 0; i < allCookies.length; ++i) {
var pushed = false;
var size = allCookies[i].size;
for (var j = 0; j < resourceURLsForDocumentURL.length; ++j) {
var resourceURL = resourceURLsForDocumentURL[j];
if (WebInspector.Cookies.cookieMatchesResourceURL(allCookies[i], resourceURL)) {
this._totalSize += size;
if (!pushed) {
pushed = true;
cookies.push(allCookies[i]);
}
}
}
}
return cookies;
},

_deleteCookie: function(cookie)
{
PageAgent.deleteCookie(cookie.name, this._cookieDomain);
this._update();
},

_deleteButtonClicked: function()
{
if (this._cookiesTable.selectedCookie)
this._deleteCookie(this._cookiesTable.selectedCookie);
},

_refreshButtonClicked: function(event)
{
this._update();
},

_contextMenu: function(event)
{
if (!this._cookies.length) {
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._update.bind(this));
contextMenu.show(event);
}
}
}

WebInspector.CookieItemsView.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.SimpleCookiesTable = function()
{
WebInspector.View.call(this);

var columns = {};
columns[0] = {};
columns[1] = {};
columns[0].title = WebInspector.UIString("Name");
columns[1].title = WebInspector.UIString("Value");

this._dataGrid = new WebInspector.DataGrid(columns);
this._dataGrid.autoSizeColumns(20, 80);
this._dataGrid.show(this.element);
}

WebInspector.SimpleCookiesTable.prototype = {
setCookies: function(cookies)
{
this._dataGrid.rootNode().removeChildren();
var addedCookies = {};
for (var i = 0; i < cookies.length; ++i) {
if (addedCookies[cookies[i].name])
continue;
addedCookies[cookies[i].name] = true;
var data = {};
data[0] = cookies[i].name;
data[1] = cookies[i].value;

var node = new WebInspector.DataGridNode(data, false);
node.selectable = true;
this._dataGrid.rootNode().appendChild(node);
}
this._dataGrid.rootNode().children[0].selected = true;
}
}

WebInspector.SimpleCookiesTable.prototype.__proto__ = WebInspector.View.prototype;

WebInspector.Cookies = {}

WebInspector.Cookies.getCookiesAsync = function(callback)
{
function mycallback(error, cookies, cookiesString)
{
if (error)
return;
if (cookiesString)
callback(WebInspector.Cookies.buildCookiesFromString(cookiesString), false);
else
callback(cookies, true);
}

PageAgent.getCookies(mycallback);
}

WebInspector.Cookies.buildCookiesFromString = function(rawCookieString)
{
var rawCookies = rawCookieString.split(/;\s*/);
var cookies = [];

if (!(/^\s*$/.test(rawCookieString))) {
for (var i = 0; i < rawCookies.length; ++i) {
var cookie = rawCookies[i];
var delimIndex = cookie.indexOf("=");
var name = cookie.substring(0, delimIndex);
var value = cookie.substring(delimIndex + 1);
var size = name.length + value.length;
cookies.push({ name: name, value: value, size: size });
}
}

return cookies;
}

WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL)
{
var url = resourceURL.asParsedURL();
if (!url || !WebInspector.Cookies.cookieDomainMatchesResourceDomain(cookie.domain, url.host))
return false;
return (url.path.startsWith(cookie.path)
&& (!cookie.port || url.port == cookie.port)
&& (!cookie.secure || url.scheme === "https"));
}

WebInspector.Cookies.cookieDomainMatchesResourceDomain = function(cookieDomain, resourceDomain)
{
if (cookieDomain.charAt(0) !== '.')
return resourceDomain === cookieDomain;
return !!resourceDomain.match(new RegExp("^([^\\.]+\\.)?" + cookieDomain.substring(1).escapeForRegExp() + "$"), "i");
}






WebInspector.ApplicationCacheModel = function()
{
ApplicationCacheAgent.enable();
InspectorBackend.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);

this._statuses = {};
this._manifestURLsByFrame = {};

this._mainFrameNavigated();

this._onLine = true;
}

WebInspector.ApplicationCacheModel.EventTypes = {
FrameManifestStatusUpdated: "FrameManifestStatusUpdated",
FrameManifestAdded: "FrameManifestAdded",
FrameManifestRemoved: "FrameManifestRemoved",
NetworkStateChanged: "NetworkStateChanged"
}

WebInspector.ApplicationCacheModel.prototype = {
_frameNavigated: function(event)
{
var frame =   event.data;
if (frame.isMainFrame()) {
this._mainFrameNavigated();
return;
}

ApplicationCacheAgent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
},


_frameDetached: function(event)
{
var frame =   event.data;
this._frameManifestRemoved(frame.id);
},

_mainFrameNavigated: function()
{
ApplicationCacheAgent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
},


_manifestForFrameLoaded: function(frameId, error, manifestURL)
{
if (error) {
console.error(error);
return;
}

if (!manifestURL)
this._frameManifestRemoved(frameId);
},


_framesWithManifestsLoaded: function(error, framesWithManifests)
{
if (error) {
console.error(error);
return;
}

for (var i = 0; i < framesWithManifests.length; ++i)
this._frameManifestUpdated(framesWithManifests[i].frameId, framesWithManifests[i].manifestURL, framesWithManifests[i].status);
},


_frameManifestUpdated: function(frameId, manifestURL, status)
{
if (status === applicationCache.UNCACHED) {
this._frameManifestRemoved(frameId);
return;
}

if (!manifestURL)
return;

if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId])
this._frameManifestRemoved(frameId);

var statusChanged = this._statuses[frameId] !== status;
this._statuses[frameId] = status;

if (!this._manifestURLsByFrame[frameId]) {
this._manifestURLsByFrame[frameId] = manifestURL;
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, frameId);
}

if (statusChanged)
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, frameId);
},


_frameManifestRemoved: function(frameId)
{
if (!this._manifestURLsByFrame[frameId])
return;

var manifestURL = this._manifestURLsByFrame[frameId];
delete this._manifestURLsByFrame[frameId];
delete this._statuses[frameId];

this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, frameId);
},


frameManifestURL: function(frameId)
{
return this._manifestURLsByFrame[frameId] || "";
},


frameManifestStatus: function(frameId)
{
return this._statuses[frameId] || applicationCache.UNCACHED;
},


get onLine()
{
return this._onLine;
},


_statusUpdated: function(frameId, manifestURL, status)
{
this._frameManifestUpdated(frameId, manifestURL, status);
},


requestApplicationCache: function(frameId, callback)
{
function callbackWrapper(error, applicationCache)
{
if (error) {
console.error(error);
callback(null);
return;
}

callback(applicationCache);
}

ApplicationCacheAgent.getApplicationCacheForFrame(frameId, callbackWrapper.bind(this));
},


_networkStateUpdated: function(isNowOnline)
{
this._onLine = isNowOnline;
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline);
}
}

WebInspector.ApplicationCacheModel.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel)
{
this._applicationCacheModel = applicationCacheModel;
}

WebInspector.ApplicationCacheDispatcher.prototype = {

applicationCacheStatusUpdated: function(frameId, manifestURL, status)
{
this._applicationCacheModel._statusUpdated(frameId, manifestURL, status);
},


networkStateUpdated: function(isNowOnline)
{
this._applicationCacheModel._networkStateUpdated(isNowOnline);
}
}






WebInspector.IndexedDBModel = function()
{
IndexedDBAgent.enable();

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);

this._frames = {};
this._databases = new Map();
this._frameIdsBySecurityOrigin = {};
this._databaseNamesBySecurityOrigin = {};

this.refreshDatabaseNames();
}

WebInspector.IndexedDBModel.KeyTypes = {
NumberType:  "number",
StringType:  "string",
DateType:    "date",
ArrayType:   "array"
};

WebInspector.IndexedDBModel.KeyPathTypes = {
NullType:    "null",
StringType:  "string",
ArrayType:   "array"
};


WebInspector.IndexedDBModel.idbKeyFromKey = function(key)
{
var idbKey;
switch (key.type) {
case WebInspector.IndexedDBModel.KeyTypes.NumberType:
idbKey = key.number;
break;
case WebInspector.IndexedDBModel.KeyTypes.StringType:
idbKey = key.string;
break;
case WebInspector.IndexedDBModel.KeyTypes.DateType:
idbKey = new Date(key.date);
break;
case WebInspector.IndexedDBModel.KeyTypes.ArrayType:
idbKey = [];
for (var i = 0; i < key.array.length; ++i)
idbKey.push(WebInspector.IndexedDBModel.idbKeyFromKey(key.array[i]));
break;
}
return idbKey;
}

WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey)
{
if (typeof(idbKey) === "undefined" || idbKey === null)
return null;

var key = {};
switch (typeof(idbKey)) {
case "number":
key.number = idbKey;
key.type = WebInspector.IndexedDBModel.KeyTypes.NumberType;
break;
case "string":
key.string = idbKey;
key.type = WebInspector.IndexedDBModel.KeyTypes.StringType;
break;
case "object":
if (idbKey instanceof Date) {
key.date = idbKey.getTime();
key.type = WebInspector.IndexedDBModel.KeyTypes.DateType;
} else if (idbKey instanceof Array) {
key.array = [];
for (var i = 0; i < idbKey.length; ++i)
key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i]));
key.type = WebInspector.IndexedDBModel.KeyTypes.ArrayType;
}
break;
default:
return null;
}
return key;
}

WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange)
{
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
if (typeof(idbKeyRange) === "undefined" || idbKeyRange === null)
return null;

var keyRange = {};
keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);
keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);
keyRange.lowerOpen = idbKeyRange.lowerOpen;
keyRange.upperOpen = idbKeyRange.upperOpen;
return keyRange;
}


WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath)
{
var idbKeyPath;
switch (keyPath.type) {
case WebInspector.IndexedDBModel.KeyPathTypes.NullType:
idbKeyPath = null;
break;
case WebInspector.IndexedDBModel.KeyPathTypes.StringType:
idbKeyPath = keyPath.string;
break;
case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType:
idbKeyPath = keyPath.array;
break;
}
return idbKeyPath;
}

WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath)
{
if (typeof idbKeyPath === "string")
return "\"" + idbKeyPath + "\"";
if (idbKeyPath instanceof Array)
return "[\"" + idbKeyPath.join("\", \"") + "\"]";
return null;
}

WebInspector.IndexedDBModel.EventTypes = {
DatabaseAdded: "DatabaseAdded",
DatabaseRemoved: "DatabaseRemoved",
DatabaseLoaded: "DatabaseLoaded"
}

WebInspector.IndexedDBModel.prototype = {
refreshDatabaseNames: function()
{
this._reset();
if (WebInspector.resourceTreeModel.mainFrame)
this._framesNavigatedRecursively(WebInspector.resourceTreeModel.mainFrame);
},


refreshDatabase: function(databaseId)
{
this._loadDatabase(databaseId);
},


_framesNavigatedRecursively: function(resourceTreeFrame)
{
this._processFrameNavigated(resourceTreeFrame);
for (var i = 0; i < resourceTreeFrame.childFrames.length; ++i)
this._framesNavigatedRecursively(resourceTreeFrame.childFrames[i]);
},


_frameNavigated: function(event)
{
var resourceTreeFrame =   event.data;
this._processFrameNavigated(resourceTreeFrame);
},


_frameDetached: function(event)
{
var resourceTreeFrame =   event.data;
this._originRemovedFromFrame(resourceTreeFrame.id);
},

_reset: function()
{
for (var frameId in this._frames)
this._originRemovedFromFrame(frameId);
},


_processFrameNavigated: function(resourceTreeFrame)
{
if (resourceTreeFrame.securityOrigin === "null")
return;
if (this._frameIdsBySecurityOrigin[resourceTreeFrame.securityOrigin])
this._originAddedToFrame(resourceTreeFrame.id, resourceTreeFrame.securityOrigin);
else
this._loadDatabaseNamesForFrame(resourceTreeFrame.id);
},


_originAddedToFrame: function(frameId, securityOrigin)
{
if (!this._frameIdsBySecurityOrigin[securityOrigin]) {
this._frameIdsBySecurityOrigin[securityOrigin] = [];
this._frameIdsBySecurityOrigin[securityOrigin].push(frameId);
this._databaseNamesBySecurityOrigin[securityOrigin] = [];
}
this._frames[frameId] = new WebInspector.IndexedDBModel.Frame(frameId, securityOrigin);
},


_originRemovedFromFrame: function(frameId)
{
var currentSecurityOrigin = this._frames[frameId] ? this._frames[frameId].securityOrigin : null;
if (!currentSecurityOrigin)
return;

delete this._frames[frameId];

var frameIdsForOrigin = this._frameIdsBySecurityOrigin[currentSecurityOrigin];
for (var i = 0; i < frameIdsForOrigin; ++i) {
if (frameIdsForOrigin[i] === frameId) {
frameIdsForOrigin.splice(i, 1);
break;
}
}
if (!frameIdsForOrigin.length)
this._originRemoved(currentSecurityOrigin);
},


_originRemoved: function(securityOrigin)
{
var frameIdsForOrigin = this._frameIdsBySecurityOrigin[securityOrigin];
for (var i = 0; i < frameIdsForOrigin; ++i)
delete this._frames[frameIdsForOrigin[i]];
delete this._frameIdsBySecurityOrigin[securityOrigin];
for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[securityOrigin][i]);
delete this._databaseNamesBySecurityOrigin[securityOrigin];
},


_updateOriginDatabaseNames: function(securityOrigin, databaseNames)
{
var newDatabaseNames = {};
for (var i = 0; i < databaseNames.length; ++i)
newDatabaseNames[databaseNames[i]] = true;
var oldDatabaseNames = {};
for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
oldDatabaseNames[databaseNames[i]] = true;

this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames;

for (var databaseName in oldDatabaseNames) {
if (!newDatabaseNames[databaseName])
this._databaseRemoved(securityOrigin, databaseName);
}
for (var databaseName in newDatabaseNames) {
if (!oldDatabaseNames[databaseName])
this._databaseAdded(securityOrigin, databaseName);
}

if (!this._databaseNamesBySecurityOrigin[securityOrigin].length)
this._originRemoved(securityOrigin);
},


_databaseAdded: function(securityOrigin, databaseName)
{
var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, databaseId);
},


_databaseRemoved: function(securityOrigin, databaseName)
{
var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, databaseId);
},


_loadDatabaseNamesForFrame: function(frameId)
{

function callback(error, securityOriginWithDatabaseNames)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}

var databaseNames = securityOriginWithDatabaseNames.databaseNames;
var oldSecurityOrigin = this._frames[frameId] ? this._frames[frameId].securityOrigin : null;
if (!oldSecurityOrigin || oldSecurityOrigin !== securityOriginWithDatabaseNames.securityOrigin) {
this._originRemovedFromFrame(frameId);
this._originAddedToFrame(frameId, securityOriginWithDatabaseNames.securityOrigin);
}
this._updateOriginDatabaseNames(securityOriginWithDatabaseNames.securityOrigin, securityOriginWithDatabaseNames.databaseNames);
}

IndexedDBAgent.requestDatabaseNamesForFrame(frameId, callback.bind(this));
},


_assertFrameId: function(databaseId)
{
var frameIds = this._frameIdsBySecurityOrigin[databaseId.securityOrigin];
if (!frameIds || !frameIds.length)
return null;

return frameIds[0];
},


_loadDatabase: function(databaseId)
{
var frameId = this._assertFrameId(databaseId);
if (!frameId)
return;


function callback(error, databaseWithObjectStores)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}

if (!this._frames[frameId])
return;

var databaseModel = new WebInspector.IndexedDBModel.Database(databaseId, databaseWithObjectStores.version);
this._databases.put(databaseId, databaseModel); 
for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++i) {
var objectStore = databaseWithObjectStores.objectStores[i];
var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath);
var objectStoreModel = new WebInspector.IndexedDBModel.ObjectStore(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement);
for (var j = 0; j < objectStore.indexes.length; ++j) {
var index = objectStore.indexes[j];
var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath);
var indexModel = new WebInspector.IndexedDBModel.Index(index.name, indexIDBKeyPath, index.unique, index.multiEntry);
objectStoreModel.indexes[indexModel.name] = indexModel;
}
databaseModel.objectStores[objectStoreModel.name] = objectStoreModel;
}

this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, databaseModel);
}

IndexedDBAgent.requestDatabase(frameId, databaseId.name, callback.bind(this));
},


loadObjectStoreData: function(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, callback)
{
this._requestData(databaseId, databaseId.name, objectStoreName, "", idbKeyRange, skipCount, pageSize, callback);
},


loadIndexData: function(databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
{
this._requestData(databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback);
},


_requestData: function(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
{
var frameId = this._assertFrameId(databaseId);
if (!frameId)
return;


function innerCallback(error, dataEntries, hasMore)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}

if (!this._frames[frameId])
return;

var entries = [];
for (var i = 0; i < dataEntries.length; ++i) {
var key = WebInspector.IndexedDBModel.idbKeyFromKey(dataEntries[i].key);
var primaryKey = WebInspector.IndexedDBModel.idbKeyFromKey(dataEntries[i].primaryKey);
var value = WebInspector.RemoteObject.fromPayload(dataEntries[i].value);
entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, value));
}
callback(entries, hasMore);
}

var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange);
IndexedDBAgent.requestData(frameId, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this));
}
}

WebInspector.IndexedDBModel.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.IndexedDBModel.Entry = function(key, primaryKey, value)
{
this.key = key;
this.primaryKey = primaryKey;
this.value = value;
}


WebInspector.IndexedDBModel.Frame = function(frameId, securityOrigin)
{
this.frameId = frameId;
this.securityOrigin = securityOrigin;
this.databaseNames = {};
}


WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name)
{
this.securityOrigin = securityOrigin;
this.name = name;
}

WebInspector.IndexedDBModel.DatabaseId.prototype = {

equals: function(databaseId)
{
return this.name === databaseId.name && this.securityOrigin === databaseId.securityOrigin;
},
}

WebInspector.IndexedDBModel.Database = function(databaseId, version)
{
this.databaseId = databaseId;
this.version = version;
this.objectStores = {};
}


WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement)
{
this.name = name;
this.keyPath = keyPath;
this.autoIncrement = autoIncrement;
this.indexes = {};
}

WebInspector.IndexedDBModel.ObjectStore.prototype = {

get keyPathString()
{
return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
}
}


WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry)
{
this.name = name;
this.keyPath = keyPath;
this.unique = unique;
this.multiEntry = multiEntry;
}

WebInspector.IndexedDBModel.Index.prototype = {

get keyPathString()
{
return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
}
}






WebInspector.Spectrum = function()
{
this._popover = new WebInspector.Popover();
this._popover.setCanShrink(false);
this._popover.element.addEventListener("mousedown", consumeEvent, false);

this._containerElement = document.createElement('div');
this._containerElement.className = "spectrum-container";
this._containerElement.tabIndex = 0;
this._containerElement.addEventListener("keydown", this._onKeyDown.bind(this), false);

var topElement = this._containerElement.createChild("div", "spectrum-top");
topElement.createChild("div", "spectrum-fill");

var topInnerElement = topElement.createChild("div", "spectrum-top-inner fill");
this._draggerElement = topInnerElement.createChild("div", "spectrum-color");
this._dragHelperElement = this._draggerElement.createChild("div", "spectrum-sat fill").createChild("div", "spectrum-val fill").createChild("div", "spectrum-dragger");

this._sliderElement = topInnerElement.createChild("div", "spectrum-hue");
this.slideHelper = this._sliderElement.createChild("div", "spectrum-slider");

var rangeContainer = this._containerElement.createChild("div", "spectrum-range-container");
var alphaLabel = rangeContainer.createChild("label");
alphaLabel.textContent = WebInspector.UIString("\u03B1:");

this._alphaElement = rangeContainer.createChild("input", "spectrum-range");
this._alphaElement.setAttribute("type", "range");
this._alphaElement.setAttribute("min", "0");
this._alphaElement.setAttribute("max", "100");
this._alphaElement.addEventListener("change", alphaDrag.bind(this), false);

var swatchElement = document.createElement("span");
swatchElement.className = "swatch";
this._swatchInnerElement = swatchElement.createChild("span", "swatch-inner");

var displayContainer = this._containerElement.createChild("div");
displayContainer.appendChild(swatchElement);
this._displayElement = displayContainer.createChild("span", "source-code spectrum-display-value");

WebInspector.Spectrum.draggable(this._sliderElement, hueDrag.bind(this));
WebInspector.Spectrum.draggable(this._draggerElement, colorDrag.bind(this), colorDragStart.bind(this));

function hueDrag(element, dragX, dragY)
{
this.hsv[0] = (dragY / this.slideHeight);

this._onchange();
}

var initialHelperOffset;

function colorDragStart(element, dragX, dragY)
{
initialHelperOffset = { x: this._dragHelperElement.offsetLeft, y: this._dragHelperElement.offsetTop };
}

function colorDrag(element, dragX, dragY, event)
{
if (event.shiftKey) {
if (Math.abs(dragX - initialHelperOffset.x) >= Math.abs(dragY - initialHelperOffset.y))
dragY = initialHelperOffset.y;
else
dragX = initialHelperOffset.x;
}

this.hsv[1] = dragX / this.dragWidth;
this.hsv[2] = (this.dragHeight - dragY) / this.dragHeight;

this._onchange();
}

function alphaDrag()
{
this.hsv[3] = this._alphaElement.value / 100;

this._onchange();
}

this._hideProxy = this.hide.bind(this, true);
};

WebInspector.Spectrum.Events = {
ColorChanged: "ColorChanged",
Hidden: "Hidden"
};

WebInspector.Spectrum.hsvaToRGBA = function(h, s, v, a)
{
var r, g, b;

var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);

switch(i % 6) {
case 0:
r = v, g = t, b = p;
break;
case 1:
r = q, g = v, b = p;
break;
case 2:
r = p, g = v, b = t;
break;
case 3:
r = p, g = q, b = v;
break;
case 4:
r = t, g = p, b = v;
break;
case 5:
r = v, g = p, b = q;
break;
}

return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a];
};

WebInspector.Spectrum.rgbaToHSVA = function(r, g, b, a)
{
r = r / 255;
g = g / 255;
b = b / 255;

var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var h;
var s;
var v = max;

var d = max - min;
s = max ? d / max : 0;

if(max === min) {

h = 0;
} else {
switch(max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [h, s, v, a];
};



WebInspector.Spectrum.draggable = function(element, onmove, onstart, onstop) {

var doc = document;
var dragging;
var offset;
var scrollOffset;
var maxHeight;
var maxWidth;

function consume(e)
{
e.consume(true);
}

function move(e)
{
if (dragging) {
var dragX = Math.max(0, Math.min(e.pageX - offset.left + scrollOffset.left, maxWidth));
var dragY = Math.max(0, Math.min(e.pageY - offset.top + scrollOffset.top, maxHeight));

if (onmove)
onmove(element, dragX, dragY, e);
}
}

function start(e)
{
var rightClick = e.which ? (e.which === 3) : (e.button === 2);

if (!rightClick && !dragging) {

if (onstart)
onstart(element, e)

dragging = true;
maxHeight = element.clientHeight;
maxWidth = element.clientWidth;

scrollOffset = element.scrollOffset();
offset = element.totalOffset();

doc.addEventListener("selectstart", consume, false);
doc.addEventListener("dragstart", consume, false);
doc.addEventListener("mousemove", move, false);
doc.addEventListener("mouseup", stop, false);

move(e);
consume(e);
}
}

function stop(e)
{
if (dragging) {
doc.removeEventListener("selectstart", consume, false);
doc.removeEventListener("dragstart", consume, false);
doc.removeEventListener("mousemove", move, false);
doc.removeEventListener("mouseup", stop, false);

if (onstop)
onstop(element, e);
}

dragging = false;
}

element.addEventListener("mousedown", start, false);
};

WebInspector.Spectrum.prototype = {

set color(color)
{
var rgba = (color.rgba || color.rgb).slice(0);

if (rgba.length === 3)
rgba[3] = 1;

this.hsv = WebInspector.Spectrum.rgbaToHSVA(rgba[0], rgba[1], rgba[2], rgba[3]);
},

get color()
{
var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], this.hsv[1], this.hsv[2], this.hsv[3]);
var color;

if (rgba[3] === 1)
color = WebInspector.Color.fromRGB(rgba[0], rgba[1], rgba[2]);
else
color = WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);

var colorValue = color.toString(this.outputColorFormat);
if (!colorValue)
colorValue = color.toString(); 
return new WebInspector.Color(colorValue);
},

get outputColorFormat()
{
var cf = WebInspector.Color.Format;
var format = this._originalFormat;

if (this.hsv[3] === 1) {

if (format === cf.RGBA)
format = cf.RGB;
else if (format === cf.HSLA)
format = cf.HSL;
} else {

if (format === cf.HSL || format === cf.HSLA)
format = cf.HSLA;
else
format = cf.RGBA;
}

return format;
},

get colorHueOnly()
{
var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], 1, 1, 1);
return WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
},

set displayText(text)
{
this._displayElement.textContent = text;
},

get visible()
{
return this._popover.visible;
},

_onchange: function()
{
this._updateUI();
this.dispatchEventToListeners(WebInspector.Spectrum.Events.ColorChanged, this.color);
},

_updateHelperLocations: function()
{
var h = this.hsv[0];
var s = this.hsv[1];
var v = this.hsv[2];


var dragX = s * this.dragWidth;
var dragY = this.dragHeight - (v * this.dragHeight);

dragX = Math.max(-this._dragHelperElementHeight,
Math.min(this.dragWidth - this._dragHelperElementHeight, dragX - this._dragHelperElementHeight));
dragY = Math.max(-this._dragHelperElementHeight,
Math.min(this.dragHeight - this._dragHelperElementHeight, dragY - this._dragHelperElementHeight));

this._dragHelperElement.positionAt(dragX, dragY);


var slideY = (h * this.slideHeight) - this.slideHelperHeight;
this.slideHelper.style.top = slideY + "px";

this._alphaElement.value = this.hsv[3] * 100;
},

_updateUI: function()
{
this._updateHelperLocations();

var rgb = (this.color.rgba || this.color.rgb).slice(0);

if (rgb.length === 3)
rgb[3] = 1;

var rgbHueOnly = this.colorHueOnly.rgb;

var flatColor = "rgb(" + rgbHueOnly[0] + ", " + rgbHueOnly[1] + ", " + rgbHueOnly[2] + ")";
var fullColor = "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " + rgb[3] + ")";

this._draggerElement.style.backgroundColor = flatColor;
this._swatchInnerElement.style.backgroundColor = fullColor;

this._alphaElement.value = this.hsv[3] * 100;
},

toggle: function(element, color, format)
{
if (this.visible)
this.hide(true);
else
this.show(element, color, format);

return this.visible;
},

show: function(element, color, format)
{
if (this.visible) {
if (this.anchorElement === element)
return false;


this.hide(true);
}

this.reposition(element);
this.anchorElement = element;

document.addEventListener("mousedown", this._hideProxy, false);
window.addEventListener("blur", this._hideProxy, false);

this.slideHeight = this._sliderElement.offsetHeight;
this.dragWidth = this._draggerElement.offsetWidth;
this.dragHeight = this._draggerElement.offsetHeight;
this._dragHelperElementHeight = this._dragHelperElement.offsetHeight / 2;
this.slideHelperHeight = this.slideHelper.offsetHeight / 2;

this.color = color;
this._originalFormat = format || color.format;

this._updateUI();

return true;
},

reposition: function(element)
{
if (!this._previousFocusElement)
this._previousFocusElement = WebInspector.currentFocusElement();
this._popover.show(this._containerElement, element);
WebInspector.setCurrentFocusElement(this._containerElement);
},


hide: function(commitEdit)
{
this._popover.hide();

document.removeEventListener("mousedown", this._hideProxy, false);
window.removeEventListener("blur", this._hideProxy, false);

this.dispatchEventToListeners(WebInspector.Spectrum.Events.Hidden, !!commitEdit);

WebInspector.setCurrentFocusElement(this._previousFocusElement);
delete this._previousFocusElement;

delete this.anchorElement;
},

_onKeyDown: function(event)
{
if (event.keyIdentifier === "Enter") {
this.hide(true);
event.consume(true);
return;
}
if (event.keyIdentifier === "U+001B") { 
this.hide(false);
event.consume(true);
}
}
}

WebInspector.Spectrum.prototype.__proto__ = WebInspector.Object.prototype;






WebInspector.SidebarPane = function(title)
{
this.element = document.createElement("div");
this.element.className = "pane";

this.titleElement = document.createElement("div");
this.titleElement.className = "title";
this.titleElement.tabIndex = 0;
this.titleElement.addEventListener("click", this.toggleExpanded.bind(this), false);
this.titleElement.addEventListener("keydown", this._onTitleKeyDown.bind(this), false);

this.bodyElement = document.createElement("div");
this.bodyElement.className = "body";

this.element.appendChild(this.titleElement);
this.element.appendChild(this.bodyElement);

this.title = title;
this.growbarVisible = false;
this.expanded = false;
}

WebInspector.SidebarPane.prototype = {
get title()
{
return this._title;
},

set title(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},

get growbarVisible()
{
return this._growbarVisible;
},

set growbarVisible(x)
{
if (this._growbarVisible === x)
return;

this._growbarVisible = x;

if (x && !this._growbarElement) {
this._growbarElement = document.createElement("div");
this._growbarElement.className = "growbar";
this.element.appendChild(this._growbarElement);
} else if (!x && this._growbarElement) {
if (this._growbarElement.parentNode)
this._growbarElement.parentNode(this._growbarElement);
delete this._growbarElement;
}
},

get expanded()
{
return this._expanded;
},

set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},

expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.addStyleClass("expanded");
this.onexpand();
},

onexpand: function()
{
},

collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
},

toggleExpanded: function()
{
this.expanded = !this.expanded;
},

_onTitleKeyDown: function(event)
{
if (isEnterKey(event) || event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
this.toggleExpanded();
}
}

WebInspector.SidebarPane.prototype.__proto__ = WebInspector.Object.prototype;






WebInspector.ElementsTreeOutline = function(omitRootDOMNode, selectEnabled, showInElementsPanelEnabled, contextMenuCallback, setPseudoClassCallback)
{
this.element = document.createElement("ol");
this.element.addEventListener("mousedown", this._onmousedown.bind(this), false);
this.element.addEventListener("mousemove", this._onmousemove.bind(this), false);
this.element.addEventListener("mouseout", this._onmouseout.bind(this), false);
this.element.addEventListener("dragstart", this._ondragstart.bind(this), false);
this.element.addEventListener("dragover", this._ondragover.bind(this), false);
this.element.addEventListener("dragleave", this._ondragleave.bind(this), false);
this.element.addEventListener("drop", this._ondrop.bind(this), false);
this.element.addEventListener("dragend", this._ondragend.bind(this), false);

TreeOutline.call(this, this.element);

this._includeRootDOMNode = !omitRootDOMNode;
this._selectEnabled = selectEnabled;
this._showInElementsPanelEnabled = showInElementsPanelEnabled;
this._rootDOMNode = null;
this._selectDOMNode = null;
this._eventSupport = new WebInspector.Object();
this._editing = false;

this._visible = false;

this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
this._contextMenuCallback = contextMenuCallback;
this._setPseudoClassCallback = setPseudoClassCallback;
this._createNodeDecorators();
}

WebInspector.ElementsTreeOutline.Events = {
SelectedNodeChanged: "SelectedNodeChanged"
}

WebInspector.ElementsTreeOutline.MappedCharToEntity = {
"\u00a0": "nbsp",
"\u2002": "ensp",
"\u2003": "emsp",
"\u2009": "thinsp",
"\u200b": "#8203", 
"\u200c": "zwnj",
"\u200d": "zwj",
"\u200e": "lrm",
"\u200f": "rlm",
"\u202a": "#8234", 
"\u202b": "#8235", 
"\u202c": "#8236", 
"\u202d": "#8237", 
"\u202e": "#8238" 
}

WebInspector.ElementsTreeOutline.prototype = {
_createNodeDecorators: function()
{
this._nodeDecorators = [];
this._nodeDecorators.push(new WebInspector.ElementsTreeOutline.PseudoStateDecorator());
},

wireToDomAgent: function()
{
this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this);
},

setVisible: function(visible)
{
this._visible = visible;
if (!this._visible)
return;

this._updateModifiedNodes();
if (this._selectedDOMNode)
this._revealAndSelectNode(this._selectedDOMNode, false);
},

addEventListener: function(eventType, listener, thisObject)
{
this._eventSupport.addEventListener(eventType, listener, thisObject);
},

removeEventListener: function(eventType, listener, thisObject)
{
this._eventSupport.removeEventListener(eventType, listener, thisObject);
},

get rootDOMNode()
{
return this._rootDOMNode;
},

set rootDOMNode(x)
{
if (this._rootDOMNode === x)
return;

this._rootDOMNode = x;

this._isXMLMimeType = x && x.isXMLNode();

this.update();
},

get isXMLMimeType()
{
return this._isXMLMimeType;
},

selectedDOMNode: function()
{
return this._selectedDOMNode;
},

selectDOMNode: function(node, focus)
{
if (this._selectedDOMNode === node) {
this._revealAndSelectNode(node, !focus);
return;
}

this._selectedDOMNode = node;
this._revealAndSelectNode(node, !focus);





if (this._selectedDOMNode === node)
this._selectedNodeChanged();
},

get editing()
{
return this._editing;
},

update: function()
{
var selectedNode = this.selectedTreeElement ? this.selectedTreeElement.representedObject : null;

this.removeChildren();

if (!this.rootDOMNode)
return;

var treeElement;
if (this._includeRootDOMNode) {
treeElement = new WebInspector.ElementsTreeElement(this.rootDOMNode);
treeElement.selectable = this._selectEnabled;
this.appendChild(treeElement);
} else {

var node = this.rootDOMNode.firstChild;
while (node) {
treeElement = new WebInspector.ElementsTreeElement(node);
treeElement.selectable = this._selectEnabled;
this.appendChild(treeElement);
node = node.nextSibling;
}
}

if (selectedNode)
this._revealAndSelectNode(selectedNode, true);
},

updateSelection: function()
{
if (!this.selectedTreeElement)
return;
var element = this.treeOutline.selectedTreeElement;
element.updateSelection();
},


updateOpenCloseTags: function(node)
{
var treeElement = this.findTreeElement(node);
if (treeElement)
treeElement.updateTitle();
var children = treeElement.children;
var closingTagElement = children[children.length - 1];
if (closingTagElement && closingTagElement._elementCloseTag)
closingTagElement.updateTitle();
},

_selectedNodeChanged: function()
{
this._eventSupport.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedDOMNode);
},


findTreeElement: function(node)
{
function isAncestorNode(ancestor, node)
{
return ancestor.isAncestor(node);
}

function parentNode(node)
{
return node.parentNode;
}

var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, isAncestorNode, parentNode);
if (!treeElement && node.nodeType() === Node.TEXT_NODE) {

treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, isAncestorNode, parentNode);
}

return treeElement;
},


createTreeElementFor: function(node)
{
var treeElement = this.findTreeElement(node);
if (treeElement)
return treeElement;
if (!node.parentNode)
return null;

treeElement = this.createTreeElementFor(node.parentNode);
if (treeElement && treeElement.showChild(node.index))
return treeElement.children[node.index];

return null;
},

set suppressRevealAndSelect(x)
{
if (this._suppressRevealAndSelect === x)
return;
this._suppressRevealAndSelect = x;
},

_revealAndSelectNode: function(node, omitFocus)
{
if (!node || this._suppressRevealAndSelect)
return;

var treeElement = this.createTreeElementFor(node);
if (!treeElement)
return;

treeElement.revealAndSelect(omitFocus);
},

_treeElementFromEvent: function(event)
{
var scrollContainer = this.element.parentElement;





var x = scrollContainer.totalOffsetLeft() + scrollContainer.offsetWidth - 36;

var y = event.pageY;




var elementUnderMouse = this.treeElementFromPoint(x, y);
var elementAboveMouse = this.treeElementFromPoint(x, y - 2);
var element;
if (elementUnderMouse === elementAboveMouse)
element = elementUnderMouse;
else
element = this.treeElementFromPoint(x, y + 2);

return element;
},

_onmousedown: function(event)
{
var element = this._treeElementFromEvent(event);

if (!element || element.isEventWithinDisclosureTriangle(event))
return;

element.select();
},

_onmousemove: function(event)
{
var element = this._treeElementFromEvent(event);
if (element && this._previousHoveredElement === element)
return;

if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}

if (element) {
element.hovered = true;
this._previousHoveredElement = element;
}

WebInspector.domAgent.highlightDOMNode(element ? element.representedObject.id : 0);
},

_onmouseout: function(event)
{
var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.element))
return;

if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}

WebInspector.domAgent.hideDOMNodeHighlight();
},

_ondragstart: function(event)
{
var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return false;

if (!this._isValidDragSourceOrTarget(treeElement))
return false;

if (treeElement.representedObject.nodeName() === "BODY" || treeElement.representedObject.nodeName() === "HEAD")
return false;

event.dataTransfer.setData("text/plain", treeElement.listItemElement.textContent);
event.dataTransfer.effectAllowed = "copyMove";
this._treeElementBeingDragged = treeElement;

WebInspector.domAgent.hideDOMNodeHighlight();

return true;
},

_ondragover: function(event)
{
if (!this._treeElementBeingDragged)
return false;

var treeElement = this._treeElementFromEvent(event);
if (!this._isValidDragSourceOrTarget(treeElement))
return false;

var node = treeElement.representedObject;
while (node) {
if (node === this._treeElementBeingDragged.representedObject)
return false;
node = node.parentNode;
}

treeElement.updateSelection();
treeElement.listItemElement.addStyleClass("elements-drag-over");
this._dragOverTreeElement = treeElement;
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
return false;
},

_ondragleave: function(event)
{
this._clearDragOverTreeElementMarker();
event.preventDefault();
return false;
},

_isValidDragSourceOrTarget: function(treeElement)
{
if (!treeElement)
return false;

var node = treeElement.representedObject;
if (!(node instanceof WebInspector.DOMNode))
return false;

if (!node.parentNode || node.parentNode.nodeType() !== Node.ELEMENT_NODE)
return false;

return true;
},

_ondrop: function(event)
{
event.preventDefault();
var treeElement = this._treeElementFromEvent(event);
if (treeElement)
this._doMove(treeElement);
},

_doMove: function(treeElement)
{
if (!this._treeElementBeingDragged)
return;

var parentNode;
var anchorNode;

if (treeElement._elementCloseTag) {

parentNode = treeElement.representedObject;
} else {
var dragTargetNode = treeElement.representedObject;
parentNode = dragTargetNode.parentNode;
anchorNode = dragTargetNode;
}

var wasExpanded = this._treeElementBeingDragged.expanded;
this._treeElementBeingDragged.representedObject.moveTo(parentNode, anchorNode, this._selectNodeAfterEdit.bind(this, null, wasExpanded));

delete this._treeElementBeingDragged;
},

_ondragend: function(event)
{
event.preventDefault();
this._clearDragOverTreeElementMarker();
delete this._treeElementBeingDragged;
},

_clearDragOverTreeElementMarker: function()
{
if (this._dragOverTreeElement) {
this._dragOverTreeElement.updateSelection();
this._dragOverTreeElement.listItemElement.removeStyleClass("elements-drag-over");
delete this._dragOverTreeElement;
}
},

_contextMenuEventFired: function(event)
{
if (!this._showInElementsPanelEnabled)
return;

var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return;

function focusElement()
{
WebInspector.domAgent.inspectElement(treeElement.representedObject.id);
}
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this));
contextMenu.show(event);
},

populateContextMenu: function(contextMenu, event)
{
var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return false;

var isTag = treeElement.representedObject.nodeType() === Node.ELEMENT_NODE;
var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (textNode && textNode.hasStyleClass("bogus"))
textNode = null;
var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-comment");
contextMenu.appendApplicableItems(event.target);
if (textNode) {
contextMenu.appendSeparator();
treeElement._populateTextContextMenu(contextMenu, textNode);
} else if (isTag) {
contextMenu.appendSeparator();
treeElement._populateTagContextMenu(contextMenu, event);
} else if (commentNode) {
contextMenu.appendSeparator();
treeElement._populateNodeContextMenu(contextMenu, textNode);
}
},

adjustCollapsedRange: function()
{
},

_updateModifiedNodes: function()
{
if (this._elementsTreeUpdater)
this._elementsTreeUpdater._updateModifiedNodes();
},

_populateContextMenu: function(contextMenu, node)
{
if (this._contextMenuCallback)
this._contextMenuCallback(contextMenu, node);
},

handleShortcut: function(event)
{
var node = this.selectedDOMNode();
var treeElement = this.getCachedTreeElement(node);
if (!node || !treeElement)
return;

if (event.keyIdentifier === "F2") {
this._toggleEditAsHTML(node);
return;
}

if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && node.parentNode) {
if (event.keyIdentifier === "Up" && node.previousSibling) {
node.moveTo(node.parentNode, node.previousSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded));
return;
}
if (event.keyIdentifier === "Down" && node.nextSibling) {
node.moveTo(node.parentNode, node.nextSibling.nextSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded));
return;
}
}

},

_toggleEditAsHTML: function(node)
{
var treeElement = this.getCachedTreeElement(node);
if (!treeElement)
return;

if (treeElement._editing && treeElement._htmlEditElement && WebInspector.isBeingEdited(treeElement._htmlEditElement))
treeElement._editing.commit();
else
treeElement._editAsHTML();
},

_selectNodeAfterEdit: function(fallbackNode, wasExpanded, error, nodeId)
{
if (error)
return;


this._updateModifiedNodes();

var newNode = WebInspector.domAgent.nodeForId(nodeId) || fallbackNode;
if (!newNode)
return;

this.selectDOMNode(newNode, true);

var newTreeItem = this.findTreeElement(newNode);
if (wasExpanded) {
if (newTreeItem)
newTreeItem.expand();
}
return newTreeItem;
}
}

WebInspector.ElementsTreeOutline.prototype.__proto__ = TreeOutline.prototype;


WebInspector.ElementsTreeOutline.ElementDecorator = function()
{
}

WebInspector.ElementsTreeOutline.ElementDecorator.prototype = {

decorate: function(node)
{
},


decorateAncestor: function(node)
{
}
}


WebInspector.ElementsTreeOutline.PseudoStateDecorator = function()
{
WebInspector.ElementsTreeOutline.ElementDecorator.call(this);
}

WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName = "pseudoState";

WebInspector.ElementsTreeOutline.PseudoStateDecorator.prototype = {
decorate: function(node)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;
var propertyValue = node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
if (!propertyValue)
return null;
return WebInspector.UIString("Element state: %s", ":" + propertyValue.join(", :"));
},

decorateAncestor: function(node)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;

var descendantCount = node.descendantUserPropertyCount(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
if (!descendantCount)
return null;
if (descendantCount === 1)
return WebInspector.UIString("%d descendant with forced state", descendantCount);
return WebInspector.UIString("%d descendants with forced state", descendantCount);
}
}

WebInspector.ElementsTreeOutline.PseudoStateDecorator.prototype.__proto__ = WebInspector.ElementsTreeOutline.ElementDecorator.prototype;


WebInspector.ElementsTreeElement = function(node, elementCloseTag)
{
this._elementCloseTag = elementCloseTag;
var hasChildrenOverride = !elementCloseTag && node.hasChildNodes() && !this._showInlineText(node);


TreeElement.call(this, "", node, hasChildrenOverride);

if (this.representedObject.nodeType() == Node.ELEMENT_NODE && !elementCloseTag)
this._canAddAttributes = true;
this._searchQuery = null;
this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit;
}

WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;




WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
"area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame",
"hr", "img", "input", "isindex", "keygen", "link", "meta", "param", "source"
].keySet();


WebInspector.ElementsTreeElement.EditTagBlacklist = [
"html", "head", "body"
].keySet();

WebInspector.ElementsTreeElement.prototype = {
highlightSearchResults: function(searchQuery)
{
if (this._searchQuery !== searchQuery) {
this._updateSearchHighlight(false);
delete this._highlightResult; 
}

this._searchQuery = searchQuery;
this._searchHighlightsVisible = true;
this.updateTitle(true);
},

hideSearchHighlights: function()
{
delete this._searchHighlightsVisible;
this._updateSearchHighlight(false);
},

_updateSearchHighlight: function(show)
{
if (!this._highlightResult)
return;

function updateEntryShow(entry)
{
switch (entry.type) {
case "added":
entry.parent.insertBefore(entry.node, entry.nextSibling);
break;
case "changed":
entry.node.textContent = entry.newText;
break;
}
}

function updateEntryHide(entry)
{
switch (entry.type) {
case "added":
if (entry.node.parentElement)
entry.node.parentElement.removeChild(entry.node);
break;
case "changed":
entry.node.textContent = entry.oldText;
break;
}
}


if (show) {
for (var i = 0, size = this._highlightResult.length; i < size; ++i)
updateEntryShow(this._highlightResult[i]);
} else {
for (var i = (this._highlightResult.length - 1); i >= 0; --i)
updateEntryHide(this._highlightResult[i]);
}
},

get hovered()
{
return this._hovered;
},

set hovered(x)
{
if (this._hovered === x)
return;

this._hovered = x;

if (this.listItemElement) {
if (x) {
this.updateSelection();
this.listItemElement.addStyleClass("hovered");
} else {
this.listItemElement.removeStyleClass("hovered");
}
}
},

get expandedChildrenLimit()
{
return this._expandedChildrenLimit;
},

set expandedChildrenLimit(x)
{
if (this._expandedChildrenLimit === x)
return;

this._expandedChildrenLimit = x;
if (this.treeOutline && !this._updateChildrenInProgress)
this._updateChildren(true);
},

get expandedChildCount()
{
var count = this.children.length;
if (count && this.children[count - 1]._elementCloseTag)
count--;
if (count && this.children[count - 1].expandAllButton)
count--;
return count;
},

showChild: function(index)
{
if (this._elementCloseTag)
return;

if (index >= this.expandedChildrenLimit) {
this._expandedChildrenLimit = index + 1;
this._updateChildren(true);
}


return this.expandedChildCount > index;
},

updateSelection: function()
{
var listItemElement = this.listItemElement;
if (!listItemElement)
return;

if (!this._readyToUpdateSelection) {
if (document.body.offsetWidth > 0)
this._readyToUpdateSelection = true;
else {


return;
}
}

if (!this.selectionElement) {
this.selectionElement = document.createElement("div");
this.selectionElement.className = "selection selected";
listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild);
}

this.selectionElement.style.height = listItemElement.offsetHeight + "px";
},

onattach: function()
{
if (this._hovered) {
this.updateSelection();
this.listItemElement.addStyleClass("hovered");
}

this.updateTitle();
this._preventFollowingLinksOnDoubleClick();
this.listItemElement.draggable = true;
},

_preventFollowingLinksOnDoubleClick: function()
{
var links = this.listItemElement.querySelectorAll("li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link");
if (!links)
return;

for (var i = 0; i < links.length; ++i)
links[i].preventFollowOnDoubleClick = true;
},

onpopulate: function()
{
if (this.children.length || this._showInlineText(this.representedObject) || this._elementCloseTag)
return;

this.updateChildren();
},


updateChildren: function(fullRefresh)
{
if (this._elementCloseTag)
return;
this.representedObject.getChildNodes(this._updateChildren.bind(this, fullRefresh));
},


insertChildElement: function(child, index, closingTag)
{
var newElement = new WebInspector.ElementsTreeElement(child, closingTag);
newElement.selectable = this.treeOutline._selectEnabled;
this.insertChild(newElement, index);
return newElement;
},

moveChild: function(child, targetIndex)
{
var wasSelected = child.selected;
this.removeChild(child);
this.insertChild(child, targetIndex);
if (wasSelected)
child.select();
},


_updateChildren: function(fullRefresh)
{
if (this._updateChildrenInProgress || !this.treeOutline._visible)
return;

this._updateChildrenInProgress = true;
var selectedNode = this.treeOutline.selectedDOMNode();
var originalScrollTop = 0;
if (fullRefresh) {
var treeOutlineContainerElement = this.treeOutline.element.parentNode;
originalScrollTop = treeOutlineContainerElement.scrollTop;
var selectedTreeElement = this.treeOutline.selectedTreeElement;
if (selectedTreeElement && selectedTreeElement.hasAncestor(this))
this.select();
this.removeChildren();
}

var treeElement = this;
var treeChildIndex = 0;
var elementToSelect;

function updateChildrenOfNode(node)
{
var treeOutline = treeElement.treeOutline;
var child = node.firstChild;
while (child) {
var currentTreeElement = treeElement.children[treeChildIndex];
if (!currentTreeElement || currentTreeElement.representedObject !== child) {

var existingTreeElement = null;
for (var i = (treeChildIndex + 1), size = treeElement.expandedChildCount; i < size; ++i) {
if (treeElement.children[i].representedObject === child) {
existingTreeElement = treeElement.children[i];
break;
}
}

if (existingTreeElement && existingTreeElement.parent === treeElement) {

treeElement.moveChild(existingTreeElement, treeChildIndex);
} else {

if (treeChildIndex < treeElement.expandedChildrenLimit) {
var newElement = treeElement.insertChildElement(child, treeChildIndex);
if (child === selectedNode)
elementToSelect = newElement;
if (treeElement.expandedChildCount > treeElement.expandedChildrenLimit)
treeElement.expandedChildrenLimit++;
}
}
}

child = child.nextSibling;
++treeChildIndex;
}
}


for (var i = (this.children.length - 1); i >= 0; --i) {
var currentChild = this.children[i];
var currentNode = currentChild.representedObject;
var currentParentNode = currentNode.parentNode;

if (currentParentNode === this.representedObject)
continue;

var selectedTreeElement = this.treeOutline.selectedTreeElement;
if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild)))
this.select();

this.removeChildAtIndex(i);
}

updateChildrenOfNode(this.representedObject);
this.adjustCollapsedRange();

var lastChild = this.children[this.children.length - 1];
if (this.representedObject.nodeType() == Node.ELEMENT_NODE && (!lastChild || !lastChild._elementCloseTag))
this.insertChildElement(this.representedObject, this.children.length, true);


if (fullRefresh && elementToSelect) {
elementToSelect.select();
if (treeOutlineContainerElement && originalScrollTop <= treeOutlineContainerElement.scrollHeight)
treeOutlineContainerElement.scrollTop = originalScrollTop;
}

delete this._updateChildrenInProgress;
},

adjustCollapsedRange: function()
{


if (this.expandAllButtonElement && this.expandAllButtonElement.__treeElement.parent)
this.removeChild(this.expandAllButtonElement.__treeElement);

const node = this.representedObject;
if (!node.children)
return;
const childNodeCount = node.children.length;


for (var i = this.expandedChildCount, limit = Math.min(this.expandedChildrenLimit, childNodeCount); i < limit; ++i)
this.insertChildElement(node.children[i], i);

const expandedChildCount = this.expandedChildCount;
if (childNodeCount > this.expandedChildCount) {
var targetButtonIndex = expandedChildCount;
if (!this.expandAllButtonElement) {
var button = document.createElement("button");
button.className = "show-all-nodes";
button.value = "";
var item = new TreeElement(button, null, false);
item.selectable = false;
item.expandAllButton = true;
this.insertChild(item, targetButtonIndex);
this.expandAllButtonElement = item.listItemElement.firstChild;
this.expandAllButtonElement.__treeElement = item;
this.expandAllButtonElement.addEventListener("click", this.handleLoadAllChildren.bind(this), false);
} else if (!this.expandAllButtonElement.__treeElement.parent)
this.insertChild(this.expandAllButtonElement.__treeElement, targetButtonIndex);
this.expandAllButtonElement.textContent = WebInspector.UIString("Show All Nodes (%d More)", childNodeCount - expandedChildCount);
} else if (this.expandAllButtonElement)
delete this.expandAllButtonElement;
},

handleLoadAllChildren: function()
{
this.expandedChildrenLimit = Math.max(this.representedObject._childNodeCount, this.expandedChildrenLimit + WebInspector.ElementsTreeElement.InitialChildrenLimit);
},

onexpand: function()
{
if (this._elementCloseTag)
return;

this.updateTitle();
this.treeOutline.updateSelection();
},

oncollapse: function()
{
if (this._elementCloseTag)
return;

this.updateTitle();
this.treeOutline.updateSelection();
},

onreveal: function()
{
if (this.listItemElement) {
var tagSpans = this.listItemElement.getElementsByClassName("webkit-html-tag-name");
if (tagSpans.length)
tagSpans[0].scrollIntoViewIfNeeded(false);
else
this.listItemElement.scrollIntoViewIfNeeded(false);
}
},

onselect: function(selectedByUser)
{
this.treeOutline.suppressRevealAndSelect = true;
this.treeOutline.selectDOMNode(this.representedObject, selectedByUser);
if (selectedByUser)
WebInspector.domAgent.highlightDOMNode(this.representedObject.id);
this.updateSelection();
this.treeOutline.suppressRevealAndSelect = false;
return true;
},

ondelete: function()
{
var startTagTreeElement = this.treeOutline.findTreeElement(this.representedObject);
startTagTreeElement ? startTagTreeElement.remove() : this.remove();
return true;
},

onenter: function()
{


if (this.treeOutline.editing)
return false;

this._startEditing();


return true;
},

selectOnMouseDown: function(event)
{
TreeElement.prototype.selectOnMouseDown.call(this, event);

if (this._editing)
return;

if (this.treeOutline._showInElementsPanelEnabled) {
WebInspector.showPanel("elements");
this.treeOutline.selectDOMNode(this.representedObject, true);
}


if (event.detail >= 2)
event.preventDefault();
},

ondblclick: function(event)
{
if (this._editing || this._elementCloseTag)
return;

if (this._startEditingTarget(event.target))
return;

if (this.hasChildren && !this.expanded)
this.expand();
},

_insertInLastAttributePosition: function(tag, node)
{
if (tag.getElementsByClassName("webkit-html-attribute").length > 0)
tag.insertBefore(node, tag.lastChild);
else {
var nodeName = tag.textContent.match(/^<(.*?)>$/)[1];
tag.textContent = '';
tag.appendChild(document.createTextNode('<'+nodeName));
tag.appendChild(node);
tag.appendChild(document.createTextNode('>'));
}

this.updateSelection();
},

_startEditingTarget: function(eventTarget)
{
if (this.treeOutline.selectedDOMNode() != this.representedObject)
return;

if (this.representedObject.nodeType() != Node.ELEMENT_NODE && this.representedObject.nodeType() != Node.TEXT_NODE)
return false;

var textNode = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (textNode)
return this._startEditingTextNode(textNode);

var attribute = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-attribute");
if (attribute)
return this._startEditingAttribute(attribute, eventTarget);

var tagName = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-tag-name");
if (tagName)
return this._startEditingTagName(tagName);

var newAttribute = eventTarget.enclosingNodeOrSelfWithClass("add-attribute");
if (newAttribute)
return this._addNewAttribute();

return false;
},

_populateTagContextMenu: function(contextMenu, event)
{
var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute");
var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute");


contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add attribute" : "Add Attribute"), this._addNewAttribute.bind(this));
if (attribute && !newAttribute)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit attribute" : "Edit Attribute"), this._startEditingAttribute.bind(this, attribute, event.target));
contextMenu.appendSeparator();
if (this.treeOutline._setPseudoClassCallback) {
var pseudoSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Force element state" : "Force Element State"));
this._populateForcedPseudoStateItems(pseudoSubMenu);
contextMenu.appendSeparator();
}

this._populateNodeContextMenu(contextMenu);
this.treeOutline._populateContextMenu(contextMenu, this.representedObject);

contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Scroll into view" : "Scroll Into View"), this._scrollIntoView.bind(this)); 
},

_populateForcedPseudoStateItems: function(subMenu)
{
const pseudoClasses = ["active", "hover", "focus", "visited"];
var node = this.representedObject;
var forcedPseudoState = (node ? node.getUserProperty("pseudoState") : null) || [];
for (var i = 0; i < pseudoClasses.length; ++i) {
var pseudoClassForced = forcedPseudoState.indexOf(pseudoClasses[i]) >= 0;
subMenu.appendCheckboxItem(":" + pseudoClasses[i], this.treeOutline._setPseudoClassCallback.bind(null, node.id, pseudoClasses[i], !pseudoClassForced), pseudoClassForced, false);
}
},

_populateTextContextMenu: function(contextMenu, textNode)
{
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit text" : "Edit Text"), this._startEditingTextNode.bind(this, textNode));
this._populateNodeContextMenu(contextMenu);
},

_populateNodeContextMenu: function(contextMenu)
{

contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._copyXPath.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this));
},

_startEditing: function()
{
if (this.treeOutline.selectedDOMNode() !== this.representedObject)
return;

var listItem = this._listItemNode;

if (this._canAddAttributes) {
var attribute = listItem.getElementsByClassName("webkit-html-attribute")[0];
if (attribute)
return this._startEditingAttribute(attribute, attribute.getElementsByClassName("webkit-html-attribute-value")[0]);

return this._addNewAttribute();
}

if (this.representedObject.nodeType() === Node.TEXT_NODE) {
var textNode = listItem.getElementsByClassName("webkit-html-text-node")[0];
if (textNode)
return this._startEditingTextNode(textNode);
return;
}
},

_addNewAttribute: function()
{


var container = document.createElement("span");
this._buildAttributeDOM(container, " ", "");
var attr = container.firstChild;
attr.style.marginLeft = "2px"; 
attr.style.marginRight = "2px"; 

var tag = this.listItemElement.getElementsByClassName("webkit-html-tag")[0];
this._insertInLastAttributePosition(tag, attr);
return this._startEditingAttribute(attr, attr);
},

_triggerEditAttribute: function(attributeName)
{
var attributeElements = this.listItemElement.getElementsByClassName("webkit-html-attribute-name");
for (var i = 0, len = attributeElements.length; i < len; ++i) {
if (attributeElements[i].textContent === attributeName) {
for (var elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) {
if (elem.nodeType !== Node.ELEMENT_NODE)
continue;

if (elem.hasStyleClass("webkit-html-attribute-value"))
return this._startEditingAttribute(elem.parentNode, elem);
}
}
}
},

_startEditingAttribute: function(attribute, elementForSelection)
{
if (WebInspector.isBeingEdited(attribute))
return true;

var attributeNameElement = attribute.getElementsByClassName("webkit-html-attribute-name")[0];
if (!attributeNameElement)
return false;

var attributeName = attributeNameElement.textContent;

function removeZeroWidthSpaceRecursive(node)
{
if (node.nodeType === Node.TEXT_NODE) {
node.nodeValue = node.nodeValue.replace(/\u200B/g, "");
return;
}

if (node.nodeType !== Node.ELEMENT_NODE)
return;

for (var child = node.firstChild; child; child = child.nextSibling)
removeZeroWidthSpaceRecursive(child);
}


removeZeroWidthSpaceRecursive(attribute);

var config = new WebInspector.EditingConfig(this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);

function handleKeyDownEvents(event)
{
var isMetaOrCtrl = WebInspector.isMac() ?
event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
return "commit";
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
return "cancel";
else if (event.keyIdentifier === "U+0009") 
return "move-" + (event.shiftKey ? "backward" : "forward");
else {
WebInspector.handleElementValueModifications(event, attribute);
return "";
}
}

config.customFinishHandler = handleKeyDownEvents.bind(this);

this._editing = WebInspector.startEditing(attribute, config);

window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);

return true;
},

_startEditingTextNode: function(textNode)
{
if (WebInspector.isBeingEdited(textNode))
return true;

var container = textNode.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (container)
container.innerText = textNode._originalContent; 
var config = new WebInspector.EditingConfig(this._textNodeEditingCommitted.bind(this), this._editingCancelled.bind(this));
this._editing = WebInspector.startEditing(textNode, config);
window.getSelection().setBaseAndExtent(textNode, 0, textNode, 1);

return true;
},

_startEditingTagName: function(tagNameElement)
{
if (!tagNameElement) {
tagNameElement = this.listItemElement.getElementsByClassName("webkit-html-tag-name")[0];
if (!tagNameElement)
return false;
}

var tagName = tagNameElement.textContent;
if (WebInspector.ElementsTreeElement.EditTagBlacklist[tagName.toLowerCase()])
return false;

if (WebInspector.isBeingEdited(tagNameElement))
return true;

var closingTagElement = this._distinctClosingTagElement();

function keyupListener(event)
{
if (closingTagElement)
closingTagElement.textContent = "</" + tagNameElement.textContent + ">";
}

function editingComitted(element, newTagName)
{
tagNameElement.removeEventListener('keyup', keyupListener, false);
this._tagNameEditingCommitted.apply(this, arguments);
}

function editingCancelled()
{
tagNameElement.removeEventListener('keyup', keyupListener, false);
this._editingCancelled.apply(this, arguments);
}

tagNameElement.addEventListener('keyup', keyupListener, false);

var config = new WebInspector.EditingConfig(editingComitted.bind(this), editingCancelled.bind(this), tagName);
this._editing = WebInspector.startEditing(tagNameElement, config);
window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
return true;
},

_startEditingAsHTML: function(commitCallback, error, initialValue)
{
if (error)
return;
if (this._htmlEditElement && WebInspector.isBeingEdited(this._htmlEditElement))
return;

function consume(event)
{
if (event.eventPhase === Event.AT_TARGET)
event.consume(true);
}

this._htmlEditElement = document.createElement("div");
this._htmlEditElement.className = "source-code elements-tree-editor";
this._htmlEditElement.textContent = initialValue;


var child = this.listItemElement.firstChild;
while (child) {
child.style.display = "none";
child = child.nextSibling;
}

if (this._childrenListNode)
this._childrenListNode.style.display = "none";

this.listItemElement.appendChild(this._htmlEditElement);
this.treeOutline.childrenListElement.parentElement.addEventListener("mousedown", consume, false);

this.updateSelection();

function commit()
{
commitCallback(initialValue, this._htmlEditElement.textContent);
dispose.call(this);
}

function dispose()
{
this._editing = false;


this.listItemElement.removeChild(this._htmlEditElement);
delete this._htmlEditElement;

if (this._childrenListNode)
this._childrenListNode.style.removeProperty("display");

var child = this.listItemElement.firstChild;
while (child) {
child.style.removeProperty("display");
child = child.nextSibling;
}

this.treeOutline.childrenListElement.parentElement.removeEventListener("mousedown", consume, false);
this.updateSelection();
}

var config = new WebInspector.EditingConfig(commit.bind(this), dispose.bind(this));
config.setMultiline(true);
this._editing = WebInspector.startEditing(this._htmlEditElement, config);
},

_attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
{
this._editing = false;

var treeOutline = this.treeOutline;

function moveToNextAttributeIfNeeded(error)
{
if (error)
this._editingCancelled(element, attributeName);

if (!moveDirection)
return;

treeOutline._updateModifiedNodes();


var attributes = this.representedObject.attributes();
for (var i = 0; i < attributes.length; ++i) {
if (attributes[i].name !== attributeName)
continue;

if (moveDirection === "backward") {
if (i === 0)
this._startEditingTagName();
else
this._triggerEditAttribute(attributes[i - 1].name);
} else {
if (i === attributes.length - 1)
this._addNewAttribute();
else
this._triggerEditAttribute(attributes[i + 1].name);
}
return;
}


if (moveDirection === "backward") {
if (newText === " ") {

if (attributes.length > 0)
this._triggerEditAttribute(attributes[attributes.length - 1].name);
} else {

if (attributes.length > 1)
this._triggerEditAttribute(attributes[attributes.length - 2].name);
}
} else if (moveDirection === "forward") {
if (!/^\s*$/.test(newText))
this._addNewAttribute();
else
this._startEditingTagName();
}
}

if (oldText !== newText)
this.representedObject.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this));
else
moveToNextAttributeIfNeeded.call(this);
},

_tagNameEditingCommitted: function(element, newText, oldText, tagName, moveDirection)
{
this._editing = false;
var self = this;

function cancel()
{
var closingTagElement = self._distinctClosingTagElement();
if (closingTagElement)
closingTagElement.textContent = "</" + tagName + ">";

self._editingCancelled(element, tagName);
moveToNextAttributeIfNeeded.call(self);
}

function moveToNextAttributeIfNeeded()
{
if (moveDirection !== "forward") {
this._addNewAttribute();
return;
}

var attributes = this.representedObject.attributes();
if (attributes.length > 0)
this._triggerEditAttribute(attributes[0].name);
else
this._addNewAttribute();
}

newText = newText.trim();
if (newText === oldText) {
cancel();
return;
}

var treeOutline = this.treeOutline;
var wasExpanded = this.expanded;

function changeTagNameCallback(error, nodeId)
{
if (error || !nodeId) {
cancel();
return;
}
var newTreeItem = treeOutline._selectNodeAfterEdit(null, wasExpanded, error, nodeId);
moveToNextAttributeIfNeeded.call(newTreeItem);
}

this.representedObject.setNodeName(newText, changeTagNameCallback);
},

_textNodeEditingCommitted: function(element, newText)
{
this._editing = false;

var textNode;
if (this.representedObject.nodeType() === Node.ELEMENT_NODE) {


textNode = this.representedObject.firstChild;
} else if (this.representedObject.nodeType() == Node.TEXT_NODE)
textNode = this.representedObject;

textNode.setNodeValue(newText, this.updateTitle.bind(this));
},

_editingCancelled: function(element, context)
{
this._editing = false;


this.updateTitle();
},

_distinctClosingTagElement: function()
{




if (this.expanded) {
var closers = this._childrenListNode.querySelectorAll(".close");
return closers[closers.length-1];
}




var tags = this.listItemElement.getElementsByClassName("webkit-html-tag");
return (tags.length === 1 ? null : tags[tags.length-1]);
},


updateTitle: function(onlySearchQueryChanged)
{


if (this._editing)
return;

if (onlySearchQueryChanged) {
if (this._highlightResult)
this._updateSearchHighlight(false);
} else {
var highlightElement = document.createElement("span");
highlightElement.className = "highlight";
highlightElement.appendChild(this._nodeTitleInfo(WebInspector.linkifyURLAsNode).titleDOM);
this.title = highlightElement;
this._updateDecorations();
delete this._highlightResult;
}

delete this.selectionElement;
if (this.selected)
this.updateSelection();
this._preventFollowingLinksOnDoubleClick();
this._highlightSearchResults();
},

_createDecoratorElement: function()
{
var node = this.representedObject;
var decoratorMessages = [];
var parentDecoratorMessages = [];
for (var i = 0; i < this.treeOutline._nodeDecorators.length; ++i) {
var decorator = this.treeOutline._nodeDecorators[i];
var message = decorator.decorate(node);
if (message) {
decoratorMessages.push(message);
continue;
}

if (this.expanded || this._elementCloseTag)
continue;

message = decorator.decorateAncestor(node);
if (message)
parentDecoratorMessages.push(message)
}
if (!decoratorMessages.length && !parentDecoratorMessages.length)
return null;

var decoratorElement = document.createElement("div");
decoratorElement.addStyleClass("elements-gutter-decoration");
if (!decoratorMessages.length)
decoratorElement.addStyleClass("elements-has-decorated-children");
decoratorElement.title = decoratorMessages.concat(parentDecoratorMessages).join("\n");
return decoratorElement;
},

_updateDecorations: function()
{
if (this._decoratorElement && this._decoratorElement.parentElement)
this._decoratorElement.parentElement.removeChild(this._decoratorElement);
this._decoratorElement = this._createDecoratorElement();
if (this._decoratorElement && this.listItemElement)
this.listItemElement.insertBefore(this._decoratorElement, this.listItemElement.firstChild);
},


_buildAttributeDOM: function(parentElement, name, value, node, linkify)
{
var hasText = (value.length > 0);
var attrSpanElement = parentElement.createChild("span", "webkit-html-attribute");
var attrNameElement = attrSpanElement.createChild("span", "webkit-html-attribute-name");
attrNameElement.textContent = name;

if (hasText)
attrSpanElement.appendChild(document.createTextNode("=\u200B\""));

if (linkify && (name === "src" || name === "href")) {
var rewrittenHref = node.resolveURL(value);
value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
if (rewrittenHref === null) {
var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
attrValueElement.textContent = value;
} else {
if (value.startsWith("data:"))
value = value.trimMiddle(60);
attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a"));
}
} else {
value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
attrValueElement.textContent = value;
}

if (hasText)
attrSpanElement.appendChild(document.createTextNode("\""));
},


_buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeElement, linkify)
{
var node =   this.representedObject;
var classes = [ "webkit-html-tag" ];
if (isClosingTag && isDistinctTreeElement)
classes.push("close");
if (node.isInShadowTree())
classes.push("shadow");
var tagElement = parentElement.createChild("span", classes.join(" "));
tagElement.appendChild(document.createTextNode("<"));
var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name");
tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName;
if (!isClosingTag && node.hasAttributes()) {
var attributes = node.attributes();
for (var i = 0; i < attributes.length; ++i) {
var attr = attributes[i];
tagElement.appendChild(document.createTextNode(" "));
this._buildAttributeDOM(tagElement, attr.name, attr.value, node, linkify);
}
}
tagElement.appendChild(document.createTextNode(">"));
parentElement.appendChild(document.createTextNode("\u200B"));
},

_convertWhitespaceToEntities: function(text)
{
var result = "";
var lastIndexAfterEntity = 0;
var charToEntity = WebInspector.ElementsTreeOutline.MappedCharToEntity;
for (var i = 0, size = text.length; i < size; ++i) {
var char = text.charAt(i);
if (charToEntity[char]) {
result += text.substring(lastIndexAfterEntity, i) + "&" + charToEntity[char] + ";";
lastIndexAfterEntity = i + 1;
}
}
if (result) {
result += text.substring(lastIndexAfterEntity);
return result;
}
return text;
},

_nodeTitleInfo: function(linkify)
{
var node = this.representedObject;
var info = {titleDOM: document.createDocumentFragment(), hasChildren: this.hasChildren};

switch (node.nodeType()) {
case Node.ATTRIBUTE_NODE:
var value = node.value || "\u200B"; 
this._buildAttributeDOM(info.titleDOM, node.name, value);
break;

case Node.ELEMENT_NODE:
var tagName = node.nodeNameInCorrectCase();
if (this._elementCloseTag) {
this._buildTagDOM(info.titleDOM, tagName, true, true);
info.hasChildren = false;
break;
}

this._buildTagDOM(info.titleDOM, tagName, false, false, linkify);

var textChild = this._singleTextChild(node);
var showInlineText = textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength;

if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) {
if (this.hasChildren) {
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node bogus");
textNodeElement.textContent = "\u2026";
info.titleDOM.appendChild(document.createTextNode("\u200B"));
}
this._buildTagDOM(info.titleDOM, tagName, true, false);
}




if (showInlineText) {
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node");
textNodeElement.textContent = this._convertWhitespaceToEntities(textChild.nodeValue());
textNodeElement._originalContent = textChild.nodeValue();
info.titleDOM.appendChild(document.createTextNode("\u200B"));
this._buildTagDOM(info.titleDOM, tagName, true, false);
info.hasChildren = false;
}
break;

case Node.TEXT_NODE:
if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") {
var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-js-node");
newNode.textContent = node.nodeValue();

var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript", true);
javascriptSyntaxHighlighter.syntaxHighlightNode(newNode);
} else if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "style") {
var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-css-node");
newNode.textContent = node.nodeValue();

var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css", true);
cssSyntaxHighlighter.syntaxHighlightNode(newNode);
} else {
info.titleDOM.appendChild(document.createTextNode("\""));
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node");
textNodeElement.textContent = this._convertWhitespaceToEntities(node.nodeValue());
textNodeElement._originalContent = node.nodeValue();
info.titleDOM.appendChild(document.createTextNode("\""));
}
break;

case Node.COMMENT_NODE:
var commentElement = info.titleDOM.createChild("span", "webkit-html-comment");
commentElement.appendChild(document.createTextNode("<!--" + node.nodeValue() + "-->"));
break;

case Node.DOCUMENT_TYPE_NODE:
var docTypeElement = info.titleDOM.createChild("span", "webkit-html-doctype");
docTypeElement.appendChild(document.createTextNode("<!DOCTYPE " + node.nodeName()));
if (node.publicId) {
docTypeElement.appendChild(document.createTextNode(" PUBLIC \"" + node.publicId + "\""));
if (node.systemId)
docTypeElement.appendChild(document.createTextNode(" \"" + node.systemId + "\""));
} else if (node.systemId)
docTypeElement.appendChild(document.createTextNode(" SYSTEM \"" + node.systemId + "\""));

if (node.internalSubset)
docTypeElement.appendChild(document.createTextNode(" [" + node.internalSubset + "]"));

docTypeElement.appendChild(document.createTextNode(">"));
break;

case Node.CDATA_SECTION_NODE:
var cdataElement = info.titleDOM.createChild("span", "webkit-html-text-node");
cdataElement.appendChild(document.createTextNode("<![CDATA[" + node.nodeValue() + "]]>"));
break;
case Node.DOCUMENT_FRAGMENT_NODE:
var fragmentElement = info.titleDOM.createChild("span", "webkit-html-fragment");
fragmentElement.textContent = node.nodeNameInCorrectCase().collapseWhitespace();
if (node.isInShadowTree())
fragmentElement.addStyleClass("shadow");
break;
default:
info.titleDOM.appendChild(document.createTextNode(node.nodeNameInCorrectCase().collapseWhitespace()));
}
return info;
},

_singleTextChild: function(node)
{
if (!node)
return null;

var firstChild = node.firstChild;
if (!firstChild || firstChild.nodeType() !== Node.TEXT_NODE)
return null;

var sibling = firstChild.nextSibling;
return sibling ? null : firstChild;
},

_showInlineText: function(node)
{
if (node.nodeType() === Node.ELEMENT_NODE) {
var textChild = this._singleTextChild(node);
if (textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength)
return true;
}
return false;
},

remove: function()
{
var parentElement = this.parent;
if (!parentElement)
return;

var self = this;
function removeNodeCallback(error, removedNodeId)
{
if (error)
return;

parentElement.removeChild(self);
parentElement.adjustCollapsedRange();
}

if (!this.representedObject.parentNode || this.representedObject.parentNode.nodeType() === Node.DOCUMENT_NODE)
return;
this.representedObject.removeNode(removeNodeCallback);
},

_editAsHTML: function()
{
var treeOutline = this.treeOutline;
var node = this.representedObject;
var parentNode = node.parentNode;
var index = node.index;
var wasExpanded = this.expanded;

function selectNode(error, nodeId)
{
if (error)
return;


treeOutline._updateModifiedNodes();

var newNode = parentNode ? parentNode.children[index] || parentNode : null;
if (!newNode)
return;

treeOutline.selectDOMNode(newNode, true);

if (wasExpanded) {
var newTreeItem = treeOutline.findTreeElement(newNode);
if (newTreeItem)
newTreeItem.expand();
}
}

function commitChange(initialValue, value)
{
if (initialValue !== value)
node.setOuterHTML(value, selectNode);
else
return;
}

node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange));
},

_copyHTML: function()
{
this.representedObject.copyNode();
},

_copyXPath: function()
{
this.representedObject.copyXPath(true);
},

_highlightSearchResults: function()
{
if (!this._searchQuery || !this._searchHighlightsVisible)
return;
if (this._highlightResult) {
this._updateSearchHighlight(true);
return;
}

var text = this.listItemElement.textContent;
var regexObject = createPlainTextSearchRegex(this._searchQuery, "gi");

var offset = 0;
var match = regexObject.exec(text);
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}


if (!matchRanges.length)
matchRanges.push({ offset: 0, length: text.length });

this._highlightResult = [];
WebInspector.highlightSearchResults(this.listItemElement, matchRanges, this._highlightResult);
},

_scrollIntoView: function()
{
function scrollIntoViewCallback(object)
{
function scrollIntoView()
{
this.scrollIntoViewIfNeeded(true);
}

if (object)
object.callFunction(scrollIntoView);
}

var node =   this.representedObject;
WebInspector.RemoteObject.resolveNode(node, "", scrollIntoViewCallback);
}
}

WebInspector.ElementsTreeElement.prototype.__proto__ = TreeElement.prototype;


WebInspector.ElementsTreeUpdater = function(treeOutline)
{
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeInserted, this._nodeInserted, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributesUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.CharacterDataModified, this._characterDataModified, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);

this._treeOutline = treeOutline;
this._recentlyModifiedNodes = new Map();
}

WebInspector.ElementsTreeUpdater.prototype = {


_nodeModified: function(node, isUpdated, parentNode)
{
if (this._treeOutline._visible)
this._updateModifiedNodesSoon();

var entry =   this._recentlyModifiedNodes.get(node);
if (!entry) {
entry = new WebInspector.ElementsTreeUpdater.UpdateEntry(isUpdated, parentNode);
this._recentlyModifiedNodes.put(node, entry);
return;
}

entry.isUpdated |= isUpdated;
if (parentNode)
entry.parent = parentNode;
},

_documentUpdated: function(event)
{
var inspectedRootDocument = event.data;

this._reset();

if (!inspectedRootDocument)
return;

this._treeOutline.rootDOMNode = inspectedRootDocument;
},

_attributesUpdated: function(event)
{
this._nodeModified(event.data.node, true);
},

_characterDataModified: function(event)
{
this._nodeModified(event.data, true);
},

_nodeInserted: function(event)
{
this._nodeModified(event.data, false, event.data.parentNode);
},

_nodeRemoved: function(event)
{
this._nodeModified(event.data.node, false, event.data.parent);
},

_childNodeCountUpdated: function(event)
{
var treeElement = this._treeOutline.findTreeElement(event.data);
if (treeElement)
treeElement.hasChildren = event.data.hasChildNodes();
},

_updateModifiedNodesSoon: function()
{
if (this._updateModifiedNodesTimeout)
return;
this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50);
},

_updateModifiedNodes: function()
{
if (this._updateModifiedNodesTimeout) {
clearTimeout(this._updateModifiedNodesTimeout);
delete this._updateModifiedNodesTimeout;
}

var updatedParentTreeElements = [];

var hidePanelWhileUpdating = this._recentlyModifiedNodes.size() > 10;
if (hidePanelWhileUpdating) {
var treeOutlineContainerElement = this._treeOutline.element.parentNode;
this._treeOutline.element.addStyleClass("hidden");
var originalScrollTop = treeOutlineContainerElement ? treeOutlineContainerElement.scrollTop : 0;
}

var keys = this._recentlyModifiedNodes.keys();
for (var i = 0, size = keys.length; i < size; ++i) {
var node = keys[i];
var entry = this._recentlyModifiedNodes.get(node);
var parent = entry.parent;

if (parent === this._treeOutline._rootDOMNode) {

this._treeOutline.update();
this._treeOutline.element.removeStyleClass("hidden");
return;
}

if (entry.isUpdated) {
var nodeItem = this._treeOutline.findTreeElement(node);
if (nodeItem)
nodeItem.updateTitle();
}

if (!parent)
continue;

var parentNodeItem = this._treeOutline.findTreeElement(parent);
if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) {
parentNodeItem.updateChildren();
parentNodeItem.alreadyUpdatedChildren = true;
updatedParentTreeElements.push(parentNodeItem);
}
}

for (var i = 0; i < updatedParentTreeElements.length; ++i)
delete updatedParentTreeElements[i].alreadyUpdatedChildren;

if (hidePanelWhileUpdating) {
this._treeOutline.element.removeStyleClass("hidden");
if (originalScrollTop)
treeOutlineContainerElement.scrollTop = originalScrollTop;
this._treeOutline.updateSelection();
}
this._recentlyModifiedNodes.clear();
},

_reset: function()
{
this._treeOutline.rootDOMNode = null;
this._treeOutline.selectDOMNode(null, false);
WebInspector.domAgent.hideDOMNodeHighlight();
this._recentlyModifiedNodes.clear();
}
}


WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent)
{
this.isUpdated = isUpdated;
if (parent)
this.parent = parent;
}





WebInspector.DOMPresentationUtils = {}

WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentElement)
{
var title = node.nodeNameInCorrectCase();

var nameElement = document.createElement("span");
nameElement.textContent = title;
parentElement.appendChild(nameElement);

var idAttribute = node.getAttribute("id");
if (idAttribute) {
var idElement = document.createElement("span");
parentElement.appendChild(idElement);

var part = "#" + idAttribute;
title += part;
idElement.appendChild(document.createTextNode(part));


nameElement.className = "extra";
}

var classAttribute = node.getAttribute("class");
if (classAttribute) {
var classes = classAttribute.split(/\s+/);
var foundClasses = {};

if (classes.length) {
var classesElement = document.createElement("span");
classesElement.className = "extra";
parentElement.appendChild(classesElement);

for (var i = 0; i < classes.length; ++i) {
var className = classes[i];
if (className && !(className in foundClasses)) {
var part = "." + className;
title += part;
classesElement.appendChild(document.createTextNode(part));
foundClasses[className] = true;
}
}
}
}
parentElement.title = title;
}

WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node)
{
var link = document.createElement("span");
link.className = "node-link";
WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);

link.addEventListener("click", WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, node.id), false);
link.addEventListener("mouseover", WebInspector.domAgent.highlightDOMNode.bind(WebInspector.domAgent, node.id, ""), false);
link.addEventListener("mouseout", WebInspector.domAgent.hideDOMNodeHighlight.bind(WebInspector.domAgent), false);

return link;
}

WebInspector.DOMPresentationUtils.linkifyNodeById = function(nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return document.createTextNode(WebInspector.UIString("<node>"));
return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
}


WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL, showDimensions, userCallback, precomputedDimensions)
{
var resource = WebInspector.resourceTreeModel.resourceForURL(imageURL);
if (!resource) {
userCallback();
return;
}

var imageElement = document.createElement("img");
imageElement.addEventListener("load", buildContent, false);
imageElement.addEventListener("error", errorCallback, false);
resource.populateImageSource(imageElement);

function errorCallback()
{

userCallback();
}

function buildContent()
{
var container = document.createElement("table");
container.className = "image-preview-container";
var naturalWidth = precomputedDimensions ? precomputedDimensions.naturalWidth : imageElement.naturalWidth;
var naturalHeight = precomputedDimensions ? precomputedDimensions.naturalHeight : imageElement.naturalHeight;
var offsetWidth = precomputedDimensions ? precomputedDimensions.offsetWidth : naturalWidth;
var offsetHeight = precomputedDimensions ? precomputedDimensions.offsetHeight : naturalHeight;
var description;
if (showDimensions) {
if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
description = WebInspector.UIString("%d \xd7 %d pixels", offsetWidth, offsetHeight);
else
description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
}

container.createChild("tr").createChild("td", "image-container").appendChild(imageElement);
if (description)
container.createChild("tr").createChild("td").createChild("span", "description").textContent = description;
userCallback(container);
}
}






WebInspector.SidebarSectionTreeElement = function(title, representedObject, hasChildren)
{
TreeElement.call(this, title.escapeHTML(), representedObject || {}, hasChildren);
this.expand();
}

WebInspector.SidebarSectionTreeElement.prototype = {
selectable: false,

collapse: function()
{

},

get smallChildren()
{
return this._smallChildren;
},

set smallChildren(x)
{
if (this._smallChildren === x)
return;

this._smallChildren = x;

if (this._smallChildren)
this._childrenListNode.addStyleClass("small");
else
this._childrenListNode.removeStyleClass("small");
},

onattach: function()
{
this._listItemNode.addStyleClass("sidebar-tree-section");
},

onreveal: function()
{
if (this.listItemElement)
this.listItemElement.scrollIntoViewIfNeeded(false);
}
}

WebInspector.SidebarSectionTreeElement.prototype.__proto__ = TreeElement.prototype;


WebInspector.SidebarTreeElement = function(className, title, subtitle, representedObject, hasChildren)
{
TreeElement.call(this, "", representedObject, hasChildren);

if (hasChildren) {
this.disclosureButton = document.createElement("button");
this.disclosureButton.className = "disclosure-button";
}

if (!this.iconElement) {
this.iconElement = document.createElement("img");
this.iconElement.className = "icon";
}

this.statusElement = document.createElement("div");
this.statusElement.className = "status";

this.titlesElement = document.createElement("div");
this.titlesElement.className = "titles";

this.titleElement = document.createElement("span");
this.titleElement.className = "title";
this.titlesElement.appendChild(this.titleElement);

this.subtitleElement = document.createElement("span");
this.subtitleElement.className = "subtitle";
this.titlesElement.appendChild(this.subtitleElement);

this.className = className;
this.mainTitle = title;
this.subtitle = subtitle;
}

WebInspector.SidebarTreeElement.prototype = {
get small()
{
return this._small;
},

set small(x)
{
this._small = x;

if (this._listItemNode) {
if (this._small)
this._listItemNode.addStyleClass("small");
else
this._listItemNode.removeStyleClass("small");
}
},

get mainTitle()
{
return this._mainTitle;
},

set mainTitle(x)
{
this._mainTitle = x;
this.refreshTitles();
},

get subtitle()
{
return this._subtitle;
},

set subtitle(x)
{
this._subtitle = x;
this.refreshTitles();
},

get bubbleText()
{
return this._bubbleText;
},

set bubbleText(x)
{
if (!this.bubbleElement) {
this.bubbleElement = document.createElement("div");
this.bubbleElement.className = "bubble";
this.statusElement.appendChild(this.bubbleElement);
}

this._bubbleText = x;
this.bubbleElement.textContent = x;
},

set wait(x)
{
if (x)
this._listItemNode.addStyleClass("wait");
else
this._listItemNode.removeStyleClass("wait");
},

refreshTitles: function()
{
var mainTitle = this.mainTitle;
if (this.titleElement.textContent !== mainTitle)
this.titleElement.textContent = mainTitle;

var subtitle = this.subtitle;
if (subtitle) {
if (this.subtitleElement.textContent !== subtitle)
this.subtitleElement.textContent = subtitle;
this.titlesElement.removeStyleClass("no-subtitle");
} else {
this.subtitleElement.textContent = "";
this.titlesElement.addStyleClass("no-subtitle");
}
},

isEventWithinDisclosureTriangle: function(event)
{
return event.target === this.disclosureButton;
},

onattach: function()
{
this._listItemNode.addStyleClass("sidebar-tree-item");

if (this.className)
this._listItemNode.addStyleClass(this.className);

if (this.small)
this._listItemNode.addStyleClass("small");

if (this.hasChildren && this.disclosureButton)
this._listItemNode.appendChild(this.disclosureButton);

this._listItemNode.appendChild(this.iconElement);
this._listItemNode.appendChild(this.statusElement);
this._listItemNode.appendChild(this.titlesElement);
},

onreveal: function()
{
if (this._listItemNode)
this._listItemNode.scrollIntoViewIfNeeded(false);
}
}

WebInspector.SidebarTreeElement.prototype.__proto__ = TreeElement.prototype;






WebInspector.Section = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "section";
this.element._section = this;

this.headerElement = document.createElement("div");
this.headerElement.className = "header";

this.titleElement = document.createElement("div");
this.titleElement.className = "title";

this.subtitleElement = document.createElement("div");
this.subtitleElement.className = "subtitle";

this.headerElement.appendChild(this.subtitleElement);
this.headerElement.appendChild(this.titleElement);

this.headerElement.addEventListener("click", this.handleClick.bind(this), false);
this.element.appendChild(this.headerElement);

this.title = title;
this.subtitle = subtitle;
this._expanded = false;
}

WebInspector.Section.prototype = {
get title()
{
return this._title;
},

set title(x)
{
if (this._title === x)
return;
this._title = x;

if (x instanceof Node) {
this.titleElement.removeChildren();
this.titleElement.appendChild(x);
} else
this.titleElement.textContent = x;
},

get subtitle()
{
return this._subtitle;
},

set subtitle(x)
{
if (this._subtitle === x)
return;
this._subtitle = x;
this.subtitleElement.textContent = x;
},

get subtitleAsTextForTest()
{
var result = this.subtitleElement.textContent;
var child = this.subtitleElement.querySelector("[data-uncopyable]");
if (child) {
var linkData = child.getAttribute("data-uncopyable");
if (linkData)
result += linkData;
}
return result;
},

get expanded()
{
return this._expanded;
},

set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},

get populated()
{
return this._populated;
},

set populated(x)
{
this._populated = x;
if (!x && this._expanded) {
this.onpopulate();
this._populated = true;
}
},

onpopulate: function()
{

},

get firstSibling()
{
var parent = this.element.parentElement;
if (!parent)
return null;

var childElement = parent.firstChild;
while (childElement) {
if (childElement._section)
return childElement._section;
childElement = childElement.nextSibling;
}

return null;
},

get lastSibling()
{
var parent = this.element.parentElement;
if (!parent)
return null;

var childElement = parent.lastChild;
while (childElement) {
if (childElement._section)
return childElement._section;
childElement = childElement.previousSibling;
}

return null;
},

get nextSibling()
{
var curElement = this.element;
do {
curElement = curElement.nextSibling;
} while (curElement && !curElement._section);

return curElement ? curElement._section : null;
},

get previousSibling()
{
var curElement = this.element;
do {
curElement = curElement.previousSibling;
} while (curElement && !curElement._section);

return curElement ? curElement._section : null;
},

expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.addStyleClass("expanded");

if (!this._populated) {
this.onpopulate();
this._populated = true;
}
},

collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
},

toggleExpanded: function()
{
this.expanded = !this.expanded;
},

handleClick: function(event)
{
this.toggleExpanded();
event.consume();
}
}






WebInspector.PropertiesSection = function(title, subtitle)
{
WebInspector.Section.call(this, title, subtitle);

this.headerElement.addStyleClass("monospace");
this.propertiesElement = document.createElement("ol");
this.propertiesElement.className = "properties properties-tree monospace";
this.propertiesTreeOutline = new TreeOutline(this.propertiesElement, true);
this.propertiesTreeOutline.setFocusable(false);
this.propertiesTreeOutline.section = this;

this.element.appendChild(this.propertiesElement);
}

WebInspector.PropertiesSection.prototype.__proto__ = WebInspector.Section.prototype;






WebInspector.RemoteObject = function(objectId, type, subtype, value, description, preview)
{
this._type = type;
this._subtype = subtype;
if (objectId) {

this._objectId = objectId;
this._description = description;
this._hasChildren = true;
this._preview = preview;
} else {

console.assert(type !== "object" || value === null);
this._description = description || (value + "");
this._hasChildren = false;
this.value = value;
}
}


WebInspector.RemoteObject.fromPrimitiveValue = function(value)
{
return new WebInspector.RemoteObject(undefined, typeof value, undefined, value);
}


WebInspector.RemoteObject.fromLocalObject = function(value)
{
return new WebInspector.LocalJSONObject(value);
}


WebInspector.RemoteObject.resolveNode = function(node, objectGroup, callback)
{

function mycallback(error, object)
{
if (!callback)
return;

if (error || !object)
callback(null);
else
callback(WebInspector.RemoteObject.fromPayload(object));
}
DOMAgent.resolveNode(node.id, objectGroup, mycallback);
}


WebInspector.RemoteObject.fromPayload = function(payload)
{
console.assert(typeof payload === "object", "Remote object payload should only be an object");

return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
}


WebInspector.RemoteObject.type = function(remoteObject)
{
if (remoteObject === null)
return "null";

var type = typeof remoteObject;
if (type !== "object" && type !== "function")
return type;

return remoteObject.type;
}

WebInspector.RemoteObject.prototype = {

get objectId()
{
return this._objectId;
},


get type()
{
return this._type;
},


get subtype()
{
return this._subtype;
},


get description()
{
return this._description;
},


get hasChildren()
{
return this._hasChildren;
},


get preview()
{
return this._preview;
},


getOwnProperties: function(callback)
{
this._getProperties(true, callback);
},


getAllProperties: function(callback)
{
this._getProperties(false, callback);
},


_getProperties: function(ownProperties, callback)
{
if (!this._objectId) {
callback([]);
return;
}


function remoteObjectBinder(error, properties)
{
if (error) {
callback(null);
return;
}
var result = [];
for (var i = 0; properties && i < properties.length; ++i) {
var property = properties[i];
if (property.get || property.set) {
if (property.get)
result.push(new WebInspector.RemoteObjectProperty("get " + property.name, WebInspector.RemoteObject.fromPayload(property.get), property));
if (property.set)
result.push(new WebInspector.RemoteObjectProperty("set " + property.name, WebInspector.RemoteObject.fromPayload(property.set), property));
} else
result.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value), property));
}
callback(result);
}
RuntimeAgent.getProperties(this._objectId, ownProperties, remoteObjectBinder);
},


setPropertyValue: function(name, value, callback)
{
if (!this._objectId) {
callback("Can't set a property of non-object.");
return;
}

RuntimeAgent.evaluate.invoke({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this));


function evaluatedCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || result.description);
return;
}

function setPropertyValue(propertyName, propertyValue)
{
this[propertyName] = propertyValue;
}

delete result.description; 
RuntimeAgent.callFunctionOn(this._objectId, setPropertyValue.toString(), [{ value:name }, result], true, undefined, propertySetCallback.bind(this));
if (result._objectId)
RuntimeAgent.releaseObject(result._objectId);
}


function propertySetCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || result.description);
return;
}
callback();
}
},


pushNodeToFrontend: function(callback)
{
if (this._objectId)
WebInspector.domAgent.pushNodeToFrontend(this._objectId, callback);
else
callback(0);
},


callFunction: function(functionDeclaration, args, callback)
{

function mycallback(error, result, wasThrown)
{
if (!callback)
return;

callback((error || wasThrown) ? null : WebInspector.RemoteObject.fromPayload(result));
}

RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, mycallback);
},


callFunctionJSON: function(functionDeclaration, args, callback)
{

function mycallback(error, result, wasThrown)
{
callback((error || wasThrown) ? null : result.value);
}

RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, mycallback);
},

release: function()
{
RuntimeAgent.releaseObject(this._objectId);
},


arrayLength: function()
{
if (this.subtype !== "array")
return 0;

var matches = this._description.match(/\[([0-9]+)\]/);
if (!matches)
return 0;
return parseInt(matches[1], 10);
}
}


WebInspector.RemoteObjectProperty = function(name, value, descriptor)
{
this.name = name;
this.value = value;
this.enumerable = descriptor ? !!descriptor.enumerable : true;
this.writable = descriptor ? !!descriptor.writable : true;
if (descriptor && descriptor.wasThrown)
this.wasThrown = true;
}


WebInspector.RemoteObjectProperty.fromPrimitiveValue = function(name, value)
{
return new WebInspector.RemoteObjectProperty(name, WebInspector.RemoteObject.fromPrimitiveValue(value));
}


WebInspector.RemoteObjectProperty.fromScopeValue = function(name, value)
{
var result = new WebInspector.RemoteObjectProperty(name, value);
result.writable = false;
return result;
}








WebInspector.LocalJSONObject = function(value)
{
this._value = value;
}

WebInspector.LocalJSONObject.prototype = {

get description()
{
if (this._cachedDescription)
return this._cachedDescription;

if (this.type === "object") {
switch (this.subtype) {
case "array":
function formatArrayItem(property)
{
return property.value.description;
}
this._cachedDescription = this._concatenate("[", "]", formatArrayItem);
break;
case "date":
this._cachedDescription = "" + this._value;
break;
case "null":
this._cachedDescription = "null";
break;
default:
function formatObjectItem(property)
{
return property.name + ":" + property.value.description;
}
this._cachedDescription = this._concatenate("{", "}", formatObjectItem);
}
} else
this._cachedDescription = String(this._value);

return this._cachedDescription;
},


_concatenate: function(prefix, suffix, formatProperty)
{
const previewChars = 100;

var buffer = prefix;
var children = this._children();
for (var i = 0; i < children.length; ++i) {
var itemDescription = formatProperty(children[i]);
if (buffer.length + itemDescription.length > previewChars) {
buffer += ",\u2026";
break;
}
if (i)
buffer += ", ";
buffer += itemDescription;
}
buffer += suffix;
return buffer;
},


get type()
{
return typeof this._value;
},


get subtype()
{
if (this._value === null)
return "null";

if (this._value instanceof Array)
return "array";

if (this._value instanceof Date)
return "date";

return undefined;
},


get hasChildren()
{
return typeof this._value === "object" && this._value !== null && !!Object.keys(this._value).length;
},


getOwnProperties: function(callback)
{
callback(this._children());
},


getAllProperties: function(callback)
{
callback(this._children());
},


_children: function()
{
if (!this.hasChildren)
return [];

function buildProperty(propName)
{
return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName]));
}
if (!this._cachedChildren)
this._cachedChildren = Object.keys(this._value || {}).map(buildProperty.bind(this));
return this._cachedChildren;
},


isError: function()
{
return false;
},


arrayLength: function()
{
return this._value instanceof Array ? this._value.length : 0;
}
}






WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor)
{
this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties"));
this.object = object;
this.ignoreHasOwnProperty = ignoreHasOwnProperty;
this.extraProperties = extraProperties;
this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectPropertyTreeElement;
this.editable = true;
this.skipProto = false;

WebInspector.PropertiesSection.call(this, title || "", subtitle);
}

WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100;

WebInspector.ObjectPropertiesSection.prototype = {
enableContextMenu: function()
{
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
},

_contextMenuEventFired: function(event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendApplicableItems(this.object);
contextMenu.show(event);
},

onpopulate: function()
{
this.update();
},

update: function()
{
if (this.object.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
this.propertiesTreeOutline.removeChildren();
WebInspector.ArrayGroupingTreeElement._populateArray(this.propertiesTreeOutline, this.object, 0, this.object.arrayLength() - 1);
return;
}

function callback(properties)
{
if (!properties)
return;
this.updateProperties(properties);
}

if (this.ignoreHasOwnProperty)
this.object.getAllProperties(callback.bind(this));
else
this.object.getOwnProperties(callback.bind(this));
},

updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer)
{
if (!rootTreeElementConstructor)
rootTreeElementConstructor = this.treeElementConstructor;

if (!rootPropertyComparer)
rootPropertyComparer = WebInspector.ObjectPropertiesSection.CompareProperties;

if (this.extraProperties)
for (var i = 0; i < this.extraProperties.length; ++i)
properties.push(this.extraProperties[i]);

properties.sort(rootPropertyComparer);

this.propertiesTreeOutline.removeChildren();

for (var i = 0; i < properties.length; ++i) {
if (this.skipProto && properties[i].name === "__proto__")
continue;
properties[i].parentObject = this.object;
}

this.propertiesForTest = properties;

for (var i = 0; i < properties.length; ++i)
this.propertiesTreeOutline.appendChild(new rootTreeElementConstructor(properties[i]));

if (!this.propertiesTreeOutline.children.length) {
var title = document.createElement("div");
title.className = "info";
title.textContent = this.emptyPlaceholder;
var infoElement = new TreeElement(title, null, false);
this.propertiesTreeOutline.appendChild(infoElement);
}
}
}

WebInspector.ObjectPropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;

WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, propertyB)
{
var a = propertyA.name;
var b = propertyB.name;
if (a === "__proto__")
return 1;
if (b === "__proto__")
return -1;





var diff = 0;
var chunk = /^\d+|^\D+/;
var chunka, chunkb, anum, bnum;
while (diff === 0) {
if (!a && b)
return -1;
if (!b && a)
return 1;
chunka = a.match(chunk)[0];
chunkb = b.match(chunk)[0];
anum = !isNaN(chunka);
bnum = !isNaN(chunkb);
if (anum && !bnum)
return -1;
if (bnum && !anum)
return 1;
if (anum && bnum) {
diff = chunka - chunkb;
if (diff === 0 && chunka.length !== chunkb.length) {
if (!+chunka && !+chunkb) 
return chunka.length - chunkb.length;
else
return chunkb.length - chunka.length;
}
} else if (chunka !== chunkb)
return (chunka < chunkb) ? -1 : 1;
a = a.substring(chunka.length);
b = b.substring(chunkb.length);
}
return diff;
}


WebInspector.ObjectPropertyTreeElement = function(property)
{
this.property = property;


TreeElement.call(this, "", null, false);
this.toggleOnClick = true;
this.selectable = false;
}

WebInspector.ObjectPropertyTreeElement.prototype = {
onpopulate: function()
{
return WebInspector.ObjectPropertyTreeElement.populate(this, this.property.value);
},

ondblclick: function(event)
{
if (this.property.writable)
this.startEditing(event);
},

onattach: function()
{
this.update();
},

update: function()
{
this.nameElement = document.createElement("span");
this.nameElement.className = "name";
this.nameElement.textContent = this.property.name;
if (!this.property.enumerable)
this.nameElement.addStyleClass("dimmed");

var separatorElement = document.createElement("span");
separatorElement.className = "separator";
separatorElement.textContent = ": ";

this.valueElement = document.createElement("span");
this.valueElement.className = "value";

var description = this.property.value.description;

if (this.property.wasThrown)
this.valueElement.textContent = "[Exception: " + description + "]";
else if (this.property.value.type === "string" && typeof description === "string") {
this.valueElement.textContent = "\"" + description.replace(/\n/g, "\u21B5") + "\"";
this.valueElement._originalTextContent = "\"" + description + "\"";
} else if (this.property.value.type === "function" && typeof description === "string") {
this.valueElement.textContent = /.*/.exec(description)[0].replace(/ +$/g, "");
this.valueElement._originalTextContent = description;
} else
this.valueElement.textContent = description;

if (this.property.wasThrown)
this.valueElement.addStyleClass("error");
if (this.property.value.subtype)
this.valueElement.addStyleClass("console-formatted-" + this.property.value.subtype);
else if (this.property.value.type)
this.valueElement.addStyleClass("console-formatted-" + this.property.value.type);

this.valueElement.addEventListener("contextmenu", this._contextMenuFired.bind(this, this.property.value), false);
this.valueElement.title = description || "";

this.listItemElement.removeChildren();

this.listItemElement.appendChild(this.nameElement);
this.listItemElement.appendChild(separatorElement);
this.listItemElement.appendChild(this.valueElement);
this.hasChildren = this.property.value.hasChildren && !this.property.wasThrown;
},

_contextMenuFired: function(value, event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendApplicableItems(value);
contextMenu.show(event);
},

updateSiblings: function()
{
if (this.parent.root)
this.treeOutline.section.update();
else
this.parent.shouldRefreshChildren = true;
},

renderPromptAsBlock: function()
{
return false;
},


elementAndValueToEdit: function(event)
{
return [this.valueElement, (typeof this.valueElement._originalTextContent === "string") ? this.valueElement._originalTextContent : undefined];
},

startEditing: function(event)
{
var elementAndValueToEdit = this.elementAndValueToEdit(event);
var elementToEdit = elementAndValueToEdit[0];
var valueToEdit = elementAndValueToEdit[1];

if (WebInspector.isBeingEdited(elementToEdit) || !this.treeOutline.section.editable || this._readOnly)
return;


if (typeof valueToEdit !== "undefined")
elementToEdit.textContent = valueToEdit;

var context = { expanded: this.expanded, elementToEdit: elementToEdit, previousContent: elementToEdit.textContent };


this.hasChildren = false;

this.listItemElement.addStyleClass("editing-sub-part");

this._prompt = new WebInspector.ObjectPropertyPrompt(this.editingCommitted.bind(this, null, elementToEdit.textContent, context.previousContent, context), this.editingCancelled.bind(this, null, context), this.renderPromptAsBlock());

function blurListener()
{
this.editingCommitted(null, elementToEdit.textContent, context.previousContent, context);
}

var proxyElement = this._prompt.attachAndStartEditing(elementToEdit, blurListener.bind(this));
window.getSelection().setBaseAndExtent(elementToEdit, 0, elementToEdit, 1);
proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, context), false);
},

editingEnded: function(context)
{
this._prompt.detach();
delete this._prompt;

this.listItemElement.scrollLeft = 0;
this.listItemElement.removeStyleClass("editing-sub-part");
if (context.expanded)
this.expand();
},

editingCancelled: function(element, context)
{
this.editingEnded(context);
this.update();
},

editingCommitted: function(element, userInput, previousContent, context)
{
if (userInput === previousContent)
return this.editingCancelled(element, context); 

this.editingEnded(context);
this.applyExpression(userInput, true);
},

_promptKeyDown: function(context, event)
{
if (isEnterKey(event)) {
event.consume(true);
return this.editingCommitted(null, context.elementToEdit.textContent, context.previousContent, context);
}
if (event.keyIdentifier === "U+001B") { 
event.consume();
return this.editingCancelled(null, context);
}
},

applyExpression: function(expression, updateInterface)
{
expression = expression.trim();
var expressionLength = expression.length;
function callback(error)
{
if (!updateInterface)
return;

if (error)
this.update();

if (!expressionLength) {

this.parent.removeChild(this);
} else {

this.updateSiblings();
}
};
this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback.bind(this));
}
}


WebInspector.ObjectPropertyTreeElement.populate = function(treeElement, value) {
if (treeElement.children.length && !treeElement.shouldRefreshChildren)
return;

if (value.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
treeElement.removeChildren();
WebInspector.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1);
return;
}

function callback(properties)
{
treeElement.removeChildren();
if (!properties)
return;

properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
if (treeElement.treeOutline.section.skipProto && properties[i].name === "__proto__")
continue;
properties[i].parentObject = value;
treeElement.appendChild(new treeElement.treeOutline.section.treeElementConstructor(properties[i]));
}
if (value.type === "function")
treeElement.appendChild(new WebInspector.FunctionScopeMainTreeElement(value));
}

value.getOwnProperties(callback);
}

WebInspector.ObjectPropertyTreeElement.prototype.__proto__ = TreeElement.prototype;


WebInspector.FunctionScopeMainTreeElement = function(remoteObject)
{
TreeElement.call(this, "<function scope>", null, false);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
this.hasChildren = true;
}

WebInspector.FunctionScopeMainTreeElement.prototype = {
onpopulate: function()
{
if (this.children.length && !this.shouldRefreshChildren)
return;

function didGetDetails(error, response)
{
if (error) {
console.error(error);
return;
}
this.removeChildren();

var scopeChain = response.scopeChain;
for (var i = 0; i < scopeChain.length; ++i) {
var scope = scopeChain[i];
var title = null;
var isTrueObject;

switch (scope.type) {
case "local":

title = WebInspector.UIString("Local");
isTrueObject = false;
break;
case "closure":
title = WebInspector.UIString("Closure");
isTrueObject = false;
break;
case "catch":
title = WebInspector.UIString("Catch");
isTrueObject = false;
break;
case "with":
title = WebInspector.UIString("With Block");
isTrueObject = true;
break;
case "global":
title = WebInspector.UIString("Global");
isTrueObject = true;
break;
}

var remoteObject = WebInspector.RemoteObject.fromPayload(scope.object);
if (isTrueObject) {
var property = WebInspector.RemoteObjectProperty.fromScopeValue(title, remoteObject);
property.parentObject = null;
this.appendChild(new this.treeOutline.section.treeElementConstructor(property));
} else {
var scopeTreeElement = new WebInspector.ScopeTreeElement(title, null, remoteObject);
this.appendChild(scopeTreeElement);
}
}

}
DebuggerAgent.getFunctionDetails(this._remoteObject.objectId, didGetDetails.bind(this));
}
};

WebInspector.FunctionScopeMainTreeElement.prototype.__proto__ = TreeElement.prototype;


WebInspector.ScopeTreeElement = function(title, subtitle, remoteObject)
{

TreeElement.call(this, title, null, false);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
this.hasChildren = true;
}

WebInspector.ScopeTreeElement.prototype = {
onpopulate: function()
{
return WebInspector.ObjectPropertyTreeElement.populate(this, this._remoteObject);
}
};

WebInspector.ScopeTreeElement.prototype.__proto__ = TreeElement.prototype;


WebInspector.ArrayGroupingTreeElement = function(object, fromIndex, toIndex, propertyCount)
{
TreeElement.call(this, String.sprintf("[%d \u2026 %d]", fromIndex, toIndex), undefined, true);
this._fromIndex = fromIndex;
this._toIndex = toIndex;
this._object = object;
this._readOnly = true;
this._propertyCount = propertyCount;
this._populated = false;
}

WebInspector.ArrayGroupingTreeElement._bucketThreshold = 100;


WebInspector.ArrayGroupingTreeElement._populateArray = function(treeElement, object, fromIndex, toIndex)
{
WebInspector.ArrayGroupingTreeElement._populateRanges(treeElement, object, fromIndex, toIndex, true);
}


WebInspector.ArrayGroupingTreeElement._populateRanges = function(treeElement, object, fromIndex, toIndex, topLevel)
{
object.callFunctionJSON(packRanges, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._bucketThreshold}], callback.bind(this));


function packRanges(fromIndex, toIndex, bucketThreshold)
{
var count = 0;
for (var i = fromIndex; i <= toIndex; ++i) {
var value = this[i];
if (typeof value !== "undefined")
++count;
}

var bucketSize = count;
if (count <= bucketThreshold)
bucketSize = count;
else
bucketSize = Math.pow(bucketThreshold, Math.floor(Math.log(count) / Math.log(bucketThreshold)));

var ranges = [];
count = 0;
var groupStart = -1;
var groupEnd = 0;
for (var i = fromIndex; i <= toIndex; ++i) {
var value = this[i];
if (typeof value === "undefined")
continue;

if (groupStart === -1)
groupStart = i;

groupEnd = i;
if (++count === bucketSize) {
ranges.push([groupStart, groupEnd, count]);
count = 0;
groupStart = -1;
}
}

if (count > 0)
ranges.push([groupStart, groupEnd, count]);
return ranges;
}

function callback(ranges)
{
if (ranges.length == 1)
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, ranges[0][0], ranges[0][1]);
else {
for (var i = 0; i < ranges.length; ++i) {
var fromIndex = ranges[i][0];
var toIndex = ranges[i][1];
var count = ranges[i][2];
if (fromIndex == toIndex)
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, fromIndex, toIndex);
else
treeElement.appendChild(new WebInspector.ArrayGroupingTreeElement(object, fromIndex, toIndex, count));
}
}
if (topLevel)
WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties(treeElement, object);
}
}


WebInspector.ArrayGroupingTreeElement._populateAsFragment = function(treeElement, object, fromIndex, toIndex)
{
object.callFunction(buildArrayFragment, [{value: fromIndex}, {value: toIndex}], processArrayFragment.bind(this));


function buildArrayFragment(fromIndex, toIndex)
{
var result = Object.create(null);
for (var i = fromIndex; i <= toIndex; ++i) {
var value = this[i];
if (typeof value !== "undefined")
result[i] = value;
}
return result;
}

function processArrayFragment(arrayFragment)
{
arrayFragment.getAllProperties(processProperties.bind(this));
}


function processProperties(properties)
{
if (!properties)
return;

properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this._object;
var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]);
childTreeElement._readOnly = true;
treeElement.appendChild(childTreeElement);
}
}
}


WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties = function(treeElement, object)
{
object.callFunction(buildObjectFragment, undefined, processObjectFragment.bind(this));


function buildObjectFragment()
{
var result = Object.create(this.__proto__);
var names = Object.getOwnPropertyNames(this);
for (var i = 0; i < names.length; ++i) {
var name = names[i];
if (!isNaN(name))
continue;
var descriptor = Object.getOwnPropertyDescriptor(this, name);
if (descriptor)
Object.defineProperty(result, name, descriptor);
}
return result;
}

function processObjectFragment(arrayFragment)
{
arrayFragment.getOwnProperties(processProperties.bind(this));
}


function processProperties(properties)
{
if (!properties)
return;

properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this._object;
var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]);
childTreeElement._readOnly = true;
treeElement.appendChild(childTreeElement);
}
}
}

WebInspector.ArrayGroupingTreeElement.prototype = {
onpopulate: function()
{
if (this._populated)
return;

this._populated = true;

if (this._propertyCount >= WebInspector.ArrayGroupingTreeElement._bucketThreshold) {
WebInspector.ArrayGroupingTreeElement._populateRanges(this, this._object, this._fromIndex, this._toIndex, false);
return;
}
WebInspector.ArrayGroupingTreeElement._populateAsFragment(this, this._object, this._fromIndex, this._toIndex);
},

onattach: function()
{
this.listItemElement.addStyleClass("name");
}
}

WebInspector.ArrayGroupingTreeElement.prototype.__proto__ = TreeElement.prototype;


WebInspector.ObjectPropertyPrompt = function(commitHandler, cancelHandler, renderAsBlock)
{
const ExpressionStopCharacters = " =:[({;,!+-*/&|^<>."; 
WebInspector.TextPrompt.call(this, WebInspector.consoleView.completionsForTextPrompt.bind(WebInspector.consoleView), ExpressionStopCharacters);
this.setSuggestBoxEnabled("generic-suggest");
if (renderAsBlock)
this.renderAsBlock();
}

WebInspector.ObjectPropertyPrompt.prototype.__proto__ = WebInspector.TextPrompt.prototype;






WebInspector.ObjectPopoverHelper = function(panelElement, getAnchor, queryObject, onHide, disableOnClick)
{
WebInspector.PopoverHelper.call(this, panelElement, getAnchor, this._showObjectPopover.bind(this), this._onHideObjectPopover.bind(this), disableOnClick);
this._queryObject = queryObject;
this._onHideCallback = onHide;
this._popoverObjectGroup = "popover";
panelElement.addEventListener("scroll", this.hidePopover.bind(this), true);
};

WebInspector.ObjectPopoverHelper.prototype = {

_showObjectPopover: function(element, popover)
{

function showObjectPopover(result, wasThrown, anchorOverride)
{
if (popover.disposed)
return;
if (wasThrown) {
this.hidePopover();
return;
}

var anchorElement = anchorOverride || element;

var popoverContentElement = null;
if (result.type !== "object") {
popoverContentElement = document.createElement("span");
popoverContentElement.className = "monospace console-formatted-" + result.type;
popoverContentElement.style.whiteSpace = "pre";
popoverContentElement.textContent = result.description;
if (result.type === "function") {
function didGetDetails(error, response)
{
if (error) {
console.error(error);
return;
}
var container = document.createElement("div");
container.style.display = "inline-block";

var title = container.createChild("div", "function-popover-title source-code");
var functionName = title.createChild("span", "function-name");
functionName.textContent = response.name || response.inferredName || response.displayName || WebInspector.UIString("(anonymous function)");

this._linkifier = new WebInspector.Linkifier();
var rawLocation =   response.location;
var link = this._linkifier.linkifyRawLocation(rawLocation, "function-location-link");
if (link)
title.appendChild(link);

container.appendChild(popoverContentElement);

popover.show(container, anchorElement);
}
DebuggerAgent.getFunctionDetails(result.objectId, didGetDetails.bind(this));
return;
}
if (result.type === "string")
popoverContentElement.textContent = "\"" + popoverContentElement.textContent + "\"";
popover.show(popoverContentElement, anchorElement);
} else {
popoverContentElement = document.createElement("div");

this._titleElement = document.createElement("div");
this._titleElement.className = "source-frame-popover-title monospace";
this._titleElement.textContent = result.description;
popoverContentElement.appendChild(this._titleElement);

var section = new WebInspector.ObjectPropertiesSection(result);

if (result.description.substr(0, 4) === "HTML") {
this._sectionUpdateProperties = section.updateProperties.bind(section);
section.updateProperties = this._updateHTMLId.bind(this);
}
section.expanded = true;
section.element.addStyleClass("source-frame-popover-tree");
section.headerElement.addStyleClass("hidden");
popoverContentElement.appendChild(section.element);

const popoverWidth = 300;
const popoverHeight = 250;
popover.show(popoverContentElement, anchorElement, popoverWidth, popoverHeight);
}
}
this._queryObject(element, showObjectPopover.bind(this), this._popoverObjectGroup);
},

_onHideObjectPopover: function()
{
if (this._linkifier) {
this._linkifier.reset();
delete this._linkifier;
}
if (this._onHideCallback)
this._onHideCallback();
RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup);
},

_updateHTMLId: function(properties, rootTreeElementConstructor, rootPropertyComparer)
{
for (var i = 0; i < properties.length; ++i) {
if (properties[i].name === "id") {
if (properties[i].value.description)
this._titleElement.textContent += "#" + properties[i].value.description;
break;
}
}
this._sectionUpdateProperties(properties, rootTreeElementConstructor, rootPropertyComparer);
}
}

WebInspector.ObjectPopoverHelper.prototype.__proto__ = WebInspector.PopoverHelper.prototype;






WebInspector.NativeBreakpointsSidebarPane = function(title)
{
WebInspector.SidebarPane.call(this, title);

this.listElement = document.createElement("ol");
this.listElement.className = "breakpoint-list";

this.emptyElement = document.createElement("div");
this.emptyElement.className = "info";
this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");

this.bodyElement.appendChild(this.emptyElement);
}

WebInspector.NativeBreakpointsSidebarPane.prototype = {
_addListElement: function(element, beforeElement)
{
if (beforeElement)
this.listElement.insertBefore(element, beforeElement);
else {
if (!this.listElement.firstChild) {
this.bodyElement.removeChild(this.emptyElement);
this.bodyElement.appendChild(this.listElement);
}
this.listElement.appendChild(element);
}
},

_removeListElement: function(element)
{
this.listElement.removeChild(element);
if (!this.listElement.firstChild) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
},

_reset: function()
{
this.listElement.removeChildren();
if (this.listElement.parentElement) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
}
}

WebInspector.NativeBreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;






WebInspector.DOMBreakpointsSidebarPane = function()
{
WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("DOM Breakpoints"));

this._breakpointElements = {};

this._breakpointTypes = {
SubtreeModified: "subtree-modified",
AttributeModified: "attribute-modified",
NodeRemoved: "node-removed"
};
this._breakpointTypeLabels = {};
this._breakpointTypeLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
this._breakpointTypeLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
this._breakpointTypeLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");

this._contextMenuLabels = {};
this._contextMenuLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Subtree modifications" : "Subtree Modifications");
this._contextMenuLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Attributes modifications" : "Attributes Modifications");
this._contextMenuLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Node removal" : "Node Removal");

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
}

WebInspector.DOMBreakpointsSidebarPane.prototype = {
_inspectedURLChanged: function(event)
{
this._breakpointElements = {};
this._reset();
var url = event.data;
this._inspectedURL = url.removeURLFragment();
},

populateNodeContextMenu: function(node, contextMenu)
{
var nodeBreakpoints = {};
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node)
nodeBreakpoints[element._type] = true;
}

function toggleBreakpoint(type)
{
if (!nodeBreakpoints[type])
this._setBreakpoint(node, type, true);
else
this._removeBreakpoint(node, type);
this._saveBreakpoints();
}

var breakPointSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Break on..."));
for (var key in this._breakpointTypes) {
var type = this._breakpointTypes[key];
var label = this._contextMenuLabels[type];
breakPointSubMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints[type]);
}
},

createBreakpointHitStatusMessage: function(auxData, callback)
{
if (auxData.type === this._breakpointTypes.SubtreeModified) {
var targetNodeObject = WebInspector.RemoteObject.fromPayload(auxData["targetNode"]);
function didPushNodeToFrontend(targetNodeId)
{
if (targetNodeId)
targetNodeObject.release();
this._doCreateBreakpointHitStatusMessage(auxData, targetNodeId, callback);
}
targetNodeObject.pushNodeToFrontend(didPushNodeToFrontend.bind(this));
} else
this._doCreateBreakpointHitStatusMessage(auxData, null, callback);
},

_doCreateBreakpointHitStatusMessage: function (auxData, targetNodeId, callback)
{
var message;
var typeLabel = this._breakpointTypeLabels[auxData.type];
var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(auxData.nodeId);
var substitutions = [typeLabel, linkifiedNode];
var targetNode = "";
if (targetNodeId)
targetNode = WebInspector.DOMPresentationUtils.linkifyNodeById(targetNodeId);

if (auxData.type === this._breakpointTypes.SubtreeModified) {
if (auxData.insertion) {
if (targetNodeId !== auxData.nodeId) {
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";
substitutions.push(targetNode);
} else
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";
} else {
message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";
substitutions.push(targetNode);
}
} else
message = "Paused on a \"%s\" breakpoint set on %s.";

var element = document.createElement("span");
var formatters = {
s: function(substitution)
{
return substitution;
}
};
function append(a, b)
{
if (typeof b === "string")
b = document.createTextNode(b);
element.appendChild(b);
}
WebInspector.formatLocalized(message, substitutions, formatters, "", append);

callback(element);
},

_nodeRemoved: function(event)
{
var node = event.data.node;
this._removeBreakpointsForNode(event.data.node);
if (!node.children)
return;
for (var i = 0; i < node.children.length; ++i)
this._removeBreakpointsForNode(node.children[i]);
this._saveBreakpoints();
},

_removeBreakpointsForNode: function(node)
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node)
this._removeBreakpoint(element._node, element._type);
}
},

_setBreakpoint: function(node, type, enabled)
{
var breakpointId = this._createBreakpointId(node.id, type);
if (breakpointId in this._breakpointElements)
return;

var element = document.createElement("li");
element._node = node;
element._type = type;
element.addEventListener("contextmenu", this._contextMenu.bind(this, node, type), true);

var checkboxElement = document.createElement("input");
checkboxElement.className = "checkbox-elem";
checkboxElement.type = "checkbox";
checkboxElement.checked = enabled;
checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, node, type), false);
element._checkboxElement = checkboxElement;
element.appendChild(checkboxElement);

var labelElement = document.createElement("span");
element.appendChild(labelElement);

var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(node.id);
linkifiedNode.addStyleClass("monospace");
labelElement.appendChild(linkifiedNode);

var description = document.createElement("div");
description.className = "source-text";
description.textContent = this._breakpointTypeLabels[type];
labelElement.appendChild(description);

var currentElement = this.listElement.firstChild;
while (currentElement) {
if (currentElement._type && currentElement._type < element._type)
break;
currentElement = currentElement.nextSibling;
}
this._addListElement(element, currentElement);
this._breakpointElements[breakpointId] = element;
if (enabled)
DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
},

_removeAllBreakpoints: function()
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
this._removeBreakpoint(element._node, element._type);
}
this._saveBreakpoints();
},

_removeBreakpoint: function(node, type)
{
var breakpointId = this._createBreakpointId(node.id, type);
var element = this._breakpointElements[breakpointId];
if (!element)
return;

this._removeListElement(element);
delete this._breakpointElements[breakpointId];
if (element._checkboxElement.checked)
DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
},

_contextMenu: function(node, type, event)
{
var contextMenu = new WebInspector.ContextMenu();
function removeBreakpoint()
{
this._removeBreakpoint(node, type);
this._saveBreakpoints();
}
contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeBreakpoint.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all DOM breakpoints" : "Remove All DOM Breakpoints"), this._removeAllBreakpoints.bind(this));
contextMenu.show(event);
},

_checkboxClicked: function(node, type, event)
{
if (event.target.checked)
DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
else
DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
this._saveBreakpoints();
},

highlightBreakpoint: function(auxData)
{
var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type);
var element = this._breakpointElements[breakpointId];
if (!element)
return;
this.expanded = true;
element.addStyleClass("breakpoint-hit");
this._highlightedElement = element;
},

clearBreakpointHighlight: function()
{
if (this._highlightedElement) {
this._highlightedElement.removeStyleClass("breakpoint-hit");
delete this._highlightedElement;
}
},

_createBreakpointId: function(nodeId, type)
{
return nodeId + ":" + type;
},

_saveBreakpoints: function()
{
var breakpoints = [];
var storedBreakpoints = WebInspector.settings.domBreakpoints.get();
for (var i = 0; i < storedBreakpoints.length; ++i) {
var breakpoint = storedBreakpoints[i];
if (breakpoint.url !== this._inspectedURL)
breakpoints.push(breakpoint);
}
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
breakpoints.push({ url: this._inspectedURL, path: element._node.path(), type: element._type, enabled: element._checkboxElement.checked });
}
WebInspector.settings.domBreakpoints.set(breakpoints);
},

restoreBreakpoints: function()
{
var pathToBreakpoints = {};

function didPushNodeByPathToFrontend(path, nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return;

var breakpoints = pathToBreakpoints[path];
for (var i = 0; i < breakpoints.length; ++i)
this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled);
}

var breakpoints = WebInspector.settings.domBreakpoints.get();
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint.url !== this._inspectedURL)
continue;
var path = breakpoint.path;
if (!pathToBreakpoints[path]) {
pathToBreakpoints[path] = [];
WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
}
pathToBreakpoints[path].push(breakpoint);
}
}
}

WebInspector.DOMBreakpointsSidebarPane.prototype.__proto__ = WebInspector.NativeBreakpointsSidebarPane.prototype;






WebInspector.Color = function(str)
{
this.value = str;
this._parse();
}


WebInspector.Color.fromRGBA = function(r, g, b, a)
{
return new WebInspector.Color("rgba(" + r + "," + g + "," + b + "," + (typeof a === "undefined" ? 1 : a) + ")");
}

WebInspector.Color.fromRGB = function(r, g, b)
{
return new WebInspector.Color("rgb(" + r + "," + g + "," + b + ")");
}

WebInspector.Color.prototype = {

get shorthex()
{
if ("_short" in this)
return this._short;

if (!this.simple)
return "";

var hex = this.hex;
if (hex.charAt(0) === hex.charAt(1) && hex.charAt(2) === hex.charAt(3) && hex.charAt(4) === hex.charAt(5))
this._short = hex.charAt(0) + hex.charAt(2) + hex.charAt(4);
else
this._short = hex;

return this._short;
},


get hex()
{
if (!this.simple)
return "";

return this._hex;
},

set hex(x)
{
this._hex = x;
},


get rgb()
{
if (this._rgb)
return this._rgb;

if (this.simple)
this._rgb = this._hexToRGB(this.hex);
else {
var rgba = this.rgba;
this._rgb = [rgba[0], rgba[1], rgba[2]];
}

return this._rgb;
},

set rgb(x)
{
this._rgb = x;
},


get hsl()
{
if (this._hsl)
return this._hsl;

this._hsl = this._rgbToHSL(this.rgb);
return this._hsl;
},

set hsl(x)
{
this._hsl = x;
},


get nickname()
{
if (typeof this._nickname !== "undefined") 
return this._nickname;
else
return "";
},

set nickname(x)
{
this._nickname = x;
},


get rgba()
{
return this._rgba;
},

set rgba(x)
{
this._rgba = x;
},


get hsla()
{
return this._hsla;
},

set hsla(x)
{
this._hsla = x;
},


hasShortHex: function()
{
var shorthex = this.shorthex;
return (!!shorthex && shorthex.length === 3);
},


toString: function(format)
{
if (!format)
format = this.format;

switch (format) {
case "original":
return this.value;
case "rgb":
return "rgb(" + this.rgb.join(", ") + ")";
case "rgba":
return "rgba(" + this.rgba.join(", ") + ")";
case "hsl":
var hsl = this.hsl;
return "hsl(" + hsl[0] + ", " + hsl[1] + "%, " + hsl[2] + "%)";
case "hsla":
var hsla = this.hsla;
return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")";
case "hex":
return "#" + this.hex;
case "shorthex":
return "#" + this.shorthex;
case "nickname":
return this.nickname;
}

throw "invalid color format";
},


toProtocolRGBA: function()
{
if (this._protocolRGBA)
return this._protocolRGBA;

var components = this.rgba;
if (components)
this._protocolRGBA = { r: Number(components[0]), g: Number(components[1]), b: Number(components[2]), a: Number(components[3]) };
else {
components = this.rgb;
this._protocolRGBA = { r: Number(components[0]), g: Number(components[1]), b: Number(components[2]) };
}
return this._protocolRGBA;
},


_clamp: function(value, min, max)
{
if (value < min)
return min;
if (value > max)
return max;
return value;
},


_individualRGBValueToFloatValue: function(rgbValue)
{
if (typeof rgbValue === "number")
return this._clamp(rgbValue, 0, 255);

if (rgbValue.indexOf("%") === -1) {
var intValue = parseInt(rgbValue, 10);
return this._clamp(intValue, 0, 255);
}

var percentValue = parseFloat(rgbValue);
return this._clamp(percentValue, 0, 100) * 2.55;
},


_individualRGBValueToHexValue: function(rgbValue)
{
var floatValue = this._individualRGBValueToFloatValue(rgbValue);
var hex = Math.round(floatValue).toString(16);
if (hex.length === 1)
hex = "0" + hex;
return hex;
},


_rgbStringsToHex: function(rgb)
{
var r = this._individualRGBValueToHexValue(rgb[0]);
var g = this._individualRGBValueToHexValue(rgb[1]);
var b = this._individualRGBValueToHexValue(rgb[2]);
return (r + g + b).toUpperCase();
},


_rgbToHex: function(rgb)
{
var r = this._individualRGBValueToHexValue(rgb[0]);
var g = this._individualRGBValueToHexValue(rgb[1]);
var b = this._individualRGBValueToHexValue(rgb[2]);
return (r + g + b).toUpperCase();
},


_hexToRGB: function(hex)
{
var r = parseInt(hex.substring(0,2), 16);
var g = parseInt(hex.substring(2,4), 16);
var b = parseInt(hex.substring(4,6), 16);

return [r, g, b];
},


_rgbToHSL: function(rgb)
{
var r = this._individualRGBValueToFloatValue(rgb[0]) / 255;
var g = this._individualRGBValueToFloatValue(rgb[1]) / 255;
var b = this._individualRGBValueToFloatValue(rgb[2]) / 255;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var diff = max - min;
var add = max + min;

if (min === max)
var h = 0;
else if (r === max)
var h = ((60 * (g - b) / diff) + 360) % 360;
else if (g === max)
var h = (60 * (b - r) / diff) + 120;
else
var h = (60 * (r - g) / diff) + 240;

var l = 0.5 * add;

if (l === 0)
var s = 0;
else if (l === 1)
var s = 1;
else if (l <= 0.5)
var s = diff / add;
else
var s = diff / (2 - add);

h = Math.round(h);
s = Math.round(s*100);
l = Math.round(l*100);

return [h, s, l];
},


_hslToRGB: function(hsl)
{
var h = parseFloat(hsl[0]) / 360;
var s = parseFloat(hsl[1]) / 100;
var l = parseFloat(hsl[2]) / 100;

if (s < 0)
s = 0;

if (l <= 0.5)
var q = l * (1 + s);
else
var q = l + s - (l * s);

var p = 2 * l - q;

var tr = h + (1 / 3);
var tg = h;
var tb = h - (1 / 3);

var r = Math.round(hueToRGB(p, q, tr) * 255);
var g = Math.round(hueToRGB(p, q, tg) * 255);
var b = Math.round(hueToRGB(p, q, tb) * 255);
return [r, g, b];

function hueToRGB(p, q, h) {
if (h < 0)
h += 1;
else if (h > 1)
h -= 1;

if ((h * 6) < 1)
return p + (q - p) * h * 6;
else if ((h * 2) < 1)
return q;
else if ((h * 3) < 2)
return p + (q - p) * ((2 / 3) - h) * 6;
else
return p;
}
},


_rgbaToHSLA: function(rgba, alpha)
{
var hsl = this._rgbToHSL(rgba)
hsl.push(alpha);
return hsl;
},


_hslaToRGBA: function(hsla, alpha)
{
var rgb = this._hslToRGB(hsla);
rgb.push(alpha);
return rgb;
},

_parse: function()
{

var value = this.value.toLowerCase().replace(/%|\s+/g, "");
if (value in WebInspector.Color.AdvancedNickNames) {
this.format = "nickname";
var set = WebInspector.Color.AdvancedNickNames[value];
this.simple = false;
this.rgba = set[0];
this.hsla = set[1];
this.nickname = set[2];
this.alpha = set[0][3];
return;
}


var simple = /^(?:#([0-9a-f]{3,6})|rgb\(([^)]+)\)|(\w+)|hsl\(([^)]+)\))$/i;
var match = this.value.match(simple);
if (match) {
this.simple = true;

if (match[1]) { 
var hex = match[1].toUpperCase();
if (hex.length === 3) {
this.format = "shorthex";
this.hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
} else {
this.format = "hex";
this.hex = hex;
}
} else if (match[2]) { 
this.format = "rgb";
var rgb = match[2].split(/\s*,\s*/);
this.rgb = rgb;
this.hex = this._rgbStringsToHex(rgb);
} else if (match[3]) { 
var nickname = match[3].toLowerCase();
if (nickname in WebInspector.Color.Nicknames) {
this.format = "nickname";
this.hex = WebInspector.Color.Nicknames[nickname];
} else 
throw "unknown color name";
} else if (match[4]) { 
this.format = "hsl";
var hsl = match[4].replace(/%/g, "").split(/\s*,\s*/);
this.hsl = hsl;
this.rgb = this._hslToRGB(hsl);
this.hex = this._rgbToHex(this.rgb);
}


var hex = this.hex;
if (hex && hex in WebInspector.Color.HexTable) {
var set = WebInspector.Color.HexTable[hex];
this.rgb = set[0];
this.hsl = set[1];
this.nickname = set[2];
}

return;
}


var advanced = /^(?:rgba\(([^)]+)\)|hsla\(([^)]+)\))$/;
match = this.value.match(advanced);
if (match) {
this.simple = false;
if (match[1]) { 
this.format = "rgba";
this.rgba = match[1].split(/\s*,\s*/);
this.rgba[3] = this.alpha = this._clamp(this.rgba[3], 0, 1);
this.hsla = this._rgbaToHSLA(this.rgba, this.alpha);
} else if (match[2]) { 
this.format = "hsla";
this.hsla = match[2].replace(/%/g, "").split(/\s*,\s*/);
this.hsla[3] = this.alpha = this._clamp(this.hsla[3], 0, 1);
this.rgba = this._hslaToRGBA(this.hsla, this.alpha);
}

return;
}


throw "could not parse color";
}
}


WebInspector.Color.HexTable = {
"000000": [[0, 0, 0], [0, 0, 0], "black"],
"000080": [[0, 0, 128], [240, 100, 25], "navy"],
"00008B": [[0, 0, 139], [240, 100, 27], "darkBlue"],
"0000CD": [[0, 0, 205], [240, 100, 40], "mediumBlue"],
"0000FF": [[0, 0, 255], [240, 100, 50], "blue"],
"006400": [[0, 100, 0], [120, 100, 20], "darkGreen"],
"008000": [[0, 128, 0], [120, 100, 25], "green"],
"008080": [[0, 128, 128], [180, 100, 25], "teal"],
"008B8B": [[0, 139, 139], [180, 100, 27], "darkCyan"],
"00BFFF": [[0, 191, 255], [195, 100, 50], "deepSkyBlue"],
"00CED1": [[0, 206, 209], [181, 100, 41], "darkTurquoise"],
"00FA9A": [[0, 250, 154], [157, 100, 49], "mediumSpringGreen"],
"00FF00": [[0, 255, 0], [120, 100, 50], "lime"],
"00FF7F": [[0, 255, 127], [150, 100, 50], "springGreen"],
"00FFFF": [[0, 255, 255], [180, 100, 50], "cyan"],
"191970": [[25, 25, 112], [240, 64, 27], "midnightBlue"],
"1E90FF": [[30, 144, 255], [210, 100, 56], "dodgerBlue"],
"20B2AA": [[32, 178, 170], [177, 70, 41], "lightSeaGreen"],
"228B22": [[34, 139, 34], [120, 61, 34], "forestGreen"],
"2E8B57": [[46, 139, 87], [146, 50, 36], "seaGreen"],
"2F4F4F": [[47, 79, 79], [180, 25, 25], "darkSlateGray"],
"32CD32": [[50, 205, 50], [120, 61, 50], "limeGreen"],
"3CB371": [[60, 179, 113], [147, 50, 47], "mediumSeaGreen"],
"40E0D0": [[64, 224, 208], [174, 72, 56], "turquoise"],
"4169E1": [[65, 105, 225], [225, 73, 57], "royalBlue"],
"4682B4": [[70, 130, 180], [207, 44, 49], "steelBlue"],
"483D8B": [[72, 61, 139], [248, 39, 39], "darkSlateBlue"],
"48D1CC": [[72, 209, 204], [178, 60, 55], "mediumTurquoise"],
"4B0082": [[75, 0, 130], [275, 100, 25], "indigo"],
"556B2F": [[85, 107, 47], [82, 39, 30], "darkOliveGreen"],
"5F9EA0": [[95, 158, 160], [182, 25, 50], "cadetBlue"],
"6495ED": [[100, 149, 237], [219, 79, 66], "cornflowerBlue"],
"66CDAA": [[102, 205, 170], [160, 51, 60], "mediumAquaMarine"],
"696969": [[105, 105, 105], [0, 0, 41], "dimGray"],
"6A5ACD": [[106, 90, 205], [248, 53, 58], "slateBlue"],
"6B8E23": [[107, 142, 35], [80, 60, 35], "oliveDrab"],
"708090": [[112, 128, 144], [210, 13, 50], "slateGray"],
"778899": [[119, 136, 153], [210, 14, 53], "lightSlateGray"],
"7B68EE": [[123, 104, 238], [249, 80, 67], "mediumSlateBlue"],
"7CFC00": [[124, 252, 0], [90, 100, 49], "lawnGreen"],
"7FFF00": [[127, 255, 0], [90, 100, 50], "chartreuse"],
"7FFFD4": [[127, 255, 212], [160, 100, 75], "aquamarine"],
"800000": [[128, 0, 0], [0, 100, 25], "maroon"],
"800080": [[128, 0, 128], [300, 100, 25], "purple"],
"808000": [[128, 128, 0], [60, 100, 25], "olive"],
"808080": [[128, 128, 128], [0, 0, 50], "gray"],
"87CEEB": [[135, 206, 235], [197, 71, 73], "skyBlue"],
"87CEFA": [[135, 206, 250], [203, 92, 75], "lightSkyBlue"],
"8A2BE2": [[138, 43, 226], [271, 76, 53], "blueViolet"],
"8B0000": [[139, 0, 0], [0, 100, 27], "darkRed"],
"8B008B": [[139, 0, 139], [300, 100, 27], "darkMagenta"],
"8B4513": [[139, 69, 19], [25, 76, 31], "saddleBrown"],
"8FBC8F": [[143, 188, 143], [120, 25, 65], "darkSeaGreen"],
"90EE90": [[144, 238, 144], [120, 73, 75], "lightGreen"],
"9370D8": [[147, 112, 219], [260, 60, 65], "mediumPurple"],
"9400D3": [[148, 0, 211], [282, 100, 41], "darkViolet"],
"98FB98": [[152, 251, 152], [120, 93, 79], "paleGreen"],
"9932CC": [[153, 50, 204], [280, 61, 50], "darkOrchid"],
"9ACD32": [[154, 205, 50], [80, 61, 50], "yellowGreen"],
"A0522D": [[160, 82, 45], [19, 56, 40], "sienna"],
"A52A2A": [[165, 42, 42], [0, 59, 41], "brown"],
"A9A9A9": [[169, 169, 169], [0, 0, 66], "darkGray"],
"ADD8E6": [[173, 216, 230], [195, 53, 79], "lightBlue"],
"ADFF2F": [[173, 255, 47], [84, 100, 59], "greenYellow"],
"AFEEEE": [[175, 238, 238], [180, 65, 81], "paleTurquoise"],
"B0C4DE": [[176, 196, 222], [214, 41, 78], "lightSteelBlue"],
"B0E0E6": [[176, 224, 230], [187, 52, 80], "powderBlue"],
"B22222": [[178, 34, 34], [0, 68, 42], "fireBrick"],
"B8860B": [[184, 134, 11], [43, 89, 38], "darkGoldenrod"],
"BA55D3": [[186, 85, 211], [288, 59, 58], "mediumOrchid"],
"BC8F8F": [[188, 143, 143], [0, 25, 65], "rosyBrown"],
"BDB76B": [[189, 183, 107], [56, 38, 58], "darkKhaki"],
"C0C0C0": [[192, 192, 192], [0, 0, 75], "silver"],
"C71585": [[199, 21, 133], [322, 81, 43], "mediumVioletRed"],
"CD5C5C": [[205, 92, 92], [0, 53, 58], "indianRed"],
"CD853F": [[205, 133, 63], [30, 59, 53], "peru"],
"D2691E": [[210, 105, 30], [25, 75, 47], "chocolate"],
"D2B48C": [[210, 180, 140], [34, 44, 69], "tan"],
"D3D3D3": [[211, 211, 211], [0, 0, 83], "lightGrey"],
"D87093": [[219, 112, 147], [340, 60, 65], "paleVioletRed"],
"D8BFD8": [[216, 191, 216], [300, 24, 80], "thistle"],
"DA70D6": [[218, 112, 214], [302, 59, 65], "orchid"],
"DAA520": [[218, 165, 32], [43, 74, 49], "goldenrod"],
"DC143C": [[237, 164, 61], [35, 83, 58], "crimson"],
"DCDCDC": [[220, 220, 220], [0, 0, 86], "gainsboro"],
"DDA0DD": [[221, 160, 221], [300, 47, 75], "plum"],
"DEB887": [[222, 184, 135], [34, 57, 70], "burlyWood"],
"E0FFFF": [[224, 255, 255], [180, 100, 94], "lightCyan"],
"E6E6FA": [[230, 230, 250], [240, 67, 94], "lavender"],
"E9967A": [[233, 150, 122], [15, 72, 70], "darkSalmon"],
"EE82EE": [[238, 130, 238], [300, 76, 72], "violet"],
"EEE8AA": [[238, 232, 170], [55, 67, 80], "paleGoldenrod"],
"F08080": [[240, 128, 128], [0, 79, 72], "lightCoral"],
"F0E68C": [[240, 230, 140], [54, 77, 75], "khaki"],
"F0F8FF": [[240, 248, 255], [208, 100, 97], "aliceBlue"],
"F0FFF0": [[240, 255, 240], [120, 100, 97], "honeyDew"],
"F0FFFF": [[240, 255, 255], [180, 100, 97], "azure"],
"F4A460": [[244, 164, 96], [28, 87, 67], "sandyBrown"],
"F5DEB3": [[245, 222, 179], [39, 77, 83], "wheat"],
"F5F5DC": [[245, 245, 220], [60, 56, 91], "beige"],
"F5F5F5": [[245, 245, 245], [0, 0, 96], "whiteSmoke"],
"F5FFFA": [[245, 255, 250], [150, 100, 98], "mintCream"],
"F8F8FF": [[248, 248, 255], [240, 100, 99], "ghostWhite"],
"FA8072": [[250, 128, 114], [6, 93, 71], "salmon"],
"FAEBD7": [[250, 235, 215], [34, 78, 91], "antiqueWhite"],
"FAF0E6": [[250, 240, 230], [30, 67, 94], "linen"],
"FAFAD2": [[250, 250, 210], [60, 80, 90], "lightGoldenrodYellow"],
"FDF5E6": [[253, 245, 230], [39, 85, 95], "oldLace"],
"FF0000": [[255, 0, 0], [0, 100, 50], "red"],
"FF00FF": [[255, 0, 255], [300, 100, 50], "magenta"],
"FF1493": [[255, 20, 147], [328, 100, 54], "deepPink"],
"FF4500": [[255, 69, 0], [16, 100, 50], "orangeRed"],
"FF6347": [[255, 99, 71], [9, 100, 64], "tomato"],
"FF69B4": [[255, 105, 180], [330, 100, 71], "hotPink"],
"FF7F50": [[255, 127, 80], [16, 100, 66], "coral"],
"FF8C00": [[255, 140, 0], [33, 100, 50], "darkOrange"],
"FFA07A": [[255, 160, 122], [17, 100, 74], "lightSalmon"],
"FFA500": [[255, 165, 0], [39, 100, 50], "orange"],
"FFB6C1": [[255, 182, 193], [351, 100, 86], "lightPink"],
"FFC0CB": [[255, 192, 203], [350, 100, 88], "pink"],
"FFD700": [[255, 215, 0], [51, 100, 50], "gold"],
"FFDAB9": [[255, 218, 185], [28, 100, 86], "peachPuff"],
"FFDEAD": [[255, 222, 173], [36, 100, 84], "navajoWhite"],
"FFE4B5": [[255, 228, 181], [38, 100, 85], "moccasin"],
"FFE4C4": [[255, 228, 196], [33, 100, 88], "bisque"],
"FFE4E1": [[255, 228, 225], [6, 100, 94], "mistyRose"],
"FFEBCD": [[255, 235, 205], [36, 100, 90], "blanchedAlmond"],
"FFEFD5": [[255, 239, 213], [37, 100, 92], "papayaWhip"],
"FFF0F5": [[255, 240, 245], [340, 100, 97], "lavenderBlush"],
"FFF5EE": [[255, 245, 238], [25, 100, 97], "seaShell"],
"FFF8DC": [[255, 248, 220], [48, 100, 93], "cornsilk"],
"FFFACD": [[255, 250, 205], [54, 100, 90], "lemonChiffon"],
"FFFAF0": [[255, 250, 240], [40, 100, 97], "floralWhite"],
"FFFAFA": [[255, 250, 250], [0, 100, 99], "snow"],
"FFFF00": [[255, 255, 0], [60, 100, 50], "yellow"],
"FFFFE0": [[255, 255, 224], [60, 100, 94], "lightYellow"],
"FFFFF0": [[255, 255, 240], [60, 100, 97], "ivory"],
"FFFFFF": [[255, 255, 255], [0, 100, 100], "white"]
};


WebInspector.Color.Nicknames = {
"aliceblue": "F0F8FF",
"antiquewhite": "FAEBD7",
"aqua": "00FFFF",
"aquamarine": "7FFFD4",
"azure": "F0FFFF",
"beige": "F5F5DC",
"bisque": "FFE4C4",
"black": "000000",
"blanchedalmond": "FFEBCD",
"blue": "0000FF",
"blueviolet": "8A2BE2",
"brown": "A52A2A",
"burlywood": "DEB887",
"cadetblue": "5F9EA0",
"chartreuse": "7FFF00",
"chocolate": "D2691E",
"coral": "FF7F50",
"cornflowerblue": "6495ED",
"cornsilk": "FFF8DC",
"crimson": "DC143C",
"cyan": "00FFFF",
"darkblue": "00008B",
"darkcyan": "008B8B",
"darkgoldenrod": "B8860B",
"darkgray": "A9A9A9",
"darkgreen": "006400",
"darkkhaki": "BDB76B",
"darkmagenta": "8B008B",
"darkolivegreen": "556B2F",
"darkorange": "FF8C00",
"darkorchid": "9932CC",
"darkred": "8B0000",
"darksalmon": "E9967A",
"darkseagreen": "8FBC8F",
"darkslateblue": "483D8B",
"darkslategray": "2F4F4F",
"darkturquoise": "00CED1",
"darkviolet": "9400D3",
"deeppink": "FF1493",
"deepskyblue": "00BFFF",
"dimgray": "696969",
"dodgerblue": "1E90FF",
"firebrick": "B22222",
"floralwhite": "FFFAF0",
"forestgreen": "228B22",
"fuchsia": "FF00FF",
"gainsboro": "DCDCDC",
"ghostwhite": "F8F8FF",
"gold": "FFD700",
"goldenrod": "DAA520",
"gray": "808080",
"green": "008000",
"greenyellow": "ADFF2F",
"honeydew": "F0FFF0",
"hotpink": "FF69B4",
"indianred": "CD5C5C",
"indigo": "4B0082",
"ivory": "FFFFF0",
"khaki": "F0E68C",
"lavender": "E6E6FA",
"lavenderblush": "FFF0F5",
"lawngreen": "7CFC00",
"lemonchiffon": "FFFACD",
"lightblue": "ADD8E6",
"lightcoral": "F08080",
"lightcyan": "E0FFFF",
"lightgoldenrodyellow": "FAFAD2",
"lightgreen": "90EE90",
"lightgrey": "D3D3D3",
"lightpink": "FFB6C1",
"lightsalmon": "FFA07A",
"lightseagreen": "20B2AA",
"lightskyblue": "87CEFA",
"lightslategray": "778899",
"lightsteelblue": "B0C4DE",
"lightyellow": "FFFFE0",
"lime": "00FF00",
"limegreen": "32CD32",
"linen": "FAF0E6",
"magenta": "FF00FF",
"maroon": "800000",
"mediumaquamarine": "66CDAA",
"mediumblue": "0000CD",
"mediumorchid": "BA55D3",
"mediumpurple": "9370DB",
"mediumseagreen": "3CB371",
"mediumslateblue": "7B68EE",
"mediumspringgreen": "00FA9A",
"mediumturquoise": "48D1CC",
"mediumvioletred": "C71585",
"midnightblue": "191970",
"mintcream": "F5FFFA",
"mistyrose": "FFE4E1",
"moccasin": "FFE4B5",
"navajowhite": "FFDEAD",
"navy": "000080",
"oldlace": "FDF5E6",
"olive": "808000",
"olivedrab": "6B8E23",
"orange": "FFA500",
"orangered": "FF4500",
"orchid": "DA70D6",
"palegoldenrod": "EEE8AA",
"palegreen": "98FB98",
"paleturquoise": "AFEEEE",
"palevioletred": "DB7093",
"papayawhip": "FFEFD5",
"peachpuff": "FFDAB9",
"peru": "CD853F",
"pink": "FFC0CB",
"plum": "DDA0DD",
"powderblue": "B0E0E6",
"purple": "800080",
"red": "FF0000",
"rosybrown": "BC8F8F",
"royalblue": "4169E1",
"saddlebrown": "8B4513",
"salmon": "FA8072",
"sandybrown": "F4A460",
"seagreen": "2E8B57",
"seashell": "FFF5EE",
"sienna": "A0522D",
"silver": "C0C0C0",
"skyblue": "87CEEB",
"slateblue": "6A5ACD",
"slategray": "708090",
"snow": "FFFAFA",
"springgreen": "00FF7F",
"steelblue": "4682B4",
"tan": "D2B48C",
"teal": "008080",
"thistle": "D8BFD8",
"tomato": "FF6347",
"turquoise": "40E0D0",
"violet": "EE82EE",
"wheat": "F5DEB3",
"white": "FFFFFF",
"whitesmoke": "F5F5F5",
"yellow": "FFFF00",
"yellowgreen": "9ACD32"
};


WebInspector.Color.AdvancedNickNames = {
"transparent": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
"rgba(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
"hsla(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
};

WebInspector.Color.PageHighlight = {
Content: WebInspector.Color.fromRGBA(111, 168, 220, .66),
ContentLight: WebInspector.Color.fromRGBA(111, 168, 220, .5),
ContentOutline: WebInspector.Color.fromRGBA(9, 83, 148),
Padding: WebInspector.Color.fromRGBA(147, 196, 125, .55),
PaddingLight: WebInspector.Color.fromRGBA(147, 196, 125, .4),
Border: WebInspector.Color.fromRGBA(255, 229, 153, .66),
BorderLight: WebInspector.Color.fromRGBA(255, 229, 153, .5),
Margin: WebInspector.Color.fromRGBA(246, 178, 107, .66),
MarginLight: WebInspector.Color.fromRGBA(246, 178, 107, .5)
}

WebInspector.Color.Format = {
Original: "original",
Nickname: "nickname",
HEX: "hex",
ShortHEX: "shorthex",
RGB: "rgb",
RGBA: "rgba",
HSL: "hsl",
HSLA: "hsla"
}






WebInspector.CSSCompletions = function(properties, acceptEmptyPrefix)
{
this._values = [];
this._longhands = {};
this._shorthands = {};
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
if (typeof property === "string") {
this._values.push(property);
continue;
}

var propertyName = property.name;
this._values.push(propertyName);

var longhands = properties[i].longhands;
if (longhands) {
this._longhands[propertyName] = longhands;
for (var j = 0; j < longhands.length; ++j) {
var longhandName = longhands[j];
var shorthands = this._shorthands[longhandName];
if (!shorthands) {
shorthands = [];
this._shorthands[longhandName] = shorthands;
}
shorthands.push(propertyName);
}
}
}
this._values.sort();
this._acceptEmptyPrefix = acceptEmptyPrefix;
}



WebInspector.CSSCompletions.cssPropertiesMetainfo = null;

WebInspector.CSSCompletions.requestCSSNameCompletions = function()
{
function propertyNamesCallback(error, properties)
{
if (!error)
WebInspector.CSSCompletions.cssPropertiesMetainfo = new WebInspector.CSSCompletions(properties, false);
}
CSSAgent.getSupportedCSSProperties(propertyNamesCallback);
}

WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet = function()
{
if (!WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet)
WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet = WebInspector.CSSCompletions.cssPropertiesMetainfo.keySet();
return WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet;
}

WebInspector.CSSCompletions.prototype = {
startsWith: function(prefix)
{
var firstIndex = this._firstIndexOfPrefix(prefix);
if (firstIndex === -1)
return [];

var results = [];
while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
results.push(this._values[firstIndex++]);
return results;
},

firstStartsWith: function(prefix)
{
var foundIndex = this._firstIndexOfPrefix(prefix);
return (foundIndex === -1 ? "" : this._values[foundIndex]);
},

_firstIndexOfPrefix: function(prefix)
{
if (!this._values.length)
return -1;
if (!prefix)
return this._acceptEmptyPrefix ? 0 : -1;

var maxIndex = this._values.length - 1;
var minIndex = 0;
var foundIndex;

do {
var middleIndex = (maxIndex + minIndex) >> 1;
if (this._values[middleIndex].startsWith(prefix)) {
foundIndex = middleIndex;
break;
}
if (this._values[middleIndex] < prefix)
minIndex = middleIndex + 1;
else
maxIndex = middleIndex - 1;
} while (minIndex <= maxIndex);

if (foundIndex === undefined)
return -1;

while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
foundIndex--;

return foundIndex;
},

keySet: function()
{
if (!this._keySet)
this._keySet = this._values.keySet();
return this._keySet;
},

next: function(str, prefix)
{
return this._closest(str, prefix, 1);
},

previous: function(str, prefix)
{
return this._closest(str, prefix, -1);
},

_closest: function(str, prefix, shift)
{
if (!str)
return "";

var index = this._values.indexOf(str);
if (index === -1)
return "";

if (!prefix) {
index = (index + this._values.length + shift) % this._values.length;
return this._values[index];
}

var propertiesWithPrefix = this.startsWith(prefix);
var j = propertiesWithPrefix.indexOf(str);
j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
return propertiesWithPrefix[j];
},


longhands: function(shorthand)
{
return this._longhands[shorthand];
},


shorthands: function(longhand)
{
return this._shorthands[longhand];
}
}





WebInspector.CSSKeywordCompletions = {}

WebInspector.CSSKeywordCompletions.forProperty = function(propertyName)
{
var acceptedKeywords = ["initial"];
if (propertyName in WebInspector.CSSKeywordCompletions._propertyKeywordMap)
acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._propertyKeywordMap[propertyName]);
if (propertyName in WebInspector.CSSKeywordCompletions._colorAwareProperties)
acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._colors);
if (propertyName in WebInspector.CSSKeywordCompletions.InheritedProperties)
acceptedKeywords.push("inherit");
return new WebInspector.CSSCompletions(acceptedKeywords, true);
}

WebInspector.CSSKeywordCompletions.isColorAwareProperty = function(propertyName)
{
return WebInspector.CSSKeywordCompletions._colorAwareProperties[propertyName] === true;
}

WebInspector.CSSKeywordCompletions.colors = function()
{
if (!WebInspector.CSSKeywordCompletions._colorsKeySet)
WebInspector.CSSKeywordCompletions._colorsKeySet = WebInspector.CSSKeywordCompletions._colors.keySet();
return WebInspector.CSSKeywordCompletions._colorsKeySet;
}


WebInspector.CSSKeywordCompletions.InheritedProperties = [
"azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
"empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "letter-spacing",
"line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "pitch-range",
"pitch", "quotes", "richness", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate", "stress",
"text-align", "text-indent", "text-transform", "text-shadow", "visibility", "voice-family", "volume", "white-space", "widows", "word-spacing"
].keySet();

WebInspector.CSSKeywordCompletions._colors = [
"aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "orange", "purple", "red",
"silver", "teal", "white", "yellow", "transparent", "currentcolor", "grey", "aliceblue", "antiquewhite",
"aquamarine", "azure", "beige", "bisque", "blanchedalmond", "blueviolet", "brown", "burlywood", "cadetblue",
"chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
"darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange",
"darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey",
"darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "gainsboro", "ghostwhite", "gold", "goldenrod", "greenyellow", "honeydew", "hotpink",
"indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
"lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
"limegreen", "linen", "magenta", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
"mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream",
"mistyrose", "moccasin", "navajowhite", "oldlace", "olivedrab", "orangered", "orchid", "palegoldenrod", "palegreen",
"paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "rosybrown",
"royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "skyblue", "slateblue",
"slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "thistle", "tomato", "turquoise", "violet",
"wheat", "whitesmoke", "yellowgreen"
];

WebInspector.CSSKeywordCompletions._colorAwareProperties = [
"background", "background-color", "background-image", "border", "border-color", "border-top", "border-right", "border-bottom",
"border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "box-shadow", "color",
"fill", "outline", "outline-color", "stroke", "text-line-through", "text-line-through-color", "text-overline", "text-overline-color",
"text-shadow", "text-underline", "text-underline-color", "-webkit-box-shadow", "-webkit-text-emphasis", "-webkit-text-emphasis-color"
].keySet();

WebInspector.CSSKeywordCompletions._propertyKeywordMap = {
"table-layout": [
"auto", "fixed"
],
"visibility": [
"hidden", "visible", "collapse"
],
"background-repeat": [
"repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"
],
"text-underline": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
],
"content": [
"list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote"
],
"list-style-image": [
"none"
],
"clear": [
"none", "left", "right", "both"
],
"text-underline-mode": [
"continuous", "skip-white-space"
],
"overflow-x": [
"hidden", "auto", "visible", "overlay", "scroll"
],
"stroke-linejoin": [
"round", "miter", "bevel"
],
"baseline-shift": [
"baseline", "sub", "super"
],
"border-bottom-width": [
"medium", "thick", "thin"
],
"marquee-speed": [
"normal", "slow", "fast"
],
"margin-top-collapse": [
"collapse", "separate", "discard"
],
"max-height": [
"none"
],
"box-orient": [
"horizontal", "vertical", "inline-axis", "block-axis"
],
"font-stretch": [
"normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
],
"-webkit-color-correction": [
"default", "srgb"
],
"text-underline-style": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
],
"text-overline-mode": [
"continuous", "skip-white-space"
],
"-webkit-background-composite": [
"highlight", "clear", "copy", "source-over", "source-in", "source-out", "source-atop", "destination-over",
"destination-in", "destination-out", "destination-atop", "xor", "plus-darker", "plus-lighter"
],
"border-left-width": [
"medium", "thick", "thin"
],
"-webkit-writing-mode": [
"lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
],
"text-line-through-mode": [
"continuous", "skip-white-space"
],
"border-collapse": [
"collapse", "separate"
],
"page-break-inside": [
"auto", "avoid"
],
"border-top-width": [
"medium", "thick", "thin"
],
"outline-color": [
"invert"
],
"text-line-through-style": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
],
"outline-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"cursor": [
"none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu",
"alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize",
"nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize",
"nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab",
"-webkit-grabbing"
],
"border-width": [
"medium", "thick", "thin"
],
"size": [
"a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
],
"background-size": [
"contain", "cover"
],
"direction": [
"ltr", "rtl"
],
"marquee-direction": [
"left", "right", "auto", "reverse", "forwards", "backwards", "ahead", "up", "down"
],
"enable-background": [
"accumulate", "new"
],
"float": [
"none", "left", "right"
],
"overflow-y": [
"hidden", "auto", "visible", "overlay", "scroll"
],
"margin-bottom-collapse": [
"collapse",  "separate", "discard"
],
"box-reflect": [
"left", "right", "above", "below"
],
"overflow": [
"hidden", "auto", "visible", "overlay", "scroll"
],
"text-rendering": [
"auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"
],
"text-align": [
"-webkit-auto", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center"
],
"list-style-position": [
"outside", "inside"
],
"margin-bottom": [
"auto"
],
"color-interpolation": [
"linearrgb"
],
"background-origin": [
"border-box", "content-box", "padding-box"
],
"word-wrap": [
"normal", "break-word"
],
"font-weight": [
"normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"
],
"margin-before-collapse": [
"collapse", "separate", "discard"
],
"text-overline-width": [
"normal", "medium", "auto", "thick", "thin"
],
"text-transform": [
"none", "capitalize", "uppercase", "lowercase"
],
"border-right-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"border-left-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"-webkit-text-emphasis": [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
],
"font-style": [
"italic", "oblique", "normal"
],
"speak": [
"none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation"
],
"text-line-through": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave", "continuous",
"skip-white-space"
],
"color-rendering": [
"auto", "optimizeSpeed", "optimizeQuality"
],
"list-style-type": [
"none", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali",
"cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam",
"mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal",
"lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar",
"ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede",
"ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez",
"ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo",
"ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre",
"ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede",
"ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede",
"ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian",
"lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha",
"katakana-iroha"
],
"-webkit-text-combine": [
"none", "horizontal"
],
"outline": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"font": [
"caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control",
"-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter",
"100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium",
"large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive",
"fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
],
"dominant-baseline": [
"middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging",
"mathematical", "use-script", "no-change", "reset-size"
],
"display": [
"none", "inline", "block", "list-item", "run-in", "compact", "inline-block", "table", "inline-table",
"table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group",
"table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box", "-wap-marquee"
],
"-webkit-text-emphasis-position": [
"over", "under"
],
"image-rendering": [
"auto", "optimizeSpeed", "optimizeQuality"
],
"alignment-baseline": [
"baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge",
"ideographic", "alphabetic", "hanging", "mathematical"
],
"outline-width": [
"medium", "thick", "thin"
],
"text-line-through-width": [
"normal", "medium", "auto", "thick", "thin"
],
"box-align": [
"baseline", "center", "stretch", "start", "end"
],
"border-right-width": [
"medium", "thick", "thin"
],
"border-top-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"line-height": [
"normal"
],
"text-overflow": [
"clip", "ellipsis"
],
"box-direction": [
"normal", "reverse"
],
"margin-after-collapse": [
"collapse", "separate", "discard"
],
"page-break-before": [
"left", "right", "auto", "always", "avoid"
],
"-webkit-hyphens": [
"none", "auto", "manual"
],
"border-image": [
"repeat", "stretch"
],
"text-decoration": [
"blink", "line-through", "overline", "underline"
],
"position": [
"absolute", "fixed", "relative", "static"
],
"font-family": [
"serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
],
"text-overflow-mode": [
"clip", "ellipsis"
],
"border-bottom-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"unicode-bidi": [
"normal", "bidi-override", "embed"
],
"clip-rule": [
"nonzero", "evenodd"
],
"margin-left": [
"auto"
],
"margin-top": [
"auto"
],
"zoom": [
"document", "reset"
],
"text-overline-style": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
],
"max-width": [
"none"
],
"empty-cells": [
"hide", "show"
],
"pointer-events": [
"none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke"
],
"letter-spacing": [
"normal"
],
"background-clip": [
"border-box", "content-box", "padding-box"
],
"-webkit-font-smoothing": [
"none", "auto", "antialiased", "subpixel-antialiased"
],
"border": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"font-size": [
"xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller",
"larger"
],
"font-variant": [
"small-caps", "normal"
],
"vertical-align": [
"baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle"
],
"marquee-style": [
"none", "scroll", "slide", "alternate"
],
"white-space": [
"normal", "nowrap", "pre", "pre-line", "pre-wrap"
],
"text-underline-width": [
"normal", "medium", "auto", "thick", "thin"
],
"box-lines": [
"single", "multiple"
],
"page-break-after": [
"left", "right", "auto", "always", "avoid"
],
"clip-path": [
"none"
],
"margin": [
"auto"
],
"marquee-repetition": [
"infinite"
],
"margin-right": [
"auto"
],
"-webkit-text-emphasis-style": [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
],
"-webkit-transform": [
"scale", "scaleX", "scaleY", "scale3d", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "skew", "skewX", "skewY", 
"translate", "translateX", "translateY", "translateZ", "translate3d", "matrix", "matrix3d", "perspective"
]
}






WebInspector.PanelEnablerView = function(identifier, headingText, disclaimerText, buttonTitle)
{
WebInspector.View.call(this);
this.registerRequiredCSS("panelEnablerView.css");

this.element.addStyleClass("panel-enabler-view");
this.element.addStyleClass(identifier);

this.contentElement = document.createElement("div");
this.contentElement.className = "panel-enabler-view-content";
this.element.appendChild(this.contentElement);

this.imageElement = document.createElement("img");
this.contentElement.appendChild(this.imageElement);

this.choicesForm = document.createElement("form");
this.contentElement.appendChild(this.choicesForm);

this.headerElement = document.createElement("h1");
this.headerElement.textContent = headingText;
this.choicesForm.appendChild(this.headerElement);

var self = this;
function enableOption(text, checked) {
var label = document.createElement("label");
var option = document.createElement("input");
option.type = "radio";
option.name = "enable-option";
if (checked)
option.checked = true;
label.appendChild(option);
label.appendChild(document.createTextNode(text));
self.choicesForm.appendChild(label);
return option;
};

this.enabledForSession = enableOption(WebInspector.UIString("Only enable for this session"), true);
this.enabledAlways = enableOption(WebInspector.UIString("Always enable"), false);

this.disclaimerElement = document.createElement("div");
this.disclaimerElement.className = "panel-enabler-disclaimer";
this.disclaimerElement.textContent = disclaimerText;
this.choicesForm.appendChild(this.disclaimerElement);

this.enableButton = document.createElement("button");
this.enableButton.setAttribute("type", "button");
this.enableButton.textContent = buttonTitle;
this.enableButton.addEventListener("click", this._enableButtonCicked.bind(this), false);
this.choicesForm.appendChild(this.enableButton);
}

WebInspector.PanelEnablerView.prototype = {
_enableButtonCicked: function()
{
this.dispatchEventToListeners("enable clicked");
},

onResize: function()
{
this.imageElement.removeStyleClass("hidden");

if (this.element.offsetWidth < (this.choicesForm.offsetWidth + this.imageElement.offsetWidth))
this.imageElement.addStyleClass("hidden");
},

get alwaysEnabled() {
return this.enabledAlways.checked;
}
}

WebInspector.PanelEnablerView.prototype.__proto__ = WebInspector.View.prototype;






WebInspector.StatusBarButton = function(title, className, states)
{
this.element = document.createElement("button");
this.element.className = className + " status-bar-item";
this.element.addEventListener("click", this._clicked.bind(this), false);

this.glyph = document.createElement("div");
this.glyph.className = "glyph";
this.element.appendChild(this.glyph);

this.glyphShadow = document.createElement("div");
this.glyphShadow.className = "glyph shadow";
this.element.appendChild(this.glyphShadow);

this.states = states;
if (!states)
this.states = 2;

if (states == 2)
this._state = false;
else
this._state = 0;

this.title = title;
this.disabled = false;
this._visible = true;
}

WebInspector.StatusBarButton.width = 31;

WebInspector.StatusBarButton.prototype = {
_clicked: function()
{
this.dispatchEventToListeners("click");
if (this._showOptionsTimer)
clearTimeout(this._showOptionsTimer);
},

get disabled()
{
return this._disabled;
},

set disabled(x)
{
if (this._disabled === x)
return;
this._disabled = x;
this.element.disabled = x;
},

get title()
{
return this._title;
},

set title(x)
{
if (this._title === x)
return;
this._title = x;
this.element.title = x;
},

get state()
{
return this._state;
},

set state(x)
{
if (this._state === x)
return;

if (this.states === 2) {
if (x)
this.element.addStyleClass("toggled-on");
else
this.element.removeStyleClass("toggled-on");
} else {
if (x !== 0) {
this.element.removeStyleClass("toggled-" + this._state);
this.element.addStyleClass("toggled-" + x);
} else
this.element.removeStyleClass("toggled-" + this._state);
}
this._state = x;
},

get toggled()
{
if (this.states !== 2)
throw("Only used toggled when there are 2 states, otherwise, use state");
return this.state;
},

set toggled(x)
{
if (this.states !== 2)
throw("Only used toggled when there are 2 states, otherwise, use state");
this.state = x;
},

get visible()
{
return this._visible;
},

set visible(x)
{
if (this._visible === x)
return;

if (x)
this.element.removeStyleClass("hidden");
else
this.element.addStyleClass("hidden");
this._visible = x;
},


makeLongClickEnabled: function(buttonsProvider)
{
this.longClickGlyph = document.createElement("div");
this.longClickGlyph.className = "fill long-click-glyph";
this.element.appendChild(this.longClickGlyph);

this.longClickGlyphShadow = document.createElement("div");
this.longClickGlyphShadow.className = "fill long-click-glyph shadow";
this.element.appendChild(this.longClickGlyphShadow);

this.element.addEventListener("mousedown", mouseDown.bind(this), false);
this.element.addEventListener("mouseout", mouseUp.bind(this), false);
this.element.addEventListener("mouseup", mouseUp.bind(this), false);

function mouseDown(e)
{
if (e.which !== 1)
return;
this._showOptionsTimer = setTimeout(this._showOptions.bind(this, buttonsProvider), 200);
}

function mouseUp(e)
{
if (e.which !== 1)
return;
if (this._showOptionsTimer)
clearTimeout(this._showOptionsTimer);
}
},


_showOptions: function(buttonsProvider)
{
var buttons = buttonsProvider();

var mouseUpListener = mouseUp.bind(this);
document.documentElement.addEventListener("mouseup", mouseUpListener, false);

var optionsGlassPane = new WebInspector.GlassPane();
var optionsBarElement = optionsGlassPane.element.createChild("div", "alternate-status-bar-buttons-bar");
const buttonHeight = 24;
optionsBarElement.style.height = (buttonHeight * buttons.length) + "px";
optionsBarElement.style.left = (this.element.offsetLeft + 1) + "px";

var boundMouseOver = mouseOver.bind(this);
var boundMouseOut = mouseOut.bind(this);
for (var i = 0; i < buttons.length; ++i) {
buttons[i].element.addEventListener("mousemove", boundMouseOver.bind(this), false);
buttons[i].element.addEventListener("mouseout", boundMouseOut.bind(this), false);
optionsBarElement.appendChild(buttons[i].element);
}
buttons[buttons.length - 1].element.addStyleClass("emulate-active");

function mouseOver(e)
{
if (e.which !== 1)
return;
var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item");
buttonElement.addStyleClass("emulate-active");
}

function mouseOut(e)
{
if (e.which !== 1)
return;
var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item");
buttonElement.removeStyleClass("emulate-active");
}

function mouseUp(e)
{
if (e.which !== 1)
return;
optionsGlassPane.dispose();
document.documentElement.removeEventListener("mouseup", mouseUpListener, false);

for (var i = 0; i < buttons.length; ++i) {
if (buttons[i].element.hasStyleClass("emulate-active"))
buttons[i]._clicked();
}
}
}
}

WebInspector.StatusBarButton.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.StatusBarComboBox = function(changeHandler, className)
{
this.element = document.createElement("span");
this.element.className = "status-bar-select-container";

this._selectElement = this.element.createChild("select", "status-bar-item");
if (changeHandler)
this._selectElement.addEventListener("change", changeHandler, false);
if (className)
this._selectElement.addStyleClass(className);
}

WebInspector.StatusBarComboBox.prototype = {

addOption: function(option)
{
this._selectElement.appendChild(option);
},


removeOption: function(option)
{
this._selectElement.removeChild(option);
},

removeOptions: function()
{
this._selectElement.removeChildren();
},


selectedOption: function()
{
if (this._selectElement.selectedIndex >= 0)
return this._selectElement[this._selectElement.selectedIndex];
return null;
},


select: function(option)
{
this._selectElement.selectedIndex = Array.prototype.indexOf.call(this._selectElement, option);
}
}






WebInspector.TextEditor = function() { };

WebInspector.TextEditor.Events = {
GutterClick: "gutterClick"
};

WebInspector.TextEditor.prototype = {


set mimeType(mimeType) { },


setReadOnly: function(readOnly) { },


readOnly: function() { },


defaultFocusedElement: function() { },


revealLine: function(lineNumber) { },


addBreakpoint: function(lineNumber, disabled, conditional) { },


removeBreakpoint: function(lineNumber) { },


setExecutionLine: function(lineNumber) { },

clearExecutionLine: function() { },


addDecoration: function(lineNumber, element) { },


removeDecoration: function(lineNumber, element) { },


markAndRevealRange: function(range) { },


highlightLine: function(lineNumber) { },

clearLineHighlight: function() { },


elementsToRestoreScrollPositionsFor: function() { },


inheritScrollPositions: function(textEditor) { },

beginUpdates: function() { },

endUpdates: function() { },

onResize: function() { },


editRange: function(range, text) { },


scrollToLine: function(lineNumber) { },


selection: function(textRange) { },


lastSelection: function() { },


setSelection: function(textRange) { },


setText: function(text) { },


text: function() { },


range: function() { },


line: function(lineNumber) { },


get linesCount() { },


setAttribute: function(line, name, value) { },


getAttribute: function(line, name) { },


removeAttribute: function(line, name) { },

wasShown: function() { },

willHide: function() { }
}


WebInspector.TextEditorDelegate = function()
{
}

WebInspector.TextEditorDelegate.prototype = {

onTextChanged: function(oldRange, newRange) { },


selectionChanged: function(textRange) { },


scrollChanged: function(lineNumber) { },


populateLineGutterContextMenu: function(contextMenu, lineNumber) { },


populateTextAreaContextMenu: function(contextMenu, lineNumber) { },


createLink: function(hrefValue, isExternal) { }
}






WebInspector.DefaultTextEditor = function(url, delegate)
{
WebInspector.View.call(this);
this._delegate = delegate;
this._url = url;

this.registerRequiredCSS("textEditor.css");

this.element.className = "text-editor monospace";

this._textModel = new WebInspector.TextEditorModel();
this._textModel.addEventListener(WebInspector.TextEditorModel.Events.TextChanged, this._textChanged, this);
this._textModel.resetUndoStack();

var enterTextChangeMode = this._enterInternalTextChangeMode.bind(this);
var exitTextChangeMode = this._exitInternalTextChangeMode.bind(this);
var syncScrollListener = this._syncScroll.bind(this);
var syncDecorationsForLineListener = this._syncDecorationsForLine.bind(this);
var syncLineHeightListener = this._syncLineHeight.bind(this);
this._mainPanel = new WebInspector.TextEditorMainPanel(this._delegate, this._textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode);
this._gutterPanel = new WebInspector.TextEditorGutterPanel(this._textModel, syncDecorationsForLineListener, syncLineHeightListener);

this._mainPanel.element.addEventListener("scroll", this._handleScrollChanged.bind(this), false);
this._mainPanel._container.addEventListener("focus", this._handleFocused.bind(this), false);

this._gutterPanel.element.addEventListener("mousedown", this._onMouseDown.bind(this), true);

this.element.appendChild(this._mainPanel.element);
this.element.appendChild(this._gutterPanel.element);


function forwardWheelEvent(event)
{
var clone = document.createEvent("WheelEvent");
clone.initWebKitWheelEvent(event.wheelDeltaX, event.wheelDeltaY,
event.view,
event.screenX, event.screenY,
event.clientX, event.clientY,
event.ctrlKey, event.altKey, event.shiftKey, event.metaKey);
this._mainPanel.element.dispatchEvent(clone);
}
this._gutterPanel.element.addEventListener("mousewheel", forwardWheelEvent.bind(this), false);

this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);

this._registerShortcuts();
}

WebInspector.DefaultTextEditor.prototype = {

set mimeType(mimeType)
{
this._mainPanel.mimeType = mimeType;
},


setReadOnly: function(readOnly)
{
if (this._mainPanel.readOnly() === readOnly)
return;
this._mainPanel.setReadOnly(readOnly, this.isShowing());
WebInspector.markBeingEdited(this.element, !readOnly);
},


readOnly: function()
{
return this._mainPanel.readOnly();
},


get textModel()
{
return this._textModel;
},


defaultFocusedElement: function()
{
return this._mainPanel.defaultFocusedElement();
},


revealLine: function(lineNumber)
{
this._mainPanel.revealLine(lineNumber);
},

_onMouseDown: function(event)
{
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: target.lineNumber, event: event });
},


addBreakpoint: function(lineNumber, disabled, conditional)
{
this.beginUpdates();
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint");
if (disabled)
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-disabled");
else
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
if (conditional)
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-conditional");
else
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
this.endUpdates();
},


removeBreakpoint: function(lineNumber)
{
this.beginUpdates();
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint");
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
this.endUpdates();
},


setExecutionLine: function(lineNumber)
{
this._executionLineNumber = lineNumber;
this._mainPanel.addDecoration(lineNumber, "webkit-execution-line");
this._gutterPanel.addDecoration(lineNumber, "webkit-execution-line");
},

clearExecutionLine: function()
{
if (typeof this._executionLineNumber === "number") {
this._mainPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line");
this._gutterPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line");
}
delete this._executionLineNumber;
},


addDecoration: function(lineNumber, element)
{
this._mainPanel.addDecoration(lineNumber, element);
this._gutterPanel.addDecoration(lineNumber, element);
},


removeDecoration: function(lineNumber, element)
{
this._mainPanel.removeDecoration(lineNumber, element);
this._gutterPanel.removeDecoration(lineNumber, element);
},


markAndRevealRange: function(range)
{
if (range)
this.setSelection(range);
this._mainPanel.markAndRevealRange(range);
},


highlightLine: function(lineNumber)
{
if (typeof lineNumber !== "number" || lineNumber < 0)
return;

lineNumber = Math.min(lineNumber, this._textModel.linesCount - 1);
this._mainPanel.highlightLine(lineNumber);
},

clearLineHighlight: function()
{
this._mainPanel.clearLineHighlight();
},

_freeCachedElements: function()
{
this._mainPanel._freeCachedElements();
this._gutterPanel._freeCachedElements();
},


elementsToRestoreScrollPositionsFor: function()
{
return [this._mainPanel.element];
},


inheritScrollPositions: function(textEditor)
{
this._mainPanel.element._scrollTop = textEditor._mainPanel.element.scrollTop;
this._mainPanel.element._scrollLeft = textEditor._mainPanel.element.scrollLeft;
},

beginUpdates: function()
{
this._mainPanel.beginUpdates();
this._gutterPanel.beginUpdates();
},

endUpdates: function()
{
this._mainPanel.endUpdates();
this._gutterPanel.endUpdates();
this._updatePanelOffsets();
},

onResize: function()
{
this._mainPanel.resize();
this._gutterPanel.resize();
this._updatePanelOffsets();
},

_textChanged: function(event)
{
if (!this._internalTextChangeMode)
this._textModel.resetUndoStack();
this._mainPanel.textChanged(event.data.oldRange, event.data.newRange);
this._gutterPanel.textChanged(event.data.oldRange, event.data.newRange);
this._updatePanelOffsets();
},


editRange: function(range, text)
{
this._enterInternalTextChangeMode();
this._textModel.markUndoableState();
var newRange = this._textModel.editRange(range, text);
this._exitInternalTextChangeMode(range, newRange);
return newRange;
},

_enterInternalTextChangeMode: function()
{
this._internalTextChangeMode = true;
},


_exitInternalTextChangeMode: function(oldRange, newRange)
{
this._internalTextChangeMode = false;
this._delegate.onTextChanged(oldRange, newRange);
},

_updatePanelOffsets: function()
{
var lineNumbersWidth = this._gutterPanel.element.offsetWidth;
if (lineNumbersWidth)
this._mainPanel.element.style.setProperty("left", (lineNumbersWidth + 2) + "px");
else
this._mainPanel.element.style.removeProperty("left"); 
},

_syncScroll: function()
{
var mainElement = this._mainPanel.element;
var gutterElement = this._gutterPanel.element;

this._gutterPanel.syncClientHeight(mainElement.clientHeight);
gutterElement.scrollTop = mainElement.scrollTop;
},


_syncDecorationsForLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;

var mainChunk = this._mainPanel.chunkForLine(lineNumber);
if (mainChunk.linesCount === 1 && mainChunk.decorated) {
var gutterChunk = this._gutterPanel.makeLineAChunk(lineNumber);
var height = mainChunk.height;
if (height)
gutterChunk.element.style.setProperty("height", height + "px");
else
gutterChunk.element.style.removeProperty("height");
} else {
var gutterChunk = this._gutterPanel.chunkForLine(lineNumber);
if (gutterChunk.linesCount === 1)
gutterChunk.element.style.removeProperty("height");
}
},


_syncLineHeight: function(gutterRow)
{
if (this._lineHeightSynced)
return;
if (gutterRow && gutterRow.offsetHeight) {

this.element.style.setProperty("line-height", gutterRow.offsetHeight + "px");
this._lineHeightSynced = true;
}
},

_registerShortcuts: function()
{
var keys = WebInspector.KeyboardShortcut.Keys;
var modifiers = WebInspector.KeyboardShortcut.Modifiers;

this._shortcuts = {};

var handleEnterKey = this._mainPanel.handleEnterKey.bind(this._mainPanel);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Enter.code, WebInspector.KeyboardShortcut.Modifiers.None)] = handleEnterKey;

var handleUndo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, false);
var handleRedo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, true);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.CtrlOrMeta)] = handleUndo;
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.Shift | modifiers.CtrlOrMeta)] = handleRedo;

var handleTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, false);
var handleShiftTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, true);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code)] = handleTabKey;
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code, modifiers.Shift)] = handleShiftTabKey;
},

_handleKeyDown: function(e)
{
if (this.readOnly())
return;

var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
var handler = this._shortcuts[shortcutKey];
if (handler && handler())
e.consume(true);
},

_contextMenu: function(event)
{
var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
if (anchor)
return;
var contextMenu = new WebInspector.ContextMenu();
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (target)
this._delegate.populateLineGutterContextMenu(contextMenu, target.lineNumber);
else {
target = this._mainPanel._enclosingLineRowOrSelf(event.target);
this._delegate.populateTextAreaContextMenu(contextMenu, target && target.lineNumber);
}
contextMenu.show(event);
},

_handleScrollChanged: function(event)
{
var visibleFrom = this._mainPanel.element.scrollTop;
var firstVisibleLineNumber = this._mainPanel._findFirstVisibleLineNumber(visibleFrom);
this._delegate.scrollChanged(firstVisibleLineNumber);
},


scrollToLine: function(lineNumber)
{
this._mainPanel.scrollToLine(lineNumber);
},

_handleSelectionChange: function(event)
{
var textRange = this._mainPanel._getSelection();
if (textRange) {


this._lastSelection = WebInspector.TextRange.createFromLocation(textRange.endLine, textRange.endColumn);
}
this._delegate.selectionChanged(textRange);
},


selection: function(textRange)
{
return this._mainPanel._getSelection();
},


lastSelection: function()
{
return this._lastSelection;
},


setSelection: function(textRange)
{
this._lastSelection = textRange;
if (this.element.isAncestor(document.activeElement))
this._mainPanel._restoreSelection(textRange);
},


setText: function(text)
{
this._textModel.setText(text);
},


text: function()
{
return this._textModel.text();
},


range: function()
{
return this._textModel.range();
},


line: function(lineNumber)
{
return this._textModel.line(lineNumber);
},


get linesCount()
{
return this._textModel.linesCount;
},


setAttribute: function(line, name, value)
{
this._textModel.setAttribute(line, name, value);
},


getAttribute: function(line, name)
{
return this._textModel.getAttribute(line, name);
},


removeAttribute: function(line, name)
{
this._textModel.removeAttribute(line, name);
},

wasShown: function()
{
if (!this.readOnly())
WebInspector.markBeingEdited(this.element, true);

this._boundSelectionChangeListener = this._handleSelectionChange.bind(this);
document.addEventListener("selectionchange", this._boundSelectionChangeListener, false);
},

_handleFocused: function()
{
if (this._lastSelection)
this.setSelection(this._lastSelection);
},

willHide: function()
{
document.removeEventListener("selectionchange", this._boundSelectionChangeListener, false);
delete this._boundSelectionChangeListener;

if (!this.readOnly())
WebInspector.markBeingEdited(this.element, false);
this._freeCachedElements();
}
}

WebInspector.DefaultTextEditor.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.TextEditorChunkedPanel = function(textModel)
{
this._textModel = textModel;

this._defaultChunkSize = 50;
this._paintCoalescingLevel = 0;
this._domUpdateCoalescingLevel = 0;
}

WebInspector.TextEditorChunkedPanel.prototype = {

get textModel()
{
return this._textModel;
},


scrollToLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this.makeLineAChunk(lineNumber);
this.element.scrollTop = chunk.offsetTop;
},


revealLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this.makeLineAChunk(lineNumber);
chunk.element.scrollIntoViewIfNeeded();
},


addDecoration: function(lineNumber, decoration)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this.makeLineAChunk(lineNumber);
chunk.addDecoration(decoration);
},


removeDecoration: function(lineNumber, decoration)
{
if (lineNumber >= this._textModel.linesCount)
return;

var chunk = this.chunkForLine(lineNumber);
chunk.removeDecoration(decoration);
},

_buildChunks: function()
{
this.beginDomUpdates();

this._container.removeChildren();

this._textChunks = [];
for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) {
var chunk = this._createNewChunk(i, i + this._defaultChunkSize);
this._textChunks.push(chunk);
this._container.appendChild(chunk.element);
}

this._repaintAll();

this.endDomUpdates();
},


makeLineAChunk: function(lineNumber)
{
var chunkNumber = this._chunkNumberForLine(lineNumber);
var oldChunk = this._textChunks[chunkNumber];

if (!oldChunk) {
console.error("No chunk for line number: " + lineNumber);
return;
}

if (oldChunk.linesCount === 1)
return oldChunk;

return this._splitChunkOnALine(lineNumber, chunkNumber, true);
},


_splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk)
{
this.beginDomUpdates();

var oldChunk = this._textChunks[chunkNumber];
var wasExpanded = oldChunk.expanded;
oldChunk.expanded = false;

var insertIndex = chunkNumber + 1;


if (lineNumber > oldChunk.startLine) {
var prefixChunk = this._createNewChunk(oldChunk.startLine, lineNumber);
prefixChunk.readOnly = oldChunk.readOnly;
this._textChunks.splice(insertIndex++, 0, prefixChunk);
this._container.insertBefore(prefixChunk.element, oldChunk.element);
}


var endLine = createSuffixChunk ? lineNumber + 1 : oldChunk.startLine + oldChunk.linesCount;
var lineChunk = this._createNewChunk(lineNumber, endLine);
lineChunk.readOnly = oldChunk.readOnly;
this._textChunks.splice(insertIndex++, 0, lineChunk);
this._container.insertBefore(lineChunk.element, oldChunk.element);


if (oldChunk.startLine + oldChunk.linesCount > endLine) {
var suffixChunk = this._createNewChunk(endLine, oldChunk.startLine + oldChunk.linesCount);
suffixChunk.readOnly = oldChunk.readOnly;
this._textChunks.splice(insertIndex, 0, suffixChunk);
this._container.insertBefore(suffixChunk.element, oldChunk.element);
}


this._textChunks.splice(chunkNumber, 1);
this._container.removeChild(oldChunk.element);

if (wasExpanded) {
if (prefixChunk)
prefixChunk.expanded = true;
lineChunk.expanded = true;
if (suffixChunk)
suffixChunk.expanded = true;
}

this.endDomUpdates();

return lineChunk;
},

_scroll: function()
{
this._scheduleRepaintAll();
if (this._syncScrollListener)
this._syncScrollListener();
},

_scheduleRepaintAll: function()
{
if (this._repaintAllTimer)
clearTimeout(this._repaintAllTimer);
this._repaintAllTimer = setTimeout(this._repaintAll.bind(this), 50);
},

beginUpdates: function()
{
this._paintCoalescingLevel++;
},

endUpdates: function()
{
this._paintCoalescingLevel--;
if (!this._paintCoalescingLevel)
this._repaintAll();
},

beginDomUpdates: function()
{
this._domUpdateCoalescingLevel++;
},

endDomUpdates: function()
{
this._domUpdateCoalescingLevel--;
},


_chunkNumberForLine: function(lineNumber)
{
function compareLineNumbers(value, chunk)
{
return value < chunk.startLine ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(lineNumber, this._textChunks, compareLineNumbers);
return insertBefore - 1;
},


chunkForLine: function(lineNumber)
{
return this._textChunks[this._chunkNumberForLine(lineNumber)];
},


_findFirstVisibleChunkNumber: function(visibleFrom)
{
function compareOffsetTops(value, chunk)
{
return value < chunk.offsetTop ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, this._textChunks, compareOffsetTops);
return insertBefore - 1;
},


_findVisibleChunks: function(visibleFrom, visibleTo)
{
var from = this._findFirstVisibleChunkNumber(visibleFrom);
for (var to = from + 1; to < this._textChunks.length; ++to) {
if (this._textChunks[to].offsetTop >= visibleTo)
break;
}
return { start: from, end: to };
},


_findFirstVisibleLineNumber: function(visibleFrom)
{
var chunk = this._textChunks[this._findFirstVisibleChunkNumber(visibleFrom)];
if (!chunk.expanded)
return chunk.startLine;

var lineNumbers = [];
for (var i = 0; i < chunk.linesCount; ++i) {
lineNumbers.push(chunk.startLine + i);
}

function compareLineRowOffsetTops(value, lineNumber)
{
var lineRow = chunk.getExpandedLineRow(lineNumber);
return value < lineRow.offsetTop ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, lineNumbers, compareLineRowOffsetTops);
return lineNumbers[insertBefore - 1];
},

_repaintAll: function()
{
delete this._repaintAllTimer;

if (this._paintCoalescingLevel || this._dirtyLines)
return;

var visibleFrom = this.element.scrollTop;
var visibleTo = this.element.scrollTop + this.element.clientHeight;

if (visibleTo) {
var result = this._findVisibleChunks(visibleFrom, visibleTo);
this._expandChunks(result.start, result.end);
}
},


_expandChunks: function(fromIndex, toIndex)
{

for (var i = 0; i < fromIndex; ++i)
this._textChunks[i].expanded = false;
for (var i = toIndex; i < this._textChunks.length; ++i)
this._textChunks[i].expanded = false;
for (var i = fromIndex; i < toIndex; ++i)
this._textChunks[i].expanded = true;
},


_totalHeight: function(firstElement, lastElement)
{
lastElement = (lastElement || firstElement).nextElementSibling;
if (lastElement)
return lastElement.offsetTop - firstElement.offsetTop;

var offsetParent = firstElement.offsetParent;
if (offsetParent && offsetParent.scrollHeight > offsetParent.clientHeight)
return offsetParent.scrollHeight - firstElement.offsetTop;

var total = 0;
while (firstElement && firstElement !== lastElement) {
total += firstElement.offsetHeight;
firstElement = firstElement.nextElementSibling;
}
return total;
},

resize: function()
{
this._repaintAll();
}
}


WebInspector.TextEditorGutterPanel = function(textModel, syncDecorationsForLineListener, syncLineHeightListener)
{
WebInspector.TextEditorChunkedPanel.call(this, textModel);

this._syncDecorationsForLineListener = syncDecorationsForLineListener;
this._syncLineHeightListener = syncLineHeightListener;

this.element = document.createElement("div");
this.element.className = "text-editor-lines";

this._container = document.createElement("div");
this._container.className = "inner-container";
this.element.appendChild(this._container);

this.element.addEventListener("scroll", this._scroll.bind(this), false);

this._freeCachedElements();
this._buildChunks();
this._decorations = {};
}

WebInspector.TextEditorGutterPanel.prototype = {
_freeCachedElements: function()
{
this._cachedRows = [];
},


_createNewChunk: function(startLine, endLine)
{
return new WebInspector.TextEditorGutterChunk(this, startLine, endLine);
},


textChanged: function(oldRange, newRange)
{
this.beginDomUpdates();

var linesDiff = newRange.linesCount - oldRange.linesCount;
if (linesDiff) {

for (var chunkNumber = this._textChunks.length - 1; chunkNumber >= 0 ; --chunkNumber) {
var chunk = this._textChunks[chunkNumber];
if (chunk.startLine + chunk.linesCount <= this._textModel.linesCount)
break;
chunk.expanded = false;
this._container.removeChild(chunk.element);
}
this._textChunks.length = chunkNumber + 1;


var totalLines = 0;
if (this._textChunks.length) {
var lastChunk = this._textChunks[this._textChunks.length - 1];
totalLines = lastChunk.startLine + lastChunk.linesCount;
}

for (var i = totalLines; i < this._textModel.linesCount; i += this._defaultChunkSize) {
var chunk = this._createNewChunk(i, i + this._defaultChunkSize);
this._textChunks.push(chunk);
this._container.appendChild(chunk.element);
}


for (var lineNumber in this._decorations) {
lineNumber = parseInt(lineNumber, 10);


if (lineNumber < oldRange.startLine)
continue;

if (lineNumber === oldRange.startLine && oldRange.startColumn)
continue;

var lineDecorationsCopy = this._decorations[lineNumber].slice();
for (var i = 0; i < lineDecorationsCopy.length; ++i) {
var decoration = lineDecorationsCopy[i];
this.removeDecoration(lineNumber, decoration);


if (lineNumber < oldRange.endLine)
continue;

this.addDecoration(lineNumber + linesDiff, decoration);
}
}

this._repaintAll();
} else {

var chunkNumber = this._chunkNumberForLine(newRange.startLine);
var chunk = this._textChunks[chunkNumber];
while (chunk && chunk.startLine <= newRange.endLine) {
if (chunk.linesCount === 1)
this._syncDecorationsForLineListener(chunk.startLine);
chunk = this._textChunks[++chunkNumber];
}
}

this.endDomUpdates();
},


syncClientHeight: function(clientHeight)
{
if (this.element.offsetHeight > clientHeight)
this._container.style.setProperty("padding-bottom", (this.element.offsetHeight - clientHeight) + "px");
else
this._container.style.removeProperty("padding-bottom");
},


addDecoration: function(lineNumber, decoration)
{
WebInspector.TextEditorChunkedPanel.prototype.addDecoration.call(this, lineNumber, decoration);
var decorations = this._decorations[lineNumber];
if (!decorations) {
decorations = [];
this._decorations[lineNumber] = decorations;
}
decorations.push(decoration);
},


removeDecoration: function(lineNumber, decoration)
{
WebInspector.TextEditorChunkedPanel.prototype.removeDecoration.call(this, lineNumber, decoration);
var decorations = this._decorations[lineNumber];
if (decorations) {
decorations.remove(decoration);
if (!decorations.length)
delete this._decorations[lineNumber];
}
}
}

WebInspector.TextEditorGutterPanel.prototype.__proto__ = WebInspector.TextEditorChunkedPanel.prototype;


WebInspector.TextEditorGutterChunk = function(textEditor, startLine, endLine)
{
this._textEditor = textEditor;
this._textModel = textEditor._textModel;

this.startLine = startLine;
endLine = Math.min(this._textModel.linesCount, endLine);
this.linesCount = endLine - startLine;

this._expanded = false;

this.element = document.createElement("div");
this.element.lineNumber = startLine;
this.element.className = "webkit-line-number";

if (this.linesCount === 1) {


var innerSpan = document.createElement("span");
innerSpan.className = "webkit-line-number-inner";
innerSpan.textContent = startLine + 1;
var outerSpan = document.createElement("div");
outerSpan.className = "webkit-line-number-outer";
outerSpan.appendChild(innerSpan);
this.element.appendChild(outerSpan);
} else {
var lineNumbers = [];
for (var i = startLine; i < endLine; ++i)
lineNumbers.push(i + 1);
this.element.textContent = lineNumbers.join("\n");
}
}

WebInspector.TextEditorGutterChunk.prototype = {

addDecoration: function(decoration)
{
this._textEditor.beginDomUpdates();
if (typeof decoration === "string")
this.element.addStyleClass(decoration);
this._textEditor.endDomUpdates();
},


removeDecoration: function(decoration)
{
this._textEditor.beginDomUpdates();
if (typeof decoration === "string")
this.element.removeStyleClass(decoration);
this._textEditor.endDomUpdates();
},


get expanded()
{
return this._expanded;
},

set expanded(expanded)
{
if (this.linesCount === 1)
this._textEditor._syncDecorationsForLineListener(this.startLine);

if (this._expanded === expanded)
return;

this._expanded = expanded;

if (this.linesCount === 1)
return;

this._textEditor.beginDomUpdates();

if (expanded) {
this._expandedLineRows = [];
var parentElement = this.element.parentElement;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._createRow(i);
parentElement.insertBefore(lineRow, this.element);
this._expandedLineRows.push(lineRow);
}
parentElement.removeChild(this.element);
this._textEditor._syncLineHeightListener(this._expandedLineRows[0]);
} else {
var elementInserted = false;
for (var i = 0; i < this._expandedLineRows.length; ++i) {
var lineRow = this._expandedLineRows[i];
var parentElement = lineRow.parentElement;
if (parentElement) {
if (!elementInserted) {
elementInserted = true;
parentElement.insertBefore(this.element, lineRow);
}
parentElement.removeChild(lineRow);
}
this._textEditor._cachedRows.push(lineRow);
}
delete this._expandedLineRows;
}

this._textEditor.endDomUpdates();
},


get height()
{
if (!this._expandedLineRows)
return this._textEditor._totalHeight(this.element);
return this._textEditor._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
},


get offsetTop()
{
return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
},


_createRow: function(lineNumber)
{
var lineRow = this._textEditor._cachedRows.pop() || document.createElement("div");
lineRow.lineNumber = lineNumber;
lineRow.className = "webkit-line-number";
lineRow.textContent = lineNumber + 1;
return lineRow;
}
}


WebInspector.TextEditorMainPanel = function(delegate, textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode)
{
WebInspector.TextEditorChunkedPanel.call(this, textModel);

this._delegate = delegate;
this._syncScrollListener = syncScrollListener;
this._syncDecorationsForLineListener = syncDecorationsForLineListener;
this._enterTextChangeMode = enterTextChangeMode;
this._exitTextChangeMode = exitTextChangeMode;

this._url = url;
this._highlighter = new WebInspector.TextEditorHighlighter(textModel, this._highlightDataReady.bind(this));
this._readOnly = true;

this.element = document.createElement("div");
this.element.className = "text-editor-contents";
this.element.tabIndex = 0;

this._container = document.createElement("div");
this._container.className = "inner-container";
this._container.tabIndex = 0;
this.element.appendChild(this._container);

this.element.addEventListener("scroll", this._scroll.bind(this), false);
this.element.addEventListener("focus", this._handleElementFocus.bind(this), false);




this._handleDOMUpdatesCallback = this._handleDOMUpdates.bind(this);
this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);

this._freeCachedElements();
this._buildChunks();
}

WebInspector.TextEditorMainPanel.prototype = {

set mimeType(mimeType)
{
this._highlighter.mimeType = mimeType;
},


setReadOnly: function(readOnly, requestFocus)
{
if (this._readOnly === readOnly)
return;

this.beginDomUpdates();
this._readOnly = readOnly;
if (this._readOnly)
this._container.removeStyleClass("text-editor-editable");
else {
this._container.addStyleClass("text-editor-editable");
if (requestFocus)
this._updateSelectionOnStartEditing();
}
this.endDomUpdates();
},


readOnly: function()
{
return this._readOnly;
},

_handleElementFocus: function()
{
if (!this._readOnly)
this._container.focus();
},


defaultFocusedElement: function()
{
if (this._readOnly)
return this.element;
return this._container;
},

_updateSelectionOnStartEditing: function()
{




this._container.focus();
var selection = window.getSelection();
if (selection.rangeCount) {
var commonAncestorContainer = selection.getRangeAt(0).commonAncestorContainer;
if (this._container.isSelfOrAncestor(commonAncestorContainer))
return;
}

selection.removeAllRanges();
var range = document.createRange();
range.setStart(this._container, 0);
range.setEnd(this._container, 0);
selection.addRange(range);
},


setEditableRange: function(startLine, endLine)
{
this.beginDomUpdates();

var firstChunkNumber = this._chunkNumberForLine(startLine);
var firstChunk = this._textChunks[firstChunkNumber];
if (firstChunk.startLine !== startLine) {
this._splitChunkOnALine(startLine, firstChunkNumber);
firstChunkNumber += 1;
}

var lastChunkNumber = this._textChunks.length;
if (endLine !== this._textModel.linesCount) {
lastChunkNumber = this._chunkNumberForLine(endLine);
var lastChunk = this._textChunks[lastChunkNumber];
if (lastChunk && lastChunk.startLine !== endLine) {
this._splitChunkOnALine(endLine, lastChunkNumber);
lastChunkNumber += 1;
}
}

for (var chunkNumber = 0; chunkNumber < firstChunkNumber; ++chunkNumber)
this._textChunks[chunkNumber].readOnly = true;
for (var chunkNumber = firstChunkNumber; chunkNumber < lastChunkNumber; ++chunkNumber)
this._textChunks[chunkNumber].readOnly = false;
for (var chunkNumber = lastChunkNumber; chunkNumber < this._textChunks.length; ++chunkNumber)
this._textChunks[chunkNumber].readOnly = true;

this.endDomUpdates();
},

clearEditableRange: function()
{
for (var chunkNumber = 0; chunkNumber < this._textChunks.length; ++chunkNumber)
this._textChunks[chunkNumber].readOnly = false;
},


markAndRevealRange: function(range)
{
if (this._rangeToMark) {
var markedLine = this._rangeToMark.startLine;
delete this._rangeToMark;

if (!this._dirtyLines) {
this.beginDomUpdates();
var chunk = this.chunkForLine(markedLine);
var wasExpanded = chunk.expanded;
chunk.expanded = false;
chunk.updateCollapsedLineRow();
chunk.expanded = wasExpanded;
this.endDomUpdates();
} else
this._paintLines(markedLine, markedLine + 1);
}

if (range) {
this._rangeToMark = range;
this.revealLine(range.startLine);
var chunk = this.makeLineAChunk(range.startLine);
this._paintLine(chunk.element);
if (this._markedRangeElement)
this._markedRangeElement.scrollIntoViewIfNeeded();
}
delete this._markedRangeElement;
},


highlightLine: function(lineNumber)
{
this.clearLineHighlight();
this._highlightedLine = lineNumber;
this.revealLine(lineNumber);

if (!this._readOnly)
this._restoreSelection(WebInspector.TextRange.createFromLocation(lineNumber, 0), false);

this.addDecoration(lineNumber, "webkit-highlighted-line");
},

clearLineHighlight: function()
{
if (typeof this._highlightedLine === "number") {
this.removeDecoration(this._highlightedLine, "webkit-highlighted-line");
delete this._highlightedLine;
}
},

_freeCachedElements: function()
{
this._cachedSpans = [];
this._cachedTextNodes = [];
this._cachedRows = [];
},


handleUndoRedo: function(redo)
{
if (this._dirtyLines)
return false;

this.beginUpdates();

function before()
{
this._enterTextChangeMode();
}

function after(oldRange, newRange)
{
this._exitTextChangeMode(oldRange, newRange);
}

var range = redo ? this._textModel.redo(before.bind(this), after.bind(this)) : this._textModel.undo(before.bind(this), after.bind(this));

this.endUpdates();


if (range)
this._restoreSelection(range, true);

return true;
},


handleTabKeyPress: function(shiftKey)
{
if (this._dirtyLines)
return false;

var selection = this._getSelection();
if (!selection)
return false;

var range = selection.normalize();

this.beginUpdates();
this._enterTextChangeMode();

var newRange;
var rangeWasEmpty = range.isEmpty();
if (shiftKey)
newRange = this._unindentLines(range);
else {
if (rangeWasEmpty)
newRange = this._editRange(range, WebInspector.settings.textEditorIndent.get());
else
newRange = this._indentLines(range);
}

this._exitTextChangeMode(range, newRange);
this.endUpdates();
if (rangeWasEmpty)
newRange.startColumn = newRange.endColumn;
this._restoreSelection(newRange, true);
return true;
},


_indentLines: function(range)
{
var indent = WebInspector.settings.textEditorIndent.get();

if (this._lastEditedRange)
this._textModel.markUndoableState();

var newRange = range.clone();


if (range.startColumn)
newRange.startColumn += indent.length;

var indentEndLine = range.endLine;
if (range.endColumn)
newRange.endColumn += indent.length;
else
indentEndLine--;

for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++)
this._textModel.editRange(WebInspector.TextRange.createFromLocation(lineNumber, 0), indent);

this._lastEditedRange = newRange;

return newRange;
},


_unindentLines: function(range)
{
if (this._lastEditedRange)
this._textModel.markUndoableState();

var indent = WebInspector.settings.textEditorIndent.get();
var indentLength = indent === WebInspector.TextEditorModel.Indent.TabCharacter ? 4 : indent.length;
var lineIndentRegex = new RegExp("^ {1," + indentLength + "}");
var newRange = range.clone();

var indentEndLine = range.endLine;
if (!range.endColumn)
indentEndLine--;

for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++) {
var line = this._textModel.line(lineNumber);
var firstCharacter = line.charAt(0);
var lineIndentLength;

if (firstCharacter === " ")
lineIndentLength = line.match(lineIndentRegex)[0].length;
else if (firstCharacter === "\t")
lineIndentLength = 1;
else
continue;

this._textModel.editRange(new WebInspector.TextRange(lineNumber, 0, lineNumber, lineIndentLength), "");

if (lineNumber === range.startLine)
newRange.startColumn = Math.max(0, newRange.startColumn - lineIndentLength);
}

if (lineIndentLength)
newRange.endColumn = Math.max(0, newRange.endColumn - lineIndentLength);

this._lastEditedRange = newRange;

return newRange;
},

handleEnterKey: function()
{
if (this._dirtyLines)
return false;

var range = this._getSelection();
if (!range)
return false;

range = range.normalize();

if (range.endColumn === 0)
return false;

var line = this._textModel.line(range.startLine);
var linePrefix = line.substring(0, range.startColumn);
var indentMatch = linePrefix.match(/^\s+/);
var currentIndent = indentMatch ? indentMatch[0] : "";

var textEditorIndent = WebInspector.settings.textEditorIndent.get();
var indent = WebInspector.TextEditorModel.endsWithBracketRegex.test(linePrefix) ? currentIndent + textEditorIndent : currentIndent;

if (!indent)
return false;

this.beginUpdates();
this._enterTextChangeMode();

var lineBreak = this._textModel.lineBreak;
var newRange;
if (range.isEmpty() && line.substr(range.endColumn - 1, 2) === '{}') {





newRange = this._editRange(range, lineBreak + indent + lineBreak + currentIndent);
newRange.endLine--;
newRange.endColumn += textEditorIndent.length;
} else
newRange = this._editRange(range, lineBreak + indent);

this._exitTextChangeMode(range, newRange);
this.endUpdates();
this._restoreSelection(newRange.collapseToEnd(), true);

return true;
},


_splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk)
{
var selection = this._getSelection();
var chunk = WebInspector.TextEditorChunkedPanel.prototype._splitChunkOnALine.call(this, lineNumber, chunkNumber, createSuffixChunk);
this._restoreSelection(selection);
return chunk;
},

beginDomUpdates: function()
{
WebInspector.TextEditorChunkedPanel.prototype.beginDomUpdates.call(this);
if (this._domUpdateCoalescingLevel === 1) {
this._container.removeEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
this._container.removeEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
this._container.removeEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
}
},

endDomUpdates: function()
{
WebInspector.TextEditorChunkedPanel.prototype.endDomUpdates.call(this);
if (this._domUpdateCoalescingLevel === 0) {
this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
}
},

_buildChunks: function()
{
for (var i = 0; i < this._textModel.linesCount; ++i)
this._textModel.removeAttribute(i, "highlight");

WebInspector.TextEditorChunkedPanel.prototype._buildChunks.call(this);
},


_createNewChunk: function(startLine, endLine)
{
return new WebInspector.TextEditorMainChunk(this, startLine, endLine);
},


_expandChunks: function(fromIndex, toIndex)
{
var lastChunk = this._textChunks[toIndex - 1];
var lastVisibleLine = lastChunk.startLine + lastChunk.linesCount;

var selection = this._getSelection();

this._muteHighlightListener = true;
this._highlighter.highlight(lastVisibleLine);
delete this._muteHighlightListener;

this._restorePaintLinesOperationsCredit();
WebInspector.TextEditorChunkedPanel.prototype._expandChunks.call(this, fromIndex, toIndex);
this._adjustPaintLinesOperationsRefreshValue();

this._restoreSelection(selection);
},


_highlightDataReady: function(fromLine, toLine)
{
if (this._muteHighlightListener)
return;
this._restorePaintLinesOperationsCredit();
this._paintLines(fromLine, toLine, true  );
},


_schedulePaintLines: function(startLine, endLine)
{
if (startLine >= endLine)
return;

if (!this._scheduledPaintLines) {
this._scheduledPaintLines = [ { startLine: startLine, endLine: endLine } ];
this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 0);
} else {
for (var i = 0; i < this._scheduledPaintLines.length; ++i) {
var chunk = this._scheduledPaintLines[i];
if (chunk.startLine <= endLine && chunk.endLine >= startLine) {
chunk.startLine = Math.min(chunk.startLine, startLine);
chunk.endLine = Math.max(chunk.endLine, endLine);
return;
}
if (chunk.startLine > endLine) {
this._scheduledPaintLines.splice(i, 0, { startLine: startLine, endLine: endLine });
return;
}
}
this._scheduledPaintLines.push({ startLine: startLine, endLine: endLine });
}
},


_paintScheduledLines: function(skipRestoreSelection)
{
if (this._paintScheduledLinesTimer)
clearTimeout(this._paintScheduledLinesTimer);
delete this._paintScheduledLinesTimer;

if (!this._scheduledPaintLines)
return;


if (this._dirtyLines || this._repaintAllTimer) {
this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 50);
return;
}

var scheduledPaintLines = this._scheduledPaintLines;
delete this._scheduledPaintLines;

this._restorePaintLinesOperationsCredit();
this._paintLineChunks(scheduledPaintLines, !skipRestoreSelection);
this._adjustPaintLinesOperationsRefreshValue();
},

_restorePaintLinesOperationsCredit: function()
{
if (!this._paintLinesOperationsRefreshValue)
this._paintLinesOperationsRefreshValue = 250;
this._paintLinesOperationsCredit = this._paintLinesOperationsRefreshValue;
this._paintLinesOperationsLastRefresh = Date.now();
},

_adjustPaintLinesOperationsRefreshValue: function()
{
var operationsDone = this._paintLinesOperationsRefreshValue - this._paintLinesOperationsCredit;
if (operationsDone <= 0)
return;
var timePast = Date.now() - this._paintLinesOperationsLastRefresh;
if (timePast <= 0)
return;

var value = Math.floor(operationsDone / timePast * 50);
this._paintLinesOperationsRefreshValue = Number.constrain(value, 150, 1500);
},


_paintLines: function(fromLine, toLine, restoreSelection)
{
this._paintLineChunks([ { startLine: fromLine, endLine: toLine } ], restoreSelection);
},


_paintLineChunks: function(lineChunks, restoreSelection)
{


var visibleFrom = this.element.scrollTop;
var firstVisibleLineNumber = this._findFirstVisibleLineNumber(visibleFrom);

var chunk;
var selection;
var invisibleLineRows = [];
for (var i = 0; i < lineChunks.length; ++i) {
var lineChunk = lineChunks[i];
if (this._dirtyLines || this._scheduledPaintLines) {
this._schedulePaintLines(lineChunk.startLine, lineChunk.endLine);
continue;
}
for (var lineNumber = lineChunk.startLine; lineNumber < lineChunk.endLine; ++lineNumber) {
if (!chunk || lineNumber < chunk.startLine || lineNumber >= chunk.startLine + chunk.linesCount)
chunk = this.chunkForLine(lineNumber);
var lineRow = chunk.getExpandedLineRow(lineNumber);
if (!lineRow)
continue;
if (lineNumber < firstVisibleLineNumber) {
invisibleLineRows.push(lineRow);
continue;
}
if (restoreSelection && !selection)
selection = this._getSelection();
this._paintLine(lineRow);
if (this._paintLinesOperationsCredit < 0) {
this._schedulePaintLines(lineNumber + 1, lineChunk.endLine);
break;
}
}
}

for (var i = 0; i < invisibleLineRows.length; ++i) {
if (restoreSelection && !selection)
selection = this._getSelection();
this._paintLine(invisibleLineRows[i]);
}

if (restoreSelection)
this._restoreSelection(selection);
},


_paintLine: function(lineRow)
{
var lineNumber = lineRow.lineNumber;
if (this._dirtyLines) {
this._schedulePaintLines(lineNumber, lineNumber + 1);
return;
}

this.beginDomUpdates();
try {
if (this._scheduledPaintLines || this._paintLinesOperationsCredit < 0) {
this._schedulePaintLines(lineNumber, lineNumber + 1);
return;
}

var highlight = this._textModel.getAttribute(lineNumber, "highlight");
if (!highlight)
return;

lineRow.removeChildren();
var line = this._textModel.line(lineNumber);
if (!line)
lineRow.appendChild(document.createElement("br"));

var plainTextStart = -1;
for (var j = 0; j < line.length;) {
if (j > 1000) {

if (plainTextStart === -1)
plainTextStart = j;
break;
}
var attribute = highlight[j];
if (!attribute || !attribute.tokenType) {
if (plainTextStart === -1)
plainTextStart = j;
j++;
} else {
if (plainTextStart !== -1) {
this._appendTextNode(lineRow, line.substring(plainTextStart, j));
plainTextStart = -1;
--this._paintLinesOperationsCredit;
}
this._appendSpan(lineRow, line.substring(j, j + attribute.length), attribute.tokenType);
j += attribute.length;
--this._paintLinesOperationsCredit;
}
}
if (plainTextStart !== -1) {
this._appendTextNode(lineRow, line.substring(plainTextStart, line.length));
--this._paintLinesOperationsCredit;
}
if (lineRow.decorationsElement)
lineRow.appendChild(lineRow.decorationsElement);
} finally {
if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
this._markedRangeElement = WebInspector.highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
this.endDomUpdates();
}
},


_releaseLinesHighlight: function(lineRow)
{
if (!lineRow)
return;
if ("spans" in lineRow) {
var spans = lineRow.spans;
for (var j = 0; j < spans.length; ++j)
this._cachedSpans.push(spans[j]);
delete lineRow.spans;
}
if ("textNodes" in lineRow) {
var textNodes = lineRow.textNodes;
for (var j = 0; j < textNodes.length; ++j)
this._cachedTextNodes.push(textNodes[j]);
delete lineRow.textNodes;
}
this._cachedRows.push(lineRow);
},


_getSelection: function()
{
var selection = window.getSelection();
if (!selection.rangeCount)
return null;

if (!this._container.isAncestor(selection.anchorNode) || !this._container.isAncestor(selection.focusNode))
return null;
var start = this._selectionToPosition(selection.anchorNode, selection.anchorOffset);
var end = selection.isCollapsed ? start : this._selectionToPosition(selection.focusNode, selection.focusOffset);
return new WebInspector.TextRange(start.line, start.column, end.line, end.column);
},


_restoreSelection: function(range, scrollIntoView)
{
if (!range)
return;
var start = this._positionToSelection(range.startLine, range.startColumn);
var end = range.isEmpty() ? start : this._positionToSelection(range.endLine, range.endColumn);
window.getSelection().setBaseAndExtent(start.container, start.offset, end.container, end.offset);

if (scrollIntoView) {
for (var node = end.container; node; node = node.parentElement) {
if (node.scrollIntoViewIfNeeded) {
node.scrollIntoViewIfNeeded();
break;
}
}
}
},


_selectionToPosition: function(container, offset)
{
if (container === this._container && offset === 0)
return { line: 0, column: 0 };
if (container === this._container && offset === 1)
return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) };

var lineRow = this._enclosingLineRowOrSelf(container);
var lineNumber = lineRow.lineNumber;
if (container === lineRow && offset === 0)
return { line: lineNumber, column: 0 };


var column = 0;
var node = lineRow.nodeType === Node.TEXT_NODE ? lineRow : lineRow.traverseNextTextNode(lineRow);
while (node && node !== container) {
var text = node.textContent;
for (var i = 0; i < text.length; ++i) {
if (text.charAt(i) === "\n") {
lineNumber++;
column = 0;
} else
column++;
}
node = node.traverseNextTextNode(lineRow);
}

if (node === container && offset) {
var text = node.textContent;
for (var i = 0; i < offset; ++i) {
if (text.charAt(i) === "\n") {
lineNumber++;
column = 0;
} else
column++;
}
}
return { line: lineNumber, column: column };
},


_positionToSelection: function(line, column)
{
var chunk = this.chunkForLine(line);

var lineRow = chunk.linesCount === 1 ? chunk.element : chunk.getExpandedLineRow(line);
if (lineRow)
var rangeBoundary = lineRow.rangeBoundaryForOffset(column);
else {
var offset = column;
for (var i = chunk.startLine; i < line; ++i)
offset += this._textModel.lineLength(i) + 1; 
lineRow = chunk.element;
if (lineRow.firstChild)
var rangeBoundary = { container: lineRow.firstChild, offset: offset };
else
var rangeBoundary = { container: lineRow, offset: 0 };
}
return rangeBoundary;
},


_enclosingLineRowOrSelf: function(element)
{
var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content");
if (lineRow)
return lineRow;

for (lineRow = element; lineRow; lineRow = lineRow.parentElement) {
if (lineRow.parentElement === this._container)
return lineRow;
}
return null;
},


_appendSpan: function(element, content, className)
{
if (className === "html-resource-link" || className === "html-external-link") {
element.appendChild(this._createLink(content, className === "html-external-link"));
return;
}

var span = this._cachedSpans.pop() || document.createElement("span");
span.className = "webkit-" + className;
span.textContent = content;
element.appendChild(span);
if (!("spans" in element))
element.spans = [];
element.spans.push(span);
},


_appendTextNode: function(element, text)
{
var textNode = this._cachedTextNodes.pop();
if (textNode)
textNode.nodeValue = text;
else
textNode = document.createTextNode(text);
element.appendChild(textNode);
if (!("textNodes" in element))
element.textNodes = [];
element.textNodes.push(textNode);
},


_createLink: function(content, isExternal)
{
var quote = content.charAt(0);
if (content.length > 1 && (quote === "\"" ||   quote === "'"))
content = content.substring(1, content.length - 1);
else
quote = null;

var span = document.createElement("span");
span.className = "webkit-html-attribute-value";
if (quote)
span.appendChild(document.createTextNode(quote));
span.appendChild(this._delegate.createLink(content, isExternal));
if (quote)
span.appendChild(document.createTextNode(quote));
return span;
},

_handleDOMUpdates: function(e)
{
if (this._domUpdateCoalescingLevel)
return;

var target = e.target;
if (target === this._container)
return;

var lineRow = this._enclosingLineRowOrSelf(target);
if (!lineRow)
return;

if (lineRow.decorationsElement && lineRow.decorationsElement.isSelfOrAncestor(target)) {
if (this._syncDecorationsForLineListener)
this._syncDecorationsForLineListener(lineRow.lineNumber);
return;
}

if (this._readOnly)
return;

if (target === lineRow && e.type === "DOMNodeInserted") {

delete lineRow.lineNumber;
}

var startLine = 0;
for (var row = lineRow; row; row = row.previousSibling) {
if (typeof row.lineNumber === "number") {
startLine = row.lineNumber;
break;
}
}

var endLine = startLine + 1;
for (var row = lineRow.nextSibling; row; row = row.nextSibling) {
if (typeof row.lineNumber === "number" && row.lineNumber > startLine) {
endLine = row.lineNumber;
break;
}
}

if (this._dirtyLines) {
this._dirtyLines.start = Math.min(this._dirtyLines.start, startLine);
this._dirtyLines.end = Math.max(this._dirtyLines.end, endLine);
} else {
this._dirtyLines = { start: startLine, end: endLine };
setTimeout(this._applyDomUpdates.bind(this), 0);

this.markAndRevealRange(null);
}
},

_applyDomUpdates: function()
{
if (!this._dirtyLines)
return;


if (this._readOnly) {
delete this._dirtyLines;
return;
}

var dirtyLines = this._dirtyLines;

var firstChunkNumber = this._chunkNumberForLine(dirtyLines.start);
var startLine = this._textChunks[firstChunkNumber].startLine;
var endLine = this._textModel.linesCount;


var firstLineRow;
if (firstChunkNumber) {
var chunk = this._textChunks[firstChunkNumber - 1];
firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element;
firstLineRow = firstLineRow.nextSibling;
} else
firstLineRow = this._container.firstChild;

var lines = [];
for (var lineRow = firstLineRow; lineRow; lineRow = lineRow.nextSibling) {
if (typeof lineRow.lineNumber === "number" && lineRow.lineNumber >= dirtyLines.end) {
endLine = lineRow.lineNumber;
break;
}

lineRow.lineNumber = startLine + lines.length;
this._collectLinesFromDiv(lines, lineRow);
}


var startOffset = 0;
while (startLine < dirtyLines.start && startOffset < lines.length) {
if (this._textModel.line(startLine) !== lines[startOffset])
break;
++startOffset;
++startLine;
}

var endOffset = lines.length;
while (endLine > dirtyLines.end && endOffset > startOffset) {
if (this._textModel.line(endLine - 1) !== lines[endOffset - 1])
break;
--endOffset;
--endLine;
}

lines = lines.slice(startOffset, endOffset);


var startColumn = 0;
var endColumn = this._textModel.lineLength(endLine - 1);
if (lines.length > 0) {
var line1 = this._textModel.line(startLine);
var line2 = lines[0];
while (line1[startColumn] && line1[startColumn] === line2[startColumn])
++startColumn;
lines[0] = line2.substring(startColumn);

line1 = this._textModel.line(endLine - 1);
line2 = lines[lines.length - 1];
for (var i = 0; i < endColumn && i < line2.length; ++i) {
if (startLine === endLine - 1 && endColumn - i <= startColumn)
break;
if (line1[endColumn - i - 1] !== line2[line2.length - i - 1])
break;
}
if (i) {
endColumn -= i;
lines[lines.length - 1] = line2.substring(0, line2.length - i);
}
}

var selection = this._getSelection();

if (lines.length === 0 && endLine < this._textModel.linesCount)
var oldRange = new WebInspector.TextRange(startLine, 0, endLine, 0);
else if (lines.length === 0 && startLine > 0)
var oldRange = new WebInspector.TextRange(startLine - 1, this._textModel.lineLength(startLine - 1), endLine - 1, this._textModel.lineLength(endLine - 1));
else
var oldRange = new WebInspector.TextRange(startLine, startColumn, endLine - 1, endColumn);

var newContent = lines.join("\n");
if (this._textModel.copyRange(oldRange) === newContent) {
delete this._dirtyLines;
return; 
}

if (lines.length === 1 && lines[0] === "}" && oldRange.isEmpty() && selection.isEmpty() && !this._textModel.line(oldRange.endLine).trim())
this._unindentAfterBlock(oldRange, selection);


this._enterTextChangeMode();

delete this._dirtyLines;

var newRange = this._editRange(oldRange, newContent);

this._paintScheduledLines(true);
this._restoreSelection(selection);

this._exitTextChangeMode(oldRange, newRange);
},


_unindentAfterBlock: function(oldRange, selection)
{
var nestingLevel = 1;
for (var i = oldRange.endLine; i >= 0; --i) {
var attribute = this._textModel.getAttribute(i, "highlight");
if (!attribute)
continue;
var columnNumbers = Object.keys(attribute).reverse();
for (var j = 0; j < columnNumbers.length; ++j) {
var column = columnNumbers[j];
if (attribute[column].tokenType === "block-start") {
if (!(--nestingLevel)) {
var lineContent = this._textModel.line(i);
var blockOffset = lineContent.length - lineContent.trimLeft().length;
if (blockOffset < oldRange.startColumn) {
oldRange.startColumn = blockOffset;
selection.startColumn = blockOffset + 1;
selection.endColumn = blockOffset + 1;
}
return;
}
}
if (attribute[column].tokenType === "block-end")
++nestingLevel;
}
}
},


textChanged: function(oldRange, newRange)
{
this.beginDomUpdates();
this._removeDecorationsInRange(oldRange);
this._updateChunksForRanges(oldRange, newRange);
this._updateHighlightsForRange(newRange);
this.endDomUpdates();
},


_editRange: function(range, text)
{
if (this._lastEditedRange && (!text || text.indexOf("\n") !== -1 || this._lastEditedRange.endLine !== range.startLine || this._lastEditedRange.endColumn !== range.startColumn))
this._textModel.markUndoableState();

var newRange = this._textModel.editRange(range, text);
this._lastEditedRange = newRange;

return newRange;
},


_removeDecorationsInRange: function(range)
{
for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i) {
var chunk = this._textChunks[i];
if (chunk.startLine > range.endLine)
break;
chunk.removeAllDecorations();
}
},


_updateChunksForRanges: function(oldRange, newRange)
{

var firstChunkNumber = this._chunkNumberForLine(oldRange.startLine);
var lastChunkNumber = firstChunkNumber;
while (lastChunkNumber + 1 < this._textChunks.length) {
if (this._textChunks[lastChunkNumber + 1].startLine > oldRange.endLine)
break;
++lastChunkNumber;
}

var startLine = this._textChunks[firstChunkNumber].startLine;
var linesCount = this._textChunks[lastChunkNumber].startLine + this._textChunks[lastChunkNumber].linesCount - startLine;
var linesDiff = newRange.linesCount - oldRange.linesCount;
linesCount += linesDiff;

if (linesDiff) {

for (var chunkNumber = lastChunkNumber + 1; chunkNumber < this._textChunks.length; ++chunkNumber)
this._textChunks[chunkNumber].startLine += linesDiff;
}

var firstLineRow;
if (firstChunkNumber) {
var chunk = this._textChunks[firstChunkNumber - 1];
firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element;
firstLineRow = firstLineRow.nextSibling;
} else
firstLineRow = this._container.firstChild;


for (var chunkNumber = firstChunkNumber; chunkNumber <= lastChunkNumber; ++chunkNumber) {
var chunk = this._textChunks[chunkNumber];
if (chunk.startLine + chunk.linesCount > this._textModel.linesCount)
break;
var lineNumber = chunk.startLine;
for (var lineRow = firstLineRow; lineRow && lineNumber < chunk.startLine + chunk.linesCount; lineRow = lineRow.nextSibling) {
if (lineRow.lineNumber !== lineNumber || lineRow !== chunk.getExpandedLineRow(lineNumber) || lineRow.textContent !== this._textModel.line(lineNumber) || !lineRow.firstChild)
break;
++lineNumber;
}
if (lineNumber < chunk.startLine + chunk.linesCount)
break;
chunk.updateCollapsedLineRow();
++firstChunkNumber;
firstLineRow = lineRow;
startLine += chunk.linesCount;
linesCount -= chunk.linesCount;
}

if (firstChunkNumber > lastChunkNumber && linesCount === 0)
return;


var chunk = this._textChunks[lastChunkNumber + 1];
var linesInLastChunk = linesCount % this._defaultChunkSize;
if (chunk && !chunk.decorated && linesInLastChunk > 0 && linesInLastChunk + chunk.linesCount <= this._defaultChunkSize) {
++lastChunkNumber;
linesCount += chunk.linesCount;
}

var scrollTop = this.element.scrollTop;
var scrollLeft = this.element.scrollLeft;


var firstUnmodifiedLineRow = null;
chunk = this._textChunks[lastChunkNumber + 1];
if (chunk)
firstUnmodifiedLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine) : chunk.element;

while (firstLineRow && firstLineRow !== firstUnmodifiedLineRow) {
var lineRow = firstLineRow;
firstLineRow = firstLineRow.nextSibling;
this._container.removeChild(lineRow);
}


for (var chunkNumber = firstChunkNumber; linesCount > 0; ++chunkNumber) {
var chunkLinesCount = Math.min(this._defaultChunkSize, linesCount);
var newChunk = this._createNewChunk(startLine, startLine + chunkLinesCount);
this._container.insertBefore(newChunk.element, firstUnmodifiedLineRow);

if (chunkNumber <= lastChunkNumber)
this._textChunks[chunkNumber] = newChunk;
else
this._textChunks.splice(chunkNumber, 0, newChunk);
startLine += chunkLinesCount;
linesCount -= chunkLinesCount;
}
if (chunkNumber <= lastChunkNumber)
this._textChunks.splice(chunkNumber, lastChunkNumber - chunkNumber + 1);

this.element.scrollTop = scrollTop;
this.element.scrollLeft = scrollLeft;
},


_updateHighlightsForRange: function(range)
{
var visibleFrom = this.element.scrollTop;
var visibleTo = this.element.scrollTop + this.element.clientHeight;

var result = this._findVisibleChunks(visibleFrom, visibleTo);
var chunk = this._textChunks[result.end - 1];
var lastVisibleLine = chunk.startLine + chunk.linesCount;

lastVisibleLine = Math.max(lastVisibleLine, range.endLine + 1);
lastVisibleLine = Math.min(lastVisibleLine, this._textModel.linesCount);

var updated = this._highlighter.updateHighlight(range.startLine, lastVisibleLine);
if (!updated) {

for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i)
this._textChunks[i].expanded = false;
}

this._repaintAll();
},


_collectLinesFromDiv: function(lines, element)
{
var textContents = [];
var node = element.nodeType === Node.TEXT_NODE ? element : element.traverseNextNode(element);
while (node) {
if (element.decorationsElement === node) {
node = node.nextSibling;
continue;
}
if (node.nodeName.toLowerCase() === "br")
textContents.push("\n");
else if (node.nodeType === Node.TEXT_NODE)
textContents.push(node.textContent);
node = node.traverseNextNode(element);
}

var textContent = textContents.join("");

textContent = textContent.replace(/\n$/, "");

textContents = textContent.split("\n");
for (var i = 0; i < textContents.length; ++i)
lines.push(textContents[i]);
}
}

WebInspector.TextEditorMainPanel.prototype.__proto__ = WebInspector.TextEditorChunkedPanel.prototype;


WebInspector.TextEditorMainChunk = function(chunkedPanel, startLine, endLine)
{
this._chunkedPanel = chunkedPanel;
this._textModel = chunkedPanel._textModel;

this.element = document.createElement("div");
this.element.lineNumber = startLine;
this.element.className = "webkit-line-content";

this._startLine = startLine;
endLine = Math.min(this._textModel.linesCount, endLine);
this.linesCount = endLine - startLine;

this._expanded = false;
this._readOnly = false;

this.updateCollapsedLineRow();
}

WebInspector.TextEditorMainChunk.prototype = {
addDecoration: function(decoration)
{
this._chunkedPanel.beginDomUpdates();
if (typeof decoration === "string")
this.element.addStyleClass(decoration);
else {
if (!this.element.decorationsElement) {
this.element.decorationsElement = document.createElement("div");
this.element.decorationsElement.className = "webkit-line-decorations";
this.element.appendChild(this.element.decorationsElement);
}
this.element.decorationsElement.appendChild(decoration);
}
this._chunkedPanel.endDomUpdates();
},


removeDecoration: function(decoration)
{
this._chunkedPanel.beginDomUpdates();
if (typeof decoration === "string")
this.element.removeStyleClass(decoration);
else if (this.element.decorationsElement)
this.element.decorationsElement.removeChild(decoration);
this._chunkedPanel.endDomUpdates();
},

removeAllDecorations: function()
{
this._chunkedPanel.beginDomUpdates();
this.element.className = "webkit-line-content";
if (this.element.decorationsElement) {
this.element.removeChild(this.element.decorationsElement);
delete this.element.decorationsElement;
}
this._chunkedPanel.endDomUpdates();
},


get decorated()
{
return this.element.className !== "webkit-line-content" || !!(this.element.decorationsElement && this.element.decorationsElement.firstChild);
},


get startLine()
{
return this._startLine;
},

set startLine(startLine)
{
this._startLine = startLine;
this.element.lineNumber = startLine;
if (this._expandedLineRows) {
for (var i = 0; i < this._expandedLineRows.length; ++i)
this._expandedLineRows[i].lineNumber = startLine + i;
}
},


get expanded()
{
return this._expanded;
},

set expanded(expanded)
{
if (this._expanded === expanded)
return;

this._expanded = expanded;

if (this.linesCount === 1) {
if (expanded)
this._chunkedPanel._paintLine(this.element);
return;
}

this._chunkedPanel.beginDomUpdates();

if (expanded) {
this._expandedLineRows = [];
var parentElement = this.element.parentElement;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._createRow(i);
this._updateElementReadOnlyState(lineRow);
parentElement.insertBefore(lineRow, this.element);
this._expandedLineRows.push(lineRow);
}
parentElement.removeChild(this.element);
this._chunkedPanel._paintLines(this.startLine, this.startLine + this.linesCount);
} else {
var elementInserted = false;
for (var i = 0; i < this._expandedLineRows.length; ++i) {
var lineRow = this._expandedLineRows[i];
var parentElement = lineRow.parentElement;
if (parentElement) {
if (!elementInserted) {
elementInserted = true;
parentElement.insertBefore(this.element, lineRow);
}
parentElement.removeChild(lineRow);
}
this._chunkedPanel._releaseLinesHighlight(lineRow);
}
delete this._expandedLineRows;
}

this._chunkedPanel.endDomUpdates();
},

set readOnly(readOnly)
{
if (this._readOnly === readOnly)
return;

this._readOnly = readOnly;
this._updateElementReadOnlyState(this.element);
if (this._expandedLineRows) {
for (var i = 0; i < this._expandedLineRows.length; ++i)
this._updateElementReadOnlyState(this._expandedLineRows[i]);
}
},


get readOnly()
{
return this._readOnly;
},

_updateElementReadOnlyState: function(element)
{
if (this._readOnly)
element.addStyleClass("text-editor-read-only");
else
element.removeStyleClass("text-editor-read-only");
},


get height()
{
if (!this._expandedLineRows)
return this._chunkedPanel._totalHeight(this.element);
return this._chunkedPanel._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
},


get offsetTop()
{
return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
},


_createRow: function(lineNumber)
{
var lineRow = this._chunkedPanel._cachedRows.pop() || document.createElement("div");
lineRow.lineNumber = lineNumber;
lineRow.className = "webkit-line-content";
lineRow.textContent = this._textModel.line(lineNumber);
if (!lineRow.textContent)
lineRow.appendChild(document.createElement("br"));
return lineRow;
},


getExpandedLineRow: function(lineNumber)
{
if (!this._expanded || lineNumber < this.startLine || lineNumber >= this.startLine + this.linesCount)
return null;
if (!this._expandedLineRows)
return this.element;
return this._expandedLineRows[lineNumber - this.startLine];
},

updateCollapsedLineRow: function()
{
if (this.linesCount === 1 && this._expanded)
return;

var lines = [];
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i)
lines.push(this._textModel.line(i));

this.element.removeChildren();
this.element.textContent = lines.join("\n");


if (!lines[lines.length - 1])
this.element.appendChild(document.createElement("br"));
}
}






WebInspector.SourceFrame = function(contentProvider)
{
WebInspector.View.call(this);
this.element.addStyleClass("script-view");

this._url = contentProvider.contentURL();
this._contentProvider = contentProvider;

var textEditorDelegate = new WebInspector.TextEditorDelegateForSourceFrame(this);

if (WebInspector.experimentsSettings.codemirror.isEnabled()) {
importScript("CodeMirrorTextEditor.js");
this._textEditor = new WebInspector.CodeMirrorTextEditor(this._url, textEditorDelegate);
} else
this._textEditor = new WebInspector.DefaultTextEditor(this._url, textEditorDelegate);

this._currentSearchResultIndex = -1;
this._searchResults = [];

this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};

this._textEditor.setReadOnly(!this.canEditSource());

this._shortcuts = {};
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)] = this._commitEditing.bind(this);
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
}


WebInspector.SourceFrame.createSearchRegex = function(query, modifiers)
{
var regex;
modifiers = modifiers || "";


try {
if (/^\/.*\/$/.test(query))
regex = new RegExp(query.substring(1, query.length - 1), modifiers);
} catch (e) {

}


if (!regex)
regex = createPlainTextSearchRegex(query, "i" + modifiers);

return regex;
}

WebInspector.SourceFrame.Events = {
ScrollChanged: "ScrollChanged",
SelectionChanged: "SelectionChanged"
}

WebInspector.SourceFrame.prototype = {
wasShown: function()
{
this._ensureContentLoaded();
this._textEditor.show(this.element);
this._wasShownOrLoaded();
},

willHide: function()
{
WebInspector.View.prototype.willHide.call(this);

this._clearLineHighlight();
this._clearLineToReveal();
},


statusBarItems: function()
{
return [];
},

defaultFocusedElement: function()
{
return this._textEditor.defaultFocusedElement();
},

get loaded()
{
return this._loaded;
},

hasContent: function()
{
return true;
},

get textEditor()
{
return this._textEditor;
},

_ensureContentLoaded: function()
{
if (!this._contentRequested) {
this._contentRequested = true;
this._contentProvider.requestContent(this.setContent.bind(this));
}
},

addMessage: function(msg)
{
this._messages.push(msg);
if (this.loaded)
this.addMessageToSource(msg.line - 1, msg);
},

clearMessages: function()
{
for (var line in this._messageBubbles) {
var bubble = this._messageBubbles[line];
bubble.parentNode.removeChild(bubble);
}

this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};

this._textEditor.doResize();
},


canHighlightLine: function(line)
{
return true;
},


highlightLine: function(line)
{
this._clearLineToReveal();
this._clearLineToScrollTo();
this._lineToHighlight = line;
this._innerHighlightLineIfNeeded();
this._textEditor.setSelection(WebInspector.TextRange.createFromLocation(line, 0));
},

_innerHighlightLineIfNeeded: function()
{
if (typeof this._lineToHighlight === "number") {
if (this.loaded && this._textEditor.isShowing()) {
this._textEditor.highlightLine(this._lineToHighlight);
delete this._lineToHighlight
}
}
},

_clearLineHighlight: function()
{
this._textEditor.clearLineHighlight();
delete this._lineToHighlight;
},


revealLine: function(line)
{
this._clearLineHighlight();
this._clearLineToScrollTo();
this._lineToReveal = line;
this._innerRevealLineIfNeeded();
},

_innerRevealLineIfNeeded: function()
{
if (typeof this._lineToReveal === "number") {
if (this.loaded && this._textEditor.isShowing()) {
this._textEditor.revealLine(this._lineToReveal);
delete this._lineToReveal
}
}
},

_clearLineToReveal: function()
{
delete this._lineToReveal;
},


scrollToLine: function(line)
{
this._clearLineHighlight();
this._clearLineToReveal();
this._lineToScrollTo = line;
this._innerScrollToLineIfNeeded();
},

_innerScrollToLineIfNeeded: function()
{
if (typeof this._lineToScrollTo === "number") {
if (this.loaded && this._textEditor.isShowing()) {
this._textEditor.scrollToLine(this._lineToScrollTo);
delete this._lineToScrollTo
}
}
},

_clearLineToScrollTo: function()
{
delete this._lineToScrollTo;
},


setSelection: function(textRange)
{
this._selectionToSet = textRange;
this._innerSetSelectionIfNeeded();
},

_innerSetSelectionIfNeeded: function()
{
if (this._selectionToSet && this.loaded && this._textEditor.isShowing()) {
this._textEditor.setSelection(this._selectionToSet);
delete this._selectionToSet;
}
},

_wasShownOrLoaded: function()
{
this._innerHighlightLineIfNeeded();
this._innerRevealLineIfNeeded();
this._innerScrollToLineIfNeeded();
this._innerSetSelectionIfNeeded();
},

onTextChanged: function(oldRange, newRange)
{
if (!this._isReplacing)
WebInspector.searchController.cancelSearch();
this.clearMessages();
},


setContent: function(content, contentEncoded, mimeType)
{
this._textEditor.mimeType = mimeType;

this._loaded = true;
this._textEditor.setText(content || "");

this._textEditor.beginUpdates();

this._setTextEditorDecorations();

this._wasShownOrLoaded();

if (this._delayedFindSearchMatches) {
this._delayedFindSearchMatches();
delete this._delayedFindSearchMatches;
}

this.onTextEditorContentLoaded();

this._textEditor.endUpdates();
},

onTextEditorContentLoaded: function() {},

_setTextEditorDecorations: function()
{
this._rowMessages = {};
this._messageBubbles = {};

this._textEditor.beginUpdates();

this._addExistingMessagesToSource();

this._textEditor.doResize();

this._textEditor.endUpdates();
},


performSearch: function(query, callback)
{

this.searchCanceled();

function doFindSearchMatches(query)
{
this._currentSearchResultIndex = -1;
this._searchResults = [];

var regex = WebInspector.SourceFrame.createSearchRegex(query);
this._searchResults = this._collectRegexMatches(regex);
var shiftToIndex = 0;
var selection = this._textEditor.lastSelection();
for (var i = 0; selection && i < this._searchResults.length; ++i) {
if (this._searchResults[i].compareTo(selection) >= 0) {
shiftToIndex = i;
break;
}
}

if (shiftToIndex)
this._searchResults = this._searchResults.rotate(shiftToIndex);

callback(this, this._searchResults.length);
}

if (this.loaded)
doFindSearchMatches.call(this, query);
else
this._delayedFindSearchMatches = doFindSearchMatches.bind(this, query);

this._ensureContentLoaded();
},

searchCanceled: function()
{
delete this._delayedFindSearchMatches;
if (!this.loaded)
return;

this._currentSearchResultIndex = -1;
this._searchResults = [];
this._textEditor.markAndRevealRange(null);
},

hasSearchResults: function()
{
return this._searchResults.length > 0;
},

jumpToFirstSearchResult: function()
{
this.jumpToSearchResult(0);
},

jumpToLastSearchResult: function()
{
this.jumpToSearchResult(this._searchResults.length - 1);
},

jumpToNextSearchResult: function()
{
this.jumpToSearchResult(this._currentSearchResultIndex + 1);
},

jumpToPreviousSearchResult: function()
{
this.jumpToSearchResult(this._currentSearchResultIndex - 1);
},

showingFirstSearchResult: function()
{
return this._searchResults.length &&  this._currentSearchResultIndex === 0;
},

showingLastSearchResult: function()
{
return this._searchResults.length && this._currentSearchResultIndex === (this._searchResults.length - 1);
},

get currentSearchResultIndex()
{
return this._currentSearchResultIndex;
},

jumpToSearchResult: function(index)
{
if (!this.loaded || !this._searchResults.length)
return;
this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
this._textEditor.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]);
},


replaceSearchMatchWith: function(text)
{
var range = this._searchResults[this._currentSearchResultIndex];
if (!range)
return;
this._textEditor.markAndRevealRange(null);

this._isReplacing = true;
var newRange = this._textEditor.editRange(range, text);
delete this._isReplacing;

this._textEditor.setSelection(newRange.collapseToEnd());
},


replaceAllWith: function(query, replacement)
{
this._textEditor.markAndRevealRange(null);

var text = this._textEditor.text();
var range = this._textEditor.range();
text = text.replace(WebInspector.SourceFrame.createSearchRegex(query, "g"), replacement);

this._isReplacing = true;
this._textEditor.editRange(range, text);
delete this._isReplacing;
},

_collectRegexMatches: function(regexObject)
{
var ranges = [];
for (var i = 0; i < this._textEditor.linesCount; ++i) {
var line = this._textEditor.line(i);
var offset = 0;
do {
var match = regexObject.exec(line);
if (match) {
if (match[0].length)
ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length));
offset += match.index + 1;
line = line.substring(match.index + 1);
}
} while (match && line);
}
return ranges;
},

_addExistingMessagesToSource: function()
{
var length = this._messages.length;
for (var i = 0; i < length; ++i)
this.addMessageToSource(this._messages[i].line - 1, this._messages[i]);
},

addMessageToSource: function(lineNumber, msg)
{
if (lineNumber >= this._textEditor.linesCount)
lineNumber = this._textEditor.linesCount - 1;
if (lineNumber < 0)
lineNumber = 0;

var messageBubbleElement = this._messageBubbles[lineNumber];
if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) {
messageBubbleElement = document.createElement("div");
messageBubbleElement.className = "webkit-html-message-bubble";
this._messageBubbles[lineNumber] = messageBubbleElement;
this._textEditor.addDecoration(lineNumber, messageBubbleElement);
}

var rowMessages = this._rowMessages[lineNumber];
if (!rowMessages) {
rowMessages = [];
this._rowMessages[lineNumber] = rowMessages;
}

for (var i = 0; i < rowMessages.length; ++i) {
if (rowMessages[i].consoleMessage.isEqual(msg)) {
rowMessages[i].repeatCount = msg.totalRepeatCount;
this._updateMessageRepeatCount(rowMessages[i]);
return;
}
}

var rowMessage = { consoleMessage: msg };
rowMessages.push(rowMessage);

var imageURL;
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Error:
messageBubbleElement.addStyleClass("webkit-html-error-message");
imageURL = "Images/errorIcon.png";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
messageBubbleElement.addStyleClass("webkit-html-warning-message");
imageURL = "Images/warningIcon.png";
break;
}

var messageLineElement = document.createElement("div");
messageLineElement.className = "webkit-html-message-line";
messageBubbleElement.appendChild(messageLineElement);


var image = document.createElement("img");
image.src = imageURL;
image.className = "webkit-html-message-icon";
messageLineElement.appendChild(image);
messageLineElement.appendChild(document.createTextNode(msg.message));

rowMessage.element = messageLineElement;
rowMessage.repeatCount = msg.totalRepeatCount;
this._updateMessageRepeatCount(rowMessage);
},

_updateMessageRepeatCount: function(rowMessage)
{
if (rowMessage.repeatCount < 2)
return;

if (!rowMessage.repeatCountElement) {
var repeatCountElement = document.createElement("span");
rowMessage.element.appendChild(repeatCountElement);
rowMessage.repeatCountElement = repeatCountElement;
}

rowMessage.repeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", rowMessage.repeatCount);
},

removeMessageFromSource: function(lineNumber, msg)
{
if (lineNumber >= this._textEditor.linesCount)
lineNumber = this._textEditor.linesCount - 1;
if (lineNumber < 0)
lineNumber = 0;

var rowMessages = this._rowMessages[lineNumber];
for (var i = 0; rowMessages && i < rowMessages.length; ++i) {
var rowMessage = rowMessages[i];
if (rowMessage.consoleMessage !== msg)
continue;

var messageLineElement = rowMessage.element;
var messageBubbleElement = messageLineElement.parentElement;
messageBubbleElement.removeChild(messageLineElement);
rowMessages.remove(rowMessage);
if (!rowMessages.length)
delete this._rowMessages[lineNumber];
if (!messageBubbleElement.childElementCount) {
this._textEditor.removeDecoration(lineNumber, messageBubbleElement);
delete this._messageBubbles[lineNumber];
}
break;
}
},

populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
},

populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
},

inheritScrollPositions: function(sourceFrame)
{
this._textEditor.inheritScrollPositions(sourceFrame._textEditor);
},


canEditSource: function()
{
return false;
},


commitEditing: function(text)
{
},


selectionChanged: function(textRange)
{
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
},


scrollChanged: function(lineNumber)
{
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.ScrollChanged, lineNumber);
},

_handleKeyDown: function(e)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
var handler = this._shortcuts[shortcutKey];
if (handler && handler())
e.consume(true);
},

_commitEditing: function()
{
if (this._textEditor.readOnly())
return false;

var content = this._textEditor.text();
this.commitEditing(content);
if (this._url && WebInspector.fileManager.isURLSaved(this._url))
WebInspector.fileManager.save(this._url, content, false);
return true;
}
}

WebInspector.SourceFrame.prototype.__proto__ = WebInspector.View.prototype;



WebInspector.TextEditorDelegateForSourceFrame = function(sourceFrame)
{
this._sourceFrame = sourceFrame;
}

WebInspector.TextEditorDelegateForSourceFrame.prototype = {
onTextChanged: function(oldRange, newRange)
{
this._sourceFrame.onTextChanged(oldRange, newRange);
},


selectionChanged: function(textRange)
{
this._sourceFrame.selectionChanged(textRange);
},


scrollChanged: function(lineNumber)
{
this._sourceFrame.scrollChanged(lineNumber);
},

populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
this._sourceFrame.populateLineGutterContextMenu(contextMenu, lineNumber);
},

populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
this._sourceFrame.populateTextAreaContextMenu(contextMenu, lineNumber);
},


createLink: function(hrefValue, isExternal)
{
var targetLocation = WebInspector.ParsedURL.completeURL(this._sourceFrame._url, hrefValue);
return WebInspector.linkifyURLAsNode(targetLocation || hrefValue, hrefValue, undefined, isExternal);
}
}

WebInspector.TextEditorDelegateForSourceFrame.prototype.__proto__ = WebInspector.TextEditorDelegate.prototype;






WebInspector.ResourceView = function(resource)
{
WebInspector.View.call(this);
this.registerRequiredCSS("resourceView.css");

this.element.addStyleClass("resource-view");
this.resource = resource;
}

WebInspector.ResourceView.prototype = {
hasContent: function()
{
return false;
}
}

WebInspector.ResourceView.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.ResourceView.hasTextContent = function(resource)
{
if (resource.type.isTextType())
return true; 
if (resource.type === WebInspector.resourceTypes.Other)
return resource.content && !resource.contentEncoded;
return false;
}


WebInspector.ResourceView.nonSourceViewForResource = function(resource)
{
switch (resource.type) {
case WebInspector.resourceTypes.Image:
return new WebInspector.ImageView(resource);
case WebInspector.resourceTypes.Font:
return new WebInspector.FontView(resource);
default:
return new WebInspector.ResourceView(resource);
}
}


WebInspector.ResourceSourceFrame = function(resource)
{
this._resource = resource;
WebInspector.SourceFrame.call(this, resource);
}

WebInspector.ResourceSourceFrame.prototype = {
get resource()
{
return this._resource;
},

populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
contextMenu.appendApplicableItems(this._resource);
if (this._resource.request)
contextMenu.appendApplicableItems(this._resource.request);
}
}

WebInspector.ResourceSourceFrame.prototype.__proto__ = WebInspector.SourceFrame.prototype;






WebInspector.FontView = function(resource)
{
WebInspector.ResourceView.call(this, resource);

this.element.addStyleClass("font");
}

WebInspector.FontView._fontPreviewLines = [ "ABCDEFGHIJKLM", "NOPQRSTUVWXYZ", "abcdefghijklm", "nopqrstuvwxyz", "1234567890" ];

WebInspector.FontView._fontId = 0;

WebInspector.FontView._measureFontSize = 50;

WebInspector.FontView.prototype = {
hasContent: function()
{
return true;
},

_createContentIfNeeded: function()
{
if (this.fontPreviewElement)
return;

var uniqueFontName = "WebInspectorFontPreview" + (++WebInspector.FontView._fontId);

this.fontStyleElement = document.createElement("style");
this.fontStyleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this.resource.url + "); }";
document.head.appendChild(this.fontStyleElement);

var fontPreview = document.createElement("div");
for (var i = 0; i < WebInspector.FontView._fontPreviewLines.length; ++i) {
if (i > 0)
fontPreview.appendChild(document.createElement("br"));
fontPreview.appendChild(document.createTextNode(WebInspector.FontView._fontPreviewLines[i]));
}
this.fontPreviewElement = fontPreview.cloneNode(true);
this.fontPreviewElement.style.setProperty("font-family", uniqueFontName);
this.fontPreviewElement.style.setProperty("visibility", "hidden");

this._dummyElement = fontPreview;
this._dummyElement.style.visibility = "hidden";
this._dummyElement.style.zIndex = "-1";
this._dummyElement.style.display = "inline";
this._dummyElement.style.position = "absolute";
this._dummyElement.style.setProperty("font-family", uniqueFontName);
this._dummyElement.style.setProperty("font-size", WebInspector.FontView._measureFontSize + "px");

this.element.appendChild(this.fontPreviewElement);
},

wasShown: function()
{
this._createContentIfNeeded();

this.updateFontPreviewSize();
},

onResize: function()
{
if (this._inResize)
return;

this._inResize = true;
try {
this.updateFontPreviewSize();
} finally {
delete this._inResize;
}
},

_measureElement: function()
{
this.element.appendChild(this._dummyElement);
var result = { width: this._dummyElement.offsetWidth, height: this._dummyElement.offsetHeight };
this.element.removeChild(this._dummyElement);

return result;
},

updateFontPreviewSize: function()
{
if (!this.fontPreviewElement || !this.isShowing())
return;

this.fontPreviewElement.style.removeProperty("visibility");
var dimension = this._measureElement();

const height = dimension.height;
const width = dimension.width;


const containerWidth = this.element.offsetWidth - 50;
const containerHeight = this.element.offsetHeight - 30;

if (!height || !width || !containerWidth || !containerHeight) {
this.fontPreviewElement.style.removeProperty("font-size");
return;
}

var widthRatio = containerWidth / width;
var heightRatio = containerHeight / height;
var finalFontSize = Math.floor(WebInspector.FontView._measureFontSize * Math.min(widthRatio, heightRatio)) - 2;

this.fontPreviewElement.style.setProperty("font-size", finalFontSize + "px", null);
}
}

WebInspector.FontView.prototype.__proto__ = WebInspector.ResourceView.prototype;






WebInspector.ImageView = function(resource)
{
WebInspector.ResourceView.call(this, resource);

this.element.addStyleClass("image");
}

WebInspector.ImageView.prototype = {
hasContent: function()
{
return true;
},

wasShown: function()
{
this._createContentIfNeeded();
},

_createContentIfNeeded: function()
{
if (this._container)
return;

var imageContainer = document.createElement("div");
imageContainer.className = "image";
this.element.appendChild(imageContainer);

var imagePreviewElement = document.createElement("img");
imagePreviewElement.addStyleClass("resource-image-view");
imageContainer.appendChild(imagePreviewElement);
imagePreviewElement.addEventListener("contextmenu", this._contextMenu.bind(this), true);

this._container = document.createElement("div");
this._container.className = "info";
this.element.appendChild(this._container);

var imageNameElement = document.createElement("h1");
imageNameElement.className = "title";
imageNameElement.textContent = this.resource.displayName;
this._container.appendChild(imageNameElement);

var infoListElement = document.createElement("dl");
infoListElement.className = "infoList";

this.resource.populateImageSource(imagePreviewElement);

function onImageLoad()
{
var content = this.resource.content;
if (content)
var resourceSize = this._base64ToSize(content);
else
var resourceSize = this.resource.resourceSize;

var imageProperties = [
{ name: WebInspector.UIString("Dimensions"), value: WebInspector.UIString("%d × %d", imagePreviewElement.naturalWidth, imagePreviewElement.naturalHeight) },
{ name: WebInspector.UIString("File size"), value: Number.bytesToString(resourceSize) },
{ name: WebInspector.UIString("MIME type"), value: this.resource.mimeType }
];

infoListElement.removeChildren();
for (var i = 0; i < imageProperties.length; ++i) {
var dt = document.createElement("dt");
dt.textContent = imageProperties[i].name;
infoListElement.appendChild(dt);
var dd = document.createElement("dd");
dd.textContent = imageProperties[i].value;
infoListElement.appendChild(dd);
}
var dt = document.createElement("dt");
dt.textContent = WebInspector.UIString("URL");
infoListElement.appendChild(dt);
var dd = document.createElement("dd");
var externalResource = true;
dd.appendChild(WebInspector.linkifyURLAsNode(this.resource.url, undefined, undefined, externalResource));
infoListElement.appendChild(dd);

this._container.appendChild(infoListElement);
}
imagePreviewElement.addEventListener("load", onImageLoad.bind(this), false);
},

_base64ToSize: function(content)
{
if (!content.length)
return 0;
var size = (content.length || 0) * 3 / 4;
if (content.length > 0 && content[content.length - 1] === "=")
size--;
if (content.length > 1 && content[content.length - 2] === "=")
size--;
return size;
},

_contextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy image URL" : "Copy Image URL"), this._copyImageURL.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open image in new tab" : "Open Image in New Tab"), this._openInNewTab.bind(this));
contextMenu.show(event);
},

_copyImageURL: function(event)
{
InspectorFrontendHost.copyText(this.resource.url);
},

_openInNewTab: function(event)
{
InspectorFrontendHost.openInNewTab(this.resource.url);
}
}

WebInspector.ImageView.prototype.__proto__ = WebInspector.ResourceView.prototype;






WebInspector.SplitView = function(sidebarPosition, sidebarWidthSettingName, defaultSidebarWidth)
{
WebInspector.View.call(this);
this.registerRequiredCSS("splitView.css");

this.element.className = "split-view";

this._leftElement = document.createElement("div");
this._leftElement.className = "split-view-contents";
this.element.appendChild(this._leftElement);

this._rightElement = document.createElement("div");
this._rightElement.className = "split-view-contents";
this.element.appendChild(this._rightElement);

this.sidebarResizerElement = document.createElement("div");
this.sidebarResizerElement.className = "split-view-resizer";
this.installResizer(this.sidebarResizerElement);
this._resizable = true;
this.element.appendChild(this.sidebarResizerElement);

defaultSidebarWidth = defaultSidebarWidth || 200;
this._savedSidebarWidth = defaultSidebarWidth;

this._sidebarWidthSettingName = sidebarWidthSettingName;
if (this._sidebarWidthSettingName)
WebInspector.settings[this._sidebarWidthSettingName] = WebInspector.settings.createSetting(this._sidebarWidthSettingName, undefined);

this._minimalSidebarWidth = Preferences.minSidebarWidth;
this._minimalMainWidth = 0;
this._minimalSidebarWidthPercent = 0;
this._minimalMainWidthPercent = 50;

this._mainElementHidden = false;
this._sidebarElementHidden = false;

this._innerSetSidebarPosition(sidebarPosition || WebInspector.SplitView.SidebarPosition.Left);
}

WebInspector.SplitView.EventTypes = {
Resized: "Resized"
}


WebInspector.SplitView.SidebarPosition = {
Left: "Left",
Right: "Right"
}

WebInspector.SplitView.prototype = {

get hasLeftSidebar()
{
return this._sidebarPosition === WebInspector.SplitView.SidebarPosition.Left;
},


get mainElement()
{
return this.hasLeftSidebar ? this._rightElement : this._leftElement;
},


get sidebarElement()
{
return this.hasLeftSidebar ? this._leftElement : this._rightElement;
},


get resizable()
{
return this._resizable && !this._mainElementHidden && !this._sidebarElementHidden;
},


set resizable(resizable)
{
if (this._resizable === resizable)
return;
this._resizable = resizable;
this._updateResizer(resizable);
},

_updateResizer: function()
{
if (this.resizable)
this.sidebarResizerElement.removeStyleClass("hidden");
else
this.sidebarResizerElement.addStyleClass("hidden");
},


set sidebarPosition(sidebarPosition)
{
if (this._sidebarPosition === sidebarPosition)
return;
this._innerSetSidebarPosition(sidebarPosition);
this._restoreSidebarWidth();
},


_innerSetSidebarPosition: function(sidebarPosition)
{
this._sidebarPosition = sidebarPosition;

this._leftElement.style.left = 0;
this._rightElement.style.right = 0;
if (this.hasLeftSidebar) {
this._leftElement.addStyleClass("split-view-sidebar-left");
this._rightElement.removeStyleClass("split-view-sidebar-right");
this._leftElement.style.removeProperty("right");
this._rightElement.style.removeProperty("width");
this.sidebarResizerElement.style.removeProperty("right");
} else {
this._rightElement.addStyleClass("split-view-sidebar-right");
this._leftElement.removeStyleClass("split-view-sidebar-left");
this._leftElement.style.removeProperty("width");
this._rightElement.style.removeProperty("left");
this.sidebarResizerElement.style.removeProperty("left");
}
},


set minimalSidebarWidth(width)
{
this._minimalSidebarWidth = width;
},


set minimalMainWidth(width)
{
this._minimalMainWidth = width;
},


set minimalSidebarWidthPercent(widthPercent)
{
this._minimalSidebarWidthPercent = widthPercent;
},


set minimalMainWidthPercent(widthPercent)
{
this._minimalMainWidthPercent = widthPercent;
},


setMainWidth: function(width)
{
this.setSidebarWidth(this._totalWidth - width);
},


setSidebarWidth: function(width)
{
if (this._sidebarWidth === width)
return;

this._innerSetSidebarWidth(width);
this.saveSidebarWidth();
},

sidebarWidth: function()
{
return this._sidebarWidth;
},


_innerSetSidebarWidth: function(width)
{
if (this.hasLeftSidebar)
this._innerSetLeftSidebarWidth(width);
else
this._innerSetRightSidebarWidth(width);
this._sidebarWidth = width;
this.doResize();
this.dispatchEventToListeners(WebInspector.SplitView.EventTypes.Resized, this._sidebarWidth);
},


_innerSetLeftSidebarWidth: function(width)
{
this._leftElement.style.width = width + "px";
this._rightElement.style.left = width + "px";
this.sidebarResizerElement.style.left = (width - 3) + "px";
},


_innerSetRightSidebarWidth: function(width)
{
this._rightElement.style.width = width + "px";
this._leftElement.style.right = width + "px";
this.sidebarResizerElement.style.right = (width - 3) + "px";
},


_setSidebarWidthEnsuringConstraints: function(width)
{
var minWidth = Math.max(this._minimalSidebarWidth, this._totalWidth * this._minimalSidebarWidthPercent);
var maxWidth = Math.min(this._totalWidth - this._minimalMainWidth, this._totalWidth * (100 - this._minimalMainWidthPercent) / 100 );
width = Number.constrain(width, minWidth, maxWidth);

this.setSidebarWidth(width);
},

hideMainElement: function()
{
if (this._mainElementHidden)
return;

if (this._sidebarElementHidden)
this.showSidebarElement();

this.mainElement.addStyleClass("hidden");
this.sidebarElement.addStyleClass("maximized");

if (this.hasLeftSidebar)
this.sidebarElement.style.right = "0px";
else
this.sidebarElement.style.left = "0px";

this._mainElementHidden = true;
this._updateResizer();
this._restoreSidebarWidth();
this.doResize();
},

showMainElement: function()
{
if (!this._mainElementHidden)
return;

this.mainElement.removeStyleClass("hidden");
this.sidebarElement.removeStyleClass("maximized");

if (this.hasLeftSidebar)
this.sidebarElement.style.right = "";
else
this.sidebarElement.style.left = "";

this._mainElementHidden = false;
this._updateResizer();
this._restoreSidebarWidth();
this.doResize();
},

hideSidebarElement: function()
{
if (this._sidebarElementHidden)
return;

if (this._mainElementHidden)
this.showMainElement();

this.sidebarElement.addStyleClass("hidden");
this._sidebarElementHidden = true;
this._updateResizer();
this._restoreSidebarWidth();
this.doResize();
},

showSidebarElement: function()
{
if (!this._sidebarElementHidden)
return;

this.sidebarElement.removeStyleClass("hidden");
this._sidebarElementHidden = false;
this._updateResizer();
this._restoreSidebarWidth();
this.doResize();
},

wasShown: function()
{
this._totalWidth = this.element.offsetWidth;
this._restoreSidebarWidth();
},

onResize: function()
{
this._totalWidth = this.element.offsetWidth;

if (this._mainElementHidden)
this._sidebarWidth = this._totalWidth;
},


_startResizerDragging: function(event)
{
if (!this._resizable)
return false;

var leftWidth = this.hasLeftSidebar ? this._sidebarWidth : this._totalWidth - this._sidebarWidth;
this._dragOffset = leftWidth - event.pageX;
return true;
},


_resizerDragging: function(event)
{
var leftWidth = event.pageX + this._dragOffset;
var rightWidth = this._totalWidth - leftWidth;
var sidebarWidth = this.hasLeftSidebar ? leftWidth : rightWidth;

this._setSidebarWidthEnsuringConstraints(sidebarWidth);
event.preventDefault();
},


_endResizerDragging: function(event)
{
delete this._dragOffset;
},


installResizer: function(resizerElement)
{
WebInspector.installDragHandle(resizerElement, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "ew-resize");
},


preferredSidebarWidth: function()
{
if (!this._sidebarWidthSettingName)
return this._savedSidebarWidth;

return WebInspector.settings[this._sidebarWidthSettingName].get() || this._savedSidebarWidth;
},

_restoreSidebarWidth: function()
{
if (this._mainElementHidden) {
this.sidebarElement.style.width = "";
this._sidebarWidth = this._totalWidth;
return;
}

if (this._sidebarElementHidden) {
this._innerSetSidebarWidth(0);
return;
}


this._setSidebarWidthEnsuringConstraints(this.preferredSidebarWidth());
},

saveSidebarWidth: function()
{
this._savedSidebarWidth = this._sidebarWidth;
if (!this._sidebarWidthSettingName)
return;

WebInspector.settings[this._sidebarWidthSettingName].set(this._sidebarWidth);
},


elementsToRestoreScrollPositionsFor: function()
{
return [ this.mainElement, this.sidebarElement ];
}
}

WebInspector.SplitView.prototype.__proto__ = WebInspector.View.prototype;






WebInspector.ConsolePanel = function()
{
WebInspector.Panel.call(this, "console");

WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.EntryAdded, this._consoleMessageAdded, this);
WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.ConsoleCleared, this._consoleCleared, this);
this._view = WebInspector.consoleView;
}

WebInspector.ConsolePanel.prototype = {
get statusBarItems()
{
return this._view.statusBarItems;
},

wasShown: function()
{
WebInspector.Panel.prototype.wasShown.call(this);
if (WebInspector.drawer.visible) {
WebInspector.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
this._drawerWasVisible = true;
}
this._view.show(this.element);
},

willHide: function()
{
if (this._drawerWasVisible) {
WebInspector.drawer.show(this._view, WebInspector.Drawer.AnimationType.Immediately);
delete this._drawerWasVisible;
}
WebInspector.Panel.prototype.willHide.call(this);
},

searchCanceled: function()
{
this._clearCurrentSearchResultHighlight();
delete this._searchResults;
delete this._searchRegex;
},


performSearch: function(query)
{
WebInspector.searchController.updateSearchMatchesCount(0, this);
this.searchCanceled();
this._searchRegex = createPlainTextSearchRegex(query, "gi");

this._searchResults = [];
var messages = WebInspector.consoleView.messages;
for (var i = 0; i < messages.length; i++) {
if (messages[i].matchesRegex(this._searchRegex)) {
this._searchResults.push(messages[i]);
this._searchRegex.lastIndex = 0;
}
}
WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this);
this._currentSearchResultIndex = -1;
if (this._searchResults.length)
this._jumpToSearchResult(0);
},

jumpToNextSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._jumpToSearchResult((this._currentSearchResultIndex + 1) % this._searchResults.length);
},

jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
var index = this._currentSearchResultIndex - 1;
if (index === -1)
index = this._searchResults.length - 1;
this._jumpToSearchResult(index);
return true;
},

_clearCurrentSearchResultHighlight: function()
{
if (!this._searchResults)
return;
var highlightedMessage = this._searchResults[this._currentSearchResultIndex];
if (highlightedMessage)
highlightedMessage.clearHighlight();
this._currentSearchResultIndex = -1;
},

_jumpToSearchResult: function(index)
{
this._clearCurrentSearchResultHighlight();
this._currentSearchResultIndex = index;
WebInspector.searchController.updateCurrentMatchIndex(this._currentSearchResultIndex, this);
this._searchResults[index].highlightSearchResults(this._searchRegex);
},

_consoleMessageAdded: function(event)
{
if (!this._searchRegex || !this.isShowing())
return;
var message = event.data;
this._searchRegex.lastIndex = 0;
if (message.matchesRegex(this._searchRegex)) {
this._searchResults.push(message);
WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this);
}
},

_consoleCleared: function()
{
if (!this._searchResults)
return;
this._clearCurrentSearchResultHighlight();
this._searchResults.length = 0;
if (this.isShowing())
WebInspector.searchController.updateSearchMatchesCount(0, this);
}
}

WebInspector.ConsolePanel.prototype.__proto__ = WebInspector.Panel.prototype;





function defineCommonExtensionSymbols(apiPrivate)
{
if (!apiPrivate.audits)
apiPrivate.audits = {};
apiPrivate.audits.Severity = {
Info: "info",
Warning: "warning",
Severe: "severe"
};

if (!apiPrivate.console)
apiPrivate.console = {};
apiPrivate.console.Severity = {
Tip: "tip",
Debug: "debug",
Log: "log",
Warning: "warning",
Error: "error"
};

if (!apiPrivate.panels)
apiPrivate.panels = {};
apiPrivate.panels.SearchAction = {
CancelSearch: "cancelSearch",
PerformSearch: "performSearch",
NextSearchResult: "nextSearchResult",
PreviousSearchResult: "previousSearchResult"
};

apiPrivate.Events = {
AuditStarted: "audit-started-",
ButtonClicked: "button-clicked-",
ConsoleMessageAdded: "console-message-added",
ElementsPanelObjectSelected: "panel-objectSelected-elements",
NetworkRequestFinished: "network-request-finished",
Reset: "reset",
OpenResource: "open-resource",
PanelSearch: "panel-search-",
Reload: "Reload",
ResourceAdded: "resource-added",
ResourceContentCommitted: "resource-content-committed",
TimelineEventRecorded: "timeline-event-recorded",
ViewShown: "view-shown-",
ViewHidden: "view-hidden-"
};

apiPrivate.Commands = {
AddAuditCategory: "addAuditCategory",
AddAuditResult: "addAuditResult",
AddConsoleMessage: "addConsoleMessage",
AddRequestHeaders: "addRequestHeaders",
CreatePanel: "createPanel",
CreateSidebarPane: "createSidebarPane",
CreateStatusBarButton: "createStatusBarButton",
EvaluateOnInspectedPage: "evaluateOnInspectedPage",
GetConsoleMessages: "getConsoleMessages",
GetHAR: "getHAR",
GetPageResources: "getPageResources",
GetRequestContent: "getRequestContent",
GetResourceContent: "getResourceContent",
Subscribe: "subscribe",
SetOpenResourceHandler: "setOpenResourceHandler",
SetResourceContent: "setResourceContent",
SetSidebarContent: "setSidebarContent",
SetSidebarHeight: "setSidebarHeight",
SetSidebarPage: "setSidebarPage",
ShowPanel: "showPanel",
StopAuditCategoryRun: "stopAuditCategoryRun",
Unsubscribe: "unsubscribe",
UpdateAuditProgress: "updateAuditProgress",
UpdateButton: "updateButton",
InspectedURLChanged: "inspectedURLChanged"
};
}

function injectedExtensionAPI(injectedScriptId)
{

var apiPrivate = {};

defineCommonExtensionSymbols(apiPrivate);

var commands = apiPrivate.Commands;
var events = apiPrivate.Events;
var userAction = false;








function EventSinkImpl(type, customDispatch)
{
this._type = type;
this._listeners = [];
this._customDispatch = customDispatch;
}

EventSinkImpl.prototype = {
addListener: function(callback)
{
if (typeof callback !== "function")
throw "addListener: callback is not a function";
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: commands.Subscribe, type: this._type });
this._listeners.push(callback);
extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(this));
},

removeListener: function(callback)
{
var listeners = this._listeners;

for (var i = 0; i < listeners.length; ++i) {
if (listeners[i] === callback) {
listeners.splice(i, 1);
break;
}
}
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: commands.Unsubscribe, type: this._type });
},

_fire: function()
{
var listeners = this._listeners.slice();
for (var i = 0; i < listeners.length; ++i)
listeners[i].apply(null, arguments);
},

_dispatch: function(request)
{
if (this._customDispatch)
this._customDispatch.call(this, request);
else
this._fire.apply(this, request.arguments);
}
}


function InspectorExtensionAPI()
{
this.audits = new Audits();
this.inspectedWindow = new InspectedWindow();
this.panels = new Panels();
this.network = new Network();
defineDeprecatedProperty(this, "webInspector", "resources", "network");
this.timeline = new Timeline();
this.console = new ConsoleAPI();

this.onReset = new EventSink(events.Reset);
}


InspectorExtensionAPI.prototype = {
log: function(message)
{
extensionServer.sendRequest({ command: commands.Log, message: message });
}
}


function ConsoleAPI()
{
this.onMessageAdded = new EventSink(events.ConsoleMessageAdded);
}

ConsoleAPI.prototype = {
getMessages: function(callback)
{
extensionServer.sendRequest({ command: commands.GetConsoleMessages }, callback);
},

addMessage: function(severity, text, url, line)
{
extensionServer.sendRequest({ command: commands.AddConsoleMessage, severity: severity, text: text, url: url, line: line });
},

get Severity()
{
return apiPrivate.console.Severity;
}
}


function Network()
{
function dispatchRequestEvent(message)
{
var request = message.arguments[1];
request.__proto__ = new Request(message.arguments[0]);
this._fire(request);
}
this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent);
defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished");
this.onNavigated = new EventSink(events.InspectedURLChanged);
}

Network.prototype = {
getHAR: function(callback)
{
function callbackWrapper(result)
{
var entries = (result && result.entries) || [];
for (var i = 0; i < entries.length; ++i) {
entries[i].__proto__ = new Request(entries[i]._requestId);
delete entries[i]._requestId;
}
callback(result);
}
return extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper);
},

addRequestHeaders: function(headers)
{
return extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname });
}
}


function RequestImpl(id)
{
this._id = id;
}

RequestImpl.prototype = {
getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}
extensionServer.sendRequest({ command: commands.GetRequestContent, id: this._id }, callback && callbackWrapper);
}
}


function Panels()
{
var panels = {
elements: new ElementsPanel()
};

function panelGetter(name)
{
return panels[name];
}
for (var panel in panels)
this.__defineGetter__(panel, panelGetter.bind(null, panel));
}

Panels.prototype = {
create: function(title, icon, page, callback)
{
var id = "extension-panel-" + extensionServer.nextObjectId();
var request = {
command: commands.CreatePanel,
id: id,
title: title,
icon: icon,
page: page
};
extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id)));
},

setOpenResourceHandler: function(callback)
{
var hadHandler = extensionServer.hasHandler(events.OpenResource);

if (!callback)
extensionServer.unregisterHandler(events.OpenResource);
else {
function callbackWrapper(message)
{

userAction = true;
try {
callback.call(null, new Resource(message.resource), message.lineNumber);
} finally {
userAction = false;
}
}
extensionServer.registerHandler(events.OpenResource, callbackWrapper);
}

if (hadHandler === !callback)
extensionServer.sendRequest({ command: commands.SetOpenResourceHandler, "handlerPresent": !!callback });
},

get SearchAction()
{
return apiPrivate.panels.SearchAction;
}
}


function ExtensionViewImpl(id)
{
this._id = id;

function dispatchShowEvent(message)
{
var frameIndex = message.arguments[0];
this._fire(window.parent.frames[frameIndex]);
}
this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
this.onHidden = new EventSink(events.ViewHidden + id);
}


function PanelWithSidebarImpl(id)
{
this._id = id;
}

PanelWithSidebarImpl.prototype = {
createSidebarPane: function(title, callback)
{
var id = "extension-sidebar-" + extensionServer.nextObjectId();
var request = {
command: commands.CreateSidebarPane,
panel: this._id,
id: id,
title: title
};
function callbackWrapper()
{
callback(new ExtensionSidebarPane(id));
}
extensionServer.sendRequest(request, callback && callbackWrapper);
}
}

PanelWithSidebarImpl.prototype.__proto__ = ExtensionViewImpl.prototype;


function ElementsPanel()
{
var id = "elements";
PanelWithSidebar.call(this, id);
this.onSelectionChanged = new EventSink(events.ElementsPanelObjectSelected);
}


function ExtensionPanelImpl(id)
{
ExtensionViewImpl.call(this, id);
this.onSearch = new EventSink(events.PanelSearch + id);
}

ExtensionPanelImpl.prototype = {
createStatusBarButton: function(iconPath, tooltipText, disabled)
{
var id = "button-" + extensionServer.nextObjectId();
var request = {
command: commands.CreateStatusBarButton,
panel: this._id,
id: id,
icon: iconPath,
tooltip: tooltipText,
disabled: !!disabled
};
extensionServer.sendRequest(request);
return new Button(id);
},

show: function()
{
if (!userAction)
return;

var request = {
command: commands.ShowPanel,
id: this._id
};
extensionServer.sendRequest(request);
}
};

ExtensionPanelImpl.prototype.__proto__ = ExtensionViewImpl.prototype;


function ExtensionSidebarPaneImpl(id)
{
ExtensionViewImpl.call(this, id);
}

ExtensionSidebarPaneImpl.prototype = {
setHeight: function(height)
{
extensionServer.sendRequest({ command: commands.SetSidebarHeight, id: this._id, height: height });
},

setExpression: function(expression, rootTitle, evaluateOptions)
{
var callback = extractCallbackArgument(arguments);
var request = {
command: commands.SetSidebarContent,
id: this._id,
expression: expression,
rootTitle: rootTitle,
evaluateOnPage: true,
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
extensionServer.sendRequest(request, callback);
},

setObject: function(jsonObject, rootTitle, callback)
{
extensionServer.sendRequest({ command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle }, callback);
},

setPage: function(page)
{
extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page });
}
}


function ButtonImpl(id)
{
this._id = id;
this.onClicked = new EventSink(events.ButtonClicked + id);
}

ButtonImpl.prototype = {
update: function(iconPath, tooltipText, disabled)
{
var request = {
command: commands.UpdateButton,
id: this._id,
icon: iconPath,
tooltip: tooltipText,
disabled: !!disabled
};
extensionServer.sendRequest(request);
}
};


function Audits()
{
}

Audits.prototype = {
addCategory: function(displayName, resultCount)
{
var id = "extension-audit-category-" + extensionServer.nextObjectId();
if (typeof resultCount !== "undefined")
console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead.");
extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id, displayName: displayName, resultCount: resultCount });
return new AuditCategory(id);
}
}


function AuditCategoryImpl(id)
{
function dispatchAuditEvent(request)
{
var auditResult = new AuditResult(request.arguments[0]);
try {
this._fire(auditResult);
} catch (e) {
console.error("Uncaught exception in extension audit event handler: " + e);
auditResult.done();
}
}
this._id = id;
this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditEvent);
}


function AuditResultImpl(id)
{
this._id = id;

this.createURL = this._nodeFactory.bind(null, "url");
this.createSnippet = this._nodeFactory.bind(null, "snippet");
this.createText = this._nodeFactory.bind(null, "text");
this.createObject = this._nodeFactory.bind(null, "object");
this.createNode = this._nodeFactory.bind(null, "node");
}

AuditResultImpl.prototype = {
addResult: function(displayName, description, severity, details)
{

if (details && !(details instanceof AuditResultNode))
details = new AuditResultNode(details instanceof Array ? details : [details]);

var request = {
command: commands.AddAuditResult,
resultId: this._id,
displayName: displayName,
description: description,
severity: severity,
details: details
};
extensionServer.sendRequest(request);
},

createResult: function()
{
return new AuditResultNode(Array.prototype.slice.call(arguments));
},

updateProgress: function(worked, totalWork)
{
extensionServer.sendRequest({ command: commands.UpdateAuditProgress, resultId: this._id, progress: worked / totalWork });
},

done: function()
{
extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id });
},

get Severity()
{
return apiPrivate.audits.Severity;
},

createResourceLink: function(url, lineNumber)
{
return {
type: "resourceLink",
arguments: [url, lineNumber && lineNumber - 1]
};
},

_nodeFactory: function(type)
{
return {
type: type,
arguments: Array.prototype.slice.call(arguments, 1)
};
}
}


function AuditResultNode(contents)
{
this.contents = contents;
this.children = [];
this.expanded = false;
}

AuditResultNode.prototype = {
addChild: function()
{
var node = new AuditResultNode(Array.prototype.slice.call(arguments));
this.children.push(node);
return node;
}
};


function InspectedWindow()
{
function dispatchResourceEvent(message)
{
this._fire(new Resource(message.arguments[0]));
}
function dispatchResourceContentEvent(message)
{
this._fire(new Resource(message.arguments[0]), message.arguments[1]);
}
this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent);
this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent);
}

InspectedWindow.prototype = {
reload: function(optionsOrUserAgent)
{
var options = null;
if (typeof optionsOrUserAgent === "object")
options = optionsOrUserAgent;
else if (typeof optionsOrUserAgent === "string") {
options = { userAgent: optionsOrUserAgent };
console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " +
"Use inspectedWindow.reload({ userAgent: value}) instead.");
}
return extensionServer.sendRequest({ command: commands.Reload, options: options });
},

eval: function(expression, evaluateOptions)
{
var callback = extractCallbackArgument(arguments);
function callbackWrapper(result)
{
callback(result.value, result.isException);
}
var request = {
command: commands.EvaluateOnInspectedPage,
expression: expression
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
return extensionServer.sendRequest(request, callback && callbackWrapper);
},

getResources: function(callback)
{
function wrapResource(resourceData)
{
return new Resource(resourceData);
}
function callbackWrapper(resources)
{
callback(resources.map(wrapResource));
}
return extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper);
}
}


function ResourceImpl(resourceData)
{
this._url = resourceData.url
this._type = resourceData.type;
}

ResourceImpl.prototype = {
get url()
{
return this._url;
},

get type()
{
return this._type;
},

getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}

return extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
},

setContent: function(content, commit, callback)
{
return extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
}
}


function TimelineImpl()
{
this.onEventRecorded = new EventSink(events.TimelineEventRecorded);
}


function ExtensionServerClient()
{
this._callbacks = {};
this._handlers = {};
this._lastRequestId = 0;
this._lastObjectId = 0;

this.registerHandler("callback", this._onCallback.bind(this));

var channel = new MessageChannel();
this._port = channel.port1;
this._port.addEventListener("message", this._onMessage.bind(this), false);
this._port.start();

window.parent.postMessage("registerExtension", [ channel.port2 ], "*");
}

ExtensionServerClient.prototype = {
sendRequest: function(message, callback)
{
if (typeof callback === "function")
message.requestId = this._registerCallback(callback);
return this._port.postMessage(message);
},

hasHandler: function(command)
{
return !!this._handlers[command];
},

registerHandler: function(command, handler)
{
this._handlers[command] = handler;
},

unregisterHandler: function(command)
{
delete this._handlers[command];
},

nextObjectId: function()
{
return injectedScriptId + "_" + ++this._lastObjectId;
},

_registerCallback: function(callback)
{
var id = ++this._lastRequestId;
this._callbacks[id] = callback;
return id;
},

_onCallback: function(request)
{
if (request.requestId in this._callbacks) {
var callback = this._callbacks[request.requestId];
delete this._callbacks[request.requestId];
callback(request.result);
}
},

_onMessage: function(event)
{
var request = event.data;
var handler = this._handlers[request.command];
if (handler)
handler.call(this, request);
}
}

function populateInterfaceClass(interface, implementation)
{
for (var member in implementation) {
if (member.charAt(0) === "_")
continue;
var descriptor = null;

for (var owner = implementation; owner && !descriptor; owner = owner.__proto__)
descriptor = Object.getOwnPropertyDescriptor(owner, member);
if (!descriptor)
continue;
if (typeof descriptor.value === "function")
interface[member] = descriptor.value.bind(implementation);
else if (typeof descriptor.get === "function")
interface.__defineGetter__(member, descriptor.get.bind(implementation));
else
Object.defineProperty(interface, member, descriptor);
}
}

function declareInterfaceClass(implConstructor)
{
return function()
{
var impl = { __proto__: implConstructor.prototype };
implConstructor.apply(impl, arguments);
populateInterfaceClass(this, impl);
}
}

function defineDeprecatedProperty(object, className, oldName, newName)
{
var warningGiven = false;
function getter()
{
if (!warningGiven) {
console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead");
warningGiven = true;
}
return object[newName];
}
object.__defineGetter__(oldName, getter);
}

function extractCallbackArgument(args)
{
var lastArgument = args[args.length - 1];
return typeof lastArgument === "function" ? lastArgument : undefined;
}

var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
var AuditResult = declareInterfaceClass(AuditResultImpl);
var Button = declareInterfaceClass(ButtonImpl);
var EventSink = declareInterfaceClass(EventSinkImpl);
var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
var Request = declareInterfaceClass(RequestImpl);
var Resource = declareInterfaceClass(ResourceImpl);
var Timeline = declareInterfaceClass(TimelineImpl);

var extensionServer = new ExtensionServerClient();

return new InspectorExtensionAPI();
}


function buildPlatformExtensionAPI(extensionInfo)
{
function platformExtensionAPI(coreAPI)
{
window.webInspector = coreAPI;
}
return platformExtensionAPI.toString();
}


function buildExtensionAPIInjectedScript(extensionInfo)
{
return "(function(injectedScriptHost, inspectedWindow, injectedScriptId){ " +
defineCommonExtensionSymbols.toString() + ";" +
injectedExtensionAPI.toString() + ";" +
buildPlatformExtensionAPI(extensionInfo) + ";" +
"platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" +
"return {};" +
"})";
}






WebInspector.ExtensionAuditCategory = function(extensionOrigin, id, displayName, ruleCount)
{
this._extensionOrigin = extensionOrigin;
this._id = id;
this._displayName = displayName;
this._ruleCount  = ruleCount;
}

WebInspector.ExtensionAuditCategory.prototype = {

get id()
{
return this._id;
},

get displayName()
{
return this._displayName;
},


run: function(requests, ruleResultCallback, categoryDoneCallback, progress)
{
var results = new WebInspector.ExtensionAuditCategoryResults(this, ruleResultCallback, categoryDoneCallback, progress);
WebInspector.extensionServer.startAuditRun(this, results);
}
}


WebInspector.ExtensionAuditCategoryResults = function(category, ruleResultCallback, categoryDoneCallback, progress)
{
this._category = category;
this._ruleResultCallback = ruleResultCallback;
this._categoryDoneCallback = categoryDoneCallback;
this._progress = progress;
this._progress.setTotalWork(1);
this._expectedResults = category._ruleCount;
this._actualResults = 0;

this.id = category.id + "-" + ++WebInspector.ExtensionAuditCategoryResults._lastId;
}

WebInspector.ExtensionAuditCategoryResults.prototype = {
done: function()
{
WebInspector.extensionServer.stopAuditRun(this);
this._progress.done();
this._categoryDoneCallback();
},

addResult: function(displayName, description, severity, details)
{
var result = new WebInspector.AuditRuleResult(displayName);
result.addChild(description);
result.severity = severity;
if (details)
this._addNode(result, details);
this._addResult(result);
},

_addNode: function(parent, node)
{
var contents = WebInspector.auditFormatters.partiallyApply(WebInspector.ExtensionAuditFormatters, this, node.contents);
var addedNode = parent.addChild(contents, node.expanded);
if (node.children) {
for (var i = 0; i < node.children.length; ++i)
this._addNode(addedNode, node.children[i]);
}
},

_addResult: function(result)
{
this._ruleResultCallback(result);
++this._actualResults;
if (typeof this._expectedResults === "number") {
this._progress.setWorked(this._actualResults / this._expectedResults);
if (this._actualResults === this._expectedResults)
this.done();
}
},


updateProgress: function(progress)
{
this._progress.setWorked(progress);
},


evaluate: function(expression, evaluateOptions, callback)
{

function onEvaluate(error, result, wasThrown)
{
if (wasThrown)
return;
var object = WebInspector.RemoteObject.fromPayload(result);
callback(object);
}
WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate);
}
}

WebInspector.ExtensionAuditFormatters = {

object: function(expression, title, evaluateOptions)
{
var parentElement = document.createElement("div");
function onEvaluate(remoteObject)
{
var section = new WebInspector.ObjectPropertiesSection(remoteObject, title);
section.expanded = true;
section.editable = false;
parentElement.appendChild(section.element);
}
this.evaluate(expression, evaluateOptions, onEvaluate);
return parentElement;
},


node: function(expression, evaluateOptions)
{
var parentElement = document.createElement("div");

function onNodeAvailable(nodeId)
{
if (!nodeId)
return;
var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
treeOutline.element.addStyleClass("outline-disclosure");
treeOutline.setVisible(true);
parentElement.appendChild(treeOutline.element);
}

function onEvaluate(remoteObject)
{
remoteObject.pushNodeToFrontend(onNodeAvailable);
}
this.evaluate(expression, evaluateOptions, onEvaluate);
return parentElement;
}
}

WebInspector.ExtensionAuditCategoryResults._lastId = 0;






WebInspector.ExtensionServer = function()
{
this._clientObjects = {};
this._handlers = {};
this._subscribers = {};
this._subscriptionStartHandlers = {};
this._subscriptionStopHandlers = {};
this._extraHeaders = {};
this._requests = {};
this._lastRequestId = 0;
this._registeredExtensions = {};
this._status = new WebInspector.ExtensionStatus();

var commands = WebInspector.extensionAPI.Commands;

this._registerHandler(commands.AddAuditCategory, this._onAddAuditCategory.bind(this));
this._registerHandler(commands.AddAuditResult, this._onAddAuditResult.bind(this));
this._registerHandler(commands.AddConsoleMessage, this._onAddConsoleMessage.bind(this));
this._registerHandler(commands.AddRequestHeaders, this._onAddRequestHeaders.bind(this));
this._registerHandler(commands.CreatePanel, this._onCreatePanel.bind(this));
this._registerHandler(commands.CreateSidebarPane, this._onCreateSidebarPane.bind(this));
this._registerHandler(commands.CreateStatusBarButton, this._onCreateStatusBarButton.bind(this));
this._registerHandler(commands.EvaluateOnInspectedPage, this._onEvaluateOnInspectedPage.bind(this));
this._registerHandler(commands.GetHAR, this._onGetHAR.bind(this));
this._registerHandler(commands.GetConsoleMessages, this._onGetConsoleMessages.bind(this));
this._registerHandler(commands.GetPageResources, this._onGetPageResources.bind(this));
this._registerHandler(commands.GetRequestContent, this._onGetRequestContent.bind(this));
this._registerHandler(commands.GetResourceContent, this._onGetResourceContent.bind(this));
this._registerHandler(commands.Log, this._onLog.bind(this));
this._registerHandler(commands.Reload, this._onReload.bind(this));
this._registerHandler(commands.SetOpenResourceHandler, this._onSetOpenResourceHandler.bind(this));
this._registerHandler(commands.SetResourceContent, this._onSetResourceContent.bind(this));
this._registerHandler(commands.SetSidebarHeight, this._onSetSidebarHeight.bind(this));
this._registerHandler(commands.SetSidebarContent, this._onSetSidebarContent.bind(this));
this._registerHandler(commands.SetSidebarPage, this._onSetSidebarPage.bind(this));
this._registerHandler(commands.ShowPanel, this._onShowPanel.bind(this));
this._registerHandler(commands.StopAuditCategoryRun, this._onStopAuditCategoryRun.bind(this));
this._registerHandler(commands.Subscribe, this._onSubscribe.bind(this));
this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
this._registerHandler(commands.UpdateAuditProgress, this._onUpdateAuditProgress.bind(this));

window.addEventListener("message", this._onWindowMessage.bind(this), false);
}

WebInspector.ExtensionServer.prototype = {
hasExtensions: function()
{
return !!Object.keys(this._registeredExtensions).length;
},

notifySearchAction: function(panelId, action, searchString)
{
this._postNotification(WebInspector.extensionAPI.Events.PanelSearch + panelId, action, searchString);
},

notifyViewShown: function(identifier, frameIndex)
{
this._postNotification(WebInspector.extensionAPI.Events.ViewShown + identifier, frameIndex);
},

notifyViewHidden: function(identifier)
{
this._postNotification(WebInspector.extensionAPI.Events.ViewHidden + identifier);
},

notifyButtonClicked: function(identifier)
{
this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked + identifier);
},

_inspectedURLChanged: function(event)
{
this._requests = {};
var url = event.data;
this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged, url);
},

_mainFrameNavigated: function(event)
{
this._postNotification(WebInspector.extensionAPI.Events.Reset);
},

startAuditRun: function(category, auditRun)
{
this._clientObjects[auditRun.id] = auditRun;
this._postNotification("audit-started-" + category.id, auditRun.id);
},

stopAuditRun: function(auditRun)
{
delete this._clientObjects[auditRun.id];
},


_postNotification: function(type, vararg)
{
var subscribers = this._subscribers[type];
if (!subscribers)
return;
var message = {
command: "notify-" + type,
arguments: Array.prototype.slice.call(arguments, 1)
};
for (var i = 0; i < subscribers.length; ++i)
subscribers[i].postMessage(message);
},

_onSubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (subscribers)
subscribers.push(port);
else {
this._subscribers[message.type] = [ port ];
if (this._subscriptionStartHandlers[message.type])
this._subscriptionStartHandlers[message.type]();
}
},

_onUnsubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (!subscribers)
return;
subscribers.remove(port);
if (!subscribers.length) {
delete this._subscribers[message.type];
if (this._subscriptionStopHandlers[message.type])
this._subscriptionStopHandlers[message.type]();
}
},

_onAddRequestHeaders: function(message)
{
var id = message.extensionId;
if (typeof id !== "string")
return this._status.E_BADARGTYPE("extensionId", typeof id, "string");
var extensionHeaders = this._extraHeaders[id];
if (!extensionHeaders) {
extensionHeaders = {};
this._extraHeaders[id] = extensionHeaders;
}
for (var name in message.headers)
extensionHeaders[name] = message.headers[name];
var allHeaders =   {};
for (var extension in this._extraHeaders) {
var headers = this._extraHeaders[extension];
for (name in headers) {
if (typeof headers[name] === "string")
allHeaders[name] = headers[name];
}
}
NetworkAgent.setExtraHTTPHeaders(allHeaders);
},

_onCreatePanel: function(message, port)
{
var id = message.id;


if (id in this._clientObjects || id in WebInspector.panels)
return this._status.E_EXISTS(id);

var page = this._expandResourcePath(port._extensionOrigin, message.page);
var panelDescriptor = new WebInspector.PanelDescriptor(id, message.title, undefined, undefined, new WebInspector.ExtensionPanel(id, page));
panelDescriptor.setIconURL(this._expandResourcePath(port._extensionOrigin, message.icon));
this._clientObjects[id] = panelDescriptor.panel();
WebInspector.inspectorView.addPanel(panelDescriptor);
return this._status.OK();
},

_onShowPanel: function(message)
{

WebInspector.showPanel(message.id);
},

_onCreateStatusBarButton: function(message, port)
{
var panel = this._clientObjects[message.panel];
if (!panel || !(panel instanceof WebInspector.ExtensionPanel))
return this._status.E_NOTFOUND(message.panel);
var button = new WebInspector.ExtensionButton(message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
this._clientObjects[message.id] = button;
panel.addStatusBarItem(button.element);
return this._status.OK();
},

_onUpdateButton: function(message, port)
{
var button = this._clientObjects[message.id];
if (!button || !(button instanceof WebInspector.ExtensionButton))
return this._status.E_NOTFOUND(message.id);
button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
return this._status.OK();
},

_onCreateSidebarPane: function(message)
{
var panel = WebInspector.panel(message.panel);
if (!panel)
return this._status.E_NOTFOUND(message.panel);
if (!panel.sidebarElement || !panel.sidebarPanes)
return this._status.E_NOTSUPPORTED();
var id = message.id;
var sidebar = new WebInspector.ExtensionSidebarPane(message.title, message.id);
this._clientObjects[id] = sidebar;
panel.sidebarPanes[id] = sidebar;
panel.sidebarElement.appendChild(sidebar.element);

return this._status.OK();
},

_onSetSidebarHeight: function(message)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.setHeight(message.height);
return this._status.OK();
},

_onSetSidebarContent: function(message, port)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
function callback(error)
{
var result = error ? this._status.E_FAILED(error) : this._status.OK();
this._dispatchCallback(message.requestId, port, result);
}
if (message.evaluateOnPage)
return sidebar.setExpression(message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
},

_onSetSidebarPage: function(message, port)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
},

_onSetOpenResourceHandler: function(message, port)
{
var name = this._registeredExtensions[port._extensionOrigin].name || ("Extension " + port._extensionOrigin);
if (message.handlerPresent)
WebInspector.openAnchorLocationRegistry.registerHandler(name, this._handleOpenURL.bind(this, port));
else
WebInspector.openAnchorLocationRegistry.unregisterHandler(name);
},

_handleOpenURL: function(port, details)
{
var url =   details.url;
var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
if (!contentProvider)
return false;

var lineNumber = details.lineNumber;
if (typeof lineNumber === "number")
lineNumber += 1;
port.postMessage({
command: "open-resource",
resource: this._makeResource(contentProvider),
lineNumber: lineNumber
});
return true;
},

_onLog: function(message)
{
WebInspector.log(message.message);
},

_onReload: function(message)
{
var options =   (message.options || {});
NetworkAgent.setUserAgentOverride(typeof options.userAgent === "string" ? options.userAgent : "");
var injectedScript;
if (options.injectedScript) {


injectedScript = "((function(){" + options.injectedScript + "})(),function(){return {}})";
}
PageAgent.reload(!!options.ignoreCache, injectedScript);
return this._status.OK();
},

_onEvaluateOnInspectedPage: function(message, port)
{

function callback(error, resultPayload, wasThrown)
{
var result = {};
if (error) {
result.isException = true;
result.value = error.toString();
}  else
result.value = resultPayload.value;

if (wasThrown)
result.isException = true;

this._dispatchCallback(message.requestId, port, result);
}
return this.evaluate(message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
},

_onGetConsoleMessages: function()
{
return WebInspector.console.messages.map(this._makeConsoleMessage);
},

_onAddConsoleMessage: function(message)
{
function convertSeverity(level)
{
switch (level) {
case WebInspector.extensionAPI.console.Severity.Tip:
return WebInspector.ConsoleMessage.MessageLevel.Tip;
case WebInspector.extensionAPI.console.Severity.Log:
return WebInspector.ConsoleMessage.MessageLevel.Log;
case WebInspector.extensionAPI.console.Severity.Warning:
return WebInspector.ConsoleMessage.MessageLevel.Warning;
case WebInspector.extensionAPI.console.Severity.Error:
return WebInspector.ConsoleMessage.MessageLevel.Error;
case WebInspector.extensionAPI.console.Severity.Debug:
return WebInspector.ConsoleMessage.MessageLevel.Debug;
}
}
var level = convertSeverity(message.severity);
if (!level)
return this._status.E_BADARG("message.severity", message.severity);

var consoleMessage = WebInspector.ConsoleMessage.create(
WebInspector.ConsoleMessage.MessageSource.JS,
level,
message.text,
WebInspector.ConsoleMessage.MessageType.Log,
message.url,
message.line);
WebInspector.console.addMessage(consoleMessage);
},

_makeConsoleMessage: function(message)
{
function convertLevel(level)
{
if (!level)
return;
switch (level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
return WebInspector.extensionAPI.console.Severity.Tip;
case WebInspector.ConsoleMessage.MessageLevel.Log:
return WebInspector.extensionAPI.console.Severity.Log;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
return WebInspector.extensionAPI.console.Severity.Warning;
case WebInspector.ConsoleMessage.MessageLevel.Error:
return WebInspector.extensionAPI.console.Severity.Error;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
return WebInspector.extensionAPI.console.Severity.Debug;
default:
return WebInspector.extensionAPI.console.Severity.Log;
}
}
var result = {
severity: convertLevel(message.level),
text: message.text,
};
if (message.url)
result.url = message.url;
if (message.line)
result.line = message.line;
return result;
},

_onGetHAR: function()
{
var requests = WebInspector.networkLog.requests;
var harLog = (new WebInspector.HARLog(requests)).build();
for (var i = 0; i < harLog.entries.length; ++i)
harLog.entries[i]._requestId = this._requestId(requests[i]);
return harLog;
},


_makeResource: function(contentProvider)
{
return {
url: contentProvider.contentURL(),
type: contentProvider.contentType().name()
};
},

_onGetPageResources: function()
{
var resources = {};

function pushResourceData(contentProvider)
{
if (!resources[contentProvider.contentURL()])
resources[contentProvider.contentURL()] = this._makeResource(contentProvider);
}
WebInspector.workspace.uiSourceCodes().forEach(pushResourceData.bind(this));
WebInspector.resourceTreeModel.forAllResources(pushResourceData.bind(this));
return Object.values(resources);
},


_getResourceContent: function(contentProvider, message, port)
{

function onContentAvailable(content, contentEncoded, mimeType)
{
var response = {
encoding: contentEncoded ? "base64" : "",
content: content
};
this._dispatchCallback(message.requestId, port, response);
}
contentProvider.requestContent(onContentAvailable.bind(this));
},

_onGetRequestContent: function(message, port)
{
var request = this._requestById(message.id);
if (!request)
return this._status.E_NOTFOUND(message.id);
this._getResourceContent(request, message, port);
},

_onGetResourceContent: function(message, port)
{
var url =   message.url;
var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
if (!contentProvider)
return this._status.E_NOTFOUND(url);
this._getResourceContent(contentProvider, message, port);
},

_onSetResourceContent: function(message, port)
{

function callbackWrapper(error)
{
var response = error ? this._status.E_FAILED(error) : this._status.OK();
this._dispatchCallback(message.requestId, port, response);
}

var url =   message.url;
var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
if (!uiSourceCode) {
var resource = WebInspector.resourceTreeModel.resourceForURL(url);
if (!resource)
return this._status.E_NOTFOUND(url);
return this._status.E_NOTSUPPORTED("Resource is not editable")
}
uiSourceCode.setWorkingCopy(message.content);
if (message.commit)
uiSourceCode.commitWorkingCopy(callbackWrapper.bind(this));
else
callbackWrapper.call(this, null);
},

_requestId: function(request)
{
if (!request._extensionRequestId) {
request._extensionRequestId = ++this._lastRequestId;
this._requests[request._extensionRequestId] = request;
}
return request._extensionRequestId;
},

_requestById: function(id)
{
return this._requests[id];
},

_onAddAuditCategory: function(message, port)
{
var category = new WebInspector.ExtensionAuditCategory(port._extensionOrigin, message.id, message.displayName, message.resultCount);
if (WebInspector.panel("audits").getCategory(category.id))
return this._status.E_EXISTS(category.id);
this._clientObjects[message.id] = category;
WebInspector.panel("audits").addCategory(category);
},

_onAddAuditResult: function(message)
{
var auditResult = this._clientObjects[message.resultId];
if (!auditResult)
return this._status.E_NOTFOUND(message.resultId);
try {
auditResult.addResult(message.displayName, message.description, message.severity, message.details);
} catch (e) {
return e;
}
return this._status.OK();
},

_onUpdateAuditProgress: function(message)
{
var auditResult = this._clientObjects[message.resultId];
if (!auditResult)
return this._status.E_NOTFOUND(message.resultId);
auditResult.updateProgress(Math.min(Math.max(0, message.progress), 1));
},

_onStopAuditCategoryRun: function(message)
{
var auditRun = this._clientObjects[message.resultId];
if (!auditRun)
return this._status.E_NOTFOUND(message.resultId);
auditRun.done();
},

_dispatchCallback: function(requestId, port, result)
{
if (requestId)
port.postMessage({ command: "callback", requestId: requestId, result: result });
},

initExtensions: function()
{
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ConsoleMessageAdded,
WebInspector.console, WebInspector.ConsoleModel.Events.MessageAdded, this._notifyConsoleMessageAdded);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.NetworkRequestFinished,
WebInspector.networkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._notifyRequestFinished);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceAdded,
WebInspector.workspace,
WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded,
this._notifyResourceAdded);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected,
WebInspector.notifications,
WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged,
this._notifyElementsSelectionChanged);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,
WebInspector.workspace,
WebInspector.Workspace.Events.UISourceCodeContentCommitted,
this._notifyUISourceCodeContentCommitted);

function onTimelineSubscriptionStarted()
{
WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
this._notifyTimelineEventRecorded, this);
WebInspector.timelineManager.start();
}
function onTimelineSubscriptionStopped()
{
WebInspector.timelineManager.stop();
WebInspector.timelineManager.removeEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
this._notifyTimelineEventRecorded, this);
}
this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.TimelineEventRecorded,
onTimelineSubscriptionStarted.bind(this), onTimelineSubscriptionStopped.bind(this));

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged,
this._inspectedURLChanged, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
this._initDone = true;
if (this._pendingExtensions) {
this._pendingExtensions.forEach(this._innerAddExtension, this);
delete this._pendingExtensions;
}
InspectorExtensionRegistry.getExtensionsAsync();
},

_notifyConsoleMessageAdded: function(event)
{
this._postNotification(WebInspector.extensionAPI.Events.ConsoleMessageAdded, this._makeConsoleMessage(event.data));
},

_notifyResourceAdded: function(event)
{
var uiSourceCode =   event.data;
this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
},

_notifyUISourceCodeContentCommitted: function(event)
{
var uiSourceCode =   event.data.uiSourceCode;
var content =   event.data.content;
this._postNotification(WebInspector.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
},

_notifyRequestFinished: function(event)
{
var request =   event.data;
this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), (new WebInspector.HAREntry(request)).build());
},

_notifyElementsSelectionChanged: function()
{
this._postNotification(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected);
},

_notifyTimelineEventRecorded: function(event)
{
this._postNotification(WebInspector.extensionAPI.Events.TimelineEventRecorded, event.data);
},


_addExtensions: function(extensions)
{
extensions.forEach(this._addExtension, this);
},

_addExtension: function(extensionInfo)
{
if (this._initDone) {
this._innerAddExtension(extensionInfo);
return;
}
if (this._pendingExtensions)
this._pendingExtensions.push(extensionInfo);
else
this._pendingExtensions = [extensionInfo];
},

_innerAddExtension: function(extensionInfo)
{
const urlOriginRegExp = new RegExp("([^:]+:\/\/[^/]*)\/"); 
var startPage = extensionInfo.startPage;
var name = extensionInfo.name;

try {
var originMatch = urlOriginRegExp.exec(startPage);
if (!originMatch) {
console.error("Skipping extension with invalid URL: " + startPage);
return false;
}
var extensionOrigin = originMatch[1];
if (!this._registeredExtensions[extensionOrigin]) {

InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, buildExtensionAPIInjectedScript(extensionInfo));
this._registeredExtensions[extensionOrigin] = { name: name };
}
var iframe = document.createElement("iframe");
iframe.src = startPage;
iframe.style.display = "none";
document.body.appendChild(iframe);
} catch (e) {
console.error("Failed to initialize extension " + startPage + ":" + e);
return false;
}
return true;
},

_onWindowMessage: function(event)
{
if (event.data === "registerExtension")
this._registerExtension(event.origin, event.ports[0]);
},

_registerExtension: function(origin, port)
{
if (!this._registeredExtensions.hasOwnProperty(origin)) {
if (origin !== window.location.origin) 
console.error("Ignoring unauthorized client request from " + origin);
return;
}
port._extensionOrigin = origin;
port.addEventListener("message", this._onmessage.bind(this), false);
port.start();
},

_onmessage: function(event)
{
var message = event.data;
var result;

if (message.command in this._handlers)
result = this._handlers[message.command](message, event.target);
else
result = this._status.E_NOTSUPPORTED(message.command);

if (result && message.requestId)
this._dispatchCallback(message.requestId, event.target, result);
},

_registerHandler: function(command, callback)
{
this._handlers[command] = callback;
},

_registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast)
{
this._subscriptionStartHandlers[eventTopic] =  onSubscribeFirst;
this._subscriptionStopHandlers[eventTopic] =  onUnsubscribeLast;
},

_registerAutosubscriptionHandler: function(eventTopic, eventTarget, frontendEventType, handler)
{
this._registerSubscriptionHandler(eventTopic,
eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
},

_expandResourcePath: function(extensionPath, resourcePath)
{
if (!resourcePath)
return;
return extensionPath + this._normalizePath(resourcePath);
},

_normalizePath: function(path)
{
var source = path.split("/");
var result = [];

for (var i = 0; i < source.length; ++i) {
if (source[i] === ".")
continue;

if (source[i] === "")
continue;
if (source[i] === "..")
result.pop();
else
result.push(source[i]);
}
return "/" + result.join("/");
},


evaluate: function(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback) 
{
var contextId;
if (typeof options === "object" && options["useContentScriptContext"]) {
var mainFrame = WebInspector.resourceTreeModel.mainFrame;
if (!mainFrame)
return this._status.E_FAILED("main frame not available yet");
var context = WebInspector.runtimeModel.contextByFrameAndSecurityOrigin(mainFrame, securityOrigin);
if (!context)
return this._status.E_NOTFOUND(securityOrigin);
contextId = context.id;
}
RuntimeAgent.evaluate(expression, "extension", exposeCommandLineAPI, true, contextId, returnByValue, callback);
}
}


WebInspector.ExtensionStatus = function()
{
function makeStatus(code, description)
{
var details = Array.prototype.slice.call(arguments, 2);
var status = { code: code, description: description, details: details };
if (code !== "OK") {
status.isError = true;
console.log("Extension server error: " + String.vsprintf(description, details));
}
return status;
}

this.OK = makeStatus.bind(null, "OK", "OK");
this.E_EXISTS = makeStatus.bind(null, "E_EXISTS", "Object already exists: %s");
this.E_BADARG = makeStatus.bind(null, "E_BADARG", "Invalid argument %s: %s");
this.E_BADARGTYPE = makeStatus.bind(null, "E_BADARGTYPE", "Invalid type for argument %s: got %s, expected %s");
this.E_NOTFOUND = makeStatus.bind(null, "E_NOTFOUND", "Object not found: %s");
this.E_NOTSUPPORTED = makeStatus.bind(null, "E_NOTSUPPORTED", "Object does not support requested operation: %s");
this.E_FAILED = makeStatus.bind(null, "E_FAILED", "Operation failed: %s");
}

WebInspector.addExtensions = function(extensions)
{
WebInspector.extensionServer._addExtensions(extensions);
}

WebInspector.extensionAPI = {};
defineCommonExtensionSymbols(WebInspector.extensionAPI);

WebInspector.extensionServer = new WebInspector.ExtensionServer();

window.addExtension = function(page, name)
{
WebInspector.extensionServer._addExtension({
startPage: page,
name: name,
});
}






WebInspector.ExtensionView = function(id, src, className)
{
WebInspector.View.call(this);
this.element.className = "fill";

this._id = id;
this._iframe = document.createElement("iframe");
this._iframe.addEventListener("load", this._onLoad.bind(this), false);
this._iframe.src = src;
this._iframe.className = className;
this.setDefaultFocusedElement(this._iframe);

this.element.appendChild(this._iframe);
}

WebInspector.ExtensionView.prototype = {
wasShown: function()
{
if (typeof this._frameIndex === "number")
WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex);
},

willHide: function()
{
if (typeof this._frameIndex === "number")
WebInspector.extensionServer.notifyViewHidden(this._id);
},

_onLoad: function()
{
this._frameIndex = Array.prototype.indexOf.call(window.frames, this._iframe.contentWindow);
if (this.isShowing())
WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex);
}
}

WebInspector.ExtensionView.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.ExtensionNotifierView = function(id)
{
WebInspector.View.call(this);

this._id = id;
}

WebInspector.ExtensionNotifierView.prototype = {
wasShown: function()
{
WebInspector.extensionServer.notifyViewShown(this._id);
},

willHide: function()
{
WebInspector.extensionServer.notifyViewHidden(this._id);
}
}

WebInspector.ExtensionNotifierView.prototype.__proto__ = WebInspector.View.prototype;






WebInspector.ExtensionPanel = function(id, pageURL)
{
WebInspector.Panel.call(this, id);
this.setHideOnDetach();
this._statusBarItems = [];
var extensionView = new WebInspector.ExtensionView(id, pageURL, "extension panel");
extensionView.show(this.element);
this.setDefaultFocusedElement(extensionView.defaultFocusedElement());
}

WebInspector.ExtensionPanel.prototype = {
defaultFocusedElement: function()
{
return WebInspector.View.prototype.defaultFocusedElement.call(this);
},

get statusBarItems()
{
return this._statusBarItems;
},


addStatusBarItem: function(element)
{
this._statusBarItems.push(element);
},

searchCanceled: function(startingNewSearch)
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.CancelSearch);
WebInspector.Panel.prototype.searchCanceled.apply(this, arguments);
},


performSearch: function(query)
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PerformSearch, query);
WebInspector.Panel.prototype.performSearch.apply(this, arguments);
},

jumpToNextSearchResult: function()
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.NextSearchResult);
WebInspector.Panel.prototype.jumpToNextSearchResult.call(this);
},

jumpToPreviousSearchResult: function()
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PreviousSearchResult);
WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this);
}
}

WebInspector.ExtensionPanel.prototype.__proto__ = WebInspector.Panel.prototype;


WebInspector.ExtensionButton = function(id, iconURL, tooltip, disabled)
{
this._id = id;
this.element = document.createElement("button");
this.element.className = "status-bar-item extension";
this.element.addEventListener("click", this._onClicked.bind(this), false);
this.update(iconURL, tooltip, disabled);
}

WebInspector.ExtensionButton.prototype = {

update: function(iconURL, tooltip, disabled)
{
if (typeof iconURL === "string")
this.element.style.backgroundImage = "url(" + iconURL + ")";
if (typeof tooltip === "string")
this.element.title = tooltip;
if (typeof disabled === "boolean")
this.element.disabled = disabled;
},

_onClicked: function()
{
WebInspector.extensionServer.notifyButtonClicked(this._id);
}
}


WebInspector.ExtensionSidebarPane = function(title, id)
{
WebInspector.SidebarPane.call(this, title);
this._id = id;
}

WebInspector.ExtensionSidebarPane.prototype = {

setObject: function(object, title, callback)
{
this._createObjectPropertiesView();
this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title, callback);
},


setExpression: function(expression, title, evaluateOptions, securityOrigin, callback)
{
this._createObjectPropertiesView();
return WebInspector.extensionServer.evaluate(expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback));
},


setPage: function(url)
{
if (this._objectPropertiesView) {
this._objectPropertiesView.detach();
delete this._objectPropertiesView;
}
if (this._extensionView)
this._extensionView.detach(true);

this._extensionView = new WebInspector.ExtensionView(this._id, url, "extension fill");
this._extensionView.show(this.bodyElement);

if (!this.bodyElement.style.height)
this.setHeight("150px");
},


setHeight: function(height)
{
this.bodyElement.style.height = height;
},


_onEvaluate: function(title, callback, error, result, wasThrown)
{
if (error)
callback(error.toString());
else
this._setObject(WebInspector.RemoteObject.fromPayload(result), title, callback);
},

_createObjectPropertiesView: function()
{
if (this._objectPropertiesView)
return;
if (this._extensionView) {
this._extensionView.detach(true);
delete this._extensionView;
}
this._objectPropertiesView = new WebInspector.ExtensionNotifierView(this._id);
this._objectPropertiesView.show(this.bodyElement);
},


_setObject: function(object, title, callback)
{

if (!this._objectPropertiesView) {
callback("operation cancelled");
return;
}
this._objectPropertiesView.element.removeChildren();
var section = new WebInspector.ObjectPropertiesSection(object, title);
if (!title)
section.headerElement.addStyleClass("hidden");
section.expanded = true;
section.editable = false;
this._objectPropertiesView.element.appendChild(section.element);
callback();
}
}

WebInspector.ExtensionSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;






WebInspector.EmptyView = function(text)
{
WebInspector.View.call(this);
this._text = text;
}

WebInspector.EmptyView.prototype = {
wasShown: function()
{
this.element.className = "storage-empty-view";
this.element.textContent = this._text;
},

set text(text)
{
this._text = text;
if (this.isShowing())
this.element.textContent = this._text;
},
}

WebInspector.EmptyView.prototype.__proto__ = WebInspector.View.prototype;






WebInspector.Formatter = function()
{
}


WebInspector.Formatter.createFormatter = function(contentType)
{
if (contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document)
return new WebInspector.ScriptFormatter();
return new WebInspector.IdentityFormatter();
}


WebInspector.Formatter.locationToPosition = function(lineEndings, lineNumber, columnNumber)
{
var position = lineNumber ? lineEndings[lineNumber - 1] + 1 : 0;
return position + columnNumber;
}


WebInspector.Formatter.positionToLocation = function(lineEndings, position)
{
var lineNumber = lineEndings.upperBound(position - 1);
if (!lineNumber)
var columnNumber = position;
else
var columnNumber = position - lineEndings[lineNumber - 1] - 1;
return [lineNumber, columnNumber];
}

WebInspector.Formatter.prototype = {

formatContent: function(mimeType, content, callback)
{
}
}


WebInspector.ScriptFormatter = function()
{
this._tasks = [];
}

WebInspector.ScriptFormatter.prototype = {

formatContent: function(mimeType, content, callback)
{
content = content.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '');
const method = "format";
var parameters = { mimeType: mimeType, content: content, indentString: WebInspector.settings.textEditorIndent.get() };
this._tasks.push({ data: parameters, callback: callback });
this._worker.postMessage({ method: method, params: parameters });
},

_didFormatContent: function(event)
{
var task = this._tasks.shift();
var originalContent = task.data.content;
var formattedContent = event.data.content;
var mapping = event.data["mapping"];
var sourceMapping = new WebInspector.FormatterSourceMappingImpl(originalContent.lineEndings(), formattedContent.lineEndings(), mapping);
task.callback(formattedContent, sourceMapping);
},


get _worker()
{
if (!this._cachedWorker) {
this._cachedWorker = new Worker("ScriptFormatterWorker.js");
this._cachedWorker.onmessage =   this._didFormatContent.bind(this);
}
return this._cachedWorker;
}
}


WebInspector.IdentityFormatter = function()
{
this._tasks = [];
}

WebInspector.IdentityFormatter.prototype = {

formatContent: function(mimeType, content, callback)
{
callback(content, new WebInspector.IdentityFormatterSourceMapping());
}
}


WebInspector.FormatterMappingPayload = function()
{
this.original = [];
this.formatted = [];
}


WebInspector.FormatterSourceMapping = function()
{
}

WebInspector.FormatterSourceMapping.prototype = {

originalToFormatted: function(lineNumber, columnNumber) { },


formattedToOriginal: function(lineNumber, columnNumber) { }
}


WebInspector.IdentityFormatterSourceMapping = function()
{
}

WebInspector.IdentityFormatterSourceMapping.prototype = {

originalToFormatted: function(lineNumber, columnNumber)
{
return [lineNumber, columnNumber || 0]; 
},


formattedToOriginal: function(lineNumber, columnNumber)
{
return [lineNumber, columnNumber || 0];
}
}


WebInspector.FormatterSourceMappingImpl = function(originalLineEndings, formattedLineEndings, mapping)
{
this._originalLineEndings = originalLineEndings;
this._formattedLineEndings = formattedLineEndings;
this._mapping = mapping;
}

WebInspector.FormatterSourceMappingImpl.prototype = {

originalToFormatted: function(lineNumber, columnNumber)
{
var originalPosition = WebInspector.Formatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber || 0);
var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition || 0);
return WebInspector.Formatter.positionToLocation(this._formattedLineEndings, formattedPosition);
},


formattedToOriginal: function(lineNumber, columnNumber)
{
var formattedPosition = WebInspector.Formatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber || 0);
var originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
return WebInspector.Formatter.positionToLocation(this._originalLineEndings, originalPosition || 0);
},


_convertPosition: function(positions1, positions2, position)
{
var index = positions1.upperBound(position) - 1;
var convertedPosition = positions2[index] + position - positions1[index];
if (index < positions2.length - 1 && convertedPosition > positions2[index + 1])
convertedPosition = positions2[index + 1];
return convertedPosition;
}
}






WebInspector.DOMSyntaxHighlighter = function(mimeType, stripExtraWhitespace)
{
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
this._stripExtraWhitespace = stripExtraWhitespace;
}

WebInspector.DOMSyntaxHighlighter.prototype = {
createSpan: function(content, className)
{
var span = document.createElement("span");
span.className = "webkit-" + className;
if (this._stripExtraWhitespace)
content = content.replace(/^[\n\r]*/, "").replace(/\s*$/, "");
span.appendChild(document.createTextNode(content));
return span;
},

syntaxHighlightNode: function(node)
{
this._tokenizer.condition = this._tokenizer.createInitialCondition();
var lines = node.textContent.split("\n");
node.removeChildren();

for (var i = lines[0].length ? 0 : 1; i < lines.length; ++i) {
var line = lines[i];
var plainTextStart = 0;
this._tokenizer.line = line;
var column = 0;
do {
var newColumn = this._tokenizer.nextToken(column);
var tokenType = this._tokenizer.tokenType;
if (tokenType) {
if (column > plainTextStart) {
var plainText = line.substring(plainTextStart, column);
node.appendChild(document.createTextNode(plainText));
}
var token = line.substring(column, newColumn);
node.appendChild(this.createSpan(token, tokenType));
plainTextStart = newColumn;
}
column = newColumn;
} while (column < line.length)

if (plainTextStart < line.length) {
var plainText = line.substring(plainTextStart, line.length);
node.appendChild(document.createTextNode(plainText));
}
if (i < lines.length - 1)
node.appendChild(document.createElement("br"));
}
}
}






WebInspector.TextRange = function(startLine, startColumn, endLine, endColumn)
{
this.startLine = startLine;
this.startColumn = startColumn;
this.endLine = endLine;
this.endColumn = endColumn;
}

WebInspector.TextRange.createFromLocation = function(line, column)
{
return new WebInspector.TextRange(line, column, line, column);
}


WebInspector.TextRange.fromObject = function (serializedTextRange)
{
return new WebInspector.TextRange(serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine, serializedTextRange.endColumn);
}

WebInspector.TextRange.prototype = {

isEmpty: function()
{
return this.startLine === this.endLine && this.startColumn === this.endColumn;
},


get linesCount()
{
return this.endLine - this.startLine;
},

collapseToEnd: function()
{
return new WebInspector.TextRange(this.endLine, this.endColumn, this.endLine, this.endColumn);
},


normalize: function()
{
if (this.startLine > this.endLine || (this.startLine === this.endLine && this.startColumn > this.endColumn))
return new WebInspector.TextRange(this.endLine, this.endColumn, this.startLine, this.startColumn);
else
return this;
},


clone: function()
{
return new WebInspector.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn);
},


serializeToObject: function()
{
var serializedTextRange = {};
serializedTextRange.startLine = this.startLine;
serializedTextRange.startColumn = this.startColumn;
serializedTextRange.endLine = this.endLine;
serializedTextRange.endColumn = this.endColumn;
return serializedTextRange;
},


compareTo: function(other)
{
if (this.startLine > other.startLine)
return 1;
if (this.startLine < other.startLine)
return -1;
if (this.startColumn > other.startColumn)
return 1;
if (this.startColumn < other.startColumn)
return -1;
return 0;
}
}


WebInspector.TextEditorCommand = function(newRange, originalText)
{
this.newRange = newRange;
this.originalText = originalText;
}


WebInspector.TextEditorModel = function()
{
this._lines = [""];
this._attributes = [];

this._undoStack = [];
this._noPunctuationRegex = /[^ !%&()*+,-.:;<=>?\[\]\^{|}~]+/;
this._lineBreak = "\n";
}

WebInspector.TextEditorModel.Indent = {
TwoSpaces: "  ",
FourSpaces: "    ",
EightSpaces: "        ",
TabCharacter: "\t"
}

WebInspector.TextEditorModel.Events = {
TextChanged: "TextChanged"
}

WebInspector.TextEditorModel.endsWithBracketRegex = /[{(\[]\s*$/;

WebInspector.TextEditorModel.prototype = {

get linesCount()
{
return this._lines.length;
},


text: function()
{
return this._lines.join(this._lineBreak);
},


range: function()
{
return new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length);
},


get lineBreak()
{
return this._lineBreak;
},


line: function(lineNumber)
{
if (lineNumber >= this._lines.length)
throw "Out of bounds:" + lineNumber;
return this._lines[lineNumber];
},


lineLength: function(lineNumber)
{
return this._lines[lineNumber].length;
},


setText: function(text)
{
text = text || "";
var range = this.range();
this._lineBreak = /\r\n/.test(text) ? "\r\n" : "\n";
var newRange = this._innerSetText(range, text);
this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange});
},


editRange: function(range, text)
{
var originalText = this.copyRange(range);
if (text === originalText)
return range; 

var newRange = this._innerSetText(range, text);
this._pushUndoableCommand(newRange, originalText);
this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange });
return newRange;
},


_innerSetText: function(range, text)
{
this._eraseRange(range);
if (text === "")
return new WebInspector.TextRange(range.startLine, range.startColumn, range.startLine, range.startColumn);

var newLines = text.split(/\r?\n/);

var prefix = this._lines[range.startLine].substring(0, range.startColumn);
var suffix = this._lines[range.startLine].substring(range.startColumn);

var postCaret = prefix.length;

if (newLines.length === 1) {
this._setLine(range.startLine, prefix + newLines[0] + suffix);
postCaret += newLines[0].length;
} else {
this._setLine(range.startLine, prefix + newLines[0]);
this._insertLines(range, newLines);
this._setLine(range.startLine + newLines.length - 1, newLines[newLines.length - 1] + suffix);
postCaret = newLines[newLines.length - 1].length;
}

return new WebInspector.TextRange(range.startLine, range.startColumn,
range.startLine + newLines.length - 1, postCaret);
},


_insertLines: function(range, newLines)
{
var lines = new Array(this._lines.length + newLines.length - 1);
for (var i = 0; i <= range.startLine; ++i)
lines[i] = this._lines[i];

for (var i = 1; i < newLines.length; ++i)
lines[range.startLine + i] = newLines[i];
for (var i = range.startLine + newLines.length; i < lines.length; ++i)
lines[i] = this._lines[i - newLines.length + 1];
this._lines = lines;


var attributes = new Array(lines.length);
var insertionIndex = range.startColumn ? range.startLine + 1 : range.startLine;
for (var i = 0; i < insertionIndex; ++i)
attributes[i] = this._attributes[i];
for (var i = insertionIndex + newLines.length - 1; i < attributes.length; ++i)
attributes[i] = this._attributes[i - newLines.length + 1];
this._attributes = attributes;
},


_eraseRange: function(range)
{
if (range.isEmpty())
return;

var prefix = this._lines[range.startLine].substring(0, range.startColumn);
var suffix = this._lines[range.endLine].substring(range.endColumn);

if (range.endLine > range.startLine) {
this._lines.splice(range.startLine + 1, range.endLine - range.startLine);

this._attributes.splice(range.startColumn ? range.startLine + 1 : range.startLine, range.endLine - range.startLine);
}
this._setLine(range.startLine, prefix + suffix);
},


_setLine: function(lineNumber, text)
{
this._lines[lineNumber] = text;
},


wordRange: function(lineNumber, column)
{
return new WebInspector.TextRange(lineNumber, this.wordStart(lineNumber, column, true), lineNumber, this.wordEnd(lineNumber, column, true));
},


wordStart: function(lineNumber, column, gapless)
{
var line = this._lines[lineNumber];
var prefix = line.substring(0, column).split("").reverse().join("");
var prefixMatch = this._noPunctuationRegex.exec(prefix);
return prefixMatch && (!gapless || prefixMatch.index === 0) ? column - prefixMatch.index - prefixMatch[0].length : column;
},


wordEnd: function(lineNumber, column, gapless)
{
var line = this._lines[lineNumber];
var suffix = line.substring(column);
var suffixMatch = this._noPunctuationRegex.exec(suffix);
return suffixMatch && (!gapless || suffixMatch.index === 0) ? column + suffixMatch.index + suffixMatch[0].length : column;
},


copyRange: function(range)
{
if (!range)
range = this.range();

var clip = [];
if (range.startLine === range.endLine) {
clip.push(this._lines[range.startLine].substring(range.startColumn, range.endColumn));
return clip.join(this._lineBreak);
}
clip.push(this._lines[range.startLine].substring(range.startColumn));
for (var i = range.startLine + 1; i < range.endLine; ++i)
clip.push(this._lines[i]);
clip.push(this._lines[range.endLine].substring(0, range.endColumn));
return clip.join(this._lineBreak);
},


setAttribute: function(line, name, value)
{
var attrs = this._attributes[line];
if (!attrs) {
attrs = {};
this._attributes[line] = attrs;
}
attrs[name] = value;
},


getAttribute: function(line, name)
{
var attrs = this._attributes[line];
return attrs ? attrs[name] : null;
},


removeAttribute: function(line, name)
{
var attrs = this._attributes[line];
if (attrs)
delete attrs[name];
},


_pushUndoableCommand: function(newRange, originalText)
{
var command = new WebInspector.TextEditorCommand(newRange.clone(), originalText);
if (this._inUndo)
this._redoStack.push(command);
else {
if (!this._inRedo)
this._redoStack = [];
this._undoStack.push(command);
}
return command;
},


undo: function(beforeCallback, afterCallback)
{
if (!this._undoStack.length)
return null;

this._markRedoableState();

this._inUndo = true;
var range = this._doUndo(this._undoStack, beforeCallback, afterCallback);
delete this._inUndo;

return range;
},


redo: function(beforeCallback, afterCallback)
{
if (!this._redoStack || !this._redoStack.length)
return null;
this.markUndoableState();

this._inRedo = true;
var range = this._doUndo(this._redoStack, beforeCallback, afterCallback);
delete this._inRedo;

return range;
},


_doUndo: function(stack, beforeCallback, afterCallback)
{
var range = null;
for (var i = stack.length - 1; i >= 0; --i) {
var command = stack[i];
stack.length = i;

if (beforeCallback)
beforeCallback();

range = this.editRange(command.newRange, command.originalText);

if (afterCallback)
afterCallback(command.newRange, range);

if (i > 0 && stack[i - 1].explicit)
return range;
}
return range;
},

markUndoableState: function()
{
if (this._undoStack.length)
this._undoStack[this._undoStack.length - 1].explicit = true;
},

_markRedoableState: function()
{
if (this._redoStack.length)
this._redoStack[this._redoStack.length - 1].explicit = true;
},

resetUndoStack: function()
{
this._undoStack = [];
}
}

WebInspector.TextEditorModel.prototype.__proto__ = WebInspector.Object.prototype;






WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
{
this._textModel = textModel;
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html");
this._damageCallback = damageCallback;
this._highlightChunkLimit = 1000;
}

WebInspector.TextEditorHighlighter._MaxLineCount = 10000;

WebInspector.TextEditorHighlighter.prototype = {
set mimeType(mimeType)
{
var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
if (tokenizer)
this._tokenizer = tokenizer;
},

set highlightChunkLimit(highlightChunkLimit)
{
this._highlightChunkLimit = highlightChunkLimit;
},


highlight: function(endLine, forceRun)
{
if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount)
return;


var state = this._textModel.getAttribute(endLine - 1, "highlight");
if (state && state.postConditionStringified) {

return;
}

this._requestedEndLine = endLine;

if (this._highlightTimer && !forceRun) {

return;
}


var startLine = endLine;
while (startLine > 0) {
state = this._textModel.getAttribute(startLine - 1, "highlight");
if (state && state.postConditionStringified)
break;
startLine--;
}


this._highlightInChunks(startLine, endLine);
},

updateHighlight: function(startLine, endLine)
{
if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount)
return;


this._clearHighlightState(startLine);

if (startLine) {
var state = this._textModel.getAttribute(startLine - 1, "highlight");
if (!state || !state.postConditionStringified) {

return false;
}
}

var restored = this._highlightLines(startLine, endLine);
if (!restored) {
for (var i = this._lastHighlightedLine; i < this._textModel.linesCount; ++i) {
var state = this._textModel.getAttribute(i, "highlight");
if (!state && i > endLine)
break;
this._textModel.setAttribute(i, "highlight-outdated", state);
this._textModel.removeAttribute(i, "highlight");
}

if (this._highlightTimer) {
clearTimeout(this._highlightTimer);
this._requestedEndLine = endLine;
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10);
}
}
return restored;
},

_highlightInChunks: function(startLine, endLine)
{
delete this._highlightTimer;


var state = this._textModel.getAttribute(this._requestedEndLine - 1, "highlight");
if (state && state.postConditionStringified)
return;

if (this._requestedEndLine !== endLine) {

this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, startLine, this._requestedEndLine), 100);
return;
}


if (this._requestedEndLine > this._textModel.linesCount)
this._requestedEndLine = this._textModel.linesCount;

this._highlightLines(startLine, this._requestedEndLine);


if (this._lastHighlightedLine < this._requestedEndLine)
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10);
},

_highlightLines: function(startLine, endLine)
{

var state = this._textModel.getAttribute(startLine - 1, "highlight");
var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.createInitialCondition());

var tokensCount = 0;
for (var lineNumber = startLine; lineNumber < endLine; ++lineNumber) {
state = this._selectHighlightState(lineNumber, postConditionStringified);
if (state.postConditionStringified) {

postConditionStringified = state.postConditionStringified;
} else {
var lastHighlightedColumn = 0;
if (state.midConditionStringified) {
lastHighlightedColumn = state.lastHighlightedColumn;
postConditionStringified = state.midConditionStringified;
}

var line = this._textModel.line(lineNumber);
this._tokenizer.line = line;
this._tokenizer.condition = JSON.parse(postConditionStringified);


do {
var newColumn = this._tokenizer.nextToken(lastHighlightedColumn);
var tokenType = this._tokenizer.tokenType;
if (tokenType)
state[lastHighlightedColumn] = { length: newColumn - lastHighlightedColumn, tokenType: tokenType };
lastHighlightedColumn = newColumn;
if (++tokensCount > this._highlightChunkLimit)
break;
} while (lastHighlightedColumn < line.length);

postConditionStringified = JSON.stringify(this._tokenizer.condition);

if (lastHighlightedColumn < line.length) {

state.lastHighlightedColumn = lastHighlightedColumn;
state.midConditionStringified = postConditionStringified;
break;
} else {
delete state.lastHighlightedColumn;
delete state.midConditionStringified;
state.postConditionStringified = postConditionStringified;
}
}

var nextLineState = this._textModel.getAttribute(lineNumber + 1, "highlight");
if (nextLineState && nextLineState.preConditionStringified === state.postConditionStringified) {

++lineNumber;
this._damageCallback(startLine, lineNumber);


for (; lineNumber < endLine; ++lineNumber) {
state = this._textModel.getAttribute(lineNumber, "highlight");
if (!state || !state.postConditionStringified)
break;
}
this._lastHighlightedLine = lineNumber;
return true;
}
}

this._damageCallback(startLine, lineNumber);
this._lastHighlightedLine = lineNumber;
return false;
},

_selectHighlightState: function(lineNumber, preConditionStringified)
{
var state = this._textModel.getAttribute(lineNumber, "highlight");
if (state && state.preConditionStringified === preConditionStringified)
return state;

var outdatedState = this._textModel.getAttribute(lineNumber, "highlight-outdated");
if (outdatedState && outdatedState.preConditionStringified === preConditionStringified) {

this._textModel.setAttribute(lineNumber, "highlight", outdatedState);
this._textModel.setAttribute(lineNumber, "highlight-outdated", state);
return outdatedState;
}

if (state)
this._textModel.setAttribute(lineNumber, "highlight-outdated", state);

state = {};
state.preConditionStringified = preConditionStringified;
this._textModel.setAttribute(lineNumber, "highlight", state);
return state;
},

_clearHighlightState: function(lineNumber)
{
this._textModel.removeAttribute(lineNumber, "highlight");
this._textModel.removeAttribute(lineNumber, "highlight-outdated");
}
}







WebInspector.SourceTokenizer = function()
{
}

WebInspector.SourceTokenizer.prototype = {
set line(line) {
this._line = line;
},

set condition(condition)
{
this._condition = condition;
},

get condition()
{
return this._condition;
},

getLexCondition: function()
{
return this.condition.lexCondition;
},

setLexCondition: function(lexCondition)
{
this.condition.lexCondition = lexCondition;
},

_charAt: function(cursor)
{
return cursor < this._line.length ? this._line.charAt(cursor) : "\n";
},

createInitialCondition: function()
{
},

nextToken: function(cursor)
{
}
}


WebInspector.SourceTokenizer.Registry = function() {
this._tokenizers = {};
this._tokenizerConstructors = {
"text/css": "SourceCSSTokenizer",
"text/html": "SourceHTMLTokenizer",
"text/javascript": "SourceJavaScriptTokenizer",
"text/x-scss": "SourceCSSTokenizer"
};
}

WebInspector.SourceTokenizer.Registry.getInstance = function()
{
if (!WebInspector.SourceTokenizer.Registry._instance)
WebInspector.SourceTokenizer.Registry._instance = new WebInspector.SourceTokenizer.Registry();
return WebInspector.SourceTokenizer.Registry._instance;
}

WebInspector.SourceTokenizer.Registry.prototype = {
getTokenizer: function(mimeType)
{
if (!this._tokenizerConstructors[mimeType])
return null;
var tokenizerClass = this._tokenizerConstructors[mimeType];
var tokenizer = this._tokenizers[tokenizerClass];
if (!tokenizer) {
tokenizer = new WebInspector[tokenizerClass]();
this._tokenizers[tokenizerClass] = tokenizer;
}
return tokenizer;
}
}











WebInspector.SourceCSSTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);

this._propertyKeywords = WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet();
this._colorKeywords = WebInspector.CSSKeywordCompletions.colors();

this._valueKeywords = [
"above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll",
"alternate", "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", "arabic-indic", "armenian", "asterisks",
"auto", "avoid", "background", "backwards", "baseline", "below", "bidi-override", "binary", "bengali", "blink",
"block", "block-axis", "bold", "bolder", "border", "border-box", "both", "bottom", "break-all", "break-word", "button",
"button-bevel", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", "capitalize", "caps-lock-indicator",
"caption", "captiontext", "caret", "cell", "center", "checkbox", "circle", "cjk-earthly-branch", "cjk-heavenly-stem", "cjk-ideographic",
"clear", "clip", "close-quote", "col-resize", "collapse", "compact", "condensed", "contain", "content", "content-box", "context-menu",
"continuous", "copy", "cover", "crop", "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", "decimal-leading-zero", "default",
"default-button", "destination-atop", "destination-in", "destination-out", "destination-over", "devanagari", "disc", "discard", "document",
"dot-dash", "dot-dot-dash", "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", "element",
"ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", "ethiopic-abegede-am-et", "ethiopic-abegede-gez",
"ethiopic-abegede-ti-er", "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", "ethiopic-halehame-aa-et",
"ethiopic-halehame-am-et", "ethiopic-halehame-gez", "ethiopic-halehame-om-et", "ethiopic-halehame-sid-et",
"ethiopic-halehame-so-et", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ew-resize", "expanded",
"extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", "forwards", "from", "geometricPrecision",
"georgian", "graytext", "groove", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", "help",
"hidden", "hide", "higher", "highlight", "highlighttext", "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline",
"inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana",
"katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "line-through", "linear", "lines",
"list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek",
"lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "match", "media-controls-background",
"media-current-time-display", "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button",
"media-rewind-button", "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display",
"media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button",
"menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple",
"myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none",
"normal", "not-allowed", "nowrap", "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", "optimizeLegibility",
"optimizeSpeed", "oriya", "oromo", "outset", "outside", "overlay", "overline", "padding", "padding-box", "painted", "paused",
"persian", "plus-darker", "plus-lighter", "pointer", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress",
"push-button", "radio", "read-only", "read-write", "read-write-plaintext-only", "relative", "repeat", "repeat-x",
"repeat-y", "reset", "reverse", "rgb", "rgba", "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", "s-resize", "sans-serif",
"scroll", "scrollbar", "se-resize", "searchfield", "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
"searchfield-results-decoration", "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", "single",
"skip-white-space", "slide", "slider-horizontal", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "solid", "somali", "source-atop", "source-in", "source-out", "source-over",
"space", "square", "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", "subpixel-antialiased", "super",
"sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group",
"table-row", "table-row-group", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin",
"threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede",
"tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-armenian",
"upper-greek", "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible",
"visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext",
"x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle",
"-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing",
"-webkit-gradient", "-webkit-inline-box", "-webkit-left", "-webkit-link", "-webkit-marquee", "-webkit-mini-control", "-webkit-nowrap", "-webkit-pictograph",
"-webkit-right", "-webkit-small-control", "-webkit-text", "-webkit-xxx-large", "-webkit-zoom-in", "-webkit-zoom-out",
].keySet();

this._scssValueKeywords = [
"abs", "adjust-color", "adjust-hue", "alpha", "append", "ceil", "change-color", "comparable", "complement", "darken", "desaturate",
"fade-in", "fade-out", "floor", "grayscale", "hue", "ie-hex-str", "invert", "join", "length", "lighten",
"lightness", "max", "min", "mix", "nth", "opacify", "opacity", "percentage", "quote", "round", "saturate",
"saturation", "scale-color", "transparentize", "type-of", "unit", "unitless", "unquote", "zip"
].keySet();

this._lexConditions = {
INITIAL: 0,
COMMENT: 1,
DSTRING: 2,
SSTRING: 3
};

this._parseConditions = {
INITIAL: 0,
PROPERTY: 1,
PROPERTY_VALUE: 2,
AT_RULE: 3,
AT_MEDIA_RULE: 4
};

this.case_INITIAL = 1000;
this.case_COMMENT = 1002;
this.case_DSTRING = 1003;
this.case_SSTRING = 1004;

this.condition = this.createInitialCondition();
}

WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords = ["from", "if", "in", "through"].keySet();

WebInspector.SourceCSSTokenizer.MediaTypes = ["all", "aural", "braille", "embossed", "handheld", "import", "print", "projection", "screen", "tty", "tv"].keySet();

WebInspector.SourceCSSTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},


_stringToken: function(cursor, stringEnds)
{
if (this._isPropertyValue())
this.tokenType = "css-string";
else
this.tokenType = null;
return cursor;
},

_isPropertyValue: function()
{
return this._condition.parseCondition === this._parseConditions.PROPERTY_VALUE || this._condition.parseCondition === this._parseConditions.AT_RULE;
},

_setParseCondition: function(condition)
{
this._condition.parseCondition = condition;
},

nextToken: function(cursor)
{
var cursorOnEnter = cursor;
var gotoCase = 1;
var YYMARKER;
while (1) {
switch (gotoCase)


{
case 1: var yych;
var yyaccept = 0;
if (this.getLexCondition() < 2) {
if (this.getLexCondition() < 1) {
{ gotoCase = this.case_INITIAL; continue; };
} else {
{ gotoCase = this.case_COMMENT; continue; };
}
} else {
if (this.getLexCondition() < 3) {
{ gotoCase = this.case_DSTRING; continue; };
} else {
{ gotoCase = this.case_SSTRING; continue; };
}
}

case this.case_COMMENT:

yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 4; continue; };
{ gotoCase = 3; continue; };
} else {
if (yych <= '\r') { gotoCase = 4; continue; };
if (yych == '*') { gotoCase = 6; continue; };
{ gotoCase = 3; continue; };
}
case 2:
{ this.tokenType = "css-comment"; return cursor; }
case 3:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 12; continue; };
case 4:
++cursor;
{ this.tokenType = null; return cursor; }
case 6:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych != '/') { gotoCase = 11; continue; };
case 7:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "css-comment"; return cursor; }
case 9:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych == '/') { gotoCase = 7; continue; };
case 11:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 12:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 2; continue; };
{ gotoCase = 11; continue; };
} else {
if (yych <= '\r') { gotoCase = 2; continue; };
if (yych == '*') { gotoCase = 9; continue; };
{ gotoCase = 11; continue; };
}

case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 17; continue; };
if (yych <= '\f') { gotoCase = 16; continue; };
{ gotoCase = 17; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 16; continue; };
{ gotoCase = 19; continue; };
} else {
if (yych == '\\') { gotoCase = 21; continue; };
{ gotoCase = 16; continue; };
}
}
case 15:
{ return this._stringToken(cursor); }
case 16:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 23; continue; };
case 17:
++cursor;
case 18:
{ this.tokenType = null; return cursor; }
case 19:
++cursor;
case 20:
this.setLexCondition(this._lexConditions.INITIAL);
{ return this._stringToken(cursor, true); }
case 21:
yych = this._charAt(++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 22; continue; };
if (yych <= '&') { gotoCase = 18; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 18; continue; };
} else {
if (yych != 'b') { gotoCase = 18; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 18; continue; };
} else {
if (yych <= 'n') { gotoCase = 22; continue; };
if (yych <= 'q') { gotoCase = 18; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 18; continue; };
} else {
if (yych != 'v') { gotoCase = 18; continue; };
}
}
}
case 22:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 23:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 15; continue; };
if (yych <= '\f') { gotoCase = 22; continue; };
{ gotoCase = 15; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 22; continue; };
{ gotoCase = 26; continue; };
} else {
if (yych != '\\') { gotoCase = 22; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 22; continue; };
if (yych >= '\'') { gotoCase = 22; continue; };
} else {
if (yych <= '\\') {
if (yych >= '\\') { gotoCase = 22; continue; };
} else {
if (yych == 'b') { gotoCase = 22; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 22; continue; };
} else {
if (yych <= 'n') { gotoCase = 22; continue; };
if (yych >= 'r') { gotoCase = 22; continue; };
}
} else {
if (yych <= 't') {
if (yych >= 't') { gotoCase = 22; continue; };
} else {
if (yych == 'v') { gotoCase = 22; continue; };
}
}
}
cursor = YYMARKER;
{ gotoCase = 15; continue; };
case 26:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 20; continue; };

case this.case_INITIAL:
yych = this._charAt(cursor);
if (yych <= ':') {
if (yych <= '&') {
if (yych <= '"') {
if (yych <= ' ') { gotoCase = 29; continue; };
if (yych <= '!') { gotoCase = 31; continue; };
{ gotoCase = 33; continue; };
} else {
if (yych <= '#') { gotoCase = 34; continue; };
if (yych <= '$') { gotoCase = 35; continue; };
if (yych >= '&') { gotoCase = 31; continue; };
}
} else {
if (yych <= '-') {
if (yych <= '\'') { gotoCase = 36; continue; };
if (yych >= '-') { gotoCase = 37; continue; };
} else {
if (yych <= '.') { gotoCase = 38; continue; };
if (yych <= '/') { gotoCase = 39; continue; };
if (yych <= '9') { gotoCase = 40; continue; };
{ gotoCase = 42; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '=') {
if (yych <= ';') { gotoCase = 44; continue; };
if (yych >= '=') { gotoCase = 31; continue; };
} else {
if (yych <= '?') { gotoCase = 29; continue; };
if (yych != '\\') { gotoCase = 31; continue; };
}
} else {
if (yych <= 'z') {
if (yych == '_') { gotoCase = 31; continue; };
if (yych >= 'a') { gotoCase = 31; continue; };
} else {
if (yych <= '{') { gotoCase = 46; continue; };
if (yych == '}') { gotoCase = 48; continue; };
}
}
}
case 29:
++cursor;
case 30:
{ this.tokenType = null; return cursor; }
case 31:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 51; continue; };
case 32:
{
var token = this._line.substring(cursorOnEnter, cursor);
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.INITIAL || this._condition.parseCondition === this._parseConditions.PROPERTY) {
if (token.charAt(0) === "@") {
this.tokenType = "css-at-rule";
this._setParseCondition(token === "@media" ? this._parseConditions.AT_MEDIA_RULE : this._parseConditions.AT_RULE);
this._condition.atKeyword = token;
} else if (this._condition.parseCondition === this._parseConditions.INITIAL)
this.tokenType = "css-selector";
else if (this._propertyKeywords.hasOwnProperty(token))
this.tokenType = "css-property";
} else if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE || this._condition.parseCondition === this._parseConditions.AT_RULE) {
if (WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords.hasOwnProperty(token))
this.tokenType = "css-at-rule";
else if (WebInspector.SourceCSSTokenizer.MediaTypes.hasOwnProperty(token))
this.tokenType = "css-keyword";
}
if (this.tokenType)
return cursor;

if (this._isPropertyValue()) {
var firstChar = token.charAt(0);
if (firstChar === "$")
this.tokenType = "scss-variable";
else if (firstChar === "!")
this.tokenType = "css-bang-keyword";
else if (this._condition.atKeyword === "@extend")
this.tokenType = "css-selector";
else if (this._valueKeywords.hasOwnProperty(token) || this._scssValueKeywords.hasOwnProperty(token))
this.tokenType = "css-keyword";
else if (this._colorKeywords.hasOwnProperty(token)) {

this.tokenType = "css-color";
}
} else if (this._condition.parseCondition !== this._parseConditions.PROPERTY_VALUE)
this.tokenType = "css-selector";
return cursor;
}
case 33:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '.') {
if (yych <= '!') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 116; continue; };
if (yych <= '%') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych == '-') { gotoCase = 130; continue; };
{ gotoCase = 132; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 130; continue; };
if (yych <= '<') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych <= '?') { gotoCase = 132; continue; };
if (yych <= '[') { gotoCase = 130; continue; };
{ gotoCase = 134; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych <= '`') { gotoCase = 132; continue; };
if (yych <= 'z') { gotoCase = 130; continue; };
{ gotoCase = 132; continue; };
}
}
}
case 34:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 127; continue; };
{ gotoCase = 30; continue; };
} else {
if (yych <= 'Z') { gotoCase = 127; continue; };
if (yych <= '`') { gotoCase = 30; continue; };
if (yych <= 'z') { gotoCase = 127; continue; };
{ gotoCase = 30; continue; };
}
case 35:
yych = this._charAt(++cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 30; continue; };
if (yych <= '"') { gotoCase = 124; continue; };
if (yych <= '%') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '.') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
} else {
if (yych == '\\') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '`') { gotoCase = 30; continue; };
if (yych <= 'z') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
}
}
}
case 36:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '.') {
if (yych <= '"') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '%') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 114; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych == '-') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 114; continue; };
if (yych <= '<') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '?') { gotoCase = 118; continue; };
if (yych <= '[') { gotoCase = 114; continue; };
{ gotoCase = 120; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '`') { gotoCase = 118; continue; };
if (yych <= 'z') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
}
case 37:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '.') { gotoCase = 67; continue; };
if (yych <= '/') { gotoCase = 51; continue; };
if (yych <= '9') { gotoCase = 52; continue; };
{ gotoCase = 51; continue; };
case 38:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
{ gotoCase = 30; continue; };
case 39:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 106; continue; };
{ gotoCase = 51; continue; };
case 40:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
switch (yych) {
case '!':
case '"':
case '&':
case '\'':
case '-':
case '/':
case '=':
case '@':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '[':
case ']':
case 'a':
case 'b':
case 'f':
case 'h':
case 'j':
case 'l':
case 'n':
case 'o':
case 'q':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':    { gotoCase = 50; continue; };
case '%':    { gotoCase = 69; continue; };
case '.':    { gotoCase = 67; continue; };
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':    { gotoCase = 52; continue; };
case 'H':    { gotoCase = 54; continue; };
case '_':    { gotoCase = 55; continue; };
case 'c':    { gotoCase = 56; continue; };
case 'd':    { gotoCase = 57; continue; };
case 'e':    { gotoCase = 58; continue; };
case 'g':    { gotoCase = 59; continue; };
case 'i':    { gotoCase = 60; continue; };
case 'k':    { gotoCase = 61; continue; };
case 'm':    { gotoCase = 62; continue; };
case 'p':    { gotoCase = 63; continue; };
case 'r':    { gotoCase = 64; continue; };
case 's':    { gotoCase = 65; continue; };
case 't':    { gotoCase = 66; continue; };
default:    { gotoCase = 41; continue; };
}
case 41:
{
if (this._isPropertyValue())
this.tokenType = "css-number";
else
this.tokenType = null;
return cursor;
}
case 42:
++cursor;
{
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.PROPERTY || this._condition.parseCondition === this._parseConditions.INITIAL)
this._setParseCondition(this._parseConditions.PROPERTY_VALUE);
return cursor;
}
case 44:
++cursor;
{
this.tokenType = null;
this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL);
delete this._condition.atKeyword;
return cursor;
}
case 46:
++cursor;
{
this.tokenType = "block-start";
this._condition.openBraces = (this._condition.openBraces || 0) + 1;
if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE)
this._setParseCondition(this._parseConditions.INITIAL);
else
this._setParseCondition(this._parseConditions.PROPERTY);
return cursor;
}
case 48:
++cursor;
{
this.tokenType = "block-end";
if (this._condition.openBraces > 0)
--this._condition.openBraces;
this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL);
delete this._condition.atKeyword;
return cursor;
}
case 50:
++cursor;
yych = this._charAt(cursor);
case 51:
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 32; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych <= '%') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 32; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
} else {
if (yych == '\\') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 32; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
}
}
}
case 52:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
switch (yych) {
case '!':
case '"':
case '&':
case '\'':
case '-':
case '/':
case '=':
case '@':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '[':
case ']':
case 'a':
case 'b':
case 'f':
case 'h':
case 'j':
case 'l':
case 'n':
case 'o':
case 'q':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':    { gotoCase = 50; continue; };
case '%':    { gotoCase = 69; continue; };
case '.':    { gotoCase = 67; continue; };
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':    { gotoCase = 52; continue; };
case 'H':    { gotoCase = 54; continue; };
case '_':    { gotoCase = 55; continue; };
case 'c':    { gotoCase = 56; continue; };
case 'd':    { gotoCase = 57; continue; };
case 'e':    { gotoCase = 58; continue; };
case 'g':    { gotoCase = 59; continue; };
case 'i':    { gotoCase = 60; continue; };
case 'k':    { gotoCase = 61; continue; };
case 'm':    { gotoCase = 62; continue; };
case 'p':    { gotoCase = 63; continue; };
case 'r':    { gotoCase = 64; continue; };
case 's':    { gotoCase = 65; continue; };
case 't':    { gotoCase = 66; continue; };
default:    { gotoCase = 41; continue; };
}
case 54:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 55:
yych = this._charAt(++cursor);
if (yych == '_') { gotoCase = 103; continue; };
{ gotoCase = 51; continue; };
case 56:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 57:
yych = this._charAt(++cursor);
if (yych == 'e') { gotoCase = 102; continue; };
{ gotoCase = 51; continue; };
case 58:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
if (yych == 'x') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 59:
yych = this._charAt(++cursor);
if (yych == 'r') { gotoCase = 100; continue; };
{ gotoCase = 51; continue; };
case 60:
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 61:
yych = this._charAt(++cursor);
if (yych == 'H') { gotoCase = 99; continue; };
{ gotoCase = 51; continue; };
case 62:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
if (yych == 's') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 63:
yych = this._charAt(++cursor);
if (yych <= 's') {
if (yych == 'c') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
} else {
if (yych <= 't') { gotoCase = 65; continue; };
if (yych == 'x') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
}
case 64:
yych = this._charAt(++cursor);
if (yych == 'a') { gotoCase = 97; continue; };
if (yych == 'e') { gotoCase = 98; continue; };
{ gotoCase = 51; continue; };
case 65:
yych = this._charAt(++cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 41; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych <= '%') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 41; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych == '\\') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 41; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
}
}
}
case 66:
yych = this._charAt(++cursor);
if (yych == 'u') { gotoCase = 95; continue; };
{ gotoCase = 51; continue; };
case 67:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 68; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
case 68:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 32; continue; };
} else {
{ gotoCase = 41; continue; };
}
case 69:
yych = this._charAt(++cursor);
{ gotoCase = 41; continue; };
case 70:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'f') {
if (yych <= 'H') {
if (yych <= '/') {
if (yych == '%') { gotoCase = 69; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= '9') { gotoCase = 70; continue; };
if (yych <= 'G') { gotoCase = 41; continue; };
{ gotoCase = 82; continue; };
}
} else {
if (yych <= 'b') {
if (yych == '_') { gotoCase = 74; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= 'c') { gotoCase = 76; continue; };
if (yych <= 'd') { gotoCase = 79; continue; };
if (yych >= 'f') { gotoCase = 41; continue; };
}
}
} else {
if (yych <= 'm') {
if (yych <= 'i') {
if (yych <= 'g') { gotoCase = 80; continue; };
if (yych <= 'h') { gotoCase = 41; continue; };
{ gotoCase = 78; continue; };
} else {
if (yych == 'k') { gotoCase = 83; continue; };
if (yych <= 'l') { gotoCase = 41; continue; };
{ gotoCase = 77; continue; };
}
} else {
if (yych <= 'q') {
if (yych == 'p') { gotoCase = 75; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= 'r') { gotoCase = 73; continue; };
if (yych <= 's') { gotoCase = 69; continue; };
if (yych <= 't') { gotoCase = 81; continue; };
{ gotoCase = 41; continue; };
}
}
}
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
if (yych == 'x') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 73:
yych = this._charAt(++cursor);
if (yych == 'a') { gotoCase = 93; continue; };
if (yych == 'e') { gotoCase = 94; continue; };
{ gotoCase = 68; continue; };
case 74:
yych = this._charAt(++cursor);
if (yych == '_') { gotoCase = 90; continue; };
{ gotoCase = 68; continue; };
case 75:
yych = this._charAt(++cursor);
if (yych <= 's') {
if (yych == 'c') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= 't') { gotoCase = 69; continue; };
if (yych == 'x') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
}
case 76:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 77:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
if (yych == 's') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 78:
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 79:
yych = this._charAt(++cursor);
if (yych == 'e') { gotoCase = 89; continue; };
{ gotoCase = 68; continue; };
case 80:
yych = this._charAt(++cursor);
if (yych == 'r') { gotoCase = 87; continue; };
{ gotoCase = 68; continue; };
case 81:
yych = this._charAt(++cursor);
if (yych == 'u') { gotoCase = 85; continue; };
{ gotoCase = 68; continue; };
case 82:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 83:
yych = this._charAt(++cursor);
if (yych != 'H') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 85:
yych = this._charAt(++cursor);
if (yych != 'r') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 87:
yych = this._charAt(++cursor);
if (yych != 'a') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 89:
yych = this._charAt(++cursor);
if (yych == 'g') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 90:
yych = this._charAt(++cursor);
if (yych != 'q') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych != 'e') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 93:
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 94:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 95:
yych = this._charAt(++cursor);
if (yych != 'r') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 97:
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 98:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 99:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 100:
yych = this._charAt(++cursor);
if (yych != 'a') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 102:
yych = this._charAt(++cursor);
if (yych == 'g') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 103:
yych = this._charAt(++cursor);
if (yych != 'q') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych != 'e') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 106:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 110; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych <= '\r') { gotoCase = 110; continue; };
if (yych != '*') { gotoCase = 106; continue; };
}
case 108:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 108; continue; };
if (yych == '/') { gotoCase = 112; continue; };
{ gotoCase = 106; continue; };
case 110:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "css-comment"; return cursor; }
case 112:
++cursor;
{ this.tokenType = "css-comment"; return cursor; }
case 114:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '"') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '%') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 114; continue; };
} else {
if (yych == '-') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 114; continue; };
if (yych <= '<') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '?') { gotoCase = 118; continue; };
if (yych <= '[') { gotoCase = 114; continue; };
{ gotoCase = 120; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '`') { gotoCase = 118; continue; };
if (yych <= 'z') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
}
case 116:
++cursor;
if ((yych = this._charAt(cursor)) <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 117; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych >= '&') { gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych >= '-') { gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 117; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
} else {
if (yych != '\\') { gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych >= '_') { gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 117; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
}
}
}
case 117:
{ return this._stringToken(cursor, true); }
case 118:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 68; continue; };
if (yych <= '\f') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 118; continue; };
{ gotoCase = 123; continue; };
} else {
if (yych != '\\') { gotoCase = 118; continue; };
}
}
case 120:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 68; continue; };
} else {
if (yych != '\r') { gotoCase = 68; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == '\\') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 118; continue; };
if (yych <= 'e') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == 'n') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == 'v') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
}
}
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ return this._stringToken(cursor); }
case 123:
yych = this._charAt(++cursor);
{ gotoCase = 117; continue; };
case 124:
++cursor;
yych = this._charAt(cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 126; continue; };
if (yych <= '"') { gotoCase = 124; continue; };
if (yych >= '&') { gotoCase = 124; continue; };
} else {
if (yych <= '-') {
if (yych >= '-') { gotoCase = 124; continue; };
} else {
if (yych <= '.') { gotoCase = 126; continue; };
if (yych <= '9') { gotoCase = 124; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 124; continue; };
} else {
if (yych != '\\') { gotoCase = 124; continue; };
}
} else {
if (yych <= '_') {
if (yych >= '_') { gotoCase = 124; continue; };
} else {
if (yych <= '`') { gotoCase = 126; continue; };
if (yych <= 'z') { gotoCase = 124; continue; };
}
}
}
case 126:
{
if (this._condition.parseCondition === this._condition.parseCondition.INITIAL || this._condition.parseCondition === this._condition.parseCondition.AT_RULE)
this._setParseCondition(this._parseConditions.PROPERTY);
this.tokenType = "scss-variable";
return cursor;
}
case 127:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 129; continue; };
if (yych <= '9') { gotoCase = 127; continue; };
} else {
if (yych <= 'Z') { gotoCase = 127; continue; };
if (yych <= '`') { gotoCase = 129; continue; };
if (yych <= 'z') { gotoCase = 127; continue; };
}
case 129:
{
if (this._isPropertyValue())
this.tokenType = "css-color";
else if (this._condition.parseCondition === this._parseConditions.INITIAL)
this.tokenType = "css-selector";
else
this.tokenType = null;
return cursor;
}
case 130:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '!') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych >= '!') { gotoCase = 130; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 116; continue; };
if (yych >= '&') { gotoCase = 130; continue; };
} else {
if (yych == '-') { gotoCase = 130; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 130; continue; };
if (yych >= '=') { gotoCase = 130; continue; };
} else {
if (yych <= '?') { gotoCase = 132; continue; };
if (yych <= '[') { gotoCase = 130; continue; };
{ gotoCase = 134; continue; };
}
} else {
if (yych <= '_') {
if (yych != '^') { gotoCase = 130; continue; };
} else {
if (yych <= '`') { gotoCase = 132; continue; };
if (yych <= 'z') { gotoCase = 130; continue; };
}
}
}
case 132:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 68; continue; };
if (yych <= '\f') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 132; continue; };
{ gotoCase = 123; continue; };
} else {
if (yych != '\\') { gotoCase = 132; continue; };
}
}
case 134:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 68; continue; };
} else {
if (yych != '\r') { gotoCase = 68; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 132; continue; };
if (yych <= '&') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == '\\') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 132; continue; };
if (yych <= 'e') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == 'n') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == 'v') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
}
}
}
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ return this._stringToken(cursor); }

case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 141; continue; };
if (yych <= '\f') { gotoCase = 140; continue; };
{ gotoCase = 141; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 140; continue; };
{ gotoCase = 143; continue; };
} else {
if (yych == '\\') { gotoCase = 145; continue; };
{ gotoCase = 140; continue; };
}
}
case 139:
{ return this._stringToken(cursor); }
case 140:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 147; continue; };
case 141:
++cursor;
case 142:
{ this.tokenType = null; return cursor; }
case 143:
++cursor;
case 144:
this.setLexCondition(this._lexConditions.INITIAL);
{ return this._stringToken(cursor, true); }
case 145:
yych = this._charAt(++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 146; continue; };
if (yych <= '&') { gotoCase = 142; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 142; continue; };
} else {
if (yych != 'b') { gotoCase = 142; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 142; continue; };
} else {
if (yych <= 'n') { gotoCase = 146; continue; };
if (yych <= 'q') { gotoCase = 142; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 142; continue; };
} else {
if (yych != 'v') { gotoCase = 142; continue; };
}
}
}
case 146:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 147:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 139; continue; };
if (yych <= '\f') { gotoCase = 146; continue; };
{ gotoCase = 139; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 146; continue; };
{ gotoCase = 150; continue; };
} else {
if (yych != '\\') { gotoCase = 146; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 146; continue; };
if (yych >= '\'') { gotoCase = 146; continue; };
} else {
if (yych <= '\\') {
if (yych >= '\\') { gotoCase = 146; continue; };
} else {
if (yych == 'b') { gotoCase = 146; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 146; continue; };
} else {
if (yych <= 'n') { gotoCase = 146; continue; };
if (yych >= 'r') { gotoCase = 146; continue; };
}
} else {
if (yych <= 't') {
if (yych >= 't') { gotoCase = 146; continue; };
} else {
if (yych == 'v') { gotoCase = 146; continue; };
}
}
}
cursor = YYMARKER;
{ gotoCase = 139; continue; };
case 150:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 144; continue; };
}

}
}
}

WebInspector.SourceCSSTokenizer.prototype.__proto__ = WebInspector.SourceTokenizer.prototype;



















WebInspector.SourceHTMLTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);


this._lexConditions = {
INITIAL: 0,
COMMENT: 1,
DOCTYPE: 2,
TAG: 3,
DSTRING: 4,
SSTRING: 5
};
this.case_INITIAL = 1000;
this.case_COMMENT = 1001;
this.case_DOCTYPE = 1002;
this.case_TAG = 1003;
this.case_DSTRING = 1004;
this.case_SSTRING = 1005;

this._parseConditions = {
INITIAL: 0,
ATTRIBUTE: 1,
ATTRIBUTE_VALUE: 2,
LINKIFY: 4,
A_NODE: 8,
SCRIPT: 16,
STYLE: 32
};

this.condition = this.createInitialCondition();
}

WebInspector.SourceHTMLTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},

set line(line) {
if (this._condition.internalJavaScriptTokenizerCondition) {
var match = /<\/script/i.exec(line);
if (match) {
this._internalJavaScriptTokenizer.line = line.substring(0, match.index);
} else
this._internalJavaScriptTokenizer.line = line;
} else if (this._condition.internalCSSTokenizerCondition) {
var match = /<\/style/i.exec(line);
if (match) {
this._internalCSSTokenizer.line = line.substring(0, match.index);
} else
this._internalCSSTokenizer.line = line;
}
this._line = line;
},

_isExpectingAttribute: function()
{
return this._condition.parseCondition & this._parseConditions.ATTRIBUTE;
},

_isExpectingAttributeValue: function()
{
return this._condition.parseCondition & this._parseConditions.ATTRIBUTE_VALUE;
},

_setExpectingAttribute: function()
{
if (this._isExpectingAttributeValue())
this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE_VALUE;
this._condition.parseCondition |= this._parseConditions.ATTRIBUTE;
},

_setExpectingAttributeValue: function()
{
if (this._isExpectingAttribute())
this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE;
this._condition.parseCondition |= this._parseConditions.ATTRIBUTE_VALUE;
},


_stringToken: function(cursor, stringEnds)
{
if (!this._isExpectingAttributeValue()) {
this.tokenType = null;
return cursor;
}
this.tokenType = this._attrValueTokenType();
if (stringEnds)
this._setExpectingAttribute();
return cursor;
},

_attrValueTokenType: function()
{
if (this._condition.parseCondition & this._parseConditions.LINKIFY) {
if (this._condition.parseCondition & this._parseConditions.A_NODE)
return "html-external-link";
return "html-resource-link";
}
return "html-attribute-value";
},

get _internalJavaScriptTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
},

get _internalCSSTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
},

scriptStarted: function(cursor)
{
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition();
},

scriptEnded: function(cursor)
{
},

styleSheetStarted: function(cursor)
{
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition();
},

styleSheetEnded: function(cursor)
{
},

nextToken: function(cursor)
{
if (this._condition.internalJavaScriptTokenizerCondition) {

this.line = this._line;
if (cursor !== this._internalJavaScriptTokenizer._line.length) {

this._internalJavaScriptTokenizer.condition = this._condition.internalJavaScriptTokenizerCondition;
var result = this._internalJavaScriptTokenizer.nextToken(cursor);
this.tokenType = this._internalJavaScriptTokenizer.tokenType;
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._condition.internalJavaScriptTokenizerCondition;
} else if (this._condition.internalCSSTokenizerCondition) {

this.line = this._line;
if (cursor !== this._internalCSSTokenizer._line.length) {

this._internalCSSTokenizer.condition = this._condition.internalCSSTokenizerCondition;
var result = this._internalCSSTokenizer.nextToken(cursor);
this.tokenType = this._internalCSSTokenizer.tokenType;
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._condition.internalCSSTokenizerCondition;
}

var cursorOnEnter = cursor;
var gotoCase = 1;
var YYMARKER;
while (1) {
switch (gotoCase)


{
case 1: var yych;
var yyaccept = 0;
if (this.getLexCondition() < 3) {
if (this.getLexCondition() < 1) {
{ gotoCase = this.case_INITIAL; continue; };
} else {
if (this.getLexCondition() < 2) {
{ gotoCase = this.case_COMMENT; continue; };
} else {
{ gotoCase = this.case_DOCTYPE; continue; };
}
}
} else {
if (this.getLexCondition() < 4) {
{ gotoCase = this.case_TAG; continue; };
} else {
if (this.getLexCondition() < 5) {
{ gotoCase = this.case_DSTRING; continue; };
} else {
{ gotoCase = this.case_SSTRING; continue; };
}
}
}

case this.case_COMMENT:

yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 4; continue; };
{ gotoCase = 3; continue; };
} else {
if (yych <= '\r') { gotoCase = 4; continue; };
if (yych == '-') { gotoCase = 6; continue; };
{ gotoCase = 3; continue; };
}
case 2:
{ this.tokenType = "html-comment"; return cursor; }
case 3:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 9; continue; };
case 4:
++cursor;
case 5:
{ this.tokenType = null; return cursor; }
case 6:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych != '-') { gotoCase = 5; continue; };
case 7:
++cursor;
yych = this._charAt(cursor);
if (yych == '>') { gotoCase = 10; continue; };
case 8:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 9:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 2; continue; };
{ gotoCase = 8; continue; };
} else {
if (yych <= '\r') { gotoCase = 2; continue; };
if (yych == '-') { gotoCase = 12; continue; };
{ gotoCase = 8; continue; };
}
case 10:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "html-comment"; return cursor; }
case 12:
++cursor;
yych = this._charAt(cursor);
if (yych == '-') { gotoCase = 7; continue; };
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 2; continue; };
} else {
{ gotoCase = 5; continue; };
}

case this.case_DOCTYPE:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 18; continue; };
{ gotoCase = 17; continue; };
} else {
if (yych <= '\r') { gotoCase = 18; continue; };
if (yych == '>') { gotoCase = 20; continue; };
{ gotoCase = 17; continue; };
}
case 16:
{ this.tokenType = "html-doctype"; return cursor; }
case 17:
yych = this._charAt(++cursor);
{ gotoCase = 23; continue; };
case 18:
++cursor;
{ this.tokenType = null; return cursor; }
case 20:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "html-doctype"; return cursor; }
case 22:
++cursor;
yych = this._charAt(cursor);
case 23:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 16; continue; };
{ gotoCase = 22; continue; };
} else {
if (yych <= '\r') { gotoCase = 16; continue; };
if (yych == '>') { gotoCase = 16; continue; };
{ gotoCase = 22; continue; };
}

case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 28; continue; };
{ gotoCase = 27; continue; };
} else {
if (yych <= '\r') { gotoCase = 28; continue; };
if (yych == '"') { gotoCase = 30; continue; };
{ gotoCase = 27; continue; };
}
case 26:
{ return this._stringToken(cursor); }
case 27:
yych = this._charAt(++cursor);
{ gotoCase = 34; continue; };
case 28:
++cursor;
{ this.tokenType = null; return cursor; }
case 30:
++cursor;
case 31:
this.setLexCondition(this._lexConditions.TAG);
{ return this._stringToken(cursor, true); }
case 32:
yych = this._charAt(++cursor);
{ gotoCase = 31; continue; };
case 33:
++cursor;
yych = this._charAt(cursor);
case 34:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 26; continue; };
{ gotoCase = 33; continue; };
} else {
if (yych <= '\r') { gotoCase = 26; continue; };
if (yych == '"') { gotoCase = 32; continue; };
{ gotoCase = 33; continue; };
}

case this.case_INITIAL:
yych = this._charAt(cursor);
if (yych == '<') { gotoCase = 39; continue; };
++cursor;
{ this.tokenType = null; return cursor; }
case 39:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '/') {
if (yych == '!') { gotoCase = 44; continue; };
if (yych >= '/') { gotoCase = 41; continue; };
} else {
if (yych <= 'S') {
if (yych >= 'S') { gotoCase = 42; continue; };
} else {
if (yych == 's') { gotoCase = 42; continue; };
}
}
case 40:
this.setLexCondition(this._lexConditions.TAG);
{
if (this._condition.parseCondition & (this._parseConditions.SCRIPT | this._parseConditions.STYLE)) {

this.setLexCondition(this._lexConditions.INITIAL);
this.tokenType = null;
return cursor;
}

this._condition.parseCondition = this._parseConditions.INITIAL;
this.tokenType = "html-tag";
return cursor;
}
case 41:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == 'S') { gotoCase = 73; continue; };
if (yych == 's') { gotoCase = 73; continue; };
{ gotoCase = 40; continue; };
case 42:
yych = this._charAt(++cursor);
if (yych <= 'T') {
if (yych == 'C') { gotoCase = 62; continue; };
if (yych >= 'T') { gotoCase = 63; continue; };
} else {
if (yych <= 'c') {
if (yych >= 'c') { gotoCase = 62; continue; };
} else {
if (yych == 't') { gotoCase = 63; continue; };
}
}
case 43:
cursor = YYMARKER;
{ gotoCase = 40; continue; };
case 44:
yych = this._charAt(++cursor);
if (yych <= 'C') {
if (yych != '-') { gotoCase = 43; continue; };
} else {
if (yych <= 'D') { gotoCase = 46; continue; };
if (yych == 'd') { gotoCase = 46; continue; };
{ gotoCase = 43; continue; };
}
yych = this._charAt(++cursor);
if (yych == '-') { gotoCase = 54; continue; };
{ gotoCase = 43; continue; };
case 46:
yych = this._charAt(++cursor);
if (yych == 'O') { gotoCase = 47; continue; };
if (yych != 'o') { gotoCase = 43; continue; };
case 47:
yych = this._charAt(++cursor);
if (yych == 'C') { gotoCase = 48; continue; };
if (yych != 'c') { gotoCase = 43; continue; };
case 48:
yych = this._charAt(++cursor);
if (yych == 'T') { gotoCase = 49; continue; };
if (yych != 't') { gotoCase = 43; continue; };
case 49:
yych = this._charAt(++cursor);
if (yych == 'Y') { gotoCase = 50; continue; };
if (yych != 'y') { gotoCase = 43; continue; };
case 50:
yych = this._charAt(++cursor);
if (yych == 'P') { gotoCase = 51; continue; };
if (yych != 'p') { gotoCase = 43; continue; };
case 51:
yych = this._charAt(++cursor);
if (yych == 'E') { gotoCase = 52; continue; };
if (yych != 'e') { gotoCase = 43; continue; };
case 52:
++cursor;
this.setLexCondition(this._lexConditions.DOCTYPE);
{ this.tokenType = "html-doctype"; return cursor; }
case 54:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 57; continue; };
{ gotoCase = 54; continue; };
} else {
if (yych <= '\r') { gotoCase = 57; continue; };
if (yych != '-') { gotoCase = 54; continue; };
}
++cursor;
yych = this._charAt(cursor);
if (yych == '-') { gotoCase = 59; continue; };
{ gotoCase = 43; continue; };
case 57:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "html-comment"; return cursor; }
case 59:
++cursor;
yych = this._charAt(cursor);
if (yych != '>') { gotoCase = 54; continue; };
++cursor;
{ this.tokenType = "html-comment"; return cursor; }
case 62:
yych = this._charAt(++cursor);
if (yych == 'R') { gotoCase = 68; continue; };
if (yych == 'r') { gotoCase = 68; continue; };
{ gotoCase = 43; continue; };
case 63:
yych = this._charAt(++cursor);
if (yych == 'Y') { gotoCase = 64; continue; };
if (yych != 'y') { gotoCase = 43; continue; };
case 64:
yych = this._charAt(++cursor);
if (yych == 'L') { gotoCase = 65; continue; };
if (yych != 'l') { gotoCase = 43; continue; };
case 65:
yych = this._charAt(++cursor);
if (yych == 'E') { gotoCase = 66; continue; };
if (yych != 'e') { gotoCase = 43; continue; };
case 66:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
if (this._condition.parseCondition & this._parseConditions.STYLE) {

this.setLexCondition(this._lexConditions.INITIAL);
this.tokenType = null;
return cursor;
}
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.STYLE;
this._setExpectingAttribute();
return cursor;
}
case 68:
yych = this._charAt(++cursor);
if (yych == 'I') { gotoCase = 69; continue; };
if (yych != 'i') { gotoCase = 43; continue; };
case 69:
yych = this._charAt(++cursor);
if (yych == 'P') { gotoCase = 70; continue; };
if (yych != 'p') { gotoCase = 43; continue; };
case 70:
yych = this._charAt(++cursor);
if (yych == 'T') { gotoCase = 71; continue; };
if (yych != 't') { gotoCase = 43; continue; };
case 71:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
if (this._condition.parseCondition & this._parseConditions.SCRIPT) {

this.setLexCondition(this._lexConditions.INITIAL);
this.tokenType = null;
return cursor;
}
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.SCRIPT;
this._setExpectingAttribute();
return cursor;
}
case 73:
yych = this._charAt(++cursor);
if (yych <= 'T') {
if (yych == 'C') { gotoCase = 75; continue; };
if (yych <= 'S') { gotoCase = 43; continue; };
} else {
if (yych <= 'c') {
if (yych <= 'b') { gotoCase = 43; continue; };
{ gotoCase = 75; continue; };
} else {
if (yych != 't') { gotoCase = 43; continue; };
}
}
yych = this._charAt(++cursor);
if (yych == 'Y') { gotoCase = 81; continue; };
if (yych == 'y') { gotoCase = 81; continue; };
{ gotoCase = 43; continue; };
case 75:
yych = this._charAt(++cursor);
if (yych == 'R') { gotoCase = 76; continue; };
if (yych != 'r') { gotoCase = 43; continue; };
case 76:
yych = this._charAt(++cursor);
if (yych == 'I') { gotoCase = 77; continue; };
if (yych != 'i') { gotoCase = 43; continue; };
case 77:
yych = this._charAt(++cursor);
if (yych == 'P') { gotoCase = 78; continue; };
if (yych != 'p') { gotoCase = 43; continue; };
case 78:
yych = this._charAt(++cursor);
if (yych == 'T') { gotoCase = 79; continue; };
if (yych != 't') { gotoCase = 43; continue; };
case 79:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.INITIAL;
this.scriptEnded(cursor - 8);
return cursor;
}
case 81:
yych = this._charAt(++cursor);
if (yych == 'L') { gotoCase = 82; continue; };
if (yych != 'l') { gotoCase = 43; continue; };
case 82:
yych = this._charAt(++cursor);
if (yych == 'E') { gotoCase = 83; continue; };
if (yych != 'e') { gotoCase = 43; continue; };
case 83:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.INITIAL;
this.styleSheetEnded(cursor - 7);
return cursor;
}

case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 89; continue; };
{ gotoCase = 88; continue; };
} else {
if (yych <= '\r') { gotoCase = 89; continue; };
if (yych == '\'') { gotoCase = 91; continue; };
{ gotoCase = 88; continue; };
}
case 87:
{ return this._stringToken(cursor); }
case 88:
yych = this._charAt(++cursor);
{ gotoCase = 95; continue; };
case 89:
++cursor;
{ this.tokenType = null; return cursor; }
case 91:
++cursor;
case 92:
this.setLexCondition(this._lexConditions.TAG);
{ return this._stringToken(cursor, true); }
case 93:
yych = this._charAt(++cursor);
{ gotoCase = 92; continue; };
case 94:
++cursor;
yych = this._charAt(cursor);
case 95:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 87; continue; };
{ gotoCase = 94; continue; };
} else {
if (yych <= '\r') { gotoCase = 87; continue; };
if (yych == '\'') { gotoCase = 93; continue; };
{ gotoCase = 94; continue; };
}

case this.case_TAG:
yych = this._charAt(cursor);
if (yych <= '&') {
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 100; continue; };
if (yych >= '\r') { gotoCase = 100; continue; };
} else {
if (yych <= ' ') {
if (yych >= ' ') { gotoCase = 100; continue; };
} else {
if (yych == '"') { gotoCase = 102; continue; };
}
}
} else {
if (yych <= '>') {
if (yych <= ';') {
if (yych <= '\'') { gotoCase = 103; continue; };
} else {
if (yych <= '<') { gotoCase = 100; continue; };
if (yych <= '=') { gotoCase = 104; continue; };
{ gotoCase = 106; continue; };
}
} else {
if (yych <= '[') {
if (yych >= '[') { gotoCase = 100; continue; };
} else {
if (yych == ']') { gotoCase = 100; continue; };
}
}
}
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 119; continue; };
case 99:
{
if (this._condition.parseCondition === this._parseConditions.SCRIPT || this._condition.parseCondition === this._parseConditions.STYLE) {

this.tokenType = null;
return cursor;
}

if (this._condition.parseCondition === this._parseConditions.INITIAL) {
this.tokenType = "html-tag";
this._setExpectingAttribute();
var token = this._line.substring(cursorOnEnter, cursor);
if (token === "a")
this._condition.parseCondition |= this._parseConditions.A_NODE;
else if (this._condition.parseCondition & this._parseConditions.A_NODE)
this._condition.parseCondition ^= this._parseConditions.A_NODE;
} else if (this._isExpectingAttribute()) {
var token = this._line.substring(cursorOnEnter, cursor);
if (token === "href" || token === "src")
this._condition.parseCondition |= this._parseConditions.LINKIFY;
else if (this._condition.parseCondition |= this._parseConditions.LINKIFY)
this._condition.parseCondition ^= this._parseConditions.LINKIFY;
this.tokenType = "html-attribute-name";
} else if (this._isExpectingAttributeValue())
this.tokenType = this._attrValueTokenType();
else
this.tokenType = null;
return cursor;
}
case 100:
++cursor;
{ this.tokenType = null; return cursor; }
case 102:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 115; continue; };
case 103:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 109; continue; };
case 104:
++cursor;
{
if (this._isExpectingAttribute())
this._setExpectingAttributeValue();
this.tokenType = null;
return cursor;
}
case 106:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{
this.tokenType = "html-tag";
if (this._condition.parseCondition & this._parseConditions.SCRIPT) {
this.scriptStarted(cursor);

return cursor;
}

if (this._condition.parseCondition & this._parseConditions.STYLE) {
this.styleSheetStarted(cursor);

return cursor;
}

this._condition.parseCondition = this._parseConditions.INITIAL;
return cursor;
}
case 108:
++cursor;
yych = this._charAt(cursor);
case 109:
if (yych <= '\f') {
if (yych != '\n') { gotoCase = 108; continue; };
} else {
if (yych <= '\r') { gotoCase = 110; continue; };
if (yych == '\'') { gotoCase = 112; continue; };
{ gotoCase = 108; continue; };
}
case 110:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ return this._stringToken(cursor); }
case 112:
++cursor;
{ return this._stringToken(cursor, true); }
case 114:
++cursor;
yych = this._charAt(cursor);
case 115:
if (yych <= '\f') {
if (yych != '\n') { gotoCase = 114; continue; };
} else {
if (yych <= '\r') { gotoCase = 116; continue; };
if (yych == '"') { gotoCase = 112; continue; };
{ gotoCase = 114; continue; };
}
case 116:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ return this._stringToken(cursor); }
case 118:
++cursor;
yych = this._charAt(cursor);
case 119:
if (yych <= '"') {
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 99; continue; };
if (yych <= '\f') { gotoCase = 118; continue; };
{ gotoCase = 99; continue; };
} else {
if (yych == ' ') { gotoCase = 99; continue; };
if (yych <= '!') { gotoCase = 118; continue; };
{ gotoCase = 99; continue; };
}
} else {
if (yych <= '>') {
if (yych == '\'') { gotoCase = 99; continue; };
if (yych <= ';') { gotoCase = 118; continue; };
{ gotoCase = 99; continue; };
} else {
if (yych <= '[') {
if (yych <= 'Z') { gotoCase = 118; continue; };
{ gotoCase = 99; continue; };
} else {
if (yych == ']') { gotoCase = 99; continue; };
{ gotoCase = 118; continue; };
}
}
}
}

}
}
}

WebInspector.SourceHTMLTokenizer.prototype.__proto__ = WebInspector.SourceTokenizer.prototype;









WebInspector.SourceJavaScriptTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);

this._lexConditions = {
DIV: 0,
NODIV: 1,
COMMENT: 2,
DSTRING: 3,
SSTRING: 4,
REGEX: 5
};

this.case_DIV = 1000;
this.case_NODIV = 1001;
this.case_COMMENT = 1002;
this.case_DSTRING = 1003;
this.case_SSTRING = 1004;
this.case_REGEX = 1005;

this.condition = this.createInitialCondition();
}

WebInspector.SourceJavaScriptTokenizer.Keywords = [
"null", "true", "false", "break", "case", "catch", "const", "default", "finally", "for",
"instanceof", "new", "var", "continue", "function", "return", "void", "delete", "if",
"this", "do", "while", "else", "in", "switch", "throw", "try", "typeof", "debugger",
"class", "enum", "export", "extends", "import", "super", "get", "set", "with"
].keySet();

WebInspector.SourceJavaScriptTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.NODIV };
},

nextToken: function(cursor)
{
var cursorOnEnter = cursor;
var gotoCase = 1;
var YYMARKER;
while (1) {
switch (gotoCase)


{
case 1: var yych;
var yyaccept = 0;
if (this.getLexCondition() < 3) {
if (this.getLexCondition() < 1) {
{ gotoCase = this.case_DIV; continue; };
} else {
if (this.getLexCondition() < 2) {
{ gotoCase = this.case_NODIV; continue; };
} else {
{ gotoCase = this.case_COMMENT; continue; };
}
}
} else {
if (this.getLexCondition() < 4) {
{ gotoCase = this.case_DSTRING; continue; };
} else {
if (this.getLexCondition() < 5) {
{ gotoCase = this.case_SSTRING; continue; };
} else {
{ gotoCase = this.case_REGEX; continue; };
}
}
}

case this.case_COMMENT:

yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 4; continue; };
{ gotoCase = 3; continue; };
} else {
if (yych <= '\r') { gotoCase = 4; continue; };
if (yych == '*') { gotoCase = 6; continue; };
{ gotoCase = 3; continue; };
}
case 2:
{ this.tokenType = "javascript-comment"; return cursor; }
case 3:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 12; continue; };
case 4:
++cursor;
{ this.tokenType = null; return cursor; }
case 6:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych != '/') { gotoCase = 11; continue; };
case 7:
++cursor;
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-comment"; return cursor; }
case 9:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych == '/') { gotoCase = 7; continue; };
case 11:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 12:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 2; continue; };
{ gotoCase = 11; continue; };
} else {
if (yych <= '\r') { gotoCase = 2; continue; };
if (yych == '*') { gotoCase = 9; continue; };
{ gotoCase = 11; continue; };
}

case this.case_DIV:
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych <= '(') {
if (yych <= '#') {
if (yych <= ' ') { gotoCase = 15; continue; };
if (yych <= '!') { gotoCase = 17; continue; };
if (yych <= '"') { gotoCase = 19; continue; };
} else {
if (yych <= '%') {
if (yych <= '$') { gotoCase = 20; continue; };
{ gotoCase = 22; continue; };
} else {
if (yych <= '&') { gotoCase = 23; continue; };
if (yych <= '\'') { gotoCase = 24; continue; };
{ gotoCase = 25; continue; };
}
}
} else {
if (yych <= ',') {
if (yych <= ')') { gotoCase = 26; continue; };
if (yych <= '*') { gotoCase = 28; continue; };
if (yych <= '+') { gotoCase = 29; continue; };
{ gotoCase = 25; continue; };
} else {
if (yych <= '.') {
if (yych <= '-') { gotoCase = 30; continue; };
{ gotoCase = 31; continue; };
} else {
if (yych <= '/') { gotoCase = 32; continue; };
if (yych <= '0') { gotoCase = 34; continue; };
{ gotoCase = 36; continue; };
}
}
}
} else {
if (yych <= '\\') {
if (yych <= '>') {
if (yych <= ';') { gotoCase = 25; continue; };
if (yych <= '<') { gotoCase = 37; continue; };
if (yych <= '=') { gotoCase = 38; continue; };
{ gotoCase = 39; continue; };
} else {
if (yych <= '@') {
if (yych <= '?') { gotoCase = 25; continue; };
} else {
if (yych <= 'Z') { gotoCase = 20; continue; };
if (yych <= '[') { gotoCase = 25; continue; };
{ gotoCase = 40; continue; };
}
}
} else {
if (yych <= 'z') {
if (yych <= '^') {
if (yych <= ']') { gotoCase = 25; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych != '`') { gotoCase = 20; continue; };
}
} else {
if (yych <= '|') {
if (yych <= '{') { gotoCase = 25; continue; };
{ gotoCase = 42; continue; };
} else {
if (yych <= '~') { gotoCase = 25; continue; };
if (yych >= 0x80) { gotoCase = 20; continue; };
}
}
}
}
case 15:
++cursor;
case 16:
{ this.tokenType = null; return cursor; }
case 17:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 115; continue; };
case 18:
this.setLexCondition(this._lexConditions.NODIV);
{
var token = this._line.charAt(cursorOnEnter);
if (token === "{")
this.tokenType = "block-start";
else if (token === "}")
this.tokenType = "block-end";
else this.tokenType = null;
return cursor;
}
case 19:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 16; continue; };
if (yych == '\r') { gotoCase = 16; continue; };
{ gotoCase = 107; continue; };
case 20:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 50; continue; };
case 21:
{
var token = this._line.substring(cursorOnEnter, cursor);
if (WebInspector.SourceJavaScriptTokenizer.Keywords[token] === true && token !== "__proto__")
this.tokenType = "javascript-keyword";
else
this.tokenType = "javascript-ident";
return cursor;
}
case 22:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 23:
yych = this._charAt(++cursor);
if (yych == '&') { gotoCase = 43; continue; };
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 24:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 16; continue; };
if (yych == '\r') { gotoCase = 16; continue; };
{ gotoCase = 96; continue; };
case 25:
yych = this._charAt(++cursor);
{ gotoCase = 18; continue; };
case 26:
++cursor;
{ this.tokenType = null; return cursor; }
case 28:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 29:
yych = this._charAt(++cursor);
if (yych == '+') { gotoCase = 43; continue; };
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 30:
yych = this._charAt(++cursor);
if (yych == '-') { gotoCase = 43; continue; };
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 31:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 18; continue; };
if (yych <= '9') { gotoCase = 89; continue; };
{ gotoCase = 18; continue; };
case 32:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '.') {
if (yych == '*') { gotoCase = 78; continue; };
} else {
if (yych <= '/') { gotoCase = 80; continue; };
if (yych == '=') { gotoCase = 77; continue; };
}
case 33:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = null; return cursor; }
case 34:
yyaccept = 3;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'E') {
if (yych <= '/') {
if (yych == '.') { gotoCase = 63; continue; };
} else {
if (yych <= '7') { gotoCase = 72; continue; };
if (yych >= 'E') { gotoCase = 62; continue; };
}
} else {
if (yych <= 'd') {
if (yych == 'X') { gotoCase = 74; continue; };
} else {
if (yych <= 'e') { gotoCase = 62; continue; };
if (yych == 'x') { gotoCase = 74; continue; };
}
}
case 35:
{ this.tokenType = "javascript-number"; return cursor; }
case 36:
yyaccept = 3;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 63; continue; };
if (yych <= '/') { gotoCase = 35; continue; };
{ gotoCase = 60; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 35; continue; };
{ gotoCase = 62; continue; };
} else {
if (yych == 'e') { gotoCase = 62; continue; };
{ gotoCase = 35; continue; };
}
}
case 37:
yych = this._charAt(++cursor);
if (yych <= ';') { gotoCase = 18; continue; };
if (yych <= '<') { gotoCase = 59; continue; };
if (yych <= '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 38:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 58; continue; };
{ gotoCase = 18; continue; };
case 39:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 18; continue; };
if (yych <= '=') { gotoCase = 43; continue; };
if (yych <= '>') { gotoCase = 56; continue; };
{ gotoCase = 18; continue; };
case 40:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == 'u') { gotoCase = 44; continue; };
{ gotoCase = 16; continue; };
case 41:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 42:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
if (yych != '|') { gotoCase = 18; continue; };
case 43:
yych = this._charAt(++cursor);
{ gotoCase = 18; continue; };
case 44:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 46; continue; };
} else {
if (yych <= 'F') { gotoCase = 46; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 46; continue; };
}
case 45:
cursor = YYMARKER;
if (yyaccept <= 1) {
if (yyaccept <= 0) {
{ gotoCase = 16; continue; };
} else {
{ gotoCase = 21; continue; };
}
} else {
if (yyaccept <= 2) {
{ gotoCase = 33; continue; };
} else {
{ gotoCase = 35; continue; };
}
}
case 46:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 47; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 47:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 48; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 48:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 49; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 49:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 50:
if (yych <= '[') {
if (yych <= '/') {
if (yych == '$') { gotoCase = 49; continue; };
{ gotoCase = 21; continue; };
} else {
if (yych <= '9') { gotoCase = 49; continue; };
if (yych <= '@') { gotoCase = 21; continue; };
if (yych <= 'Z') { gotoCase = 49; continue; };
{ gotoCase = 21; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '\\') { gotoCase = 51; continue; };
if (yych <= '^') { gotoCase = 21; continue; };
{ gotoCase = 49; continue; };
} else {
if (yych <= '`') { gotoCase = 21; continue; };
if (yych <= 'z') { gotoCase = 49; continue; };
if (yych <= String.fromCharCode(0x7F)) { gotoCase = 21; continue; };
{ gotoCase = 49; continue; };
}
}
case 51:
++cursor;
yych = this._charAt(cursor);
if (yych != 'u') { gotoCase = 45; continue; };
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 53; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 53:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 54; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 54:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 55; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 55:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 49; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 49; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 49; continue; };
{ gotoCase = 45; continue; };
}
case 56:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 18; continue; };
if (yych <= '=') { gotoCase = 43; continue; };
if (yych >= '?') { gotoCase = 18; continue; };
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 58:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 59:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };
case 60:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 63; continue; };
if (yych <= '/') { gotoCase = 35; continue; };
{ gotoCase = 60; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 35; continue; };
} else {
if (yych != 'e') { gotoCase = 35; continue; };
}
}
case 62:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych == '+') { gotoCase = 69; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= '-') { gotoCase = 69; continue; };
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
{ gotoCase = 45; continue; };
}
case 63:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 63; continue; };
{ gotoCase = 35; continue; };
} else {
if (yych <= 'E') { gotoCase = 65; continue; };
if (yych != 'e') { gotoCase = 35; continue; };
}
case 65:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 45; continue; };
} else {
if (yych <= '-') { gotoCase = 66; continue; };
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 67; continue; };
{ gotoCase = 45; continue; };
}
case 66:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
case 67:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 67; continue; };
{ gotoCase = 35; continue; };
case 69:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
case 70:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
{ gotoCase = 35; continue; };
case 72:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '7') { gotoCase = 72; continue; };
{ gotoCase = 35; continue; };
case 74:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 75; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 75:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 75; continue; };
{ gotoCase = 35; continue; };
} else {
if (yych <= 'F') { gotoCase = 75; continue; };
if (yych <= '`') { gotoCase = 35; continue; };
if (yych <= 'f') { gotoCase = 75; continue; };
{ gotoCase = 35; continue; };
}
case 77:
yych = this._charAt(++cursor);
{ gotoCase = 33; continue; };
case 78:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 85; continue; };
{ gotoCase = 78; continue; };
} else {
if (yych <= '\r') { gotoCase = 85; continue; };
if (yych == '*') { gotoCase = 83; continue; };
{ gotoCase = 78; continue; };
}
case 80:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 82; continue; };
if (yych != '\r') { gotoCase = 80; continue; };
case 82:
{ this.tokenType = "javascript-comment"; return cursor; }
case 83:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 83; continue; };
if (yych == '/') { gotoCase = 87; continue; };
{ gotoCase = 78; continue; };
case 85:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "javascript-comment"; return cursor; }
case 87:
++cursor;
{ this.tokenType = "javascript-comment"; return cursor; }
case 89:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 89; continue; };
{ gotoCase = 35; continue; };
} else {
if (yych <= 'E') { gotoCase = 91; continue; };
if (yych != 'e') { gotoCase = 35; continue; };
}
case 91:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 45; continue; };
} else {
if (yych <= '-') { gotoCase = 92; continue; };
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 93; continue; };
{ gotoCase = 45; continue; };
}
case 92:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
case 93:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 35; continue; };
if (yych <= '9') { gotoCase = 93; continue; };
{ gotoCase = 35; continue; };
case 95:
++cursor;
yych = this._charAt(cursor);
case 96:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 45; continue; };
if (yych <= '\f') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 95; continue; };
{ gotoCase = 98; continue; };
} else {
if (yych != '\\') { gotoCase = 95; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 45; continue; };
{ gotoCase = 101; continue; };
} else {
if (yych == '\r') { gotoCase = 101; continue; };
{ gotoCase = 45; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 95; continue; };
if (yych <= '&') { gotoCase = 45; continue; };
{ gotoCase = 95; continue; };
} else {
if (yych == '\\') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 95; continue; };
if (yych <= 'e') { gotoCase = 45; continue; };
{ gotoCase = 95; continue; };
} else {
if (yych == 'n') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 45; continue; };
{ gotoCase = 95; continue; };
} else {
if (yych <= 'u') { gotoCase = 100; continue; };
if (yych <= 'v') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
}
}
}
case 98:
++cursor;
{ this.tokenType = "javascript-string"; return cursor; }
case 100:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 103; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 103; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 103; continue; };
{ gotoCase = 45; continue; };
}
case 101:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 103:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 104; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 104:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 105; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 105:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 95; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 95; continue; };
{ gotoCase = 45; continue; };
}
case 106:
++cursor;
yych = this._charAt(cursor);
case 107:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 45; continue; };
if (yych <= '\f') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 106; continue; };
{ gotoCase = 98; continue; };
} else {
if (yych != '\\') { gotoCase = 106; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 45; continue; };
{ gotoCase = 110; continue; };
} else {
if (yych == '\r') { gotoCase = 110; continue; };
{ gotoCase = 45; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 106; continue; };
if (yych <= '&') { gotoCase = 45; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych == '\\') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 106; continue; };
if (yych <= 'e') { gotoCase = 45; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych == 'n') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 45; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych <= 'u') { gotoCase = 109; continue; };
if (yych <= 'v') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
}
}
}
case 109:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 112; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 112; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 112; continue; };
{ gotoCase = 45; continue; };
}
case 110:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 112:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 113; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 113:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych >= ':') { gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 114; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych >= 'g') { gotoCase = 45; continue; };
}
case 114:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 45; continue; };
if (yych <= '9') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
} else {
if (yych <= 'F') { gotoCase = 106; continue; };
if (yych <= '`') { gotoCase = 45; continue; };
if (yych <= 'f') { gotoCase = 106; continue; };
{ gotoCase = 45; continue; };
}
case 115:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 43; continue; };
{ gotoCase = 18; continue; };

case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 120; continue; };
if (yych <= '\f') { gotoCase = 119; continue; };
{ gotoCase = 120; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 119; continue; };
{ gotoCase = 122; continue; };
} else {
if (yych == '\\') { gotoCase = 124; continue; };
{ gotoCase = 119; continue; };
}
}
case 118:
{ this.tokenType = "javascript-string"; return cursor; }
case 119:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 126; continue; };
case 120:
++cursor;
case 121:
{ this.tokenType = null; return cursor; }
case 122:
++cursor;
case 123:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-string"; return cursor; }
case 124:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 125; continue; };
if (yych <= '&') { gotoCase = 121; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 121; continue; };
} else {
if (yych != 'b') { gotoCase = 121; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 121; continue; };
} else {
if (yych <= 'n') { gotoCase = 125; continue; };
if (yych <= 'q') { gotoCase = 121; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 121; continue; };
} else {
if (yych <= 'u') { gotoCase = 127; continue; };
if (yych >= 'w') { gotoCase = 121; continue; };
}
}
}
case 125:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 126:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 118; continue; };
if (yych <= '\f') { gotoCase = 125; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 125; continue; };
{ gotoCase = 133; continue; };
} else {
if (yych == '\\') { gotoCase = 132; continue; };
{ gotoCase = 125; continue; };
}
}
case 127:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 128; continue; };
if (yych <= '9') { gotoCase = 129; continue; };
} else {
if (yych <= 'F') { gotoCase = 129; continue; };
if (yych <= '`') { gotoCase = 128; continue; };
if (yych <= 'f') { gotoCase = 129; continue; };
}
case 128:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 118; continue; };
} else {
{ gotoCase = 121; continue; };
}
case 129:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 128; continue; };
if (yych >= ':') { gotoCase = 128; continue; };
} else {
if (yych <= 'F') { gotoCase = 130; continue; };
if (yych <= '`') { gotoCase = 128; continue; };
if (yych >= 'g') { gotoCase = 128; continue; };
}
case 130:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 128; continue; };
if (yych >= ':') { gotoCase = 128; continue; };
} else {
if (yych <= 'F') { gotoCase = 131; continue; };
if (yych <= '`') { gotoCase = 128; continue; };
if (yych >= 'g') { gotoCase = 128; continue; };
}
case 131:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 128; continue; };
if (yych <= '9') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
} else {
if (yych <= 'F') { gotoCase = 125; continue; };
if (yych <= '`') { gotoCase = 128; continue; };
if (yych <= 'f') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
}
case 132:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 125; continue; };
if (yych <= '&') { gotoCase = 128; continue; };
{ gotoCase = 125; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 128; continue; };
{ gotoCase = 125; continue; };
} else {
if (yych == 'b') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
} else {
if (yych <= 'n') { gotoCase = 125; continue; };
if (yych <= 'q') { gotoCase = 128; continue; };
{ gotoCase = 125; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 128; continue; };
{ gotoCase = 125; continue; };
} else {
if (yych <= 'u') { gotoCase = 127; continue; };
if (yych <= 'v') { gotoCase = 125; continue; };
{ gotoCase = 128; continue; };
}
}
}
case 133:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 123; continue; };

case this.case_NODIV:
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych <= '(') {
if (yych <= '#') {
if (yych <= ' ') { gotoCase = 136; continue; };
if (yych <= '!') { gotoCase = 138; continue; };
if (yych <= '"') { gotoCase = 140; continue; };
} else {
if (yych <= '%') {
if (yych <= '$') { gotoCase = 141; continue; };
{ gotoCase = 143; continue; };
} else {
if (yych <= '&') { gotoCase = 144; continue; };
if (yych <= '\'') { gotoCase = 145; continue; };
{ gotoCase = 146; continue; };
}
}
} else {
if (yych <= ',') {
if (yych <= ')') { gotoCase = 147; continue; };
if (yych <= '*') { gotoCase = 149; continue; };
if (yych <= '+') { gotoCase = 150; continue; };
{ gotoCase = 146; continue; };
} else {
if (yych <= '.') {
if (yych <= '-') { gotoCase = 151; continue; };
{ gotoCase = 152; continue; };
} else {
if (yych <= '/') { gotoCase = 153; continue; };
if (yych <= '0') { gotoCase = 154; continue; };
{ gotoCase = 156; continue; };
}
}
}
} else {
if (yych <= '\\') {
if (yych <= '>') {
if (yych <= ';') { gotoCase = 146; continue; };
if (yych <= '<') { gotoCase = 157; continue; };
if (yych <= '=') { gotoCase = 158; continue; };
{ gotoCase = 159; continue; };
} else {
if (yych <= '@') {
if (yych <= '?') { gotoCase = 146; continue; };
} else {
if (yych <= 'Z') { gotoCase = 141; continue; };
if (yych <= '[') { gotoCase = 146; continue; };
{ gotoCase = 160; continue; };
}
}
} else {
if (yych <= 'z') {
if (yych <= '^') {
if (yych <= ']') { gotoCase = 146; continue; };
{ gotoCase = 161; continue; };
} else {
if (yych != '`') { gotoCase = 141; continue; };
}
} else {
if (yych <= '|') {
if (yych <= '{') { gotoCase = 146; continue; };
{ gotoCase = 162; continue; };
} else {
if (yych <= '~') { gotoCase = 146; continue; };
if (yych >= 0x80) { gotoCase = 141; continue; };
}
}
}
}
case 136:
++cursor;
case 137:
{ this.tokenType = null; return cursor; }
case 138:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 260; continue; };
case 139:
{
var token = this._line.charAt(cursorOnEnter);
if (token === "{")
this.tokenType = "block-start";
else if (token === "}")
this.tokenType = "block-end";
else this.tokenType = null;
return cursor;
}
case 140:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 137; continue; };
if (yych == '\r') { gotoCase = 137; continue; };
{ gotoCase = 252; continue; };
case 141:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 170; continue; };
case 142:
this.setLexCondition(this._lexConditions.DIV);
{
var token = this._line.substring(cursorOnEnter, cursor);
if (WebInspector.SourceJavaScriptTokenizer.Keywords[token] === true && token !== "__proto__")
this.tokenType = "javascript-keyword";
else
this.tokenType = "javascript-ident";
return cursor;
}
case 143:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 144:
yych = this._charAt(++cursor);
if (yych == '&') { gotoCase = 163; continue; };
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 145:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '\n') { gotoCase = 137; continue; };
if (yych == '\r') { gotoCase = 137; continue; };
{ gotoCase = 241; continue; };
case 146:
yych = this._charAt(++cursor);
{ gotoCase = 139; continue; };
case 147:
++cursor;
this.setLexCondition(this._lexConditions.DIV);
{ this.tokenType = null; return cursor; }
case 149:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 150:
yych = this._charAt(++cursor);
if (yych == '+') { gotoCase = 163; continue; };
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 151:
yych = this._charAt(++cursor);
if (yych == '-') { gotoCase = 163; continue; };
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 152:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 139; continue; };
if (yych <= '9') { gotoCase = 234; continue; };
{ gotoCase = 139; continue; };
case 153:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 137; continue; };
{ gotoCase = 197; continue; };
} else {
if (yych <= '\r') { gotoCase = 137; continue; };
if (yych <= ')') { gotoCase = 197; continue; };
{ gotoCase = 202; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 204; continue; };
{ gotoCase = 197; continue; };
} else {
if (yych <= '[') { gotoCase = 200; continue; };
if (yych <= '\\') { gotoCase = 199; continue; };
if (yych <= ']') { gotoCase = 137; continue; };
{ gotoCase = 197; continue; };
}
}
case 154:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'E') {
if (yych <= '/') {
if (yych == '.') { gotoCase = 183; continue; };
} else {
if (yych <= '7') { gotoCase = 192; continue; };
if (yych >= 'E') { gotoCase = 182; continue; };
}
} else {
if (yych <= 'd') {
if (yych == 'X') { gotoCase = 194; continue; };
} else {
if (yych <= 'e') { gotoCase = 182; continue; };
if (yych == 'x') { gotoCase = 194; continue; };
}
}
case 155:
this.setLexCondition(this._lexConditions.DIV);
{ this.tokenType = "javascript-number"; return cursor; }
case 156:
yyaccept = 2;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 183; continue; };
if (yych <= '/') { gotoCase = 155; continue; };
{ gotoCase = 180; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 155; continue; };
{ gotoCase = 182; continue; };
} else {
if (yych == 'e') { gotoCase = 182; continue; };
{ gotoCase = 155; continue; };
}
}
case 157:
yych = this._charAt(++cursor);
if (yych <= ';') { gotoCase = 139; continue; };
if (yych <= '<') { gotoCase = 179; continue; };
if (yych <= '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 158:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 178; continue; };
{ gotoCase = 139; continue; };
case 159:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 139; continue; };
if (yych <= '=') { gotoCase = 163; continue; };
if (yych <= '>') { gotoCase = 176; continue; };
{ gotoCase = 139; continue; };
case 160:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == 'u') { gotoCase = 164; continue; };
{ gotoCase = 137; continue; };
case 161:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 162:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
if (yych != '|') { gotoCase = 139; continue; };
case 163:
yych = this._charAt(++cursor);
{ gotoCase = 139; continue; };
case 164:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 166; continue; };
} else {
if (yych <= 'F') { gotoCase = 166; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 166; continue; };
}
case 165:
cursor = YYMARKER;
if (yyaccept <= 1) {
if (yyaccept <= 0) {
{ gotoCase = 137; continue; };
} else {
{ gotoCase = 142; continue; };
}
} else {
if (yyaccept <= 2) {
{ gotoCase = 155; continue; };
} else {
{ gotoCase = 217; continue; };
}
}
case 166:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 167; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 167:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 168; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 168:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 169; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 169:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 170:
if (yych <= '[') {
if (yych <= '/') {
if (yych == '$') { gotoCase = 169; continue; };
{ gotoCase = 142; continue; };
} else {
if (yych <= '9') { gotoCase = 169; continue; };
if (yych <= '@') { gotoCase = 142; continue; };
if (yych <= 'Z') { gotoCase = 169; continue; };
{ gotoCase = 142; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '\\') { gotoCase = 171; continue; };
if (yych <= '^') { gotoCase = 142; continue; };
{ gotoCase = 169; continue; };
} else {
if (yych <= '`') { gotoCase = 142; continue; };
if (yych <= 'z') { gotoCase = 169; continue; };
if (yych <= String.fromCharCode(0x7F)) { gotoCase = 142; continue; };
{ gotoCase = 169; continue; };
}
}
case 171:
++cursor;
yych = this._charAt(cursor);
if (yych != 'u') { gotoCase = 165; continue; };
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 173; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 173:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 174; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 174:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 175; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 175:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 169; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 169; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 169; continue; };
{ gotoCase = 165; continue; };
}
case 176:
yych = this._charAt(++cursor);
if (yych <= '<') { gotoCase = 139; continue; };
if (yych <= '=') { gotoCase = 163; continue; };
if (yych >= '?') { gotoCase = 139; continue; };
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 178:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 179:
yych = this._charAt(++cursor);
if (yych == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };
case 180:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '9') {
if (yych == '.') { gotoCase = 183; continue; };
if (yych <= '/') { gotoCase = 155; continue; };
{ gotoCase = 180; continue; };
} else {
if (yych <= 'E') {
if (yych <= 'D') { gotoCase = 155; continue; };
} else {
if (yych != 'e') { gotoCase = 155; continue; };
}
}
case 182:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych == '+') { gotoCase = 189; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= '-') { gotoCase = 189; continue; };
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 190; continue; };
{ gotoCase = 165; continue; };
}
case 183:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 183; continue; };
{ gotoCase = 155; continue; };
} else {
if (yych <= 'E') { gotoCase = 185; continue; };
if (yych != 'e') { gotoCase = 155; continue; };
}
case 185:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 165; continue; };
} else {
if (yych <= '-') { gotoCase = 186; continue; };
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 187; continue; };
{ gotoCase = 165; continue; };
}
case 186:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
case 187:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 187; continue; };
{ gotoCase = 155; continue; };
case 189:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
case 190:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 190; continue; };
{ gotoCase = 155; continue; };
case 192:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '7') { gotoCase = 192; continue; };
{ gotoCase = 155; continue; };
case 194:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 195; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 195:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 195; continue; };
{ gotoCase = 155; continue; };
} else {
if (yych <= 'F') { gotoCase = 195; continue; };
if (yych <= '`') { gotoCase = 155; continue; };
if (yych <= 'f') { gotoCase = 195; continue; };
{ gotoCase = 155; continue; };
}
case 197:
++cursor;
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 197; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 197; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 220; continue; };
if (yych <= 'Z') { gotoCase = 197; continue; };
{ gotoCase = 228; continue; };
} else {
if (yych <= '\\') { gotoCase = 227; continue; };
if (yych <= ']') { gotoCase = 165; continue; };
{ gotoCase = 197; continue; };
}
}
case 199:
yych = this._charAt(++cursor);
if (yych == '\n') { gotoCase = 165; continue; };
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 197; continue; };
case 200:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 200; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 200; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 165; continue; };
{ gotoCase = 200; continue; };
} else {
if (yych <= '\\') { gotoCase = 215; continue; };
if (yych <= ']') { gotoCase = 213; continue; };
{ gotoCase = 200; continue; };
}
}
case 202:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 209; continue; };
{ gotoCase = 202; continue; };
} else {
if (yych <= '\r') { gotoCase = 209; continue; };
if (yych == '*') { gotoCase = 207; continue; };
{ gotoCase = 202; continue; };
}
case 204:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 206; continue; };
if (yych != '\r') { gotoCase = 204; continue; };
case 206:
{ this.tokenType = "javascript-comment"; return cursor; }
case 207:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 207; continue; };
if (yych == '/') { gotoCase = 211; continue; };
{ gotoCase = 202; continue; };
case 209:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "javascript-comment"; return cursor; }
case 211:
++cursor;
{ this.tokenType = "javascript-comment"; return cursor; }
case 213:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 213; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 213; continue; };
{ gotoCase = 197; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 220; continue; };
{ gotoCase = 213; continue; };
} else {
if (yych <= '[') { gotoCase = 218; continue; };
if (yych <= '\\') { gotoCase = 216; continue; };
{ gotoCase = 213; continue; };
}
}
case 215:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 165; continue; };
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 200; continue; };
case 216:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 217; continue; };
if (yych != '\r') { gotoCase = 213; continue; };
case 217:
this.setLexCondition(this._lexConditions.REGEX);
{ this.tokenType = "javascript-regexp"; return cursor; }
case 218:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 218; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 218; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 165; continue; };
{ gotoCase = 218; continue; };
} else {
if (yych <= '\\') { gotoCase = 225; continue; };
if (yych <= ']') { gotoCase = 223; continue; };
{ gotoCase = 218; continue; };
}
}
case 220:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'h') {
if (yych == 'g') { gotoCase = 220; continue; };
} else {
if (yych <= 'i') { gotoCase = 220; continue; };
if (yych == 'm') { gotoCase = 220; continue; };
}
{ this.tokenType = "javascript-regexp"; return cursor; }
case 223:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 223; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 223; continue; };
{ gotoCase = 197; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 220; continue; };
{ gotoCase = 223; continue; };
} else {
if (yych <= '[') { gotoCase = 218; continue; };
if (yych <= '\\') { gotoCase = 226; continue; };
{ gotoCase = 223; continue; };
}
}
case 225:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 165; continue; };
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 218; continue; };
case 226:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 217; continue; };
if (yych == '\r') { gotoCase = 217; continue; };
{ gotoCase = 223; continue; };
case 227:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 217; continue; };
if (yych == '\r') { gotoCase = 217; continue; };
{ gotoCase = 197; continue; };
case 228:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 228; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 228; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 165; continue; };
{ gotoCase = 228; continue; };
} else {
if (yych <= '\\') { gotoCase = 232; continue; };
if (yych >= '^') { gotoCase = 228; continue; };
}
}
case 230:
++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 165; continue; };
{ gotoCase = 230; continue; };
} else {
if (yych <= '\r') { gotoCase = 165; continue; };
if (yych <= ')') { gotoCase = 230; continue; };
{ gotoCase = 197; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 220; continue; };
{ gotoCase = 230; continue; };
} else {
if (yych <= '[') { gotoCase = 228; continue; };
if (yych <= '\\') { gotoCase = 233; continue; };
{ gotoCase = 230; continue; };
}
}
case 232:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 165; continue; };
if (yych == '\r') { gotoCase = 165; continue; };
{ gotoCase = 228; continue; };
case 233:
yyaccept = 3;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 217; continue; };
if (yych == '\r') { gotoCase = 217; continue; };
{ gotoCase = 230; continue; };
case 234:
yyaccept = 2;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'D') {
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 234; continue; };
{ gotoCase = 155; continue; };
} else {
if (yych <= 'E') { gotoCase = 236; continue; };
if (yych != 'e') { gotoCase = 155; continue; };
}
case 236:
yych = this._charAt(++cursor);
if (yych <= ',') {
if (yych != '+') { gotoCase = 165; continue; };
} else {
if (yych <= '-') { gotoCase = 237; continue; };
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 238; continue; };
{ gotoCase = 165; continue; };
}
case 237:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
case 238:
++cursor;
yych = this._charAt(cursor);
if (yych <= '/') { gotoCase = 155; continue; };
if (yych <= '9') { gotoCase = 238; continue; };
{ gotoCase = 155; continue; };
case 240:
++cursor;
yych = this._charAt(cursor);
case 241:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 165; continue; };
if (yych <= '\f') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 240; continue; };
{ gotoCase = 243; continue; };
} else {
if (yych != '\\') { gotoCase = 240; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 165; continue; };
{ gotoCase = 246; continue; };
} else {
if (yych == '\r') { gotoCase = 246; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 240; continue; };
if (yych <= '&') { gotoCase = 165; continue; };
{ gotoCase = 240; continue; };
} else {
if (yych == '\\') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 240; continue; };
if (yych <= 'e') { gotoCase = 165; continue; };
{ gotoCase = 240; continue; };
} else {
if (yych == 'n') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 165; continue; };
{ gotoCase = 240; continue; };
} else {
if (yych <= 'u') { gotoCase = 245; continue; };
if (yych <= 'v') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
}
}
}
case 243:
++cursor;
{ this.tokenType = "javascript-string"; return cursor; }
case 245:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 248; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 248; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 248; continue; };
{ gotoCase = 165; continue; };
}
case 246:
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 248:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 249; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 249:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 250; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 250:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 240; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 240; continue; };
{ gotoCase = 165; continue; };
}
case 251:
++cursor;
yych = this._charAt(cursor);
case 252:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 165; continue; };
if (yych <= '\f') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 251; continue; };
{ gotoCase = 243; continue; };
} else {
if (yych != '\\') { gotoCase = 251; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 165; continue; };
{ gotoCase = 255; continue; };
} else {
if (yych == '\r') { gotoCase = 255; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 251; continue; };
if (yych <= '&') { gotoCase = 165; continue; };
{ gotoCase = 251; continue; };
} else {
if (yych == '\\') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 251; continue; };
if (yych <= 'e') { gotoCase = 165; continue; };
{ gotoCase = 251; continue; };
} else {
if (yych == 'n') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 165; continue; };
{ gotoCase = 251; continue; };
} else {
if (yych <= 'u') { gotoCase = 254; continue; };
if (yych <= 'v') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
}
}
}
case 254:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 257; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 257; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 257; continue; };
{ gotoCase = 165; continue; };
}
case 255:
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ this.tokenType = "javascript-string"; return cursor; }
case 257:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 258; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 258:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych >= ':') { gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 259; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych >= 'g') { gotoCase = 165; continue; };
}
case 259:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 165; continue; };
if (yych <= '9') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
} else {
if (yych <= 'F') { gotoCase = 251; continue; };
if (yych <= '`') { gotoCase = 165; continue; };
if (yych <= 'f') { gotoCase = 251; continue; };
{ gotoCase = 165; continue; };
}
case 260:
++cursor;
if ((yych = this._charAt(cursor)) == '=') { gotoCase = 163; continue; };
{ gotoCase = 139; continue; };

case this.case_REGEX:
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 264; continue; };
{ gotoCase = 265; continue; };
} else {
if (yych == '\r') { gotoCase = 265; continue; };
{ gotoCase = 264; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 267; continue; };
if (yych <= 'Z') { gotoCase = 264; continue; };
{ gotoCase = 269; continue; };
} else {
if (yych <= '\\') { gotoCase = 270; continue; };
if (yych <= ']') { gotoCase = 265; continue; };
{ gotoCase = 264; continue; };
}
}
case 263:
{ this.tokenType = "javascript-regexp"; return cursor; }
case 264:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 272; continue; };
case 265:
++cursor;
case 266:
{ this.tokenType = null; return cursor; }
case 267:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 278; continue; };
case 268:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-regexp"; return cursor; }
case 269:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 266; continue; };
if (yych <= '\f') { gotoCase = 276; continue; };
{ gotoCase = 266; continue; };
} else {
if (yych <= '*') {
if (yych <= ')') { gotoCase = 276; continue; };
{ gotoCase = 266; continue; };
} else {
if (yych == '/') { gotoCase = 266; continue; };
{ gotoCase = 276; continue; };
}
}
case 270:
yych = this._charAt(++cursor);
if (yych == '\n') { gotoCase = 266; continue; };
if (yych == '\r') { gotoCase = 266; continue; };
case 271:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 272:
if (yych <= '.') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 271; continue; };
{ gotoCase = 263; continue; };
} else {
if (yych == '\r') { gotoCase = 263; continue; };
{ gotoCase = 271; continue; };
}
} else {
if (yych <= '[') {
if (yych <= '/') { gotoCase = 277; continue; };
if (yych <= 'Z') { gotoCase = 271; continue; };
{ gotoCase = 275; continue; };
} else {
if (yych <= '\\') { gotoCase = 273; continue; };
if (yych <= ']') { gotoCase = 263; continue; };
{ gotoCase = 271; continue; };
}
}
case 273:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 274; continue; };
if (yych != '\r') { gotoCase = 271; continue; };
case 274:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 263; continue; };
} else {
{ gotoCase = 266; continue; };
}
case 275:
++cursor;
yych = this._charAt(cursor);
case 276:
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 274; continue; };
{ gotoCase = 275; continue; };
} else {
if (yych <= '\r') { gotoCase = 274; continue; };
if (yych <= ')') { gotoCase = 275; continue; };
{ gotoCase = 274; continue; };
}
} else {
if (yych <= '[') {
if (yych == '/') { gotoCase = 274; continue; };
{ gotoCase = 275; continue; };
} else {
if (yych <= '\\') { gotoCase = 281; continue; };
if (yych <= ']') { gotoCase = 279; continue; };
{ gotoCase = 275; continue; };
}
}
case 277:
++cursor;
yych = this._charAt(cursor);
case 278:
if (yych <= 'h') {
if (yych == 'g') { gotoCase = 277; continue; };
{ gotoCase = 268; continue; };
} else {
if (yych <= 'i') { gotoCase = 277; continue; };
if (yych == 'm') { gotoCase = 277; continue; };
{ gotoCase = 268; continue; };
}
case 279:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '*') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 263; continue; };
{ gotoCase = 279; continue; };
} else {
if (yych <= '\r') { gotoCase = 263; continue; };
if (yych <= ')') { gotoCase = 279; continue; };
{ gotoCase = 271; continue; };
}
} else {
if (yych <= 'Z') {
if (yych == '/') { gotoCase = 277; continue; };
{ gotoCase = 279; continue; };
} else {
if (yych <= '[') { gotoCase = 275; continue; };
if (yych <= '\\') { gotoCase = 282; continue; };
{ gotoCase = 279; continue; };
}
}
case 281:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 274; continue; };
if (yych == '\r') { gotoCase = 274; continue; };
{ gotoCase = 275; continue; };
case 282:
++cursor;
yych = this._charAt(cursor);
if (yych == '\n') { gotoCase = 274; continue; };
if (yych == '\r') { gotoCase = 274; continue; };
{ gotoCase = 279; continue; };

case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 287; continue; };
if (yych <= '\f') { gotoCase = 286; continue; };
{ gotoCase = 287; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 286; continue; };
{ gotoCase = 289; continue; };
} else {
if (yych == '\\') { gotoCase = 291; continue; };
{ gotoCase = 286; continue; };
}
}
case 285:
{ this.tokenType = "javascript-string"; return cursor; }
case 286:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 293; continue; };
case 287:
++cursor;
case 288:
{ this.tokenType = null; return cursor; }
case 289:
++cursor;
case 290:
this.setLexCondition(this._lexConditions.NODIV);
{ this.tokenType = "javascript-string"; return cursor; }
case 291:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 292; continue; };
if (yych <= '&') { gotoCase = 288; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 288; continue; };
} else {
if (yych != 'b') { gotoCase = 288; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 288; continue; };
} else {
if (yych <= 'n') { gotoCase = 292; continue; };
if (yych <= 'q') { gotoCase = 288; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 288; continue; };
} else {
if (yych <= 'u') { gotoCase = 294; continue; };
if (yych >= 'w') { gotoCase = 288; continue; };
}
}
}
case 292:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 293:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 285; continue; };
if (yych <= '\f') { gotoCase = 292; continue; };
{ gotoCase = 285; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 292; continue; };
{ gotoCase = 300; continue; };
} else {
if (yych == '\\') { gotoCase = 299; continue; };
{ gotoCase = 292; continue; };
}
}
case 294:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 295; continue; };
if (yych <= '9') { gotoCase = 296; continue; };
} else {
if (yych <= 'F') { gotoCase = 296; continue; };
if (yych <= '`') { gotoCase = 295; continue; };
if (yych <= 'f') { gotoCase = 296; continue; };
}
case 295:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 285; continue; };
} else {
{ gotoCase = 288; continue; };
}
case 296:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 295; continue; };
if (yych >= ':') { gotoCase = 295; continue; };
} else {
if (yych <= 'F') { gotoCase = 297; continue; };
if (yych <= '`') { gotoCase = 295; continue; };
if (yych >= 'g') { gotoCase = 295; continue; };
}
case 297:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 295; continue; };
if (yych >= ':') { gotoCase = 295; continue; };
} else {
if (yych <= 'F') { gotoCase = 298; continue; };
if (yych <= '`') { gotoCase = 295; continue; };
if (yych >= 'g') { gotoCase = 295; continue; };
}
case 298:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 295; continue; };
if (yych <= '9') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
} else {
if (yych <= 'F') { gotoCase = 292; continue; };
if (yych <= '`') { gotoCase = 295; continue; };
if (yych <= 'f') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
}
case 299:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 292; continue; };
if (yych <= '&') { gotoCase = 295; continue; };
{ gotoCase = 292; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 295; continue; };
{ gotoCase = 292; continue; };
} else {
if (yych == 'b') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
} else {
if (yych <= 'n') { gotoCase = 292; continue; };
if (yych <= 'q') { gotoCase = 295; continue; };
{ gotoCase = 292; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 295; continue; };
{ gotoCase = 292; continue; };
} else {
if (yych <= 'u') { gotoCase = 294; continue; };
if (yych <= 'v') { gotoCase = 292; continue; };
{ gotoCase = 295; continue; };
}
}
}
case 300:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 290; continue; };
}

}
}
}

WebInspector.SourceJavaScriptTokenizer.prototype.__proto__ = WebInspector.SourceTokenizer.prototype;






WebInspector.FileSystemModel = function()
{
WebInspector.Object.call(this);

this._originForFrameId = {};
this._frameIdsForOrigin = {};
this._fileSystemsForOrigin = {};

WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);

FileSystemAgent.enable();

if (WebInspector.resourceTreeModel.mainFrame)
this._attachFrameRecursively(WebInspector.resourceTreeModel.mainFrame);
}

WebInspector.FileSystemModel.prototype = {

_frameAdded: function(event)
{
var frame =   event.data;
this._attachFrameRecursively(frame);
},


_frameNavigated: function(event)
{
var frame =   event.data;
this._attachFrameRecursively(frame);
},


_frameDetached: function(event)
{
var frame =   event.data;
this._detachFrameRecursively(frame);
},


_attachFrame: function(frame)
{
if (this._originForFrameId[frame.id])
this._detachFrameRecursively(frame);

if (frame.securityOrigin === "null")
return;

this._originForFrameId[frame.id] = frame.securityOrigin;

var newOrigin = false;
if (!this._frameIdsForOrigin[frame.securityOrigin]) {
this._frameIdsForOrigin[frame.securityOrigin] = {};
newOrigin = true;
}
this._frameIdsForOrigin[frame.securityOrigin][frame.id] = frame.id;
if (newOrigin)
this._originAdded(frame.securityOrigin);
},


_attachFrameRecursively: function(frame)
{
this._attachFrame(frame);
for (var i = 0; i < frame.childFrames.length; ++i)
this._attachFrameRecursively(frame.childFrames[i]);
},


_detachFrame: function(frame)
{
if (!this._originForFrameId[frame.id])
return;
var origin = this._originForFrameId[frame.id];
delete this._originForFrameId[frame.id];
delete this._frameIdsForOrigin[origin][frame.id];

var lastOrigin = Object.isEmpty(this._frameIdsForOrigin[origin]);
if (lastOrigin) {
delete this._frameIdsForOrigin[origin];
this._originRemoved(origin);
}
},


_detachFrameRecursively: function(frame)
{
for (var i = 0; i < frame.childFrames.length; ++i)
this._detachFrameRecursively(frame.childFrames[i]);
this._detachFrame(frame);
},


_originAdded: function(origin)
{
this._fileSystemsForOrigin[origin] = {};

var types = ["persistent", "temporary"];
for (var i = 0; i < types.length; ++i)
this._requestFileSystemRoot(origin, types[i], this._fileSystemRootReceived.bind(this, origin, types[i], this._fileSystemsForOrigin[origin]));
},


_requestFileSystemRoot: function(origin, type, callback)
{

function innerCallback(error, errorCode, backendRootEntry)
{
if (error) {
callback(FileError.SECURITY_ERR);
return;
}

callback(errorCode, backendRootEntry);
}

FileSystemAgent.requestFileSystemRoot(origin, type, innerCallback.bind(this));
},


_originRemoved: function(origin)
{
for (var type in this._fileSystemsForOrigin[origin]) {
var fileSystem = this._fileSystemsForOrigin[origin][type];
delete this._fileSystemsForOrigin[origin][type];
this._fileSystemRemoved(fileSystem);
}
delete this._fileSystemsForOrigin[origin];
},


_fileSystemAdded: function(fileSystem)
{
this.dispatchEventToListeners(WebInspector.FileSystemModel.EventTypes.FileSystemAdded, fileSystem);
},


_fileSystemRemoved: function(fileSystem)
{
this.dispatchEventToListeners(WebInspector.FileSystemModel.EventTypes.FileSystemRemoved, fileSystem);
},

refreshFileSystemList: function()
{
if (WebInspector.resourceTreeModel.mainFrame) {
this._detachFrameRecursively(WebInspector.resourceTreeModel.mainFrame);
this._attachFrameRecursively(WebInspector.resourceTreeModel.mainFrame);
}
},


_fileSystemRootReceived: function(origin, type, store, errorCode, backendRootEntry)
{
if (!errorCode && backendRootEntry && this._fileSystemsForOrigin[origin] === store) {
var fileSystem = new WebInspector.FileSystemModel.FileSystem(this, origin, type, backendRootEntry);
store[type] = fileSystem;
this._fileSystemAdded(fileSystem);
}
},


requestDirectoryContent: function(directory, callback)
{
this._requestDirectoryContent(directory.url, this._directoryContentReceived.bind(this, directory, callback));
},


_requestDirectoryContent: function(url, callback)
{

function innerCallback(error, errorCode, backendEntries)
{
if (error) {
callback(FileError.SECURITY_ERR);
return;
}

if (errorCode !== 0) {
callback(errorCode, null);
return;
}

callback(errorCode, backendEntries);
}

FileSystemAgent.requestDirectoryContent(url, innerCallback.bind(this));
},


_directoryContentReceived: function(parentDirectory, callback, errorCode, backendEntries)
{
var entries = [];
for (var i = 0; i < backendEntries.length; ++i) {
if (backendEntries[i].isDirectory)
entries.push(new WebInspector.FileSystemModel.Directory(this, parentDirectory.fileSystem, backendEntries[i]));
else
entries.push(new WebInspector.FileSystemModel.File(this, parentDirectory.fileSystem, backendEntries[i]));
}

callback(errorCode, entries);
},


requestMetadata: function(entry, callback)
{

function innerCallback(error, errorCode, metadata)
{
if (error) {
callback(FileError.SECURITY_ERR);
return;
}

callback(errorCode, metadata);
}

FileSystemAgent.requestMetadata(entry.url, innerCallback.bind(this));
},


requestFileContent: function(file, readAsText, start, end, charset, callback)
{
this._requestFileContent(file.url, readAsText, start, end, charset, callback);
},


_requestFileContent: function(url, readAsText, start, end, charset, callback)
{

function innerCallback(error, errorCode, content, charset)
{
if (error) {
if (callback)
callback(FileError.SECURITY_ERR);
return;
}

if (callback)
callback(errorCode, content, charset);
}

FileSystemAgent.requestFileContent(url, readAsText, start, end, charset, innerCallback.bind(this));
},

deleteEntry: function(entry, callback)
{
var fileSystemModel = this;
if (entry === entry.fileSystem.root)
this._deleteEntry(entry.url, hookFileSystemDeletion);
else
this._deleteEntry(entry.url, callback);

function hookFileSystemDeletion(errorCode)
{
callback(errorCode);
if (!errorCode)
fileSystemModel._removeFileSystem(entry.fileSystem);
}
},


_deleteEntry: function(url, callback)
{

function innerCallback(error, errorCode)
{
if (error) {
if (callback)
callback(FileError.SECURITY_ERR);
return;
}

if (callback)
callback(errorCode);
}

FileSystemAgent.deleteEntry(url, innerCallback.bind(this));
},


_removeFileSystem: function(fileSystem)
{
var origin = fileSystem.origin;
var type = fileSystem.type;
if (this._fileSystemsForOrigin[origin] && this._fileSystemsForOrigin[origin][type]) {
delete this._fileSystemsForOrigin[origin][type];
this._fileSystemRemoved(fileSystem);

if (Object.isEmpty(this._fileSystemsForOrigin[origin]))
delete this._fileSystemsForOrigin[origin];
}
}
}

WebInspector.FileSystemModel.EventTypes = {
FileSystemAdded: "FileSystemAdded",
FileSystemRemoved: "FileSystemRemoved"
}

WebInspector.FileSystemModel.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.FileSystemModel.FileSystem = function(fileSystemModel, origin, type, backendRootEntry)
{
this.origin = origin;
this.type = type;

this.root = new WebInspector.FileSystemModel.Directory(fileSystemModel, this, backendRootEntry);
}

WebInspector.FileSystemModel.FileSystem.prototype = {

get name()
{
return "filesystem:" + this.origin + "/" + this.type;
}
}


WebInspector.FileSystemModel.Entry = function(fileSystemModel, fileSystem, backendEntry)
{
this._fileSystemModel = fileSystemModel;
this._fileSystem = fileSystem;

this._url = backendEntry.url;
this._name = backendEntry.name;
this._isDirectory = backendEntry.isDirectory;
}


WebInspector.FileSystemModel.Entry.compare = function(x, y)
{
if (x.isDirectory != y.isDirectory)
return y.isDirectory ? 1 : -1;
return x.name.localeCompare(y.name);
}

WebInspector.FileSystemModel.Entry.prototype = {

get fileSystemModel()
{
return this._fileSystemModel;
},


get fileSystem()
{
return this._fileSystem;
},


get url()
{
return this._url;
},


get name()
{
return this._name;
},


get isDirectory()
{
return this._isDirectory;
},


requestMetadata: function(callback)
{
this.fileSystemModel.requestMetadata(this, callback);
},


deleteEntry: function(callback)
{
this.fileSystemModel.deleteEntry(this, callback);
}
}


WebInspector.FileSystemModel.Directory = function(fileSystemModel, fileSystem, backendEntry)
{
WebInspector.FileSystemModel.Entry.call(this, fileSystemModel, fileSystem, backendEntry);
}

WebInspector.FileSystemModel.Directory.prototype = {

requestDirectoryContent: function(callback)
{
this.fileSystemModel.requestDirectoryContent(this, callback);
}
}

WebInspector.FileSystemModel.Directory.prototype.__proto__ = WebInspector.FileSystemModel.Entry.prototype;


WebInspector.FileSystemModel.File = function(fileSystemModel, fileSystem, backendEntry)
{
WebInspector.FileSystemModel.Entry.call(this, fileSystemModel, fileSystem, backendEntry);

this._mimeType = backendEntry.mimeType;
this._resourceType = WebInspector.resourceTypes[backendEntry.resourceType];
this._isTextFile = backendEntry.isTextFile;
}

WebInspector.FileSystemModel.File.prototype = {

get mimeType()
{
return this._mimeType;
},


get resourceType()
{
return this._resourceType;
},


get isTextFile()
{
return this._isTextFile;
},


requestFileContent: function(readAsText, start, end, charset, callback)
{
this.fileSystemModel.requestFileContent(this, readAsText, start, end, charset, callback);
}
}

WebInspector.FileSystemModel.File.prototype.__proto__ = WebInspector.FileSystemModel.Entry.prototype;






WebInspector.OutputStreamDelegate = function()
{
}

WebInspector.OutputStreamDelegate.prototype = {
onTransferStarted: function(source) { },

onChunkTransferred: function(source) { },

onTransferFinished: function(source) { },

onError: function(source, event) { }
}


WebInspector.OutputStream = function()
{
}

WebInspector.OutputStream.prototype = {
startTransfer: function() { },


transferChunk: function(chunk) { },

finishTransfer: function() { },

dispose: function() { }
}


WebInspector.ChunkedFileReader = function(file, chunkSize, delegate)
{
this._file = file;
this._fileSize = file.size;
this._loadedSize = 0;
this._chunkSize = chunkSize;
this._delegate = delegate;
this._isCanceled = false;
}

WebInspector.ChunkedFileReader.prototype = {

start: function(output)
{
this._output = output;

this._reader = new FileReader();
this._reader.onload = this._onChunkLoaded.bind(this);
this._reader.onerror = this._delegate.onError.bind(this._delegate, this);
this._output.startTransfer();
this._delegate.onTransferStarted(this);
this._loadChunk();
},

cancel: function()
{
this._isCanceled = true;
},

loadedSize: function()
{
return this._loadedSize;
},

fileSize: function()
{
return this._fileSize;
},

fileName: function()
{
return this._file.name;
},


_onChunkLoaded: function(event)
{
if (this._isCanceled)
return;

if (event.target.readyState !== FileReader.DONE)
return;

var data = event.target.result;
this._loadedSize += data.length;

this._output.transferChunk(data);
if (this._isCanceled)
return;
this._delegate.onChunkTransferred(this);

if (this._loadedSize === this._fileSize) {
this._file = null;
this._reader = null;
this._output.finishTransfer();
this._delegate.onTransferFinished(this);
return;
}

this._loadChunk();
},

_loadChunk: function()
{
var chunkStart = this._loadedSize;
var chunkEnd = Math.min(this._fileSize, chunkStart + this._chunkSize)
var nextPart = this._file.webkitSlice(chunkStart, chunkEnd);
this._reader.readAsText(nextPart);
}
}


WebInspector.ChunkedXHRReader = function(url, delegate)
{
this._url = url;
this._delegate = delegate;
this._fileSize = 0;
this._loadedSize = 0;
this._isCanceled = false;
}

WebInspector.ChunkedXHRReader.prototype = {

start: function(output)
{
this._output = output;

this._xhr = new XMLHttpRequest();
this._xhr.open("GET", this._url, true);
this._xhr.onload = this._onLoad.bind(this);
this._xhr.onprogress = this._onProgress.bind(this);
this._xhr.onerror = this._delegate.onError.bind(this._delegate, this);
this._xhr.send(null);

this._output.startTransfer();
this._delegate.onTransferStarted(this);
},

cancel: function()
{
this._isCanceled = true;
this._xhr.abort();
},

loadedSize: function()
{
return this._loadedSize;
},

fileSize: function()
{
return this._fileSize;
},

fileName: function()
{
return this._url;
},


_onProgress: function(event)
{
if (this._isCanceled)
return;

if (event.lengthComputable)
this._fileSize = event.total;

var data = this._xhr.responseText.substring(this._loadedSize);
if (!data.length)
return;

this._loadedSize += data.length;
this._output.transferChunk(data);
if (this._isCanceled)
return;
this._delegate.onChunkTransferred(this);
},


_onLoad: function(event)
{
this._onProgress(event);

if (this._isCanceled)
return;

this._output.finishTransfer();
this._delegate.onTransferFinished(this);
}
}


WebInspector.createFileSelectorElement = function(callback) {
var fileSelectorElement = document.createElement("input");
fileSelectorElement.type = "file";
fileSelectorElement.style.zIndex = -1;
fileSelectorElement.style.position = "absolute";
fileSelectorElement.onchange = function(event) {
callback(fileSelectorElement.files[0]);
};
return fileSelectorElement;
}


WebInspector.findBalancedCurlyBrackets = function(source, startIndex, lastIndex) {
lastIndex = lastIndex || source.length;
startIndex = startIndex || 0;
var counter = 0;
var inString = false;

for (var index = startIndex; index < lastIndex; ++index) {
var character = source[index];
if (inString) {
if (character === "\\")
++index;
else if (character === "\"")
inString = false;
} else {
if (character === "\"")
inString = true;
else if (character === "{")
++counter;
else if (character === "}") {
if (--counter === 0)
return index + 1;
}
}
}
return -1;
}


WebInspector.FileOutputStream = function(fileName, delegate)
{
this._fileName = fileName;
this._delegate = delegate;
}

WebInspector.FileOutputStream.prototype = {

startTransfer: function()
{
WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.SavedURL, this._onTransferStarted, this);
WebInspector.fileManager.save(this._fileName, "", true);
},


transferChunk: function(chunk)
{
WebInspector.fileManager.append(this._fileName, chunk);
},


finishTransfer: function()
{
WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._onChunkTransferred, this);
this._delegate.onTransferFinished(this);
},

dispose: function()
{
},


_onTransferStarted: function(event)
{
if (event.data !== this._fileName)
return;
this._delegate.onTransferStarted(this);
WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.SavedURL, this._onTransferStarted, this);
WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._onChunkTransferred, this);
},


_onChunkTransferred: function(event)
{
if (event.data !== this._fileName)
return;
this._delegate.onChunkTransferred(this);
}
}






WebInspector.DebuggerModel = function()
{
InspectorBackend.registerDebuggerDispatcher(new WebInspector.DebuggerDispatcher(this));

this._debuggerPausedDetails = null;

this._scripts = {};
this._scriptsBySourceURL = {};

this._canSetScriptSource = false;
this._breakpointsActive = true;

WebInspector.settings.pauseOnExceptionStateString = WebInspector.settings.createSetting("pauseOnExceptionStateString", WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions);
WebInspector.settings.pauseOnExceptionStateString.addChangeListener(this._pauseOnExceptionStateChanged, this);

if (!Capabilities.debuggerCausesRecompilation || WebInspector.settings.debuggerEnabled.get())
this.enableDebugger();
}


WebInspector.DebuggerModel.PauseOnExceptionsState = {
DontPauseOnExceptions : "none",
PauseOnAllExceptions : "all",
PauseOnUncaughtExceptions: "uncaught"
};


WebInspector.DebuggerModel.Location = function(scriptId, lineNumber, columnNumber)
{
this.scriptId = scriptId;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}

WebInspector.DebuggerModel.Events = {
DebuggerWasEnabled: "DebuggerWasEnabled",
DebuggerWasDisabled: "DebuggerWasDisabled",
DebuggerPaused: "DebuggerPaused",
DebuggerResumed: "DebuggerResumed",
ParsedScriptSource: "ParsedScriptSource",
FailedToParseScriptSource: "FailedToParseScriptSource",
BreakpointResolved: "BreakpointResolved",
GlobalObjectCleared: "GlobalObjectCleared",
CallFrameSelected: "CallFrameSelected",
ExecutionLineChanged: "ExecutionLineChanged",
ConsoleCommandEvaluatedInSelectedCallFrame: "ConsoleCommandEvaluatedInSelectedCallFrame",
BreakpointsActiveStateChanged: "BreakpointsActiveStateChanged"
}

WebInspector.DebuggerModel.BreakReason = {
DOM: "DOM",
EventListener: "EventListener",
XHR: "XHR",
Exception: "exception",
Assert: "assert",
CSPViolation: "CSPViolation"
}

WebInspector.DebuggerModel.prototype = {

debuggerEnabled: function()
{
return !!this._debuggerEnabled;
},

enableDebugger: function()
{
if (this._debuggerEnabled)
return;

function callback(error, result)
{
this._canSetScriptSource = result;
}
DebuggerAgent.canSetScriptSource(callback.bind(this));
DebuggerAgent.enable(this._debuggerWasEnabled.bind(this));
},

disableDebugger: function()
{
if (!this._debuggerEnabled)
return;

DebuggerAgent.disable(this._debuggerWasDisabled.bind(this));
},


canSetScriptSource: function()
{
return this._canSetScriptSource;
},

_debuggerWasEnabled: function()
{
this._debuggerEnabled = true;
this._pauseOnExceptionStateChanged();
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasEnabled);
},

_pauseOnExceptionStateChanged: function()
{
DebuggerAgent.setPauseOnExceptions(WebInspector.settings.pauseOnExceptionStateString.get());
},

_debuggerWasDisabled: function()
{
this._debuggerEnabled = false;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasDisabled);
},


continueToLocation: function(rawLocation)
{
DebuggerAgent.continueToLocation(rawLocation);
},


setBreakpointByScriptLocation: function(rawLocation, condition, callback)
{
var script = this.scriptForId(rawLocation.scriptId);
if (script.sourceURL)
this.setBreakpointByURL(script.sourceURL, rawLocation.lineNumber, rawLocation.columnNumber, condition, callback);
else
this.setBreakpointBySourceId(rawLocation, condition, callback);
},


setBreakpointByURL: function(url, lineNumber, columnNumber, condition, callback)
{

var minColumnNumber = 0;
var scripts = this._scriptsBySourceURL[url] || [];
for (var i = 0, l = scripts.length; i < l; ++i) {
var script = scripts[i];
if (lineNumber === script.lineOffset)
minColumnNumber = minColumnNumber ? Math.min(minColumnNumber, script.columnOffset) : script.columnOffset;
}
columnNumber = Math.max(columnNumber, minColumnNumber);


function didSetBreakpoint(error, breakpointId, locations)
{
if (callback) {
var rawLocations =   locations;
callback(error ? null : breakpointId, rawLocations);
}
}
DebuggerAgent.setBreakpointByUrl(lineNumber, url, undefined, columnNumber, condition, didSetBreakpoint.bind(this));
WebInspector.userMetrics.ScriptsBreakpointSet.record();
},


setBreakpointBySourceId: function(rawLocation, condition, callback)
{

function didSetBreakpoint(error, breakpointId, actualLocation)
{
if (callback) {
var rawLocation =   actualLocation;
callback(error ? null : breakpointId, [rawLocation]);
}
}
DebuggerAgent.setBreakpoint(rawLocation, condition, didSetBreakpoint.bind(this));
WebInspector.userMetrics.ScriptsBreakpointSet.record();
},


removeBreakpoint: function(breakpointId, callback)
{
DebuggerAgent.removeBreakpoint(breakpointId, callback);
},


_breakpointResolved: function(breakpointId, location)
{
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, {breakpointId: breakpointId, location: location});
},

_globalObjectCleared: function()
{
this._setDebuggerPausedDetails(null);
this._reset();
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.GlobalObjectCleared);
},

_reset: function()
{
this._scripts = {};
this._scriptsBySourceURL = {};
},


get scripts()
{
return this._scripts;
},


scriptForId: function(scriptId)
{
return this._scripts[scriptId] || null;
},


setScriptSource: function(scriptId, newSource, callback)
{
this._scripts[scriptId].editSource(newSource, this._didEditScriptSource.bind(this, scriptId, newSource, callback));
},


_didEditScriptSource: function(scriptId, newSource, callback, error, callFrames)
{
callback(error);
if (!error && callFrames && callFrames.length)
this._pausedScript(callFrames, this._debuggerPausedDetails.reason, this._debuggerPausedDetails.auxData);
},


get callFrames()
{
return this._debuggerPausedDetails ? this._debuggerPausedDetails.callFrames : null;
},


debuggerPausedDetails: function()
{
return this._debuggerPausedDetails;
},


_setDebuggerPausedDetails: function(debuggerPausedDetails)
{
if (this._debuggerPausedDetails)
this._debuggerPausedDetails.dispose();
this._debuggerPausedDetails = debuggerPausedDetails;
if (this._debuggerPausedDetails)
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPausedDetails);
if (debuggerPausedDetails) {
this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
DebuggerAgent.setOverlayMessage(WebInspector.UIString("Paused in debugger"));
} else {
this.setSelectedCallFrame(null);
DebuggerAgent.setOverlayMessage();
}
},


_pausedScript: function(callFrames, reason, auxData)
{
this._setDebuggerPausedDetails(new WebInspector.DebuggerPausedDetails(this, callFrames, reason, auxData));
},

_resumedScript: function()
{
this._setDebuggerPausedDetails(null);
if (this._executionLineLiveLocation)
this._executionLineLiveLocation.dispose();
this._executionLineLiveLocation = null;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed);
},


_parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL)
{
var script = new WebInspector.Script(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL);
this._registerScript(script);
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script);
},


_registerScript: function(script)
{
this._scripts[script.scriptId] = script;
if (script.sourceURL) {
var scripts = this._scriptsBySourceURL[script.sourceURL];
if (!scripts) {
scripts = [];
this._scriptsBySourceURL[script.sourceURL] = scripts;
}
scripts.push(script);
}
},


createRawLocation: function(script, lineNumber, columnNumber)
{
if (script.sourceURL)
return this.createRawLocationByURL(script.sourceURL, lineNumber, columnNumber)
return new WebInspector.DebuggerModel.Location(script.scriptId, lineNumber, columnNumber);
},


createRawLocationByURL: function(sourceURL, lineNumber, columnNumber)
{
var closestScript = null;
var scripts = this._scriptsBySourceURL[sourceURL] || [];
for (var i = 0, l = scripts.length; i < l; ++i) {
var script = scripts[i];
if (!closestScript)
closestScript = script;
if (script.lineOffset > lineNumber || (script.lineOffset === lineNumber && script.columnOffset > columnNumber))
continue;
if (script.endLine < lineNumber || (script.endLine === lineNumber && script.endColumn <= columnNumber))
continue;
closestScript = script;
break;
}
return closestScript ? new WebInspector.DebuggerModel.Location(closestScript.scriptId, lineNumber, columnNumber) : null;
},


isPaused: function()
{
return !!this.debuggerPausedDetails();
},


setSelectedCallFrame: function(callFrame)
{
if (this._executionLineLiveLocation)
this._executionLineLiveLocation.dispose();
delete this._executionLineLiveLocation;

this._selectedCallFrame = callFrame;
if (!this._selectedCallFrame)
return;

this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.CallFrameSelected, callFrame);

function updateExecutionLine(uiLocation)
{
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ExecutionLineChanged, uiLocation);
}
this._executionLineLiveLocation = callFrame.script.createLiveLocation(callFrame.location, updateExecutionLine.bind(this));
},


selectedCallFrame: function()
{
return this._selectedCallFrame;
},


evaluateOnSelectedCallFrame: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, callback)
{

function didEvaluate(result, wasThrown)
{
if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result);
else
callback(WebInspector.RemoteObject.fromPayload(result), !!wasThrown);

if (objectGroup === "console")
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame);
}

this.selectedCallFrame().evaluate(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, didEvaluate.bind(this));
},


getSelectedCallFrameVariables: function(callback)
{
var result = { this: true };

var selectedCallFrame = this._selectedCallFrame;
if (!selectedCallFrame)
callback(result);

var pendingRequests = 0;

function propertiesCollected(properties)
{
for (var i = 0; properties && i < properties.length; ++i)
result[properties[i].name] = true;
if (--pendingRequests == 0)
callback(result);
}

for (var i = 0; i < selectedCallFrame.scopeChain.length; ++i) {
var scope = selectedCallFrame.scopeChain[i];
var object = WebInspector.RemoteObject.fromPayload(scope.object);
pendingRequests++;
object.getAllProperties(propertiesCollected);
}
},


setBreakpointsActive: function(active)
{
if (this._breakpointsActive === active)
return;
this._breakpointsActive = active;
DebuggerAgent.setBreakpointsActive(active);
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, active);
},


breakpointsActive: function()
{
return this._breakpointsActive;
},


createLiveLocation: function(rawLocation, updateDelegate)
{
var script = this._scripts[rawLocation.scriptId];
return script.createLiveLocation(rawLocation, updateDelegate);
},


rawLocationToUILocation: function(rawLocation)
{
var script = this._scripts[rawLocation.scriptId];
if (!script)
return null;
return script.rawLocationToUILocation(rawLocation.lineNumber, rawLocation.columnNumber);
},


callStackModified: function(newCallFrames, details)
{

if (details && details["stack_update_needs_step_in"])
DebuggerAgent.stepInto();
else {
if (newCallFrames && newCallFrames.length)
this._pausedScript(newCallFrames, this._debuggerPausedDetails.reason, this._debuggerPausedDetails.auxData);

}
}
}

WebInspector.DebuggerModel.prototype.__proto__ = WebInspector.Object.prototype;

WebInspector.DebuggerEventTypes = {
JavaScriptPause: 0,
JavaScriptBreakpoint: 1,
NativeBreakpoint: 2
};


WebInspector.DebuggerDispatcher = function(debuggerModel)
{
this._debuggerModel = debuggerModel;
}

WebInspector.DebuggerDispatcher.prototype = {

paused: function(callFrames, reason, auxData)
{
this._debuggerModel._pausedScript(callFrames, reason, auxData);
},

resumed: function()
{
this._debuggerModel._resumedScript();
},

globalObjectCleared: function()
{
this._debuggerModel._globalObjectCleared();
},


scriptParsed: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL)
{
this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, !!isContentScript, sourceMapURL);
},


scriptFailedToParse: function(sourceURL, source, startingLine, errorLine, errorMessage)
{
},


breakpointResolved: function(breakpointId, location)
{
this._debuggerModel._breakpointResolved(breakpointId, location);
}
}


WebInspector.DebuggerModel.CallFrame = function(script, payload)
{
this._script = script;
this._payload = payload;
this._locations = [];
}

WebInspector.DebuggerModel.CallFrame.prototype = {

get script()
{
return this._script;
},


get type()
{
return this._payload.type;
},


get scopeChain()
{
return this._payload.scopeChain;
},


get this()
{
return this._payload.this;
},


get functionName()
{
return this._payload.functionName;
},


get location()
{
var rawLocation =   this._payload.location;
return rawLocation;
},


evaluate: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, callback)
{

function didEvaluateOnCallFrame(error, result, wasThrown)
{
if (error) {
console.error(error);
callback(null, false);
return;
}
callback(result, wasThrown);
}
DebuggerAgent.evaluateOnCallFrame(this._payload.callFrameId, code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, didEvaluateOnCallFrame.bind(this));
},


restart: function(callback)
{

function protocolCallback(error, callFrames, details)
{
if (!error)
WebInspector.debuggerModel.callStackModified(callFrames, details);
if (callback)
callback(error);
}
DebuggerAgent.restartFrame(this._payload.callFrameId, protocolCallback);
},


createLiveLocation: function(updateDelegate)
{
var location = this._script.createLiveLocation(this.location, updateDelegate);
this._locations.push(location);
return location;
},

dispose: function(updateDelegate)
{
for (var i = 0; i < this._locations.length; ++i)
this._locations[i].dispose();
this._locations = [];
}
}


WebInspector.DebuggerPausedDetails = function(model, callFrames, reason, auxData)
{
this.callFrames = [];
for (var i = 0; i < callFrames.length; ++i) {
var callFrame = callFrames[i];
var script = model.scriptForId(callFrame.location.scriptId);
if (script)
this.callFrames.push(new WebInspector.DebuggerModel.CallFrame(script, callFrame));
}
this.reason = reason;
this.auxData = auxData;
}

WebInspector.DebuggerPausedDetails.prototype = {
dispose: function()
{
for (var i = 0; i < this.callFrames.length; ++i) {
var callFrame = this.callFrames[i];
callFrame.dispose();
}
}
}


WebInspector.debuggerModel = null;






WebInspector.SourceMapping = function()
{
}

WebInspector.SourceMapping.prototype = {

rawLocationToUILocation: function(rawLocation) { },


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber) { }
}







WebInspector.UISourceCode = function(url, resource, contentProvider)
{
this._url = url;
this._resource = resource;
this._parsedURL = new WebInspector.ParsedURL(url);
this._contentProvider = contentProvider;
this.isContentScript = false;

this._requestContentCallbacks = [];

this._liveLocations = [];

this._consoleMessages = [];


this.history = [];
this._restoreRevisionHistory();
this._formatterMapping = new WebInspector.IdentityFormatterSourceMapping();
}

WebInspector.UISourceCode.Events = {
ContentChanged: "ContentChanged",
WorkingCopyChanged: "WorkingCopyChanged",
TitleChanged: "TitleChanged",
ConsoleMessageAdded: "ConsoleMessageAdded",
ConsoleMessageRemoved: "ConsoleMessageRemoved",
ConsoleMessagesCleared: "ConsoleMessagesCleared"
}

WebInspector.UISourceCode.prototype = {

get url()
{
return this._url;
},


urlChanged: function(url)
{
this._url = url;
this._parsedURL = new WebInspector.ParsedURL(this._url);
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.TitleChanged, null);
},


resource: function()
{
return this._resource;
},


get parsedURL()
{
return this._parsedURL;
},


contentURL: function()
{
return this._url;
},


contentType: function()
{
return this._contentProvider.contentType();
},


requestContent: function(callback)
{
if (this._content || this._contentLoaded) {
callback(this._content, false, this._mimeType);
return;
}
this._requestContentCallbacks.push(callback);
if (this._requestContentCallbacks.length === 1)
this._contentProvider.requestContent(this._fireContentAvailable.bind(this));
},


requestOriginalContent: function(callback)
{
this._contentProvider.requestContent(callback);
},


_setContent: function(newContent)
{
this.setWorkingCopy(newContent);
this.commitWorkingCopy(function() {});
},


addRevision: function(content, timestamp, restoringHistory)
{
if (this.history.length) {
var lastRevision = this.history[this.history.length - 1];
if (lastRevision._content === content)
return;
}
var revision = new WebInspector.Revision(this, content, timestamp || new Date());
this.history.push(revision);

this.contentChanged(revision.content || "", this.canonicalMimeType());
if (!restoringHistory)
revision._persist();
WebInspector.workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeContentCommitted, { uiSourceCode: this, content: content });
},

_restoreRevisionHistory: function()
{
if (!window.localStorage)
return;

var registry = WebInspector.Revision._revisionHistoryRegistry();
var historyItems = registry[this.url];
for (var i = 0; historyItems && i < historyItems.length; ++i)
this.addRevision(window.localStorage[historyItems[i].key], new Date(historyItems[i].timestamp), true);
},

_clearRevisionHistory: function()
{
if (!window.localStorage)
return;

var registry = WebInspector.Revision._revisionHistoryRegistry();
var historyItems = registry[this.url];
for (var i = 0; historyItems && i < historyItems.length; ++i)
delete window.localStorage[historyItems[i].key];
delete registry[this.url];
window.localStorage["revision-history"] = JSON.stringify(registry);
},

revertToOriginal: function()
{

function callback(content, contentEncoded, mimeType)
{
if (typeof content === "undefined")
return;

this._setContent(  content);
}

this.requestOriginalContent(callback.bind(this));
},


revertAndClearHistory: function(callback)
{

function revert(content, contentEncoded, mimeType)
{
if (typeof content === "undefined")
return;

this._setContent(  content);
this._clearRevisionHistory();
this.history = [];
callback(this);
}

this.requestOriginalContent(revert.bind(this));
},


contentChanged: function(newContent, mimeType)
{
this._content = newContent;
this._mimeType = mimeType;
this._contentLoaded = true;
delete this._workingCopy;
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ContentChanged, {content: newContent});
},


isEditable: function()
{
return false;
},


workingCopy: function()
{
if (this.isDirty())
return this._workingCopy;
return this._content;
},


setWorkingCopy: function(newWorkingCopy)
{
var oldWorkingCopy = this._workingCopy;
if (this._content === newWorkingCopy)
delete this._workingCopy;
else
this._workingCopy = newWorkingCopy;
this.workingCopyChanged();
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.WorkingCopyChanged, {oldWorkingCopy: oldWorkingCopy, workingCopy: newWorkingCopy});
},

workingCopyChanged: function()
{  

},


commitWorkingCopy: function(callback)
{
if (!this.isDirty()) {
callback(null);
return;
}

var newContent = this._workingCopy;
this.workingCopyCommitted(callback);
this.addRevision(newContent);
},


workingCopyCommitted: function(callback)
{  

},


isDirty: function()
{
return typeof this._workingCopy !== "undefined" && this._workingCopy !== this._content;
},


mimeType: function()
{
return this._mimeType;
},


canonicalMimeType: function()
{
return this.contentType().canonicalMimeType() || this._mimeType;
},


content: function()
{
return this._content;
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
this._contentProvider.searchInContent(query, caseSensitive, isRegex, callback);
},


_fireContentAvailable: function(content, contentEncoded, mimeType)
{
this._contentLoaded = true;
this._mimeType = mimeType;
this._content = content;

var callbacks = this._requestContentCallbacks.slice();
this._requestContentCallbacks = [];
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](content, contentEncoded, mimeType);

if (this._formatOnLoad) {
delete this._formatOnLoad;
this.setFormatted(true);
}
},


contentLoaded: function()
{
return this._contentLoaded;
},


uiLocationToRawLocation: function(lineNumber, columnNumber)
{
if (!this._sourceMapping)
return null;
var location = this._formatterMapping.formattedToOriginal(lineNumber, columnNumber);
return this._sourceMapping.uiLocationToRawLocation(this, location[0], location[1]);
},


addLiveLocation: function(liveLocation)
{
this._liveLocations.push(liveLocation);
},


removeLiveLocation: function(liveLocation)
{
this._liveLocations.remove(liveLocation);
},

updateLiveLocations: function()
{
var locationsCopy = this._liveLocations.slice();
for (var i = 0; i < locationsCopy.length; ++i)
locationsCopy[i].update();
},


overrideLocation: function(uiLocation)
{
var location = this._formatterMapping.originalToFormatted(uiLocation.lineNumber, uiLocation.columnNumber);
uiLocation.lineNumber = location[0];
uiLocation.columnNumber = location[1];
return uiLocation;
},


consoleMessages: function()
{
return this._consoleMessages;
},


consoleMessageAdded: function(message)
{
this._consoleMessages.push(message);
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessageAdded, message);
},


consoleMessageRemoved: function(message)
{
this._consoleMessages.remove(message);
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessageRemoved, message);
},

consoleMessagesCleared: function()
{
this._consoleMessages = [];
this.dispatchEventToListeners(WebInspector.UISourceCode.Events.ConsoleMessagesCleared);
},


togglingFormatter: function()
{
return this._togglingFormatter;
},


formatted: function()
{
return this._formatted;
},


setFormatted: function(formatted, callback)
{
callback = callback || function() {};
if (!this.contentLoaded()) {
this._formatOnLoad = formatted;
callback();
return;
}

if (this._formatted === formatted) {
callback();
return;
}

this._formatted = formatted;


this._contentLoaded = false;
this._content = false;
WebInspector.UISourceCode.prototype.requestContent.call(this, didGetContent.bind(this));


function didGetContent(content, contentEncoded, mimeType)
{
var formatter;
if (!formatted)
formatter = new WebInspector.IdentityFormatter();
else
formatter = WebInspector.Formatter.createFormatter(this.contentType());
formatter.formatContent(mimeType, content || "", formattedChanged.bind(this));


function formattedChanged(content, formatterMapping)
{
this._togglingFormatter = true;
this.contentChanged(content, mimeType);
delete this._togglingFormatter;
this._formatterMapping = formatterMapping;
this.updateLiveLocations();
this.formattedChanged();
callback();
}
}
},


createFormatter: function()
{

return null;
},


setSourceMapping: function(sourceMapping)
{
this._sourceMapping = sourceMapping;
},

formattedChanged: function()
{
}
}

WebInspector.UISourceCode.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.UISourceCodeProvider = function()
{
}

WebInspector.UISourceCodeProvider.Events = {
UISourceCodeAdded: "UISourceCodeAdded",
UISourceCodeReplaced: "UISourceCodeReplaced",
UISourceCodeRemoved: "UISourceCodeRemoved"
}

WebInspector.UISourceCodeProvider.prototype = {

uiSourceCodes: function() {},


addEventListener: function(eventType, listener, thisObject) { },


removeEventListener: function(eventType, listener, thisObject) { }
}


WebInspector.UILocation = function(uiSourceCode, lineNumber, columnNumber)
{
this.uiSourceCode = uiSourceCode;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}

WebInspector.UILocation.prototype = {

uiLocationToRawLocation: function()
{
return this.uiSourceCode.uiLocationToRawLocation(this.lineNumber, this.columnNumber);
},


url: function()
{
return this.uiSourceCode.contentURL();
}
}


WebInspector.RawLocation = function()
{
}


WebInspector.LiveLocation = function(rawLocation, updateDelegate)
{
this._rawLocation = rawLocation;
this._updateDelegate = updateDelegate;
this._uiSourceCodes = [];
}

WebInspector.LiveLocation.prototype = {
update: function()
{
var uiLocation = this.uiLocation();
if (uiLocation) {
var uiSourceCode = uiLocation.uiSourceCode;
if (this._uiSourceCodes.indexOf(uiSourceCode) === -1) {
uiSourceCode.addLiveLocation(this);
this._uiSourceCodes.push(uiSourceCode);
}
var oneTime = this._updateDelegate(uiLocation);
if (oneTime)
this.dispose();
}
},


rawLocation: function()
{
return this._rawLocation;
},


uiLocation: function()
{

},

dispose: function()
{
for (var i = 0; i < this._uiSourceCodes.length; ++i)
this._uiSourceCodes[i].removeLiveLocation(this);
this._uiSourceCodes = [];
}
}


WebInspector.Revision = function(uiSourceCode, content, timestamp)
{
this._uiSourceCode = uiSourceCode;
this._content = content;
this._timestamp = timestamp;
}

WebInspector.Revision._revisionHistoryRegistry = function()
{
if (!WebInspector.Revision._revisionHistoryRegistryObject) {
if (window.localStorage) {
var revisionHistory = window.localStorage["revision-history"];
try {
WebInspector.Revision._revisionHistoryRegistryObject = revisionHistory ? JSON.parse(revisionHistory) : {};
} catch (e) {
WebInspector.Revision._revisionHistoryRegistryObject = {};
}
} else
WebInspector.Revision._revisionHistoryRegistryObject = {};
}
return WebInspector.Revision._revisionHistoryRegistryObject;
}

WebInspector.Revision.filterOutStaleRevisions = function()
{
if (!window.localStorage)
return;

var registry = WebInspector.Revision._revisionHistoryRegistry();
var filteredRegistry = {};
for (var url in registry) {
var historyItems = registry[url];
var filteredHistoryItems = [];
for (var i = 0; historyItems && i < historyItems.length; ++i) {
var historyItem = historyItems[i];
if (historyItem.loaderId === WebInspector.resourceTreeModel.mainFrame.loaderId) {
filteredHistoryItems.push(historyItem);
filteredRegistry[url] = filteredHistoryItems;
} else
delete window.localStorage[historyItem.key];
}
}
WebInspector.Revision._revisionHistoryRegistryObject = filteredRegistry;

function persist()
{
window.localStorage["revision-history"] = JSON.stringify(filteredRegistry);
}


setTimeout(persist, 0);
}

WebInspector.Revision.prototype = {

get uiSourceCode()
{
return this._uiSourceCode;
},


get timestamp()
{
return this._timestamp;
},


get content()
{
return this._content || null;
},

revertToThis: function()
{
function revert(content)
{
if (this._uiSourceCode._content !== content)
this._uiSourceCode._setContent(content);
}
this.requestContent(revert.bind(this));
},


contentURL: function()
{
return this._uiSourceCode.url;
},


contentType: function()
{
return this._uiSourceCode.contentType();
},


requestContent: function(callback)
{
callback(this._content || "", false, this.uiSourceCode.canonicalMimeType());
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
},

_persist: function()
{
if (!window.localStorage)
return;

var url = this.contentURL();
if (url.startsWith("inspector://"))
return;

var loaderId = WebInspector.resourceTreeModel.mainFrame.loaderId;
var timestamp = this.timestamp.getTime();
var key = "revision-history|" + url + "|" + loaderId + "|" + timestamp;

var registry = WebInspector.Revision._revisionHistoryRegistry();

var historyItems = registry[url];
if (!historyItems) {
historyItems = [];
registry[url] = historyItems;
}
historyItems.push({url: url, loaderId: loaderId, timestamp: timestamp, key: key});

function persist()
{
window.localStorage[key] = this._content;
window.localStorage["revision-history"] = JSON.stringify(registry);
}


setTimeout(persist.bind(this), 0);
}
}






WebInspector.Script = function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL)
{
this.scriptId = scriptId;
this.sourceURL = sourceURL;
this.lineOffset = startLine;
this.columnOffset = startColumn;
this.endLine = endLine;
this.endColumn = endColumn;
this.isContentScript = isContentScript;
this.sourceMapURL = sourceMapURL;
this._locations = [];
}

WebInspector.Script.prototype = {

contentURL: function()
{
return this.sourceURL;
},


contentType: function()
{
return WebInspector.resourceTypes.Script;
},


requestContent: function(callback)
{
if (this._source) {
callback(this._source, false, "text/javascript");
return;
}


function didGetScriptSource(error, source)
{
this._source = error ? "" : source;
callback(this._source, false, "text/javascript");
}
if (this.scriptId) {

DebuggerAgent.getScriptSource(this.scriptId, didGetScriptSource.bind(this));
} else
callback("", false, "text/javascript");
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{

function innerCallback(error, searchMatches)
{
if (error)
console.error(error);
var result = [];
for (var i = 0; i < searchMatches.length; ++i) {
var searchMatch = new WebInspector.ContentProvider.SearchMatch(searchMatches[i].lineNumber, searchMatches[i].lineContent);
result.push(searchMatch);
}
callback(result || []);
}

if (this.scriptId) {

DebuggerAgent.searchInContent(this.scriptId, query, caseSensitive, isRegex, innerCallback.bind(this));
} else
callback([]);
},


editSource: function(newSource, callback)
{

function didEditScriptSource(error, callFrames, debugData)
{

if (!error)
this._source = newSource;
callback(error, callFrames);
}
if (this.scriptId) {

DebuggerAgent.setScriptSource(this.scriptId, newSource, undefined, didEditScriptSource.bind(this));
} else
callback("Script failed to parse");
},


isInlineScript: function()
{
var startsAtZero = !this.lineOffset && !this.columnOffset;
return !!this.sourceURL && !startsAtZero;
},


isAnonymousScript: function()
{
return !this.sourceURL;
},


rawLocationToUILocation: function(lineNumber, columnNumber)
{
var uiLocation = this._sourceMapping.rawLocationToUILocation(new WebInspector.DebuggerModel.Location(this.scriptId, lineNumber, columnNumber || 0));
return uiLocation.uiSourceCode.overrideLocation(uiLocation);
},


setSourceMapping: function(sourceMapping)
{
this._sourceMapping = sourceMapping;
for (var i = 0; i < this._locations.length; ++i)
this._locations[i].update();
},


createLiveLocation: function(rawLocation, updateDelegate)
{
console.assert(rawLocation.scriptId === this.scriptId);
var location = new WebInspector.Script.Location(this, rawLocation, updateDelegate);
this._locations.push(location);
location.update();
return location;
}
}


WebInspector.Script.Location = function(script, rawLocation, updateDelegate)
{
WebInspector.LiveLocation.call(this, rawLocation, updateDelegate);
this._script = script;
}

WebInspector.Script.Location.prototype = {

uiLocation: function()
{
var debuggerModelLocation =   this.rawLocation();
return this._script.rawLocationToUILocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber);
},

dispose: function()
{
WebInspector.LiveLocation.prototype.dispose.call(this);
this._script._locations.remove(this);
}
}

WebInspector.Script.Location.prototype.__proto__ = WebInspector.LiveLocation.prototype;






WebInspector.JavaScriptSource = function(url, resource, contentProvider, isEditable)
{
WebInspector.UISourceCode.call(this, url, resource, contentProvider);
this._isEditable = isEditable;
}

WebInspector.JavaScriptSource.prototype = {

uiLocationToRawLocation: function(lineNumber, columnNumber)
{
var rawLocation = WebInspector.UISourceCode.prototype.uiLocationToRawLocation.call(this, lineNumber, columnNumber);
var debuggerModelLocation =   rawLocation;
return debuggerModelLocation;
},


supportsEnabledBreakpointsWhileEditing: function()
{
return false;
},


breakpointStorageId: function()
{
return this.formatted() ? "deobfuscated:" + this.url : this.url;
},


isEditable: function()
{
return this._isEditable && WebInspector.debuggerModel.canSetScriptSource();
},


isDivergedFromVM: function()
{

return this.isDirty();
},


workingCopyCommitted: function(callback)
{

function innerCallback(error)
{
this._isDivergedFromVM = !!error;
callback(error);
}

var rawLocation = this.uiLocationToRawLocation(0, 0);
var script = WebInspector.debuggerModel.scriptForId(rawLocation.scriptId);
WebInspector.debuggerModel.setScriptSource(script.scriptId, this.workingCopy(), innerCallback.bind(this));
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
var content = this.content();
var provider = content ? new WebInspector.StaticContentProvider(this._contentProvider.contentType(), content) : this._contentProvider;
provider.searchInContent(query, caseSensitive, isRegex, callback);
},

formattedChanged: function()
{
WebInspector.breakpointManager.restoreBreakpoints(this);
}
}

WebInspector.JavaScriptSource.prototype.__proto__ = WebInspector.UISourceCode.prototype;






WebInspector.LinkifierFormatter = function()
{
}

WebInspector.LinkifierFormatter.prototype = {

formatLiveAnchor: function(anchor, uiLocation) { }
}


WebInspector.Linkifier = function(formatter)
{
this._formatter = formatter || new WebInspector.Linkifier.DefaultFormatter();
this._liveLocations = [];
}

WebInspector.Linkifier.prototype = {

linkifyLocation: function(sourceURL, lineNumber, columnNumber, classes)
{
var rawLocation = WebInspector.debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0);
if (!rawLocation)
return WebInspector.linkifyResourceAsNode(sourceURL, lineNumber, classes);
return this.linkifyRawLocation(rawLocation, classes);
},


linkifyRawLocation: function(rawLocation, classes)
{
var script = WebInspector.debuggerModel.scriptForId(rawLocation.scriptId);
if (!script)
return null;
var anchor = WebInspector.linkifyURLAsNode("", "", classes, false);
var liveLocation = script.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor));
this._liveLocations.push(liveLocation);
return anchor;
},

reset: function()
{
for (var i = 0; i < this._liveLocations.length; ++i)
this._liveLocations[i].dispose();
this._liveLocations = [];
},


_updateAnchor: function(anchor, uiLocation)
{
anchor.preferredPanel = "scripts";
anchor.href = sanitizeHref(uiLocation.uiSourceCode.url);
anchor.uiSourceCode = uiLocation.uiSourceCode;
anchor.lineNumber = uiLocation.lineNumber;
this._formatter.formatLiveAnchor(anchor, uiLocation);
}
}


WebInspector.Linkifier.DefaultFormatter = function(maxLength)
{
this._maxLength = maxLength;
}

WebInspector.Linkifier.DefaultFormatter.prototype = {

formatLiveAnchor: function(anchor, uiLocation)
{
anchor.textContent = WebInspector.formatLinkText(uiLocation.uiSourceCode.url, uiLocation.lineNumber);

var text = WebInspector.formatLinkText(uiLocation.uiSourceCode.url, uiLocation.lineNumber);
if (this._maxLength)
text = text.trimMiddle(this._maxLength);
anchor.textContent = text;
}
}

WebInspector.Linkifier.DefaultFormatter.prototype.__proto__ = WebInspector.LinkifierFormatter.prototype;






WebInspector.DebuggerScriptMapping = function(workspace)
{
this._mappings = [];

this._resourceMapping = new WebInspector.ResourceScriptMapping(workspace);
this._mappings.push(this._resourceMapping);
this._compilerMapping = new WebInspector.CompilerScriptMapping(workspace);
this._mappings.push(this._compilerMapping);
this._snippetMapping = WebInspector.scriptSnippetModel.scriptMapping;
this._mappings.push(this._snippetMapping);

WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
}

WebInspector.DebuggerScriptMapping.prototype = {

_parsedScriptSource: function(event)
{
var script =   event.data;
var mapping = this._mappingForScript(script);
mapping.addScript(script);
},


_mappingForScript: function(script)
{
if (WebInspector.experimentsSettings.snippetsSupport.isEnabled()) {
if (this._snippetMapping && this._snippetMapping.snippetIdForSourceURL(script.sourceURL))
return this._snippetMapping;
}

if (WebInspector.settings.sourceMapsEnabled.get() && script.sourceMapURL) {
if (this._compilerMapping.loadSourceMapForScript(script))
return this._compilerMapping;
}

return this._resourceMapping;
}
}






WebInspector.PresentationConsoleMessageHelper = function(uiSourceCodeProvider)
{

this._pendingConsoleMessages = {};
this._presentationConsoleMessages = [];
this._uiSourceCodeProvider = uiSourceCodeProvider;

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);

WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
}

WebInspector.PresentationConsoleMessageHelper.prototype = {

_consoleMessageAdded: function(event)
{
var message =   event.data;
if (!message.url || !message.isErrorOrWarning())
return;

var rawLocation = message.location();
if (rawLocation)
this._addConsoleMessageToScript(message, rawLocation);
else
this._addPendingConsoleMessage(message);
},


_addConsoleMessageToScript: function(message, rawLocation)
{
this._presentationConsoleMessages.push(new WebInspector.PresentationConsoleMessage(message, rawLocation));
},


_addPendingConsoleMessage: function(message)
{
if (!message.url)
return;
if (!this._pendingConsoleMessages[message.url])
this._pendingConsoleMessages[message.url] = [];
this._pendingConsoleMessages[message.url].push(message);
},


_parsedScriptSource: function(event)
{
var script =   event.data;

var messages = this._pendingConsoleMessages[script.sourceURL];
if (!messages)
return;

var pendingMessages = [];
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
var rawLocation =   message.location();
if (script.scriptId === rawLocation.scriptId)
this._addConsoleMessageToScript(message, rawLocation);
else
pendingMessages.push(message);
}

if (pendingMessages.length)
this._pendingConsoleMessages[script.sourceURL] = pendingMessages;
else
delete this._pendingConsoleMessages[script.sourceURL];
},

_consoleCleared: function()
{
this._pendingConsoleMessages = {};
for (var i = 0; i < this._presentationConsoleMessages.length; ++i)
this._presentationConsoleMessages[i].dispose();
this._presentationConsoleMessages = [];
var uiSourceCodes = this._uiSourceCodeProvider.uiSourceCodes();
for (var i = 0; i < uiSourceCodes.length; ++i)
uiSourceCodes[i].consoleMessagesCleared();
},

_debuggerReset: function()
{
this._pendingConsoleMessages = {};
this._presentationConsoleMessages = [];
}
}


WebInspector.PresentationConsoleMessage = function(message, rawLocation)
{
this.originalMessage = message;
this._liveLocation = WebInspector.debuggerModel.createLiveLocation(rawLocation, this._updateLocation.bind(this));
}

WebInspector.PresentationConsoleMessage.prototype = {

_updateLocation: function(uiLocation)
{
if (this._uiLocation)
this._uiLocation.uiSourceCode.consoleMessageRemoved(this);
this._uiLocation = uiLocation;
this._uiLocation.uiSourceCode.consoleMessageAdded(this);
},

get lineNumber()
{
return this._uiLocation.lineNumber;
},

dispose: function()
{
this._liveLocation.dispose();
}
}






WebInspector.WorkspaceController = function(workspace)
{
this._workspace = workspace;
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
}

WebInspector.WorkspaceController.prototype = {
_mainFrameNavigated: function()
{
WebInspector.Revision.filterOutStaleRevisions();
this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectWillReset, this._workspace.project());
this._workspace.project().reset();
this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectDidReset, this._workspace.project());
},

_frameAdded: function(event)
{
var frame =   event.data;
if (frame.isMainFrame())
WebInspector.Revision.filterOutStaleRevisions();
}
}


WebInspector.workspaceController = null;


WebInspector.Project = function(workspace)
{
this._uiSourceCodes = [];
this._workspace = workspace;
}

WebInspector.Project.prototype = {
reset: function()
{
this._uiSourceCodes = [];
},


addUISourceCode: function(uiSourceCode)
{
this._uiSourceCodes.push(uiSourceCode);
this._workspace.dispatchEventToListeners(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, uiSourceCode);
},


replaceUISourceCode: function(oldUISourceCode, uiSourceCode)
{
this._uiSourceCodes.splice(this._uiSourceCodes.indexOf(oldUISourceCode), 1);
if (this._uiSourceCodes.indexOf(uiSourceCode) === -1)
this._uiSourceCodes.push(uiSourceCode);
var data = { oldUISourceCode: oldUISourceCode, uiSourceCode: uiSourceCode };
this._workspace.dispatchEventToListeners(WebInspector.UISourceCodeProvider.Events.UISourceCodeReplaced, data);
},


removeUISourceCode: function(uiSourceCode)
{
this._uiSourceCodes.splice(this._uiSourceCodes.indexOf(uiSourceCode), 1);
this._workspace.dispatchEventToListeners(WebInspector.UISourceCodeProvider.Events.UISourceCodeRemoved, uiSourceCode);
},


uiSourceCodeForURL: function(url)
{
for (var i = 0; i < this._uiSourceCodes.length; ++i) {
if (this._uiSourceCodes[i].url === url)
return this._uiSourceCodes[i];
}
return null;
},


uiSourceCodes: function()
{
return this._uiSourceCodes;
}
}


WebInspector.Workspace = function()
{
this._project = new WebInspector.Project(this);
}

WebInspector.Workspace.Events = {
UISourceCodeContentCommitted: "UISourceCodeContentCommitted",
ProjectWillReset: "ProjectWillReset",
ProjectDidReset: "ProjectDidReset"
}

WebInspector.Workspace.prototype = {

uiSourceCodeForURL: function(url)
{
return this._project.uiSourceCodeForURL(url);
},


project: function()
{

return this._project;
},


uiSourceCodes: function()
{
return this._project.uiSourceCodes();
}
}

WebInspector.Workspace.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.workspace = null;






WebInspector.BreakpointManager = function(breakpointStorage, debuggerModel, workspace)
{
this._storage = new WebInspector.BreakpointManager.Storage(this, breakpointStorage);
this._debuggerModel = debuggerModel;
this._workspace = workspace;

this._breakpoints = [];
this._breakpointForDebuggerId = {};
this._breakpointsForUISourceCode = new Map();
this._sourceFilesWithRestoredBreakpoints = {};

this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._workspaceReset, this);
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
}

WebInspector.BreakpointManager.Events = {
BreakpointAdded: "breakpoint-added",
BreakpointRemoved: "breakpoint-removed"
}

WebInspector.BreakpointManager.prototype = {

restoreBreakpoints: function(uiSourceCode)
{
var sourceFileId = uiSourceCode.breakpointStorageId();
if (!sourceFileId || this._sourceFilesWithRestoredBreakpoints[sourceFileId])
return;
this._sourceFilesWithRestoredBreakpoints[sourceFileId] = true;


for (var debuggerId in this._breakpointForDebuggerId) {
var breakpoint = this._breakpointForDebuggerId[debuggerId];
if (breakpoint._sourceCodeStorageId !== sourceFileId)
continue;
this._debuggerModel.removeBreakpoint(debuggerId);
delete this._breakpointForDebuggerId[debuggerId];
}
this._storage._restoreBreakpoints(uiSourceCode);
},


_uiSourceCodeAdded: function(event)
{
var uiSourceCode =   event.data;
if (uiSourceCode instanceof WebInspector.JavaScriptSource)
this.restoreBreakpoints(uiSourceCode);
},


setBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
{
this._debuggerModel.setBreakpointsActive(true);
return this._innerSetBreakpoint(uiSourceCode, lineNumber, condition, enabled);
},


_innerSetBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
{
var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber);
if (breakpoint) {
breakpoint._updateBreakpoint(condition, enabled);
return breakpoint;
}
breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, uiSourceCode, lineNumber, condition, enabled);
this._breakpoints.push(breakpoint);
return breakpoint;
},


findBreakpoint: function(uiSourceCode, lineNumber)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
var lineBreakpoints = breakpoints ? breakpoints[lineNumber] : null;
return lineBreakpoints ? lineBreakpoints[0] : null;
},


_filteredBreakpointLocations: function(filter)
{
var result = [];
for (var i = 0; i < this._breakpoints.length; ++i) {
var breakpoint = this._breakpoints[i];
for (var stringifiedLocation in breakpoint._uiLocations) {
var uiLocation = breakpoint._uiLocations[stringifiedLocation];
if (filter(breakpoint, uiLocation))
result.push({breakpoint: breakpoint, uiLocation: uiLocation});
}
}
return result;
},


breakpointLocationsForUISourceCode: function(uiSourceCode)
{
function filter(breakpoint, uiLocation)
{
return uiLocation.uiSourceCode === uiSourceCode;   
}

return this._filteredBreakpointLocations(filter);
},


allBreakpointLocations: function()
{
return this._filteredBreakpointLocations(function(breakpoint, uiLocation) { return true; });
},


toggleAllBreakpoints: function(toggleState)
{
for (var i = 0; i < this._breakpoints.length; ++i) {
var breakpoint = this._breakpoints[i];
if (breakpoint.enabled() != toggleState)
breakpoint.setEnabled(toggleState);
}
},

removeAllBreakpoints: function()
{
var breakpoints = this._breakpoints.slice();
for (var i = 0; i < breakpoints.length; ++i)
breakpoints[i].remove();
},

reset: function()
{

this._storage._muted = true;
this.removeAllBreakpoints();
delete this._storage._muted;


for (var debuggerId in this._breakpointForDebuggerId)
this._debuggerModel.removeBreakpoint(debuggerId);
this._breakpointForDebuggerId = {};
this._sourceFilesWithRestoredBreakpoints = {};
},

_workspaceReset: function()
{
var breakpoints = this._breakpoints.slice();
for (var i = 0; i < breakpoints.length; ++i) {
breakpoints[i]._resetLocations();
breakpoints[i]._isProvisional = true;
}
this._breakpoints = [];
this._breakpointsForUISourceCode.clear();
this._sourceFilesWithRestoredBreakpoints = {};
},

_breakpointResolved: function(event)
{
var breakpointId =   event.data.breakpointId;
var location =   event.data.location;
var breakpoint = this._breakpointForDebuggerId[breakpointId];
if (!breakpoint || breakpoint._isProvisional)
return;
breakpoint._addResolvedLocation(location);
},


_removeBreakpoint: function(breakpoint, removeFromStorage)
{
console.assert(!breakpoint._debuggerId)
this._breakpoints.remove(breakpoint);
if (removeFromStorage)
this._storage._removeBreakpoint(breakpoint);
},


_uiLocationAdded: function(breakpoint, uiLocation)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
if (!breakpoints) {
breakpoints = {};
this._breakpointsForUISourceCode.put(uiLocation.uiSourceCode, breakpoints);
}

var lineBreakpoints = breakpoints[uiLocation.lineNumber];
if (!lineBreakpoints) {
lineBreakpoints = [];
breakpoints[uiLocation.lineNumber] = lineBreakpoints;
}

lineBreakpoints.push(breakpoint);
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation});
},


_uiLocationRemoved: function(breakpoint, uiLocation)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
if (!breakpoints)
return;

var lineBreakpoints = breakpoints[uiLocation.lineNumber];
if (!lineBreakpoints)
return;

lineBreakpoints.remove(breakpoint);
if (!lineBreakpoints.length)
delete breakpoints[uiLocation.lineNumber];
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation});
}
}

WebInspector.BreakpointManager.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, uiSourceCode, lineNumber, condition, enabled)
{
this._breakpointManager = breakpointManager;
this._primaryUILocation = new WebInspector.UILocation(uiSourceCode, lineNumber, 0);
this._sourceCodeStorageId = uiSourceCode.breakpointStorageId();

this._liveLocations = [];

this._uiLocations = {};


this._condition;
this._enabled;
this._updateBreakpoint(condition, enabled);
}

WebInspector.BreakpointManager.Breakpoint.prototype = {

primaryUILocation: function()
{
return this._primaryUILocation;
},


_addResolvedLocation: function(location)
{
this._liveLocations.push(this._breakpointManager._debuggerModel.createLiveLocation(location, this._locationUpdated.bind(this, location)));
},


_locationUpdated: function(location, uiLocation)
{
var stringifiedLocation = location.scriptId + ":" + location.lineNumber + ":" + location.columnNumber;
var oldUILocation =   this._uiLocations[stringifiedLocation];
if (oldUILocation)
this._breakpointManager._uiLocationRemoved(this, oldUILocation);
if (this._uiLocations[""]) {
delete this._uiLocations[""];
this._breakpointManager._uiLocationRemoved(this, this._primaryUILocation);
}
this._uiLocations[stringifiedLocation] = uiLocation;
this._breakpointManager._uiLocationAdded(this, uiLocation);
},


enabled: function()
{
return this._enabled;
},


setEnabled: function(enabled)
{
this._updateBreakpoint(this._condition, enabled);
},


condition: function()
{
return this._condition;
},


setCondition: function(condition)
{
this._updateBreakpoint(condition, this._enabled);
},


_updateBreakpoint: function(condition, enabled)
{
if (this._enabled === enabled && this._condition === condition)
return;

if (this._enabled)
this._removeFromDebugger();

this._enabled = enabled;
this._condition = condition;
this._breakpointManager._storage._updateBreakpoint(this);

if (this._enabled && !this._primaryUILocation.uiSourceCode.isDivergedFromVM()) {
this._setInDebugger();
return;
}

this._fakeBreakpointAtPrimaryLocation();
},

remove: function()
{
this._resetLocations();
this._removeFromDebugger();
this._breakpointManager._removeBreakpoint(this, true);
},

_setInDebugger: function()
{
var rawLocation = this._primaryUILocation.uiLocationToRawLocation();
var debuggerModelLocation =   rawLocation;
if (debuggerModelLocation)
this._breakpointManager._debuggerModel.setBreakpointByScriptLocation(debuggerModelLocation, this._condition, didSetBreakpoint.bind(this));
else
this._breakpointManager._debuggerModel.setBreakpointByURL(this._primaryUILocation.uiSourceCode.url, this._primaryUILocation.lineNumber, 0, this._condition, didSetBreakpoint.bind(this));


function didSetBreakpoint(breakpointId, locations)
{
if (!breakpointId) {
this._resetLocations();
this._breakpointManager._removeBreakpoint(this, false);
return;
}

this._debuggerId = breakpointId;
this._breakpointManager._breakpointForDebuggerId[breakpointId] = this;

if (!locations.length) {
this._fakeBreakpointAtPrimaryLocation();
return;
}

this._resetLocations();
for (var i = 0; i < locations.length; ++i) {
var script = this._breakpointManager._debuggerModel.scriptForId(locations[i].scriptId);
var uiLocation = script.rawLocationToUILocation(locations[i].lineNumber, locations[i].columnNumber);
if (this._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber)) {

this.remove();
return;
}
}

for (var i = 0; i < locations.length; ++i)
this._addResolvedLocation(locations[i]);
}
},

_removeFromDebugger: function()
{
if (this._debuggerId) {
this._breakpointManager._debuggerModel.removeBreakpoint(this._debuggerId);
delete this._breakpointManager._breakpointForDebuggerId[this._debuggerId];
delete this._debuggerId;
}
},

_resetLocations: function()
{
for (var stringifiedLocation in this._uiLocations)
this._breakpointManager._uiLocationRemoved(this, this._uiLocations[stringifiedLocation]);

for (var i = 0; i < this._liveLocations.length; ++i)
this._liveLocations[i].dispose();
this._liveLocations = [];

this._uiLocations = {};
},


_breakpointStorageId: function()
{
return this._primaryUILocation.uiSourceCode.breakpointStorageId() + ":" + this._primaryUILocation.lineNumber;
},

_fakeBreakpointAtPrimaryLocation: function()
{
this._resetLocations();
this._uiLocations[""] = this._primaryUILocation;
this._breakpointManager._uiLocationAdded(this, this._primaryUILocation);
}
}


WebInspector.BreakpointManager.Storage = function(breakpointManager, setting)
{
this._breakpointManager = breakpointManager;
this._setting = setting;
var breakpoints = this._setting.get();

this._breakpoints = {};
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint =   breakpoints[i];
this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber] = breakpoint;
}
}

WebInspector.BreakpointManager.Storage.prototype = {

_restoreBreakpoints: function(uiSourceCode)
{
this._muted = true;
var breakpointStorageId = uiSourceCode.breakpointStorageId();
for (var id in this._breakpoints) {
var breakpoint = this._breakpoints[id];
if (breakpoint.sourceFileId === breakpointStorageId)
this._breakpointManager._innerSetBreakpoint(uiSourceCode, breakpoint.lineNumber, breakpoint.condition, breakpoint.enabled);
}
delete this._muted;
},


_updateBreakpoint: function(breakpoint)
{
if (this._muted)
return;
this._breakpoints[breakpoint._breakpointStorageId()] = new WebInspector.BreakpointManager.Storage.Item(breakpoint);
this._save();
},


_removeBreakpoint: function(breakpoint)
{
if (this._muted)
return;
delete this._breakpoints[breakpoint._breakpointStorageId()];
this._save();
},

_save: function()
{
var breakpointsArray = [];
for (var id in this._breakpoints)
breakpointsArray.push(this._breakpoints[id]);
this._setting.set(breakpointsArray);
}
}


WebInspector.BreakpointManager.Storage.Item = function(breakpoint)
{
var primaryUILocation = breakpoint.primaryUILocation();
this.sourceFileId = primaryUILocation.uiSourceCode.breakpointStorageId();
this.lineNumber = primaryUILocation.lineNumber;
this.condition = breakpoint.condition();
this.enabled = breakpoint.enabled();
}


WebInspector.breakpointManager = null;






WebInspector.ConcatenatedScriptsContentProvider = function(scripts)
{
this._mimeType = "text/html";
this._scripts = scripts;
}

WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag = "<script>";
WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag = "</script>";

WebInspector.ConcatenatedScriptsContentProvider.prototype = {

_sortedScripts: function()
{
if (this._sortedScriptsArray)
return this._sortedScriptsArray;

this._sortedScriptsArray = [];

var scripts = this._scripts.slice();
scripts.sort(function(x, y) { return x.lineOffset - y.lineOffset || x.columnOffset - y.columnOffset; });

var scriptOpenTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag.length;
var scriptCloseTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag.length;

this._sortedScriptsArray.push(scripts[0]);
for (var i = 1; i < scripts.length; ++i) {
var previousScript = this._sortedScriptsArray[this._sortedScriptsArray.length - 1];

var lineNumber = previousScript.endLine;
var columnNumber = previousScript.endColumn + scriptCloseTagLength + scriptOpenTagLength;

if (lineNumber < scripts[i].lineOffset || (lineNumber === scripts[i].lineOffset && columnNumber <= scripts[i].columnOffset))
this._sortedScriptsArray.push(scripts[i]);
}
return this._sortedScriptsArray;
},


contentURL: function()
{
return null;
},


contentType: function()
{
return WebInspector.resourceTypes.Document;
},


requestContent: function(callback)
{
var scripts = this._sortedScripts();
var sources = [];
function didRequestSource(content, contentEncoded, mimeType)
{
sources.push(content);
if (sources.length == scripts.length)
callback(this._concatenateScriptsContent(scripts, sources), false, this._mimeType);
}
for (var i = 0; i < scripts.length; ++i)
scripts[i].requestContent(didRequestSource.bind(this));
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
var results = {};
var scripts = this._sortedScripts();
var scriptsLeft = scripts.length;

function maybeCallback()
{
if (scriptsLeft)
return;

var result = [];
for (var i = 0; i < scripts.length; ++i)
result = result.concat(results[scripts[i].scriptId]);
callback(result);
}


function searchCallback(script, searchMatches)
{
results[script.scriptId] = [];
for (var i = 0; i < searchMatches.length; ++i) {
var searchMatch = new WebInspector.ContentProvider.SearchMatch(searchMatches[i].lineNumber + script.lineOffset, searchMatches[i].lineContent);
results[script.scriptId].push(searchMatch);
}
scriptsLeft--;
maybeCallback.call(this);
}

maybeCallback();
for (var i = 0; i < scripts.length; ++i)
scripts[i].searchInContent(query, caseSensitive, isRegex, searchCallback.bind(this, scripts[i]));
},


_concatenateScriptsContent: function(scripts, sources)
{
var content = "";
var lineNumber = 0;
var columnNumber = 0;

var scriptOpenTag = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag;
var scriptCloseTag = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag;
for (var i = 0; i < scripts.length; ++i) {

for (var newLinesCount = scripts[i].lineOffset - lineNumber; newLinesCount > 0; --newLinesCount) {
columnNumber = 0;
content += "\n";
}
for (var spacesCount = scripts[i].columnOffset - columnNumber - scriptOpenTag.length; spacesCount > 0; --spacesCount)
content += " ";


content += scriptOpenTag;
content += sources[i];
content += scriptCloseTag;
lineNumber = scripts[i].endLine;
columnNumber = scripts[i].endColumn + scriptCloseTag.length;
}

return content;
}
}

WebInspector.ConcatenatedScriptsContentProvider.prototype.__proto__ = WebInspector.ContentProvider.prototype;


WebInspector.CompilerSourceMappingContentProvider = function(sourceURL)
{
this._sourceURL = sourceURL;
}

WebInspector.CompilerSourceMappingContentProvider.prototype = {

contentURL: function()
{
return this._sourceURL;
},


contentType: function()
{
return WebInspector.resourceTypes.Script;
},


requestContent: function(callback)
{
var sourceCode = "";
try {

sourceCode = InspectorFrontendHost.loadResourceSynchronously(this._sourceURL);
} catch(e) {
console.error(e.message);
}
callback(sourceCode, false, "text/javascript");
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
}
}

WebInspector.CompilerSourceMappingContentProvider.prototype.__proto__ = WebInspector.ContentProvider.prototype;


WebInspector.StaticContentProvider = function(contentType, content, mimeType)
{
this._content = content;
this._contentType = contentType;
this._mimeType = mimeType;
}

WebInspector.StaticContentProvider.prototype = {

contentURL: function()
{
return null;
},


contentType: function()
{
return this._contentType;
},


requestContent: function(callback)
{
callback(this._content, false, this._mimeType || this._contentType.canonicalMimeType());
},


searchInContent: function(query, caseSensitive, isRegex, callback)
{
function performSearch()
{
var regex = createSearchRegex(query, caseSensitive, isRegex);

var result = [];
var lineEndings = this._content.lineEndings();
for (var i = 0; i < lineEndings.length; ++i) {
var lineStart = i > 0 ? lineEndings[i - 1] + 1 : 0;
var lineEnd = lineEndings[i];
var lineContent = this._content.substring(lineStart, lineEnd);
if (lineContent.length > 0 && lineContent.charAt(lineContent.length - 1) === "\r")
lineContent = lineContent.substring(0, lineContent.length - 1)

if (regex.exec(lineContent))
result.push(new WebInspector.ContentProvider.SearchMatch(i, lineContent));
}
callback(result);
}


window.setTimeout(performSearch.bind(this), 0);
}
}

WebInspector.StaticContentProvider.prototype.__proto__ = WebInspector.ContentProvider.prototype;






WebInspector.ResourceScriptMapping = function(workspace)
{
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._reset, this);
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);


this._uiSourceCodeForScriptId = {};
this._scriptIdForUISourceCode = new Map();
this._temporaryUISourceCodes = new Map();

this._nextDynamicScriptIndexForURL = {};
}

WebInspector.ResourceScriptMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation =   rawLocation;
var script = WebInspector.debuggerModel.scriptForId(debuggerModelLocation.scriptId);
var uiSourceCode = this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId];
return new WebInspector.UILocation(uiSourceCode, debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var scriptId = this._scriptIdForUISourceCode.get(uiSourceCode);
var script = WebInspector.debuggerModel.scriptForId(scriptId);
return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},


addScript: function(script)
{
console.assert(!this._uiSourceCodeForScriptId[script.scriptId]);

var isDynamicScript = false;
if (!script.isAnonymousScript()) {
var uiSourceCode = this._workspace.uiSourceCodeForURL(script.sourceURL);
isDynamicScript = !!uiSourceCode && uiSourceCode.contentType() === WebInspector.resourceTypes.Document && !script.isInlineScript();
if (uiSourceCode && !isDynamicScript && !this._temporaryUISourceCodes.get(uiSourceCode))
this._bindUISourceCodeToScripts(uiSourceCode, [script]);
}
if (!this._uiSourceCodeForScriptId[script.scriptId])
this._addOrReplaceTemporaryUISourceCode(script, isDynamicScript);

console.assert(this._uiSourceCodeForScriptId[script.scriptId]);
},


_bindUISourceCodeToScripts: function(uiSourceCode, scripts)
{
console.assert(scripts.length);

for (var i = 0; i < scripts.length; ++i) {
this._uiSourceCodeForScriptId[scripts[i].scriptId] = uiSourceCode;
scripts[i].setSourceMapping(this);
}
uiSourceCode.isContentScript = scripts[0].isContentScript;
uiSourceCode.setSourceMapping(this);
this._scriptIdForUISourceCode.put(uiSourceCode, scripts[0].scriptId);
},


_scriptsForSourceURL: function(sourceURL, isInlineScript)
{
function filter(script)
{
return script.sourceURL === sourceURL && script.isInlineScript() === isInlineScript;
}

return Object.values(WebInspector.debuggerModel.scripts).filter(filter);
},


_addOrReplaceTemporaryUISourceCode: function(script, isDynamicScript)
{
var scripts = script.isInlineScript() ? this._scriptsForSourceURL(script.sourceURL, true) : [script];

var oldUISourceCode;
for (var i = 0; i < scripts.length; ++i) {
oldUISourceCode = this._uiSourceCodeForScriptId[scripts[i].scriptId];
if (oldUISourceCode)
break;
}
console.assert(!oldUISourceCode || this._temporaryUISourceCodes.get(oldUISourceCode));

var contentProvider = script.isInlineScript() ? new WebInspector.ConcatenatedScriptsContentProvider(scripts) : script;
var url = script.sourceURL;
if (isDynamicScript) {
var nextIndex = this._nextDynamicScriptIndexForURL[script.sourceURL] || 1;
url += " (" + nextIndex + ")";
this._nextDynamicScriptIndexForURL[script.sourceURL] = nextIndex + 1;
}
var uiSourceCode = new WebInspector.JavaScriptSource(url, null, contentProvider, !script.isInlineScript());
this._temporaryUISourceCodes.put(uiSourceCode, uiSourceCode);
this._bindUISourceCodeToScripts(uiSourceCode, scripts);

if (!script.sourceURL)
return uiSourceCode;

if (oldUISourceCode)
this._uiSourceCodeReplaced(oldUISourceCode, uiSourceCode);
else
this._workspace.project().addUISourceCode(uiSourceCode);
return uiSourceCode;
},

_uiSourceCodeAddedToWorkspace: function(event)
{
var uiSourceCode =   event.data;
console.assert(!this._scriptIdForUISourceCode.get(uiSourceCode) || this._temporaryUISourceCodes.get(uiSourceCode));
if (!uiSourceCode.url || this._temporaryUISourceCodes.get(uiSourceCode))
return;
this._addUISourceCode(uiSourceCode);
},


_addUISourceCode: function(uiSourceCode)
{
var isInlineScript;
switch (uiSourceCode.contentType()) {
case WebInspector.resourceTypes.Document:
isInlineScript = true;
break;
case WebInspector.resourceTypes.Script:
isInlineScript = false;
break;
default:
return;
}

var scripts = this._scriptsForSourceURL(uiSourceCode.url, isInlineScript);
if (!scripts.length)
return;

var oldUISourceCode = this._uiSourceCodeForScriptId[scripts[0].scriptId];
this._bindUISourceCodeToScripts(uiSourceCode, scripts);

if (oldUISourceCode) {
console.assert(this._temporaryUISourceCodes.get(oldUISourceCode));
this._uiSourceCodeReplaced(oldUISourceCode, uiSourceCode);
}

console.assert(this._scriptIdForUISourceCode.get(uiSourceCode) && !this._temporaryUISourceCodes.get(uiSourceCode));
},


_uiSourceCodeReplaced: function(oldUISourceCode, uiSourceCode)
{
this._temporaryUISourceCodes.remove(oldUISourceCode);
this._scriptIdForUISourceCode.remove(oldUISourceCode);
this._workspace.project().replaceUISourceCode(oldUISourceCode, uiSourceCode);
},

_reset: function()
{
this._uiSourceCodeForScriptId = {};
this._scriptIdForUISourceCode.clear();
this._temporaryUISourceCodes.clear();
this._nextDynamicScriptIndexForURL = {};
},
}






WebInspector.CompilerScriptMapping = function(workspace)
{
this._workspace = workspace;
this._sourceMapByURL = {};
this._sourceMapForScriptId = {};
this._scriptForSourceMap = new Map();
this._sourceMapForUISourceCode = new Map();
this._uiSourceCodeByURL = {};
this._originalUISourceCodeForScriptId = {};
this._scriptForOriginalUISource = new Map();
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._reset, this);
}

WebInspector.CompilerScriptMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation =   rawLocation;
var sourceMap = this._sourceMapForScriptId[debuggerModelLocation.scriptId];
var lineNumber = debuggerModelLocation.lineNumber;
var columnNumber = debuggerModelLocation.columnNumber || 0;
var entry = sourceMap.findEntry(lineNumber, columnNumber);
if (entry.length === 2)
return new WebInspector.UILocation(this._originalUISourceCodeForScriptId[debuggerModelLocation.scriptId], lineNumber, columnNumber);
return new WebInspector.UILocation(this._uiSourceCodeByURL[entry[2]], entry[3], entry[4]);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var script = this._scriptForOriginalUISource.get(uiSourceCode);
if (script)
return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
var sourceMap = this._sourceMapForUISourceCode.get(uiSourceCode);
var entry = sourceMap.findEntryReversed(uiSourceCode.url, lineNumber);
return WebInspector.debuggerModel.createRawLocation(this._scriptForSourceMap.get(sourceMap), entry[0], entry[1]);
},


addScript: function(script)
{
var originalUISourceCode = new WebInspector.JavaScriptSource(script.sourceURL, null, script, true);
this._originalUISourceCodeForScriptId[script.scriptId] = originalUISourceCode;
this._scriptForOriginalUISource.put(originalUISourceCode, script);
this._workspace.project().addUISourceCode(originalUISourceCode);

var sourceMap = this.loadSourceMapForScript(script);

if (this._scriptForSourceMap.get(sourceMap)) {
this._sourceMapForScriptId[script.scriptId] = sourceMap;
script.setSourceMapping(this);
return;
}

var uiSourceCodeList = [];
var sourceURLs = sourceMap.sources();
for (var i = 0; i < sourceURLs.length; ++i) {
var sourceURL = sourceURLs[i];
if (this._uiSourceCodeByURL[sourceURL])
continue;
var sourceContent = sourceMap.sourceContent(sourceURL);
var contentProvider;
if (sourceContent)
contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, sourceContent);
else
contentProvider = new WebInspector.CompilerSourceMappingContentProvider(sourceURL);
var uiSourceCode = new WebInspector.JavaScriptSource(sourceURL, null, contentProvider, false);
uiSourceCode.setSourceMapping(this);
uiSourceCode.isContentScript = script.isContentScript;
this._uiSourceCodeByURL[sourceURL] = uiSourceCode;
this._sourceMapForUISourceCode.put(uiSourceCode, sourceMap);
uiSourceCodeList.push(uiSourceCode);
}

this._sourceMapForScriptId[script.scriptId] = sourceMap;
this._scriptForSourceMap.put(sourceMap, script);
script.setSourceMapping(this);

for (var i = 0; i < uiSourceCodeList.length; ++i)
this._workspace.project().addUISourceCode(uiSourceCodeList[i]);
},


loadSourceMapForScript: function(script)
{
var sourceMapURL = WebInspector.SourceMapParser.prototype._canonicalizeURL(script.sourceMapURL, script.sourceURL);
var sourceMap = this._sourceMapByURL[sourceMapURL];
if (sourceMap)
return sourceMap;

try {

var response = InspectorFrontendHost.loadResourceSynchronously(sourceMapURL);
if (response.slice(0, 3) === ")]}")
response = response.substring(response.indexOf('\n'));
var payload =   JSON.parse(response);
sourceMap = new WebInspector.SourceMapParser(sourceMapURL, payload);
} catch(e) {
console.error(e.message);
return null;
}
this._sourceMapByURL[sourceMapURL] = sourceMap;
return sourceMap;
},

_reset: function()
{
this._sourceMapByURL = {};
this._sourceMapForScriptId = {};
this._scriptForSourceMap = new Map();
this._sourceMapForUISourceCode = new Map();
this._uiSourceCodeByURL = {};
this._originalUISourceCodeForScriptId = {};
this._scriptForOriginalUISource = new Map();
}
}


WebInspector.SourceMapPayload = function()
{
this.sections = [];
this.mappings = "";
this.sourceRoot = "";
this.sources = [];
}


WebInspector.SourceMapParser = function(sourceMappingURL, payload)
{
if (!WebInspector.SourceMapParser.prototype._base64Map) {
const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
WebInspector.SourceMapParser.prototype._base64Map = {};
for (var i = 0; i < base64Digits.length; ++i)
WebInspector.SourceMapParser.prototype._base64Map[base64Digits.charAt(i)] = i;
}

this._sourceMappingURL = sourceMappingURL;
this._mappings = [];
this._reverseMappingsBySourceURL = {};
this._sourceContentByURL = {};
this._parseMappingPayload(payload);
}

WebInspector.SourceMapParser.prototype = {

sources: function()
{
var sources = [];
for (var sourceURL in this._reverseMappingsBySourceURL)
sources.push(sourceURL);
return sources;
},

sourceContent: function(sourceURL)
{
return this._sourceContentByURL[sourceURL];
},

findEntry: function(lineNumber, columnNumber)
{
var first = 0;
var count = this._mappings.length;
while (count > 1) {
var step = count >> 1;
var middle = first + step;
var mapping = this._mappings[middle];
if (lineNumber < mapping[0] || (lineNumber == mapping[0] && columnNumber < mapping[1]))
count = step;
else {
first = middle;
count -= step;
}
}
return this._mappings[first];
},

findEntryReversed: function(sourceURL, lineNumber)
{
var mappings = this._reverseMappingsBySourceURL[sourceURL];
for ( ; lineNumber < mappings.length; ++lineNumber) {
var mapping = mappings[lineNumber];
if (mapping)
return mapping;
}
return this._mappings[0];
},

_parseMappingPayload: function(mappingPayload)
{
if (mappingPayload.sections)
this._parseSections(mappingPayload.sections);
else
this._parseMap(mappingPayload, 0, 0);
},


_parseSections: function(sections)
{
for (var i = 0; i < sections.length; ++i) {
var section = sections[i];
this._parseMap(section.map, section.offset.line, section.offset.column)
}
},


_parseMap: function(map, lineNumber, columnNumber)
{
var sourceIndex = 0;
var sourceLineNumber = 0;
var sourceColumnNumber = 0;
var nameIndex = 0;

var sources = [];
for (var i = 0; i < map.sources.length; ++i) {
var sourceURL = map.sources[i];
if (map.sourceRoot)
sourceURL = map.sourceRoot + "/" + sourceURL;
var url = this._canonicalizeURL(sourceURL, this._sourceMappingURL);
sources.push(url);
if (!this._reverseMappingsBySourceURL[url])
this._reverseMappingsBySourceURL[url] = [];
if (map.sourcesContent && map.sourcesContent[i])
this._sourceContentByURL[url] = map.sourcesContent[i];
}

var stringCharIterator = new WebInspector.SourceMapParser.StringCharIterator(map.mappings);
var sourceURL = sources[sourceIndex];
var reverseMappings = this._reverseMappingsBySourceURL[sourceURL];

while (true) {
if (stringCharIterator.peek() === ",")
stringCharIterator.next();
else {
while (stringCharIterator.peek() === ";") {
lineNumber += 1;
columnNumber = 0;
stringCharIterator.next();
}
if (!stringCharIterator.hasNext())
break;
}

columnNumber += this._decodeVLQ(stringCharIterator);
if (this._isSeparator(stringCharIterator.peek())) {
this._mappings.push([lineNumber, columnNumber]);
continue;
}

var sourceIndexDelta = this._decodeVLQ(stringCharIterator);
if (sourceIndexDelta) {
sourceIndex += sourceIndexDelta;
sourceURL = sources[sourceIndex];
reverseMappings = this._reverseMappingsBySourceURL[sourceURL];
}
sourceLineNumber += this._decodeVLQ(stringCharIterator);
sourceColumnNumber += this._decodeVLQ(stringCharIterator);
if (!this._isSeparator(stringCharIterator.peek()))
nameIndex += this._decodeVLQ(stringCharIterator);

this._mappings.push([lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber]);
if (!reverseMappings[sourceLineNumber])
reverseMappings[sourceLineNumber] = [lineNumber, columnNumber];
}
},

_isSeparator: function(char)
{
return char === "," || char === ";";
},

_decodeVLQ: function(stringCharIterator)
{

var result = 0;
var shift = 0;
do {
var digit = this._base64Map[stringCharIterator.next()];
result += (digit & this._VLQ_BASE_MASK) << shift;
shift += this._VLQ_BASE_SHIFT;
} while (digit & this._VLQ_CONTINUATION_MASK);


var negative = result & 1;
result >>= 1;
return negative ? -result : result;
},

_canonicalizeURL: function(url, baseURL)
{
if (!url || !baseURL || url.asParsedURL() || url.substring(0, 5) === "data:")
return url;

var base = baseURL.asParsedURL();
if (!base)
return url;

var baseHost = base.scheme + "://" + base.host + (base.port ? ":" + base.port : "");
if (url[0] === "/")
return baseHost + url;
return baseHost + base.folderPathComponents + "/" + url;
},

_VLQ_BASE_SHIFT: 5,
_VLQ_BASE_MASK: (1 << 5) - 1,
_VLQ_CONTINUATION_MASK: 1 << 5
}


WebInspector.SourceMapParser.StringCharIterator = function(string)
{
this._string = string;
this._position = 0;
}

WebInspector.SourceMapParser.StringCharIterator.prototype = {
next: function()
{
return this._string.charAt(this._position++);
},

peek: function()
{
return this._string.charAt(this._position);
},

hasNext: function()
{
return this._position < this._string.length;
}
}






WebInspector.SASSSourceMapping = function(workspace)
{
this._workspace = workspace;
this._uiSourceCodeForURL = {};
this._uiLocations = {};
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._reset, this);
}

WebInspector.SASSSourceMapping.prototype = {
_populate: function()
{
function populateFrame(frame)
{
for (var i = 0; i < frame.childFrames.length; ++i)
populateFrame.call(this, frame.childFrames[i]);

var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this._resourceAdded({data:resources[i]});
}

populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
},


_resourceAdded: function(event)
{
var resource =   event.data;
if (resource.type !== WebInspector.resourceTypes.Stylesheet)
return;


function didRequestContent(content, contentEncoded, mimeType)
{
if (!content)
return;
var lines = content.split(/\r?\n/);
var debugInfoRegex = /@media\s\-sass\-debug\-info{filename{font-family:([^}]+)}line{font-family:\\[0]+([^}]*)}}/i;
            var lineNumbersRegex = /\/\*\s+line\s+([0-9]+),\s+([^*\/]+)/;
for (var lineNumber = 0; lineNumber < lines.length; ++lineNumber) {
var match = debugInfoRegex.exec(lines[lineNumber]);
if (match) {
var url = match[1].replace(/\\(.)/g, "$1");
var line = parseInt(decodeURI(match[2].replace(/(..)/g, "%$1")), 10);
this._bindUISourceCode(url, line, resource.url, lineNumber);
continue;
}
match = lineNumbersRegex.exec(lines[lineNumber]);
if (match) {
var fileName = match[2].trim();
var line = parseInt(match[1], 10);
var url = resource.url;
if (url.endsWith("/" + resource.parsedURL.lastPathComponent))
url = url.substring(0, url.length - resource.parsedURL.lastPathComponent.length) + fileName;
else
url = fileName;
this._bindUISourceCode(url, line, resource.url, lineNumber);
continue;
}
}
}
resource.requestContent(didRequestContent.bind(this));
},


_bindUISourceCode: function(url, line, rawURL, rawLine)
{
var uiSourceCode = this._uiSourceCodeForURL[url];
if (!uiSourceCode) {
uiSourceCode = new WebInspector.SASSSource(url);
this._uiSourceCodeForURL[url] = uiSourceCode;
this._workspace.project().addUISourceCode(uiSourceCode);
WebInspector.cssModel.setSourceMapping(rawURL, this);
}
var rawLocationString = rawURL + ":" + (rawLine + 1);  
this._uiLocations[rawLocationString] = new WebInspector.UILocation(uiSourceCode, line - 1, 0);
},


rawLocationToUILocation: function(rawLocation)
{
var location =   rawLocation;
var uiLocation = this._uiLocations[location.url + ":" + location.lineNumber];
if (!uiLocation) {
var uiSourceCode = this._workspace.uiSourceCodeForURL(location.url);
uiLocation = new WebInspector.UILocation(uiSourceCode, location.lineNumber, 0);
}
return uiLocation;
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{

return new WebInspector.CSSLocation(uiSourceCode.contentURL() || "", lineNumber);
},

_reset: function()
{
this._uiSourceCodeForURL = {};
this._uiLocations = {};
this._populate();
}
}


WebInspector.SASSSource = function(sassURL)
{
var content = InspectorFrontendHost.loadResourceSynchronously(sassURL);
var contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Stylesheet, content, "text/x-scss");
WebInspector.UISourceCode.call(this, sassURL, null, contentProvider);
}

WebInspector.SASSSource.prototype = {

isEditable: function()
{
return true;
}
}

WebInspector.SASSSource.prototype.__proto__ = WebInspector.UISourceCode.prototype;






WebInspector.DOMNode = function(domAgent, doc, isInShadowTree, payload) {
this._domAgent = domAgent;
this.ownerDocument = doc;
this._isInShadowTree = isInShadowTree;

this.id = payload.nodeId;
domAgent._idToDOMNode[this.id] = this;
this._nodeType = payload.nodeType;
this._nodeName = payload.nodeName;
this._localName = payload.localName;
this._nodeValue = payload.nodeValue;

this._shadowRoots = [];

this._attributes = [];
this._attributesMap = {};
if (payload.attributes)
this._setAttributesPayload(payload.attributes);

this._userProperties = {};
this._descendantUserPropertyCounters = {};

this._childNodeCount = payload.childNodeCount;
this.children = null;

this.nextSibling = null;
this.previousSibling = null;
this.firstChild = null;
this.lastChild = null;
this.parentNode = null;

if (payload.children)
this._setChildrenPayload(payload.children);

if (payload.contentDocument) {
this._contentDocument = new WebInspector.DOMDocument(domAgent, payload.contentDocument);
this.children = [this._contentDocument];
this._renumber();
}

if (payload.shadowRoots && WebInspector.experimentsSettings.showShadowDOM.isEnabled()) {
for (var i = 0; i < payload.shadowRoots.length; ++i) {
var root = payload.shadowRoots[i];
var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, true, root);
this._shadowRoots.push(node);
}
}

if (this._nodeType === Node.ELEMENT_NODE) {

if (this.ownerDocument && !this.ownerDocument.documentElement && this._nodeName === "HTML")
this.ownerDocument.documentElement = this;
if (this.ownerDocument && !this.ownerDocument.body && this._nodeName === "BODY")
this.ownerDocument.body = this;
} else if (this._nodeType === Node.DOCUMENT_TYPE_NODE) {
this.publicId = payload.publicId;
this.systemId = payload.systemId;
this.internalSubset = payload.internalSubset;
} else if (this._nodeType === Node.ATTRIBUTE_NODE) {
this.name = payload.name;
this.value = payload.value;
}
}


WebInspector.DOMNode.XPathStep = function(value, optimized)
{
this.value = value;
this.optimized = optimized;
}

WebInspector.DOMNode.XPathStep.prototype = {
toString: function()
{
return this.value;
}
}

WebInspector.DOMNode.prototype = {

hasAttributes: function()
{
return this._attributes.length > 0;
},


hasChildNodes: function()
{
return this._childNodeCount > 0 || !!this._shadowRoots.length;
},


nodeType: function()
{
return this._nodeType;
},


nodeName: function()
{
return this._nodeName;
},


isInShadowTree: function()
{
return this._isInShadowTree;
},


nodeNameInCorrectCase: function()
{
return this.isXMLNode() ? this.nodeName() : this.nodeName().toLowerCase();
},


setNodeName: function(name, callback)
{
DOMAgent.setNodeName(this.id, name, WebInspector.domAgent._markRevision(this, callback));
},


localName: function()
{
return this._localName;
},


nodeValue: function()
{
return this._nodeValue;
},


setNodeValue: function(value, callback)
{
DOMAgent.setNodeValue(this.id, value, WebInspector.domAgent._markRevision(this, callback));
},


getAttribute: function(name)
{
var attr = this._attributesMap[name];
return attr ? attr.value : undefined;
},


setAttribute: function(name, text, callback)
{
DOMAgent.setAttributesAsText(this.id, text, name, WebInspector.domAgent._markRevision(this, callback));
},


setAttributeValue: function(name, value, callback)
{
DOMAgent.setAttributeValue(this.id, name, value, WebInspector.domAgent._markRevision(this, callback));
},


attributes: function()
{
return this._attributes;
},


removeAttribute: function(name, callback)
{

function mycallback(error)
{
if (!error) {
delete this._attributesMap[name];
for (var i = 0;  i < this._attributes.length; ++i) {
if (this._attributes[i].name === name) {
this._attributes.splice(i, 1);
break;
}
}
}

WebInspector.domAgent._markRevision(this, callback)(error);
}
DOMAgent.removeAttribute(this.id, name, mycallback.bind(this));
},


getChildNodes: function(callback)
{
if (this.children) {
if (callback)
callback(this.children);
return;
}


function mycallback(error)
{
if (!error && callback)
callback(this.children);
}

DOMAgent.requestChildNodes(this.id, mycallback.bind(this));
},


getOuterHTML: function(callback)
{
DOMAgent.getOuterHTML(this.id, callback);
},


setOuterHTML: function(html, callback)
{
DOMAgent.setOuterHTML(this.id, html, WebInspector.domAgent._markRevision(this, callback));
},


removeNode: function(callback)
{
DOMAgent.removeNode(this.id, WebInspector.domAgent._markRevision(this, callback));
},

copyNode: function()
{
function copy(error, text)
{
if (!error)
InspectorFrontendHost.copyText(text);
}
DOMAgent.getOuterHTML(this.id, copy);
},


copyXPath: function(optimized)
{
InspectorFrontendHost.copyText(this.xPath(optimized));
},


eventListeners: function(callback)
{
DOMAgent.getEventListenersForNode(this.id, callback);
},


path: function()
{
var path = [];
var node = this;
while (node && "index" in node && node._nodeName.length) {
path.push([node.index, node._nodeName]);
node = node.parentNode;
}
path.reverse();
return path.join(",");
},


appropriateSelectorFor: function(justSelector)
{
var lowerCaseName = this.localName() || this.nodeName().toLowerCase();

var id = this.getAttribute("id");
if (id) {
var selector = "#" + id;
return (justSelector ? selector : lowerCaseName + selector);
}

var className = this.getAttribute("class");
if (className) {
var selector = "." + className.trim().replace(/\s+/g, ".");
return (justSelector ? selector : lowerCaseName + selector);
}

if (lowerCaseName === "input" && this.getAttribute("type"))
return lowerCaseName + "[type=\"" + this.getAttribute("type") + "\"]";

return lowerCaseName;
},


isAncestor: function(node)
{
if (!node)
return false;

var currentNode = node.parentNode;
while (currentNode) {
if (this === currentNode)
return true;
currentNode = currentNode.parentNode;
}
return false;
},


isDescendant: function(descendant)
{
return descendant !== null && descendant.isAncestor(this);
},


_setAttributesPayload: function(attrs)
{
var attributesChanged = !this._attributes || attrs.length !== this._attributes.length * 2;
var oldAttributesMap = this._attributesMap || {};

this._attributes = [];
this._attributesMap = {};

for (var i = 0; i < attrs.length; i += 2) {
var name = attrs[i];
var value = attrs[i + 1];
this._addAttribute(name, value);

if (attributesChanged)
continue;

if (!oldAttributesMap[name] || oldAttributesMap[name].value !== value)
attributesChanged = true;
}
return attributesChanged;
},


_insertChild: function(prev, payload)
{
var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, this._isInShadowTree, payload);
if (!prev) {
if (!this.children) {

this.children = this._shadowRoots.concat([ node ]);
} else
this.children.unshift(node);
} else
this.children.splice(this.children.indexOf(prev) + 1, 0, node);
this._renumber();
return node;
},


_removeChild: function(node)
{
this.children.splice(this.children.indexOf(node), 1);
node.parentNode = null;
node._updateChildUserPropertyCountsOnRemoval(this);
this._renumber();
},


_setChildrenPayload: function(payloads)
{

if (this._contentDocument)
return;

this.children = this._shadowRoots.slice();
for (var i = 0; i < payloads.length; ++i) {
var payload = payloads[i];
var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, this._isInShadowTree, payload);
this.children.push(node);
}
this._renumber();
},

_renumber: function()
{
this._childNodeCount = this.children.length;
if (this._childNodeCount == 0) {
this.firstChild = null;
this.lastChild = null;
return;
}
this.firstChild = this.children[0];
this.lastChild = this.children[this._childNodeCount - 1];
for (var i = 0; i < this._childNodeCount; ++i) {
var child = this.children[i];
child.index = i;
child.nextSibling = i + 1 < this._childNodeCount ? this.children[i + 1] : null;
child.previousSibling = i - 1 >= 0 ? this.children[i - 1] : null;
child.parentNode = this;
}
},


_addAttribute: function(name, value)
{
var attr = {
name: name,
value: value,
_node: this
};
this._attributesMap[name] = attr;
this._attributes.push(attr);
},


_setAttribute: function(name, value)
{
var attr = this._attributesMap[name];
if (attr)
attr.value = value;
else
this._addAttribute(name, value);
},


_removeAttribute: function(name)
{
var attr = this._attributesMap[name];
if (attr) {
this._attributes.remove(attr);
delete this._attributesMap[name];
}
},


moveTo: function(targetNode, anchorNode, callback)
{
DOMAgent.moveTo(this.id, targetNode.id, anchorNode ? anchorNode.id : undefined, WebInspector.domAgent._markRevision(this, callback));
},


isXMLNode: function()
{
return !!this.ownerDocument && !!this.ownerDocument.xmlVersion;
},


xPath: function(optimized)
{
if (this._nodeType === Node.DOCUMENT_NODE)
return "/";

var steps = [];
var contextNode = this;
while (contextNode) {
var step = contextNode._xPathValue(optimized);
if (!step)
break; 
steps.push(step);
if (step.optimized)
break;
contextNode = contextNode.parentNode;
}

steps.reverse();
return (steps.length && steps[0].optimized ? "" : "/") + steps.join("/");
},


_xPathValue: function(optimized)
{
var ownValue;
var ownIndex = this._xPathIndex();
if (ownIndex === -1)
return null; 

switch (this._nodeType) {
case Node.ELEMENT_NODE:
if (optimized && this.getAttribute("id"))
return new WebInspector.DOMNode.XPathStep("//*[@id=\"" + this.getAttribute("id") + "\"]", true);
ownValue = this._localName;
break;
case Node.ATTRIBUTE_NODE:
ownValue = "@" + this._nodeName;
break;
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
ownValue = "text()";
break;
case Node.PROCESSING_INSTRUCTION_NODE:
ownValue = "processing-instruction()";
break;
case Node.COMMENT_NODE:
ownValue = "comment()";
break;
case Node.DOCUMENT_NODE:
ownValue = "";
break;
default:
ownValue = "";
break;
}

if (ownIndex > 0)
ownValue += "[" + ownIndex + "]";

return new WebInspector.DOMNode.XPathStep(ownValue, this._nodeType === Node.DOCUMENT_NODE);
},


_xPathIndex: function()
{

function areNodesSimilar(left, right)
{
if (left === right)
return true;

if (left._nodeType === Node.ELEMENT_NODE && right._nodeType === Node.ELEMENT_NODE)
return left._localName === right._localName;

if (left._nodeType === right._nodeType)
return true;


var leftType = left._nodeType === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : left._nodeType;
var rightType = right._nodeType === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : right._nodeType;
return leftType === rightType;
}

var siblings = this.parentNode ? this.parentNode.children : null;
if (!siblings)
return 0; 
var hasSameNamedElements;
for (var i = 0; i < siblings.length; ++i) {
if (areNodesSimilar(this, siblings[i]) && siblings[i] !== this) {
hasSameNamedElements = true;
break;
}
}
if (!hasSameNamedElements)
return 0;
var ownIndex = 1; 
for (var i = 0; i < siblings.length; ++i) {
if (areNodesSimilar(this, siblings[i])) {
if (siblings[i] === this)
return ownIndex;
++ownIndex;
}
}
return -1; 
},

_updateChildUserPropertyCountsOnRemoval: function(parentNode)
{
var result = {};
if (this._userProperties) {
for (var name in this._userProperties)
result[name] = (result[name] || 0) + 1;
}

if (this._descendantUserPropertyCounters) {
for (var name in this._descendantUserPropertyCounters) {
var counter = this._descendantUserPropertyCounters[name];
result[name] = (result[name] || 0) + counter;
}
}

for (var name in result)
parentNode._updateDescendantUserPropertyCount(name, -result[name]);
},

_updateDescendantUserPropertyCount: function(name, delta)
{
if (!this._descendantUserPropertyCounters.hasOwnProperty(name))
this._descendantUserPropertyCounters[name] = 0;
this._descendantUserPropertyCounters[name] += delta;
if (!this._descendantUserPropertyCounters[name])
delete this._descendantUserPropertyCounters[name];
if (this.parentNode)
this.parentNode._updateDescendantUserPropertyCount(name, delta);
},

setUserProperty: function(name, value)
{
if (value === null) {
this.removeUserProperty(name);
return;
}

if (this.parentNode && !this._userProperties.hasOwnProperty(name))
this.parentNode._updateDescendantUserPropertyCount(name, 1);

this._userProperties[name] = value;
},

removeUserProperty: function(name)
{
if (!this._userProperties.hasOwnProperty(name))
return;

delete this._userProperties[name];
if (this.parentNode)
this.parentNode._updateDescendantUserPropertyCount(name, -1);
},

getUserProperty: function(name)
{
return this._userProperties ? this._userProperties[name] : null;
},

descendantUserPropertyCount: function(name)
{
return this._descendantUserPropertyCounters && this._descendantUserPropertyCounters[name] ? this._descendantUserPropertyCounters[name] : 0;
},


resolveURL: function(url)
{
if (!url)
return url;
for (var frameOwnerCandidate = this; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
if (frameOwnerCandidate.documentURL)
return WebInspector.ParsedURL.completeURL(frameOwnerCandidate.documentURL, url);
}
return null;
}
}


WebInspector.DOMDocument = function(domAgent, payload)
{
WebInspector.DOMNode.call(this, domAgent, this, false, payload);
this.documentURL = payload.documentURL || "";
this.xmlVersion = payload.xmlVersion;
this._listeners = {};
}

WebInspector.DOMDocument.prototype.__proto__ = WebInspector.DOMNode.prototype;


WebInspector.DOMAgent = function() {

this._idToDOMNode = {};
this._document = null;
this._attributeLoadNodeIds = {};
InspectorBackend.registerDOMDispatcher(new WebInspector.DOMDispatcher(this));
if (WebInspector.settings.emulateTouchEvents.get())
this._emulateTouchEventsChanged();
WebInspector.settings.emulateTouchEvents.addChangeListener(this._emulateTouchEventsChanged, this);
}

WebInspector.DOMAgent.Events = {
AttrModified: "AttrModified",
AttrRemoved: "AttrRemoved",
CharacterDataModified: "CharacterDataModified",
NodeInserted: "NodeInserted",
NodeRemoved: "NodeRemoved",
DocumentUpdated: "DocumentUpdated",
ChildNodeCountUpdated: "ChildNodeCountUpdated",
InspectElementRequested: "InspectElementRequested",
UndoRedoRequested: "UndoRedoRequested",
UndoRedoCompleted: "UndoRedoCompleted"
}

WebInspector.DOMAgent.prototype = {

requestDocument: function(callback)
{
if (this._document) {
if (callback)
callback(this._document);
return;
}

if (this._pendingDocumentRequestCallbacks) {
this._pendingDocumentRequestCallbacks.push(callback);
return;
}

this._pendingDocumentRequestCallbacks = [callback];


function onDocumentAvailable(error, root)
{
if (!error)
this._setDocument(root);

for (var i = 0; i < this._pendingDocumentRequestCallbacks.length; ++i) {
var callback = this._pendingDocumentRequestCallbacks[i];
if (callback)
callback(this._document);
}
delete this._pendingDocumentRequestCallbacks;
}

DOMAgent.getDocument(onDocumentAvailable.bind(this));
},


existingDocument: function()
{
return this._document;
},


pushNodeToFrontend: function(objectId, callback)
{
var callbackCast =   callback;
this._dispatchWhenDocumentAvailable(DOMAgent.requestNode.bind(DOMAgent, objectId), callbackCast);
},


pushNodeByPathToFrontend: function(path, callback)
{
var callbackCast =   callback;
this._dispatchWhenDocumentAvailable(DOMAgent.pushNodeByPathToFrontend.bind(DOMAgent, path), callbackCast);
},


_wrapClientCallback: function(callback)
{
if (!callback)
return;

return function(error, result)
{

callback(error ? null : result);
}
},


_dispatchWhenDocumentAvailable: function(func, callback)
{
var callbackWrapper =   this._wrapClientCallback(callback);

function onDocumentAvailable()
{
if (this._document)
func(callbackWrapper);
else {
if (callbackWrapper)
callbackWrapper("No document");
}
}
this.requestDocument(onDocumentAvailable.bind(this));
},


_attributeModified: function(nodeId, name, value)
{
var node = this._idToDOMNode[nodeId];
if (!node)
return;

node._setAttribute(name, value);
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: name });
},


_attributeRemoved: function(nodeId, name)
{
var node = this._idToDOMNode[nodeId];
if (!node)
return;
node._removeAttribute(name);
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrRemoved, { node: node, name: name });
},


_inlineStyleInvalidated: function(nodeIds)
{
for (var i = 0; i < nodeIds.length; ++i)
this._attributeLoadNodeIds[nodeIds[i]] = true;
if ("_loadNodeAttributesTimeout" in this)
return;
this._loadNodeAttributesTimeout = setTimeout(this._loadNodeAttributes.bind(this), 0);
},

_loadNodeAttributes: function()
{

function callback(nodeId, error, attributes)
{
if (error) {

return;
}
var node = this._idToDOMNode[nodeId];
if (node) {
if (node._setAttributesPayload(attributes))
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: "style" });
}
}

delete this._loadNodeAttributesTimeout;

for (var nodeId in this._attributeLoadNodeIds) {
var nodeIdAsNumber = parseInt(nodeId, 10);
DOMAgent.getAttributes(nodeIdAsNumber, callback.bind(this, nodeIdAsNumber));
}
this._attributeLoadNodeIds = {};
},


_characterDataModified: function(nodeId, newValue)
{
var node = this._idToDOMNode[nodeId];
node._nodeValue = newValue;
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.CharacterDataModified, node);
},


nodeForId: function(nodeId)
{
return this._idToDOMNode[nodeId];
},

_documentUpdated: function()
{
this._setDocument(null);
},


_setDocument: function(payload)
{
this._idToDOMNode = {};
if (payload && "nodeId" in payload)
this._document = new WebInspector.DOMDocument(this, payload);
else
this._document = null;
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.DocumentUpdated, this._document);
},


_setDetachedRoot: function(payload)
{
if (payload.nodeName === "#document")
new WebInspector.DOMDocument(this, payload);
else
new WebInspector.DOMNode(this, null, false, payload);
},


_setChildNodes: function(parentId, payloads)
{
if (!parentId && payloads.length) {
this._setDetachedRoot(payloads[0]);
return;
}

var parent = this._idToDOMNode[parentId];
parent._setChildrenPayload(payloads);
},


_childNodeCountUpdated: function(nodeId, newValue)
{
var node = this._idToDOMNode[nodeId];
node._childNodeCount = newValue;
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, node);
},


_childNodeInserted: function(parentId, prevId, payload)
{
var parent = this._idToDOMNode[parentId];
var prev = this._idToDOMNode[prevId];
var node = parent._insertChild(prev, payload);
this._idToDOMNode[node.id] = node;
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeInserted, node);
},


_childNodeRemoved: function(parentId, nodeId)
{
var parent = this._idToDOMNode[parentId];
var node = this._idToDOMNode[nodeId];
parent._removeChild(node);
this._unbind(node);
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: node, parent: parent});
},


_shadowRootPopped: function(rootId)
{
},


_unbind: function(node)
{
delete this._idToDOMNode[node.id];
for (var i = 0; node.children && i < node.children.length; ++i)
this._unbind(node.children[i]);
},


inspectElement: function(nodeId)
{
var node = this._idToDOMNode[nodeId];
if (node)
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.InspectElementRequested, node);
},


performSearch: function(query, searchCallback)
{
this.cancelSearch();


function callback(error, searchId, resultsCount)
{
this._searchId = searchId;
searchCallback(resultsCount);
}
DOMAgent.performSearch(query, callback.bind(this));
},


searchResult: function(index, callback)
{
if (this._searchId) {

function mycallback(error, nodeIds)
{
if (error) {
console.error(error);
callback(null);
return;
}
if (nodeIds.length != 1)
return;

callback(this._idToDOMNode[nodeIds[0]]);
}
DOMAgent.getSearchResults(this._searchId, index, index + 1, mycallback.bind(this));
} else
callback(null);
},

cancelSearch: function()
{
if (this._searchId) {
DOMAgent.discardSearchResults(this._searchId);
delete this._searchId;
}
},


querySelector: function(nodeId, selectors, callback)
{
var callbackCast =  callback;
DOMAgent.querySelector(nodeId, selectors, this._wrapClientCallback(callbackCast));
},


querySelectorAll: function(nodeId, selectors, callback)
{
var callbackCast =  callback;
DOMAgent.querySelectorAll(nodeId, selectors, this._wrapClientCallback(callbackCast));
},


highlightDOMNode: function(nodeId, mode)
{
if (this._hideDOMNodeHighlightTimeout) {
clearTimeout(this._hideDOMNodeHighlightTimeout);
delete this._hideDOMNodeHighlightTimeout;
}

this._highlightedDOMNodeId = nodeId;
if (nodeId)
DOMAgent.highlightNode(nodeId, this._buildHighlightConfig(mode));
else
DOMAgent.hideHighlight();
},

hideDOMNodeHighlight: function()
{
this.highlightDOMNode(0);
},


highlightDOMNodeForTwoSeconds: function(nodeId)
{
this.highlightDOMNode(nodeId);
this._hideDOMNodeHighlightTimeout = setTimeout(this.hideDOMNodeHighlight.bind(this), 2000);
},


setInspectModeEnabled: function(enabled, callback)
{
DOMAgent.setInspectModeEnabled(enabled, this._buildHighlightConfig(), callback);
},


_buildHighlightConfig: function(mode)
{
mode = mode || "all";
var highlightConfig = { showInfo: mode === "all" };
if (mode === "all" || mode === "content")
highlightConfig.contentColor = WebInspector.Color.PageHighlight.Content.toProtocolRGBA();

if (mode === "all" || mode === "padding")
highlightConfig.paddingColor = WebInspector.Color.PageHighlight.Padding.toProtocolRGBA();

if (mode === "all" || mode === "border")
highlightConfig.borderColor = WebInspector.Color.PageHighlight.Border.toProtocolRGBA();

if (mode === "all" || mode === "margin")
highlightConfig.marginColor = WebInspector.Color.PageHighlight.Margin.toProtocolRGBA();

return highlightConfig;
},


_markRevision: function(node, callback)
{
function wrapperFunction(error)
{
if (!error)
this.markUndoableState();

if (callback)
callback.apply(this, arguments);
}
return wrapperFunction.bind(this);
},

_emulateTouchEventsChanged: function()
{
const injectedFunction = function() {
const touchEvents = ["ontouchstart", "ontouchend", "ontouchmove", "ontouchcancel"];
for (var i = 0; i < touchEvents.length; ++i) {
if (!(touchEvents[i] in window.__proto__))
Object.defineProperty(window.__proto__, touchEvents[i], { value: null, writable: true, configurable: true, enumerable: true });
if (!(touchEvents[i] in document.__proto__))
Object.defineProperty(document.__proto__, touchEvents[i], { value: null, writable: true, configurable: true, enumerable: true });
}
}

var emulationEnabled = WebInspector.settings.emulateTouchEvents.get();
if (emulationEnabled && !this._addTouchEventsScriptInjecting) {
this._addTouchEventsScriptInjecting = true;
PageAgent.addScriptToEvaluateOnLoad("(" + injectedFunction.toString() + ")", scriptAddedCallback.bind(this));
} else {
if (typeof this._addTouchEventsScriptId !== "undefined") {
PageAgent.removeScriptToEvaluateOnLoad(this._addTouchEventsScriptId);
delete this._addTouchEventsScriptId;
}
}

function scriptAddedCallback(error, scriptId)
{
delete this._addTouchEventsScriptInjecting;
if (error)
return;
this._addTouchEventsScriptId = scriptId;
}

PageAgent.setTouchEmulationEnabled(emulationEnabled);
},

markUndoableState: function()
{
DOMAgent.markUndoableState();
},


undo: function(callback)
{
function mycallback(error)
{
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoCompleted);
callback(error);
}

this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoRequested);
DOMAgent.undo(callback);
},


redo: function(callback)
{
function mycallback(error)
{
this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoCompleted);
callback(error);
}

this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoRequested);
DOMAgent.redo(callback);
}
}

WebInspector.DOMAgent.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.DOMDispatcher = function(domAgent)
{
this._domAgent = domAgent;
}

WebInspector.DOMDispatcher.prototype = {
documentUpdated: function()
{
this._domAgent._documentUpdated();
},


attributeModified: function(nodeId, name, value)
{
this._domAgent._attributeModified(nodeId, name, value);
},


attributeRemoved: function(nodeId, name)
{
this._domAgent._attributeRemoved(nodeId, name);
},


inlineStyleInvalidated: function(nodeIds)
{
this._domAgent._inlineStyleInvalidated(nodeIds);
},


characterDataModified: function(nodeId, characterData)
{
this._domAgent._characterDataModified(nodeId, characterData);
},


setChildNodes: function(parentId, payloads)
{
this._domAgent._setChildNodes(parentId, payloads);
},


childNodeCountUpdated: function(nodeId, childNodeCount)
{
this._domAgent._childNodeCountUpdated(nodeId, childNodeCount);
},


childNodeInserted: function(parentNodeId, previousNodeId, payload)
{
this._domAgent._childNodeInserted(parentNodeId, previousNodeId, payload);
},


childNodeRemoved: function(parentNodeId, nodeId)
{
this._domAgent._childNodeRemoved(parentNodeId, nodeId);
},


shadowRootPushed: function(hostId, root)
{
this._domAgent._childNodeInserted(hostId, 0, root);
},


shadowRootPopped: function(hostId, rootId)
{
this._domAgent._childNodeRemoved(hostId, rootId);
}
}


WebInspector.domAgent = null;






WebInspector.TestController = function()
{
}

WebInspector.TestController.prototype = {
notifyDone: function(callId, result)
{
var message = typeof result === "undefined" ? "\"<undefined>\"" : JSON.stringify(result);
RuntimeAgent.evaluate("didEvaluateForTestInFrontend(" + callId + ", " + message + ")", "test");
}
}

WebInspector.evaluateForTestInFrontend = function(callId, script)
{
function invokeMethod()
{
try {
script = script + "//@ sourceURL=evaluateInWebInspector" + callId + ".js";
var result = window.eval(script);
WebInspector.TestController.prototype.notifyDone(callId, result);
} catch (e) {
WebInspector.TestController.prototype.notifyDone(callId, e.toString());
}
}
InspectorBackend.runAfterPendingDispatches(invokeMethod);
}






WebInspector.Dialog = function(relativeToElement, delegate)
{
this._delegate = delegate;
this._relativeToElement = relativeToElement;


this._glassPaneElement = document.body.createChild("div");
this._glassPaneElement.className = "dialog-glass-pane";
this._glassPaneElement.tabIndex = 0;
this._glassPaneElement.addEventListener("focus", this._onGlassPaneFocus.bind(this), false);

this._element = this._glassPaneElement.createChild("div");
this._element.tabIndex = 0;
this._element.addEventListener("focus", this._onFocus.bind(this), false);
this._element.addEventListener("keydown", this._onKeyDown.bind(this), false);
this._closeKeys = [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
];

delegate.show(this._element);

this._position();
this._windowResizeHandler = this._position.bind(this);
window.addEventListener("resize", this._windowResizeHandler, true);

this._previousFocusElement = WebInspector.currentFocusElement();
this._delegate.focus();
}


WebInspector.Dialog.currentInstance = function()
{
return WebInspector.Dialog._instance;
}


WebInspector.Dialog.show = function(relativeToElement, delegate)
{
if (WebInspector.Dialog._instance)
return;
WebInspector.Dialog._instance = new WebInspector.Dialog(relativeToElement, delegate);
}

WebInspector.Dialog.hide = function()
{
if (!WebInspector.Dialog._instance)
return;
WebInspector.Dialog._instance._hide();
}

WebInspector.Dialog.prototype = {
_hide: function()
{
if (this._isHiding)
return;
this._isHiding = true;

this._delegate.willHide();

if (this._element.isSelfOrAncestor(document.activeElement))
WebInspector.setCurrentFocusElement(this._previousFocusElement);
delete WebInspector.Dialog._instance;
document.body.removeChild(this._glassPaneElement);
window.removeEventListener("resize", this._windowResizeHandler, true);
},

_onGlassPaneFocus: function(event)
{
this._hide();
},

_onFocus: function(event)
{
this._delegate.focus();
},

_position: function()
{
this._delegate.position(this._element, this._relativeToElement);
},

_onKeyDown: function(event)
{
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) {
event.preventDefault();
return;
}

if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code)
this._delegate.onEnter();

if (this._closeKeys.indexOf(event.keyCode) >= 0) {
this._hide();
event.consume(true);
}
}
};


WebInspector.DialogDelegate = function()
{
}

WebInspector.DialogDelegate.prototype = {

show: function(element)
{
element.appendChild(this.element);
this.element.addStyleClass("dialog-contents");
element.addStyleClass("dialog");    
},


position: function(element, relativeToElement)
{
var offset = relativeToElement.offsetRelativeToWindow(window);

var positionX = offset.x + (relativeToElement.offsetWidth - element.offsetWidth) / 2;
positionX = Number.constrain(positionX, 0, window.innerWidth - element.offsetWidth);

var positionY = offset.y + (relativeToElement.offsetHeight - element.offsetHeight) / 2;
positionY = Number.constrain(positionY, 0, window.innerHeight - element.offsetHeight);

element.style.left = positionX + "px";
element.style.top = positionY + "px";
},

focus: function() { },

onEnter: function() { },

willHide: function() { }
};

WebInspector.DialogDelegate.prototype.__proto__ = WebInspector.Object.prototype;






WebInspector.GoToLineDialog = function(view)
{
WebInspector.DialogDelegate.call(this);

this.element = document.createElement("div");
this.element.className = "go-to-line-dialog";

this.element.createChild("label").textContent = WebInspector.UIString("Go to line: ");

this._input = this.element.createChild("input");
this._input.setAttribute("type", "text");
this._input.setAttribute("size", 6);

this._goButton = this.element.createChild("button");
this._goButton.textContent = WebInspector.UIString("Go");
this._goButton.addEventListener("click", this._onGoClick.bind(this), false);

this._view = view;
}


WebInspector.GoToLineDialog.install = function(panel, viewGetter)
{
function showGoToLineDialog()
{
var view = viewGetter();
if (view)
WebInspector.GoToLineDialog._show(view);
}

var goToLineShortcut = WebInspector.GoToLineDialog.createShortcut();
panel.registerShortcut(goToLineShortcut.key, showGoToLineDialog);
}

WebInspector.GoToLineDialog._show = function(sourceView)
{
if (!sourceView || !sourceView.canHighlightLine())
return;
WebInspector.Dialog.show(sourceView.element, new WebInspector.GoToLineDialog(sourceView));
}

WebInspector.GoToLineDialog.createShortcut = function()
{
var isMac = WebInspector.isMac();
var shortcut;
if (isMac)
return WebInspector.KeyboardShortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Meta);
return WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
}

WebInspector.GoToLineDialog.prototype = {
focus: function()
{
WebInspector.setCurrentFocusElement(this._input);
this._input.select();
},

_onGoClick: function()
{
this._applyLineNumber();
WebInspector.Dialog.hide();
},

_applyLineNumber: function()
{
var value = this._input.value;
var lineNumber = parseInt(value, 10) - 1;
if (!isNaN(lineNumber) && lineNumber >= 0)
this._view.highlightLine(lineNumber);
},

onEnter: function()
{
this._applyLineNumber();
}
}

WebInspector.GoToLineDialog.prototype.__proto__ = WebInspector.DialogDelegate.prototype;






WebInspector.SidebarOverlay = function(view, widthSettingName, minimalWidth)
{
this.element = document.createElement("div");
this.element.className = "sidebar-overlay";

this._view = view;
this._widthSettingName = widthSettingName;
this._minimalWidth = minimalWidth;
this._savedWidth = minimalWidth || 300;

if (this._widthSettingName)
WebInspector.settings[this._widthSettingName] = WebInspector.settings.createSetting(this._widthSettingName, undefined);

this._resizerElement = document.createElement("div");
this._resizerElement.className = "sidebar-overlay-resizer";
this._installResizer(this._resizerElement);
}

WebInspector.SidebarOverlay.prototype = {

show: function(relativeToElement)
{
relativeToElement.appendChild(this.element);
relativeToElement.addStyleClass("sidebar-overlay-shown");
this._view.show(this.element);
this.element.appendChild(this._resizerElement);
if (this._resizerWidgetElement)
this.element.appendChild(this._resizerWidgetElement);
this.position(relativeToElement);
},


position: function(relativeToElement)
{
this._totalWidth = relativeToElement.offsetWidth;
this._setWidth(this._preferredWidth());
},

focus: function()
{
WebInspector.setCurrentFocusElement(this._view.element);
},

hide: function()
{
var element = this.element.parentElement;
if (!element)
return;

this._view.detach();
element.removeChild(this.element);
element.removeStyleClass("sidebar-overlay-shown");
this.element.removeChild(this._resizerElement);
if (this._resizerWidgetElement)
this.element.removeChild(this._resizerWidgetElement);
},


_setWidth: function(newWidth)
{
var width = Number.constrain(newWidth, this._minimalWidth, this._totalWidth);

if (this._width === width)
return;

this.element.style.width = width + "px";
this._resizerElement.style.left = (width - 3) + "px";
this._width = width;
this._view.doResize();
this._saveWidth();
},


_preferredWidth: function()
{
if (!this._widthSettingName)
return this._savedWidth;

return WebInspector.settings[this._widthSettingName].get() || this._savedWidth;
},

_saveWidth: function()
{
this._savedWidth = this._width;
if (!this._widthSettingName)
return;

WebInspector.settings[this._widthSettingName].set(this._width);
},


_startResizerDragging: function(event)
{
var width = this._width;
this._dragOffset = width - event.pageX;
return true;
},


_resizerDragging: function(event)
{
var width = event.pageX + this._dragOffset;
this._setWidth(width);
event.preventDefault();
},


_endResizerDragging: function(event)
{
delete this._dragOffset;
},


_installResizer: function(resizerElement)
{
WebInspector.installDragHandle(resizerElement, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "ew-resize");
},


set resizerWidgetElement(resizerWidgetElement)
{
this._resizerWidgetElement = resizerWidgetElement;
this._installResizer(resizerWidgetElement);
}
}






WebInspector.SettingsScreen = function(onHide)
{
WebInspector.HelpScreen.call(this);
this.element.id = "settings-screen";


this._onHide = onHide;

this._tabbedPane = new WebInspector.TabbedPane();
this._tabbedPane.element.addStyleClass("help-window-main");
this._tabbedPane.element.appendChild(this._createCloseButton());
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.General, WebInspector.UIString("General"), new WebInspector.GenericSettingsTab());
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.UserAgent, WebInspector.UIString("Overrides"), new WebInspector.UserAgentSettingsTab());
if (WebInspector.experimentsSettings.experimentsEnabled)
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.Experiments, WebInspector.UIString("Experiments"), new WebInspector.ExperimentsSettingsTab());
this._tabbedPane.appendTab(WebInspector.SettingsScreen.Tabs.Shortcuts, WebInspector.UIString("Shortcuts"), WebInspector.shortcutsScreen.createShortcutsTabView());
this._tabbedPane.shrinkableTabs = true;

this._lastSelectedTabSetting = WebInspector.settings.createSetting("lastSelectedSettingsTab", WebInspector.SettingsScreen.Tabs.General);
this.selectTab(this._lastSelectedTabSetting.get());
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
}

WebInspector.SettingsScreen.Tabs = {
General: "General",
UserAgent: "UserAgent",
Experiments: "Experiments",
Shortcuts: "Shortcuts"
}

WebInspector.SettingsScreen.prototype = {

selectTab: function(tabId)
{
this._tabbedPane.selectTab(tabId);
},


_tabSelected: function(event)
{
this._lastSelectedTabSetting.set(this._tabbedPane.selectedTabId);
},


wasShown: function()
{
this._tabbedPane.show(this.element);
WebInspector.HelpScreen.prototype.wasShown.call(this);
},


isClosingKey: function(keyCode)
{
return [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
].indexOf(keyCode) >= 0;
},


willHide: function()
{
this._onHide();
WebInspector.HelpScreen.prototype.willHide.call(this);
}
}

WebInspector.SettingsScreen.prototype.__proto__ = WebInspector.HelpScreen.prototype;


WebInspector.SettingsTab = function()
{
WebInspector.View.call(this);
this.element.className = "settings-tab help-content help-container";
}

WebInspector.SettingsTab.prototype = {

_appendSection: function(name)
{
var block = this.element.createChild("div", "help-block");
if (name)
block.createChild("div", "help-section-title").textContent = name;
return block;
},


_createCheckboxSetting: function(name, setting, omitParagraphElement, inputElement)
{
var input = inputElement || document.createElement("input");
input.type = "checkbox";
input.name = name;
input.checked = setting.get();

function listener()
{
setting.set(input.checked);
}
input.addEventListener("click", listener, false);

var label = document.createElement("label");
label.appendChild(input);
label.appendChild(document.createTextNode(name));
if (omitParagraphElement)
return label;

var p = document.createElement("p");
p.appendChild(label);
return p;
},

_createSelectSetting: function(name, options, setting)
{
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.createChild("label").textContent = name;

var select = document.createElement("select");
var settingValue = setting.get();

for (var i = 0; i < options.length; ++i) {
var option = options[i];
select.add(new Option(option[0], option[1]));
if (settingValue === option[1])
select.selectedIndex = i;
}

function changeListener(e)
{
setting.set(e.target.value);
}

select.addEventListener("change", changeListener, false);
fieldsetElement.appendChild(select);

var p = document.createElement("p");
p.appendChild(fieldsetElement);
return p;
},

_createRadioSetting: function(name, options, setting)
{
var pp = document.createElement("p");
var fieldsetElement = document.createElement("fieldset");
var legendElement = document.createElement("legend");
legendElement.textContent = name;
fieldsetElement.appendChild(legendElement);

function clickListener(e)
{
setting.set(e.target.value);
}

var settingValue = setting.get();
for (var i = 0; i < options.length; ++i) {
var p = document.createElement("p");
var label = document.createElement("label");
p.appendChild(label);

var input = document.createElement("input");
input.type = "radio";
input.name = setting.name;
input.value = options[i][0];
input.addEventListener("click", clickListener, false);
if (settingValue == input.value)
input.checked = true;

label.appendChild(input);
label.appendChild(document.createTextNode(options[i][1]));

fieldsetElement.appendChild(p);
}

pp.appendChild(fieldsetElement);
return pp;
},

_createCustomSetting: function(name, element)
{
var p = document.createElement("p");
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.createChild("label").textContent = name;
fieldsetElement.appendChild(element);
p.appendChild(fieldsetElement);
return p;
}
}

WebInspector.SettingsTab.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.GenericSettingsTab = function()
{
WebInspector.SettingsTab.call(this);

var p = this._appendSection();
if (Preferences.showDockToRight)
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Dock to right"), WebInspector.settings.dockToRight));
if (Preferences.exposeDisableCache)
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Disable cache"), WebInspector.settings.cacheDisabled));
var disableJSElement = this._createCheckboxSetting(WebInspector.UIString("Disable JavaScript"), WebInspector.settings.javaScriptDisabled);
p.appendChild(disableJSElement);
WebInspector.settings.javaScriptDisabled.addChangeListener(this._javaScriptDisabledChanged, this);
this._disableJSCheckbox = disableJSElement.getElementsByTagName("input")[0];
this._updateScriptDisabledCheckbox();

p = this._appendSection(WebInspector.UIString("Elements"));
p.appendChild(this._createRadioSetting(WebInspector.UIString("Color format"), [
[ WebInspector.Color.Format.Original, WebInspector.UIString("As authored") ],
[ WebInspector.Color.Format.HEX, "HEX: #DAC0DE" ],
[ WebInspector.Color.Format.RGB, "RGB: rgb(128, 255, 255)" ],
[ WebInspector.Color.Format.HSL, "HSL: hsl(300, 80%, 90%)" ] ], WebInspector.settings.colorFormat));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show user agent styles"), WebInspector.settings.showUserAgentStyles));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Word wrap"), WebInspector.settings.domWordWrap));

p = this._appendSection(WebInspector.UIString("Rendering"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show paint rectangles"), WebInspector.settings.showPaintRects));
WebInspector.settings.showPaintRects.addChangeListener(this._showPaintRectsChanged, this);

p = this._appendSection(WebInspector.UIString("Sources"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show folders"), WebInspector.settings.showScriptFolders));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Search in content scripts"), WebInspector.settings.searchInContentScripts));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Enable source maps"), WebInspector.settings.sourceMapsEnabled));
p.appendChild(this._createSelectSetting(WebInspector.UIString("Indentation"), [
[ WebInspector.UIString("2 spaces"), WebInspector.TextEditorModel.Indent.TwoSpaces ],
[ WebInspector.UIString("4 spaces"), WebInspector.TextEditorModel.Indent.FourSpaces ],
[ WebInspector.UIString("8 spaces"), WebInspector.TextEditorModel.Indent.EightSpaces ],
[ WebInspector.UIString("Tab character"), WebInspector.TextEditorModel.Indent.TabCharacter ]
], WebInspector.settings.textEditorIndent));

p = this._appendSection(WebInspector.UIString("Profiler"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show objects' hidden properties"), WebInspector.settings.showHeapSnapshotObjectsHiddenProperties));

p = this._appendSection(WebInspector.UIString("Console"));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Log XMLHttpRequests"), WebInspector.settings.monitoringXHREnabled));
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Preserve log upon navigation"), WebInspector.settings.preserveConsoleLog));

if (WebInspector.extensionServer.hasExtensions()) {
var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);
p = this._appendSection(WebInspector.UIString("Extensions"));
p.appendChild(this._createCustomSetting(WebInspector.UIString("Open links in"), handlerSelector.element));
}
}

WebInspector.GenericSettingsTab.prototype = {
_showPaintRectsChanged: function()
{
PageAgent.setShowPaintRects(WebInspector.settings.showPaintRects.get());
},

_updateScriptDisabledCheckbox: function()
{
function executionStatusCallback(error, status)
{
if (error || !status)
return;

switch (status) {
case "forbidden":
this._disableJSCheckbox.checked = true;
this._disableJSCheckbox.disabled = true;
break;
case "disabled":
this._disableJSCheckbox.checked = true;
break;
default:
this._disableJSCheckbox.checked = false;
break;
}
}

PageAgent.getScriptExecutionStatus(executionStatusCallback.bind(this));
},

_javaScriptDisabledChanged: function()
{

PageAgent.setScriptExecutionDisabled(WebInspector.settings.javaScriptDisabled.get(), this._updateScriptDisabledCheckbox.bind(this));
}
}

WebInspector.GenericSettingsTab.prototype.__proto__ = WebInspector.SettingsTab.prototype;


WebInspector.UserAgentSettingsTab = function()
{
WebInspector.SettingsTab.call(this);

var p = this._appendSection();
p.appendChild(this._createUserAgentControl());
if (Capabilities.canOverrideDeviceMetrics)
p.appendChild(this._createDeviceMetricsControl());
if (Capabilities.canOverrideGeolocation && WebInspector.experimentsSettings.geolocationOverride.isEnabled())
p.appendChild(this._createGeolocationOverrideControl());
if (Capabilities.canOverrideDeviceOrientation && WebInspector.experimentsSettings.deviceOrientationOverride.isEnabled())
p.appendChild(this._createDeviceOrientationOverrideControl());
p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Emulate touch events"), WebInspector.settings.emulateTouchEvents));
}

WebInspector.UserAgentSettingsTab.prototype = {
_createUserAgentControl: function()
{
var userAgent = WebInspector.settings.userAgent.get();

var p = document.createElement("p");
var labelElement = p.createChild("label");
var checkboxElement = labelElement.createChild("input");
checkboxElement.type = "checkbox";
checkboxElement.checked = !!userAgent;
labelElement.appendChild(document.createTextNode("User Agent"));
p.appendChild(this._createUserAgentSelectRowElement(checkboxElement));
return p;
},

_createUserAgentSelectRowElement: function(checkboxElement)
{
var userAgent = WebInspector.settings.userAgent.get();





const userAgents = [
["Internet Explorer 9", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"],
["Internet Explorer 8", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"],
["Internet Explorer 7", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"],

["Firefox 7 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"],
["Firefox 7 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"],
["Firefox 4 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"],
["Firefox 4 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"],

["iPhone \u2014 iOS 5", "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3", "640x960x1"],
["iPhone \u2014 iOS 4", "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5", "640x960x1"],
["iPad \u2014 iOS 5", "Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3", "1024x768x1"],
["iPad \u2014 iOS 4", "Mozilla/5.0 (iPad; CPU OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5", "1024x768x1"],

["Android 2.3 \u2014 Nexus S", "Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "480x800x1.1"],
["Android 4.0.2 \u2014 Galaxy Nexus", "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "720x1280x1.1"],

["BlackBerry \u2014 PlayBook 2.1", "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+", "1024x600x1"],
["BlackBerry \u2014 9900", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+", "640x480x1"],
["BlackBerry \u2014 BB10", "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.1+ (KHTML, like Gecko) Version/10.0.0.1337 Mobile Safari/537.1+", "768x1280x1"],

["MeeGo \u2014 Nokia N9", "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13", "480x854x1"],

[WebInspector.UIString("Other..."), "Other"]
];

var fieldsetElement = document.createElement("fieldset");
this._selectElement = fieldsetElement.createChild("select");
this._otherUserAgentElement = fieldsetElement.createChild("input");
this._otherUserAgentElement.value = userAgent;
this._otherUserAgentElement.title = userAgent;

var selectionRestored = false;
for (var i = 0; i < userAgents.length; ++i) {
var agent = userAgents[i];
var option = new Option(agent[0], agent[1]);
option._metrics = agent[2] ? agent[2] : "";
this._selectElement.add(option);
if (userAgent === agent[1]) {
this._selectElement.selectedIndex = i;
selectionRestored = true;
}
}

if (!selectionRestored) {
if (!userAgent)
this._selectElement.selectedIndex = 0;
else
this._selectElement.selectedIndex = userAgents.length - 1;
}

this._selectElement.addEventListener("change", this._selectionChanged.bind(this, true), false);

fieldsetElement.addEventListener("dblclick", textDoubleClicked.bind(this), false);
this._otherUserAgentElement.addEventListener("blur", textChanged.bind(this), false);

function textDoubleClicked()
{
this._selectElement.selectedIndex = userAgents.length - 1;
this._selectionChanged();
}

function textChanged()
{
WebInspector.settings.userAgent.set(this._otherUserAgentElement.value);
}

function checkboxClicked()
{
if (checkboxElement.checked) {
this._selectElement.disabled = false;
this._selectionChanged();
} else {
this._selectElement.disabled = true;
this._otherUserAgentElement.disabled = true;
WebInspector.settings.userAgent.set("");
}
}
checkboxElement.addEventListener("click", checkboxClicked.bind(this), false);

checkboxClicked.call(this);
return fieldsetElement;
},


_selectionChanged: function(isUserGesture)
{
var value = this._selectElement.options[this._selectElement.selectedIndex].value;
if (value !== "Other") {
WebInspector.settings.userAgent.set(value);
this._otherUserAgentElement.value = value;
this._otherUserAgentElement.title = value;
this._otherUserAgentElement.disabled = true;
} else {
this._otherUserAgentElement.disabled = false;
this._otherUserAgentElement.focus();
}

if (isUserGesture && Capabilities.canOverrideDeviceMetrics) {
var metrics = this._selectElement.options[this._selectElement.selectedIndex]._metrics;
this._setDeviceMetricsOverride(WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(metrics), false, true);
}
},

_updateScriptDisabledCheckbox: function()
{
function executionStatusCallback(error, status)
{
if (error || !status)
return;

switch (status) {
case "forbidden":
this._disableJSCheckbox.checked = true;
this._disableJSCheckbox.disabled = true;
break;
case "disabled":
this._disableJSCheckbox.checked = true;
break;
default:
this._disableJSCheckbox.checked = false;
break;
}
}

PageAgent.getScriptExecutionStatus(executionStatusCallback.bind(this));
},


_createInput: function(parentElement, id, defaultText, eventListener)
{
var element = parentElement.createChild("input");
element.id = id;
element.maxLength = 12;
element.style.width = "80px";
element.value = defaultText;
element.align = "right";
element.addEventListener("blur", eventListener, false);
return element;
},

_createDeviceMetricsControl: function()
{
const metricsSetting = WebInspector.settings.deviceMetrics.get();
var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(metricsSetting);

const p = document.createElement("p");
const labelElement = p.createChild("label");
const checkboxElement = labelElement.createChild("input");
checkboxElement.id = "metrics-override-checkbox";
checkboxElement.type = "checkbox";
checkboxElement.checked = !metrics || (metrics.width && metrics.height && metrics.fontScaleFactor);
checkboxElement.addEventListener("click", this._onMetricsCheckboxClicked.bind(this), false);
this._metricsCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Device metrics")));

const metricsSectionElement = this._createDeviceMetricsElement(metrics);
p.appendChild(metricsSectionElement);
this._metricsSectionElement = metricsSectionElement;

this._setDeviceMetricsOverride(metrics, false, true);

return p;
},

_onMetricsCheckboxClicked: function()
{
var controlsDisabled = !this._metricsCheckboxElement.checked;
this._widthOverrideElement.disabled = controlsDisabled;
this._heightOverrideElement.disabled = controlsDisabled;
this._fontScaleFactorOverrideElement.disabled = controlsDisabled;
this._swapDimensionsElement.disabled = controlsDisabled;
this._fitWindowCheckboxElement.disabled = controlsDisabled;

if (this._metricsCheckboxElement.checked) {
var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput(this._widthOverrideElement.value, this._heightOverrideElement.value, this._fontScaleFactorOverrideElement.value);
if (metrics && metrics.isValid() && metrics.width && metrics.height)
this._setDeviceMetricsOverride(metrics, false, false);
if (!this._widthOverrideElement.value)
this._widthOverrideElement.focus();
} else {
if (WebInspector.settings.deviceMetrics.get())
WebInspector.settings.deviceMetrics.set("");
}
},

_applyDeviceMetricsUserInput: function()
{
this._setDeviceMetricsOverride(WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput(this._widthOverrideElement.value.trim(), this._heightOverrideElement.value.trim(), this._fontScaleFactorOverrideElement.value.trim()), true, false);
},


_setDeviceMetricsOverride: function(metrics, userInputModified, updateCheckbox)
{
function setValid(condition, element)
{
if (condition)
element.removeStyleClass("error-input");
else
element.addStyleClass("error-input");
}

setValid(metrics && metrics.isWidthValid(), this._widthOverrideElement);
setValid(metrics && metrics.isHeightValid(), this._heightOverrideElement);
setValid(metrics && metrics.isFontScaleFactorValid(), this._fontScaleFactorOverrideElement);

if (!metrics)
return;

if (!userInputModified) {
this._widthOverrideElement.value = metrics.widthToInput();
this._heightOverrideElement.value = metrics.heightToInput();
this._fontScaleFactorOverrideElement.value = metrics.fontScaleFactorToInput();
}

if (metrics.isValid()) {
var value = metrics.toSetting();
if (value !== WebInspector.settings.deviceMetrics.get())
WebInspector.settings.deviceMetrics.set(value);
}

if (this._metricsCheckboxElement && updateCheckbox) {
this._metricsCheckboxElement.checked = !!metrics.toSetting();
this._onMetricsCheckboxClicked();
}
},


_createDeviceMetricsElement: function(metrics)
{
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.id = "metrics-override-section";

function swapDimensionsClicked(event)
{
var widthValue = this._widthOverrideElement.value;
this._widthOverrideElement.value = this._heightOverrideElement.value;
this._heightOverrideElement.value = widthValue;
this._applyDeviceMetricsUserInput();
}

var tableElement = fieldsetElement.createChild("table", "nowrap");

var rowElement = tableElement.createChild("tr");
var cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode(WebInspector.UIString("Screen resolution:")));
cellElement = rowElement.createChild("td");
this._widthOverrideElement = this._createInput(cellElement, "metrics-override-width", String(metrics.width || screen.width), this._applyDeviceMetricsUserInput.bind(this));
cellElement.appendChild(document.createTextNode(" \u00D7 ")); 
this._heightOverrideElement = this._createInput(cellElement, "metrics-override-height", String(metrics.height || screen.height), this._applyDeviceMetricsUserInput.bind(this));
cellElement.appendChild(document.createTextNode(" \u2014 ")); 
this._swapDimensionsElement = cellElement.createChild("button");
this._swapDimensionsElement.appendChild(document.createTextNode(" \u21C4 ")); 
this._swapDimensionsElement.title = WebInspector.UIString("Swap dimensions");
this._swapDimensionsElement.addEventListener("click", swapDimensionsClicked.bind(this), false);

rowElement = tableElement.createChild("tr");
cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode(WebInspector.UIString("Font scale factor:")));
cellElement = rowElement.createChild("td");
this._fontScaleFactorOverrideElement = this._createInput(cellElement, "metrics-override-font-scale", String(metrics.fontScaleFactor || 1), this._applyDeviceMetricsUserInput.bind(this));

rowElement = tableElement.createChild("tr");
cellElement = rowElement.createChild("td");
cellElement.colspan = 2;
this._fitWindowCheckboxElement = document.createElement("input");
cellElement.appendChild(this._createCheckboxSetting(WebInspector.UIString("Fit in window"), WebInspector.settings.deviceFitWindow, true, this._fitWindowCheckboxElement));

return fieldsetElement;
},

_createGeolocationOverrideControl: function()
{
const geolocationSetting = WebInspector.settings.geolocationOverride.get();
var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseSetting(geolocationSetting);
var p = document.createElement("p");
var labelElement = p.createChild("label");
var checkboxElement = labelElement.createChild("input");
checkboxElement.id = "geolocation-override-checkbox";
checkboxElement.type = "checkbox";
checkboxElement.checked = !geolocation || (((typeof geolocation.latitude === "number") && (typeof geolocation.longitude === "number")) || geolocation.error);
checkboxElement.addEventListener("click", this._onGeolocationOverrideCheckboxClicked.bind(this), false);
this._geolocationOverrideCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Override Geolocation")));

var geolocationSectionElement = this._createGeolocationOverrideElement(geolocation);
p.appendChild(geolocationSectionElement);
this._geolocationSectionElement = geolocationSectionElement;
this._setGeolocationPosition(geolocation, false, true);
return p;
},

_onGeolocationOverrideCheckboxClicked: function()
{
var controlsDisabled = !this._geolocationOverrideCheckboxElement.checked;
this._latitudeElement.disabled = controlsDisabled;
this._longitudeElement.disabled = controlsDisabled;
this._geolocationErrorElement.disabled = controlsDisabled;

if (this._geolocationOverrideCheckboxElement.checked) {
var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value, this._longitudeElement.value, this._geolocationErrorElement.checked);
if (geolocation)
this._setGeolocationPosition(geolocation, false, false);
if (!this._latitudeElement.value)
this._latitudeElement.focus();
} else
WebInspector.UserAgentSupport.GeolocationPosition.clearGeolocationOverride();
},

_applyGeolocationUserInput: function()
{
this._setGeolocationPosition(WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value.trim(), this._longitudeElement.value.trim(), this._geolocationErrorElement.checked), true, false);
},


_setGeolocationPosition: function(geolocation, userInputModified, updateCheckbox)
{
if (!geolocation)
return;

if (!userInputModified) {
this._latitudeElement.value = geolocation.latitude;
this._longitudeElement.value = geolocation.longitude;
}

var value = geolocation.toSetting();
WebInspector.settings.geolocationOverride.set(value);

if (this._geolocationOverrideCheckboxElement && updateCheckbox) {
this._geolocationOverrideCheckboxElement.checked = !!geolocation.toSetting();
this._onGeolocationOverrideCheckboxClicked();
}
},


_createGeolocationOverrideElement: function(geolocation)
{
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.id = "geolocation-override-section";

var tableElement = fieldsetElement.createChild("table");
var rowElement = tableElement.createChild("tr");
var cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode(WebInspector.UIString("Geolocation Position") + ":"));
cellElement = rowElement.createChild("td");
this._latitudeElement = this._createInput(cellElement, "geolocation-override-latitude", String(geolocation.latitude), this._applyGeolocationUserInput.bind(this));
cellElement.appendChild(document.createTextNode(" , "));
this._longitudeElement = this._createInput(cellElement, "geolocation-override-longitude", String(geolocation.longitude), this._applyGeolocationUserInput.bind(this));
rowElement = tableElement.createChild("tr");
cellElement = rowElement.createChild("td");
var geolocationErrorLabelElement = document.createElement("label");
var geolocationErrorCheckboxElement = geolocationErrorLabelElement.createChild("input");
geolocationErrorCheckboxElement.id = "geolocation-error";
geolocationErrorCheckboxElement.type = "checkbox";
geolocationErrorCheckboxElement.checked = !geolocation || geolocation.error;
geolocationErrorCheckboxElement.addEventListener("click", this._applyGeolocationUserInput.bind(this), false);
geolocationErrorLabelElement.appendChild(document.createTextNode(WebInspector.UIString("Emulate position unavailable")));
this._geolocationErrorElement = geolocationErrorCheckboxElement;
cellElement.appendChild(geolocationErrorLabelElement);

return fieldsetElement;
},

_createDeviceOrientationOverrideControl: function()
{
const deviceOrientationSetting = WebInspector.settings.deviceOrientationOverride.get();
var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseSetting(deviceOrientationSetting);

var p = document.createElement("p");
var labelElement = p.createChild("label");
var checkboxElement = labelElement.createChild("input");
checkboxElement.id = "device-orientation-override-checkbox";
checkboxElement.type = "checkbox";
checkboxElement.checked = !deviceOrientation;
checkboxElement.addEventListener("click", this._onDeviceOrientationOverrideCheckboxClicked.bind(this), false);
this._deviceOrientationOverrideCheckboxElement = checkboxElement;
labelElement.appendChild(document.createTextNode(WebInspector.UIString("Override Device Orientation")));

var deviceOrientationSectionElement = this._createDeviceOrientationOverrideElement(deviceOrientation);
p.appendChild(deviceOrientationSectionElement);
this._deviceOrientationSectionElement = deviceOrientationSectionElement;

this._setDeviceOrientation(deviceOrientation, false, true);

return p;
},

_onDeviceOrientationOverrideCheckboxClicked: function()
{
var controlsDisabled = !this._deviceOrientationOverrideCheckboxElement.checked;
this._alphaElement.disabled = controlsDisabled;
this._betaElement.disabled = controlsDisabled;
this._gammaElement.disabled = controlsDisabled;

if (this._deviceOrientationOverrideCheckboxElement.checked) {
var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput(this._alphaElement.value, this._betaElement.value, this._gammaElement.value);
if (deviceOrientation)
this._setDeviceOrientation(deviceOrientation, false, false);
if (!this._alphaElement.value)
this._alphaElement.focus();
} else
WebInspector.UserAgentSupport.DeviceOrientation.clearDeviceOrientationOverride();
},

_applyDeviceOrientationUserInput: function()
{
this._setDeviceOrientation(WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput(this._alphaElement.value.trim(), this._betaElement.value.trim(), this._gammaElement.value.trim()), true, false);
},


_setDeviceOrientation: function(deviceOrientation, userInputModified, updateCheckbox)
{
if (!deviceOrientation)
return;

if (!userInputModified) {
this._alphaElement.value = deviceOrientation.alpha;
this._betaElement.value = deviceOrientation.beta;
this._gammaElement.value = deviceOrientation.gamma;
}

var value = deviceOrientation.toSetting();
WebInspector.settings.deviceOrientationOverride.set(value);

if (this._deviceOrientationOverrideCheckboxElement && updateCheckbox) {
this._deviceOrientationOverrideCheckboxElement.checked = !!deviceOrientation.toSetting();
this._onDeviceOrientationOverrideCheckboxClicked();
}
},


_createDeviceOrientationOverrideElement: function(deviceOrientation)
{
var fieldsetElement = document.createElement("fieldset");
fieldsetElement.id = "device-orientation-override-section";

var tableElement = fieldsetElement.createChild("table");

var rowElement = tableElement.createChild("tr");
var cellElement = rowElement.createChild("td");
cellElement.appendChild(document.createTextNode("\u03B1: "));
this._alphaElement = this._createInput(cellElement, "device-orientation-override-alpha", String(deviceOrientation.alpha), this._applyDeviceOrientationUserInput.bind(this));
cellElement.appendChild(document.createTextNode(" \u03B2: "));
this._betaElement = this._createInput(cellElement, "device-orientation-override-beta", String(deviceOrientation.beta), this._applyDeviceOrientationUserInput.bind(this));
cellElement.appendChild(document.createTextNode(" \u03B3: "));
this._gammaElement = this._createInput(cellElement, "device-orientation-override-gamma", String(deviceOrientation.gamma), this._applyDeviceOrientationUserInput.bind(this));

return fieldsetElement;
}
}

WebInspector.UserAgentSettingsTab.prototype.__proto__ = WebInspector.SettingsTab.prototype;


WebInspector.ExperimentsSettingsTab = function()
{
WebInspector.SettingsTab.call(this);

var experiments = WebInspector.experimentsSettings.experiments;
if (experiments.length) {
var experimentsSection = this._appendSection();
experimentsSection.appendChild(this._createExperimentsWarningSubsection());
for (var i = 0; i < experiments.length; ++i)
experimentsSection.appendChild(this._createExperimentCheckbox(experiments[i]));
}
}

WebInspector.ExperimentsSettingsTab.prototype = {

_createExperimentsWarningSubsection: function()
{
var subsection = document.createElement("div");
var warning = subsection.createChild("span", "settings-experiments-warning-subsection-warning");
warning.textContent = WebInspector.UIString("WARNING:");
subsection.appendChild(document.createTextNode(" "));
var message = subsection.createChild("span", "settings-experiments-warning-subsection-message");
message.textContent = WebInspector.UIString("These experiments could be dangerous and may require restart.");
return subsection;
},

_createExperimentCheckbox: function(experiment)
{
var input = document.createElement("input");
input.type = "checkbox";
input.name = experiment.name;
input.checked = experiment.isEnabled();
function listener()
{
experiment.setEnabled(input.checked);
}
input.addEventListener("click", listener, false);

var p = document.createElement("p");
var label = document.createElement("label");
label.appendChild(input);
label.appendChild(document.createTextNode(WebInspector.UIString(experiment.title)));
p.appendChild(label);
return p;
}
}

WebInspector.ExperimentsSettingsTab.prototype.__proto__ = WebInspector.SettingsTab.prototype;


WebInspector.SettingsController = function()
{
this._statusBarButton = new WebInspector.StatusBarButton(WebInspector.UIString("Settings"), "settings-status-bar-item");;
this._statusBarButton.addEventListener("click", this._buttonClicked, this);


this._settingsScreen;
}

WebInspector.SettingsController.prototype =
{
get statusBarItem()
{
return this._statusBarButton.element;
},

_buttonClicked: function()
{
if (this._statusBarButton.toggled)
this._hideSettingsScreen();
else
this.showSettingsScreen();
},

_onHideSettingsScreen: function()
{
this._statusBarButton.toggled = false;
},


showSettingsScreen: function(tabId)
{
if (!this._settingsScreen)
this._settingsScreen = new WebInspector.SettingsScreen(this._onHideSettingsScreen.bind(this));

if (tabId)
this._settingsScreen.selectTab(tabId);

this._settingsScreen.showModal();
this._statusBarButton.toggled = true;
},

_hideSettingsScreen: function()
{
if (this._settingsScreen)
this._settingsScreen.hide();
},

resize: function()
{
if (this._settingsScreen && this._settingsScreen.isShowing())
this._settingsScreen.doResize();
}
}






WebInspector.ShortcutsScreen = function()
{
this._sections = {};
}

WebInspector.ShortcutsScreen.prototype = {
section: function(name)
{
var section = this._sections[name];
if (!section)
this._sections[name] = section = new WebInspector.ShortcutsSection(name);
return section;
},

createShortcutsTabView: function()
{
var orderedSections = [];
for (var section in this._sections)
orderedSections.push(this._sections[section]);
function compareSections(a, b)
{
return a.order - b.order;
}
orderedSections.sort(compareSections);

var view = new WebInspector.View();

var container = view.element;
container.className = "help-content help-container";
for (var i = 0; i < orderedSections.length; ++i)
orderedSections[i].renderSection(container);

return view;
}
}


WebInspector.shortcutsScreen = null;


WebInspector.ShortcutsSection = function(name)
{
this.name = name;
this._lines = [];
this.order = ++WebInspector.ShortcutsSection._sequenceNumber;
};

WebInspector.ShortcutsSection._sequenceNumber = 0;

WebInspector.ShortcutsSection.prototype = {
addKey: function(key, description)
{
this._addLine(this._renderKey(key), description);
},

addRelatedKeys: function(keys, description)
{
this._addLine(this._renderSequence(keys, "/"), description);
},

addAlternateKeys: function(keys, description)
{
this._addLine(this._renderSequence(keys, WebInspector.UIString("or")), description);
},

_addLine: function(keyElement, description)
{
this._lines.push({ key: keyElement, text: description })
},


renderSection: function(container)
{
var parent = container.createChild("div", "help-block");

var headLine = parent.createChild("div", "help-line");
headLine.createChild("div", "help-key-cell");
headLine.createChild("div", "help-section-title help-cell").textContent = this.name;

for (var i = 0; i < this._lines.length; ++i) {
var line = parent.createChild("div", "help-line");
var keyCell = line.createChild("div", "help-key-cell");
keyCell.appendChild(this._lines[i].key);
keyCell.appendChild(this._createSpan("help-key-delimiter", ":"));
line.createChild("div", "help-cell").textContent = this._lines[i].text;
}
},

_renderSequence: function(sequence, delimiter)
{
var delimiterSpan = this._createSpan("help-key-delimiter", delimiter);
return this._joinNodes(sequence.map(this._renderKey.bind(this)), delimiterSpan);
},

_renderKey: function(key)
{
var plus = this._createSpan("help-combine-keys", "+");
return this._joinNodes(key.split(" + ").map(this._createSpan.bind(this, "help-key monospace")), plus);
},

_createSpan: function(className, textContent)
{
var node = document.createElement("span");
node.className = className;
node.textContent = textContent;
return node;
},

_joinNodes: function(nodes, delimiter)
{
var result = document.createDocumentFragment();
for (var i = 0; i < nodes.length; ++i) {
if (i > 0)
result.appendChild(delimiter.cloneNode(true));
result.appendChild(nodes[i]);
}
return result;
}
}












WebInspector.HAREntry = function(request)
{
this._request = request;
}

WebInspector.HAREntry.prototype = {

build: function()
{
var entry =  {
startedDateTime: new Date(this._request.startTime * 1000),
time: WebInspector.HAREntry._toMilliseconds(this._request.duration),
request: this._buildRequest(),
response: this._buildResponse(),
cache: { }, 
timings: this._buildTimings()
};
var page = WebInspector.networkLog.pageLoadForRequest(this._request);
if (page)
entry.pageref = "page_" + page.id;
return entry;
},


_buildRequest: function()
{
var res = {
method: this._request.requestMethod,
url: this._buildRequestURL(this._request.url),
httpVersion: this._request.requestHttpVersion,
headers: this._request.requestHeaders,
queryString: this._buildParameters(this._request.queryParameters || []),
cookies: this._buildCookies(this._request.requestCookies || []),
headersSize: this._request.requestHeadersSize,
bodySize: this.requestBodySize
};
if (this._request.requestFormData)
res.postData = this._buildPostData();

return res;
},


_buildResponse: function()
{
return {
status: this._request.statusCode,
statusText: this._request.statusText,
httpVersion: this._request.responseHttpVersion,
headers: this._request.responseHeaders,
cookies: this._buildCookies(this._request.responseCookies || []),
content: this._buildContent(),
redirectURL: this._request.responseHeaderValue("Location") || "",
headersSize: this._request.responseHeadersSize,
bodySize: this.responseBodySize
};
},


_buildContent: function()
{
var content = {
size: this._request.resourceSize,
mimeType: this._request.mimeType,

};
var compression = this.responseCompression;
if (typeof compression === "number")
content.compression = compression;
return content;
},


_buildTimings: function()
{
var waitForConnection = this._interval("connectStart", "connectEnd");
var blocked;
var connect;
var dns = this._interval("dnsStart", "dnsEnd");
var send = this._interval("sendStart", "sendEnd");
var ssl = this._interval("sslStart", "sslEnd");

if (ssl !== -1 && send !== -1)
send -= ssl;

if (this._request.connectionReused) {
connect = -1;
blocked = waitForConnection;
} else {
blocked = 0;
connect = waitForConnection;
if (dns !== -1)
connect -= dns;
}

return {
blocked: blocked,
dns: dns,
connect: connect,
send: send,
wait: this._interval("sendEnd", "receiveHeadersEnd"),
receive: WebInspector.HAREntry._toMilliseconds(this._request.receiveDuration),
ssl: ssl
};
},


_buildPostData: function()
{
var res = {
mimeType: this._request.requestHeaderValue("Content-Type"),
text: this._request.requestFormData
};
if (this._request.formParameters)
res.params = this._buildParameters(this._request.formParameters);
return res;
},


_buildParameters: function(parameters)
{
return parameters.slice();
},


_buildRequestURL: function(url)
{
return url.split("#", 2)[0];
},


_buildCookies: function(cookies)
{
return cookies.map(this._buildCookie.bind(this));
},


_buildCookie: function(cookie)
{
return {
name: cookie.name,
value: cookie.value,
path: cookie.path,
domain: cookie.domain,
expires: cookie.expires(new Date(this._request.startTime * 1000)),
httpOnly: cookie.httpOnly,
secure: cookie.secure
};
},


_interval: function(start, end)
{
var timing = this._request.timing;
if (!timing)
return -1;
var startTime = timing[start];
return typeof startTime !== "number" || startTime === -1 ? -1 : Math.round(timing[end] - startTime);
},


get requestBodySize()
{
return !this._request.requestFormData ? 0 : this._request.requestFormData.length;
},


get responseBodySize()
{
if (this._request.cached || this._request.statusCode === 304)
return 0;
return this._request.transferSize - this._request.responseHeadersSize
},


get responseCompression()
{
if (this._request.cached || this._request.statusCode === 304)
return;
return this._request.resourceSize - (this._request.transferSize - this._request.responseHeadersSize);
}
}


WebInspector.HAREntry._toMilliseconds = function(time)
{
return time === -1 ? -1 : Math.round(time * 1000);
}


WebInspector.HARLog = function(requests)
{
this._requests = requests;
}

WebInspector.HARLog.prototype = {

build: function()
{
var webKitVersion = /AppleWebKit\/([^ ]+)/.exec(window.navigator.userAgent);

return {
version: "1.2",
creator: {
name: "WebInspector",
version: webKitVersion ? webKitVersion[1] : "n/a"
},
pages: this._buildPages(),
entries: this._requests.map(this._convertResource.bind(this))
}
},


_buildPages: function()
{
var seenIdentifiers = {};
var pages = [];
for (var i = 0; i < this._requests.length; ++i) {
var page = WebInspector.networkLog.pageLoadForRequest(this._requests[i]);
if (!page || seenIdentifiers[page.id])
continue;
seenIdentifiers[page.id] = true;
pages.push(this._convertPage(page));
}
return pages;
},


_convertPage: function(page)
{
return {
startedDateTime: new Date(page.startTime * 1000),
id: "page_" + page.id,
title: page.url, 
pageTimings: {
onContentLoad: this._pageEventTime(page, page.contentLoadTime),
onLoad: this._pageEventTime(page, page.loadTime)
}
}
},


_convertResource: function(request)
{
return (new WebInspector.HAREntry(request)).build();
},


_pageEventTime: function(page, time)
{
var startTime = page.startTime;
if (time === -1 || startTime === -1)
return -1;
return WebInspector.HAREntry._toMilliseconds(time - startTime);
}
}













WebInspector.CookieParser = function()
{
}


WebInspector.CookieParser.KeyValue = function(key, value, position)
{
this.key = key;
this.value = value;
this.position = position;
}

WebInspector.CookieParser.prototype = {

get cookies()
{
return this._cookies;
},


parseCookie: function(cookieHeader)
{
if (!this._initialize(cookieHeader))
return null;

for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
if (kv.key.charAt(0) === "$" && this._lastCookie)
this._lastCookie.addAttribute(kv.key.slice(1), kv.value);
else if (kv.key.toLowerCase() !== "$version" && typeof kv.value === "string")
this._addCookie(kv, WebInspector.Cookie.Type.Request);
this._advanceAndCheckCookieDelimiter();
}
this._flushCookie();
return this._cookies;
},


parseSetCookie: function(setCookieHeader)
{
if (!this._initialize(setCookieHeader))
return null;
for (var kv = this._extractKeyValue(); kv; kv = this._extractKeyValue()) {
if (this._lastCookie)
this._lastCookie.addAttribute(kv.key, kv.value);
else
this._addCookie(kv, WebInspector.Cookie.Type.Response);
if (this._advanceAndCheckCookieDelimiter())
this._flushCookie();
}
this._flushCookie();
return this._cookies;
},


_initialize: function(headerValue)
{
this._input = headerValue;
if (typeof headerValue !== "string")
return false;
this._cookies = [];
this._lastCookie = null;
this._originalInputLength = this._input.length;
return true;
},

_flushCookie: function()
{
if (this._lastCookie)
this._lastCookie.size = this._originalInputLength - this._input.length - this._lastCookiePosition;
this._lastCookie = null;
},


_extractKeyValue: function()
{
if (!this._input || !this._input.length)
return null;





var keyValueMatch = /^[ \t]*([^\s=;]+)[ \t]*(?:=[ \t]*([^;\n]*))?/.exec(this._input);
        if (!keyValueMatch) {
            console.log("Failed parsing cookie header before: " + this._input);
            return null;
        }

        var result = new WebInspector.CookieParser.KeyValue(keyValueMatch[1], keyValueMatch[2] && keyValueMatch[2].trim(), this._originalInputLength - this._input.length);
        this._input = this._input.slice(keyValueMatch[0].length);
        return result;
    },

    /**
* @return {boolean}
*/
_advanceAndCheckCookieDelimiter: function()
{
var match = /^\s*[\n;]\s*/.exec(this._input);
if (!match)
return false;
this._input = this._input.slice(match[0].length);
return match[0].match("\n") !== null;
},


_addCookie: function(keyValue, type)
{
if (this._lastCookie)
this._lastCookie.size = keyValue.position - this._lastCookiePosition;


this._lastCookie = keyValue.value ? new WebInspector.Cookie(keyValue.key, keyValue.value, type) :
new WebInspector.Cookie("", keyValue.key, type);
this._lastCookiePosition = keyValue.position;
this._cookies.push(this._lastCookie);
}
};


WebInspector.CookieParser.parseCookie = function(header)
{
return (new WebInspector.CookieParser()).parseCookie(header);
}


WebInspector.CookieParser.parseSetCookie = function(header)
{
return (new WebInspector.CookieParser()).parseSetCookie(header);
}


WebInspector.Cookie = function(name, value, type)
{
this.name = name;
this.value = value;
this.type = type;
this._attributes = {};
}

WebInspector.Cookie.prototype = {

get httpOnly()
{
return "httponly" in this._attributes;
},


get secure()
{
return "secure" in this._attributes;
},


get session()
{


return  !("expries" in this._attributes || "max-age" in this._attributes);
},


get path()
{
return this._attributes["path"];
},


get domain()
{
return this._attributes["domain"];
},


expires: function(requestDate)
{
return this._attributes["expires"] ? new Date(this._attributes["expires"]) :
(this._attributes["max-age"] ? new Date(requestDate.getTime() + 1000 * this._attributes["max-age"]) : null);
},


get attributes()
{
return this._attributes;
},


addAttribute: function(key, value)
{
this._attributes[key.toLowerCase()] = value;
}
}

WebInspector.Cookie.Type = {
Request: 0,
Response: 1
};






WebInspector.Toolbar = function()
{
this.element = document.getElementById("toolbar");
WebInspector.installDragHandle(this.element, this._toolbarDragStart.bind(this), this._toolbarDrag.bind(this), this._toolbarDragEnd.bind(this), (WebInspector.isCompactMode() ? "row-resize" : "default"));

this._dropdownButton = document.getElementById("toolbar-dropdown-arrow");
this._dropdownButton.addEventListener("click", this._toggleDropdown.bind(this), false);

document.getElementById("close-button-left").addEventListener("click", this._onClose, true);
document.getElementById("close-button-right").addEventListener("click", this._onClose, true);
}

WebInspector.Toolbar.prototype = {
resize: function()
{
this._updateDropdownButtonAndHideDropdown();
},


addPanel: function(panelDescriptor)
{
this.element.appendChild(this._createPanelToolbarItem(panelDescriptor));
this.resize();
},


_createPanelToolbarItem: function(panelDescriptor)
{
var toolbarItem = document.createElement("button");
toolbarItem.className = "toolbar-item toggleable";
toolbarItem.panelDescriptor = panelDescriptor;
toolbarItem.addStyleClass(panelDescriptor.name());

function onToolbarItemClicked()
{
this._updateDropdownButtonAndHideDropdown();
WebInspector.inspectorView.setCurrentPanel(panelDescriptor.panel());
}
toolbarItem.addEventListener("click", onToolbarItemClicked.bind(this), false);

function panelSelected()
{
if (WebInspector.inspectorView.currentPanel() && panelDescriptor.name() === WebInspector.inspectorView.currentPanel().name)
toolbarItem.addStyleClass("toggled-on");
else
toolbarItem.removeStyleClass("toggled-on");
}
WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, panelSelected);

var iconElement = toolbarItem.createChild("div", "toolbar-icon");
toolbarItem.createChild("div", "toolbar-label").textContent = panelDescriptor.title();
if (panelDescriptor.iconURL()) {
iconElement.addStyleClass("custom-toolbar-icon");
iconElement.style.backgroundImage = "url(" + panelDescriptor.iconURL() + ")";
}
panelSelected();
return toolbarItem;
},


_toolbarDragStart: function(event)
{
if ((!WebInspector.isCompactMode() && WebInspector.platformFlavor() !== WebInspector.PlatformFlavor.MacLeopard && WebInspector.platformFlavor() !== WebInspector.PlatformFlavor.MacSnowLeopard) || WebInspector.port() == "qt")
return false;

var target = event.target;
if (target.hasStyleClass("toolbar-item") && target.hasStyleClass("toggleable"))
return false;

if (target !== this.element && !target.hasStyleClass("toolbar-item"))
return false;

this.element.lastScreenX = event.screenX;
this.element.lastScreenY = event.screenY;
return true;
},

_toolbarDragEnd: function(event)
{
delete this.element.lastScreenX;
delete this.element.lastScreenY;
},

_toolbarDrag: function(event)
{
if (WebInspector.isCompactMode()) {
var height = window.innerHeight - (event.screenY - this.element.lastScreenY);

InspectorFrontendHost.setAttachedWindowHeight(height);
} else {
var x = event.screenX - this.element.lastScreenX;
var y = event.screenY - this.element.lastScreenY;



InspectorFrontendHost.moveWindowBy(x, y);
}

this.element.lastScreenX = event.screenX;
this.element.lastScreenY = event.screenY;

event.preventDefault();
},

_onClose: function()
{
WebInspector.close();
},

_setDropdownVisible: function(visible)
{
if (!this._dropdown) {
if (!visible)
return;
this._dropdown = new WebInspector.ToolbarDropdown(this);
}
if (visible)
this._dropdown.show();
else
this._dropdown.hide();
},

_toggleDropdown: function()
{
this._setDropdownVisible(!this._dropdown || !this._dropdown.visible);
},

_updateDropdownButtonAndHideDropdown: function()
{
WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateDropdownButtonAndHideDropdown);
},

_innerUpdateDropdownButtonAndHideDropdown: function()
{
this._setDropdownVisible(false);

var toolbar = document.getElementById("toolbar");
if (this.element.scrollHeight > this.element.clientHeight)
this._dropdownButton.removeStyleClass("hidden");
else
this._dropdownButton.addStyleClass("hidden");
}
}


WebInspector.ToolbarDropdown = function(toolbar)
{
this._toolbar = toolbar;
this._arrow = document.getElementById("toolbar-dropdown-arrow");
this.element = document.createElement("div");
this.element.id = "toolbar-dropdown";
this.element.className = "toolbar-small";
this._contentElement = this.element.createChild("div", "scrollable-content");
this._contentElement.tabIndex = 0;
this._contentElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
}

WebInspector.ToolbarDropdown.prototype = {
show: function()
{
if (this.visible)
return;
var style = this.element.style;
this._populate();
var top = this._arrow.totalOffsetTop() + this._arrow.clientHeight;
this._arrow.addStyleClass("dropdown-visible");
this.element.style.top = top + "px";
this.element.style.left = this._arrow.totalOffsetLeft() + "px";
this._contentElement.style.maxHeight = window.innerHeight - top - 20 + "px";
this._toolbar.element.appendChild(this.element);
},

hide: function()
{
if (!this.visible)
return;
this._arrow.removeStyleClass("dropdown-visible");
this.element.parentNode.removeChild(this.element);
this._contentElement.removeChildren();
},

get visible()
{
return !!this.element.parentNode;
},

_populate: function()
{
var toolbarItems = this._toolbar.element.querySelectorAll(".toolbar-item.toggleable");

for (var i = 0; i < toolbarItems.length; ++i) {
if (toolbarItems[i].offsetTop > 0)
this._contentElement.appendChild(this._toolbar._createPanelToolbarItem(toolbarItems[i].panelDescriptor));
}
},

_onKeyDown: function(event)
{
if (event.keyCode !== WebInspector.KeyboardShortcut.Keys.Esc.code)
return;
event.consume();
this.hide();
}
}


WebInspector.toolbar = null;






WebInspector.SearchController = function()
{
this._element = document.createElement("table");
this._element.className = "toolbar-search";
this._element.cellSpacing = 0;

this._firstRowElement = this._element.createChild("tr");
this._secondRowElement = this._element.createChild("tr", "hidden");


var searchControlElementColumn = this._firstRowElement.createChild("td"); 
this._searchControlElement = searchControlElementColumn.createChild("span", "toolbar-search-control");
this._searchInputElement = this._searchControlElement.createChild("input", "search-replace");
this._searchInputElement.id = "search-input-field";
this._searchInputElement.placeholder = WebInspector.UIString("Find");

this._filterControlElement = searchControlElementColumn.createChild("span", "toolbar-search-control");
this._filterControlElement.addStyleClass("hidden");
this._filterInputElement = this._filterControlElement.createChild("input", "filter");
this._filterInputElement.id = "filter-input-field";
this._filterInputElement.placeholder = WebInspector.UIString("Filter");

this._matchesElement = this._searchControlElement.createChild("label", "search-results-matches");
this._matchesElement.setAttribute("for", "search-input-field");

var searchNavigationElement = this._searchControlElement.createChild("div", "toolbar-search-navigation-controls");

this._searchNavigationPrevElement = searchNavigationElement.createChild("div", "toolbar-search-navigation toolbar-search-navigation-prev");
this._searchNavigationPrevElement.addEventListener("click", this._onPrevButtonSearch.bind(this), false);
this._searchNavigationPrevElement.title = WebInspector.UIString("Search Previous");

this._searchNavigationNextElement = searchNavigationElement.createChild("div", "toolbar-search-navigation toolbar-search-navigation-next"); 
this._searchNavigationNextElement.addEventListener("click", this._onNextButtonSearch.bind(this), false);
this._searchNavigationNextElement.title = WebInspector.UIString("Search Next");

this._searchInputElement.addEventListener("mousedown", this._onSearchFieldManualFocus.bind(this), false); 
this._searchInputElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
this._filterInputElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
this._filterInputElement.addEventListener("input", this._onFilterInput.bind(this), false);
this._searchInputElement.addEventListener("input", this._onSearchInput.bind(this), false);

this._replaceInputElement = this._secondRowElement.createChild("td").createChild("input", "search-replace toolbar-replace-control");
this._replaceInputElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
this._replaceInputElement.placeholder = WebInspector.UIString("Replace");


this._findButtonElement = this._firstRowElement.createChild("td").createChild("button", "hidden");
this._findButtonElement.textContent = WebInspector.UIString("Find");
this._findButtonElement.tabIndex = -1;
this._findButtonElement.addEventListener("click", this._onNextButtonSearch.bind(this), false);

this._replaceButtonElement = this._secondRowElement.createChild("td").createChild("button");
this._replaceButtonElement.textContent = WebInspector.UIString("Replace");
this._replaceButtonElement.disabled = true;
this._replaceButtonElement.tabIndex = -1;
this._replaceButtonElement.addEventListener("click", this._replace.bind(this), false);


this._prevButtonElement = this._firstRowElement.createChild("td").createChild("button", "hidden");
this._prevButtonElement.textContent = WebInspector.UIString("Previous");
this._prevButtonElement.disabled = true;
this._prevButtonElement.tabIndex = -1;
this._prevButtonElement.addEventListener("click", this._onPrevButtonSearch.bind(this), false);

this._replaceAllButtonElement = this._secondRowElement.createChild("td").createChild("button");
this._replaceAllButtonElement.textContent = WebInspector.UIString("Replace All");
this._replaceAllButtonElement.addEventListener("click", this._replaceAll.bind(this), false);


this._replaceElement = this._firstRowElement.createChild("td").createChild("span");

this._replaceCheckboxElement = this._replaceElement.createChild("input");
this._replaceCheckboxElement.type = "checkbox";
this._replaceCheckboxElement.id = "search-replace-trigger";
this._replaceCheckboxElement.addEventListener("click", this._updateSecondRowVisibility.bind(this), false);

this._replaceLabelElement = this._replaceElement.createChild("label");
this._replaceLabelElement.textContent = WebInspector.UIString("Replace");
this._replaceLabelElement.setAttribute("for", "search-replace-trigger");


this._filterCheckboxContainer = this._firstRowElement.createChild("td").createChild("span");

this._filterCheckboxElement = this._filterCheckboxContainer.createChild("input");
this._filterCheckboxElement.type = "checkbox";
this._filterCheckboxElement.id = "filter-trigger";
this._filterCheckboxElement.addEventListener("click", this._filterCheckboxClick.bind(this), false);

this._filterLabelElement = this._filterCheckboxContainer.createChild("label");
this._filterLabelElement.textContent = WebInspector.UIString("Filter");
this._filterLabelElement.setAttribute("for", "filter-trigger");


var cancelButtonElement = this._firstRowElement.createChild("td").createChild("button");
cancelButtonElement.textContent = WebInspector.UIString("Cancel");
cancelButtonElement.tabIndex = -1;
cancelButtonElement.addEventListener("click", this.cancelSearch.bind(this), false);
}

WebInspector.SearchController.prototype = {
updateSearchMatchesCount: function(matches, panel)
{
if (!panel)
panel = WebInspector.inspectorView.currentPanel();

panel.currentSearchMatches = matches;

if (panel === WebInspector.inspectorView.currentPanel())
this._updateSearchMatchesCountAndCurrentMatchIndex(WebInspector.inspectorView.currentPanel().currentQuery ? matches : 0, -1);
},

updateCurrentMatchIndex: function(currentMatchIndex, panel)
{
if (panel === WebInspector.inspectorView.currentPanel())
this._updateSearchMatchesCountAndCurrentMatchIndex(panel.currentSearchMatches, currentMatchIndex);
},

cancelSearch: function()
{
if (!this._searchIsVisible)
return;
if (this._filterCheckboxElement.checked) {
this._filterCheckboxElement.checked = false;
this._switchFilterToSearch();
} 
delete this._searchIsVisible;
WebInspector.inspectorView.setFooterElement(null);
this.resetSearch();
},

resetSearch: function()
{
this._performSearch("", false, false);
this._updateReplaceVisibility();
this._matchesElement.textContent = "";
},

disableSearchUntilExplicitAction: function()
{
this._performSearch("", false, false);
},


handleShortcut: function(event)
{
var isMac = WebInspector.isMac();

switch (event.keyIdentifier) {
case "U+0046": 
if (isMac)
var isFindKey = event.metaKey && !event.ctrlKey && !event.altKey && !event.shiftKey;
else
var isFindKey = event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey;

if (isFindKey) {
this.showSearchField();
event.consume(true);
return true;
}
break;

case "F3":
if (!isMac) {
this.showSearchField();
event.consume();
}
break;

case "U+0047": 
var currentPanel = WebInspector.inspectorView.currentPanel();

if (isMac && event.metaKey && !event.ctrlKey && !event.altKey) {
if (event.shiftKey)
currentPanel.jumpToPreviousSearchResult();
else
currentPanel.jumpToNextSearchResult();
event.consume(true);
return true;
}
break;
}
return false;
},

_updateSearchNavigationButtonState: function(enabled)
{
this._replaceButtonElement.disabled = !enabled;
this._prevButtonElement.disabled = !enabled;
var panel = WebInspector.inspectorView.currentPanel();
if (enabled) {
this._searchNavigationPrevElement.addStyleClass("enabled");
this._searchNavigationNextElement.addStyleClass("enabled");
} else {
this._searchNavigationPrevElement.removeStyleClass("enabled");
this._searchNavigationNextElement.removeStyleClass("enabled");
}
},


_updateSearchMatchesCountAndCurrentMatchIndex: function(matches, currentMatchIndex)
{
if (matches === 0 || currentMatchIndex >= 0)
this._matchesElement.textContent = WebInspector.UIString("%d of %d", currentMatchIndex + 1, matches);
this._updateSearchNavigationButtonState(matches > 0);
},

showSearchField: function()
{
WebInspector.inspectorView.setFooterElement(this._element);
this._updateReplaceVisibility();
this._updateFilterVisibility();
this._searchInputElement.focus();
this._searchInputElement.select();
this._searchIsVisible = true;
},

_switchFilterToSearch: function()
{
this._filterControlElement.addStyleClass("hidden");
this._searchControlElement.removeStyleClass("hidden");
this._searchInputElement.focus();
this._searchInputElement.select();
this._searchInputElement.value = this._filterInputElement.value;
this.resetFilter();
},

_switchSearchToFilter: function()
{
this._filterControlElement.removeStyleClass("hidden");
this._searchControlElement.addStyleClass("hidden");
this._filterInputElement.focus();
this._filterInputElement.select();
this._filterInputElement.value = this._searchInputElement.value;
this.resetSearch();
},

_updateFilterVisibility: function()
{
if (WebInspector.inspectorView.currentPanel().canFilter())
this._filterCheckboxContainer.removeStyleClass("hidden");
else
this._filterCheckboxContainer.addStyleClass("hidden");
},

_updateReplaceVisibility: function()
{
var panel = WebInspector.inspectorView.currentPanel();
if (panel && panel.canSearchAndReplace())
this._replaceElement.removeStyleClass("hidden");
else {
this._replaceElement.addStyleClass("hidden");
this._replaceCheckboxElement.checked = false;
this._updateSecondRowVisibility();
}
},

_onSearchFieldManualFocus: function(event)
{
WebInspector.setCurrentFocusElement(event.target);
},

_onKeyDown: function(event)
{

if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
event.consume(true);
this.cancelSearch();
WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
if (WebInspector.currentFocusElement() === event.target)
WebInspector.currentFocusElement().select();
return false;
}

if (isEnterKey(event)) {
if (event.target === this._searchInputElement)
this._performSearch(event.target.value, true, event.shiftKey);
else if (event.target === this._replaceInputElement)
this._replace();
}
},

_onNextButtonSearch: function(event)
{

this._performSearch(this._searchInputElement.value, true, false);
this._searchInputElement.focus();
},

_onPrevButtonSearch: function(event)
{
if (!this._searchNavigationPrevElement.hasStyleClass("enabled"))
return;

this._performSearch(this._searchInputElement.value, true, true);
this._searchInputElement.focus();
},


_performSearch: function(query, forceSearch, isBackwardSearch)
{
if (!query || !query.length) {
delete this._currentQuery;

for (var panelName in WebInspector.panels) {
var panel = WebInspector.panels[panelName];
var hadCurrentQuery = !!panel.currentQuery;
delete panel.currentQuery;
if (hadCurrentQuery)
panel.searchCanceled();
}
this._updateSearchMatchesCountAndCurrentMatchIndex(0, -1);
return;
}

var currentPanel = WebInspector.inspectorView.currentPanel();
if (query === currentPanel.currentQuery && currentPanel.currentQuery === this._currentQuery) {


if (forceSearch) {
if (!isBackwardSearch)
currentPanel.jumpToNextSearchResult();
else if (isBackwardSearch)
currentPanel.jumpToPreviousSearchResult();
}
return;
}

if (!forceSearch && query.length < 3 && !this._currentQuery)
return;

this._currentQuery = query;

currentPanel.currentQuery = query;
currentPanel.performSearch(query);
},

_updateSecondRowVisibility: function()
{
if (!this._searchIsVisible)
return;
if (this._replaceCheckboxElement.checked) {
this._element.addStyleClass("toolbar-search-replace");
this._secondRowElement.removeStyleClass("hidden");
this._prevButtonElement.removeStyleClass("hidden");
this._findButtonElement.removeStyleClass("hidden");
this._replaceCheckboxElement.tabIndex = -1;
this._replaceInputElement.focus();
} else {
this._element.removeStyleClass("toolbar-search-replace");
this._secondRowElement.addStyleClass("hidden");
this._prevButtonElement.addStyleClass("hidden");
this._findButtonElement.addStyleClass("hidden");
this._replaceCheckboxElement.tabIndex = 0;
this._searchInputElement.focus();
}
WebInspector.inspectorView.setFooterElement(this._element);
},

_replace: function()
{
var currentPanel = WebInspector.inspectorView.currentPanel();
currentPanel.replaceSelectionWith(this._replaceInputElement.value);
var query = this._currentQuery;
delete this._currentQuery;
this._performSearch(query, true, false);
},

_replaceAll: function()
{
var currentPanel = WebInspector.inspectorView.currentPanel();
currentPanel.replaceAllWith(this._searchInputElement.value, this._replaceInputElement.value);
},

_filterCheckboxClick: function()
{
if (this._filterCheckboxElement.checked) { 
this._switchSearchToFilter();
this._performFilter(this._filterInputElement.value);
} else {
this._switchFilterToSearch();
this._performSearch(this._searchInputElement.value, false, false);
}
},


_performFilter: function(query)
{
WebInspector.inspectorView.currentPanel().performFilter(query);
},

_onFilterInput: function(event)
{
this._performFilter(event.target.value);
},

_onSearchInput: function(event)
{
this._performSearch(event.target.value, false, false);
},

resetFilter: function()
{
this._performFilter("");
}
}


WebInspector.searchController = null;






WebInspector.WorkerManager = function()
{
this._workerIdToWindow = {};
InspectorBackend.registerWorkerDispatcher(new WebInspector.WorkerDispatcher(this));
}

WebInspector.WorkerManager.isWorkerFrontend = function()
{
return !!WebInspector.queryParamsObject["dedicatedWorkerId"] ||
!!WebInspector.queryParamsObject["isSharedWorker"];
}

WebInspector.WorkerManager.isDedicatedWorkerFrontend = function()
{
return !!WebInspector.queryParamsObject["dedicatedWorkerId"];
}

WebInspector.WorkerManager.loaded = function()
{
var workerId = WebInspector.queryParamsObject["dedicatedWorkerId"];
if (workerId)
WebInspector.WorkerManager._initializeDedicatedWorkerFrontend(workerId);
else
WebInspector.workerManager = new WebInspector.WorkerManager();
}

WebInspector.WorkerManager.loadCompleted = function()
{


if (WebInspector.queryParamsObject["workerPaused"]) {
DebuggerAgent.pause();
RuntimeAgent.run(calculateTitle);
} else if (WebInspector.WorkerManager.isWorkerFrontend())
calculateTitle();

function calculateTitle()
{
WebInspector.WorkerManager._calculateWorkerInspectorTitle();
}

if (WebInspector.workerManager)
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, WebInspector.workerManager._mainFrameNavigated, WebInspector.workerManager);
}

WebInspector.WorkerManager._initializeDedicatedWorkerFrontend = function(workerId)
{
function receiveMessage(event)
{
var message = event.data;
InspectorBackend.dispatch(message);
}
window.addEventListener("message", receiveMessage, true);


InspectorBackend.sendMessageObjectToBackend = function(message)
{
window.opener.postMessage({workerId: workerId, command: "sendMessageToBackend", message: message}, "*");
}

InspectorFrontendHost.loaded = function()
{
window.opener.postMessage({workerId: workerId, command: "loaded"}, "*");
}
}

WebInspector.WorkerManager._calculateWorkerInspectorTitle = function()
{
var expression = "location.href";
if (WebInspector.queryParamsObject["isSharedWorker"])
expression += " + (this.name ? ' (' + this.name + ')' : '')";
RuntimeAgent.evaluate.invoke({expression:expression, doNotPauseOnExceptionsAndMuteConsole:true, returnByValue: true}, evalCallback.bind(this));


function evalCallback(error, result, wasThrown)
{
if (error || wasThrown) {
console.error(error);
return;
}
InspectorFrontendHost.inspectedURLChanged(result.value);
}
}

WebInspector.WorkerManager.Events = {
WorkerAdded: "worker-added",
WorkerRemoved: "worker-removed",
WorkersCleared: "workers-cleared",
}

WebInspector.WorkerManager.prototype = {
_workerCreated: function(workerId, url, inspectorConnected)
{
if (inspectorConnected)
this._openInspectorWindow(workerId, true);
this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerAdded, {workerId: workerId, url: url, inspectorConnected: inspectorConnected});
},

_workerTerminated: function(workerId)
{
this.closeWorkerInspector(workerId);
this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerRemoved, workerId);
},

_sendMessageToWorkerInspector: function(workerId, message)
{
var workerInspectorWindow = this._workerIdToWindow[workerId];
if (workerInspectorWindow)
workerInspectorWindow.postMessage(message, "*");
},

openWorkerInspector: function(workerId)
{
var existingInspector = this._workerIdToWindow[workerId];
if (existingInspector) {
existingInspector.focus();
return;
}

this._openInspectorWindow(workerId, false);
WorkerAgent.connectToWorker(workerId);
},

_openInspectorWindow: function(workerId, workerIsPaused)
{
var search = window.location.search;
var hash = window.location.hash;
var url = window.location.href;

url = url.replace(hash, "");
url += (search ? "&dedicatedWorkerId=" : "?dedicatedWorkerId=") + workerId;
if (workerIsPaused)
url += "&workerPaused=true";
url = url.replace("docked=true&", "");
url += hash;

var workerInspectorWindow = window.open(url, undefined, "location=0");
this._workerIdToWindow[workerId] = workerInspectorWindow;
workerInspectorWindow.addEventListener("beforeunload", this._workerInspectorClosing.bind(this, workerId), true);


window.addEventListener("beforeunload", this._pageInspectorClosing.bind(this), true);
WebInspector.notifications.addEventListener(WebInspector.Events.InspectorClosing, this._pageInspectorClosing, this);
},

closeWorkerInspector: function(workerId)
{
var workerInspectorWindow = this._workerIdToWindow[workerId];
if (workerInspectorWindow)
workerInspectorWindow.close();
},

_mainFrameNavigated: function(event)
{
for (var workerId in this._workerIdToWindow)
this.closeWorkerInspector(workerId);
this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkersCleared);
},

_pageInspectorClosing: function()
{
this._ignoreWorkerInspectorClosing = true;
for (var workerId in this._workerIdToWindow) {
this._workerIdToWindow[workerId].close();
WorkerAgent.disconnectFromWorker(parseInt(workerId, 10));
}
},

_workerInspectorClosing: function(workerId, event)
{
if (event.target.location.href === "about:blank")
return;
if (this._ignoreWorkerInspectorClosing)
return;
delete this._workerIdToWindow[workerId];
WorkerAgent.disconnectFromWorker(workerId);
},

_disconnectedFromWorker: function()
{
var screen = new WebInspector.WorkerTerminatedScreen();
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, screen.hide, screen);
screen.showModal();
}
}

WebInspector.WorkerManager.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.WorkerDispatcher = function(workerManager)
{
this._workerManager = workerManager;
window.addEventListener("message", this._receiveMessage.bind(this), true);
}

WebInspector.WorkerDispatcher.prototype = {
_receiveMessage: function(event)
{
var workerId = event.data["workerId"];
workerId = parseInt(workerId, 10);
var command = event.data.command;
var message = event.data.message;

if (command == "sendMessageToBackend")
WorkerAgent.sendMessageToWorker(workerId, message);
},

workerCreated: function(workerId, url, inspectorConnected)
{
this._workerManager._workerCreated(workerId, url, inspectorConnected);
},

workerTerminated: function(workerId)
{
this._workerManager._workerTerminated(workerId);
},

dispatchMessageFromWorker: function(workerId, message)
{
this._workerManager._sendMessageToWorkerInspector(workerId, message);
},

disconnectedFromWorker: function()
{
this._workerManager._disconnectedFromWorker();
}
}


WebInspector.WorkerTerminatedScreen = function()
{
WebInspector.HelpScreen.call(this, WebInspector.UIString("Inspected worker terminated"));
var p = this.contentElement.createChild("p");
p.addStyleClass("help-section");
p.textContent = WebInspector.UIString("Inspected worker has terminated. Once it restarts we will attach to it automatically.");
}

WebInspector.WorkerTerminatedScreen.prototype = {

willHide: function()
{
WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
WebInspector.HelpScreen.prototype.willHide.call(this);
}
}

WebInspector.WorkerTerminatedScreen.prototype.__proto__ = WebInspector.HelpScreen.prototype;






WebInspector.UserMetrics = function()
{
for (var actionName in WebInspector.UserMetrics._ActionCodes) {
var actionCode = WebInspector.UserMetrics._ActionCodes[actionName];
this[actionName] = new WebInspector.UserMetrics._Recorder(actionCode);
}

function settingChanged(trueCode, falseCode, event)
{
if (event.data)
InspectorFrontendHost.recordSettingChanged(trueCode);
else
InspectorFrontendHost.recordSettingChanged(falseCode);
}

WebInspector.settings.domWordWrap.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ElementsDOMWrapOn, WebInspector.UserMetrics._SettingCodes.ElementsDOMWrapOff));
WebInspector.settings.monitoringXHREnabled.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ConsoleMonitorXHROn, WebInspector.UserMetrics._SettingCodes.ConsoleMonitorXHROff));
WebInspector.settings.preserveConsoleLog.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ConsolePreserveLogOn, WebInspector.UserMetrics._SettingCodes.ConsolePreserveLogOff));
WebInspector.settings.resourcesLargeRows.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.NetworkShowLargeRowsOn, WebInspector.UserMetrics._SettingCodes.NetworkShowLargeRowsOff));
}





WebInspector.UserMetrics._ActionCodes = {
WindowDocked: 1,
WindowUndocked: 2,
ScriptsBreakpointSet: 3,
TimelineStarted: 4,
ProfilesCPUProfileTaken: 5,
ProfilesHeapProfileTaken: 6,
AuditsStarted: 7,
ConsoleEvaluated: 8
}

WebInspector.UserMetrics._SettingCodes = {
ElementsDOMWrapOn: 1,
ElementsDOMWrapOff: 2,
ConsoleMonitorXHROn: 3,
ConsoleMonitorXHROff: 4,
ConsolePreserveLogOn: 5,
ConsolePreserveLogOff: 6,
NetworkShowLargeRowsOn: 7,
NetworkShowLargeRowsOff: 8
}

WebInspector.UserMetrics._PanelCodes = {
elements: 1,
resources: 2,
network: 3,
scripts: 4,
timeline: 5,
profiles: 6,
audits: 7,
console: 8
}

WebInspector.UserMetrics.prototype = {
panelShown: function(panelName)
{
InspectorFrontendHost.recordPanelShown(WebInspector.UserMetrics._PanelCodes[panelName] || 0);
}
}


WebInspector.UserMetrics._Recorder = function(actionCode)
{
this._actionCode = actionCode;
}

WebInspector.UserMetrics._Recorder.prototype = {
record: function()
{
InspectorFrontendHost.recordActionTaken(this._actionCode);
}
}

WebInspector.userMetrics = new WebInspector.UserMetrics();






WebInspector.RuntimeModel = function(resourceTreeModel)
{
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._didLoadCachedResources, this);
this._frameIdToContextList = {};
}

WebInspector.RuntimeModel.Events = {
FrameExecutionContextListAdded: "FrameExecutionContextListAdded",
FrameExecutionContextListRemoved: "FrameExecutionContextListRemoved",
}

WebInspector.RuntimeModel.prototype = {

contextLists: function()
{
return Object.values(this._frameIdToContextList);
},


contextByFrameAndSecurityOrigin: function(frame, securityOrigin)
{
var frameContext = this._frameIdToContextList[frame.id];
return frameContext && frameContext.contextBySecurityOrigin(securityOrigin);
},

_frameAdded: function(event)
{
var frame = event.data;
var context = new WebInspector.FrameExecutionContextList(frame);
this._frameIdToContextList[frame.id] = context;
this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, context);
},

_frameNavigated: function(event)
{
var frame = event.data;
var context = this._frameIdToContextList[frame.id];
if (context)
context._frameNavigated(frame);
},

_frameDetached: function(event)
{
var frame = event.data;
var context = this._frameIdToContextList[frame.id];
if (!context)
return;
this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, context);
delete this._frameIdToContextList[frame.id];
},

_didLoadCachedResources: function()
{
InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeDispatcher(this));
RuntimeAgent.setReportExecutionContextCreation(true);
},

_executionContextCreated: function(context)
{
var contextList = this._frameIdToContextList[context.frameId];

if (!contextList)
return;
contextList._addExecutionContext(new WebInspector.ExecutionContext(context.id, context.name, context.isPageContext));
}
}

WebInspector.RuntimeModel.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.runtimeModel = null;


WebInspector.RuntimeDispatcher = function(runtimeModel)
{
this._runtimeModel = runtimeModel;
}

WebInspector.RuntimeDispatcher.prototype = {
executionContextCreated: function(context)
{
this._runtimeModel._executionContextCreated(context);
}
}


WebInspector.ExecutionContext = function(id, name, isPageContext)
{
this.id = id;
this.name = (isPageContext && !name) ? "<page context>" : name;
this.isMainWorldContext = isPageContext;
}


WebInspector.ExecutionContext.comparator = function(a, b)
{

if (a.isMainWorldContext)
return -1;
if (b.isMainWorldContext)
return +1;
return a.name.localeCompare(b.name);
}


WebInspector.FrameExecutionContextList = function(frame)
{
this._frame = frame;
this._executionContexts = [];
}

WebInspector.FrameExecutionContextList.EventTypes = {
ContextsUpdated: "ContextsUpdated",
ContextAdded: "ContextAdded"
}

WebInspector.FrameExecutionContextList.prototype =
{
_frameNavigated: function(frame)
{
this._frame = frame;
this._executionContexts = [];
this.dispatchEventToListeners(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this);
},


_addExecutionContext: function(context)
{
var insertAt = insertionIndexForObjectInListSortedByFunction(context, this._executionContexts, WebInspector.ExecutionContext.comparator);
this._executionContexts.splice(insertAt, 0, context);
this.dispatchEventToListeners(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this);
},

executionContexts: function()
{
return this._executionContexts;
},


contextBySecurityOrigin: function(securityOrigin)
{
for (var i = 0; i < this._executionContexts.length; ++i) {
var context = this._executionContexts[i];
if (!context.isMainWorldContext && context.name === securityOrigin)
return context; 
}
},

get frameId()
{
return this._frame.id;
},

get url()
{
return this._frame.url;
},

get displayName()
{
if (!this._frame.parentFrame)
return "<top frame>";
var name = this._frame.name || "";
var subtitle = new WebInspector.ParsedURL(this._frame.url).displayName;
if (subtitle) {
if (!name)
return subtitle;
return name + "( " + subtitle + " )";
}
return "<iframe>";
}
}

WebInspector.FrameExecutionContextList.prototype.__proto__ = WebInspector.Object.prototype;






WebInspector.HandlerRegistry = function(setting)
{
WebInspector.Object.call(this);
this._handlers = {};
this._setting = setting;
this._activeHandler = this._setting.get();
WebInspector.ContextMenu.registerProvider(this);
}

WebInspector.HandlerRegistry.prototype = {
get handlerNames()
{
return Object.getOwnPropertyNames(this._handlers);
},

get activeHandler()
{
return this._activeHandler;
},

set activeHandler(value)
{
this._activeHandler = value;
this._setting.set(value);
},


dispatch: function(data)
{
return this.dispatchToHandler(this._activeHandler, data);
},


dispatchToHandler: function(name, data)
{
var handler = this._handlers[name];
var result = handler && handler(data);
return !!result;
},

registerHandler: function(name, handler)
{
this._handlers[name] = handler;
this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
},

unregisterHandler: function(name)
{
delete this._handlers[name];
this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
},


appendApplicableItems: function(contextMenu, target)
{
this._appendContentProviderItems(contextMenu, target);
this._appendHrefItems(contextMenu, target);
},


_appendContentProviderItems: function(contextMenu, target)
{
if (!(target instanceof WebInspector.UISourceCode || target instanceof WebInspector.Resource || target instanceof WebInspector.NetworkRequest))
return;
var contentProvider =   target;
if (!contentProvider.contentURL())
return;

contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, contentProvider.contentURL(), false));

for (var i = 1; i < this.handlerNames.length; ++i) {
var handler = this.handlerNames[i];
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open using %s" : "Open Using %s", handler),
this.dispatchToHandler.bind(this, handler, { url: contentProvider.contentURL() }));
}
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, contentProvider.contentURL()));

if (!InspectorFrontendHost.canSave() || !contentProvider.contentURL())
return;

var contentType = contentProvider.contentType();
if (contentType !== WebInspector.resourceTypes.Document &&
contentType !== WebInspector.resourceTypes.Stylesheet &&
contentType !== WebInspector.resourceTypes.Script)
return;

function doSave(forceSaveAs, content)
{
WebInspector.fileManager.save(contentProvider.contentURL(), content, forceSaveAs);
}

function save(forceSaveAs)
{
if (contentProvider instanceof WebInspector.UISourceCode) {
var uiSourceCode =   contentProvider;
if (uiSourceCode.isDirty()) {
doSave(forceSaveAs, uiSourceCode.workingCopy());
return;
}
}
contentProvider.requestContent(doSave.bind(this, forceSaveAs));
}

contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(this, false));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save as..." : "Save As..."), save.bind(this, true));
},


_appendHrefItems: function(contextMenu, target)
{
if (!(target instanceof Node))
return;
var targetNode =   target;

var anchorElement = targetNode.enclosingNodeOrSelfWithClass("webkit-html-resource-link") || targetNode.enclosingNodeOrSelfWithClass("webkit-html-external-link");
if (!anchorElement)
return;

var resourceURL = anchorElement.href;
if (!resourceURL)
return;


contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, resourceURL, false));
if (WebInspector.resourceForURL(resourceURL))
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in Resources panel" : "Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true));
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL));
}
}

WebInspector.HandlerRegistry.EventTypes = {
HandlersUpdated: "HandlersUpdated"
}

WebInspector.HandlerRegistry.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.HandlerSelector = function(handlerRegistry)
{
this._handlerRegistry = handlerRegistry;
this.element = document.createElement("select");
this.element.addEventListener("change", this._onChange.bind(this), false);
this._update();
this._handlerRegistry.addEventListener(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated, this._update.bind(this));
}

WebInspector.HandlerSelector.prototype =
{
_update: function()
{
this.element.removeChildren();
var names = this._handlerRegistry.handlerNames;
var activeHandler = this._handlerRegistry.activeHandler;

for (var i = 0; i < names.length; ++i) {
var option = document.createElement("option");
option.textContent = names[i];
option.selected = activeHandler === names[i];
this.element.appendChild(option);
}
this.element.disabled = names.length <= 1;
},

_onChange: function(event)
{
var value = event.target.value;
this._handlerRegistry.activeHandler = value;
}
}



WebInspector.openAnchorLocationRegistry = null;






WebInspector.SnippetStorage = function(settingPrefix, namePrefix)
{
this._snippets = {};

this._lastSnippetIdentifierSetting = WebInspector.settings.createSetting(settingPrefix + "Snippets_lastIdentifier", 0);
this._snippetsSetting = WebInspector.settings.createSetting(settingPrefix + "Snippets", []);
this._namePrefix = namePrefix;

this._loadSettings();
}

WebInspector.SnippetStorage.prototype = {
get namePrefix()
{
return this._namePrefix;
},

_saveSettings: function()
{
var savedSnippets = [];
for (var id in this._snippets)
savedSnippets.push(this._snippets[id].serializeToObject());
this._snippetsSetting.set(savedSnippets);
},


snippets: function()
{
var result = [];
for (var id in this._snippets)
result.push(this._snippets[id]);
return result;
},


snippetForId: function(id)
{
return this._snippets[id];
},

_loadSettings: function()
{
var savedSnippets = this._snippetsSetting.get();
for (var i = 0; i < savedSnippets.length; ++i)
this._snippetAdded(WebInspector.Snippet.fromObject(this, savedSnippets[i]));
},


deleteSnippet: function(snippet)
{
delete this._snippets[snippet.id];
this._saveSettings();
},


createSnippet: function()
{
var nextId = this._lastSnippetIdentifierSetting.get() + 1;
var snippetId = String(nextId);
this._lastSnippetIdentifierSetting.set(nextId);
var snippet = new WebInspector.Snippet(this, snippetId);
this._snippetAdded(snippet);
this._saveSettings();
return snippet;
},


_snippetAdded: function(snippet)
{
this._snippets[snippet.id] = snippet;
},

reset: function()
{
this._lastSnippetIdentifierSetting.set(0);
this._snippetsSetting.set([]);
this._snippets = {};
}
}

WebInspector.SnippetStorage.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.Snippet = function(storage, id, name, content)
{
this._storage = storage;
this._id = id;
this._name = name || storage.namePrefix + id;
this._content = content || "";
}


WebInspector.Snippet.fromObject = function(storage, serializedSnippet)
{
return new WebInspector.Snippet(storage, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content);
}

WebInspector.Snippet.prototype = {

get id()
{
return this._id;
},


get name()
{
return this._name;
},

set name(name)
{
if (this._name === name)
return;

this._name = name;
this._storage._saveSettings();
},


get content()
{
return this._content;
},

set content(content)
{
if (this._content === content)
return;

this._content = content;
this._storage._saveSettings();
},


serializeToObject: function()
{
var serializedSnippet = {};
serializedSnippet.id = this.id;
serializedSnippet.name = this.name;
serializedSnippet.content = this.content;
return serializedSnippet;
}
}

WebInspector.Snippet.prototype.__proto__ = WebInspector.Object.prototype;






WebInspector.ScriptSnippetModel = function(workspace)
{
this._workspace = workspace;
this._uiSourceCodeForScriptId = {};
this._scriptForUISourceCode = new Map();
this._snippetJavaScriptSourceForSnippetId = {};

this._snippetStorage = new WebInspector.SnippetStorage("script", "Script snippet #");
this._lastSnippetEvaluationIndexSetting = WebInspector.settings.createSetting("lastSnippetEvaluationIndex", 0);
this._snippetScriptMapping = new WebInspector.SnippetScriptMapping(this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectDidReset, this._projectDidReset, this);
this._loadSnippets();
}

WebInspector.ScriptSnippetModel.snippetSourceURLPrefix = "snippets:///";

WebInspector.ScriptSnippetModel.prototype = {

get scriptMapping()
{
return this._snippetScriptMapping;
},

_loadSnippets: function()
{
var snippets = this._snippetStorage.snippets();
for (var i = 0; i < snippets.length; ++i)
this._addScriptSnippet(snippets[i]);
},


createScriptSnippet: function()
{
var snippet = this._snippetStorage.createSnippet();
return this._addScriptSnippet(snippet);
},


_addScriptSnippet: function(snippet)
{
var snippetJavaScriptSource = new WebInspector.SnippetJavaScriptSource(snippet.id, snippet.name, new WebInspector.SnippetContentProvider(snippet), this);
snippetJavaScriptSource.setSourceMapping(this._snippetScriptMapping); 
this._snippetJavaScriptSourceForSnippetId[snippet.id] = snippetJavaScriptSource;
this._workspace.project().addUISourceCode(snippetJavaScriptSource);
return snippetJavaScriptSource;
},


deleteScriptSnippet: function(snippetJavaScriptSource)
{
var snippet = this._snippetStorage.snippetForId(snippetJavaScriptSource.snippetId);
this._snippetStorage.deleteSnippet(snippet);
this._removeBreakpoints(snippetJavaScriptSource);
this._releaseSnippetScript(snippetJavaScriptSource);
delete this._snippetJavaScriptSourceForSnippetId[snippet.id];
this._workspace.project().removeUISourceCode(snippetJavaScriptSource);
},


renameScriptSnippet: function(snippetJavaScriptSource, newName)
{
var snippet = this._snippetStorage.snippetForId(snippetJavaScriptSource.snippetId);
if (!snippet || !newName || snippet.name === newName)
return;
snippet.name = newName;
snippetJavaScriptSource.urlChanged(snippet.name);
},


_isDivergedFromVM: function(snippetJavaScriptSource)
{
var script = this._scriptForUISourceCode.get(snippetJavaScriptSource);
return !script;
},


_setScriptSnippetContent: function(snippetJavaScriptSource, newContent)
{
var snippet = this._snippetStorage.snippetForId(snippetJavaScriptSource.snippetId);
snippet.content = newContent;
},


_scriptSnippetEdited: function(snippetJavaScriptSource)
{
var script = this._scriptForUISourceCode.get(snippetJavaScriptSource);
if (!script)
return;

var breakpointLocations = this._removeBreakpoints(snippetJavaScriptSource);
this._releaseSnippetScript(snippetJavaScriptSource);
this._restoreBreakpoints(snippetJavaScriptSource, breakpointLocations);
},


_nextEvaluationIndex: function(snippetId)
{
var evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
return evaluationIndex;
},


evaluateScriptSnippet: function(snippetJavaScriptSource)
{
var breakpointLocations = this._removeBreakpoints(snippetJavaScriptSource);
this._releaseSnippetScript(snippetJavaScriptSource);
this._restoreBreakpoints(snippetJavaScriptSource, breakpointLocations);
var evaluationIndex = this._nextEvaluationIndex(snippetJavaScriptSource.snippetId);
snippetJavaScriptSource._evaluationIndex = evaluationIndex;
var evaluationUrl = this._evaluationSourceURL(snippetJavaScriptSource);

var expression = snippetJavaScriptSource.workingCopy();





if (WebInspector.debuggerModel.selectedCallFrame() || !Capabilities.separateScriptCompilationAndExecutionEnabled) {
expression = snippetJavaScriptSource.workingCopy() + "\n//@ sourceURL=" + evaluationUrl + "\n";
WebInspector.evaluateInConsole(expression, true);
return;
}

WebInspector.showConsole();
DebuggerAgent.compileScript(expression, evaluationUrl, compileCallback.bind(this));


function compileCallback(error, scriptId, syntaxErrorMessage)
{
if (!snippetJavaScriptSource || snippetJavaScriptSource._evaluationIndex !== evaluationIndex)
return;

if (error) {
console.error(error);
return;
}

if (!scriptId) {
var consoleMessage = WebInspector.ConsoleMessage.create(
WebInspector.ConsoleMessage.MessageSource.JS,
WebInspector.ConsoleMessage.MessageLevel.Error,
syntaxErrorMessage || "");
WebInspector.console.addMessage(consoleMessage);
return;
}

var breakpointLocations = this._removeBreakpoints(snippetJavaScriptSource);
this._restoreBreakpoints(snippetJavaScriptSource, breakpointLocations);

WebInspector.consoleView.runScript(scriptId);
}
},


_rawLocationToUILocation: function(rawLocation)
{
var uiSourceCode = this._uiSourceCodeForScriptId[rawLocation.scriptId];
return new WebInspector.UILocation(uiSourceCode, rawLocation.lineNumber, rawLocation.columnNumber || 0);
},


_uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var script = this._scriptForUISourceCode.get(uiSourceCode);
if (!script)
return null;

return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},


_releasedUISourceCodes: function()
{
var result = [];
for (var scriptId in this._uiSourceCodeForScriptId) {
var uiSourceCode = this._uiSourceCodeForScriptId[scriptId];
if (!uiSourceCode.isSnippet)
result.push(uiSourceCode);
}
return result;
},


_addScript: function(script)
{
var snippetId = this._snippetIdForSourceURL(script.sourceURL);
var snippetJavaScriptSource = this._snippetJavaScriptSourceForSnippetId[snippetId];

if (!snippetJavaScriptSource || this._evaluationSourceURL(snippetJavaScriptSource) !== script.sourceURL) {
this._createUISourceCodeForScript(script);
return;
}

console.assert(!this._scriptForUISourceCode.get(snippetJavaScriptSource));
this._uiSourceCodeForScriptId[script.scriptId] = snippetJavaScriptSource;
this._scriptForUISourceCode.put(snippetJavaScriptSource, script);
script.setSourceMapping(this._snippetScriptMapping);
},


_createUISourceCodeForScript: function(script)
{
var uiSourceCode = new WebInspector.JavaScriptSource(script.sourceURL, null, script, false);
uiSourceCode.setSourceMapping(this._snippetScriptMapping); 
uiSourceCode.isSnippetEvaluation = true;
this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
this._scriptForUISourceCode.put(uiSourceCode, script);
script.setSourceMapping(this._snippetScriptMapping);
},


_removeBreakpoints: function(snippetJavaScriptSource)
{
var breakpointLocations = WebInspector.breakpointManager.breakpointLocationsForUISourceCode(snippetJavaScriptSource);
for (var i = 0; i < breakpointLocations.length; ++i)
breakpointLocations[i].breakpoint.remove();
return breakpointLocations;
},


_restoreBreakpoints: function(snippetJavaScriptSource, breakpointLocations)
{
for (var i = 0; i < breakpointLocations.length; ++i) {
var uiLocation = breakpointLocations[i].uiLocation;
var breakpoint = breakpointLocations[i].breakpoint;
WebInspector.breakpointManager.setBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, breakpoint.condition(), breakpoint.enabled());
}
},


_releaseSnippetScript: function(snippetJavaScriptSource)
{
var script = this._scriptForUISourceCode.get(snippetJavaScriptSource);
if (!script)
return;

delete this._uiSourceCodeForScriptId[script.scriptId];
this._scriptForUISourceCode.remove(snippetJavaScriptSource);
delete snippetJavaScriptSource._evaluationIndex;
this._createUISourceCodeForScript(script);
},


_evaluationSourceURL: function(snippetJavaScriptSource)
{
var snippetPrefix = WebInspector.ScriptSnippetModel.snippetSourceURLPrefix;
var evaluationSuffix = "_" + snippetJavaScriptSource._evaluationIndex;
return snippetPrefix + snippetJavaScriptSource.snippetId + evaluationSuffix;
},


_snippetIdForSourceURL: function(sourceURL)
{
var snippetPrefix = WebInspector.ScriptSnippetModel.snippetSourceURLPrefix;
if (!sourceURL.startsWith(snippetPrefix))
return null;
var splittedURL = sourceURL.substring(snippetPrefix.length).split("_");
var snippetId = splittedURL[0];
return snippetId;
},

_projectWillReset: function()
{
var removedUISourceCodes = this._releasedUISourceCodes();
this._uiSourceCodeForScriptId = {};
this._scriptForUISourceCode = new Map();
this._snippetJavaScriptSourceForSnippetId = {};
},

_projectDidReset: function()
{
this._loadSnippets();
}
}

WebInspector.ScriptSnippetModel.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.SnippetJavaScriptSource = function(snippetId, snippetName, contentProvider, scriptSnippetModel)
{
WebInspector.JavaScriptSource.call(this, snippetName, null, contentProvider, true);
this._snippetId = snippetId;
this._scriptSnippetModel = scriptSnippetModel;
this.isSnippet = true;
}

WebInspector.SnippetJavaScriptSource.prototype = {

isEditable: function()
{
return true;
},


isDivergedFromVM: function()
{
return this._scriptSnippetModel._isDivergedFromVM(this);
},


workingCopyCommitted: function(callback)
{  
this._scriptSnippetModel._setScriptSnippetContent(this, this.workingCopy());
callback(null);
},

workingCopyChanged: function()
{  
this._scriptSnippetModel._scriptSnippetEdited(this);
},

evaluate: function()
{
this._scriptSnippetModel.evaluateScriptSnippet(this);
},


supportsEnabledBreakpointsWhileEditing: function()
{
return true;
},


breakpointStorageId: function()
{
return WebInspector.ScriptSnippetModel.snippetSourceURLPrefix + this.snippetId;
},


get snippetId()
{
return this._snippetId;
}
}

WebInspector.SnippetJavaScriptSource.prototype.__proto__ = WebInspector.JavaScriptSource.prototype;


WebInspector.SnippetScriptMapping = function(scriptSnippetModel)
{
this._scriptSnippetModel = scriptSnippetModel;
}

WebInspector.SnippetScriptMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation =   rawLocation;
return this._scriptSnippetModel._rawLocationToUILocation(debuggerModelLocation);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
return this._scriptSnippetModel._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
},


snippetIdForSourceURL: function(sourceURL)
{
return this._scriptSnippetModel._snippetIdForSourceURL(sourceURL);
},


addScript: function(script)
{
this._scriptSnippetModel._addScript(script);
}
}


WebInspector.SnippetContentProvider = function(snippet)
{
WebInspector.StaticContentProvider.call(this, WebInspector.resourceTypes.Script, snippet.content);
}

WebInspector.SnippetContentProvider.prototype.__proto__ = WebInspector.StaticContentProvider.prototype;


WebInspector.scriptSnippetModel = null;






WebInspector.Progress = function()
{
}

WebInspector.Progress.prototype = {

setTotalWork: function(totalWork) { },


setTitle: function(title) { },


setWorked: function(worked, title) { },


worked: function(worked) { },

done: function() { },


isCanceled: function() { return false; }
}


WebInspector.ProgressIndicator = function()
{
this.element = document.createElement("div");
this.element.className = "progress-bar-container";
this._labelElement = this.element.createChild("span");
this._progressElement = this.element.createChild("progress");
this._stopButton = new WebInspector.StatusBarButton(WebInspector.UIString("Cancel"), "progress-bar-stop-button");
this._stopButton.addEventListener("click", this.cancel, this);
this.element.appendChild(this._stopButton.element);
this._isCanceled = false;
this._worked = 0;
}

WebInspector.ProgressIndicator.Events = {
Done: "Done"
}

WebInspector.ProgressIndicator.prototype = {

show: function(parent)
{
parent.appendChild(this.element);
},

hide: function()
{
var parent = this.element.parentElement;
if (parent)
parent.removeChild(this.element);
},

done: function()
{
if (this._isDone)
return;
this._isDone = true;
this.hide();
this.dispatchEventToListeners(WebInspector.ProgressIndicator.Events.Done);
},

cancel: function()
{
this._isCanceled = true;
},

isCanceled: function()
{
return this._isCanceled;
},


setTitle: function(title)
{
this._labelElement.textContent = title;
},


setTotalWork: function(totalWork)
{
this._progressElement.max = totalWork;
},


setWorked: function(worked, title)
{
this._worked = worked;
this._progressElement.value = worked;
if (title)
this.setTitle(title);
},


worked: function(worked)
{
this.setWorked(this._worked + (worked || 1));
}
}

WebInspector.ProgressIndicator.prototype.__proto__ = WebInspector.Object.prototype;


WebInspector.CompositeProgress = function(parent)
{
this._parent = parent;
this._children = [];
this._childrenDone = 0;
this._parent.setTotalWork(1);
this._parent.setWorked(0);
}

WebInspector.CompositeProgress.prototype = {
_childDone: function()
{
if (++this._childrenDone === this._children.length)
this._parent.done();
},


createSubProgress: function(weight)
{
var child = new WebInspector.SubProgress(this, weight);
this._children.push(child);
return child;
},

_update: function()
{
var totalWeights = 0;
var done = 0;

for (var i = 0; i < this._children.length; ++i) {
var child = this._children[i];
if (child._totalWork)
done += child._weight * child._worked / child._totalWork;
totalWeights += child._weight;
}
this._parent.setWorked(done / totalWeights);
}
}


WebInspector.SubProgress = function(composite, weight)
{
this._composite = composite;
this._weight = weight || 1;
this._worked = 0;
}

WebInspector.SubProgress.prototype = {

isCanceled: function()
{
return this._composite._parent.isCanceled();
},


setTitle: function(title)
{
this._composite._parent.setTitle(title);
},

done: function()
{
this.setWorked(this._totalWork);
this._composite._childDone();
},


setTotalWork: function(totalWork)
{
this._totalWork = totalWork;
this._composite._update();
},


setWorked: function(worked, title)
{
this._worked = worked;
if (typeof title !== "undefined")
this.setTitle(title);
this._composite._update();
},


worked: function(worked)
{
this.setWorked(this._worked + (worked || 1));
}
}






WebInspector.StylesSourceMapping = function(workspace)
{
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._reset, this);
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);

this._uiSourceCodeForURL = {};
}

WebInspector.StylesSourceMapping.prototype = {

rawLocationToUILocation: function(rawLocation)
{
var location =   rawLocation;
var uiSourceCode = this._uiSourceCodeForURL[location.url];
return new WebInspector.UILocation(uiSourceCode, location.lineNumber, 0);
},


uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
return new WebInspector.CSSLocation(uiSourceCode.contentURL() || "", lineNumber);
},

_uiSourceCodeAddedToWorkspace: function(event)
{
var uiSourceCode =   event.data;
if (!uiSourceCode.url || this._uiSourceCodeForURL[uiSourceCode.url])
return;
if (uiSourceCode.contentType() !== WebInspector.resourceTypes.StyleSheet)
return;

this._addUISourceCode(uiSourceCode);
},


_addUISourceCode: function(uiSourceCode)
{
this._uiSourceCodeForURL[uiSourceCode.url] = uiSourceCode;
uiSourceCode.setSourceMapping(this);
WebInspector.cssModel.setSourceMapping(uiSourceCode.url, this);
},

_reset: function()
{
this._uiSourceCodeForURL = {};
WebInspector.cssModel.resetSourceMappings();
}
}







WebInspector.StyleSource = function(resource)
{
WebInspector.UISourceCode.call(this, resource.url, resource, resource);
}

WebInspector.StyleSource.updateTimeout = 200;

WebInspector.StyleSource.prototype = {

isEditable: function()
{
return true;
},


workingCopyCommitted: function(callback)
{  
this._commitIncrementalEdit(true, callback);
},

workingCopyChanged: function()
{
this._callOrSetTimeout(this._commitIncrementalEdit.bind(this, false, function() {}));
},


_callOrSetTimeout: function(callback)
{

if (WebInspector.StyleSource.updateTimeout >= 0)
this._incrementalUpdateTimer = setTimeout(callback, WebInspector.StyleSource.updateTimeout);
else
callback(null);
},


_commitIncrementalEdit: function(majorChange, callback)
{
this._clearIncrementalUpdateTimer();
WebInspector.cssModel.resourceBinding().setStyleContent(this, this.workingCopy(), majorChange, callback);
},

_clearIncrementalUpdateTimer: function()
{
if (this._incrementalUpdateTimer)
clearTimeout(this._incrementalUpdateTimer);
delete this._incrementalUpdateTimer;
}
}

WebInspector.StyleSource.prototype.__proto__ = WebInspector.UISourceCode.prototype;






WebInspector.NetworkUISourceCodeProvider = function(workspace)
{
this._workspace = workspace;
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectDidReset, this._projectDidReset, this);

this._uiSourceCodeForResource = {};
}

WebInspector.NetworkUISourceCodeProvider.prototype = {
_populate: function()
{
function populateFrame(frame)
{
for (var i = 0; i < frame.childFrames.length; ++i)
populateFrame.call(this, frame.childFrames[i]);

var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this._resourceAdded({data:resources[i]});
}

populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
},


_resourceAdded: function(event)
{
var resource =   event.data;
if (this._uiSourceCodeForResource[resource.url])
return;
var uiSourceCode;
switch (resource.type) {
case WebInspector.resourceTypes.Stylesheet:
uiSourceCode = new WebInspector.StyleSource(resource);
break;
case WebInspector.resourceTypes.Document:
uiSourceCode = new WebInspector.JavaScriptSource(resource.url, resource, resource, false);
break;
case WebInspector.resourceTypes.Script:
uiSourceCode = new WebInspector.JavaScriptSource(resource.url, resource, resource, true);
break;
}
if (uiSourceCode) {
this._uiSourceCodeForResource[resource.url] = uiSourceCode;
this._workspace.project().addUISourceCode(uiSourceCode);
}
},

_projectWillReset: function()
{
this._uiSourceCodeForResource = {};
},

_projectDidReset: function()
{
this._populate();
}
}






WebInspector.ElementsPanelDescriptor = function()
{
WebInspector.PanelDescriptor.call(this, "elements", WebInspector.UIString("Elements"), "ElementsPanel", "ElementsPanel.js");
WebInspector.ContextMenu.registerProvider(this);
}

WebInspector.ElementsPanelDescriptor.prototype = {

appendApplicableItems: function(contextMenu, target)
{
if (!(target instanceof WebInspector.RemoteObject))
return;
var remoteObject =   target;
if (remoteObject.subtype !== "node")
return;
this.panel().appendApplicableItems(contextMenu, target);
}
}

WebInspector.ElementsPanelDescriptor.prototype.__proto__ = WebInspector.PanelDescriptor.prototype;







WebInspector.NetworkPanelDescriptor = function()
{
WebInspector.PanelDescriptor.call(this, "network", WebInspector.UIString("Network"), "NetworkPanel", "NetworkPanel.js");
WebInspector.ContextMenu.registerProvider(this);
}

WebInspector.NetworkPanelDescriptor.prototype = {

appendApplicableItems: function(contextMenu, target)
{
if (!(target instanceof WebInspector.NetworkRequest))
return;
this.panel().appendApplicableItems(contextMenu, target);
}
}

WebInspector.NetworkPanelDescriptor.prototype.__proto__ = WebInspector.PanelDescriptor.prototype;






WebInspector.ScriptsPanelDescriptor = function()
{
WebInspector.PanelDescriptor.call(this, "scripts", WebInspector.UIString("Sources"), "ScriptsPanel", "ScriptsPanel.js");
WebInspector.ContextMenu.registerProvider(this);
}

WebInspector.ScriptsPanelDescriptor.prototype = {

appendApplicableItems: function(contextMenu, target)
{
var hasApplicableItems = target instanceof WebInspector.UISourceCode;

if (!hasApplicableItems && target instanceof WebInspector.RemoteObject) {
var remoteObject =   target;
if (remoteObject.type !== "function")
return;
}

this.panel().appendApplicableItems(contextMenu, target);
}
}

WebInspector.ScriptsPanelDescriptor.prototype.__proto__ = WebInspector.PanelDescriptor.prototype;







{(function () {
Preferences.useLowerCaseMenuTitlesOnWindows = true;
Preferences.sharedWorkersDebugNote = "Shared workers can be inspected in the Task Manager";
Preferences.localizeUI = false;
Preferences.applicationTitle = "Developer Tools - %s";
Preferences.exposeDisableCache = true;
Preferences.showDockToRight = true;
Preferences.exposeFileSystemInspection = true;
})();}

function buildPlatformExtensionAPI(extensionInfo)
{
return "var extensionInfo = " + JSON.stringify(extensionInfo) + ";" +
"var tabId = " + WebInspector._inspectedTabId + ";" +
platformExtensionAPI.toString();
}

WebInspector.setInspectedTabId = function(tabId)
{
WebInspector._inspectedTabId = tabId;
}

WebInspector.clipboardAccessDeniedMessage = function()
{
return "You need to install a Chrome extension that grants clipboard access to Developer Tools.";
}





function platformExtensionAPI(coreAPI)
{
function getTabId()
{
return tabId;
}
chrome = window.chrome || {};



var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools");
if (!devtools_descriptor || devtools_descriptor.get)
Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true });

chrome.devtools.inspectedWindow = {};
chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId);
chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
chrome.devtools.network = coreAPI.network;
chrome.devtools.panels = coreAPI.panels;


if (extensionInfo.exposeExperimentalAPIs !== false) {
chrome.experimental = chrome.experimental || {};
chrome.experimental.devtools = chrome.experimental.devtools || {};

var properties = Object.getOwnPropertyNames(coreAPI);
for (var i = 0; i < properties.length; ++i) {
var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
}
chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
}
if (extensionInfo.exposeWebInspectorNamespace)
window.webInspector = coreAPI;
}








if (window.domAutomationController) {

var ___interactiveUiTestsMode = true;


TestSuite = function()
{
this.controlTaken_ = false;
this.timerId_ = -1;
};



TestSuite.prototype.fail = function(message)
{
if (this.controlTaken_)
this.reportFailure_(message);
else
throw message;
};



TestSuite.prototype.assertEquals = function(expected, actual, opt_message)
{
if (expected !== actual) {
var message = "Expected: '" + expected + "', but was '" + actual + "'";
if (opt_message)
message = opt_message + "(" + message + ")";
this.fail(message);
}
};


TestSuite.prototype.assertTrue = function(value, opt_message)
{
this.assertEquals(true, !!value, opt_message);
};



TestSuite.prototype.assertContains = function(string, substring)
{
if (string.indexOf(substring) === -1)
this.fail("Expected to: '" + string + "' to contain '" + substring + "'");
};



TestSuite.prototype.takeControl = function()
{
this.controlTaken_ = true;

var self = this;
this.timerId_ = setTimeout(function() {
self.reportFailure_("Timeout exceeded: 20 sec");
}, 20000);
};



TestSuite.prototype.releaseControl = function()
{
if (this.timerId_ !== -1) {
clearTimeout(this.timerId_);
this.timerId_ = -1;
}
this.reportOk_();
};



TestSuite.prototype.reportOk_ = function()
{
window.domAutomationController.send("[OK]");
};



TestSuite.prototype.reportFailure_ = function(error)
{
if (this.timerId_ !== -1) {
clearTimeout(this.timerId_);
this.timerId_ = -1;
}
window.domAutomationController.send("[FAILED] " + error);
};



TestSuite.prototype.runTest = function(testName)
{
try {
this[testName]();
if (!this.controlTaken_)
this.reportOk_();
} catch (e) {
this.reportFailure_(e);
}
};



TestSuite.prototype.showPanel = function(panelName)
{

var toolbar = document.getElementById("toolbar");
var button = toolbar.getElementsByClassName(panelName)[0];
button.click();
this.assertEquals(WebInspector.panels[panelName], WebInspector.inspectorView.currentPanel());
};



TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_sticky)
{
var orig = receiver[methodName];
if (typeof orig !== "function")
this.fail("Cannot find method to override: " + methodName);
var test = this;
receiver[methodName] = function(var_args) {
try {
var result = orig.apply(this, arguments);
} finally {
if (!opt_sticky)
receiver[methodName] = orig;
}

try {
override.apply(this, arguments);
} catch (e) {
test.fail("Exception in overriden method '" + methodName + "': " + e);
}
return result;
};
};


TestSuite.prototype.testEnableResourcesTab = function()
{

}

TestSuite.prototype.testCompletionOnPause = function()
{

}





TestSuite.prototype.testShowScriptsTab = function()
{
this.showPanel("scripts");
var test = this;

this._waitUntilScriptsAreParsed(["debugger_test_page.html"],
function() {
test.releaseControl();
});

this.takeControl();
};



TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function()
{
var test = this;
this.assertEquals(WebInspector.panels.elements, WebInspector.inspectorView.currentPanel(), "Elements panel should be current one.");

WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, waitUntilScriptIsParsed);


test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});

function waitUntilScriptIsParsed()
{
WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, waitUntilScriptIsParsed);
test.showPanel("scripts");
test._waitUntilScriptsAreParsed(["debugger_test_page.html"],
function() {
test.releaseControl();
});
}


this.takeControl();
};



TestSuite.prototype.testContentScriptIsPresent = function()
{
this.showPanel("scripts");
var test = this;

test._waitUntilScriptsAreParsed(
["page_with_content_script.html", "simple_content_script.js"],
function() {
test.releaseControl();
});


this.takeControl();
};



TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function()
{
var test = this;




var expectedScriptsCount = 2;
var parsedScripts = [];

this.showPanel("scripts");

function switchToElementsTab() {
test.showPanel("elements");
setTimeout(switchToScriptsTab, 0);
}

function switchToScriptsTab() {
test.showPanel("scripts");
setTimeout(checkScriptsPanel, 0);
}

function checkScriptsPanel() {
test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html"]), "Some scripts are missing.");
checkNoDuplicates();
test.releaseControl();
}

function checkNoDuplicates() {
var uiSourceCodes = test.nonAnonymousUISourceCodes_();
for (var i = 0; i < uiSourceCodes.length; i++) {
var scriptName = uiSourceCodes[i].fileName;
for (var j = i + 1; j < uiSourceCodes.length; j++)
test.assertTrue(scriptName !== uiSourceCodes[j].fileName, "Found script duplicates: " + test.uiSourceCodesToString_(uiSourceCodes));
}
}

test._waitUntilScriptsAreParsed(
["debugger_test_page.html"],
function() {
checkNoDuplicates();
setTimeout(switchToElementsTab, 0);
});



this.takeControl();
};




TestSuite.prototype.testPauseWhenLoadingDevTools = function()
{
this.showPanel("scripts");


if (WebInspector.debuggerModel.debuggerPausedDetails)
return;

this._waitForScriptPause(this.releaseControl.bind(this));
this.takeControl();
};




TestSuite.prototype.testPauseWhenScriptIsRunning = function()
{
this.showPanel("scripts");

this.evaluateInConsole_(
'setTimeout("handleClick()" , 0)',
didEvaluateInConsole.bind(this));

function didEvaluateInConsole(resultText) {
this.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);


setTimeout(testScriptPause.bind(this), 300);
}

function testScriptPause() {


WebInspector.panels.scripts.pauseButton.click();

this._waitForScriptPause(this.releaseControl.bind(this));
}

this.takeControl();
};



TestSuite.prototype.testNetworkSize = function()
{
var test = this;

function finishResource(resource, finishTime)
{
test.assertEquals(219, resource.transferSize, "Incorrect total encoded data length");
test.assertEquals(25, resource.resourceSize, "Incorrect total data length");
test.releaseControl();
}

this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkRequest", finishResource);


test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});

this.takeControl();
};



TestSuite.prototype.testNetworkSyncSize = function()
{
var test = this;

function finishResource(resource, finishTime)
{
test.assertEquals(219, resource.transferSize, "Incorrect total encoded data length");
test.assertEquals(25, resource.resourceSize, "Incorrect total data length");
test.releaseControl();
}

this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkRequest", finishResource);


test.evaluateInConsole_("var xhr = new XMLHttpRequest(); xhr.open(\"GET\", \"chunked\", false); xhr.send(null);", function() {});

this.takeControl();
};



TestSuite.prototype.testNetworkRawHeadersText = function()
{
var test = this;

function finishResource(resource, finishTime)
{
if (!resource.responseHeadersText)
test.fail("Failure: resource does not have response headers text");
test.assertEquals(164, resource.responseHeadersText.length, "Incorrect response headers text length");
test.releaseControl();
}

this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkRequest", finishResource);


test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});

this.takeControl();
};



TestSuite.prototype.testNetworkTiming = function()
{
var test = this;

function finishResource(resource, finishTime)
{



test.assertTrue(resource.timing.receiveHeadersEnd - resource.timing.connectStart >= 70, 
"Time between receiveHeadersEnd and connectStart should be >=70ms, but was " +
"receiveHeadersEnd=" + resource.timing.receiveHeadersEnd + ", connectStart=" + resource.timing.connectStart + ".");
test.assertTrue(resource.responseReceivedTime - resource.startTime >= 0.07, 
"Time between responseReceivedTime and startTime should be >=0.07s, but was " +
"responseReceivedTime=" + resource.responseReceivedTime + ", startTime=" + resource.startTime + ".");
test.assertTrue(resource.endTime - resource.startTime >= 0.14, 
"Time between endTime and startTime should be >=0.14s, but was " +
"endtime=" + resource.endTime + ", startTime=" + resource.startTime + ".");

test.releaseControl();
}

this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishNetworkRequest", finishResource);


test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});

this.takeControl();
};


TestSuite.prototype.testConsoleOnNavigateBack = function()
{
if (WebInspector.console.messages.length === 1)
firstConsoleMessageReceived.call(this);
else
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this);

function firstConsoleMessageReceived() {
this.evaluateInConsole_("clickLink();", didClickLink.bind(this));
}

function didClickLink() {

this.assertEquals(1, WebInspector.console.messages.length);
this.assertEquals(1, WebInspector.console.messages[0].totalRepeatCount);
this.evaluateInConsole_("history.back();", didNavigateBack.bind(this));
}

function didNavigateBack()
{

this.evaluateInConsole_("void 0;", didCompleteNavigation.bind(this));
}

function didCompleteNavigation() {
this.assertEquals(1, WebInspector.console.messages.length);
this.assertEquals(1, WebInspector.console.messages[0].totalRepeatCount);
this.releaseControl();
}

this.takeControl();
};


TestSuite.prototype.testReattachAfterCrash = function()
{
this.evaluateInConsole_("1+1;", this.releaseControl.bind(this));
this.takeControl();
};


TestSuite.prototype.testSharedWorker = function()
{
function didEvaluateInConsole(resultText) {
this.assertEquals("2011", resultText);
this.releaseControl();
}
this.evaluateInConsole_("globalVar", didEvaluateInConsole.bind(this));
this.takeControl();
};


TestSuite.prototype.testPauseInSharedWorkerInitialization = function()
{
if (WebInspector.debuggerModel.debuggerPausedDetails)
return;
this._waitForScriptPause(this.releaseControl.bind(this));
this.takeControl();
};


TestSuite.prototype.waitForTestResultsInConsole = function()
{
var messages = WebInspector.console.messages;
for (var i = 0; i < messages.length; ++i) {
var text = messages[i].text;
if (text === "PASS")
return;
else if (/^FAIL/.test(text))
this.fail(text); 
}

function onConsoleMessage(event)
{
var text = event.data.text;
if (text === "PASS")
this.releaseControl();
else if (/^FAIL/.test(text))
this.fail(text);
}

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
this.takeControl();
};

TestSuite.prototype.checkLogAndErrorMessages = function()
{
var messages = WebInspector.console.messages;

var matchesCount = 0;
function validMessage(message)
{
if (message.text === "log" && message.level === WebInspector.ConsoleMessage.MessageLevel.Log) {
++matchesCount;
return true;
}

if (message.text === "error" && message.level === WebInspector.ConsoleMessage.MessageLevel.Error) {
++matchesCount;
return true;
}
return false;
}

for (var i = 0; i < messages.length; ++i) {
if (validMessage(messages[i]))
continue;
this.fail(messages[i].text + ":" + messages[i].level); 
}

if (matchesCount === 2)
return;


function onConsoleMessage(event)
{
var message = event.data;
if (validMessage(message)) {
if (matchesCount === 2) {
this.releaseControl();
return;
}
} else
this.fail(message.text + ":" + messages[i].level);
}

WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
this.takeControl();
};


TestSuite.prototype.uiSourceCodesToString_ = function(uiSourceCodes)
{
var names = [];
for (var i = 0; i < uiSourceCodes.length; i++)
names.push('"' + uiSourceCodes[i].fileName + '"');
return names.join(",");
};



TestSuite.prototype.nonAnonymousUISourceCodes_ = function()
{
function filterOutAnonymous(uiSourceCode)
{
return !!uiSourceCode.url;
}

var uiSourceCodes = WebInspector.workspace.uiSourceCodes();
return uiSourceCodes.filter(filterOutAnonymous);
};



TestSuite.prototype.evaluateInConsole_ = function(code, callback)
{
WebInspector.showConsole();
WebInspector.consoleView.prompt.text = code;
WebInspector.consoleView.promptElement.dispatchEvent(TestSuite.createKeyEvent("Enter"));

this.addSniffer(WebInspector.ConsoleView.prototype, "_appendConsoleMessage",
function(commandResult) {
callback(commandResult.toMessageElement().textContent);
});
};



TestSuite.prototype._scriptsAreParsed = function(expected)
{
var uiSourceCodes = this.nonAnonymousUISourceCodes_();

var missing = expected.slice(0);
for (var i = 0; i < uiSourceCodes.length; ++i) {
for (var j = 0; j < missing.length; ++j) {
if (uiSourceCodes[i].parsedURL.lastPathComponent.search(missing[j]) !== -1) {
missing.splice(j, 1);
break;
}
}
}
return missing.length === 0;
};



TestSuite.prototype._waitForScriptPause = function(callback)
{
function pauseListener(event) {
WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, pauseListener, this);
callback();
}
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, pauseListener, this);
};



TestSuite.prototype._executeCodeWhenScriptsAreParsed = function(code, expectedScripts)
{
var test = this;

function executeFunctionInInspectedPage() {


test.evaluateInConsole_(
'setTimeout("' + code + '" , 0)',
function(resultText) {
test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText + ". Code: " + code);
});
}

test._waitUntilScriptsAreParsed(expectedScripts, executeFunctionInInspectedPage);
};



TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callback)
{
var test = this;

function waitForAllScripts() {
if (test._scriptsAreParsed(expectedScripts))
callback();
else
test.addSniffer(WebInspector.panels.scripts, "_addUISourceCode", waitForAllScripts);
}

waitForAllScripts();
};



TestSuite.createKeyEvent = function(keyIdentifier)
{
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keydown", true  , true  , null  , keyIdentifier, "");
return evt;
};



var uiTests = {};



uiTests.runAllTests = function()
{

for (var name in TestSuite.prototype) {
if (name.substring(0, 4) === "test" && typeof TestSuite.prototype[name] === "function")
uiTests.runTest(name);
}
};



uiTests.runTest = function(name)
{
if (uiTests._populatedInterface)
new TestSuite().runTest(name);
else
uiTests._pendingTestName = name;
};

(function() {

function runTests()
{
uiTests._populatedInterface = true;
var name = uiTests._pendingTestName;
delete uiTests._pendingTestName;
if (name)
new TestSuite().runTest(name);
}

var oldLoadCompleted = InspectorFrontendAPI.loadCompleted;
InspectorFrontendAPI.loadCompleted = function()
{
oldLoadCompleted.call(InspectorFrontendAPI);
runTests();
}

})();

}

