UNPKG

22.7 kBHTMLView Raw
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4<meta charset="utf-8"/>
5<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
6
7<link rel="stylesheet" href="../assets/css/style.css"/>
8<!-- Copyright 1998-2021 by Northwoods Software Corporation. --> <title> GoJS Collections -- Northwoods Software </title>
9 <link rel="stylesheet" href="../assets/css/prism.css" />
10 </head>
11 <script>
12
13 window.diagrams = [];
14 window.goCode = function(pre, w, h, parentid, animation) {
15 window.diagrams.push([pre, w, h, parentid, animation]);
16 }
17 </script>
18 <body>
19 <nav id="navTop" class="w-full z-30 top-0 text-white bg-nwoods-primary">
20 <div class="w-full container max-w-screen-lg mx-auto flex flex-wrap sm:flex-nowrap items-center justify-between mt-0 py-2">
21 <div class="md:pl-4">
22 <a class="text-white hover:text-white no-underline hover:no-underline
23 font-bold text-2xl lg:text-4xl rounded-lg hover:bg-nwoods-secondary " href="../">
24 <h1 class="mb-0 p-1 ">GoJS</h1>
25 </a>
26 </div>
27 <button id="topnavButton" class="rounded-lg sm:hidden focus:outline-none focus:ring" aria-label="Navigation">
28 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
29 <path id="topnavOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
30 <path id="topnavClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
31 </svg>
32 </button>
33 <div id="topnavList" class="hidden sm:block items-center w-auto mt-0 text-white p-0 z-20">
34 <ul class="list-reset list-none font-semibold flex justify-end flex-wrap sm:flex-nowrap items-center px-0 pb-0">
35 <li class="p-1 sm:p-0"><a class="topnav-link" href="../learn/">Learn</a></li>
36 <li class="p-1 sm:p-0"><a class="topnav-link" href="../samples/">Samples</a></li>
37 <li class="p-1 sm:p-0"><a class="topnav-link" href="../intro/">Intro</a></li>
38 <li class="p-1 sm:p-0"><a class="topnav-link" href="../api/">API</a></li>
39 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/products/register.html">Register</a></li>
40 <li class="p-1 sm:p-0"><a class="topnav-link" href="../download.html">Download</a></li>
41 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://forum.nwoods.com/c/gojs/11">Forum</a></li>
42 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/contact.html"
43 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a></li>
44 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/sales/index.html"
45 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a></li>
46 </ul>
47 </div>
48 </div>
49 <hr class="border-b border-gray-600 opacity-50 my-0 py-0" />
50 </nav>
51
52 <div class="md:flex flex-col md:flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
53
54 <div id="navSide" class="flex flex-col w-full md:w-40 lg:w-48 text-gray-700 bg-white flex-shrink-0">
55 <div class="flex-shrink-0 px-8 py-4">
56 <button id="navButton" class="rounded-lg md:hidden focus:outline-none focus:ring" aria-label="Navigation">
57 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
58 <path id="navOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
59 <path id="navClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
60 </svg>
61 </button>
62 </div>
63 <nav id="navList" class="min-h-screen hidden md:block sidebar-nav flex-grow px-1 lg:px-4 pb-4 md:pb-0 md:overflow-y-auto break-words">
64 <a href="index.html">Basics</a>
65 <a href="buildingObjects.html">Building Parts</a>
66 <a href="usingModels.html">Using Models</a>
67 <a href="dataBinding.html">Data Binding</a>
68 <a href="react.html">GoJS with React</a>
69 <a href="angular.html">GoJS with Angular</a>
70 <a href="textBlocks.html">TextBlocks</a>
71 <a href="shapes.html">Shapes</a>
72 <a href="pictures.html">Pictures</a>
73 <a href="panels.html">Panels</a>
74 <a href="tablePanels.html">Table Panels</a>
75 <a href="brush.html">Brushes</a>
76 <a href="sizing.html">Sizing Objects</a>
77 <a href="itemArrays.html">Item Arrays</a>
78 <a href="changedEvents.html">Changed Events</a>
79 <a href="transactions.html">Transactions</a>
80 <a href="viewport.html">Coordinates</a>
81 <a href="initialView.html">Initial View</a>
82 <a href="collections.html">Collections</a>
83 <a href="links.html">Links</a>
84 <a href="linkLabels.html">Link Labels</a>
85 <a href="connectionPoints.html">Link Points</a>
86 <a href="ports.html">Ports</a>
87 <a href="nodes.html">Nodes</a>
88 <a href="debugging.html">Debugging</a>
89 <a href="layouts.html">Layouts</a>
90 <a href="trees.html">Trees</a>
91 <a href="subtrees.html">SubTrees</a>
92 <a href="groups.html">Groups</a>
93 <a href="subgraphs.html">SubGraphs</a>
94 <a href="sizedGroups.html">Sized Groups</a>
95 <a href="selection.html">Selection</a>
96 <a href="highlighting.html">Highlighting</a>
97 <a href="animation.html">Animation</a>
98 <a href="toolTips.html">ToolTips</a>
99 <a href="contextmenus.html">Context Menus</a>
100 <a href="events.html">Diagram Events</a>
101 <a href="tools.html">Tools</a>
102 <a href="commands.html">Commands</a>
103 <a href="permissions.html">Permissions</a>
104 <a href="validation.html">Validation</a>
105 <a href="HTMLInteraction.html">HTML Interaction</a>
106 <a href="layers.html">Layers &amp; Z-ordering</a>
107 <a href="palette.html">Palette</a>
108 <a href="overview.html">Overview</a>
109 <a href="resizing.html">Resizing Diagrams</a>
110 <a href="replacingDeleting.html">Replacing and Deleting</a>
111 <a href="buttons.html">Buttons</a>
112 <a href="templateMaps.html">Template Maps</a>
113 <a href="legends.html">Legends and Titles</a>
114 <a href="extensions.html">Extensions</a>
115 <a href="geometry.html">Geometry Strings</a>
116 <a href="grids.html">Grid Patterns</a>
117 <a href="graduatedPanels.html">Graduated Panels</a>
118 <a href="makingImages.html">Diagram Images</a>
119 <a href="makingSVG.html">Diagram SVG</a>
120 <a href="printing.html">Printing</a>
121 <a href="serverSideImages.html">Server-side Images</a>
122 <a href="nodeScript.html">GoJS in Node.js</a>
123 <a href="testing.html">Testing</a>
124 <a href="storage.html">Storage</a>
125 <a href="performance.html">Performance</a>
126 <a href="source.html">Building from Source</a>
127 <a href="platforms.html">Platforms</a>
128 <a href="deployment.html">Deployment</a>
129 </nav>
130 </div>
131 <div class="pt-4 px-2 md:px-0 lg:px-4 pb-16 w-full overflow-hidden">
132
133
134
135
136<h1>Collections</h1>
137<p>
138<b>GoJS</b> provides its own collection classes: <a>List</a>, <a>Set</a>, and <a>Map</a>.
139You can iterate over a collection by using an <a>Iterator</a>.
140</p>
141<p>
142These collection classes have several advantages over using JavaScript arrays as lists or objects as maps.
143They raise an error when trying to get the next item of an iterator if the collection has been modified since getting the iterator.
144They can be made read-only to avoid unexpected modifications.
145They offer methods not found on simple arrays or objects, such as <a>Iterator.any</a>, <a>Iterator.all</a>, and <a>Iterator.each</a>.
146If you are writing in TypeScript, they optionally enforce compile-time type checking of the item types.
147</p>
148<p>
149In <b>GoJS</b> most of the properties and methods that return collections describing the structure of the diagram return an <a>Iterator</a>.
150That is because the implementation of the collections are internal -- you only need to know how to iterate over the result collection.
151Other methods or properties will allow you to modify the diagram.
152An example is <a>Diagram.nodes</a>, which returns the current collection of <a>Node</a>s and <a>Group</a>s in the diagram as an <a>Iterator</a>.
153The collection is automatically modified as the programmer adds or removes node data in the model or by direct calls to
154<a>Diagram.add</a> or <a>Diagram.remove</a>.
155</p>
156<p>
157However there are a few properties that return collections that are allowed to be modified.
158Examples include collections on classes that are usually frozen after initialization:
159<a>Geometry.figures</a>, <a>PathFigure.segments</a>, and <a>Brush.colorStops</a>.
160Other examples include collections that are modified very infrequently, usually only upon diagram initialization:
161<a>ToolManager.mouseDownTools</a> (and the other lists of tools) and <a>Diagram.nodeTemplateMap</a>
162(and other template maps).
163</p>
164<p>
165See samples that make use of collections in the <a href="../samples/index.html#collections">samples index</a>.
166</p>
167<h2 id="List">List</h2>
168<p>
169A <a>List</a> is an ordered collection of values that are indexed by integers from zero to one less than the count.
170</p>
171
172<pre class="lang-js"><code>
173 var l = new go.List();
174 l.add("A");
175 l.add("B");
176 l.add("C");
177
178 assert(l.count === 3);
179 assert(l.elt(0) === "A");
180 assert(l.has("B"));
181 assert(l.indexOf("B") === 1);
182
183 l.setElt(1, "z"); // replace an item
184 assert(l.elt(1) === "z");
185
186 l.removeAt(1); // remove an item
187 assert(l.count === 2);
188 assert(l.elt(1) === "C");
189</code></pre>
190<p>
191 In 2.0, the optional argument to the <a>List</a> constructor has been removed.
192 However, if you are writing in TypeScript, GoJS collections classes (<code>List</code>, <code>Map</code>, <code>Set</code>) are now generic, and will help you enforce types:
193</p>
194
195
196<pre class="lang-ts"><code>
197 // TypeScript:
198 var l = new go.List&lt;string&gt;(); // Create a list of only strings
199 l.add("A");
200 l.add(23); // throws an error during compilation or in an IDE
201 l.add({}); // throws an error during compilation or in an IDE
202</code></pre>
203
204
205
206<p>
207To iterate over a <a>List</a>, get its <a>List.iterator</a> and call <a>Iterator.next</a>
208on it to advance its position in the list. Its <a>Iterator.value</a> will be a list item;
209its <a>Iterator.key</a> will be the corresponding index in the list.
210</p>
211<pre class="lang-js"><code>
212 var l = new go.List();
213 l.add("A");
214 l.add("B");
215 l.add("C");
216
217 var it = l.iterator;
218 while (it.next()) {
219 console.log(it.key + ": " + it.value);
220 }
221 // This outputs:
222 // 0: A
223 // 1: B
224 // 2: C
225</code></pre>
226
227<h2 id="Set">Set</h2>
228<p>
229A <a>Set</a> is an unordered collection of values that does not allow duplicate values.
230This class is similar to the <code>Set</code> object that is defined in ECMAScript 2015 (ES6).
231</p>
232<p>
233The optional argument to the <a>Set</a> constructor specifies the type of the items that may be added to the set.
234</p>
235<pre class="lang-js"><code>
236 var s = new go.Set();
237 s.add("A");
238 s.add("B");
239 s.add("C");
240 s.add("B"); // duplicate is ignored
241
242 assert(s.count === 3);
243 assert(s.has("B"));
244
245 s.remove("B"); // remove an item
246 assert(s.count === 2);
247 assert(!s.has("B"));
248</code></pre>
249
250<p>
251 As with <code>List</code> and <code>Map</code>, in 2.0 the optional argument to the <a>Set</a> constructor has been removed, but it is now a generic class in TypeScript and can enforce types:
252</p>
253
254<pre class="lang-ts"><code>
255 // TypeScript:
256 var s = new go.Set&lt;string&gt;(); // Create a set of only strings
257 s.add("A");
258 s.add(23); // throws an error during compilation or in an IDE
259 s.add({}); // throws an error during compilation or in an IDE
260</code></pre>
261
262
263<p>
264Iterating over the items in a <a>Set</a> is just like iterating over a <a>List</a>,
265except that the order of the items may vary.
266</p>
267<pre class="lang-js"><code>
268 var s = new go.Set();
269 s.add("A");
270 s.add("B");
271 s.add("C");
272 s.add("B"); // duplicate is ignored
273
274 var it = s.iterator;
275 while (it.next()) {
276 console.log(it.value);
277 }
278 // This might output, perhaps in different order:
279 // A
280 // B
281 // C
282</code></pre>
283
284<h2 id="Map">Map</h2>
285<p>
286A <a>Map</a> is an unordered collection of key-value pairs that are indexed by the keys.
287This class is similar to the <code>Map</code> object that is defined in ECMAScript 2015 (ES6).
288</p>
289<p>
290The two optional arguments to the <a>Map</a> constructor specifies the types of the keys and the types of the item values that may be added to the map.
291</p>
292<pre class="lang-js"><code>
293 var m = new go.Map();
294 m.add("A", 1); // associate "A" with 1
295 m.add("B", 2);
296 m.add("C", 3);
297
298 assert(s.count === 3);
299 assert(s.has("B"));
300 assert(s.get("B") === 2);
301
302 m.add("B", 222); // replace the value for "B"
303 assert(s.get("B") === 222);
304
305 s.remove("B"); // remove an item
306 assert(s.count === 2);
307 assert(!s.has("B"));
308 assert(s.get("B") === null);
309</code></pre>
310
311<p>
312 As with <code>List</code> and <code>Set</code>, in 2.0 the optional arguments to the <a>Map</a> constructor have been removed, but it is now a generic class in TypeScript and can enforce types:
313</p>
314
315<pre class="lang-ts"><code>
316 // TypeScript:
317 var m = new go.Map&lt;string, number&gt;(); // Create a map of strings to numbers
318 m.add("A", 1);
319 m.add(23, 23); // throws an error during compilation or in an IDE
320 m.add({}, 23); // throws an error during compilation or in an IDE
321</code></pre>
322
323<p>
324Iterating over the items in a <a>Map</a> is just like iterating over a <a>List</a>,
325but offering access to both the keys and the values.
326As with <a>Set</a>s the order of the items may vary.
327</p>
328<pre class="lang-js"><code>
329 var m = new go.Map();
330 m.add("A", 1); // associate "A" with 1
331 m.add("B", 2);
332 m.add("C", 3);
333 m.add("B", 222); // replace the value for "B"
334
335 // Normal iteration lets you get both the key and its corresponding value:
336 var it = m.iterator;
337 while (it.next()) {
338 console.log(it.key + ": " + it.value);
339 }
340 // This might output, perhaps in different order:
341 // A: 1
342 // B: 222
343 // C: 3
344
345 // To get a collection of the keys, use Map.iteratorKeys:
346 var kit = m.iteratorKeys;
347 while (kit.next()) {
348 console.log(kit.value);
349 }
350 // This might output, perhaps in different order:
351 // A
352 // B
353 // C
354
355 // To get a collection of the values, use Map.iteratorValues:
356 var vit = m.iteratorValues;
357 while (vit.next()) {
358 console.log(vit.value);
359 }
360 // This might output, perhaps in different order:
361 // 1
362 // 222
363 // 3
364</code></pre>
365<p>
366Typically one uses <a>Map.iteratorKeys</a> or <a>Map.iteratorValues</a>
367when needing to pass a collection on to other methods that take an <a>Iterator</a>.
368</p>
369
370<h2 id="MoreIterationExamples">More Iteration Examples</h2>
371
372<p>
373It is commonplace to iterate over the selected <a>Part</a>s of a <a>Diagram</a>:
374<pre class="lang-js"><code>
375 for (var it = diagram.selection.iterator; it.next(); ) {
376 var part = it.value; // part is now a Node or a Group or a Link or maybe a simple Part
377 if (part instanceof go.Node) { . . . }
378 else if (part instanceof go.Link) { . . . }
379 }
380</code></pre>
381Alternatively:
382<pre class="lang-js"><code>
383 diagram.selection.each(function(part) {
384 // part is now a Node or a Group or a Link or maybe a simple Part
385 if (part instanceof go.Node) { . . . }
386 else if (part instanceof go.Link) { . . . }
387 });
388</code></pre>
389</p>
390
391<p>
392Sometimes one needs to iterate over the <a>Node</a>s in a <a>Diagram</a>:
393<pre class="lang-js"><code>
394 for (var it = diagram.nodes; it.next(); ) {
395 var n = it.value; // n is now a Node or a Group
396 if (n.category === "Special") { . . . }
397 }
398</code></pre>
399</p>
400
401<p>
402You can also iterate over the port elements in a <a>Node</a>, or the <a>Link</a>s connected to a port element:
403<pre class="lang-js"><code>
404 for (var pit = node.ports; pit.next(); ) {
405 var port = pit.value; // port is now a GraphObject within the node
406 for (var lit = node.findLinksConnected(port.portId); lit.next(); ) {
407 var link = lit.value; // link is now a Link connected with the port
408 if (link.data.xyz === 17) { . . . }
409 }
410 }
411</code></pre>
412</p>
413
414<p>
415Or perhaps you need to iterate over the elements of a <a>Panel</a>:
416<pre class="lang-js"><code>
417 for (var it = panel.elements; it.next(); ) {
418 var elt = it.value; // elt is now a GraphObject that is an immediate child of the Panel
419 if (elt instanceof go.TextBlock) { . . . }
420 else if (elt instanceof go.Panel) { . . . recurse . . . }
421 }
422</code></pre>
423</p>
424
425<p>
426If you want to find <a>Node</a>s that are immediate members of a <a>Group</a>:
427<pre class="lang-js"><code>
428 for (var mit = group.memberParts; mit.next(); ) {
429 var part = mit.value; // part is now a Part within the Group
430 if (part instanceof go.Node) { . . . maybe work with part.data . . . }
431 }
432</code></pre>
433</p>
434
435
436 </div>
437 </div>
438
439 <div class="bg-nwoods-primary">
440 <section class="max-w-screen-lg text-white container mx-auto py-2 px-12">
441 <p id="version" class="leading-none mb-2 my-4">GoJS</p>
442 </section>
443 </div><footer class="bg-nwoods-primary text-white">
444 <div class="container max-w-screen-lg mx-auto px-8">
445 <div class="w-full py-6">
446
447 <div class="max-w-screen-lg xl:max-w-screen-xl mx-auto px-4 sm:px-6 md:px-8">
448 <ul class="text-sm font-medium pb-14 sm:pb-20 grid grid-cols-1 sm:grid-cols-3 gap-y-10">
449 <li class="list-none row-span-2">
450 <h2 class="text-base font-semibold tracking-wide">GoJS</h2>
451 <ul class="list-none space-y-4 md:space-y-1 px-0">
452 <li>
453 <a href="../samples/index.html">Samples</a>
454 </li>
455 <li>
456 <a href="../learn/index.html">Learn</a>
457 </li>
458 <li>
459 <a href="../intro/index.html">Intro</a>
460 </li>
461 <li>
462 <a href="../api/index.html">API</a>
463 </li>
464 <li>
465 <a href="../changelog.html">Changelog</a>
466 </li>
467 <li>
468 <a href="https://github.com/NorthwoodsSoftware/GoJS">GitHub</a>
469 </li>
470 </ul>
471 </li>
472 <li class="list-none row-span-2">
473 <h2 class="text-base font-semibold tracking-wide">Support</h2>
474 <ul class="list-none space-y-4 md:space-y-1 px-0">
475 <li>
476 <a href="https://www.nwoods.com/contact.html"
477 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a>
478 </li>
479 <li>
480 <a href="https://forum.nwoods.com/c/gojs">Forum</a>
481 </li>
482 <li>
483 <a href="https://www.nwoods.com/app/activate.aspx?sku=gojs">Activate</a>
484 </li>
485 <li>
486 <a href="https://www.nwoods.com/sales/index.html"
487 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a>
488 </li>
489 <li>
490 <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">Videos</a>
491 </li>
492 </ul>
493 </li>
494 <li class="list-none row-span-2">
495 <h2 class="text-base font-semibold tracking-wide">Company</h2>
496 <ul class="list-none space-y-4 md:space-y-1 px-0">
497 <li>
498 <a href="https://www.nwoods.com">Northwoods</a>
499 </li>
500 <li>
501 <a href="https://www.nwoods.com/about.html">About Us</a>
502 </li>
503 <li>
504 <a href="https://www.nwoods.com/contact.html">Contact Us</a>
505 </li>
506 <li>
507 <a href="https://twitter.com/northwoodsgo">Twitter</a>
508 </li>
509
510 </ul>
511 </li>
512 </ul>
513
514
515 <p class="text-sm text-gray-100 md:mb-6">
516 Copyright 1998-2021 <a class="text-white" href="https://www.nwoods.com">Northwoods Software</a>
517 </p>
518 </div>
519 </div>
520</footer> </body>
521
522<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-5"></script>
523<script>
524 window.dataLayer = window.dataLayer || [];
525 function gtag(){dataLayer.push(arguments);}
526 gtag('js', new Date()); gtag('config', 'UA-1506307-5');
527 var getOutboundLink = function(url, label) {
528 gtag('event', 'click', {
529 'event_category': 'outbound',
530 'event_label': label,
531 'transport_type': 'beacon'
532 });
533 }
534
535 // topnav
536 var topButton = document.getElementById("topnavButton");
537 var topnavList = document.getElementById("topnavList");
538 topButton.addEventListener("click", function() {
539 this.classList.toggle("active");
540 topnavList.classList.toggle("hidden");
541 document.getElementById("topnavOpen").classList.toggle("hidden");
542 document.getElementById("topnavClosed").classList.toggle("hidden");
543 });
544</script>
545 <script src="../assets/js/prism.js"></script>
546 <script src="../release/go.js"></script>
547 <script src="../assets/js/goDoc.js"></script>
548 <script>
549 document.addEventListener("DOMContentLoaded", function() {
550 if (window.go) document.getElementById('version').textContent = "GoJS version " + go.version;
551 if (window.goDoc) window.goDoc();
552 var d = window.diagrams;
553 for (var i = 0; i < d.length; i++) {
554 var dargs = d[i];
555 goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
556 }
557 if (window.extra) window.extra();
558 });
559 </script>
560</html>