protobuf-platform 1.2.720 → 1.2.722
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.
- package/package.json +1 -1
- package/payment/payment.proto +9 -0
- package/payment/payment_pb.js +147 -3
- package/scripts/verify-canonical-rg-receipt.js +38 -0
- package/user/user.proto +2 -0
- package/user/user_pb.js +49 -1
package/package.json
CHANGED
package/payment/payment.proto
CHANGED
|
@@ -278,6 +278,9 @@ message MethodItem {
|
|
|
278
278
|
optional string code = 13;
|
|
279
279
|
optional string currency_type = 14;
|
|
280
280
|
optional bool is_test = 15;
|
|
281
|
+
// Coming soon at the payment-method level. Mutually exclusive with an active method.
|
|
282
|
+
// Absent means false for older producers and legacy rows.
|
|
283
|
+
optional bool soon = 16;
|
|
281
284
|
}
|
|
282
285
|
message MethodRequest {
|
|
283
286
|
oneof request {
|
|
@@ -296,6 +299,9 @@ message MethodItemRequest {
|
|
|
296
299
|
optional string code = 9;
|
|
297
300
|
optional string currency_type = 10;
|
|
298
301
|
optional bool is_test = 11;
|
|
302
|
+
// Coming soon at the payment-method level. Mutually exclusive with is_active=true.
|
|
303
|
+
// Absent leaves the stored value unchanged on update.
|
|
304
|
+
optional bool soon = 12;
|
|
299
305
|
}
|
|
300
306
|
message GetMethodRequest {
|
|
301
307
|
int32 id = 1;
|
|
@@ -998,6 +1004,9 @@ message UserPaymentMethodItem {
|
|
|
998
1004
|
repeated SavedDepositCard saved_cards = 31;
|
|
999
1005
|
// Most recently confirmed successful saved card for this method. Never a PAN.
|
|
1000
1006
|
optional string saved_card_id = 32;
|
|
1007
|
+
// True only for a coming-soon method returned by client discovery.
|
|
1008
|
+
// Absent means false. Hidden methods are omitted entirely.
|
|
1009
|
+
optional bool soon = 33;
|
|
1001
1010
|
}
|
|
1002
1011
|
message UserPaymentMethodsResponse {
|
|
1003
1012
|
repeated UserPaymentMethodItem items = 1;
|
package/payment/payment_pb.js
CHANGED
|
@@ -10568,7 +10568,8 @@ proto.payment.MethodItem.toObject = function(includeInstance, msg) {
|
|
|
10568
10568
|
providerImageCdn: jspb.Message.getFieldWithDefault(msg, 12, ""),
|
|
10569
10569
|
code: jspb.Message.getFieldWithDefault(msg, 13, ""),
|
|
10570
10570
|
currencyType: jspb.Message.getFieldWithDefault(msg, 14, ""),
|
|
10571
|
-
isTest: jspb.Message.getBooleanFieldWithDefault(msg, 15, false)
|
|
10571
|
+
isTest: jspb.Message.getBooleanFieldWithDefault(msg, 15, false),
|
|
10572
|
+
soon: jspb.Message.getBooleanFieldWithDefault(msg, 16, false)
|
|
10572
10573
|
};
|
|
10573
10574
|
|
|
10574
10575
|
if (includeInstance) {
|
|
@@ -10661,6 +10662,10 @@ proto.payment.MethodItem.deserializeBinaryFromReader = function(msg, reader) {
|
|
|
10661
10662
|
var value = /** @type {boolean} */ (reader.readBool());
|
|
10662
10663
|
msg.setIsTest(value);
|
|
10663
10664
|
break;
|
|
10665
|
+
case 16:
|
|
10666
|
+
var value = /** @type {boolean} */ (reader.readBool());
|
|
10667
|
+
msg.setSoon(value);
|
|
10668
|
+
break;
|
|
10664
10669
|
default:
|
|
10665
10670
|
reader.skipField();
|
|
10666
10671
|
break;
|
|
@@ -10788,6 +10793,13 @@ proto.payment.MethodItem.serializeBinaryToWriter = function(message, writer) {
|
|
|
10788
10793
|
f
|
|
10789
10794
|
);
|
|
10790
10795
|
}
|
|
10796
|
+
f = /** @type {boolean} */ (jspb.Message.getField(message, 16));
|
|
10797
|
+
if (f != null) {
|
|
10798
|
+
writer.writeBool(
|
|
10799
|
+
16,
|
|
10800
|
+
f
|
|
10801
|
+
);
|
|
10802
|
+
}
|
|
10791
10803
|
};
|
|
10792
10804
|
|
|
10793
10805
|
|
|
@@ -11295,6 +11307,42 @@ proto.payment.MethodItem.prototype.hasIsTest = function() {
|
|
|
11295
11307
|
};
|
|
11296
11308
|
|
|
11297
11309
|
|
|
11310
|
+
/**
|
|
11311
|
+
* optional bool soon = 16;
|
|
11312
|
+
* @return {boolean}
|
|
11313
|
+
*/
|
|
11314
|
+
proto.payment.MethodItem.prototype.getSoon = function() {
|
|
11315
|
+
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 16, false));
|
|
11316
|
+
};
|
|
11317
|
+
|
|
11318
|
+
|
|
11319
|
+
/**
|
|
11320
|
+
* @param {boolean} value
|
|
11321
|
+
* @return {!proto.payment.MethodItem} returns this
|
|
11322
|
+
*/
|
|
11323
|
+
proto.payment.MethodItem.prototype.setSoon = function(value) {
|
|
11324
|
+
return jspb.Message.setField(this, 16, value);
|
|
11325
|
+
};
|
|
11326
|
+
|
|
11327
|
+
|
|
11328
|
+
/**
|
|
11329
|
+
* Clears the field making it undefined.
|
|
11330
|
+
* @return {!proto.payment.MethodItem} returns this
|
|
11331
|
+
*/
|
|
11332
|
+
proto.payment.MethodItem.prototype.clearSoon = function() {
|
|
11333
|
+
return jspb.Message.setField(this, 16, undefined);
|
|
11334
|
+
};
|
|
11335
|
+
|
|
11336
|
+
|
|
11337
|
+
/**
|
|
11338
|
+
* Returns whether this field is set.
|
|
11339
|
+
* @return {boolean}
|
|
11340
|
+
*/
|
|
11341
|
+
proto.payment.MethodItem.prototype.hasSoon = function() {
|
|
11342
|
+
return jspb.Message.getField(this, 16) != null;
|
|
11343
|
+
};
|
|
11344
|
+
|
|
11345
|
+
|
|
11298
11346
|
|
|
11299
11347
|
/**
|
|
11300
11348
|
* Oneof group definitions for this message. Each group defines the field
|
|
@@ -11564,7 +11612,8 @@ proto.payment.MethodItemRequest.toObject = function(includeInstance, msg) {
|
|
|
11564
11612
|
processingType: jspb.Message.getFieldWithDefault(msg, 8, ""),
|
|
11565
11613
|
code: jspb.Message.getFieldWithDefault(msg, 9, ""),
|
|
11566
11614
|
currencyType: jspb.Message.getFieldWithDefault(msg, 10, ""),
|
|
11567
|
-
isTest: jspb.Message.getBooleanFieldWithDefault(msg, 11, false)
|
|
11615
|
+
isTest: jspb.Message.getBooleanFieldWithDefault(msg, 11, false),
|
|
11616
|
+
soon: jspb.Message.getBooleanFieldWithDefault(msg, 12, false)
|
|
11568
11617
|
};
|
|
11569
11618
|
|
|
11570
11619
|
if (includeInstance) {
|
|
@@ -11641,6 +11690,10 @@ proto.payment.MethodItemRequest.deserializeBinaryFromReader = function(msg, read
|
|
|
11641
11690
|
var value = /** @type {boolean} */ (reader.readBool());
|
|
11642
11691
|
msg.setIsTest(value);
|
|
11643
11692
|
break;
|
|
11693
|
+
case 12:
|
|
11694
|
+
var value = /** @type {boolean} */ (reader.readBool());
|
|
11695
|
+
msg.setSoon(value);
|
|
11696
|
+
break;
|
|
11644
11697
|
default:
|
|
11645
11698
|
reader.skipField();
|
|
11646
11699
|
break;
|
|
@@ -11740,6 +11793,13 @@ proto.payment.MethodItemRequest.serializeBinaryToWriter = function(message, writ
|
|
|
11740
11793
|
f
|
|
11741
11794
|
);
|
|
11742
11795
|
}
|
|
11796
|
+
f = /** @type {boolean} */ (jspb.Message.getField(message, 12));
|
|
11797
|
+
if (f != null) {
|
|
11798
|
+
writer.writeBool(
|
|
11799
|
+
12,
|
|
11800
|
+
f
|
|
11801
|
+
);
|
|
11802
|
+
}
|
|
11743
11803
|
};
|
|
11744
11804
|
|
|
11745
11805
|
|
|
@@ -12103,6 +12163,42 @@ proto.payment.MethodItemRequest.prototype.hasIsTest = function() {
|
|
|
12103
12163
|
};
|
|
12104
12164
|
|
|
12105
12165
|
|
|
12166
|
+
/**
|
|
12167
|
+
* optional bool soon = 12;
|
|
12168
|
+
* @return {boolean}
|
|
12169
|
+
*/
|
|
12170
|
+
proto.payment.MethodItemRequest.prototype.getSoon = function() {
|
|
12171
|
+
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 12, false));
|
|
12172
|
+
};
|
|
12173
|
+
|
|
12174
|
+
|
|
12175
|
+
/**
|
|
12176
|
+
* @param {boolean} value
|
|
12177
|
+
* @return {!proto.payment.MethodItemRequest} returns this
|
|
12178
|
+
*/
|
|
12179
|
+
proto.payment.MethodItemRequest.prototype.setSoon = function(value) {
|
|
12180
|
+
return jspb.Message.setField(this, 12, value);
|
|
12181
|
+
};
|
|
12182
|
+
|
|
12183
|
+
|
|
12184
|
+
/**
|
|
12185
|
+
* Clears the field making it undefined.
|
|
12186
|
+
* @return {!proto.payment.MethodItemRequest} returns this
|
|
12187
|
+
*/
|
|
12188
|
+
proto.payment.MethodItemRequest.prototype.clearSoon = function() {
|
|
12189
|
+
return jspb.Message.setField(this, 12, undefined);
|
|
12190
|
+
};
|
|
12191
|
+
|
|
12192
|
+
|
|
12193
|
+
/**
|
|
12194
|
+
* Returns whether this field is set.
|
|
12195
|
+
* @return {boolean}
|
|
12196
|
+
*/
|
|
12197
|
+
proto.payment.MethodItemRequest.prototype.hasSoon = function() {
|
|
12198
|
+
return jspb.Message.getField(this, 12) != null;
|
|
12199
|
+
};
|
|
12200
|
+
|
|
12201
|
+
|
|
12106
12202
|
|
|
12107
12203
|
|
|
12108
12204
|
|
|
@@ -40803,7 +40899,8 @@ proto.payment.UserPaymentMethodItem.toObject = function(includeInstance, msg) {
|
|
|
40803
40899
|
saveCard: jspb.Message.getBooleanFieldWithDefault(msg, 30, false),
|
|
40804
40900
|
savedCardsList: jspb.Message.toObjectList(msg.getSavedCardsList(),
|
|
40805
40901
|
proto.payment.SavedDepositCard.toObject, includeInstance),
|
|
40806
|
-
savedCardId: jspb.Message.getFieldWithDefault(msg, 32, "")
|
|
40902
|
+
savedCardId: jspb.Message.getFieldWithDefault(msg, 32, ""),
|
|
40903
|
+
soon: jspb.Message.getBooleanFieldWithDefault(msg, 33, false)
|
|
40807
40904
|
};
|
|
40808
40905
|
|
|
40809
40906
|
if (includeInstance) {
|
|
@@ -40970,6 +41067,10 @@ proto.payment.UserPaymentMethodItem.deserializeBinaryFromReader = function(msg,
|
|
|
40970
41067
|
var value = /** @type {string} */ (reader.readString());
|
|
40971
41068
|
msg.setSavedCardId(value);
|
|
40972
41069
|
break;
|
|
41070
|
+
case 33:
|
|
41071
|
+
var value = /** @type {boolean} */ (reader.readBool());
|
|
41072
|
+
msg.setSoon(value);
|
|
41073
|
+
break;
|
|
40973
41074
|
default:
|
|
40974
41075
|
reader.skipField();
|
|
40975
41076
|
break;
|
|
@@ -41225,6 +41326,13 @@ proto.payment.UserPaymentMethodItem.serializeBinaryToWriter = function(message,
|
|
|
41225
41326
|
f
|
|
41226
41327
|
);
|
|
41227
41328
|
}
|
|
41329
|
+
f = /** @type {boolean} */ (jspb.Message.getField(message, 33));
|
|
41330
|
+
if (f != null) {
|
|
41331
|
+
writer.writeBool(
|
|
41332
|
+
33,
|
|
41333
|
+
f
|
|
41334
|
+
);
|
|
41335
|
+
}
|
|
41228
41336
|
};
|
|
41229
41337
|
|
|
41230
41338
|
|
|
@@ -42204,6 +42312,42 @@ proto.payment.UserPaymentMethodItem.prototype.hasSavedCardId = function() {
|
|
|
42204
42312
|
};
|
|
42205
42313
|
|
|
42206
42314
|
|
|
42315
|
+
/**
|
|
42316
|
+
* optional bool soon = 33;
|
|
42317
|
+
* @return {boolean}
|
|
42318
|
+
*/
|
|
42319
|
+
proto.payment.UserPaymentMethodItem.prototype.getSoon = function() {
|
|
42320
|
+
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 33, false));
|
|
42321
|
+
};
|
|
42322
|
+
|
|
42323
|
+
|
|
42324
|
+
/**
|
|
42325
|
+
* @param {boolean} value
|
|
42326
|
+
* @return {!proto.payment.UserPaymentMethodItem} returns this
|
|
42327
|
+
*/
|
|
42328
|
+
proto.payment.UserPaymentMethodItem.prototype.setSoon = function(value) {
|
|
42329
|
+
return jspb.Message.setField(this, 33, value);
|
|
42330
|
+
};
|
|
42331
|
+
|
|
42332
|
+
|
|
42333
|
+
/**
|
|
42334
|
+
* Clears the field making it undefined.
|
|
42335
|
+
* @return {!proto.payment.UserPaymentMethodItem} returns this
|
|
42336
|
+
*/
|
|
42337
|
+
proto.payment.UserPaymentMethodItem.prototype.clearSoon = function() {
|
|
42338
|
+
return jspb.Message.setField(this, 33, undefined);
|
|
42339
|
+
};
|
|
42340
|
+
|
|
42341
|
+
|
|
42342
|
+
/**
|
|
42343
|
+
* Returns whether this field is set.
|
|
42344
|
+
* @return {boolean}
|
|
42345
|
+
*/
|
|
42346
|
+
proto.payment.UserPaymentMethodItem.prototype.hasSoon = function() {
|
|
42347
|
+
return jspb.Message.getField(this, 33) != null;
|
|
42348
|
+
};
|
|
42349
|
+
|
|
42350
|
+
|
|
42207
42351
|
|
|
42208
42352
|
/**
|
|
42209
42353
|
* List of repeated fields within this message type.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const assert = require('node:assert/strict');
|
|
3
|
+
const M = require('../user/user_pb');
|
|
4
|
+
const T = M.PrecisionRgAdmissionResponse;
|
|
5
|
+
const absent = T.deserializeBinary(new T().serializeBinary());
|
|
6
|
+
assert.equal(absent.hasCanonicalReceiptJson(), false);
|
|
7
|
+
assert.equal(absent.getCanonicalReceiptJson(), '');
|
|
8
|
+
const response = new T();
|
|
9
|
+
response.setCurrentGeneration('9007199254740993');
|
|
10
|
+
response.setAdmissionReceiptId('initial-receipt');
|
|
11
|
+
response.setCanonicalReceiptJson('');
|
|
12
|
+
assert.equal(T.deserializeBinary(response.serializeBinary()).hasCanonicalReceiptJson(), true);
|
|
13
|
+
const packet = { protocolVersion: 2, version: 1, state: 'RESERVED', decision: { allowed: true, evaluatedAt: '2026-11-03T00:00:00.000Z', details: { time_deltas_seconds: {} } } };
|
|
14
|
+
const exact = JSON.stringify(packet);
|
|
15
|
+
response.setCanonicalReceiptJson(exact);
|
|
16
|
+
const decoded = T.deserializeBinary(response.serializeBinary());
|
|
17
|
+
assert.equal(decoded.getCanonicalReceiptJson(), exact);
|
|
18
|
+
assert.equal(decoded.getCurrentGeneration(), '9007199254740993');
|
|
19
|
+
assert.equal(decoded.getAdmissionReceiptId(), 'initial-receipt');
|
|
20
|
+
decoded.clearCanonicalReceiptJson();
|
|
21
|
+
assert.equal(T.deserializeBinary(decoded.serializeBinary()).hasCanonicalReceiptJson(), false);
|
|
22
|
+
console.log('PASS: canonical RG receipt optional presence and lossless JSON wire value; existing fields unchanged');
|
|
23
|
+
const fs = require('node:fs');
|
|
24
|
+
const vm = require('node:vm');
|
|
25
|
+
const { execFileSync } = require('node:child_process');
|
|
26
|
+
const baseline = '7e5f089e5a223061058ad607b7809b89bd3f1282';
|
|
27
|
+
const readOld = (file) => execFileSync('git', ['show', `${baseline}:${file}`], { encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
|
|
28
|
+
const source = fs.readFileSync(require('node:path').join(__dirname, '../user/user.proto'), 'utf8');
|
|
29
|
+
assert.equal(source.replace(' // Exact persisted initial SQL-v2 receipt; absent when no initial receipt exists.\n optional string canonical_receipt_json = 9;\n', ''), readOld('user/user.proto'));
|
|
30
|
+
const sandbox = { exports: {}, require, console };
|
|
31
|
+
vm.runInNewContext(readOld('user/user_pb.js'), sandbox);
|
|
32
|
+
const Old = sandbox.exports.PrecisionRgAdmissionResponse;
|
|
33
|
+
const oldReadsNew = Old.deserializeBinary(response.serializeBinary());
|
|
34
|
+
assert.equal(oldReadsNew.getAdmissionReceiptId(), 'initial-receipt');
|
|
35
|
+
assert.equal(oldReadsNew.getCurrentGeneration(), '9007199254740993');
|
|
36
|
+
assert.equal(T.deserializeBinary(oldReadsNew.serializeBinary()).hasCanonicalReceiptJson(), false);
|
|
37
|
+
assert.equal(T.deserializeBinary(new Old().serializeBinary()).hasCanonicalReceiptJson(), false);
|
|
38
|
+
console.log('PASS: previous released reader interoperability; old reserialization loses optional tag as expected; only approved source addition');
|
package/user/user.proto
CHANGED
|
@@ -2691,6 +2691,8 @@ message PrecisionRgAdmissionResponse {
|
|
|
2691
2691
|
string release_receipt_id = 6;
|
|
2692
2692
|
string commit_receipt_id = 7;
|
|
2693
2693
|
EvaluateResponsibleGamingDecisionResponse decision = 8;
|
|
2694
|
+
// Exact persisted initial SQL-v2 receipt; absent when no initial receipt exists.
|
|
2695
|
+
optional string canonical_receipt_json = 9;
|
|
2694
2696
|
}
|
|
2695
2697
|
|
|
2696
2698
|
message ImportPlayerInvitationsRequest {
|
package/user/user_pb.js
CHANGED
|
@@ -107763,7 +107763,8 @@ proto.user.PrecisionRgAdmissionResponse.toObject = function(includeInstance, msg
|
|
|
107763
107763
|
admissionReceiptId: jspb.Message.getFieldWithDefault(msg, 5, ""),
|
|
107764
107764
|
releaseReceiptId: jspb.Message.getFieldWithDefault(msg, 6, ""),
|
|
107765
107765
|
commitReceiptId: jspb.Message.getFieldWithDefault(msg, 7, ""),
|
|
107766
|
-
decision: (f = msg.getDecision()) && proto.user.EvaluateResponsibleGamingDecisionResponse.toObject(includeInstance, f)
|
|
107766
|
+
decision: (f = msg.getDecision()) && proto.user.EvaluateResponsibleGamingDecisionResponse.toObject(includeInstance, f),
|
|
107767
|
+
canonicalReceiptJson: jspb.Message.getFieldWithDefault(msg, 9, "")
|
|
107767
107768
|
};
|
|
107768
107769
|
|
|
107769
107770
|
if (includeInstance) {
|
|
@@ -107834,6 +107835,10 @@ proto.user.PrecisionRgAdmissionResponse.deserializeBinaryFromReader = function(m
|
|
|
107834
107835
|
reader.readMessage(value,proto.user.EvaluateResponsibleGamingDecisionResponse.deserializeBinaryFromReader);
|
|
107835
107836
|
msg.setDecision(value);
|
|
107836
107837
|
break;
|
|
107838
|
+
case 9:
|
|
107839
|
+
var value = /** @type {string} */ (reader.readString());
|
|
107840
|
+
msg.setCanonicalReceiptJson(value);
|
|
107841
|
+
break;
|
|
107837
107842
|
default:
|
|
107838
107843
|
reader.skipField();
|
|
107839
107844
|
break;
|
|
@@ -107921,6 +107926,13 @@ proto.user.PrecisionRgAdmissionResponse.serializeBinaryToWriter = function(messa
|
|
|
107921
107926
|
proto.user.EvaluateResponsibleGamingDecisionResponse.serializeBinaryToWriter
|
|
107922
107927
|
);
|
|
107923
107928
|
}
|
|
107929
|
+
f = /** @type {string} */ (jspb.Message.getField(message, 9));
|
|
107930
|
+
if (f != null) {
|
|
107931
|
+
writer.writeString(
|
|
107932
|
+
9,
|
|
107933
|
+
f
|
|
107934
|
+
);
|
|
107935
|
+
}
|
|
107924
107936
|
};
|
|
107925
107937
|
|
|
107926
107938
|
|
|
@@ -108106,6 +108118,42 @@ proto.user.PrecisionRgAdmissionResponse.prototype.hasDecision = function() {
|
|
|
108106
108118
|
};
|
|
108107
108119
|
|
|
108108
108120
|
|
|
108121
|
+
/**
|
|
108122
|
+
* optional string canonical_receipt_json = 9;
|
|
108123
|
+
* @return {string}
|
|
108124
|
+
*/
|
|
108125
|
+
proto.user.PrecisionRgAdmissionResponse.prototype.getCanonicalReceiptJson = function() {
|
|
108126
|
+
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
|
|
108127
|
+
};
|
|
108128
|
+
|
|
108129
|
+
|
|
108130
|
+
/**
|
|
108131
|
+
* @param {string} value
|
|
108132
|
+
* @return {!proto.user.PrecisionRgAdmissionResponse} returns this
|
|
108133
|
+
*/
|
|
108134
|
+
proto.user.PrecisionRgAdmissionResponse.prototype.setCanonicalReceiptJson = function(value) {
|
|
108135
|
+
return jspb.Message.setField(this, 9, value);
|
|
108136
|
+
};
|
|
108137
|
+
|
|
108138
|
+
|
|
108139
|
+
/**
|
|
108140
|
+
* Clears the field making it undefined.
|
|
108141
|
+
* @return {!proto.user.PrecisionRgAdmissionResponse} returns this
|
|
108142
|
+
*/
|
|
108143
|
+
proto.user.PrecisionRgAdmissionResponse.prototype.clearCanonicalReceiptJson = function() {
|
|
108144
|
+
return jspb.Message.setField(this, 9, undefined);
|
|
108145
|
+
};
|
|
108146
|
+
|
|
108147
|
+
|
|
108148
|
+
/**
|
|
108149
|
+
* Returns whether this field is set.
|
|
108150
|
+
* @return {boolean}
|
|
108151
|
+
*/
|
|
108152
|
+
proto.user.PrecisionRgAdmissionResponse.prototype.hasCanonicalReceiptJson = function() {
|
|
108153
|
+
return jspb.Message.getField(this, 9) != null;
|
|
108154
|
+
};
|
|
108155
|
+
|
|
108156
|
+
|
|
108109
108157
|
|
|
108110
108158
|
|
|
108111
108159
|
|