@tiledesk/tiledesk-server 2.10.14 → 2.10.16
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +9 -0
- package/app.js +2 -1
- package/models/request.js +8 -0
- package/package.json +4 -3
- package/pubmodules/activities/test/activityRoute.js +6 -2
- package/pubmodules/events/test/eventRoute.js +7 -3
- package/pubmodules/pubModulesManager.js +24 -0
- package/pubmodules/voice-twilio/index.js +6 -0
- package/pubmodules/voice-twilio/listener.js +59 -0
- package/routes/campaigns.js +1 -1
- package/routes/files.js +6 -4
- package/routes/images.js +0 -2
- package/routes/kb.js +7 -1
- package/routes/request.js +10 -0
- package/routes/users.js +2 -2
- package/services/fileGridFsService.js +12 -10
- package/services/requestService.js +2 -1
- package/test/app-test.js +36 -1
- package/test/authentication.js +662 -796
- package/test/authenticationJwt.js +213 -315
- package/test/authorization.js +53 -72
- package/test/campaignsRoute.js +42 -47
- package/test/cannedRoute.js +30 -16
- package/test/departmentService.js +222 -274
- package/test/example.json +31 -1
- package/test/faqRoute.js +713 -622
- package/test/faqService.js +124 -159
- package/test/faqkbRoute.js +128 -100
- package/test/fileRoute.js +50 -46
- package/test/imageRoute.js +263 -254
- package/test/jwtRoute.js +128 -153
- package/test/kbRoute.js +40 -17
- package/test/kbsettingsRoute.js +78 -54
- package/test/keysRoute.js +6 -7
- package/test/labelRoute.js +591 -696
- package/test/labelService.js +40 -47
- package/test/leadService.js +100 -115
- package/test/logsRoute.js +13 -7
- package/test/messageRootRoute.js +112 -102
- package/test/messageRoute.js +1171 -1419
- package/test/messageService.js +41 -43
- package/test/openaiRoute.js +5 -1
- package/test/projectRoute.js +23 -4
- package/test/projectService.js +3 -1
- package/test/quoteManager.js +36 -13
- package/test/requestRoute.js +103 -72
- package/test/requestService.js +51 -51
- package/test/userRoute.js +37 -8
- package/test/userService.js +34 -31
- package/utils/promiseUtil.js +1 -1
package/test/authorization.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
//During the test the env variable is set to test
|
2
2
|
process.env.NODE_ENV = 'test';
|
3
|
+
process.env.LOG_LEVEL = 'critical';
|
3
4
|
|
4
5
|
//var User = require('../models/user');
|
5
6
|
var projectService = require('../services/projectService');
|
@@ -13,6 +14,8 @@ let chaiHttp = require('chai-http');
|
|
13
14
|
let server = require('../app');
|
14
15
|
let should = chai.should();
|
15
16
|
|
17
|
+
let log = false;
|
18
|
+
|
16
19
|
// chai.config.includeStack = true;
|
17
20
|
|
18
21
|
var expect = chai.expect;
|
@@ -22,89 +25,74 @@ chai.use(chaiHttp);
|
|
22
25
|
|
23
26
|
describe('Authorization', () => {
|
24
27
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
|
29
29
|
it('userBelongsToProject', (done) => {
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
32
|
+
var pwd = "Pwd1234!";
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
userService.signup( email ,pwd, "Test Firstname", "Test lastname").then(function(savedUser) {
|
38
|
-
projectService.createAndReturnProjectAndProjectUser("test-auth", savedUser._id).then(function(savedProjectAndPU) {
|
34
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
35
|
+
projectService.createAndReturnProjectAndProjectUser("test-auth", savedUser._id).then(function (savedProjectAndPU) {
|
39
36
|
var savedProject = savedProjectAndPU.project;
|
40
|
-
leadService.createIfNotExists("request_id1-userBelongsToProject", "email@userBelongsToProject.com", savedProject._id).then(function(createdLead) {
|
37
|
+
leadService.createIfNotExists("request_id1-userBelongsToProject", "email@userBelongsToProject.com", savedProject._id).then(function (createdLead) {
|
41
38
|
// createWithIdAndRequester(request_id, project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes) {
|
42
|
-
|
43
|
-
|
44
|
-
// var webhookContent = { "assignee": 'assignee-member'}
|
45
|
-
|
46
|
-
|
47
|
-
chai.request(server)
|
48
|
-
.get('/'+ savedProject._id + '/requests/' + savedRequest.request_id )
|
49
|
-
.auth(email, pwd)
|
50
|
-
.end((err, res) => {
|
51
|
-
//console.log("res", res);
|
52
|
-
console.log("res.body", res.body);
|
53
|
-
res.should.have.status(200);
|
54
|
-
res.body.should.be.a('object');
|
55
|
-
|
56
|
-
|
57
|
-
done();
|
58
|
-
});
|
39
|
+
var id_request = "test-userBelongsToProject" + Date.now();
|
40
|
+
requestService.createWithIdAndRequester(id_request, savedProjectAndPU.project_user._id, createdLead._id, savedProject._id, "first_text").then(function (savedRequest) {
|
59
41
|
|
60
|
-
|
61
|
-
|
42
|
+
// var webhookContent = { "assignee": 'assignee-member'}
|
43
|
+
chai.request(server)
|
44
|
+
.get('/' + savedProject._id + '/requests/' + savedRequest.request_id)
|
45
|
+
.auth(email, pwd)
|
46
|
+
.end((err, res) => {
|
47
|
+
|
48
|
+
if (err) { console.error("err: ", err); }
|
49
|
+
if (log) { console.log("res.body", res.body); }
|
50
|
+
|
51
|
+
res.should.have.status(200);
|
52
|
+
res.body.should.be.a('object');
|
53
|
+
|
54
|
+
done();
|
55
|
+
});
|
56
|
+
});
|
62
57
|
});
|
63
58
|
});
|
64
|
-
|
59
|
+
});
|
65
60
|
}).timeout(20000);
|
66
61
|
|
67
62
|
|
68
|
-
|
69
|
-
|
70
63
|
it('userNOTBelongsToProject', (done) => {
|
71
64
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
var email = "test-signup-other-" + Date.now() + "@email.com";
|
76
|
-
var pwd = "pwd";
|
65
|
+
var email = "test-signup-other-" + Date.now() + "@email.com";
|
66
|
+
var pwd = "pwd";
|
77
67
|
|
78
|
-
|
79
|
-
userService.signup(
|
80
|
-
projectService.createAndReturnProjectAndProjectUser("test-auth", savedUserOther._id).then(function(savedProjectAndPU) {
|
68
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
69
|
+
userService.signup("test-signup" + Date.now() + "@email.com", pwd, "Test Firstname other", "Test lastname other").then(function (savedUserOther) {
|
70
|
+
projectService.createAndReturnProjectAndProjectUser("test-auth", savedUserOther._id).then(function (savedProjectAndPU) {
|
81
71
|
var savedProject = savedProjectAndPU.project;
|
82
|
-
leadService.createIfNotExists("request_id1-userNOTBelongsToProject", "email@userNOTBelongsToProject.com", savedProject._id).then(function(createdLead) {
|
83
|
-
requestService.createWithIdAndRequester("test-auth",savedProjectAndPU.project_user._id, createdLead._id, savedProject._id, "first_text").then(function(savedRequest) {
|
84
|
-
|
85
|
-
// var webhookContent = { "assignee": 'assignee-member'}
|
86
|
-
|
87
|
-
|
88
|
-
chai.request(server)
|
89
|
-
.get('/'+ savedProject._id + '/requests/' + savedRequest._id )
|
90
|
-
.auth(email, pwd)
|
91
|
-
.end((err, res) => {
|
92
|
-
//console.log("res", res);
|
93
|
-
console.log("res.body", res.body);
|
94
|
-
res.should.have.status(403);
|
95
|
-
|
96
|
-
done();
|
97
|
-
});
|
98
|
-
|
99
|
-
});
|
100
|
-
});
|
101
|
-
});
|
102
|
-
});
|
103
|
-
});
|
104
|
-
}).timeout(20000);
|
72
|
+
leadService.createIfNotExists("request_id1-userNOTBelongsToProject", "email@userNOTBelongsToProject.com", savedProject._id).then(function (createdLead) {
|
105
73
|
|
74
|
+
var id_request = "test-auth" + Date.now();
|
75
|
+
requestService.createWithIdAndRequester(id_request, savedProjectAndPU.project_user._id, createdLead._id, savedProject._id, "first_text").then(function (savedRequest) {
|
106
76
|
|
77
|
+
// var webhookContent = { "assignee": 'assignee-member'}
|
78
|
+
chai.request(server)
|
79
|
+
.get('/' + savedProject._id + '/requests/' + savedRequest._id)
|
80
|
+
.auth(email, pwd)
|
81
|
+
.end((err, res) => {
|
82
|
+
|
83
|
+
if (err) { console.error("err: ", err); }
|
84
|
+
if (log) { console.log("res.body", res.body); }
|
107
85
|
|
86
|
+
res.should.have.status(403);
|
87
|
+
|
88
|
+
done();
|
89
|
+
});
|
90
|
+
});
|
91
|
+
});
|
92
|
+
});
|
93
|
+
});
|
94
|
+
});
|
95
|
+
}).timeout(20000);
|
108
96
|
|
109
97
|
|
110
98
|
// it('userCANTAddProjectUser', (done) => {
|
@@ -141,13 +129,6 @@ describe('Authorization', () => {
|
|
141
129
|
// });
|
142
130
|
// }).timeout(20000);
|
143
131
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
});
|
150
|
-
|
151
132
|
});
|
152
133
|
|
153
134
|
|
package/test/campaignsRoute.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
//During the test the env variable is set to test
|
2
2
|
process.env.NODE_ENV = 'test';
|
3
|
+
process.env.LOG_LEVEL = 'critical';
|
3
4
|
|
4
5
|
var User = require('../models/user');
|
5
6
|
var projectService = require('../services/projectService');
|
@@ -15,6 +16,8 @@ var winston = require('../config/winston');
|
|
15
16
|
var jwt = require('jsonwebtoken');
|
16
17
|
// chai.config.includeStack = true;
|
17
18
|
|
19
|
+
let log = false;
|
20
|
+
|
18
21
|
var expect = chai.expect;
|
19
22
|
var assert = chai.assert;
|
20
23
|
|
@@ -24,7 +27,6 @@ describe('CampaignsRoute', () => {
|
|
24
27
|
|
25
28
|
|
26
29
|
// mocha test/campaignsRoute.js --grep 'directSimpleNoOut'
|
27
|
-
|
28
30
|
it('directSimpleNoOut', function (done) {
|
29
31
|
|
30
32
|
var email = "test-message-create-" + Date.now() + "@email.com";
|
@@ -42,15 +44,15 @@ describe('CampaignsRoute', () => {
|
|
42
44
|
.set('content-type', 'application/json')
|
43
45
|
.send({ "text": "ciao", "recipient": recipient })
|
44
46
|
.end(function (err, res) {
|
45
|
-
//console.log("res", res);
|
46
|
-
console.log("res.body", res.body);
|
47
|
-
res.should.have.status(200);
|
48
|
-
res.body.should.be.a('object');
|
49
47
|
|
48
|
+
if (err) { console.error("err: ", err); }
|
49
|
+
if (log) { console.log("res.body", res.body); }
|
50
50
|
|
51
|
+
res.should.have.status(200);
|
52
|
+
res.body.should.be.a('object');
|
51
53
|
|
52
|
-
expect(res.body.success).to.equal(true);
|
53
|
-
|
54
|
+
// expect(res.body.success).to.equal(true); //CHECK IT! Why was it checking success and not queued?
|
55
|
+
expect(res.body.queued).to.equal(true);
|
54
56
|
|
55
57
|
done();
|
56
58
|
});
|
@@ -58,13 +60,8 @@ describe('CampaignsRoute', () => {
|
|
58
60
|
});
|
59
61
|
});
|
60
62
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
|
66
64
|
// mocha test/campaignsRoute.js --grep 'directSimple'
|
67
|
-
|
68
65
|
it('directSimple', function (done) {
|
69
66
|
|
70
67
|
var email = "test-message-create-" + Date.now() + "@email.com";
|
@@ -82,19 +79,22 @@ describe('CampaignsRoute', () => {
|
|
82
79
|
.set('content-type', 'application/json')
|
83
80
|
.send({ "text": "ciao", "recipient": recipient, returnobject: true })
|
84
81
|
.end(function (err, res) {
|
85
|
-
|
86
|
-
console.
|
82
|
+
|
83
|
+
if (err) { console.error("err: ", err); }
|
84
|
+
if (log) { console.log("res.body", res.body); }
|
85
|
+
|
87
86
|
res.should.have.status(200);
|
88
87
|
res.body.should.be.a('object');
|
89
88
|
|
90
|
-
expect(res.body.channel_type).to.equal("direct");
|
91
|
-
expect(res.body.senderFullname).to.equal("Test Firstname Test lastname");
|
92
|
-
expect(res.body.sender).to.equal(savedUser._id.toString());
|
93
|
-
expect(res.body.recipient).to.equal(recipient);
|
94
|
-
|
95
89
|
|
96
|
-
//
|
90
|
+
// WARNING! The service returns { queued: true } and not the message
|
91
|
+
// So the following expects can't work
|
92
|
+
// expect(res.body.channel_type).to.equal("direct");
|
93
|
+
// expect(res.body.senderFullname).to.equal("Test Firstname Test lastname");
|
94
|
+
// expect(res.body.sender).to.equal(savedUser._id.toString());
|
95
|
+
// expect(res.body.recipient).to.equal(recipient);
|
97
96
|
|
97
|
+
expect(res.body.queued).to.equal(true);
|
98
98
|
|
99
99
|
done();
|
100
100
|
});
|
@@ -103,10 +103,7 @@ describe('CampaignsRoute', () => {
|
|
103
103
|
});
|
104
104
|
|
105
105
|
|
106
|
-
|
107
|
-
|
108
106
|
// mocha test/campaignsRoute.js --grep 'directGroupIdNoOut'
|
109
|
-
|
110
107
|
it('directGroupIdNoOut', function (done) {
|
111
108
|
|
112
109
|
var email = "test-message-create-" + Date.now() + "@email.com";
|
@@ -132,8 +129,8 @@ describe('CampaignsRoute', () => {
|
|
132
129
|
updatedBy: userid
|
133
130
|
});
|
134
131
|
newGroup.save(function (err, savedGroup) {
|
135
|
-
|
136
|
-
|
132
|
+
|
133
|
+
if (log) { console.log("savedGroup", savedGroup); }
|
137
134
|
|
138
135
|
chai.request(server)
|
139
136
|
.post('/' + savedProject._id + '/campaigns/direct')
|
@@ -141,14 +138,15 @@ describe('CampaignsRoute', () => {
|
|
141
138
|
.set('content-type', 'application/json')
|
142
139
|
.send({ "text": "ciao", "group_id": savedGroup._id.toString() })
|
143
140
|
.end(function (err, res) {
|
144
|
-
|
145
|
-
console.
|
141
|
+
|
142
|
+
if (err) { console.error("err: ", err); }
|
143
|
+
if (log) { console.log("res.body", res.body); }
|
144
|
+
|
146
145
|
res.should.have.status(200);
|
147
146
|
res.body.should.be.a('object');
|
148
147
|
|
149
|
-
|
150
|
-
expect(res.body.
|
151
|
-
|
148
|
+
// expect(res.body.success).to.equal(true); //CHECK IT! Why was it checking success and not queued?
|
149
|
+
expect(res.body.queued).to.equal(true);
|
152
150
|
|
153
151
|
done();
|
154
152
|
});
|
@@ -159,10 +157,7 @@ describe('CampaignsRoute', () => {
|
|
159
157
|
});
|
160
158
|
|
161
159
|
|
162
|
-
|
163
|
-
|
164
160
|
// mocha test/campaignsRoute.js --grep 'directGroupId2'
|
165
|
-
|
166
161
|
it('directGroupId2', function (done) {
|
167
162
|
|
168
163
|
var email = "test-message-create-" + Date.now() + "@email.com";
|
@@ -188,8 +183,8 @@ describe('CampaignsRoute', () => {
|
|
188
183
|
updatedBy: userid
|
189
184
|
});
|
190
185
|
newGroup.save(function (err, savedGroup) {
|
191
|
-
|
192
|
-
|
186
|
+
|
187
|
+
if (log) { console.log("savedGroup", savedGroup); }
|
193
188
|
|
194
189
|
chai.request(server)
|
195
190
|
.post('/' + savedProject._id + '/campaigns/direct')
|
@@ -197,15 +192,19 @@ describe('CampaignsRoute', () => {
|
|
197
192
|
.set('content-type', 'application/json')
|
198
193
|
.send({ "text": "ciao", "group_id": savedGroup._id.toString(), returnobject: true })
|
199
194
|
.end(function (err, res) {
|
200
|
-
|
201
|
-
console.
|
195
|
+
|
196
|
+
if (err) { console.error("err: ", err); }
|
197
|
+
if (log) { console.log("res.body", res.body); }
|
198
|
+
|
202
199
|
res.should.have.status(200);
|
203
|
-
res.body.should.be.a('array');
|
204
200
|
|
205
|
-
|
206
|
-
|
207
|
-
expect(res.body
|
208
|
-
// expect(res.body.
|
201
|
+
// WARNING! The service returns { queued: true } and not the message
|
202
|
+
// res.body.should.be.a('array');
|
203
|
+
// expect(res.body.length).to.equal(2);
|
204
|
+
// expect(res.body[0].recipient).to.equal(userid.toString());
|
205
|
+
// expect(res.body[1].recipient).to.equal(savedUser2._id.toString());
|
206
|
+
|
207
|
+
expect(res.body.queued).to.equal(true);
|
209
208
|
|
210
209
|
|
211
210
|
done();
|
@@ -217,10 +216,6 @@ describe('CampaignsRoute', () => {
|
|
217
216
|
});
|
218
217
|
|
219
218
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
219
|
});
|
225
220
|
|
226
221
|
|
package/test/cannedRoute.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
//During the test the env variable is set to test
|
2
2
|
process.env.NODE_ENV = 'test';
|
3
|
+
process.env.LOG_LEVEL = 'critical';
|
3
4
|
|
4
5
|
//Require the dev-dependencies
|
5
6
|
let chai = require('chai');
|
@@ -13,7 +14,7 @@ var RoleConstants = require("../models/roleConstants");
|
|
13
14
|
const Project_user = require('../models/project_user');
|
14
15
|
let should = chai.should();
|
15
16
|
|
16
|
-
|
17
|
+
let log = false;
|
17
18
|
|
18
19
|
chai.use(chaiHttp);
|
19
20
|
|
@@ -32,6 +33,10 @@ describe('CannedRoute', () => {
|
|
32
33
|
.set('content-type', 'application/json')
|
33
34
|
.send({ "title": "Test Title", "text": "Test Text" })
|
34
35
|
.end((err, res) => {
|
36
|
+
|
37
|
+
if (err) { console.error("err: ", err); }
|
38
|
+
if (log) { console.log("res.body: ", res.body); }
|
39
|
+
|
35
40
|
res.should.have.status(200);
|
36
41
|
res.body.should.be.a('object');
|
37
42
|
res.body.should.have.property('title').eql("Test Title");
|
@@ -59,6 +64,10 @@ describe('CannedRoute', () => {
|
|
59
64
|
.set('content-type', 'application/json')
|
60
65
|
.send({ title: "Test Title", text: "Test Text" })
|
61
66
|
.end((err, res) => {
|
67
|
+
|
68
|
+
if (err) { console.error("err: ", err); }
|
69
|
+
if (log) { console.log("res.body: ", res.body); }
|
70
|
+
|
62
71
|
res.body.should.be.a('object');
|
63
72
|
res.body.should.have.property('title').eql("Test Title");
|
64
73
|
res.body.should.have.property('text').eql("Test Text");
|
@@ -81,7 +90,7 @@ describe('CannedRoute', () => {
|
|
81
90
|
userService.signup(email_owner, pwd, "Owner Firstname", "Owner Lastname").then(savedOwner => {
|
82
91
|
userService.signup(email_agent, pwd, "Agent Firstname", "Agent Lastname").then(savedAgent => {
|
83
92
|
projectService.create("test1", savedOwner._id).then(savedProject => {
|
84
|
-
|
93
|
+
|
85
94
|
// invite Agent on savedProject (?)
|
86
95
|
chai.request(server)
|
87
96
|
.post('/' + savedProject._id + "/project_users/invite")
|
@@ -89,8 +98,11 @@ describe('CannedRoute', () => {
|
|
89
98
|
.set('content-type', 'application/json')
|
90
99
|
.send({ email: email_agent, role: "agent", userAvailable: false })
|
91
100
|
.end((err, res) => {
|
92
|
-
res.should.have.status(200);
|
93
101
|
|
102
|
+
if (err) { console.error("err: ", err); }
|
103
|
+
if (log) { console.log("res.body: ", res.body); }
|
104
|
+
|
105
|
+
res.should.have.status(200);
|
94
106
|
|
95
107
|
chai.request(server)
|
96
108
|
.post('/' + savedProject._id + "/canned/")
|
@@ -99,6 +111,9 @@ describe('CannedRoute', () => {
|
|
99
111
|
.send({ title: "Test1 Title", text: "Test1 Text" })
|
100
112
|
.end((err, res) => {
|
101
113
|
|
114
|
+
if (err) { console.error("err: ", err); }
|
115
|
+
if (log) { console.log("res.body: ", res.body); }
|
116
|
+
|
102
117
|
res.should.have.status(200);
|
103
118
|
res.body.should.be.a('object');
|
104
119
|
|
@@ -108,7 +123,10 @@ describe('CannedRoute', () => {
|
|
108
123
|
.set('content-type', 'application/json')
|
109
124
|
.send({ title: "Test2 Title", text: "Test2 Text" })
|
110
125
|
.end((err, res) => {
|
111
|
-
|
126
|
+
|
127
|
+
if (err) { console.error("err: ", err); }
|
128
|
+
if (log) { console.log("res.body: ", res.body); }
|
129
|
+
|
112
130
|
res.should.have.status(200);
|
113
131
|
res.body.should.be.a('object');
|
114
132
|
|
@@ -121,7 +139,7 @@ describe('CannedRoute', () => {
|
|
121
139
|
|
122
140
|
res.should.have.status(200);
|
123
141
|
//res.body.should.be.a('array');
|
124
|
-
|
142
|
+
|
125
143
|
expect(res.body).to.be.an('array')
|
126
144
|
expect(res.body.length).to.equal(1);
|
127
145
|
|
@@ -132,26 +150,22 @@ describe('CannedRoute', () => {
|
|
132
150
|
.send()
|
133
151
|
.end((err, res) => {
|
134
152
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
expect(res.body).to.be.an('array')
|
139
|
-
expect(res.body.length).to.equal(2);
|
153
|
+
res.should.have.status(200);
|
154
|
+
//res.body.should.be.a('array');
|
140
155
|
|
141
|
-
|
142
|
-
|
143
|
-
})
|
156
|
+
expect(res.body).to.be.an('array')
|
157
|
+
expect(res.body.length).to.equal(2);
|
144
158
|
|
159
|
+
done();
|
145
160
|
|
161
|
+
})
|
146
162
|
})
|
147
|
-
|
148
|
-
|
149
163
|
})
|
150
|
-
|
151
164
|
})
|
152
165
|
})
|
153
166
|
})
|
154
167
|
})
|
155
168
|
})
|
156
169
|
}).timeout(5000);
|
170
|
+
|
157
171
|
})
|