Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Unified Diff: third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
index c6da1dd1e9d3da25b8939a60ecbd2b19ef0b75c4..079330b58f43437f07ce43c5dc21434f244e01af 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
@@ -1,443 +1,404 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-
/**
- * @constructor
* @implements {WebInspector.Searchable}
- * @extends {WebInspector.ProfileView}
- * @param {!WebInspector.SamplingHeapProfileHeader} profileHeader
+ * @unrestricted
*/
-WebInspector.HeapProfileView = function(profileHeader)
-{
- WebInspector.ProfileView.call(this);
+WebInspector.HeapProfileView = class extends WebInspector.ProfileView {
+ /**
+ * @param {!WebInspector.SamplingHeapProfileHeader} profileHeader
+ */
+ constructor(profileHeader) {
+ super();
this._profileHeader = profileHeader;
this.profile = new WebInspector.SamplingHeapProfileModel(profileHeader._profile || profileHeader.protocolProfile());
this.adjustedTotal = this.profile.total;
var views = [
- WebInspector.ProfileView.ViewTypes.Flame,
- WebInspector.ProfileView.ViewTypes.Heavy,
- WebInspector.ProfileView.ViewTypes.Tree
+ WebInspector.ProfileView.ViewTypes.Flame, WebInspector.ProfileView.ViewTypes.Heavy,
+ WebInspector.ProfileView.ViewTypes.Tree
];
this.initialize(new WebInspector.HeapProfileView.NodeFormatter(this), views);
-};
-
-WebInspector.HeapProfileView.prototype = {
- /**
- * @override
- * @param {string} columnId
- * @return {string}
- */
- columnHeader: function(columnId)
- {
- switch (columnId) {
- case "self": return WebInspector.UIString("Self Size (bytes)");
- case "total": return WebInspector.UIString("Total Size (bytes)");
- }
- return "";
- },
-
- /**
- * @override
- * @return {!WebInspector.FlameChartDataProvider}
- */
- createFlameChartDataProvider: function()
- {
- return new WebInspector.HeapFlameChartDataProvider(this.profile, this._profileHeader.target());
- },
-
- __proto__: WebInspector.ProfileView.prototype
+ }
+
+ /**
+ * @override
+ * @param {string} columnId
+ * @return {string}
+ */
+ columnHeader(columnId) {
+ switch (columnId) {
+ case 'self':
+ return WebInspector.UIString('Self Size (bytes)');
+ case 'total':
+ return WebInspector.UIString('Total Size (bytes)');
+ }
+ return '';
+ }
+
+ /**
+ * @override
+ * @return {!WebInspector.FlameChartDataProvider}
+ */
+ createFlameChartDataProvider() {
+ return new WebInspector.HeapFlameChartDataProvider(this.profile, this._profileHeader.target());
+ }
};
/**
- * @constructor
- * @extends {WebInspector.ProfileType}
+ * @unrestricted
*/
-WebInspector.SamplingHeapProfileType = function()
-{
- WebInspector.ProfileType.call(this, WebInspector.SamplingHeapProfileType.TypeId, WebInspector.UIString("Record Allocation Profile"));
+WebInspector.SamplingHeapProfileType = class extends WebInspector.ProfileType {
+ constructor() {
+ super(WebInspector.SamplingHeapProfileType.TypeId, WebInspector.UIString('Record Allocation Profile'));
this._recording = false;
WebInspector.SamplingHeapProfileType.instance = this;
-};
-
-WebInspector.SamplingHeapProfileType.TypeId = "SamplingHeap";
-
-WebInspector.SamplingHeapProfileType.prototype = {
- /**
- * @override
- * @return {string}
- */
- typeName: function()
- {
- return "Heap";
- },
-
- /**
- * @override
- * @return {string}
- */
- fileExtension: function()
- {
- return ".heapprofile";
- },
-
- get buttonTooltip()
- {
- return this._recording ? WebInspector.UIString("Stop heap profiling") : WebInspector.UIString("Start heap profiling");
- },
+ }
+
+ /**
+ * @override
+ * @return {string}
+ */
+ typeName() {
+ return 'Heap';
+ }
+
+ /**
+ * @override
+ * @return {string}
+ */
+ fileExtension() {
+ return '.heapprofile';
+ }
+
+ get buttonTooltip() {
+ return this._recording ? WebInspector.UIString('Stop heap profiling') :
+ WebInspector.UIString('Start heap profiling');
+ }
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ buttonClicked() {
+ var wasRecording = this._recording;
+ if (wasRecording)
+ this.stopRecordingProfile();
+ else
+ this.startRecordingProfile();
+ return !wasRecording;
+ }
+
+ get treeItemTitle() {
+ return WebInspector.UIString('ALLOCATION PROFILES');
+ }
+
+ get description() {
+ return WebInspector.UIString('Allocation profiles show memory allocations from your JavaScript functions.');
+ }
+
+ startRecordingProfile() {
+ var target = WebInspector.context.flavor(WebInspector.Target);
+ if (this._profileBeingRecorded || !target)
+ return;
+ var profile = new WebInspector.SamplingHeapProfileHeader(target, this);
+ this.setProfileBeingRecorded(profile);
+ WebInspector.targetManager.suspendAllTargets();
+ this.addProfile(profile);
+ profile.updateStatus(WebInspector.UIString('Recording\u2026'));
+ this._recording = true;
+ target.heapProfilerModel.startSampling();
+ }
+
+ stopRecordingProfile() {
+ this._recording = false;
+ if (!this._profileBeingRecorded || !this._profileBeingRecorded.target())
+ return;
- /**
- * @override
- * @return {boolean}
- */
- buttonClicked: function()
- {
- var wasRecording = this._recording;
- if (wasRecording)
- this.stopRecordingProfile();
- else
- this.startRecordingProfile();
- return !wasRecording;
- },
-
- get treeItemTitle()
- {
- return WebInspector.UIString("ALLOCATION PROFILES");
- },
-
- get description()
- {
- return WebInspector.UIString("Allocation profiles show memory allocations from your JavaScript functions.");
- },
-
- startRecordingProfile: function()
- {
- var target = WebInspector.context.flavor(WebInspector.Target);
- if (this._profileBeingRecorded || !target)
- return;
- var profile = new WebInspector.SamplingHeapProfileHeader(target, this);
- this.setProfileBeingRecorded(profile);
- WebInspector.targetManager.suspendAllTargets();
- this.addProfile(profile);
- profile.updateStatus(WebInspector.UIString("Recording\u2026"));
- this._recording = true;
- target.heapProfilerModel.startSampling();
- },
-
- stopRecordingProfile: function()
- {
- this._recording = false;
- if (!this._profileBeingRecorded || !this._profileBeingRecorded.target())
- return;
-
- var recordedProfile;
-
- /**
- * @param {?HeapProfilerAgent.SamplingHeapProfile} profile
- * @this {WebInspector.SamplingHeapProfileType}
- */
- function didStopProfiling(profile)
- {
- if (!this._profileBeingRecorded)
- return;
- console.assert(profile);
- this._profileBeingRecorded.setProtocolProfile(profile);
- this._profileBeingRecorded.updateStatus("");
- recordedProfile = this._profileBeingRecorded;
- this.setProfileBeingRecorded(null);
- }
-
- /**
- * @this {WebInspector.SamplingHeapProfileType}
- */
- function fireEvent()
- {
- this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, recordedProfile);
- }
-
- this._profileBeingRecorded.target().heapProfilerModel.stopSampling()
- .then(didStopProfiling.bind(this))
- .then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector.targetManager))
- .then(fireEvent.bind(this));
- },
+ var recordedProfile;
/**
- * @override
- * @param {string} title
- * @return {!WebInspector.ProfileHeader}
+ * @param {?HeapProfilerAgent.SamplingHeapProfile} profile
+ * @this {WebInspector.SamplingHeapProfileType}
*/
- createProfileLoadedFromFile: function(title)
- {
- return new WebInspector.SamplingHeapProfileHeader(null, this, title);
- },
+ function didStopProfiling(profile) {
+ if (!this._profileBeingRecorded)
+ return;
+ console.assert(profile);
+ this._profileBeingRecorded.setProtocolProfile(profile);
+ this._profileBeingRecorded.updateStatus('');
+ recordedProfile = this._profileBeingRecorded;
+ this.setProfileBeingRecorded(null);
+ }
/**
- * @override
+ * @this {WebInspector.SamplingHeapProfileType}
*/
- profileBeingRecordedRemoved: function()
- {
- this.stopRecordingProfile();
- },
+ function fireEvent() {
+ this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, recordedProfile);
+ }
- __proto__: WebInspector.ProfileType.prototype
+ this._profileBeingRecorded.target()
+ .heapProfilerModel.stopSampling()
+ .then(didStopProfiling.bind(this))
+ .then(WebInspector.targetManager.resumeAllTargets.bind(WebInspector.targetManager))
+ .then(fireEvent.bind(this));
+ }
+
+ /**
+ * @override
+ * @param {string} title
+ * @return {!WebInspector.ProfileHeader}
+ */
+ createProfileLoadedFromFile(title) {
+ return new WebInspector.SamplingHeapProfileHeader(null, this, title);
+ }
+
+ /**
+ * @override
+ */
+ profileBeingRecordedRemoved() {
+ this.stopRecordingProfile();
+ }
};
+WebInspector.SamplingHeapProfileType.TypeId = 'SamplingHeap';
+
/**
- * @constructor
- * @extends {WebInspector.WritableProfileHeader}
- * @param {?WebInspector.Target} target
- * @param {!WebInspector.SamplingHeapProfileType} type
- * @param {string=} title
+ * @unrestricted
*/
-WebInspector.SamplingHeapProfileHeader = function(target, type, title)
-{
- WebInspector.WritableProfileHeader.call(this, target, type, title || WebInspector.UIString("Profile %d", type.nextProfileUid()));
-};
-
-WebInspector.SamplingHeapProfileHeader.prototype = {
- /**
- * @override
- * @return {!WebInspector.ProfileView}
- */
- createView: function()
- {
- return new WebInspector.HeapProfileView(this);
- },
-
- /**
- * @return {!HeapProfilerAgent.SamplingHeapProfile}
- */
- protocolProfile: function()
- {
- return this._protocolProfile;
- },
-
- __proto__: WebInspector.WritableProfileHeader.prototype
+WebInspector.SamplingHeapProfileHeader = class extends WebInspector.WritableProfileHeader {
+ /**
+ * @param {?WebInspector.Target} target
+ * @param {!WebInspector.SamplingHeapProfileType} type
+ * @param {string=} title
+ */
+ constructor(target, type, title) {
+ super(target, type, title || WebInspector.UIString('Profile %d', type.nextProfileUid()));
+ }
+
+ /**
+ * @override
+ * @return {!WebInspector.ProfileView}
+ */
+ createView() {
+ return new WebInspector.HeapProfileView(this);
+ }
+
+ /**
+ * @return {!HeapProfilerAgent.SamplingHeapProfile}
+ */
+ protocolProfile() {
+ return this._protocolProfile;
+ }
};
/**
- * @constructor
- * @extends {WebInspector.ProfileNode}
- * @param {!HeapProfilerAgent.SamplingHeapProfileNode} node
+ * @unrestricted
*/
-WebInspector.SamplingHeapProfileNode = function(node)
-{
+WebInspector.SamplingHeapProfileNode = class extends WebInspector.ProfileNode {
+ /**
+ * @param {!HeapProfilerAgent.SamplingHeapProfileNode} node
+ */
+ constructor(node) {
var callFrame = node.callFrame || /** @type {!RuntimeAgent.CallFrame} */ ({
- // Backward compatibility for old CpuProfileNode format.
- functionName: node["functionName"],
- scriptId: node["scriptId"],
- url: node["url"],
- lineNumber: node["lineNumber"] - 1,
- columnNumber: node["columnNumber"] - 1
- });
- WebInspector.ProfileNode.call(this, callFrame);
+ // Backward compatibility for old CpuProfileNode format.
+ functionName: node['functionName'],
+ scriptId: node['scriptId'],
+ url: node['url'],
+ lineNumber: node['lineNumber'] - 1,
+ columnNumber: node['columnNumber'] - 1
+ });
+ super(callFrame);
this.self = node.selfSize;
-};
-
-WebInspector.SamplingHeapProfileNode.prototype = {
- __proto__: WebInspector.ProfileNode.prototype
+ }
};
/**
- * @constructor
- * @extends {WebInspector.ProfileTreeModel}
- * @param {!HeapProfilerAgent.SamplingHeapProfile} profile
+ * @unrestricted
*/
-WebInspector.SamplingHeapProfileModel = function(profile)
-{
- WebInspector.ProfileTreeModel.call(this);
+WebInspector.SamplingHeapProfileModel = class extends WebInspector.ProfileTreeModel {
+ /**
+ * @param {!HeapProfilerAgent.SamplingHeapProfile} profile
+ */
+ constructor(profile) {
+ super();
this.initialize(translateProfileTree(profile.head));
/**
* @param {!HeapProfilerAgent.SamplingHeapProfileNode} root
* @return {!WebInspector.SamplingHeapProfileNode}
*/
- function translateProfileTree(root)
- {
- var resultRoot = new WebInspector.SamplingHeapProfileNode(root);
- var targetNodeStack = [resultRoot];
- var sourceNodeStack = [root];
- while (sourceNodeStack.length) {
- var sourceNode = sourceNodeStack.pop();
- var parentNode = targetNodeStack.pop();
- parentNode.children = sourceNode.children.map(child => new WebInspector.SamplingHeapProfileNode(child));
- sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children);
- targetNodeStack.push.apply(targetNodeStack, parentNode.children);
- }
- return resultRoot;
+ function translateProfileTree(root) {
+ var resultRoot = new WebInspector.SamplingHeapProfileNode(root);
+ var targetNodeStack = [resultRoot];
+ var sourceNodeStack = [root];
+ while (sourceNodeStack.length) {
+ var sourceNode = sourceNodeStack.pop();
+ var parentNode = targetNodeStack.pop();
+ parentNode.children = sourceNode.children.map(child => new WebInspector.SamplingHeapProfileNode(child));
+ sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children);
+ targetNodeStack.push.apply(targetNodeStack, parentNode.children);
+ }
+ return resultRoot;
}
-};
-
-WebInspector.SamplingHeapProfileModel.prototype = {
-
- __proto__: WebInspector.ProfileTreeModel.prototype
+ }
};
/**
- * @constructor
* @implements {WebInspector.ProfileDataGridNode.Formatter}
- * @param {!WebInspector.ProfileView} profileView
+ * @unrestricted
*/
-WebInspector.HeapProfileView.NodeFormatter = function(profileView)
-{
+WebInspector.HeapProfileView.NodeFormatter = class {
+ /**
+ * @param {!WebInspector.ProfileView} profileView
+ */
+ constructor(profileView) {
this._profileView = profileView;
-};
-
-WebInspector.HeapProfileView.NodeFormatter.prototype = {
- /**
- * @override
- * @param {number} value
- * @return {string}
- */
- formatValue: function(value)
- {
- return Number.withThousandsSeparator(value);
- },
-
- /**
- * @override
- * @param {number} value
- * @param {!WebInspector.ProfileDataGridNode} node
- * @return {string}
- */
- formatPercent: function(value, node)
- {
- return WebInspector.UIString("%.2f\u2009%%", value);
- },
-
- /**
- * @override
- * @param {!WebInspector.ProfileDataGridNode} node
- * @return {?Element}
- */
- linkifyNode: function(node)
- {
- return this._profileView.linkifier().maybeLinkifyConsoleCallFrame(this._profileView.target(), node.profileNode.callFrame, "profile-node-file");
- }
+ }
+
+ /**
+ * @override
+ * @param {number} value
+ * @return {string}
+ */
+ formatValue(value) {
+ return Number.withThousandsSeparator(value);
+ }
+
+ /**
+ * @override
+ * @param {number} value
+ * @param {!WebInspector.ProfileDataGridNode} node
+ * @return {string}
+ */
+ formatPercent(value, node) {
+ return WebInspector.UIString('%.2f\u2009%%', value);
+ }
+
+ /**
+ * @override
+ * @param {!WebInspector.ProfileDataGridNode} node
+ * @return {?Element}
+ */
+ linkifyNode(node) {
+ return this._profileView.linkifier().maybeLinkifyConsoleCallFrame(
+ this._profileView.target(), node.profileNode.callFrame, 'profile-node-file');
+ }
};
/**
- * @constructor
- * @extends {WebInspector.ProfileFlameChartDataProvider}
- * @param {!WebInspector.ProfileTreeModel} profile
- * @param {?WebInspector.Target} target
+ * @unrestricted
*/
-WebInspector.HeapFlameChartDataProvider = function(profile, target)
-{
- WebInspector.ProfileFlameChartDataProvider.call(this, target);
+WebInspector.HeapFlameChartDataProvider = class extends WebInspector.ProfileFlameChartDataProvider {
+ /**
+ * @param {!WebInspector.ProfileTreeModel} profile
+ * @param {?WebInspector.Target} target
+ */
+ constructor(profile, target) {
+ super(target);
this._profile = profile;
-};
-
-WebInspector.HeapFlameChartDataProvider.prototype = {
- /**
- * @override
- * @return {number}
- */
- minimumBoundary: function()
- {
- return 0;
- },
-
+ }
+
+ /**
+ * @override
+ * @return {number}
+ */
+ minimumBoundary() {
+ return 0;
+ }
+
+ /**
+ * @override
+ * @return {number}
+ */
+ totalTime() {
+ return this._profile.root.total;
+ }
+
+ /**
+ * @override
+ * @param {number} value
+ * @param {number=} precision
+ * @return {string}
+ */
+ formatValue(value, precision) {
+ return WebInspector.UIString('%s\u2009KB', Number.withThousandsSeparator(value / 1e3));
+ }
+
+ /**
+ * @override
+ * @return {!WebInspector.FlameChart.TimelineData}
+ */
+ _calculateTimelineData() {
/**
- * @override
+ * @param {!WebInspector.ProfileNode} node
* @return {number}
*/
- totalTime: function()
- {
- return this._profile.root.total;
- },
-
- /**
- * @override
- * @param {number} value
- * @param {number=} precision
- * @return {string}
- */
- formatValue: function(value, precision)
- {
- return WebInspector.UIString("%s\u2009KB", Number.withThousandsSeparator(value / 1e3));
- },
+ function nodesCount(node) {
+ return node.children.reduce((count, node) => count + nodesCount(node), 1);
+ }
+ var count = nodesCount(this._profile.root);
+ /** @type {!Array<!WebInspector.ProfileNode>} */
+ var entryNodes = new Array(count);
+ var entryLevels = new Uint16Array(count);
+ var entryTotalTimes = new Float32Array(count);
+ var entryStartTimes = new Float64Array(count);
+ var depth = 0;
+ var maxDepth = 0;
+ var position = 0;
+ var index = 0;
/**
- * @override
- * @return {!WebInspector.FlameChart.TimelineData}
+ * @param {!WebInspector.ProfileNode} node
*/
- _calculateTimelineData: function()
- {
- /**
- * @param {!WebInspector.ProfileNode} node
- * @return {number}
- */
- function nodesCount(node)
- {
- return node.children.reduce((count, node) => count + nodesCount(node), 1);
- }
- var count = nodesCount(this._profile.root);
- /** @type {!Array<!WebInspector.ProfileNode>} */
- var entryNodes = new Array(count);
- var entryLevels = new Uint16Array(count);
- var entryTotalTimes = new Float32Array(count);
- var entryStartTimes = new Float64Array(count);
- var depth = 0;
- var maxDepth = 0;
- var position = 0;
- var index = 0;
-
- /**
- * @param {!WebInspector.ProfileNode} node
- */
- function addNode(node)
- {
- var start = position;
- entryNodes[index] = node;
- entryLevels[index] = depth;
- entryTotalTimes[index] = node.total;
- entryStartTimes[index] = position;
- ++index;
- ++depth;
- node.children.forEach(addNode);
- --depth;
- maxDepth = Math.max(maxDepth, depth);
- position = start + node.total;
- }
- addNode(this._profile.root);
-
- this._maxStackDepth = maxDepth + 1;
- this._entryNodes = entryNodes;
- this._timelineData = new WebInspector.FlameChart.TimelineData(entryLevels, entryTotalTimes, entryStartTimes, null);
-
- return this._timelineData;
- },
-
+ function addNode(node) {
+ var start = position;
+ entryNodes[index] = node;
+ entryLevels[index] = depth;
+ entryTotalTimes[index] = node.total;
+ entryStartTimes[index] = position;
+ ++index;
+ ++depth;
+ node.children.forEach(addNode);
+ --depth;
+ maxDepth = Math.max(maxDepth, depth);
+ position = start + node.total;
+ }
+ addNode(this._profile.root);
+
+ this._maxStackDepth = maxDepth + 1;
+ this._entryNodes = entryNodes;
+ this._timelineData = new WebInspector.FlameChart.TimelineData(entryLevels, entryTotalTimes, entryStartTimes, null);
+
+ return this._timelineData;
+ }
+
+ /**
+ * @override
+ * @param {number} entryIndex
+ * @return {?Element}
+ */
+ prepareHighlightedEntryInfo(entryIndex) {
+ var node = this._entryNodes[entryIndex];
+ if (!node)
+ return null;
+ var entryInfo = [];
/**
- * @override
- * @param {number} entryIndex
- * @return {?Element}
+ * @param {string} title
+ * @param {string} value
*/
- prepareHighlightedEntryInfo: function(entryIndex)
- {
- var node = this._entryNodes[entryIndex];
- if (!node)
- return null;
- var entryInfo = [];
- /**
- * @param {string} title
- * @param {string} value
- */
- function pushEntryInfoRow(title, value)
- {
- entryInfo.push({ title: title, value: value });
- }
- pushEntryInfoRow(WebInspector.UIString("Name"), WebInspector.beautifyFunctionName(node.functionName));
- pushEntryInfoRow(WebInspector.UIString("Self size"), Number.bytesToString(node.self));
- pushEntryInfoRow(WebInspector.UIString("Total size"), Number.bytesToString(node.total));
- var linkifier = new WebInspector.Linkifier();
- var link = linkifier.maybeLinkifyConsoleCallFrame(this._target, node.callFrame);
- if (link)
- pushEntryInfoRow(WebInspector.UIString("URL"), link.textContent);
- linkifier.dispose();
- return WebInspector.ProfileView.buildPopoverTable(entryInfo);
- },
-
- __proto__: WebInspector.ProfileFlameChartDataProvider.prototype
+ function pushEntryInfoRow(title, value) {
+ entryInfo.push({title: title, value: value});
+ }
+ pushEntryInfoRow(WebInspector.UIString('Name'), WebInspector.beautifyFunctionName(node.functionName));
+ pushEntryInfoRow(WebInspector.UIString('Self size'), Number.bytesToString(node.self));
+ pushEntryInfoRow(WebInspector.UIString('Total size'), Number.bytesToString(node.total));
+ var linkifier = new WebInspector.Linkifier();
+ var link = linkifier.maybeLinkifyConsoleCallFrame(this._target, node.callFrame);
+ if (link)
+ pushEntryInfoRow(WebInspector.UIString('URL'), link.textContent);
+ linkifier.dispose();
+ return WebInspector.ProfileView.buildPopoverTable(entryInfo);
+ }
};

Powered by Google App Engine
This is Rietveld 408576698