graphdb-workbench-tests 3.4.0-TR3 → 3.4.0-TR5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -104,14 +104,14 @@ describe('Cluster states', () => {
104
104
  ClusterViewSteps.getLink('pc-desktop-7300-pc-desktop-7302').should('have.css', 'stroke-dasharray', '10px, 10px')
105
105
  .and('have.css', 'marker-mid', 'url("#arrowhead_big")')
106
106
  .invoke('attr', 'stroke')
107
- .should('eq', 'var(--gw-secondary-base)');
107
+ .should('eq', 'var(--gw-foreground-on-surface-primary)');
108
108
  // And I expect an out of sync link between the leader and the out of sync node (the one receiving the snapshot)
109
109
  ClusterViewSteps.getLink('pc-desktop-7301-pc-desktop-7300').should('have.css', 'stroke-dasharray', '10px, 10px')
110
110
  .invoke('attr', 'stroke')
111
- .should('eq', 'var(--gw-neutral-base)');
111
+ .should('eq', 'var(--gw-neutral-light)');
112
112
  // And I expect to have an in sync link between the leader and the node sending the snapshot
113
113
  ClusterViewSteps.getLink('pc-desktop-7301-pc-desktop-7302').should('have.css', 'stroke-dasharray', 'none')
114
114
  .invoke('attr', 'stroke')
115
- .should('eq', 'var(--gw-secondary-base)');
115
+ .should('eq', 'var(--gw-foreground-on-surface-primary)');
116
116
  });
117
117
  });
@@ -5,6 +5,7 @@ import {ApplicationSteps} from '../../../steps/application-steps';
5
5
  import HomeSteps from '../../../steps/home-steps.js';
6
6
  import {BaseSteps} from "../../../steps/base-steps.js";
7
7
  import SparqlSteps from "../../../steps/sparql-steps.js";
8
+ import {VisualGraphSplitButtonSteps} from '../../../steps/visual-graph-split-button-steps.js';
8
9
 
9
10
  const FILE_TO_IMPORT = 'wine.rdf';
10
11
  const VALID_RESOURCE = 'USRegion';
