From e1a6d79744b37275d92afa7e2cd1ac021b0aba76 Mon Sep 17 00:00:00 2001 From: jacksona Date: Thu, 18 Jul 2019 15:44:36 -0700 Subject: [PATCH 1/7] add hacking info to README --- minigui/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/minigui/README.md b/minigui/README.md index 1bc9cd544..2d8c2d26b 100644 --- a/minigui/README.md +++ b/minigui/README.md @@ -310,3 +310,16 @@ stdout: = D4 - *fails*: If the id doesn't correspond to a position played in the game or one of its variations. - *comments*: Required only for Minigui's study mode. + + +### Hacking + + +e.g. in study.ts, change the last line to something like + +``` +(window as any)['app'] = new ExploreApp(); +``` + +This will put the application in a global variable named "app"; you need to cast +the window object to the "any" type to silence the TS compiler. From 659c203518f81f8d2ba4645aa543d4c78e9a14a9 Mon Sep 17 00:00:00 2001 From: jacksona Date: Thu, 18 Jul 2019 15:48:01 -0700 Subject: [PATCH 2/7] Remove annotation enum, make annotation layer draw annotations as alabels. Position::addChild() will now add annotations to non-mainline children. --- minigui/layer.ts | 48 +++++++++++++++++++++++++------------- minigui/position.ts | 33 +++++++++++++++++++------- minigui/static/layer.js | 45 ++++++++++++++++++++++------------- minigui/static/position.js | 31 +++++++++++++++++------- 4 files changed, 107 insertions(+), 50 deletions(-) diff --git a/minigui/layer.ts b/minigui/layer.ts index f1503ac1a..6bd019751 100644 --- a/minigui/layer.ts +++ b/minigui/layer.ts @@ -458,7 +458,20 @@ namespace Variation { class Annotations extends Layer { - private annotations = new Map(); + private annotations = new Map(); + private _showDivergence = false; + + get showDivergence() : boolean { + return this._showDivergence; + } + set showDivergence(x: boolean) { + if (x == this._showDivergence) { + return; + } + this._showDivergence = x; + this.update(new Set(["annotations"])); + this.board.draw(); + } clear() { if (this.annotations.size > 0) { @@ -475,10 +488,12 @@ class Annotations extends Layer { let position = this.board.position; this.annotations.clear(); for (let annotation of position.annotations) { - let byShape = this.annotations.get(annotation.shape); + // this isn't really working with the enums, but its not clear how the + // annotations on a position should be grouped, otherwise. + let byShape = this.annotations.get(annotation.label); if (byShape === undefined) { byShape = []; - this.annotations.set(annotation.shape, byShape); + this.annotations.set(annotation.label, byShape); } byShape.push(annotation); } @@ -491,21 +506,22 @@ class Annotations extends Layer { } let sr = this.board.stoneRadius; - let pr = pixelRatio(); let ctx = this.board.ctx; - ctx.lineCap = 'round'; - this.annotations.forEach((annotations: Annotation[], shape: Annotation.Shape) => { - switch (shape) { - case Annotation.Shape.Dot: - for (let annotation of annotations) { - let c = this.boardToCanvas(annotation.p.row, annotation.p.col); - ctx.fillStyle = annotation.colors[0]; - ctx.beginPath(); - ctx.arc(c.x + 0.5, c.y + 0.5, 0.16 * sr, 0, 2 * Math.PI); - ctx.fill(); - } - break; + let textHeight = Math.floor(0.8 * sr); + ctx.font = `${textHeight}px sans-serif`; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + this.annotations.forEach((annotations: Annotation[], label: string) => { + for (let annotation of annotations) { + ctx.fillStyle = annotation.colors[0]; + let c = this.boardToCanvas(annotation.p.row, annotation.p.col); + if (label == "●"){ + ctx.fillText(label, c.x, c.y); + } + else if (this.showDivergence) { + ctx.fillText(label, c.x, c.y); + } } }); } diff --git a/minigui/position.ts b/minigui/position.ts index 3ec5bc06a..d857f1376 100644 --- a/minigui/position.ts +++ b/minigui/position.ts @@ -15,15 +15,9 @@ import {Color, Move, N, Nullable, Point, moveIsPoint, movesEqual, otherColor, stonesEqual, toGtp} from './base' import * as util from './util' -namespace Annotation { - export enum Shape { - Dot, - } -} - interface Annotation { p: Point; - shape: Annotation.Shape; + label: string; colors: string[]; } @@ -100,10 +94,10 @@ class Position { if (moveIsPoint(this.lastMove)) { this.annotations.push({ p: this.lastMove, - shape: Annotation.Shape.Dot, + label: "●", colors: ['#ef6c02'], }); - } + } } addChild(p: Position) { @@ -125,6 +119,27 @@ class Position { // Create a new child. p.isMainLine = this.isMainLine && this.children.length == 0; p.parent = this; + + // If it is not on the main line, prepare the move number annotations. + if (! p.isMainLine) { + let result: Move[] = []; + let node: Nullable + for (node = p; node && node.isMainLine != true; node = node.parent) { + if (node.lastMove == null) { break; } + result.push(node.lastMove); + } + result.reverse(); + for (let i=0; i < result.length -1; ++i) { + let thing = result[i]; + if (moveIsPoint(thing)) { + p.annotations.push({ + p: thing, // 'p' here for 'point'. + label: (i+1).toString(), + colors: ['#999999'], + }); + } + } + } this.children.push(p); } diff --git a/minigui/static/layer.js b/minigui/static/layer.js index ebbd76b6c..89a345b15 100644 --- a/minigui/static/layer.js +++ b/minigui/static/layer.js @@ -1,4 +1,4 @@ -define(["require", "exports", "./position", "./base", "./util"], function (require, exports, position_1, base_1, util_1) { +define(["require", "exports", "./base", "./util"], function (require, exports, base_1, util_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const STAR_POINTS = { @@ -383,6 +383,18 @@ define(["require", "exports", "./position", "./base", "./util"], function (requi constructor() { super(...arguments); this.annotations = new Map(); + this._showDivergence = false; + } + get showDivergence() { + return this._showDivergence; + } + set showDivergence(x) { + if (x == this._showDivergence) { + return; + } + this._showDivergence = x; + this.update(new Set(["annotations"])); + this.board.draw(); } clear() { if (this.annotations.size > 0) { @@ -397,10 +409,10 @@ define(["require", "exports", "./position", "./base", "./util"], function (requi let position = this.board.position; this.annotations.clear(); for (let annotation of position.annotations) { - let byShape = this.annotations.get(annotation.shape); + let byShape = this.annotations.get(annotation.label); if (byShape === undefined) { byShape = []; - this.annotations.set(annotation.shape, byShape); + this.annotations.set(annotation.label, byShape); } byShape.push(annotation); } @@ -411,20 +423,21 @@ define(["require", "exports", "./position", "./base", "./util"], function (requi return; } let sr = this.board.stoneRadius; - let pr = util_1.pixelRatio(); let ctx = this.board.ctx; - ctx.lineCap = 'round'; - this.annotations.forEach((annotations, shape) => { - switch (shape) { - case position_1.Annotation.Shape.Dot: - for (let annotation of annotations) { - let c = this.boardToCanvas(annotation.p.row, annotation.p.col); - ctx.fillStyle = annotation.colors[0]; - ctx.beginPath(); - ctx.arc(c.x + 0.5, c.y + 0.5, 0.16 * sr, 0, 2 * Math.PI); - ctx.fill(); - } - break; + let textHeight = Math.floor(0.8 * sr); + ctx.font = `${textHeight}px sans-serif`; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + this.annotations.forEach((annotations, label) => { + for (let annotation of annotations) { + ctx.fillStyle = annotation.colors[0]; + let c = this.boardToCanvas(annotation.p.row, annotation.p.col); + if (label == "●") { + ctx.fillText(label, c.x, c.y); + } + else if (this.showDivergence) { + ctx.fillText(label, c.x, c.y); + } } }); } diff --git a/minigui/static/position.js b/minigui/static/position.js index 0ab9fa1fc..fc7499c17 100644 --- a/minigui/static/position.js +++ b/minigui/static/position.js @@ -1,14 +1,6 @@ define(["require", "exports", "./base", "./util"], function (require, exports, base_1, util) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); - var Annotation; - (function (Annotation) { - let Shape; - (function (Shape) { - Shape[Shape["Dot"] = 0] = "Dot"; - })(Shape = Annotation.Shape || (Annotation.Shape = {})); - })(Annotation || (Annotation = {})); - exports.Annotation = Annotation; class Position { constructor(j) { this.parent = null; @@ -62,7 +54,7 @@ define(["require", "exports", "./base", "./util"], function (require, exports, b if (base_1.moveIsPoint(this.lastMove)) { this.annotations.push({ p: this.lastMove, - shape: Annotation.Shape.Dot, + label: "●", colors: ['#ef6c02'], }); } @@ -81,6 +73,27 @@ define(["require", "exports", "./base", "./util"], function (require, exports, b } p.isMainLine = this.isMainLine && this.children.length == 0; p.parent = this; + if (!p.isMainLine) { + let result = []; + let node; + for (node = p; node && node.isMainLine != true; node = node.parent) { + if (node.lastMove == null) { + break; + } + result.push(node.lastMove); + } + result.reverse(); + for (let i = 0; i < result.length - 1; ++i) { + let thing = result[i]; + if (base_1.moveIsPoint(thing)) { + p.annotations.push({ + p: thing, + label: (i + 1).toString(), + colors: ['#999999'], + }); + } + } + } this.children.push(p); } getChild(move) { From 0f5d5063492f73e9a37b80b38eb2544846f9d6d1 Mon Sep 17 00:00:00 2001 From: jacksona Date: Thu, 18 Jul 2019 15:48:21 -0700 Subject: [PATCH 3/7] add show-divergence handlers to study mode --- minigui/static/study.js | 10 +++++++++- minigui/study.ts | 14 +++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/minigui/static/study.js b/minigui/static/study.js index 59ba3a78e..1bd5b9db3 100644 --- a/minigui/static/study.js +++ b/minigui/static/study.js @@ -7,11 +7,12 @@ define(["require", "exports", "./app", "./base", "./board", "./layer", "./log", this.gtp = gtp; this._highlightedNextMove = null; this.searchLyr = new lyr.Search(); + this.annoLyr = new lyr.Annotations(); this.addLayers([ new lyr.Label(), new lyr.BoardStones(), this.searchLyr, - new lyr.Annotations() + this.annoLyr ]); this.enabled = true; } @@ -82,6 +83,7 @@ define(["require", "exports", "./app", "./base", "./board", "./layer", "./log", this.variationTree = new variation_tree_1.VariationTree('tree'); this.log = new log_1.Log('log', 'console'); this.showSearch = true; + this.showDiverge = false; this.showConsole = false; this.moveElem = util_1.getElement('move'); this.commentElem = util_1.getElement('comment'); @@ -184,6 +186,9 @@ define(["require", "exports", "./app", "./base", "./board", "./layer", "./log", case 'End': this.goForward(Infinity); break; + case 'v': + this.toggleNumberVariations(); + break; } }); window.addEventListener('wheel', (e) => { @@ -361,6 +366,9 @@ define(["require", "exports", "./app", "./base", "./board", "./layer", "./log", this.searchElem.innerText = 'Show search'; } } + toggleNumberVariations() { + this.board.annoLyr.showDivergence = !this.board.annoLyr.showDivergence; + } uploadTmpFile(contents) { return fetch('write_tmp_file', { method: 'POST', diff --git a/minigui/study.ts b/minigui/study.ts index fc8d9d430..01fb6e08d 100644 --- a/minigui/study.ts +++ b/minigui/study.ts @@ -47,16 +47,20 @@ class ExploreBoard extends ClickableBoard { } private searchLyr: lyr.Search; + public annoLyr: lyr.Annotations; + constructor(parentElemId: string, position: Position, private gtp: Socket) { super(parentElemId, position, []); this.searchLyr = new lyr.Search(); + this.annoLyr = new lyr.Annotations(); + this.addLayers([ new lyr.Label(), new lyr.BoardStones(), this.searchLyr, - new lyr.Annotations()]); + this.annoLyr]); this.enabled = true; } @@ -118,6 +122,7 @@ class ExploreApp extends App { private variationTree = new VariationTree('tree'); private log = new Log('log', 'console'); private showSearch = true; + private showDiverge = false; private showConsole = false; private moveElem = getElement('move'); private commentElem = getElement('comment'); @@ -246,6 +251,9 @@ class ExploreApp extends App { case 'End': this.goForward(Infinity); break; + case 'v': + this.toggleNumberVariations(); + break; } }); @@ -458,6 +466,10 @@ class ExploreApp extends App { } } + private toggleNumberVariations() { + this.board.annoLyr.showDivergence = !this.board.annoLyr.showDivergence; + } + private uploadTmpFile(contents: string) { return fetch('write_tmp_file', { method: 'POST', From a41efa056724b811af1507f602677612b85ff087 Mon Sep 17 00:00:00 2001 From: jacksona Date: Thu, 18 Jul 2019 15:49:53 -0700 Subject: [PATCH 4/7] fix type error caught by ts; null not a valid value to assign. --- minigui/board.ts | 2 +- minigui/static/board.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/minigui/board.ts b/minigui/board.ts index bc171b4cc..1213be850 100644 --- a/minigui/board.ts +++ b/minigui/board.ts @@ -284,7 +284,7 @@ class ClickableBoard extends Board { drawImpl() { super.drawImpl(); let p = this.enabled ? this.p : null; - this.ctx.canvas.style.cursor = p ? 'pointer' : null; + this.ctx.canvas.style.cursor = p ? 'pointer' : 'none'; if (p) { this.drawStones([p], this.position.toPlay, 0.6); } diff --git a/minigui/static/board.js b/minigui/static/board.js index 1ae7b0696..cd88b6819 100644 --- a/minigui/static/board.js +++ b/minigui/static/board.js @@ -214,7 +214,7 @@ define(["require", "exports", "./base", "./layer", "./util", "./view"], function drawImpl() { super.drawImpl(); let p = this.enabled ? this.p : null; - this.ctx.canvas.style.cursor = p ? 'pointer' : null; + this.ctx.canvas.style.cursor = p ? 'pointer' : 'none'; if (p) { this.drawStones([p], this.position.toPlay, 0.6); } From 96f8cebce8cc7c7719c8403e5aa4fc296ce7a4e4 Mon Sep 17 00:00:00 2001 From: jacksona Date: Tue, 23 Jul 2019 12:14:14 -0700 Subject: [PATCH 5/7] add duplicate annotation checking to position.ts --- minigui/layer.ts | 2 ++ minigui/position.ts | 13 ++++++++++--- minigui/static/position.js | 12 +++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/minigui/layer.ts b/minigui/layer.ts index 6bd019751..abf890c18 100644 --- a/minigui/layer.ts +++ b/minigui/layer.ts @@ -512,6 +512,8 @@ class Annotations extends Layer { ctx.font = `${textHeight}px sans-serif`; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; + + // TODO this.annotation should be keyed by the board position, oops. this.annotations.forEach((annotations: Annotation[], label: string) => { for (let annotation of annotations) { ctx.fillStyle = annotation.colors[0]; diff --git a/minigui/position.ts b/minigui/position.ts index d857f1376..0b09941d6 100644 --- a/minigui/position.ts +++ b/minigui/position.ts @@ -129,11 +129,18 @@ class Position { result.push(node.lastMove); } result.reverse(); + let playedCount = new Uint16Array(N * N); for (let i=0; i < result.length -1; ++i) { - let thing = result[i]; - if (moveIsPoint(thing)) { + let move = result[i]; + + if (moveIsPoint(move)) { + let idx = move.row * N + move.col; + let count = ++playedCount[idx]; + if (count != 1) { + continue; + } p.annotations.push({ - p: thing, // 'p' here for 'point'. + p: move, // 'p' here for 'point'. label: (i+1).toString(), colors: ['#999999'], }); diff --git a/minigui/static/position.js b/minigui/static/position.js index fc7499c17..370d8acd3 100644 --- a/minigui/static/position.js +++ b/minigui/static/position.js @@ -83,11 +83,17 @@ define(["require", "exports", "./base", "./util"], function (require, exports, b result.push(node.lastMove); } result.reverse(); + let playedCount = new Uint16Array(base_1.N * base_1.N); for (let i = 0; i < result.length - 1; ++i) { - let thing = result[i]; - if (base_1.moveIsPoint(thing)) { + let move = result[i]; + if (base_1.moveIsPoint(move)) { + let idx = move.row * base_1.N + move.col; + let count = ++playedCount[idx]; + if (count != 1) { + continue; + } p.annotations.push({ - p: thing, + p: move, label: (i + 1).toString(), colors: ['#999999'], }); From ea0bf317da46e1c771b02ff25b0136d3373bb6c1 Mon Sep 17 00:00:00 2001 From: jacksona Date: Tue, 23 Jul 2019 15:44:07 -0700 Subject: [PATCH 6/7] fix null property for pointer style, nits --- minigui/board.ts | 2 +- minigui/position.ts | 4 ++-- minigui/static/board.js | 2 +- minigui/static/position.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/minigui/board.ts b/minigui/board.ts index 1213be850..fdf7e8c38 100644 --- a/minigui/board.ts +++ b/minigui/board.ts @@ -284,7 +284,7 @@ class ClickableBoard extends Board { drawImpl() { super.drawImpl(); let p = this.enabled ? this.p : null; - this.ctx.canvas.style.cursor = p ? 'pointer' : 'none'; + this.ctx.canvas.style.cursor = p ? 'pointer' : ''; if (p) { this.drawStones([p], this.position.toPlay, 0.6); } diff --git a/minigui/position.ts b/minigui/position.ts index 0b09941d6..7af83dbb6 100644 --- a/minigui/position.ts +++ b/minigui/position.ts @@ -124,13 +124,13 @@ class Position { if (! p.isMainLine) { let result: Move[] = []; let node: Nullable - for (node = p; node && node.isMainLine != true; node = node.parent) { + for (node = p; node && !node.isMainLine; node = node.parent) { if (node.lastMove == null) { break; } result.push(node.lastMove); } result.reverse(); let playedCount = new Uint16Array(N * N); - for (let i=0; i < result.length -1; ++i) { + for (let i=0; i < result.length - 1; ++i) { let move = result[i]; if (moveIsPoint(move)) { diff --git a/minigui/static/board.js b/minigui/static/board.js index cd88b6819..c7158773d 100644 --- a/minigui/static/board.js +++ b/minigui/static/board.js @@ -214,7 +214,7 @@ define(["require", "exports", "./base", "./layer", "./util", "./view"], function drawImpl() { super.drawImpl(); let p = this.enabled ? this.p : null; - this.ctx.canvas.style.cursor = p ? 'pointer' : 'none'; + this.ctx.canvas.style.cursor = p ? 'pointer' : ''; if (p) { this.drawStones([p], this.position.toPlay, 0.6); } diff --git a/minigui/static/position.js b/minigui/static/position.js index 370d8acd3..a8f4a61e0 100644 --- a/minigui/static/position.js +++ b/minigui/static/position.js @@ -76,7 +76,7 @@ define(["require", "exports", "./base", "./util"], function (require, exports, b if (!p.isMainLine) { let result = []; let node; - for (node = p; node && node.isMainLine != true; node = node.parent) { + for (node = p; node && !node.isMainLine; node = node.parent) { if (node.lastMove == null) { break; } From 6d00ff62b72997f425037733f6e8b17c135ea0ef Mon Sep 17 00:00:00 2001 From: jacksona Date: Wed, 24 Jul 2019 11:19:55 -0700 Subject: [PATCH 7/7] change map to flat array --- minigui/layer.ts | 42 +++++++++++++++-------------------------- minigui/static/layer.js | 38 ++++++++++++++----------------------- 2 files changed, 29 insertions(+), 51 deletions(-) diff --git a/minigui/layer.ts b/minigui/layer.ts index abf890c18..147244d40 100644 --- a/minigui/layer.ts +++ b/minigui/layer.ts @@ -458,7 +458,7 @@ namespace Variation { class Annotations extends Layer { - private annotations = new Map(); + private annotations: Annotation[] = []; private _showDivergence = false; get showDivergence() : boolean { @@ -474,8 +474,8 @@ class Annotations extends Layer { } clear() { - if (this.annotations.size > 0) { - this.annotations.clear(); + if (this.annotations.length > 0) { + this.annotations = []; this.board.draw(); } } @@ -486,22 +486,13 @@ class Annotations extends Layer { } let position = this.board.position; - this.annotations.clear(); - for (let annotation of position.annotations) { - // this isn't really working with the enums, but its not clear how the - // annotations on a position should be grouped, otherwise. - let byShape = this.annotations.get(annotation.label); - if (byShape === undefined) { - byShape = []; - this.annotations.set(annotation.label, byShape); - } - byShape.push(annotation); - } + // TODO this.annotations could be a map keyed by coordinate. + this.annotations = position.annotations; return true; } draw() { - if (this.annotations.size == 0) { + if (this.annotations.length == 0) { return; } @@ -513,19 +504,16 @@ class Annotations extends Layer { ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; - // TODO this.annotation should be keyed by the board position, oops. - this.annotations.forEach((annotations: Annotation[], label: string) => { - for (let annotation of annotations) { - ctx.fillStyle = annotation.colors[0]; - let c = this.boardToCanvas(annotation.p.row, annotation.p.col); - if (label == "●"){ - ctx.fillText(label, c.x, c.y); - } - else if (this.showDivergence) { - ctx.fillText(label, c.x, c.y); - } + for (let annotation of this.annotations) { + ctx.fillStyle = annotation.colors[0]; + let c = this.boardToCanvas(annotation.p.row, annotation.p.col); + if (annotation.label == "●"){ + ctx.fillText(annotation.label, c.x, c.y); } - }); + else if (this.showDivergence) { + ctx.fillText(annotation.label, c.x, c.y); + } + } } } diff --git a/minigui/static/layer.js b/minigui/static/layer.js index 89a345b15..1c589765b 100644 --- a/minigui/static/layer.js +++ b/minigui/static/layer.js @@ -382,7 +382,7 @@ define(["require", "exports", "./base", "./util"], function (require, exports, b class Annotations extends Layer { constructor() { super(...arguments); - this.annotations = new Map(); + this.annotations = []; this._showDivergence = false; } get showDivergence() { @@ -397,8 +397,8 @@ define(["require", "exports", "./base", "./util"], function (require, exports, b this.board.draw(); } clear() { - if (this.annotations.size > 0) { - this.annotations.clear(); + if (this.annotations.length > 0) { + this.annotations = []; this.board.draw(); } } @@ -407,19 +407,11 @@ define(["require", "exports", "./base", "./util"], function (require, exports, b return false; } let position = this.board.position; - this.annotations.clear(); - for (let annotation of position.annotations) { - let byShape = this.annotations.get(annotation.label); - if (byShape === undefined) { - byShape = []; - this.annotations.set(annotation.label, byShape); - } - byShape.push(annotation); - } + this.annotations = position.annotations; return true; } draw() { - if (this.annotations.size == 0) { + if (this.annotations.length == 0) { return; } let sr = this.board.stoneRadius; @@ -428,18 +420,16 @@ define(["require", "exports", "./base", "./util"], function (require, exports, b ctx.font = `${textHeight}px sans-serif`; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; - this.annotations.forEach((annotations, label) => { - for (let annotation of annotations) { - ctx.fillStyle = annotation.colors[0]; - let c = this.boardToCanvas(annotation.p.row, annotation.p.col); - if (label == "●") { - ctx.fillText(label, c.x, c.y); - } - else if (this.showDivergence) { - ctx.fillText(label, c.x, c.y); - } + for (let annotation of this.annotations) { + ctx.fillStyle = annotation.colors[0]; + let c = this.boardToCanvas(annotation.p.row, annotation.p.col); + if (annotation.label == "●") { + ctx.fillText(annotation.label, c.x, c.y); } - }); + else if (this.showDivergence) { + ctx.fillText(annotation.label, c.x, c.y); + } + } } } exports.Annotations = Annotations;