@@ -121,9 +122,10 @@ describe('Visual graph linksLimit URL parameter', () => {
121
122
  SparqlSteps.visit();
122
123
  SparqlSteps.typeQuery(`CONSTRUCT WHERE {?s ?p ?o} LIMIT 10`);
123
124
  SparqlSteps.executeQuery();
124
- SparqlSteps.visualizeConstructQuery();
125
+ VisualGraphSplitButtonSteps.clickOnVisualizeMainButton();
125
126
 
126
127
  // Then, I expect to see 10 nodes before changing the limit
128
+ BaseSteps.getUrl().should('include', 'linksLimit=10');
127
129
  VisualGraphSteps.getNodes().should('have.length', 10); // 10 nodes total, since we don't have a root node
128
130
 
129
131
  // When, I update the link limit from the input field
@@ -3,6 +3,7 @@ import {GuideSteps} from "../../../steps/guides/guide-steps.js";
3
3
  import {GuideDialogSteps} from "../../../steps/guides/guide-dialog-steps.js";
4
4
  import {YasrSteps} from "../../../steps/yasgui/yasr-steps.js";
5
5
  import {ResourceSteps} from "../../../steps/resource/resource-steps.js";
6
+ import {VisualGraphSplitButtonSteps} from '../../../steps/visual-graph-split-button-steps.js';
6
7
 
7
8
  describe('Table Graph explore', () => {
8
9
  const FILE_TO_IMPORT = 'wine.rdf';
@@ -107,7 +108,7 @@ describe('Table Graph explore', () => {
107
108
 
108
109
  GuideDialogSteps.assertDialogWithTitleIsVisible('Explore RDF as a table — 6/8');
109
110
  GuideDialogSteps.assertDialogWithContentIsVisible('You can always explore the same data using the Visual graph view. Click on the Visual graph button to try it now.');
110
- ResourceSteps.clickOnVisualGraphButton();
111
+ VisualGraphSplitButtonSteps.clickOnVisualizeMainButton();
111
112
 
112
113
  GuideDialogSteps.assertDialogWithTitleIsVisible('Explore RDF as a table — 7/8');
113
114
  GuideDialogSteps.assertDialogWithContentIsVisible('The graph shows connections between the start node, vin:WineGrape, and other nodes. Each arrow represents one or more connections (RDF statements).');
@@ -7,10 +7,12 @@ import {YasqeSteps} from "../../steps/yasgui/yasqe-steps";
7
7
  import {YasrSteps} from "../../steps/yasgui/yasr-steps";
8
8
  import {YasguiSteps} from "../../steps/yasgui/yasgui-steps";
9
9
  import {JsonLdModalSteps} from "../../steps/json-ld-modal-steps";
10
+ import {GraphConfigStubs} from '../../stubs/graph-config-stubs.js';
11
+ import {VisualGraphSplitButtonSteps} from '../../steps/visual-graph-split-button-steps.js';
10
12
 
11
13
  const FILE_TO_IMPORT = 'resource-test-data.ttl';
12
- const SUBJECT_RESOURCE = 'http:%2F%2Fexample.com%2Fontology%23CustomerLoyalty';
13
- const SUBJECT_RESOURCE_SHORT_URI = 'http://example.com/ontology#CustomerLoyalty';
14
+ const SUBJECT_RESOURCE_ENCODED = 'http:%2F%2Fexample.com%2Fontology%23CustomerLoyalty';
15
+ const SUBJECT_RESOURCE = 'http://example.com/ontology#CustomerLoyalty';
14
16
  const PREDICATE_SOURCE = 'http:%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23subClassOf';
15
17
  const CONTEXT_EXPLICIT = 'http://www.ontotext.com/explicit';
16
18
  const OBJECT_RESOURCE = 'http:%2F%2Fexample.com%2Fontology%23Metric';
@@ -33,13 +35,13 @@ describe('Resource view', () => {
33
35
 
34
36
  it('should open resource view with active role tab depend on url role parameter', () => {
35
37
  ResourceSteps.getAllRoles().forEach((role) => {
36
- ResourceSteps.visit(`uri=${SUBJECT_RESOURCE}&role=${role}`);
38
+ ResourceSteps.visit(`uri=${SUBJECT_RESOURCE_ENCODED}&role=${role}`);
37
39
  ResourceSteps.verifyActiveRoleTab(role);
38
40
  });
39
41
  });
40
42
 
41
43
  it('should open subject tab if role parameter is miss', () => {
42
- ResourceSteps.visit(`uri=${SUBJECT_RESOURCE}&role=subject`);
44
+ ResourceSteps.visit(`uri=${SUBJECT_RESOURCE_ENCODED}&role=subject`);
43
45
  ResourceSteps.verifyActiveRoleTab('subject');
44
46
  });
45
47
 
@@ -62,17 +64,35 @@ describe('Resource view', () => {
62
64
  YasrSteps.getResults().should('have.length', 5);
63
65
  });
64
66
 
65
- it('should navigate to visual graph view', () => {
67
+ it('should open graphs-visualizations view when click on main button', () => {
66
68
  // When I am on resource view and page loaded a resource.
67
- ResourceSteps.visit(`uri=${SUBJECT_RESOURCE}&role=subject`);
69
+ ResourceSteps.visit(`uri=${SUBJECT_RESOURCE_ENCODED}&role=subject`);
68
70
 
69
71
  // When I click on "Visual graph" button.
70
- ResourceSteps.clickOnVisualGraphButton();
72
+ VisualGraphSplitButtonSteps.clickOnVisualizeMainButton();
71
73
 
72
74
  // Then I expect to be redirected to explore graph view.
73
75
  VisualGraphSteps.verifyUrl();
74
76
  });
75
77
 
78
+ it('should open graphs-visualizations view when select a graph configuration', () => {
79
+ // When I am on resource view and page loaded a resource.
80
+ ResourceSteps.visit(`uri=${SUBJECT_RESOURCE_ENCODED}&role=subject`);
81
+ GraphConfigStubs.stubGetGraphConfigs();
82
+
83
+ // WHEN: I open the dropdown.
84
+ VisualGraphSplitButtonSteps.toggleGraphConfigDropdown();
85
+ // THEN: I expect to see all graph configurations.
86
+ VisualGraphSplitButtonSteps.getGraphConfigs().should('have.length', 3);
87
+
88
+ // WHEN: I select a graph configuration
89
+ VisualGraphSplitButtonSteps.selectGraphConfig();
90
+ // THEN: I expect to be navigated to graphs-visualizations view.
91
+ cy.url().should('include', 'graphs-visualizations');
92
+ cy.getQueryParam('uri').should('include', SUBJECT_RESOURCE);
93
+ cy.getQueryParam('config').should('eq', 'de99fd5de7f94ef98f1875dff55fc1c9');
94
+ });
95
+
76
96
  it('should displays results depends on explicit/implicit dropdown', () => {
77
97
  // When I am on resource view and page loaded a resource that has triplets in explicit and implicit context,
78
98
  ResourceSteps.visit(`uri=${IMPLICIT_EXPLICIT_RESOURCE}&role=all`);
@@ -175,11 +195,11 @@ describe('Resource view', () => {
175
195
  it('should list the triples of a resource used as subject', () => {
176
196
  // When I am on resource view,
177
197
  // and page loaded a resource that is used as subject,
178
- ResourceSteps.visit(`uri=${SUBJECT_RESOURCE}&role=subject`);
198
+ ResourceSteps.visit(`uri=${SUBJECT_RESOURCE_ENCODED}&role=subject`);
179
199
 
180
200
  // Then I expect to see only one result because the resource has only one triplet as subject.
181
201
  YasrSteps.getResults().should('have.length', 1);
182
- YasrSteps.getResultLink(0, 1).should('contain', SUBJECT_RESOURCE_SHORT_URI);
202
+ YasrSteps.getResultLink(0, 1).should('contain', SUBJECT_RESOURCE);
183
203
  YasrSteps.getResultLink(0, 2).should('contain', 'rdfs:subClassOf');
184
204
  YasrSteps.getResultLink(0, 3).should('contain', 'http://example.com/ontology#Metric');
185
205
  YasrSteps.getResultLink(0, 4).should('contain', CONTEXT_EXPLICIT);
@@ -196,7 +216,7 @@ describe('Resource view', () => {
196
216
  YasrSteps.getResults().should('have.length', 1);
197
217
  YasrSteps.getResultLink(0, 1).should('contain', 'http://example.com/resource/person/W6J1827/customerLoyalty');
198
218
  YasrSteps.getResultLink(0, 2).should('contain', 'rdf:type');
199
- YasrSteps.getResultLink(0, 3).should('contain', SUBJECT_RESOURCE_SHORT_URI);
219
+ YasrSteps.getResultLink(0, 3).should('contain', SUBJECT_RESOURCE);
200
220
  YasrSteps.getResultLink(0, 4).should('contain', CONTEXT_EXPLICIT);
201
221
 
202
222
  // When I click on "context" tab.
@@ -211,14 +231,14 @@ describe('Resource view', () => {
211
231
  // Then I expect to see all triples of subject without mater of its role.
212
232
  YasrSteps.getResults().should('have.length', 2);
213
233
 
214
- YasrSteps.getResultLink(0, 1).should('contain', SUBJECT_RESOURCE_SHORT_URI);
234
+ YasrSteps.getResultLink(0, 1).should('contain', SUBJECT_RESOURCE);
215
235
  YasrSteps.getResultLink(0, 2).should('contain', 'rdfs:subClassOf');
216
236
  YasrSteps.getResultLink(0, 3).should('contain', 'http://example.com/ontology#Metric');
217
237
  YasrSteps.getResultLink(0, 4).should('contain', CONTEXT_EXPLICIT);
218
238
 
219
239
  YasrSteps.getResultLink(1, 1).should('contain', 'http://example.com/resource/person/W6J1827/customerLoyalty');
220
240
  YasrSteps.getResultLink(1, 2).should('contain', 'rdf:type');
221
- YasrSteps.getResultLink(1, 3).should('contain', SUBJECT_RESOURCE_SHORT_URI);
241
+ YasrSteps.getResultLink(1, 3).should('contain', SUBJECT_RESOURCE);
222
242
  YasrSteps.getResultLink(1, 4).should('contain', CONTEXT_EXPLICIT);
223
243
  });
224
244
 
@@ -364,7 +384,7 @@ describe('Resource view', () => {
364
384
  context('Download as', () => {
365
385
  it('should download as JSON-LD and then restore defaults', () => {
366
386
  // Given I am in the Resource view
367
- ResourceSteps.visit(`uri=${SUBJECT_RESOURCE}&role=subject`);
387
+ ResourceSteps.visit(`uri=${SUBJECT_RESOURCE_ENCODED}&role=subject`);
368
388
  cy.window().then((win) => {
369
389
  expect(win.jsonld).to.exist;
370
390
  cy.stub(win.jsonld, 'compact').resolves({
@@ -1,9 +1,9 @@
1
1
  import {SparqlEditorSteps} from '../../../../steps/sparql-editor-steps';
2
2
  import {YasqeSteps} from '../../../../steps/yasgui/yasqe-steps';
3
- import {YasrSteps} from '../../../../steps/yasgui/yasr-steps';
4
3
  import {QueryStubs} from '../../../../stubs/yasgui/query-stubs';
5
4
  import {GraphConfigStubs} from '../../../../stubs/graph-config-stubs.js';
6
5
  import {BrowserStubs} from '../../../../stubs/browser-stubs.js';
6
+ import {VisualGraphSplitButtonSteps} from '../../../../steps/visual-graph-split-button-steps.js';
7
7
 
8
8
  describe('"Visualize" split button', () => {
9
9
  let repositoryId;
@@ -25,17 +25,17 @@ describe('"Visualize" split button', () => {
25
25
  // WHEN: I visit a page with 'ontotext-yasgui-web-component' on it, and execute select query.
26
26
  executeSelectQuery();
27
27
  // THEN: I expect the 'Visualize' button to not be visible.
28
- YasrSteps.getVisualizeMainButton().should('not.be.visible');
28
+ VisualGraphSplitButtonSteps.getVisualizeMainButton().should('not.be.visible');
29
29
 
30
30
  // WHEN: I execute a CONSTRUCT query.
31
31
  executeConstructQuery();
32
32
  // THEN: I expect the 'Visualize' button to be visible.
33
- YasrSteps.getVisualizeMainButton().should('be.visible');
33
+ VisualGraphSplitButtonSteps.getVisualizeMainButton().should('be.visible');
34
34
 
35
35
  // WHEN: I execute SELECT query again.
36
36
  executeSelectQuery();
37
37
  // THEN: I expect the 'Visualize' button to not be visible.
38
- YasrSteps.getVisualizeMainButton().should('not.be.visible');
38
+ VisualGraphSplitButtonSteps.getVisualizeMainButton().should('not.be.visible');
39
39
  });
40
40
 
41
41
  it('should inform user that there no created graph configurations', () => {
@@ -45,13 +45,13 @@ describe('"Visualize" split button', () => {
45
45
  executeConstructQuery();
46
46
 
47
47
  // WHEN: I open the dropdown.
48
- YasrSteps.toggleGraphConfigDropdown();
48
+ VisualGraphSplitButtonSteps.toggleGraphConfigDropdown();
49
49
  // THEN: I expect to see message that informs that there are no graph configurations.
50
- YasrSteps.getNoConfigurationsMessage().should('contain.text', 'No advanced graph configuration.');
50
+ VisualGraphSplitButtonSteps.getNoConfigurationsMessage().should('contain.text', 'No advanced graph configuration.');
51
51
 
52
52
  // WHEN: I click on create link.
53
53
  BrowserStubs.stubWindowOpen();
54
- YasrSteps.clickCreateGraphConfigLink();
54
+ VisualGraphSplitButtonSteps.clickCreateGraphConfigLink();
55
55
  // THEN: I expect to be navigated to graph configurations page.
56
56
  cy.get(BrowserStubs.WINDOW_OPEN_ALIAS()).should('have.been.calledWithMatch', 'graphs-visualizations', '_blank', 'noopener,noreferrer');
57
57
  });
@@ -61,7 +61,7 @@ describe('"Visualize" split button', () => {
61
61
  executeConstructQuery();
62
62
 
63
63
  // WHEN: I click on main button
64
- YasrSteps.clickOnVisualizeMainButton();
64
+ VisualGraphSplitButtonSteps.clickOnVisualizeMainButton();
65
65
  // THEN: I expect to be navigated to graphs-visualizations view.
66
66
  cy.url().should('include', 'graphs-visualizations');
67
67
  cy.getQueryParam('query').should('include', 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>PREFIX onto: <http://www.ontotext.com/>CONSTRUCT {?source rdf:type ?destination .} WHERE {?bag rdf:type ?source .?flight rdf:type ?destination}');
@@ -74,12 +74,12 @@ describe('"Visualize" split button', () => {
74
74
  GraphConfigStubs.stubGetGraphConfigs();
75
75
 
76
76
  // WHEN: I open the dropdown.
77
- YasrSteps.toggleGraphConfigDropdown();
77
+ VisualGraphSplitButtonSteps.toggleGraphConfigDropdown();
78
78
  // THEN: I expect to see all graph configurations.
79
- YasrSteps.getGraphConfigs().should('have.length', 3);
79
+ VisualGraphSplitButtonSteps.getGraphConfigs().should('have.length', 3);
80
80
 
81
81
  // WHEN: I select a graph configuration
82
- YasrSteps.selectGraphConfig();
82
+ VisualGraphSplitButtonSteps.selectGraphConfig();
83
83
  // THEN: I expect to be navigated to graphs-visualizations view.
84
84
  cy.url().should('include', 'graphs-visualizations');
85
85
  cy.getQueryParam('query').should('include', 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>PREFIX onto: <http://www.ontotext.com/>CONSTRUCT {?source rdf:type ?destination .} WHERE {?bag rdf:type ?source .?flight rdf:type ?destination}');
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "3.4.0-TR3",
3
+ "version": "3.4.0-TR5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "graphdb-workbench-tests",
9
- "version": "3.4.0-TR3",
9
+ "version": "3.4.0-TR5",
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
12
  "@bahmutov/cypress-code-coverage": "^2.7.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphdb-workbench-tests",
3
- "version": "3.4.0-TR3",
3
+ "version": "3.4.0-TR5",
4
4
  "description": "Cypress tests for GraphDB workbench",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -5,6 +5,7 @@ import {VisualGraphSteps} from "../visual-graph-steps";
5
5
  import {YasrSteps} from "../yasgui/yasr-steps";
6
6
  import {YasqeSteps} from "../yasgui/yasqe-steps";
7
7
  import {ResourceSteps} from "../resource/resource-steps";
8
+ import {VisualGraphSplitButtonSteps} from '../visual-graph-split-button-steps.js';
8
9
 
9
10
  export class MoviesGuideSteps {
10
11
 
@@ -181,7 +182,7 @@ export class MoviesGuideSteps {
181
182
  static assertExploreRDFStep7() {
182
183
  GuideSteps.assertPageNotInteractive();
183
184
  GuideDialogSteps.assertDialogWithTitleIsVisible('Explore RDF as a table — 7/10');
184
- ResourceSteps.getVisualGraphButton().should('be.visible');
185
+ VisualGraphSplitButtonSteps.getVisualizeMainButton().should('be.visible');
185
186
  }
186
187
 
187
188
  static assertExploreRDFStep8() {
@@ -61,14 +61,6 @@ export class ResourceSteps {
61
61
  cy.get('.download-options li').eq(option).click();
62
62
  }
63
63
 
64
- static getVisualGraphButton() {
65
- return cy.get('.visual-graph-btn');
66
- }
67
-
68
- static clickOnVisualGraphButton() {
69
- ResourceSteps.getVisualGraphButton().click();
70
- }
71
-
72
64
  static getEditResourceLink() {
73
65
  return cy.get('.edit-resource-link');
74
66
  }
@@ -429,7 +429,7 @@ export class TtygAgentSettingsModalSteps extends ModalDialogSteps {
429
429
  }
430
430
 
431
431
  static enterContextSize(input) {
432
- this.getContextSizeField().type(input);
432
+ this.getContextSizeField().type(input, {force: true});
433
433
  }
434
434
 
435
435
  static getContextSizeError() {
@@ -0,0 +1,45 @@
1
+ export class VisualGraphSplitButtonSteps {
2
+ static getGraphExploreSplitButton() {
3
+ return cy.get('onto-graph-explore-split-button');
4
+ }
5
+
6
+ static getVisualizeMainButton() {
7
+ return VisualGraphSplitButtonSteps.getGraphExploreSplitButton().find('.explore-visual-graph-button');
8
+ }
9
+
10
+ static clickOnVisualizeMainButton() {
11
+ VisualGraphSplitButtonSteps.getVisualizeMainButton().click();
12
+ }
13
+
14
+ static getDropdownToggleButton() {
15
+ return VisualGraphSplitButtonSteps.getGraphExploreSplitButton().find('.onto-dropdown-button');
16
+ }
17
+
18
+ static toggleGraphConfigDropdown() {
19
+ VisualGraphSplitButtonSteps.getDropdownToggleButton().click();
20
+ }
21
+
22
+ static getGraphConfigs() {
23
+ return VisualGraphSplitButtonSteps.getGraphExploreSplitButton().find('.onto-dropdown-menu-item');
24
+ }
25
+
26
+ static getGraphConfig(index = 0) {
27
+ return VisualGraphSplitButtonSteps.getGraphConfigs().eq(index);
28
+ }
29
+
30
+ static selectGraphConfig(index = 0) {
31
+ VisualGraphSplitButtonSteps.getGraphConfig(index).click();
32
+ }
33
+
34
+ static getCreateGraphConfigLink() {
35
+ return VisualGraphSplitButtonSteps.getGraphExploreSplitButton().find('.graph-create-link');
36
+ }
37
+
38
+ static clickCreateGraphConfigLink() {
39
+ VisualGraphSplitButtonSteps.getCreateGraphConfigLink().click();
40
+ }
41
+
42
+ static getNoConfigurationsMessage() {
43
+ return VisualGraphSplitButtonSteps.getGraphExploreSplitButton().find('.no-configurations-message');
44
+ }
45
+ }
@@ -113,50 +113,6 @@ export class YasrSteps extends BaseSteps {
113
113
  return YasrSteps.getYasr().find('.yasr-toolbar');
114
114
  }
115
115
 
116
- static getGraphExploreSplitButton() {
117
- return YasrSteps.getYasrToolbar().find('.explore-visual-graph');
118
- }
119
-
120
- static getVisualizeMainButton() {
121
- return YasrSteps.getGraphExploreSplitButton().find('.explore-visual-graph-button');
122
- }
123
-
124
- static clickOnVisualizeMainButton() {
125
- YasrSteps.getVisualizeMainButton().click();
126
- }
127
-
128
- static getDropdownToggleButton() {
129
- return YasrSteps.getGraphExploreSplitButton().find('.onto-dropdown-button');
130
- }
131
-
132
- static toggleGraphConfigDropdown() {
133
- YasrSteps.getDropdownToggleButton().click();
134
- }
135
-
136
- static getGraphConfigs() {
137
- return YasrSteps.getGraphExploreSplitButton().find('.onto-dropdown-menu-item');
138
- }
139
-
140
- static getGraphConfig(index = 0) {
141
- return YasrSteps.getGraphConfigs().eq(index);
142
- }
143
-
144
- static selectGraphConfig(index = 0) {
145
- YasrSteps.getGraphConfig(index).click();
146
- }
147
-
148
- static getCreateGraphConfigLink() {
149
- return YasrSteps.getGraphExploreSplitButton().find('.graph-create-link');
150
- }
151
-
152
- static clickCreateGraphConfigLink() {
153
- YasrSteps.getCreateGraphConfigLink().click();
154
- }
155
-
156
- static getNoConfigurationsMessage() {
157
- return YasrSteps.getGraphExploreSplitButton().find('.no-configurations-message');
158
- }
159
-
160
116
  static getNoDataElement() {
161
117
  return cy.get('.dataTables_empty');
162
118
  }